--- /dev/null
+# Copyright © 2008, 2010 Nick Bowler
+#
+# License WTFPL2: Do What The Fuck You Want To Public License, version 2.
+# This is free software: you are free to do what the fuck you want to.
+# There is NO WARRANTY, to the extent permitted by law.
+#
+# MPDSplat helps you annoy your friends by posting your MPD status. By
+# posting to public channels, you can piss off a wider audience.
+
+use strict;
+use vars qw($VERSION %IRSSI);
+
+use utf8;
+use encoding 'utf8';
+use IO::Socket::INET6;
+
+$VERSION = '0.2';
+%IRSSI = (
+ authors => 'Nick Bowler',
+ contact => 'nbowler@draconx.ca',
+ name => 'MPDSplat',
+ description => 'Annoy your friends with MPD status information.',
+ license => 'WTFPL2',
+);
+
+# MPD Connection Settings
+$ENV{"MPD_HOST"} = "localhost" unless ($ENV{"MPD_HOST"});
+$ENV{"MPD_PORT"} = 6600 unless ($ENV{"MPD_PORT"});
+Irssi::settings_add_str("mpd", "mpd_host", $ENV{"MPD_HOST"});
+Irssi::settings_add_int("mpd", "mpd_port", $ENV{"MPD_PORT"});
+
+# Open a connection to MPD.
+sub mpd_open {
+ my $sock = new IO::Socket::INET6(
+ PeerAddr => Irssi::settings_get_str("mpd_host"),
+ PeerPort => Irssi::settings_get_int("mpd_port"),
+ Proto => 'tcp',
+ ) or do {
+ print CLIENTERROR "failed to open MPD socket: $!.";
+ return undef;
+ };
+ binmode($sock, ":utf8");
+
+ # Grab the MPD version.
+ if (!(<$sock> =~ /^OK MPD ([0-9]+)\.([0-9]+)\.([0-9]+)$/)) {
+ print CLIENTERROR "failed MPD handshake: $!.";
+ return undef;
+ }
+
+ return $sock;
+}
+
+sub mpd_currentsong {
+ my ($sock) = @_;
+ my %data;
+
+ # Get MPD status.
+ print $sock "status\n";
+ while (<$sock>) {
+ last if (/^OK/);
+ do { print CLIENTERROR "$_"; return undef } if (/^ACK/);
+
+ if (/^(\w+): (.*)$/) {
+ $data{$1} = $2;
+ }
+ }
+ return %data if (!defined $data{"songid"});
+
+ # Get song info
+ print $sock "playlistid $data{songid}\n";
+ while (<$sock>) {
+ last if (/^OK/);
+ do { print CLIENTERROR "$_"; return undef } if (/^ACK/);
+
+ if (/^(\w+): (.*)$/) {
+ $data{$1} = $2;
+ }
+ }
+
+ return %data;
+}
+
+sub mpd_close {
+ my ($sock) = @_;
+ print $sock "close\n";
+ close $sock;
+}
+
+sub fileformat {
+ ($_) = @_;
+
+ return "vorbis" if (/\.ogg$/);
+ return "flac" if (/\.flac$/);
+ return "mp3" if (/\.mp3$/);
+}
+
+sub cmd_current {
+ my ($data, $server, $witem) = @_;
+ my ($window, $local) = (Irssi::active_win());
+
+ my $sock = mpd_open() or return;
+ my %info = mpd_currentsong($sock) or return;
+ mpd_close($sock);
+
+ if ($info{'state'} eq "stop") {
+ $window->print("MPD is currently stopped.");
+ return;
+ }
+
+ my $text = "$info{Artist} – $info{Title}, "
+ . "track $info{Track}"
+ . ($info{Disc} > 1 ? ", disc $info{Disc} " : "")
+ . " of “$info{Album}” "
+ . "($info{bitrate}kbps " . fileformat($info{'file'}) . ")";
+
+ # If the active window is not a channel or query, display locally.
+ $local = 1 unless ($witem && ($witem->{type} eq "CHANNEL"
+ || $witem->{type} eq "QUERY"));
+
+ if ($local) {
+ $window->print($text);
+ } elsif ($data) {
+ $data =~ s/\s.*//;
+ $witem->command("SAY $data: /me is listening to $text.");
+ } else {
+ $witem->command("SAY /me is listening to $text.");
+ }
+}
+Irssi::command_bind('mpd', 'cmd_current');