-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathencode-files
executable file
·127 lines (102 loc) · 4.02 KB
/
encode-files
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env perl6
use Tinky;
=begin pod
=head1 NAME
encode-files - watch a directory of files and encode WAV to FLAC
=head1 SYNOPSIS
=begin code
encode-files [--out-dir=/tmp/flac ] <DIRECTORY>
=end code
=head1 DESCRIPTION
This watches the directory supplied as an argument and when a new WAV file
shows up it will be copied to the output directory (default "/tmp/flac"
but can be specified with the C<--out-dir> parameter, ) and then encoded
as FLAC.
It notifies of state changes to STDERR.
You will of course need the 'flac' program for this to work.
=end pod
my $state-new = Tinky::State.new(name => 'new');
my $state-ready = Tinky::State.new(name => 'ready');
my $state-copied = Tinky::State.new(name => 'copied');
my $state-done = Tinky::State.new(name => 'done');
my $state-failed = Tinky::State.new(name => 'failed');
my $ready = Tinky::Transition.new(name => 'ready', from => $state-new, to => $state-ready);
my $copied = Tinky::Transition.new(name => 'copied', from => $state-ready, to => $state-copied);
my $copy-fail = Tinky::Transition.new(name => 'fail', from => $state-ready, to => $state-failed);
my $encoded = Tinky::Transition.new(name => 'done', from => $state-copied, to => $state-done);
my $encode-fail = Tinky::Transition.new(name => 'fail', from => $state-copied, to => $state-failed);
my @transitions = ( $ready, $copied, $copy-fail, $encoded, $encode-fail);
my $workflow = Tinky::Workflow.new(name => "encoding", :@transitions, initial-state => $state-new);
class ProcessFile does Tinky::Object {
has Str $.path is required;
has Str $.out-dir is required;
has Str $.new-path;
has Str $.flac-file;
has @.errors;
method new-path() returns Str {
$!new-path //= $!out-dir.IO.child($!path.IO.basename).Str;
}
method flac-file() returns Str {
$!flac-file //= self.new-path.subst(/\.wav$/, '.flac');
$!flac-file;
}
}
multi sub MAIN($dir, Str :$out-dir = '/tmp/flac') {
my ProcessFile @process-files;
my $watch-supply = IO::Notification.watch-path($dir).grep({ $_.path ~~ /\.wav$/ }).unique(as => { $_.path }, expires => 5);
say "Watching '$dir'";
react {
whenever $watch-supply -> $change {
if @process-files.grep({ $_.path eq $change.path }) {
$*ERR.say: "** Already processing '", $change.path, "' **";
}
else {
CATCH {
default {
say $_;
}
}
my $pf = ProcessFile.new(path => $change.path, :$out-dir);
say "Processing '{ $pf.path }'";
$pf.apply-workflow($workflow);
@process-files.append: $pf;
$pf.ready;
}
}
whenever $state-ready.enter-supply -> $pf {
CATCH {
default {
$pf.fail;
}
}
my $copy = Proc::Async.new('/usr/bin/cp', $pf.path, $pf.new-path, :err);
whenever $copy.start {
$pf.copied;
}
}
whenever $state-copied.enter-supply -> $pf {
CATCH {
default {
$pf.fail;
}
}
my $encode = Proc::Async.new('/usr/bin/flac', $pf.new-path);
whenever $encode.stdout {
# ignored
}
whenever $encode.stderr -> $error {
$pf.errors.append: $error;
}
whenever $encode.start {
$pf.done;
}
}
whenever $state-done.enter-supply -> $pf {
say "File '{ $pf.path }' has been processed to '{ $pf.flac-file }'";
}
whenever $workflow.transition-supply -> ($trans, $pf ) {
$*ERR.say("File '{ $pf.path }' went from '{ $trans.from.name }' to '{ $trans.to.name }'");
}
}
}
# vim: expandtab shiftwidth=4 ft=raku