1 # Copyright © 2008, 2010, 2020 Nick Bowler
3 # License WTFPL2: Do What The Fuck You Want To Public License, version 2.
4 # This is free software: you are free to do what the fuck you want to.
5 # There is NO WARRANTY, to the extent permitted by law.
7 # MPDSplat helps you annoy your friends by posting your MPD status. By
8 # posting to public channels, you can piss off a wider audience.
13 use vars qw($VERSION %IRSSI);
15 use IO::Socket::INET6;
20 authors => 'Nick Bowler',
21 contact => 'nbowler@draconx.ca',
23 description => 'Annoy your friends with MPD status information.',
27 # MPD Connection Settings
28 $ENV{"MPD_HOST"} //= "localhost";
29 $ENV{"MPD_PORT"} //= 6600;
30 Irssi::settings_add_str("mpd", "mpd_host", $ENV{"MPD_HOST"});
31 Irssi::settings_add_int("mpd", "mpd_port", $ENV{"MPD_PORT"});
33 # Open a connection to MPD.
35 my $host = Irssi::settings_get_str("mpd_host");
36 my $port = Irssi::settings_get_int("mpd_port");
39 if ($host =~ /^[@\/]/) {
41 $sock = new IO::Socket::UNIX(Type => SOCK_STREAM(),
44 $sock = new IO::Socket::INET6(PeerAddr => $host,
51 print CLIENTERROR "failed to open MPD socket: $!";
55 binmode($sock, ":utf8");
57 # Grab the MPD version.
58 unless (<$sock> =~ /^OK MPD ([0-9]+)\.([0-9]+)\.([0-9]+)$/) {
59 print CLIENTERROR "failed MPD handshake: $!";
71 print $sock "status\n";
74 do { print CLIENTERROR "$_"; return undef } if (/^ACK/);
76 if (/^(\w+): (.*)$/) {
80 return %data if (!defined $data{"songid"});
83 print $sock "playlistid $data{songid}\n";
86 do { print CLIENTERROR "$_"; return undef } if (/^ACK/);
88 if (/^(\w+): (.*)$/) {
98 print $sock "close\n";
105 return "vorbis" if (/\.ogg$/);
106 return "flac" if (/\.flac$/);
107 return "mp3" if (/\.mp3$/);
111 my ($data, $server, $witem) = @_;
112 my ($window, $local) = (Irssi::active_win());
114 my $sock = mpd_open() or return;
115 my %info = mpd_currentsong($sock) or return;
118 if ($info{'state'} eq "stop") {
119 $window->print("MPD is currently stopped.");
123 my $text = "$info{Artist} – $info{Title}, "
124 . "track $info{Track}"
125 . ($info{Disc} > 1 ? ", disc $info{Disc} " : "")
126 . " of “$info{Album}” "
127 . "($info{bitrate}kbps " . fileformat($info{'file'}) . ")";
129 # If the active window is not a channel or query, display locally.
130 $local = 1 unless ($witem && ($witem->{type} eq "CHANNEL"
131 || $witem->{type} eq "QUERY"));
134 $window->print($text);
137 $witem->command("SAY $data: /me is listening to $text.");
139 $witem->command("SAY /me is listening to $text.");
142 Irssi::command_bind('mpd', 'cmd_current');