archive

- Random tools & helpful resources for IRC
git clone git://git.acid.vegas/archive.git
Log | Files | Refs | Archive

play.pl (4579B)

      1 use strict;
      2 use warnings;
      3 use File::Find::Rule;
      4 no strict 'subs';
      5 
      6 my $SCRIPT_NAME = 'play';
      7 my $SCRIPT_AUTHOR = 'The Krusty Krab <wowaname@volatile.ch>';
      8 my $SCRIPT_VERSION = '1.2';
      9 my $SCRIPT_LICENCE = 'Public domain';
     10 my $SCRIPT_DESC = 'Play ASCII art';
     11 our (%queue, %timer);
     12 
     13 if (weechat::register($SCRIPT_NAME, $SCRIPT_AUTHOR, $SCRIPT_VERSION,
     14  $SCRIPT_LICENCE, $SCRIPT_DESC, '', '')) {
     15 	weechat::hook_command('play', 'Play ASCII art',
     16 		'[-delay ms] [-repeat times] [-pipe "command"] [-fmt "list"] filename'.
     17 		"\n-find pattern\n-stop\n",
     18 		"-delay: delay in milliseconds between lines\n".
     19 		"-find: list matching files, don't play\n".
     20 		"-pipe: pipe output into command\n".
     21 		"-fmt: treat file as a format string and replace with arguments in\n".
     22 		"    list. Arguments are separated by semicolons (;)\n".
     23 		"filename: file to play. Supports wildcards. By default, searches\n".
     24 		"    subdirectories as well unless '/' is found in the filename\n".
     25 		"-stop: stop currently playing file in buffer",
     26 		'-delay|-pipe|-fmt|-repeat|%*'.
     27 		' || -find'.
     28 		' || -stop',
     29 		'cmd_play', '');
     30 
     31 	my %OPTIONS = (
     32 		delay => ['Default delay between lines, in milliseconds', 0],
     33 		dir => ['Art directory',
     34 			weechat::info_get('weechat_dir', '').'/ascii'],
     35 		find_limit => ['Maximum number of results returned by -find. '.
     36 			'-1 = unlimited (may lock up WeeChat with many results!)', 32],
     37 		);
     38 
     39 	for my $option (keys %OPTIONS) {
     40 		weechat::config_set_plugin($option, $OPTIONS{$option}[1])
     41 		 unless weechat::config_is_set_plugin($option);
     42 		weechat::config_set_desc_plugin($option, $OPTIONS{$option}[0]);
     43 	}
     44 }
     45 
     46 sub parse
     47 {
     48 	my ($input, $delay, $pipe, $find, $repeat, $fmt) =
     49 		(shift, weechat::config_get_plugin('delay'), '/msg *', 0, 1, '');
     50 
     51 	if ($input =~ / *-delay +([0-9]+) /) {
     52 		$delay = $1;
     53 		$input =~ s/-delay +[0-9]+//;
     54 	}
     55 	if ($input =~ / *-find /) {
     56 		$find = 1;
     57 		$input =~ s/-find//;
     58 	}
     59 	if ($input =~ / *-fmt +("(?:[^"\\]|\\.)+"|[^ ]+) /) {
     60 		$fmt = $1;
     61 		$fmt =~ s/^"(.+)"$/$1/ if $fmt =~ /^".+"$/;
     62 		$input =~ s/-fmt +("(?:[^"\\]|\\.)+"|[^ ]+)//;
     63 	}
     64 	if ($input =~ / *-repeat +([0-9]+) /) {
     65 		$repeat = $1;
     66 		$input =~ s/-repeat +[0-9]+//;
     67 	}
     68 	if ($input =~ / *-pipe +("(?:[^"\\]|\\.)+"|[^ ]+) /) {
     69 		$pipe = $1;
     70 		$pipe =~ s/^"(.+)"$/$1/ if $pipe =~ /^".+"$/;
     71 		$input =~ s/-pipe +("(?:[^"\\]|\\.)+"|[^ ]+)//;
     72 	}
     73 
     74 	return ($delay, $pipe, $find, $repeat, $fmt, $input =~ s/^ +| +$//r);
     75 }
     76 
     77 sub play
     78 {
     79 	my $buffer = shift;
     80 
     81 	weechat::command($buffer, shift @{ $queue{$buffer} });
     82 	delete $queue{$buffer} unless @{ $queue{$buffer} };
     83 
     84 	return weechat::WEECHAT_RC_OK;
     85 }
     86 
     87 sub cmd_play
     88 {
     89 	my $buffer = $_[1];
     90 
     91 	if ($_[2] eq '-stop') {
     92 		if (exists $timer{$buffer}) {
     93 			weechat::unhook($timer{$buffer});
     94 			delete $queue{$buffer};
     95 		}
     96 		return weechat::WEECHAT_RC_OK;
     97 	}
     98 
     99 	my ($delay, $pipe, $find, $repeat, $fmt, $file) = parse($_[2]);
    100 	my $server = weechat::info_get($buffer, 'localvar_server');
    101 	my ($prio_s, $prio_d) = (
    102 		weechat::config_get("irc.server.$server.anti_flood_prio_high"),
    103 		weechat::config_get("irc.server_default.anti_flood_prio_high"),
    104 		);
    105 	$delay = ($delay or 1000 * (
    106 		weechat::config_option_is_null($prio_s)
    107 		? weechat::config_integer($prio_d)
    108 		: weechat::config_integer($prio_s)
    109 		) or 10);
    110 
    111 	my $rule = File::Find::Rule
    112 		->file
    113 		->name($file)
    114 		->start(weechat::config_get_plugin('dir'));
    115 
    116 	if ($find) {
    117 		my $i = weechat::config_get_plugin('find_limit');
    118 		weechat::print($buffer, " \t$_")
    119 			while defined( $_ = $rule->match ) and --$i;
    120 		weechat::print($buffer, weechat::prefix('error').
    121 			"Too many results; please narrow your search") unless $i;
    122 		weechat::print($buffer, " \tEnd of file listing for '$file'");
    123 		return weechat::WEECHAT_RC_OK;
    124 	}
    125 
    126 	my $path;
    127 	if ($file =~ m"/") { $path = weechat::config_get_plugin('dir')."/$file" }
    128 	else { $path = $rule->match }
    129 
    130 	if ($path and -z $path) {
    131 		weechat::print($buffer, weechat::prefix('error').
    132 			"File '$file' is empty");
    133 	} elsif ($path and open FH, "<", $path) {
    134 		my @lines;
    135 		while (<FH>) {
    136 			no warnings; # sprintf barks if there's nothing to replace
    137 			$_ = sprintf $_, split ';', $fmt if $fmt;
    138 			push @lines, s/[\r\n]*$//r
    139 		}
    140 		close FH;
    141 		for (1 .. $repeat) {
    142 			push @{ $queue{$buffer} }, "$pipe \x0f$_\x0f" for @lines;
    143 		}
    144 
    145 		weechat::unhook($timer{$buffer}) if exists $timer{$buffer};
    146 		$timer{$buffer} =
    147 			weechat::hook_timer($delay, 0, scalar @{ $queue{$buffer} },
    148 			'play', $buffer);
    149 	} else {
    150 		weechat::print($buffer, weechat::prefix('error').
    151 			"Cannot open '$file'".($! ? ": $!" : ""));
    152 		return weechat::WEECHAT_RC_ERROR;
    153 	}
    154 
    155 	return weechat::WEECHAT_RC_OK;
    156 }