#! /usr/bin/perl sub notify ($$) { my ($head, $body) = @_; $body =~ s:\&:&:g; $body =~ s:\<:<:g; $body =~ s:\>:>:g; my $kid = fork; defined $kid or return; if (!$kid) { open STDOUT, ">", "/dev/null"; exec "gdbus", "call", "-e", "-d", "org.freedesktop.Notifications", "-o", "/org/freedesktop/Notifications", "-m", "org.freedesktop.Notifications.Notify", "--", "DisOrder", "0", "audio-volume-high", $head, $body, "[]", "{}", "5000"; } waitpid $kid, 0; } sub cmd (@) { my @args = @_; open my $f, "-|", "disorder", @args; chomp (my @r = <$f>); close $f; if (wantarray) { return @r; } elsif (@r == 1) { return $r[0]; } else { return "??? multiple lines"; } } sub now_playing (;$) { my ($track) = @_; if (!defined $track) { my @r = cmd "playing"; if ($r[0] =~ /^track\s+(.*)$/) { $track = $1; } else { return; } } my %p; for my $p ("artist", "album", "title") { $p{$p} = cmd "part", $track, "display", $p; } if ($p{artist} =~ /^[A-Z]$/) { $p{artist} = $p{album}; $p{album} = undef; } elsif ($p{artist} eq "share" && $p{album} eq "disorder") { next LINE; } my $r = "$p{artist}: ‘$p{title}’"; if (defined $p{album}) { $r .= ", from ‘$p{album}’"; } notify "DisOrder: now playing", $r; } for (;;) { open my $log, "-|", "disorder", "log"; my $startp = 1; my $stateinfo = undef; LINE: while (<$log>) { chomp; my @f = (); my $q = my $t = undef; my $e = 0; my $j = -1; for (my $i = 0; $i < length $_; $i++) { my $ch = substr($_, $i, 1); if ($e) { if ($ch eq "n") { $ch = "\n"; } $t .= $ch; $e = 0; } elsif ($ch eq $q) { push @f, $t; $q = $t = undef; } elsif (defined $q) { if ($ch eq "\\") { $e = 1; } else { $t .= $ch; } } elsif ($ch eq " ") { push @f, $t if defined $t; $t = undef; } elsif (!defined $t && ($ch eq '"' || $ch eq "'")) { $t //= ""; $q = $ch; $j = $i; } else { $t //= ""; $t .= $ch; } } defined $q and die "unmatched $q (pos $j) in: $_"; push @f, $t if defined $t; my $what = $f[1]; if ($what eq "volume" && $startp) { $startp = 0; notify "DisOrder state", "Connected: $startinfo"; now_playing; } elsif ($what eq "state") { my $st = $f[2]; my $msg; my $np = 0; if ($st eq "disable_random") { $msg = "random play disabled"; } elsif ($st eq "enable_random") { $msg = "random play enabled"; } elsif ($st eq "disable_play") { $msg = "playing disabled"; } elsif ($st eq "enable_play") { $msg = "playing enabled"; } elsif ($st eq "pause") { $msg = "paused"; } elsif ($st eq "resume") { $msg = "playing"; $np = 1; } else { next LINE; } if (!$startp) { notify "DisOrder state", ucfirst $msg; now_playing if $np; } else { if (defined $startinfo) { $startinfo .= "; " . $msg; } else { $startinfo = $msg; } } } elsif ($what eq "scratched") { notify "DisOrder state", "Scratched playing track"; } elsif ($what eq "playing") { now_playing $f[2]; } } close $log; sleep 5; }