weechat-opal/scripts/play.pl

150 lines
4.4 KiB
Perl
Raw Normal View History

2016-10-02 08:24:28 +00:00
use strict;
use warnings;
use File::Find::Rule;
no strict 'subs';
my $SCRIPT_NAME = 'play';
my $SCRIPT_AUTHOR = 'The Krusty Krab <wowaname@volatile.ch>';
my $SCRIPT_VERSION = '1.2';
2016-10-02 08:24:28 +00:00
my $SCRIPT_LICENCE = 'Public domain';
my $SCRIPT_DESC = 'Play ASCII art';
2016-10-02 10:44:45 +00:00
our (%queue, %timer);
2016-10-02 08:24:28 +00:00
if (weechat::register($SCRIPT_NAME, $SCRIPT_AUTHOR, $SCRIPT_VERSION,
$SCRIPT_LICENCE, $SCRIPT_DESC, '', '')) {
weechat::hook_command('play', 'Play ASCII art',
qq([-delay ms] [-find] [-pipe "command"] [-fmt "list"] filename\n-stop),
2016-10-02 08:24:28 +00:00
"-delay: delay in milliseconds between lines\n".
"-find: list matching files, don't play\n".
"-pipe: pipe output into command\n".
"-fmt: treat file as a format string and replace with arguments in\n".
" list. Arguments are separated by semicolons (;)\n".
2016-10-02 10:44:45 +00:00
"filename: file to play. Supports wildcards. By default, searches\n".
" subdirectories as well unless '/' is found in the filename\n".
"-stop: stop currently playing file in buffer",
2016-10-02 08:24:28 +00:00
'', 'cmd_play', '');
my %OPTIONS = (
delay => ['Default delay between lines', 0],
dir => ['Art directory',
weechat::info_get('weechat_dir', '').'/ascii'],
find_limit => ['Maximum number of results returned by -find. '.
'-1 = unlimited (may lock up WeeChat with many results!)', 32],
2016-10-02 08:24:28 +00:00
);
for my $option (keys %OPTIONS) {
weechat::config_set_plugin($option, $OPTIONS{$option}[1])
unless weechat::config_is_set_plugin($option);
weechat::config_set_desc_plugin($option, $OPTIONS{$option}[0]);
}
}
sub parse {
2016-10-21 20:10:17 +00:00
my ($input, $delay, $pipe, $find, $repeat, $fmt) =
(shift, weechat::config_get_plugin('delay'), '/msg *', 0, 1, '');
2016-10-02 08:24:28 +00:00
if ($input =~ / *-delay +([0-9]+) /) {
$delay = $1;
2016-10-02 21:53:44 +00:00
$input =~ s/-delay +[0-9]+//;
2016-10-02 08:24:28 +00:00
}
if ($input =~ / *-find /) {
$find = 1;
2016-10-02 21:53:44 +00:00
$input =~ s/-find//;
}
2016-10-21 20:10:17 +00:00
if ($input =~ / *-fmt +("(?:[^"\\]|\\.)+"|[^ ]+) /) {
$fmt = $1;
$fmt =~ s/^"(.+)"$/$1/ if $fmt =~ /^".+"$/;
$input =~ s/-fmt +("(?:[^"\\]|\\.)+"|[^ ]+)//;
}
2016-10-02 21:53:44 +00:00
if ($input =~ / *-repeat +([0-9]+) /) {
$repeat = $1;
$input =~ s/-repeat +[0-9]+//;
2016-10-02 08:24:28 +00:00
}
2016-10-21 20:10:17 +00:00
if ($input =~ / *-pipe +("(?:[^"\\]|\\.)+"|[^ ]+) /) {
2016-10-02 08:24:28 +00:00
$pipe = $1;
$pipe =~ s/^"(.+)"$/$1/ if $pipe =~ /^".+"$/;
2016-10-21 20:10:17 +00:00
$input =~ s/-pipe +("(?:[^"\\]|\\.)+"|[^ ]+)//;
2016-10-02 08:24:28 +00:00
}
2016-10-21 20:10:17 +00:00
return ($delay, $pipe, $find, $repeat, $fmt, $input =~ s/^ +| +$//r);
2016-10-02 08:24:28 +00:00
}
sub play {
2016-10-02 10:44:45 +00:00
my $buffer = shift;
2016-10-02 08:24:28 +00:00
2016-10-02 10:44:45 +00:00
weechat::command($buffer, shift @{ $queue{$buffer} });
delete $queue{$buffer} unless @{ $queue{$buffer} };
2016-10-02 08:24:28 +00:00
return weechat::WEECHAT_RC_OK;
}
sub cmd_play {
my $buffer = $_[1];
2016-10-02 10:44:45 +00:00
2016-10-21 20:10:17 +00:00
if ($_[2] eq '-stop') {
if (exists $timer{$buffer}) {
weechat::unhook($timer{$buffer});
delete $queue{$buffer};
}
2016-10-02 10:44:45 +00:00
return weechat::WEECHAT_RC_OK;
}
2016-10-21 20:10:17 +00:00
my ($delay, $pipe, $find, $repeat, $fmt, $file) = parse($_[2]);
2016-10-02 08:24:28 +00:00
my $server = weechat::info_get($buffer, 'localvar_server');
my ($prio_s, $prio_d) = (
weechat::config_get("irc.server.$server.anti_flood_prio_high"),
weechat::config_get("irc.server_default.anti_flood_prio_high"),
);
$delay = ($delay or 1000 * (
weechat::config_option_is_null($prio_s)
? weechat::config_integer($prio_d)
: weechat::config_integer($prio_s)
) or 10);
my $rule = File::Find::Rule
->file
->name($file)
2016-10-02 08:24:28 +00:00
->start(weechat::config_get_plugin('dir'));
if ($find) {
my $i = weechat::config_get_plugin('find_limit');
weechat::print($buffer, " \t$_")
while defined( $_ = $rule->match ) and --$i;
weechat::print($buffer, weechat::prefix('error').
"Too many results; please narrow your search") unless $i;
weechat::print($buffer, " \tEnd of file listing for '$file'");
2016-10-02 08:24:28 +00:00
return weechat::WEECHAT_RC_OK;
}
2016-10-03 01:01:48 +00:00
my $path;
if ($file =~ m"/") { $path = weechat::config_get_plugin('dir')."/$file" }
else { $path = $rule->match }
if ($path and -z $path) {
weechat::print($buffer, weechat::prefix('error').
"File '$file' is empty");
} elsif ($path and open FH, "<", $path) {
2016-10-02 21:53:44 +00:00
my @lines;
2016-10-21 20:10:17 +00:00
while (<FH>) {
no warnings; # sprintf barks if there's nothing to replace
$_ = sprintf $_, split ';', $fmt if $fmt;
2016-10-21 20:10:17 +00:00
push @lines, s/[\r\n]*$//r
}
2016-10-02 08:24:28 +00:00
close FH;
2016-10-02 21:53:44 +00:00
for (1 .. $repeat) {
push @{ $queue{$buffer} }, "$pipe \x0f$_\x0f" for @lines;
}
2016-10-02 10:44:45 +00:00
weechat::unhook($timer{$buffer}) if exists $timer{$buffer};
$timer{$buffer} =
weechat::hook_timer($delay, 0, scalar @{ $queue{$buffer} },
'play', $buffer);
2016-10-02 08:24:28 +00:00
} else {
weechat::print($buffer, weechat::prefix('error').
"Cannot open '$file'".($! ? ": $!" : ""));
2016-10-02 08:24:28 +00:00
return weechat::WEECHAT_RC_ERROR;
}
return weechat::WEECHAT_RC_OK;
}