/var/www/www.irssi.org-old/scripts/html/amarok_ssh.pl


   1 # amarok by Tobias 'camel69' Wulff
   2 
   3 use strict;
   4 use vars qw($VERSION %IRSSI);
   5 $VERSION = "1.0";
   6 %IRSSI = (
   7     authors     => "Tobias 'camel69' Wulff",
   8     contact     => "camel69(at)codeeye.de",
   9     name        => "amaroK (via ssh)",
  10     description => "Retrievs song infos and controls amaroK via dcop, optionally running on another computer via ssh",
  11     license     => "Public Domain",
  12     commands	=> "amarok",
  13     url		=> "http://www.codeeye.de/irssi/"
  14 );
  15 
  16 use Irssi;
  17 
  18 Irssi::settings_add_bool('amarok', 'amarok_use_ssh', 1);
  19 Irssi::settings_add_str('amarok', 'amarok_ssh_client', 'localhost');
  20 Irssi::settings_add_str('amarok', 'amarok_dcop_user', '');
  21 
  22 sub show_help() {
  23     my $help = $IRSSI{name}." ".$VERSION."
  24 /amarok song [loud]
  25         Prints the artist and title of the song which is currently played.
  26         If the argument loud is given, all users in the current channel can
  27         see what song you are currently listening.
  28 /amarok time [loud]
  29         Prints the total time of the song as well as the played time
  30         and remaining time. Same behaviour for given argument loud
  31         as above.
  32 /amarok pause
  33         Pauses (or unpauses) the current song.
  34 /amarok play
  35         Plays the current song (again).
  36 /amarok stop
  37         Stops the current song.
  38 /amarok next
  39         Skips to the next song.
  40 /amarok prev
  41         Skips to the previous song.
  42 /amarok seek [+|-]secs|min:secs
  43         Seeks to the given position. If + or - is given amaroK seeks
  44         relatively the amount of minutes and/or seconds to the
  45         current position.
  46 /amarok vol [0 to 100]
  47         Prints or changes the output volume of amaroK.
  48 /amarok mute
  49         Toggles between volume 0 and the last used volume.
  50 /amarok help
  51         Prints this help text.
  52 
  53 Settings you can change with /SET
  54         amarok_use_ssh:    Enable or disable remote amaroK'ing
  55         amarok_ssh_client: IP or hostname of the remote pc
  56         amarok_dcop_user:  user who is running dcop and amaroK";
  57     
  58     print CLIENTCRAP $help;
  59 }
  60 
  61 my $preprint = '%Bamarok%n> ';
  62 
  63 # Load settings
  64 my $amarok_use_ssh = Irssi::settings_get_bool('amarok_use_ssh');
  65 my $ssh_client = Irssi::settings_get_str('amarok_ssh_client');
  66 my $dcop_user = Irssi::settings_get_str('amarok_dcop_user');
  67 
  68 sub cmd ($) {
  69     my ($postcmd) = @_;
  70     my $dcop_precmd = 'dcop --user '.$dcop_user.' amarok player';
  71 
  72     if ($amarok_use_ssh == 1) {
  73         #print "ssh ".$ssh_client." '".$dcop_precmd." ".$postcmd."'";
  74         return `ssh $ssh_client '$dcop_precmd $postcmd'`;
  75     } else {
  76         #print $dcop_precmd.' '.$postcmd;
  77         return `$dcop_precmd $postcmd`;
  78     }
  79 }
  80 
  81 sub amarokSong ($$) {
  82     my($witem, $me_cmd) = @_;
  83     if ($me_cmd == 1) {
  84         if (!$witem or $witem->{type} ne 'CHANNEL') {
  85 	    print CLIENTCRAP $preprint."The option 'loud' can only be used in channels.";
  86             return;
  87 	}
  88     }
  89     
  90     my $artist = cmd('artist');
  91     my $title = cmd('title');
  92     my $text = 'listening to '.$artist.' - '.$title;
  93     $text =~ s/\n//g;
  94 
  95     if ($me_cmd == 1) {
  96         $witem->command("ME is ".$text);
  97     } else {
  98         print CLIENTCRAP $preprint.$text;
  99     }
 100 }
 101 
 102 sub amarokTime($$) {
 103     my ($witem, $me_cmd) = @_;
 104     if ($me_cmd == 1 and (!$witem or $witem->{type} ne 'CHANNEL')) {
 105         print CLIENTCRAP $preprint."The option 'loud' can only be used in channels.";
 106         return;
 107     }
 108     
 109     # Zeiten in Sekunden holen
 110     my $time_total_secs = cmd('trackTotalTime');
 111     my $time_played_secs = cmd('trackCurrentTime');
 112     my $time_remaining_secs = $time_total_secs - $time_played_secs;
 113 
 114     # Zeiten in richtige Minutenangabe umwandeln
 115     my @time_total = (0, $time_total_secs % 60);
 116     $time_total[0] = ($time_total_secs - $time_total[1]) / 60;
 117     my @time_played = (0, $time_played_secs % 60);
 118     $time_played[0] = ($time_played_secs - $time_played[1]) / 60;
 119     my @time_remaining = (0, $time_remaining_secs % 60);
 120     $time_remaining[0] = ($time_remaining_secs - $time_remaining[1]) / 60;
 121 
 122     # Text bauen und ausgeben
 123     # Gesamtzeit
 124     my $text = 'Total time of track is '.$time_total[0].':';
 125     if ($time_total[1] < 10) { $text .= '0'; }
 126     $text .= $time_total[1];
 127 
 128     # Gespielte Zeit
 129     $text .= ' (played: '.$time_played[0].':';
 130     if ($time_played[1] < 10) { $text .= '0'; }
 131     $text .= $time_played[1];
 132     
 133     # Verbleibende Zeit
 134     $text .= ' / remaining: '.$time_remaining[0].':';
 135     if ($time_remaining[1] < 10) { $text .= '0'; }
 136     $text .= $time_remaining[1].')';
 137     
 138     if ($me_cmd == 1) {
 139         $witem->command("SAY ".$text);
 140     } else {
 141         print CLIENTCRAP $preprint.$text;
 142     }
 143 }
 144 
 145 sub amarokSeek ($) {
 146     my($time) = @_;
 147     
 148     # format correct?
 149     # just seconds: + or -, some numbers (seconds)
 150     # mm:ss format: + or -, some numbers (minutes), :, 2 numbers (seconds)
 151     if ($time !~ /^(\+|-)?[0-9]+$/ and
 152         $time !~ /^(\+|-)?[0-9]+:[0-9]{2}$/) {
 153         print CLIENTCRAP $preprint.'%RERROR%n: Wrong time format (see help for correct format)!';
 154 	return;
 155     }
 156     
 157     my $origtime = cmd('trackCurrentTime');
 158 
 159     # Assume there's no + or -
 160     my $seek_sign = '';
 161     
 162     # Check for + or - in $time
 163     # If a sign is found save it in $seek_sign and remove
 164     # it from $time.
 165     $_ = $time;
 166     if (/^\+/) {
 167 	$seek_sign = '+';
 168 	$time =~ s/^\+//g;
 169     } elsif (/^-/) {
 170 	$seek_sign = '-';
 171 	$time =~ s/^-//g;
 172     }
 173 
 174     # Now split $timearg at ':' if there's one
 175     my @timeparts = split(/:/, $time);
 176 
 177     # time has format mm:ss
 178     if (defined $timeparts[1]) {
 179 	# Convert $time into secs
 180         $time = 60 * $timeparts[0] + $timeparts[1];
 181     }
 182 
 183     # if there's a + or - recalc $time
 184     if ($seek_sign eq '+') {
 185         $time = $origtime + $time;
 186     } elsif ($seek_sign eq '-') {
 187         $time = $origtime - $time;
 188     }
 189     
 190     # print and do it
 191     cmd('seek '.$time);
 192     my $newtime = cmd('currentTime');
 193     chomp($newtime);
 194     print CLIENTCRAP $preprint.'Seeked to '.$newtime.'.';
 195 }
 196 
 197 sub cmd_amarok ($$$) {
 198     my ($args, $server, $witem) = @_;
 199     my @arg = split(/ /, $args);
 200     
 201     # enough arguments?
 202     if (scalar(@arg) == 0) {
 203         print CLIENTCRAP $preprint.'%RERROR%n: not enough arguments!';
 204 	return;
 205     }
 206 
 207     my $loud = 0;
 208     if (defined $arg[1] && $arg[1] eq 'loud') { $loud = 1; }
 209     
 210     # is amaroK running?
 211     # if so, is it currently playing?
 212     # status = 0: stopped
 213     #        = 1: paused
 214     #        = 2: playing
 215     my $status = cmd('status');
 216     if ($status eq 'call failed') {
 217         print CLIENTCRAP $preprint.'%RERROR%n: amaroK is not running!';
 218 	return;
 219     } elsif ($status == 0 && $arg[0] ne 'play' && $arg[0] ne 'help' && $arg[0] ne 'vol' && $arg[0] ne 'mute') {
 220         print CLIENTCRAP $preprint.'%RERROR%n: amaroK is not playing yet!';
 221 	print CLIENTCRAP $preprint.'Only the play, vol, mute and help commands are available.';
 222 	return;
 223     }
 224     
 225     # amaroK is running and playing or some commands are available though.
 226     if ($arg[0] eq 'song') {
 227         amarokSong($witem, $loud);
 228     } elsif ($arg[0] eq 'time') {
 229         amarokTime($witem, $loud);
 230     } elsif ($arg[0] eq 'pause') {
 231         cmd('pause');
 232 	if ($status == 1) {
 233 	    print CLIENTCRAP $preprint.'Song unpaused.';
 234 	} elsif ($status == 2) {
 235 	    print CLIENTCRAP $preprint.'Song paused.';
 236         }
 237     } elsif ($arg[0] eq 'next') {
 238         cmd('next');
 239 	print CLIENTCRAP $preprint.'Skipped to next song.';
 240     } elsif ($arg[0] eq 'prev') {
 241         cmd('prev');
 242 	print CLIENTCRAP $preprint.'Skipped to previous song.';
 243     } elsif ($arg[0] eq 'play') {
 244         cmd('play');
 245 	print CLIENTCRAP $preprint.'Playing song.';
 246     } elsif ($arg[0] eq 'stop') {
 247         cmd('stop');
 248 	print CLIENTCRAP $preprint.'Song stopped.';
 249     } elsif ($arg[0] eq 'seek') {
 250         if (!(defined $arg[1])) {
 251 	    print CLIENTCRAP $preprint.'Not enough arguments.';
 252 	} else {
 253 	    amarokSeek($arg[1]);
 254 	}
 255     } elsif ($arg[0] eq 'vol') {
 256         if (!(defined $arg[1])) {
 257 	    my $o_vol = cmd('getVolume');
 258 	    chomp($o_vol);
 259 	    print CLIENTCRAP $preprint.'Current volume is '.$o_vol.'%%.';
 260 	} else {
 261 	    if ($arg[1] < 0 or $arg[1] > 100) {
 262 	        print CLIENTCRAP $preprint.'Given volume is out of range (0-100)';
 263 		return;
 264 	    }
 265 	    cmd('setVolume '.$arg[1]);
 266 	    print CLIENTCRAP $preprint.'Volume changed to '.$arg[1].'%%.';
 267 	}
 268     } elsif ($arg[0] eq 'mute') {
 269         cmd('mute');
 270 	print CLIENTCRAP $preprint.'Mute toggled.';
 271     } elsif ($arg[0] eq 'help') {
 272         show_help();
 273     } else {
 274         print CLIENTCRAP $preprint.'%RERROR%n: Unknown command!';
 275     }
 276 }
 277 
 278 Irssi::command_bind('amarok' => \&cmd_amarok);
 279 
 280 foreach my $cmd ('song', 'time', 'pause', 'play', 'stop', 'next', 'prev', 'seek', 'vol', 'mute', 'help') {
 281     Irssi::command_bind('amarok '.$cmd =>
 282         sub { cmd_amarok("$cmd ".$_[0], $_[1], $_[2]); } );
 283 }
 284  
 285 print CLIENTCRAP $preprint.$IRSSI{name}.' '.$VERSION.' loaded: type /amarok help for help';