8 (my $PROG = $0) =~ s:.*/::;
10 sub grobble_dir (\@$$$);
12 sub grobble_dir (\@$$$) {
13 my ($list, $sk, $root, $dir) = @_;
16 for my $f (send_command $sk, "files", "$root$dir") {
17 my ($tail) = $f =~ /\Q$root\E(.*)$/;
18 die "`$f' not under root `$root'" unless $tail;
22 for my $d (send_command $sk, "dirs", "$root$dir") {
23 my ($tail) = $d =~ /\Q$root\E(.*)$/;
24 die "`$d' not under root `$root'" unless $tail;
27 for my $d (@d) { grobble_dir @$list, $sk, $root, $d; }
30 sub grobble_root ($) {
35 for my $d (send_command $sk, "dirs", "") {
36 my ($pre, $tail) = $d =~ m{^(.*/)([^/]*)$};
37 die "no root in `$_'?" unless $pre;
38 if (!defined $root) { $root = $pre; }
39 elsif ($root ne $pre) { die "root was `$root'; now it's `$pre'"; }
40 grobble_dir @list, $sk, $root, $tail;
45 sub trim_extension ($) {
47 $f =~ s/\.(flac|mp[23]|ogg|wav)$//;
55 $PROG set CONFIG [LIST]
60 defined (my $op = shift @ARGV) or die_usage;
62 defined (my $conf = shift @ARGV) or die_usage;
64 my $sk = connect_to_server $conf;
65 my ($root, $list) = grobble_root $sk;
67 for my $f (sort @$list) {
68 my $pick = send_command $sk, "get", "$root$f", "pick_at_random";
69 if (($pick // 1) eq "0") { print trim_extension $f, "\n"; }
73 defined (my $conf = shift @ARGV) or die_usage;
75 if (defined (my $list = shift @ARGV)) { open $fh, "<", $list; }
76 else { $fh = \*STDIN; }
78 while (<$fh>) { chomp; $black{$_} = 1; }
79 my $sk = connect_to_server $conf;
80 my ($root, $list) = grobble_root $sk;
82 FILE: for my $f (sort @$list) {
83 my $pick = send_command $sk, "get", "$root$f", "pick_at_random";
84 if (($pick // 1) eq "0") {
85 next FILE if $black{trim_extension $f};
86 send_command $sk, "unset", "$root$f", "pick_at_random";
87 print STDERR ";; reinstate <$f>\n";
89 next FILE unless $black{trim_extension $f};
90 send_command $sk, "set", "$root$f", "pick_at_random", 0;
91 print STDERR ";; blacklist <$f>\n";