chiark / gitweb /
el/dot-emacs.el (mdw-fontify-rust): Fix integer literal syntax.
[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 "gdbus", "call", "-e",
14       "-d", "org.freedesktop.Notifications",
15       "-o", "/org/freedesktop/Notifications",
16       "-m", "org.freedesktop.Notifications.Notify", "--",
17       "DisOrder", "0", "audio-volume-high",
18       $head, $body, "[]", "{}", "5000";
19   }
20   waitpid $kid, 0;
21 }
22
23 sub cmd (@) {
24   my @args = @_;
25   open my $f, "-|", "disorder", @args;
26   chomp (my @r = <$f>);
27   close $f;
28   if (wantarray) { return @r; }
29   elsif (@r == 1) { return $r[0]; }
30   else { return "??? multiple lines"; }
31 }
32
33 sub now_playing (;$) {
34   my ($track) = @_;
35   if (!defined $track) {
36     my @r = cmd "playing";
37     if ($r[0] =~ /^track\s+(.*)$/) { $track = $1; }
38     else { return; }
39   }
40   my %p;
41   for my $p ("artist", "album", "title")
42     { $p{$p} = cmd "part", $track, "display", $p; }
43   if ($p{artist} =~ /^[A-Z]$/)
44     { $p{artist} = $p{album}; $p{album} = undef; }
45   elsif ($p{artist} eq "share" && $p{album} eq "disorder")
46     { next LINE; }
47   my $r = "$p{artist}: ‘$p{title}’";
48   if (defined $p{album}) { $r .= ", from ‘$p{album}’"; }
49   notify "DisOrder: now playing", $r;
50 }
51
52 for (;;) {
53   open my $log, "-|", "disorder", "log";
54   my $startp = 1;
55   my $stateinfo = undef;
56   LINE: while (<$log>) {
57     chomp;
58     my @f = ();
59     my $q = my $t = undef;
60     my $e = 0;
61     my $j = -1;
62     for (my $i = 0; $i < length $_; $i++) {
63       my $ch = substr($_, $i, 1);
64       if ($e) {
65         if ($ch eq "n") { $ch = "\n"; }
66         $t .= $ch; $e = 0;
67       } elsif ($ch eq $q) {
68         push @f, $t; $q = $t = undef;
69       } elsif (defined $q) {
70         if ($ch eq "\\") { $e = 1; }
71         else { $t .= $ch; }
72       } elsif ($ch eq " ") {
73         push @f, $t if defined $t; $t = undef;
74       } elsif (!defined $t && ($ch eq '"' || $ch eq "'")) {
75         $t //= ""; $q = $ch; $j = $i;
76       } else {
77         $t //= ""; $t .= $ch;
78       }
79     }
80     defined $q and die "unmatched $q (pos $j) in: $_";
81     push @f, $t if defined $t;
82
83     my $what = $f[1];
84     if ($what eq "volume" && $startp) {
85       $startp = 0;
86       notify "DisOrder state", "Connected: $startinfo";
87       now_playing;
88     } elsif ($what eq "state") {
89       my $st = $f[2];
90       my $msg;
91       my $np = 0;
92       if ($st eq "disable_random") { $msg = "random play disabled"; }
93       elsif ($st eq "enable_random") { $msg = "random play enabled"; }
94       elsif ($st eq "disable_play") { $msg = "playing disabled"; }
95       elsif ($st eq "enable_play") { $msg = "playing enabled"; }
96       elsif ($st eq "pause") { $msg = "paused"; }
97       elsif ($st eq "resume") { $msg = "playing"; $np = 1; }
98       else { next LINE; }
99       if (!$startp) {
100         notify "DisOrder state", ucfirst $msg;
101         now_playing if $np;
102       } else {
103         if (defined $startinfo) { $startinfo .= "; " . $msg; }
104         else { $startinfo = $msg; }
105       }
106     } elsif ($what eq "scratched") {
107       notify "DisOrder state", "Scratched playing track";
108     } elsif ($what eq "playing") {
109       now_playing $f[2];
110     }
111   }
112   close $log;
113   sleep 5;
114 }