html/l33tmusic.pl
1 use strict;
2 use Irssi;
3 use Irssi::TextUI;
4 use vars qw($VERSION %IRSSI);
5 use Xmms;
6 use Xmms::Remote ();
7
8 #changed to recommended version system with onedigit.twodigits, sorry :)
9 $VERSION = '2.01';
10 %IRSSI = (
11 authors => 'Mikachu',
12 contact => 'Mikachu @ quakenet|freenode|arcnet|oftc',
13 description => 'A script to show playing xmms song in channel or in a statusbar, and also control xmms. Be sure to read through the script to see all features.',
14 name => 'l33t xmms music showing script',
15 license => 'GPL',
16 modules => 'Bundle::Xmms',
17 sbitems => 'l33tmusic'
18 );
19
20 #Stuff i've added recently that i can remember:
21 #
22 #fixed the -c parameter, now you can do stuff like
23 #/l33tmusic -c / jump_to_timestr 1:24 to jump around
24 #and /l33tmusic -c / pause to pause, and /l33tmusic
25 #-c /echo get_playlist_pos to echo the position :)
26 #
27 #only answers to /ctcp music if xmms is actually on
28 #(if someone /ctcp music nick 2 it will show your current+2
29 #song in playlist as currently playing instead of saying
30 #that it is the second next song, oh well :)
31 #
32 #some stuff now take a numerical argument as an offset
33 #to the current position in the playlist
34 #
35 #Stuff i've added that i can't remember:
36 #
37 #if you expected to find something here you weren't thinking
38 #look below for stuff
39
40 #this function from nickcolor.pl
41 my @colors = qw/2 3 4 5 6 7 9 10 11 12 13/;
42 sub simple_hash {
43 my ($string) = @_;
44 chomp $string;
45 my @chars = split //, $string;
46 my $counter;
47
48 foreach my $char (@chars) {
49 $counter += ord $char;
50 }
51
52 $counter = $colors[$counter % 11];
53
54 return $counter;
55 }
56
57 sub getvars {
58 if ($_[0] =~ "songinfo") {
59 my ($position, $title, $time, $status, $filename);
60 my $xmmscontrol = Xmms::Remote->new;
61 my $wantedpos = $_[0];
62 $wantedpos =~ s/songinfo //;
63 unless ($wantedpos =~ /^-?\d+$/ && (( $wantedpos + $xmmscontrol->get_playlist_pos <= $xmmscontrol->get_playlist_length-1 && $wantedpos >= 0) || 0-$wantedpos <= $xmmscontrol->get_playlist_pos && $wantedpos <= 0) ) {
64 $wantedpos = 0;
65 }
66 my $wantedpos = $xmmscontrol->get_playlist_pos + $wantedpos;
67 $title = $xmmscontrol->get_playlist_title($wantedpos);
68 my $seconds = ($xmmscontrol->get_output_time/1000)%60;
69 my $tmp = length($seconds);
70 if($tmp == "1") {
71 $seconds = "0" . $seconds;
72 }
73 $position = int($xmmscontrol->get_output_time/60000) . ":" . $seconds;
74 $time = $xmmscontrol->get_playlist_timestr($wantedpos);
75 if ($xmmscontrol->is_playing) {
76 if ($xmmscontrol->is_paused) {
77 $status = "Paused";
78 } else {
79 $status = "Playing";
80 }
81 } else {
82 $status = "Stopped";
83 }
84 $filename = $xmmscontrol->get_playlist_file($wantedpos);
85
86 $title =~ s/[\r\n]/ /g;
87 $filename =~ s/[\r\n]/ /g;
88
89 return($position, $title, $time, $status, $filename);
90 } elsif ($_[0] =~ "filename") {
91 my $xmmscontrol = Xmms::Remote->new;
92 my $wantedpos = $_[0];
93 $wantedpos =~ s/filename //;
94 unless ($wantedpos =~ /^-?\d+$/ && (( $wantedpos + $xmmscontrol->get_playlist_pos <= $xmmscontrol->get_playlist_length-1 && $wantedpos >= 0) || 0-$wantedpos <= $xmmscontrol->get_playlist_pos && $wantedpos <= 0) ) {
95 $wantedpos = 0;
96 }
97 $wantedpos = $xmmscontrol->get_playlist_pos + $wantedpos;
98 $filename = $xmmscontrol->get_playlist_file($wantedpos);
99 $filename =~ s/[\r\n]/ /g;
100 return($filename);
101 }
102 }
103
104 sub ctcp_info {
105 if (Irssi::settings_get_bool('l33tctcp_enabled') && Xmms::Remote->new->is_running) {
106 my ($server, $msg, $nick, $address, $channel) = @_;
107 my ($p, $n, $t, $s) = getvars("songinfo $msg");
108 my $reply = Irssi::settings_get_str('l33tctcpreply');
109 $reply =~ s/(\$\w+)/$1/eeg;
110 $server->command("^notice $nick $reply");
111 Irssi::statusbar_items_redraw('l33tmusic');
112 }
113 }
114
115 sub triggersend {
116 my $trigger = Irssi::settings_get_str('l33ttrigger');
117 if ($_[1] =~ /^$trigger/) {
118 if (Irssi::settings_get_bool('l33ttrigger_enabled')) {
119 $_[1] =~ s/$trigger //g;
120 $_[1] = getvars("filename $_[1]");
121 $_[0]->command("DCC SEND $_[2] \"$filename\"");
122 } else {
123 $_[0]->command("^notice $_[2] Trigger currently disabled");
124 }
125 }
126 }
127
128 sub themainthingie {
129 if (Xmms::Remote->new->is_running) {
130 my ($msg, $server, $nick, $address, $channel) = @_;
131 my $command;
132 my ($p, $n, $t, $s, $f) = getvars("songinfo 0");
133 #The -m switch will echo the info in the status window,
134 #I have this bound to meta-q :), takes a numerical argument
135 #same as the -s switch
136 if ($msg =~ "^-m") {
137 $msg =~ s/^-m //;
138 my ($p, $n, $t, $s, $f) = getvars("songinfo " . $msg);
139 print CLIENTCRAP "" . simple_hash("$n") . "$n ($p / $t)";
140 $command = "";
141 #This allows a fully customized message, to be used in
142 #aliases, since it's not fun to write the full thing every
143 #time
144 } elsif ($msg =~ "^-e") {
145 $msg =~ s/^\-e //;
146 $command = "$msg";
147 #The -c switch is now fixed mostly, it seems that you
148 #can do whatever you want, and if it happens to match
149 #a proper command such as jump_to_timestr and you pass
150 #the right parameter, it works, otherwise i made it not
151 #crash anymore, weee :)
152 } elsif ($msg =~ "^-c") {
153 $msg =~ s/^\-c //;
154 my $thingie;
155 my ($msg, $reply, $param) = split(/ /, "$msg", 3);
156 if ($param) {
157 return unless eval {
158 $thingie = Xmms::Remote->new->$reply($param);
159 }
160 } else {
161 return unless eval {
162 $thingie = Xmms::Remote->new->$reply;
163 }
164 }
165 if ($thingie) {
166 $command = "$msg $thingie";
167 }
168 #The -f switch has been removed, please use
169 #/l33tmusic -e /colme or /colsay from the
170 #ascii.pl script to get better functionality
171
172 #This switch will send the currently playing song to
173 #the nick on the command line, takes a numerical
174 #argument like the -m switch
175 } elsif ($msg =~ "^-s") {
176 $msg =~ s/^-s //;
177 (my $friend, $msg) = split " ", $msg;
178 $friend =~ s/ //;
179 my ($p, $n, $t, $s, $f) = getvars("songinfo " . $msg);
180 $server->command("dcc send $friend \"$f\"");
181 #If a string was given, put it in front of the info, and
182 #anything after a # after the info. If nothing is in front
183 #of the #, throw in the string from the settings.
184 } elsif ($msg) {
185 my $msg2;
186 $msg =~ s/(\$\w+)/$1/eeg;
187 ($msg, $msg2) = split "#", $msg;
188 if ($msg =~ /^$/) {
189 $msg = Irssi::settings_get_str('l33tstringplaying');
190 }
191 $command = "me $msg $n ($p / $t) $msg2";
192 #Just go with the defaults
193 } else {
194 if ( $s eq "Playing" ) {
195 $command = Irssi::settings_get_str('l33tstringplaying');
196 $command = Irssi::settings_get_str('l33tstringaction') . " $command " . Irssi::settings_get_str('l33tstringsongformat');
197 } else {
198 $command = "echo Xmms is $s";
199 }
200 }
201 $command =~ s/(\$\w+)/$1/eeg;
202 $command =~ s/\s+/ /g;
203 if ($command) {
204 Irssi::active_win()->command("$command");
205 }
206 }else {
207 Irssi::active_win()->command("echo Xmms isn't currently running");
208 }
209 }
210
211 sub checkformpg123 {
212 my ($msg, $server, $witem) = @_;
213 if ($msg =~ /^Playing( MPEG stream from )?/) {
214 $msg =~ s/Playing MPEG stream from //;
215 $msg =~ s/Playing //;
216 $msg =~ s/%20/ /g;
217 $msg =~ s/\.(mp3|ogg)( \.\.\.)?//i;
218 $msg =~ s/_/ /g;
219 $msg =~ s/oc remix//i;
220 $msg = Irssi::settings_get_str('l33tstringaction') . " " . Irssi::settings_get_str('l33tstringplayingmpg123') . " $msg";
221 Irssi::signal_stop();
222 Irssi::signal_remove('send text', 'checkformpg123');
223 Irssi::signal_emit('send command', $msg, $server, $witem);
224 Irssi::signal_add('send text', 'checkformpg123');
225 }
226
227 }
228
229 my $statusbar_item;
230 my $refresh_tag;
231 my $scrollpos=0;
232 sub refresh_statusbar {
233 my ($p, $no, $t, $s, $f) = getvars("songinfo 0");
234 my $width=Irssi::active_win()->{width};
235 my $n;
236 my $others = Irssi::settings_get_str('l33tstatusbar');
237 $others =~ s/\%.//g;
238 $others =~ s/\$n//g;
239 $others =~ s/(\$\w+)/$1/eeg;
240 my $maxlength=$width - length($others);
241 if (length($no) > $maxlength) {
242 my $middlethingie = Irssi::settings_get_str('l33tmiddlethingie');
243 $no = "$no $middlethingie";
244 $n=substr(substr($no, $scrollpos, length($no)) . substr($no, 0, $scrollpos), 0, $maxlength);
245 $scrollpos++;
246 $scrollpos=0 if ($scrollpos + 1 > length($no));
247 } else {
248 $n = $no;
249 }
250 $n =~ s/\%/\%\%/g;
251 $statusbar_item = Irssi::settings_get_str('l33tstatusbar');
252 $statusbar_item =~ s/(\$\w+)/$1/eeg;
253 Irssi::statusbar_items_redraw('l33tmusic');
254 }
255
256 sub l33tmusic_statusbar {
257 my ($item, $get_size_only) = @_;
258 $item->default_handler($get_size_only, "$statusbar_item", undef, 1);
259 }
260
261
262 Irssi::signal_add('send text', 'checkformpg123');
263 Irssi::command_bind('l33tmusic', 'themainthingie');
264 Irssi::settings_add_str('infopipe', 'l33tstringaction', '/me');
265 Irssi::settings_add_str('infopipe', 'l33tstringplayingmpg123', 'is listening to');
266 Irssi::settings_add_str('infopipe', 'l33tstringplaying', 'is listening to');
267 Irssi::settings_add_str('infopipe', 'l33tstatusbar', '$n ($p / $t)');
268 Irssi::settings_add_str('infopipe', 'l33tstatusbarrefresh', '500');
269 Irssi::settings_add_str('infopipe', 'l33tmiddlethingie', '*** ');
270 Irssi::settings_add_str('infopipe', 'l33tstringsongformat', '$n ($p / $t)');
271 Irssi::settings_add_str('infopipe', 'l33tctcpreply', 'I\'m listening to $n ($p / $t) Status: $s');
272 Irssi::settings_add_str('infopipe', 'l33ttrigger', '¡yourtriggerhere');
273 Irssi::settings_add_bool('infopipe', 'l33ttrigger_enabled', 0);
274 Irssi::settings_add_bool('infopipe', 'l33tctcp_enabled', 0);
275 Irssi::settings_add_bool('infopipe', 'l33twarning_read', 0);
276 Irssi::signal_add("ctcp msg music", "ctcp_info");
277 Irssi::signal_add_last("message public", "triggersend");
278 Irssi::statusbar_item_register('l33tmusic', undef, 'l33tmusic_statusbar');
279 $refresh_tag=Irssi::timeout_add(Irssi::settings_get_str('l33tstatusbarrefresh'), 'refresh_statusbar', undef);
280 unless (Irssi::settings_get_bool('l33twarning_read')) {
281 print CLIENTCRAP "Type /set l33t to see all available settings. To remove this message, please type /set l33twarning_read on. Type /set l33t to list all options.";
282 print CLIENTCRAP "If you want statusbar, add \'l33tmusic = { placement = \"top\"; items = { l33tmusic = { }; }; };\' to your config file, above \'topic = {\', and do a /reload.";
283 }