bin/mdw-build: Do all of the log descriptor setting in one place.
[profile] / bin / disorder-notify
1 #! /usr/bin/perl
2
3 sub notify ($$) {
4 my ($head, $body) = @_;
5
6 $body =~ s:\&:&:g;
7 $body =~ s:\<:&lt;:g;
8 $body =~ s:\>:&gt;:g;
9 my $kid = fork;
10 defined $kid or return;
11 if (!$kid) {
12 open STDOUT, ">", "/dev/null";
13 exec "notify-send",
14 "-c", "DisOrder", "-i", "audio-volume-high", "-t", "5000",
15 $head, $body;
16 }
17 waitpid $kid, 0;
18 }
19
20 sub cmd (@) {
21 my @args = @_;
22 open my $f, "-|", "disorder", @args;
23 chomp (my @r = <$f>);
24 close $f;
25 if (wantarray) { return @r; }
26 elsif (@r == 1) { return $r[0]; }
27 else { return "??? multiple lines"; }
28 }
29
30 sub now_playing (;$) {
31 my ($track) = @_;
32 if (!defined $track) {
33 my @r = cmd "playing";
34 if ($r[0] =~ /^track\s+(.*)$/) { $track = $1; }
35 else { return; }
36 }
37 my %p;
38 for my $p ("artist", "album", "title")
39 { $p{$p} = cmd "part", $track, "display", $p; }
40 if ($p{artist} =~ /^[A-Z]$/)
41 { $p{artist} = $p{album}; $p{album} = undef; }
42 elsif ($p{artist} eq "share" && $p{album} eq "disorder")
43 { next LINE; }
44 my $r = "$p{artist}: ‘$p{title}’";
45 if (defined $p{album}) { $r .= ", from ‘$p{album}’"; }
46 notify "DisOrder: now playing", $r;
47 }
48
49 for (;;) {
50 open my $log, "-|", "disorder", "log";
51 my $startp = 1;
52 my $stateinfo = undef;
53 LINE: while (<$log>) {
54 chomp;
55 my @f = ();
56 my $q = my $t = undef;
57 my $e = 0;
58 my $j = -1;
59 for (my $i = 0; $i < length $_; $i++) {
60 my $ch = substr($_, $i, 1);
61 if ($e) {
62 if ($ch eq "n") { $ch = "\n"; }
63 $t .= $ch; $e = 0;
64 } elsif ($ch eq $q) {
65 push @f, $t; $q = $t = undef;
66 } elsif (defined $q) {
67 if ($ch eq "\\") { $e = 1; }
68 else { $t .= $ch; }
69 } elsif ($ch eq " ") {
70 push @f, $t if defined $t; $t = undef;
71 } elsif (!defined $t && ($ch eq '"' || $ch eq "'")) {
72 $t //= ""; $q = $ch; $j = $i;
73 } else {
74 $t //= ""; $t .= $ch;
75 }
76 }
77 defined $q and die "unmatched $q (pos $j) in: $_";
78 push @f, $t if defined $t;
79
80 my $what = $f[1];
81 if ($what eq "volume" && $startp) {
82 $startp = 0;
83 notify "DisOrder state", "Connected: $startinfo";
84 now_playing;
85 } elsif ($what eq "state") {
86 my $st = $f[2];
87 my $msg;
88 my $np = 0;
89 if ($st eq "disable_random") { $msg = "random play disabled"; }
90 elsif ($st eq "enable_random") { $msg = "random play enabled"; }
91 elsif ($st eq "disable_play") { $msg = "playing disabled"; }
92 elsif ($st eq "enable_play") { $msg = "playing enabled"; }
93 elsif ($st eq "pause") { $msg = "paused"; }
94 elsif ($st eq "resume") { $msg = "playing"; $np = 1; }
95 else { next LINE; }
96 if (!$startp) {
97 notify "DisOrder state", ucfirst $msg;
98 now_playing if $np;
99 } else {
100 if (defined $startinfo) { $startinfo .= "; " . $msg; }
101 else { $startinfo = $msg; }
102 }
103 } elsif ($what eq "scratched") {
104 notify "DisOrder state", "Scratched playing track";
105 } elsif ($what eq "playing") {
106 now_playing $f[2];
107 }
108 }
109 close $log;
110 sleep 5;
111 }