1# irssiBlaster 1.6
2# Copyright (C) 2003 legion
3#
4# "Now Playing" (mp3blaster) in Irssi and more.
5#
6# - mp3blaster (http://www.stack.nl/~brama/mp3blaster.html)
7# - irssi (http://irssi.org)
8# for /npsend (EXPERIMENTAL):
9# - lsof (ftp://vic.cc.purdue.edu/pub/tools/unix/lsof/)
10#
11# NOTE: these applications are available in any linux distribution.
12#
13# should work with any version (i'm using irssi 0.8.8 & mp3blaster 3.2.0)
14# bug reports,features requests or comments -> a.lepore@email.it
15#
16# License:
17# This program is free software; you can redistribute it and/or modify it under
18# the terms of the GNU General Public License as published by the Free Software
19# Foundation; either version 2 of the License, or any later version. www.gnu.org
20#
21#################################################################################
22# *** USAGE:
23#
24# /np			: display the "Artist - Song" played in current window,
25# 			  any argument is printed after the song name (i.e. you own comment).
26#
27# /npa			: like /np, but prints "Artist - Album [Year]".
28# 			  If there isn't an appropriate album tag,print nothing.
29#
30# /anp			: /np in all channels.
31#
32# /anpa			: /npa in all channels.
33#
34# /npinfo		: display all available info for the current file.
35#
36# /cleanbar		: clean the statubar item (until the next song).
37#
38# /npsend NICK		: *EXPERIMENTAL* (irssi often CRASH)
39# 			  send the current played file to NICK user.
40# 			  maybe it will be usable in version 2.0.
41#
42#
43# *** SETTINGS:
44#
45# blaster_bar ON/OFF		: statusbar item activation.
46# 				  ATTENTION:
47# 				  you also have to add the item 'blaster' to your statusbar.
48# 				  see: http://irssi.org/?page=docs&doc=startup-HOWTO#c12
49# 				  example:
50# 				  /statusbar window add -priority "-10" -alignment right blaster
51#
52# blaster_infos_path FILE	: the file with infos (mp3blaster -f FILE).
53# 				  default is ~/.infoz
54#
55# blaster_bar_prefix STRING	: the bar prefix to filename. default is "playing:"
56#
57# blaster_prefix		: the /np prefix to filename. default is "np:"
58#
59#################################################################################
60# Changelog:
61#
62# 1.6:
63# - /npinfo.
64# - /cleanbar.
65# - /anpa.
66# - /npa.
67# - help fixes. $infofile is now /tmp/irssiblaster.
68# - /npsend (EXPERIMENTAL).
69# - /np [comment].
70# - /anp.
71# - BUGFIX: no spaces at the end of the filenames.
72# - added code comments.
73# - prefixes can be changed.
74# - statusbar realtime print.
75# - 'mp3blaster_infos_path' is now 'blaster_infos_path'.
76#
77# 1.0:
78# - initial release.
79#
80# TODO:
81# - working /npsend
82# - (automatic) /cleanbar
83# - support for others stuff (album,time..)
84# - /help
85# - use strict;
86#################################################################################
87
88use strict;
89use Irssi;
90use Irssi::TextUI;
91use vars qw($VERSION %IRSSI);
92
93$VERSION = '1.6';
94%IRSSI = (
95	authors		=> 'legion',
96	contact		=> 'a.lepore@email.it',
97	name		=> 'irssiBlaster',
98	description	=> 'Display the song played by mp3blaster in channels and statusbar. See the top of the file for usage.',
99	sbitems		=> 'blaster',
100	license		=> 'GNU GPLv2 or later',
101	changed		=> 'Fri Oct 31 12:22:08 CET 2003',
102);
103
104# TODO get rid of all those globals. This script needs some serious rework.
105my (@all, @artist, @title, @album, @year, @name, @status, @comment, @mode, @format, @bitrate, @samplerate, @length, @next, @tot);
106my ($name, $infofile, $status, $artist, $title, $year, $album, $comment, $format, $bitrate, $mode, $samplerate, $length, $next, $min, $sec, $secs, $prefix, $barprefix, $tot);
107
108sub get_info {
109
110	my $infofile = Irssi::settings_get_str('blaster_infos_path');
111	open (FILE, "<", $infofile); # open and read file with infos
112	my @all = <FILE>;
113	close (FILE);
114
115	@artist = grep (/^artist/, @all); # get the lines with tag infos
116	@title = grep (/^title/, @all);
117	@album = grep (/^album/, @all);
118	@year = grep (/^year/, @all);
119	@name = grep (/^path/, @all);     # get the line with filename
120
121} ##
122
123sub get_allinfo {
124
125	$infofile = Irssi::settings_get_str('blaster_infos_path');
126	open (FILE, "<", $infofile);
127	@all = <FILE>;
128	close (FILE);
129
130	@name = grep (/^path/, @all);
131	$name = $name[0];
132	$name =~ s/^path //;
133	chomp $name;
134	@status = grep (/^status/, @all);
135	$status = $status[0];
136	$status =~ s/^status //;
137	chomp $status;
138	@artist = grep (/^artist/, @all);
139	$artist = $artist[0];
140	$artist =~ s/^artist //;
141	chomp $artist;
142	@title = grep (/^title/, @all);
143	$title = $title[0];
144	$title =~ s/^title //;
145	chomp $title;
146	@album = grep (/^album/, @all);
147	$album = $album[0];
148	$album =~ s/^album //;
149	chomp $album;
150	@year = grep (/^year/, @all);
151	$year = $year[0];
152	$year =~ s/^year //;
153	chomp $year;
154	@comment = grep (/^comment/, @all);
155	$comment = $comment[0];
156	$comment =~ s/^comment //;
157	chomp $comment;
158	@mode = grep (/^mode/, @all);
159	$mode = $mode[0];
160	$mode =~ s/^mode //;
161	chomp $mode;
162	@format = grep (/^format/, @all);
163	$format = $format[0];
164	$format =~ s/^format //;
165	chomp $format;
166	@bitrate = grep (/^bitrate/, @all);
167	$bitrate = $bitrate[0];
168	$bitrate =~ s/^bitrate //;
169	chomp $bitrate;
170	@samplerate = grep (/^samplerate/, @all);
171	$samplerate = $samplerate[0];
172	$samplerate =~ s/^samplerate //;
173	chomp $samplerate;
174	@length = grep (/^length/, @all);
175	$length = $length[0];
176	$length =~ s/^length //;
177	chomp $length;
178	@next = grep (/^next/, @all);
179	$next = $next[0];
180	$next =~ s/^next //;
181	chomp $next;
182
183} ##
184
185sub get_status {
186
187	$infofile = Irssi::settings_get_str('blaster_infos_path');
188	open (FILE, "<", $infofile);
189	@all = <FILE>;
190	close (FILE);
191
192	@status = grep (/^status/, @all);
193} ##
194
195sub get_tag_info {
196
197	$artist = $artist[0]; # is an one-element array
198	$artist =~ s/^artist //; # remove prefixes
199	chomp $artist;           # remove last char (for correct printing)
200	$title = $title[0];
201	$title =~ s/^title //;
202	chomp $title;
203	$album = $album[0];
204	$album =~ s/^album //;
205	chomp $album;
206	$year = $year[0];
207	$year =~ s/^year //;
208	chomp $year;
209
210	$prefix = Irssi::settings_get_str('blaster_prefix');
211	$barprefix = Irssi::settings_get_str('blaster_bar_prefix');
212
213} ##
214
215sub get_name_info {
216
217	$name = $name[0];
218	$name =~ s/^path //;  # remove prefix
219	$name =~ s/\.mp3$//i; # remove extensions
220	$name =~ s/\.ogg$//i;
221	$name =~ s/_/ /g;     # change underscores to spaces
222	chomp $name;
223
224	$prefix = Irssi::settings_get_str('blaster_prefix');
225	$barprefix = Irssi::settings_get_str('blaster_bar_prefix');
226
227} ##
228
229sub noinfo_error {
230
231	$infofile = Irssi::settings_get_str('blaster_infos_path');
232	# print help if the info file is not valid
233	Irssi::print(
234	"%9IrssiBlaster:%_ \"$infofile\" is not a valid info file. %9Make sure%_ %Rmp3blaster -f $infofile%n %9is running!!!%_\n".
235	"%9IrssiBlaster:%_ (Hint: put %9alias mp3blaster='mp3blaster -f $infofile'%_ in your ~/.bashrc )"
236	, MSGLEVEL_CRAP);
237
238} ##
239
240
241
242
243sub cmd_np { # /np stuff
244
245get_info;
246
247if (@artist && @title) { # if file has a an id3tag
248
249	get_tag_info;
250
251	my ($comment, $server, $witem) = @_; # np: blabla in current window (copied from other scripts..)
252	if ($witem && ($witem->{type} eq "CHANNEL" || $witem->{type} eq "QUERY")) {
253		$witem->command("me $prefix $artist - $title $comment");
254	}
255	else {
256		Irssi::print("$prefix $artist - $title $comment", MSGLEVEL_CRAP); # or print in client level if no active channel/query
257	}
258}
259
260elsif (@name) { # if there isn't id3tag we use the filename
261
262	get_name_info;
263
264	my ($comment, $server, $witem) = @_;
265	if ($witem && ($witem->{type} eq "CHANNEL" || $witem->{type} eq "QUERY")) {
266		$witem->command("me $prefix $name $comment");
267	}
268	else {
269		Irssi::print("$prefix $name $comment", MSGLEVEL_CRAP);
270	}
271}
272
273else { noinfo_error; }
274
275} ##
276
277sub cmd_npall { # /anp stuff
278
279get_info;
280
281if (@artist && @title) {
282
283	get_tag_info;
284
285	my ($comment, $server, $witem) = @_;
286	Irssi::command("foreach channel /me $prefix $artist - $title $comment");
287}
288
289elsif (@name) {
290
291	get_name_info;
292
293	my ($comment, $server, $witem) = @_;
294	Irssi::command("foreach channel /me $prefix $name $comment");
295}
296
297else { noinfo_error; }
298
299} ##
300
301sub cmd_npalbum { # /npa stuff
302
303if (@artist && @album) {
304
305	get_tag_info;
306
307	if ($year) { $year = "[$year]"; }
308
309	my ($comment, $server, $witem) = @_;
310	if ($witem && ($witem->{type} eq "CHANNEL" || $witem->{type} eq "QUERY")) {
311		$witem->command("me $prefix $artist - $album $year $comment");
312	}
313	else {
314		Irssi::print("$prefix $artist - $album $year $comment", MSGLEVEL_CRAP);
315	}
316}
317else {
318	Irssi::print("%9IrssiBlaster:%_ filename has no album tag.", MSGLEVEL_CRAP);
319}
320} ##
321
322sub cmd_npalbumall { # /anpa stuff
323
324get_info;
325
326if (@artist && @album) {
327
328	get_tag_info;
329
330	if ($year) { $year = "[$year]"; }
331
332	my ($comment, $server, $witem) = @_;
333	Irssi::command("foreach channel /me $prefix $artist - $album $year $comment");
334}
335else {
336        Irssi::print("%9IrssiBlaster:%_ filename has no album tag.", MSGLEVEL_CRAP);
337}
338} ##
339
340sub cmd_info {
341
342get_allinfo;
343
344$tot = $length/60; # calculating minutes:seconds
345@tot = split(/\./, $tot);
346$min = $tot[0];
347$sec = $min*60;
348$secs = $length-$sec;
349
350Irssi::print("\n%9IrssiBlaster - File Info:%_", MSGLEVEL_CRAP);
351Irssi::print("%9F%_ile%9:%_ $name", MSGLEVEL_CRAP);
352Irssi::print("%9S%_tatus%9:%_ $status", MSGLEVEL_CRAP);
353if ($artist) { Irssi::print("%9A%_rtist%9:%_ $artist", MSGLEVEL_CRAP); }
354if ($title) { Irssi::print("%9T%_itle%9:%_ $title", MSGLEVEL_CRAP); }
355if ($album) { Irssi::print("%9A%_lbum%9:%_ $album", MSGLEVEL_CRAP); }
356if ($year) { Irssi::print("%9Y%_ear%9:%_ $year", MSGLEVEL_CRAP); }
357if ($comment) { Irssi::print("%9C%_omment%9:%_ $comment", MSGLEVEL_CRAP); }
358Irssi::print("%9-%_----------%9-%_", MSGLEVEL_CRAP);
359if ($secs =~ /^.{1}$/) { Irssi::print("%9L%_ength%9:%_ $min\:0$secs", MSGLEVEL_CRAP); }
360else { Irssi::print("%9L%_ength%9:%_ $min\:$secs", MSGLEVEL_CRAP); }
361if ($format =~ /0$/) { Irssi::print("%9F%_iletype%9:%_ $format (Ogg/Vorbis?)", MSGLEVEL_CRAP); }
362else { Irssi::print("%9F%_iletype%9:%_ $format", MSGLEVEL_CRAP); }
363Irssi::print("%9R%_ate%9:%_ $bitrate\kb/$samplerate\Khz", MSGLEVEL_CRAP);
364if ($mode) { Irssi::print("%9M%_ode%9:%_ $mode", MSGLEVEL_CRAP); }
365if ($next) { Irssi::print("%9N%_ext in playlist%9:%_ $next", MSGLEVEL_CRAP); }
366
367} ##
368
369#######################################################################################
370
371sub bar_np { # statusbar stuff
372
373my ($item, $get_size_only) = @_;
374
375my $bar_activation = Irssi::settings_get_str('blaster_bar');
376if ($bar_activation =~ /^on$/i) { # display in bar only if /set blaster_bar = ON
377
378get_info;
379
380if (@artist && @title) {
381
382	get_tag_info;
383
384	# print in statusbar
385	$item->default_handler($get_size_only, "{sb $barprefix $artist - $title}", undef, 1);
386}
387
388elsif (@name) {
389
390	get_name_info;
391
392	$item->default_handler($get_size_only, "{sb $barprefix $name}", undef, 1);
393}
394
395else {
396	$item->default_handler($get_size_only, undef, undef, 1);
397}
398}
399} ##
400
401sub refresh {
402	Irssi::statusbar_items_redraw('blaster'); # refresh statusbar
403	Irssi::statusbars_recreate_items();
404} ##
405
406sub cmd_cleanbar { # /cleanbar stuff
407
408my $infofile = Irssi::settings_get_str('blaster_infos_path');
409unlink $infofile;
410
411} ##
412
413sub cmd_send { # /npsend stuff
414
415	get_info;
416
417	my @name = grep (/^path/, @all);
418	my $name = $name[0];
419	$name =~ s/path //;
420	chomp $name;
421
422	# get the full path of the file from 'lsof' (i have lsof 4.64)
423	my @open_files = grep (/$name$/, `lsof -c mp3blaste -F n`);
424	$open_files[0] =~ s/^n//;
425	my $filename = $open_files[0];
426	chomp $filename;
427
428	my ($target, $server, $witem) = @_;
429	$server->command("DCC SEND $target \"$filename\""); # /dcc send
430
431} ##
432
433
434Irssi::settings_add_str('irssiBlaster', 'blaster_infos_path', '/tmp/irssiblaster'); # register settings
435Irssi::settings_add_str('irssiBlaster', 'blaster_prefix', 'np:');
436Irssi::settings_add_str('irssiBlaster', 'blaster_bar_prefix', 'playing:');
437Irssi::settings_add_str('irssiBlaster', 'blaster_bar', 'OFF');
438Irssi::command_bind('np', 'cmd_np'); # register /commands
439Irssi::command_bind('anp', 'cmd_npall');
440Irssi::command_bind('npa', 'cmd_npalbum');
441Irssi::command_bind('anpa', 'cmd_npalbumall');
442Irssi::command_bind('npinfo', 'cmd_info');
443Irssi::command_bind('cleanbar', 'cmd_cleanbar');
444Irssi::command_bind('npsend', 'cmd_send');
445Irssi::statusbar_item_register('blaster', undef, 'bar_np'); # register statusbar item
446Irssi::timeout_add(1000, 'refresh', undef); # refresh every 1 second
447