#/usr/bin/perl -w ######################################################################## # # iMPD - irssi MPD controller # Copyright (C) 2004 Shawn Fogle (starz@antisocial.com) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ######################################################################## # # iMPD - irssi MPD # # Requirements: mpc, mpd (http://musicpd.org) # # Please report b00gs to http://www.musicpd.org/forum/viewtopic.php?t=19 # Get the latest and greatest from pulling the module at musicpd's # SVN (module iMPD). # # OK, This is the a script for irssi/mpc/mpd for people who want to # control mpd from irssi. It's very bloated, and featureful, but this # is a good thing because it's just a perl script and you really don't # ever need to use anything that's in here that doesn't pertain to you. # If you need it (or want it) it's most likely in here. # # I am up for suggestions, alot of this may not work for you, and # I will not fix it unless you tell me about it. # # I do not believe in backwards compatibility if that means it gets in # the way of development, so this is probably needs the latest and # greatest due to changes in mpc/mpd. # ######################################################################## # Changes ######################################################################## # # 0.0.0m->0.0.0n # # - Added Move / Crossfade # # - Fixed problems with finding mpc if it's in your path. # # - Began work on AddNext (Adding next in the queue, unless it's on # random or shuffle, don't know if it will ever be added but this # release needs to make it out soon to fix path b00g. # # - Finally attached the GPL to make this fully GPLv2 compatible # ######################################################################## # Buglist / Wishlist / Todo (In no particular order) ######################################################################## # # - Have to be able to tell if MPD goes down, so it can gracefully # shutdown the statusbar, so it doesn't try and access mpc every # 5 seconds (gets even worse if mpdbar_refresh is faster than # default). This will more than likely be fixed by the MPD module. # Note to self: Script unloading self leads to _bad_problems ;p # # - Update issues will go away in 0.11.0 (see musicpd.org) due to # update being non-blocking from there on out (hopefully ;p) # ######################################################################## # You don't need to edit below this unless you know what you're doing :) ######################################################################## use File::Basename; use Irssi; use Irssi::TextUI; use strict; use vars qw($VERSION %ENABLED %SAVE_VARS %IRSSI %COUNT %SET); $VERSION = '0.0.0o'; %IRSSI = ( authors => 'Santabutthead', contact => 'starz@antisocial.com', name => 'iMPD', description => 'This controls Music Player Daemon from the familiar irssi interface', sbitems => 'mpdbar', license => 'GPL v2', url => 'http://www.musicpd.org' ); # Create $SET{'mpc_override'}="/outside/path" if mpc's not in your path ### DO NOT EDIT THESE! Use /set mpd_host /set mpd_port ### $SET{'port'} = "2100"; $SET{'host'} = "127.0.0.1"; ### Let's go ahead and set this up, so irssi doesn't have a tantrum ### Irssi::signal_add('setup changed' => \&read_settings); Irssi::settings_add_bool('misc', 'mpdbar_bottom', 0); Irssi::settings_add_bool('misc', 'mpdbar_top', 0); Irssi::settings_add_bool('misc', 'mpdbar_window', 0); Irssi::settings_add_bool('misc', 'current_window', '0'); Irssi::settings_add_int('misc', 'output_window', '1'); Irssi::settings_add_int('misc', 'mpd_port', '2100'); Irssi::settings_add_str('misc', 'mpd_host', '127.0.0.1'); Irssi::signal_add_first('command script unload', \&cleanup); Irssi::signal_add_first('command script load', \&cleanup); Irssi::signal_add('setup changed' => \&mpdbar_refresh); # Keep the $2- to treat spaces right Irssi::statusbar_item_register('mpdbar', '{sb $0 $1 $2-}', 'mpdbar_setup'); Irssi::statusbars_recreate_items(); ####################################################################### print "For usage information on iMPD type /mhelp"; sub add { if ($_[0]) { &read_settings; my $j; ¤t_window; if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) { my @i = split / /, $_[0]; $j = $i[0]; $_[0] =~ s/^(\w+)\s//; } else { $j = "filename"; } Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add" ); &set_active; } else { print "%W/madd (album|artist|filename|title) {search term} {search term}..%w"; print " - Search for {search term} and automagically add it to the end of the queue"; print " - This command does not support play number. (it doesn't make sense)"; print " - If not specified it will use filename by default"; } } sub addall { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} add \"\"" ); &set_active; } sub addallPlay { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} add \"\" && $SET{'intrashell'} play" ); &mpdbar_refresh; # Impatience &set_active; } sub addallShufflePlay { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} add \"\" && $SET{'intrashell'} shuffle && $SET{'intrashell'} play" ); &mpdbar_refresh; # Impatience &set_active; } sub addNext { # This does not work yet, but doesn't hurt being here until it does :) if ($_[0]) { &read_settings; my $j; ¤t_window; &song_count; if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) { my @i = split / /, $_[0]; $j = $i[0]; $_[0] =~ s/^(\w+)\s//; } else { $j = "filename"; } Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add" ); my $new_pos =~ $COUNT{'song'}++; my $playcount =~ $COUNT{'playlist'}++; Irssi::command( "$SET{'intrairssi'} mpc $playcount $new_pos"); #random detect stuff here; &set_active; } else { print "%W/maddnext (album|artist|filename|title) {search term} {search term}..%w"; print " - Search for {search term} and automagically add it to the next position in"; print " - the queue. This command does not support play number. (it doesn't make sense)"; print " - If not specified it will use filename by default"; } } sub addPlay { if ($_[0]) { &read_settings; my $j; ¤t_window; if ($_[0]=~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) { my @i = split / /, $_[0]; $j = $i[0]; $_[0] =~ s/^(\w+)\s//; } else { $j = "filename"; } Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} play" ); &mpdbar_refresh; # Impatience &set_active; } else { print "%W/map (add play) (album|artist|filename|title) {search term} {search term}..%w"; print " - Search for {search term} and automagically add it to the end of the queue"; print " - This command does not support play number. (it doesn't make sense)"; print " - If not specified it will use filename by default"; } } sub addShuffle { if ($_[0]) { &read_settings; my $j; ¤t_window; if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) { my @i = split / /, $_[0]; $j = $i[0]; $_[0] =~ s/^(\w+)\s//; } else { $j = "filename"; } Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} shuffle" ); &set_active; } else { print "%W/mas (add shuffle) (album|artist|filename|title) {search term} {search term}..%w"; print " - Search for {search term} and automagically add it to the end of the queue"; print " - This command does not support play number. (it doesn't make sense)"; print " - If not specified it will use filename by default"; } } sub addShufflePlay { if ($_[0]) { &read_settings; my $j; ¤t_window; if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) { my @i = split / /, $_[0]; $j = $i[0]; $_[0] =~ s/^(\w+)\s//; } else { $j = "filename"; } Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} shuffle && $SET{'intrashell'} play" ); &mpdbar_refresh; # Impatience &set_active; } else { print "%W/masp (add shuffle play) (album|artist|filename|title) {search term} {search term}..%w"; print " - Search for {search term} and automagically add it to the end of the queue"; print " - This command does not support play number. (it doesn't make sense)"; print " - If not specified it will use filename by default"; } } sub cleanup { my ($file) = Irssi::get_irssi_dir."/iMPD.conf"; open CONF, ">", $file; for my $net (sort keys %SAVE_VARS) { print CONF "$net\t$SAVE_VARS{$net}\n"; close CONF; } Irssi::command( "statusbar mpdbar disable" ); } sub clear { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} clear" ); &mpdbar_refresh; # Impatience &set_active; } sub clearAddAllPlay { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} clear && $SET{'intrashell'} add \"\" && $SET{'intrashell'} play" ); &mpdbar_refresh; # Impatience &set_active; } sub clearAddAllShufflePlay { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} clear && $SET{'intrashell'} add \"\" && $SET{'intrashell'} shuffle && $SET{'intrashell'} play" ); &mpdbar_refresh; # Impatience &set_active; } sub clearAddPlay { if ($_[0]) { &read_settings; my $j; ¤t_window; if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) { my @i = split / /, $_[0]; $j = $i[0]; $_[0] =~ s/^(\w+)\s//; } else { $j = "filename"; } Irssi::command( "$SET{'intrairssi'} clear && $SET{'intrashell'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} play" ); &mpdbar_refresh; # Impatience &set_active; } else { print "%W/mcap (clear add play) (album|artist|filename|title) {search term} {search term}..%w"; print " - Search for {search term} and automagically add it to the end of the queue"; print " - This command does not support play number. (it doesn't make sense)"; print " - If not specified it will use filename by default"; } } sub clearAddShufflePlay { if ($_[0]) { &read_settings; my $j; ¤t_window; if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) { my @i = split / /, $_[0]; $j = $i[0]; $_[0] =~ s/^(\w+)\s//; } else { $j = "filename"; } Irssi::command( "$SET{'intrairssi'} clear && $SET{'intrashell'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} shuffle && $SET{'intrashell'} play" ); &mpdbar_refresh; # Impatience &set_active; } else { print "%W/mcasp (clear add shuffle play) (album|artist|filename|title) {search term} {search term}..%w"; print " - Search for {search term} and automagically add it to the end of the queue"; print " - This command does not support play number. (it doesn't make sense)"; print " - If not specified it will use filename by default"; } } sub clearback { &read_settings; &song_count; ¤t_window; Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'}" ); &set_active; } sub crossfade { &read_settings; if ($_[0] =~ m/\d{1,4}/) { ¤t_window; Irssi::command( "$SET{'intrairssi'} crossfade $_[0]" ); &mpdbar_refresh; # Impatience &set_active; } else { print "%W/mcrossfade %w- Number of seconds to crossfade between songs"; } } sub current_status{ &read_settings; ¤t_window; my $i = `$SET{'intrashell'}`; chomp($i); $SET{'active'}->print( $i ); &set_active; return; } sub current_window { $SET{'active'} = Irssi::active_win(); if (! $SET{'current'}) { Irssi::window_find_refnum($SET{'output'})->set_active; } } sub delete { if($_[0]) { my (@i,$j,$k); @i = split / /, $_[0]; $j = shift(@i); &read_settings; ¤t_window; # You may ask why? This is for the future when del (hopefully) has useful output $k = "$SET{'intrairssi'} playlist | grep \"$j\" | $SET{'intrashell'} del"; $_[0] =~ s/^(\w+)\s//; $k = "$k && $SET{'intrashell'} playlist | grep \"$_[0]\" | $SET{'intrashell'} del"; Irssi::command( "$k" ); &set_active; } else { print"%W/mdel {search term} {search term}..%w"; print" - Search for {search term} and automagically"; print" - delete it from the queue"; } } sub iMPD_help { my $mpd_help = < %w- Starts MPD (with optional number of song to start on) %W/mprev %w- Previous Song %W/mstop %w- Stops the current playlist, options are minutes, hours and days, seconds are the default %W/mupdate %w- Update MPD Database %W/mvolume (0-100) %w- Sets the volume on the OSS mixer to (0-100) %r---=[ %WSearch Commands %r]=---%w %W/madd (album|artist|filename|title) {search term} {search term} ..%w %w- Search for {search term} and automagically add it to the end of the queue, upto 5 search terms - If not specified it will use filename by default %W/mdel {search term} {search term} ..%w %w- Search for {search term} and automagically delete it from the queue %W/msearch (album|artist|filename|title) {search term} {search term}..%w %w- Search for {search term} - If not specified it will use filename by default %r---=[ %WNavigation/Playlist Commands %r]=---%w %W/maddall %w- Add all known music to the playlist %W/mclear %w- Clear the current playlist %W/mclearback %w- Clears all songs before the current playing song %W/mcrossfade %w- Number of seconds to crossfade between songs %W/mls [] %w- Lists all files/folders in %W/mmove %w- Move song on playlist %W/mplaylist %w- Print entire playlist if there's no range - Otherwise will print the range (i.e. 1-10) %W/mplaylistls %w- List available playlists %W/mplaylistload %w- Load playlist %W/mplaylistrm %w- Remove (delete) playlist %W/mplaylistsave %w- Save playlist %W/mpls {search term} {search term}...%w %w- Playlist search {search term} %W/mseek %w- Seeks to the spot specified for the current file, in terms of percent time (0-100) %W/mshuffle %w- Shuffle the MPD playlist %W/mrandom %w- Play the playlist randomly %W/mwipe %w- Remove all songs but the one currently playing %r---=[ %WMiscellaneous Commands %r]=---%w %W/mhelp %w- This screen %W/mloud %w- Show everyone in the current window the MPD stats %W/mlouder %w- Show everyone in the current window the MPD stats *use with caution* %W/minfo %w- Show MPD Status in the status window %W/mrm .. %w- Remove song from the current playlist (by number %w- or number range) See Also: /mhelpadv /mhelpmpdbar /set mpd_host mpd_port /set mpd_current_window mpd_output_window (EXPERIMENTAL) MPD_HELP print $mpd_help; } sub iMPD_helpAdv{ my $mpd_help_advanced = <) { my($net,$val) = split; if ($net && $val) { $SAVE_VARS{$net} = $val; } close CONF; } } # For those who want to be loud/annoying :) sub loud { &read_settings; my ($i,$j); my @split = `$SET{'intrashell'}`; if (! $split[1]) { Irssi::print( "iMPD is not currently playing" ); return; } $i = basename $split[0]; $i =~ s/[_]/ /g; # Feel free to put your personal PERL regexps here ;p # Experiment with these to do some wicked stuff to your loud output. # $i =~ s/.mp3//ig; # $i =~ s/.flac//ig; # $i =~ s/.flc//ig; # $i =~ s/.ogg//ig; # $i =~ s/^\p{0,2}//; # $i =~ s/[.]//g; $i = substr($i,0,-1); Irssi::active_win->command( "/me is listening to $i" ); close Reader; } sub louder { &read_settings; my @split=`$SET{'intrashell'}`; chomp(@split); Irssi::active_win->command( "/say $split[0]" ); Irssi::active_win->command( "/say $split[1]" ); Irssi::active_win->command( "/say $split[2]" ); close Reader; } sub ls { if ($_[0]) { &read_settings; ¤t_window; $_[0] =~ "\Q$_[0]\E"; $_[0] =~ s/^\\//; # Rid of beginning / it doesn't delimit correctly. $_[0] =~ s/\///; # Help out the degenerates. Irssi::command( "$SET{'intrairssi'} ls " . "\Q$_[0]\E" ); &set_active; } else { print "%W/mls [] %w- Lists all files/folders in ."; } } sub lsplaylists { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} lsplaylists" ); &set_active; } sub move { &read_settings; if ($_[0] =~ m/\d{1,2}\s{1,2}/) { ¤t_window; Irssi::command( "$SET{'intrairssi'} move $_[0]" ); &mpdbar_refresh; # Impatience &set_active; } else { print "%W/mmove %w- Move song on playlist"; } } sub mpdbar_help { my $mpdbarhelp = < - This command will set the refresh in seconds, it defaults to 5 seconds, you might be able to set it higher although I don't recommend setting it higher if your mpd server is across a network (of any kind ;p). /set mpdbar_top on This command will (obviously) display a mpdbar on the top. /set mpdbar_window on This command will (not-so-obviously) display a mpdbar next to your current window statusbar. MPDBAR_HELP print $mpdbarhelp; } sub mpdbar_get_stats { ### Variable map ### # $SET{'stat_time'}-Time/Percent(change) # $SET{'stat_current'}-Status(change) # $SET{'songbase'}-basename filename if(Irssi::settings_get_bool('mpdbar_bottom') or Irssi::settings_get_bool('mpdbar_top') or Irssi::settings_get_bool('mpdbar_window')) { &read_settings; ($SET{'stat1'},$SET{'stat2'},$SET{'stat3'}) = undef; ($SET{'stat1'},$SET{'stat2'},$SET{'stat3'}) = `$SET{'intrashell'}`; chomp($SET{'stat1'},$SET{'stat2'},$SET{'stat3'}); if ($SET{'stat2'} =~ m/(\d{1,5}\:\d{1,2}\s\(\d{1,3}\%\))/) { $SET{'stat_time'} = $1; } if ($SET{'stat2'} =~ m/\[(\w+)\]/) { $SET{'stat_current'} = $1; } if($SET{'stat2'} and $SET{'stat1'} =~ m/\//g) { # Not sure if this will have an effect :/ $SET{'songbase'} = basename $SET{'stat1'}; } else { $SET{'songbase'} = $SET{'stat1'}; } } } sub mpdbar_refresh { if(Irssi::settings_get_bool('mpdbar_bottom') or Irssi::settings_get_bool('mpdbar_top') or Irssi::settings_get_bool('mpdbar_window')) { &mpdbar_get_stats; if (Irssi::settings_get_bool('mpdbar_bottom') and Irssi::settings_get_bool('mpdbar_top')) { Irssi::print( "Have not implemented ability to mpdbar top and bottom at the same time" ); Irssi::print( "That's fine though, I'll just set it to the bottom for you for now" ); Irssi::settings_set_bool('mpdbar_bottom',1); Irssi::settings_set_bool('mpdbar_top',0); } if (Irssi::settings_get_bool('mpdbar_window') and $SET{'stat2'}) { $ENABLED{'window'} = "1"; Irssi::command( "statusbar window add mpdbar" ); Irssi::command( "statusbar window enable mpdbar" ); } else { if($ENABLED{'window'} == 1) { Irssi::command( "statusbar window remove mpdbar" ); $ENABLED{'window'} = 0; } } if (Irssi::settings_get_bool('mpdbar_bottom') and $SET{'stat2'} and ! $ENABLED{'top'}) { $ENABLED{'bottom'} = "1"; Irssi::command( "statusbar mpdbar placement bottom" ); Irssi::command( "statusbar mpdbar position 2" ); Irssi::command( "statusbar mpdbar enable" ); Irssi::command( "statusbar mpdbar add mpdbar" ); Irssi::command( "statusbar mpdbar visible active" ); } else { if($ENABLED{'bottom'} == 1){ Irssi::command( "statusbar mpdbar remove mpdbar" ); Irssi::command( "statusbar mpdbar disable" ); $ENABLED{'bottom'} = 0; } } if (Irssi::settings_get_bool('mpdbar_top') and $SET{'stat2'} and ! $ENABLED{'bottom'}) { $ENABLED{'top'} = "1"; Irssi::command( "statusbar mpdbar placement top" ); Irssi::command( "statusbar mpdbar position 2" ); Irssi::command( "statusbar mpdbar enable" ); Irssi::command( "statusbar mpdbar add mpdbar" ); Irssi::command( "statusbar mpdbar visible active" ); } else { if($ENABLED{'top'} == 1){ Irssi::command( "statusbar mpdbar remove mpdbar" ); Irssi::command( "statusbar mpdbar disable" ); $ENABLED{'top'} = 0; } } } } sub mpdbar_setup { my ($item, $get_size_only) = @_; if (! $SET{'stat2'}) { # If it's not on $item->default_handler($get_size_only, undef, "$SET{'stat2'}", 1); } else { $SET{'stat_current'} =~ s/$SET{'stat_current'}/\u\L$SET{'stat_current'}/; $item->default_handler($get_size_only, undef, "$SET{'stat_current'} $SET{'songbase'} $SET{'stat_time'}", 1); } } sub mute { &read_settings; ¤t_window; my @i = `$SET{'intrashell'}`; my $j; # This next conditional is for when the music is not playing if (exists $i[2]) { $j = $i[2]; } else { $j = $i[0]; } if ($j =~ m/volume\:\s{0,2}(\d{1,3})\%/) { $j = $1; } if ($j != 0 and ! $SAVE_VARS{'muted'} == 0) { print "Warning: Not currently muted, although it said it was"; delete $SAVE_VARS{'muted'} } if ($j == 0 and ! $SAVE_VARS{'muted'}) { print "Error: Volume is currently muted, but I don't know how it got there. Manually set the volume please."; delete $SAVE_VARS{'muted'}; } if (!$SAVE_VARS{'muted'}) { $SAVE_VARS{'muted'} = $j; `$SET{'intrashell'} volume 0`; print "Sound is muted, to unmute just hit /mmute again"; } else { `$SET{'intrashell'} volume $SAVE_VARS{'muted'}`; print "Reset the volume back to it's originial position ($SAVE_VARS{'muted'}%)"; delete $SAVE_VARS{'muted'}; } } sub next { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} next" ); &set_active; &mpdbar_refresh; # Impatience } sub pause { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} pause" ); &mpdbar_refresh; # Impatience &set_active; } sub play { &read_settings; my $i; ¤t_window; if ($_[0] =~ m/\d{1,6}/) { $i = $_[0]; } Irssi::command( "$SET{'intrairssi'} play $i" ); &mpdbar_refresh; # Impatience &set_active; } sub playlist { &read_settings; my @playlist; if ($_[0] =~ m/\d{1,6}\-\d{1,6}/) { my ($head,$tail); my @playlist = `$SET{'intrashell'} playlist`; ($head, $tail) = split /-/, $_[0]; # OK, just understand I'm here for you if you're # tired enough to let this happen to you. if($head > $tail) { my $i; $i = $head; $head = $tail; $tail = $i; } $head =~ $head--; $tail = $tail - $head; chomp $head; chomp $tail; @playlist = splice(@playlist,$head,$tail); my $i = pop(@playlist); chomp $i; push (@playlist,$i); print @playlist; } else { ¤t_window; Irssi::command( "$SET{'intrairssi'} playlist" ); &set_active; } } sub playlist_load { if ($_[0]) { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} load \Q$_[0]\E" ); &set_active; } else { print "%W/mplaylistload %w- Load playlist "; } } sub playlist_remove { if ($_[0]) { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} rm \Q$_[0]\E" ); &set_active; } } sub playlist_save { if ($_[0]) { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} save \Q$_[0]\E" ); &set_active; } else { print "%W/mplaylistsave %w- Save playlist "; } } sub playlistsearch { if ($_[0]) { &read_settings; my @i = split / /, $_[0]; ¤t_window; foreach(@i) { Irssi::command( "$SET{'intrairssi'} playlist | grep $_" ); } &set_active; } else { print "%W/pls {search term} {search term}..%w"; print " - Search for {search term} and automagically and show the playlist entry"; } } sub previous { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} prev" ); &mpdbar_refresh; # Impatience &set_active; } sub random{ &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} random" ); &set_active; } sub read_settings { ($SET{'mbar_time'}) && Irssi::timeout_remove($SET{'mbar_time'}); $SET{'mbar_time'}=Irssi::timeout_add(Irssi::settings_get_int('mpdbar_refresh') * 1000, 'mpdbar_refresh', undef); $SET{'current'} = Irssi::settings_get_bool('current_window'); $SET{'output'} = Irssi::settings_get_int('output_window'); if (Irssi::settings_get_int( "mpd_port" )) { $SET{'port'} = Irssi::settings_get_int( "mpd_port" ); $SET{'port'} = "MPD_PORT=$SET{'port'}" } if (Irssi::settings_get_str( "mpd_host" )) { $SET{'host'} = Irssi::settings_get_str( "mpd_host" ); $SET{'host'} = "MPD_HOST=$SET{'host'}" } my $MPC_BIN; if ( ! -x $SET{'mpc_override'} ) { my @paths = split/:/,$ENV{'PATH'}; foreach(@paths) { my $path = $_; if( -x "$path" . "/" . "mpc" ) { $MPC_BIN = "$path/mpc"; } } } else { $MPC_BIN = $SET{'mpc_override'}; } if (! $MPC_BIN) { print "mpc was not found in any of the known paths"; print "mpc is required to use this script, please download it from http://musicpd.org/files.php"; } $SET{'intrashell'} = "$SET{'port'} $SET{'host'} $MPC_BIN"; $SET{'intrairssi'} = "exec - $SET{'intrashell'}"; } sub repeat { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} repeat" ); &set_active; } sub remove_song { &read_settings; if ($_[0] =~ m/\d{1,6}/ or $_[0] =~ m/\d{1,6}\-\d{1,6}/) { ¤t_window; Irssi::command( "$SET{'intrairssi'} del $_[0]" ); &mpdbar_refresh; # Impatience &set_active; } else { print "%W/mrm .. %w- Remove song from the current playlist (by number)"; print "%w - Note that can be a range also"; } } sub search { if ($_[0]) { &read_settings; my $j; ¤t_window; if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) { my @i = split / /, $_[0]; $j = $i[0]; $_[0] =~ s/^(\w+)\s//; } else { $j = "filename"; } Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E" ); &set_active; } else { print "%W/search (album|artist|filename|title) {search term} {search term}..%w"; print " - Search for {search term} and automagically add it to the end of the queue"; print " - If not specified it will use filename by default"; } } sub seek { &read_settings; if ($_[0] =~ m/\d{1,3}/) { ¤t_window; Irssi::command( "$SET{'intrairssi'} seek $_[0]" ); &mpdbar_refresh; # Impatience &set_active; } else { print "%W/mseek %w- Seeks to the spot specified for the current file, in terms of percent time (0-100)"; } } sub set_active { if (! $SET{'current'}) { $SET{'active'}->set_active; } } sub shuffle{ &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} shuffle" ); &set_active; } sub song_count { %COUNT = undef; my @counts = `$SET{'intrashell'}`; chomp(@counts); if ($counts[1] =~ m/\#(\d{1,6})\//) { $COUNT{'song'} = $1; } if ($counts[1] =~ m/\/(\d{1,6})\s/) { $COUNT{'playlist'} = $1; } if ($COUNT{'song'} > 1) { my $i = $COUNT{'song'} - 1; $COUNT{'sr1'} = "1-$i"; } if ($COUNT{'song'} < $COUNT{'playlist'}){# and $COUNT{'song'} != $COUNT{'playlist'}) { my $i = $COUNT{'song'} + 1; $COUNT{'sr2'} = "$i-$COUNT{'playlist'}"; } } sub stop { &read_settings; my ($i,$time); if ($_[0]) { my $unit; ($time, $unit) = split / /, $_[0]; if ($unit =~ /minute/i or $unit =~ /minutes/i) { $time = ($time * 60); } if ($unit =~ /hour/i or $unit =~ /hours/i) { $time = ($time * 86400); } #ok. it's ridiculous to use this script for days, but in any case here ya go. if ($unit =~ /day/i or $unit =~ /days/i) { $time = ($time * 2073600); } $time = $time . "s"; $i = "exec - /bin/sleep $time && $SET{'intrashell'} stop"; } else { $i = "$SET{'intrairssi'} stop"; } ¤t_window; Irssi::command( "$i" ); &mpdbar_refresh; # Impatience &set_active; } sub update { &read_settings; ¤t_window; Irssi::command( "$SET{'intrairssi'} update" ); Irssi::print( "Irssi will not be accepting commands while updating" ); &set_active; } sub volume { &read_settings; ¤t_window; my (@i,$j); if ($_[0] =~ m/\d{1,3}/) { @i = `$SET{'intrashell'} volume $_[0]`; } else { @i = `$SET{'intrashell'}`; } # This next conditional is for when the music is not playing if (exists $i[2]) { $j = $i[2]; } else { $j = $i[0]; } if ($j =~ m/volume\:\s{0,2}(\d{1,3})\%/) { $j = $1; } # OK, if anyone wants to tell me _why_ this seems to be the only way # to get a "%" on the end please feel free (suspected to be due to # color codes if ($_[0]) { Irssi::print( "The volume is at $j%" . "%" ); } else { $SET{'active'}->print( "The volume is at $j%" . "%" ); } &set_active; } sub wipe { &read_settings; ¤t_window; &song_count; if($COUNT{'sr1'} or $COUNT{'sr2'}) { Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'} $COUNT{'sr2'}" ); } else { Irssi::print( "Can't wipe when there's only one song in the playlist" ); } &set_active; } sub wipeAdd{ if ($_[0]) { &read_settings; &song_count; my $j; if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) { my @i = split / /, $_[0]; $j = $i[0]; $_[0] =~ s/^(\w+)\s//; } else { $j = "filename"; } ¤t_window; if($COUNT{'sr1'} or $COUNT{'sr2'}) { Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'} $COUNT{'sr2'} && $SET{'intrashell'} search $j \Q$_[0]\E | $SET{'intrashell'} add" ); } else { # Do the thinking for the person Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add" ); } &set_active; } else { print "%W/mwa (wipe add) (album|artist|filename|title) {search term} {search term}..%w"; print " - Search for {search term} and automagically add it to the end of the queue"; print " - This command does not support play number. (it doesn't make sense)"; print " - If not specified it will use filename by default" } } sub wipeAddall{ &read_settings; &song_count; ¤t_window; if($COUNT{'sr1'} or $COUNT{'sr2'}) { Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'} $COUNT{'sr2'} && $SET{'intrashell'} add \"\"" ); } else { Irssi::command( "$SET{'intrairssi'} add \"\"" ); } &set_active; } sub wipeAddallShuffle{ &read_settings; &song_count; ¤t_window; if($COUNT{'sr1'} or $COUNT{'sr2'}) { Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'} $COUNT{'sr2'} && $SET{'intrashell'} add \"\" && $SET{'intrashell'} shuffle" ); } else { Irssi::command( "$SET{'intrairssi'} add \"\" && $SET{'intrashell'} shuffle" ); } &set_active; } sub wipeAddShuffle{ if ($_[0]) { &read_settings; my $j; if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) { my @i = split / /, $_[0]; $j = $i[0]; $_[0] =~ s/^(\w+)\s//; } else { $j = "filename"; } &song_count; ¤t_window; if($COUNT{'sr1'} or $COUNT{'sr2'}) { Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'} $COUNT{'sr2'} && $SET{'intrashell'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} shuffle" ); } else { Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} shuffle" ); } &set_active; } else { print "%W/mwas (wipe add shuffle) (album|artist|filename|title) {search term} {search term}..%w"; print " - Search for {search term} and automagically add it to the end of the queue"; print " - This command does not support play number. (it doesn't make sense)"; print " - If not specified it will use filename by default"; } } Irssi::settings_add_int('misc', 'mpdbar_refresh', '5'); &load_settings; &mpdbar_refresh; Irssi::command_bind madd => \&add; Irssi::command_bind maddall => \&addall; # Irssi::command_bind maddnext => \&addNext; Irssi::command_bind maap => \&addallPlay; Irssi::command_bind maasp => \&addallShufflePlay; Irssi::command_bind mas => \&addShuffle; Irssi::command_bind masp => \&addShufflePlay; Irssi::command_bind map => \&addPlay; Irssi::command_bind mclear => \&clear; Irssi::command_bind mclearback => \&clearback; Irssi::command_bind mcaap => \&clearAddAllPlay; Irssi::command_bind mcaasp => \&clearAddAllShufflePlay; Irssi::command_bind mcap => \&clearAddPlay; Irssi::command_bind mcasp => \&clearAddShufflePlay; Irssi::command_bind mdel => \&delete; Irssi::command_bind mls => \&ls; Irssi::command_bind mhelp => \&iMPD_help; Irssi::command_bind mhelpadv => \&iMPD_helpAdv; Irssi::command_bind minfo => \¤t_status; Irssi::command_bind mloud => \&loud; Irssi::command_bind mlouder => \&louder; Irssi::command_bind mmute => \&mute; Irssi::command_bind mnext => \&next; Irssi::command_bind mpause => \&pause; Irssi::command_bind mhelpmpdbar => \&mpdbar_help; Irssi::command_bind mmove => \&move; Irssi::command_bind mplay => \&play; Irssi::command_bind mplaylist => \&playlist; Irssi::command_bind mpls => \&playlistsearch; Irssi::command_bind mplaylistls => \&lsplaylists; Irssi::command_bind mplaylistload => \&playlist_load; Irssi::command_bind mplaylistrm => \&playlist_remove; Irssi::command_bind mplaylistsave => \&playlist_save; Irssi::command_bind mprev => \&previous; Irssi::command_bind mrandom => \&random; Irssi::command_bind mrepeat => \&repeat; Irssi::command_bind mrm => \&remove_song; Irssi::command_bind mseek => \&seek; Irssi::command_bind msearch => \&search; Irssi::command_bind mshuffle => \&shuffle; Irssi::command_bind mstop => \&stop; Irssi::command_bind mupdate => \&update; Irssi::command_bind mvolume => \&volume; Irssi::command_bind mwa => \&wipeAdd; Irssi::command_bind mwaa => \&wipeAddall; Irssi::command_bind mwaas => \&wipeAddallShuffle; Irssi::command_bind mwas => \&wipeAddShuffle; Irssi::command_bind mwipe => \&wipe;