From: Nick Bowler Date: Sun, 26 Feb 2012 18:58:00 +0000 (-0500) Subject: Add mpdsplat script. X-Git-Url: https://git.draconx.ca/gitweb/irssi-scripts.git/commitdiff_plain/d4f45ff98f261451d14cd9594d3a71936d4443da Add mpdsplat script. --- diff --git a/mpdsplat.pl b/mpdsplat.pl new file mode 100644 index 0000000..3a46cbe --- /dev/null +++ b/mpdsplat.pl @@ -0,0 +1,129 @@ +# 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');