3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-12-23 19:22:40 +01:00

Simplify use of getopt() throughout

This commit is contained in:
Pragmatic Software 2021-07-30 15:01:38 -07:00
parent bbe5b58b97
commit 483984754a
12 changed files with 439 additions and 370 deletions

View File

@ -12,7 +12,6 @@ use parent 'PBot::Core::Class';
use Time::Duration; use Time::Duration;
use Time::HiRes qw(gettimeofday); use Time::HiRes qw(gettimeofday);
use Getopt::Long qw(GetOptionsFromArray);
use POSIX qw(strftime); use POSIX qw(strftime);
use Storable; use Storable;
use LWP::UserAgent; use LWP::UserAgent;
@ -94,25 +93,26 @@ sub cmd_factundo {
my $arguments = $context->{arguments}; my $arguments = $context->{arguments};
my $getopt_error;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
my ($list_undos, $goto_revision); my ($list_undos, $goto_revision);
my @opt_args = $self->{pbot}->{interpreter}->split_line($arguments, strip_quotes => 1);
GetOptionsFromArray( my %opts = (
\@opt_args, l => \$list_undos,
'l:i' => \$list_undos, r => \$goto_revision,
'r=i' => \$goto_revision
); );
return "/say $getopt_error -- $usage" if defined $getopt_error; my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
return $usage if @opt_args > 2; $arguments,
return $usage if not @opt_args; \%opts,
['bundling'],
'l:i',
'r=i',
);
$arguments = join(' ', map { $_ = "'$_'" if $_ =~ m/ /; $_; } @opt_args); return "/say $opt_error -- $usage" if defined $opt_error;
return $usage if @$opt_args > 2;
return $usage if not @$opt_args;
$arguments = join(' ', map { $_ = "'$_'" if $_ =~ m/ /; $_; } @$opt_args);
my $arglist = $self->{pbot}->{interpreter}->make_args($arguments); my $arglist = $self->{pbot}->{interpreter}->make_args($arguments);
my ($channel, $trigger) = $self->find_factoid_with_optional_channel( my ($channel, $trigger) = $self->find_factoid_with_optional_channel(
@ -199,25 +199,26 @@ sub cmd_factredo {
my $arguments = $context->{arguments}; my $arguments = $context->{arguments};
my $getopt_error;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
my ($list_undos, $goto_revision); my ($list_undos, $goto_revision);
my @opt_args = $self->{pbot}->{interpreter}->split_line($arguments, strip_quotes => 1);
GetOptionsFromArray( my %opts = (
\@opt_args, l => \$list_undos,
'l:i' => \$list_undos, r => \$goto_revision,
'r=i' => \$goto_revision
); );
return "/say $getopt_error -- $usage" if defined $getopt_error; my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
return $usage if @opt_args > 2; $arguments,
return $usage if not @opt_args; \%opts,
['bundling'],
'l:i',
'r=i',
);
$arguments = join(' ', map { $_ = "'$_'" if $_ =~ m/ /; $_; } @opt_args); return "/say $opt_error -- $usage" if defined $opt_error;
return $usage if @$opt_args > 2;
return $usage if not @$opt_args;
$arguments = join(' ', map { $_ = "'$_'" if $_ =~ m/ /; $_; } @$opt_args);
my ($channel, $trigger) = $self->find_factoid_with_optional_channel( my ($channel, $trigger) = $self->find_factoid_with_optional_channel(
$context->{from}, $context->{arguments}, 'factredo', explicit => 1, exact_channel => 1 $context->{from}, $context->{arguments}, 'factredo', explicit => 1, exact_channel => 1
@ -807,31 +808,30 @@ sub cmd_factrem {
sub cmd_factshow { sub cmd_factshow {
my ($self, $context) = @_; my ($self, $context) = @_;
my $factoids = $self->{pbot}->{factoids}->{data}->{storage};
$context->{preserve_whitespace} = 1;
my $usage = "Usage: factshow [-p] [channel] <keyword>; -p to paste"; my $usage = "Usage: factshow [-p] [channel] <keyword>; -p to paste";
return $usage if not length $context->{arguments}; return $usage if not length $context->{arguments};
my $getopt_error; my %opts;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
my ($paste); my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
my @opt_args = $self->{pbot}->{interpreter}->split_line($context->{arguments}, strip_quotes => 1); $context->{arguments},
GetOptionsFromArray( \%opts,
\@opt_args, ['bundling'],
'p' => \$paste 'p',
); );
return "/say $getopt_error -- $usage" if defined $getopt_error; return "/say $opt_error -- $usage" if defined $opt_error;
return "Too many arguments -- $usage" if @opt_args > 2; return "Too many arguments -- $usage" if @$opt_args > 2;
return "Missing argument -- $usage" if not @opt_args; return "Missing argument -- $usage" if not @$opt_args;
my ($chan, $trig) = @opt_args; my $factoids = $self->{pbot}->{factoids}->{data}->{storage};
$context->{preserve_whitespace} = 1;
my ($chan, $trig) = @$opt_args;
$chan = $context->{from} if not defined $trig; $chan = $context->{from} if not defined $trig;
my $args = join(' ', map { $_ = "'$_'" if $_ =~ m/ /; $_; } @opt_args); my $args = join(' ', map { $_ = "'$_'" if $_ =~ m/ /; $_; } @$opt_args);
my ($channel, $trigger) = $self->find_factoid_with_optional_channel($context->{from}, $args, 'factshow', usage => $usage); my ($channel, $trigger) = $self->find_factoid_with_optional_channel($context->{from}, $args, 'factshow', usage => $usage);
return $channel if not defined $trigger; # if $trigger is not defined, $channel is an error message return $channel if not defined $trigger; # if $trigger is not defined, $channel is an error message
@ -843,7 +843,7 @@ sub cmd_factshow {
my $result = "$trigger_name: "; my $result = "$trigger_name: ";
if ($paste) { if ($opts{p}) {
$result .= $self->{pbot}->{webpaste}->paste($factoids->get_data($channel, $trigger, 'action'), no_split => 1); $result .= $self->{pbot}->{webpaste}->paste($factoids->get_data($channel, $trigger, 'action'), no_split => 1);
$result = "[$channel_name] $result" if $channel ne lc $chan; $result = "[$channel_name] $result" if $channel ne lc $chan;
return $result; return $result;
@ -862,25 +862,25 @@ sub cmd_factlog {
return $usage if not length $context->{arguments}; return $usage if not length $context->{arguments};
my $getopt_error;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
my ($show_hostmask, $actual_timestamp); my ($show_hostmask, $actual_timestamp);
my @opt_args = $self->{pbot}->{interpreter}->split_line($context->{arguments}, strip_quotes => 1);
GetOptionsFromArray( my %opts = (
\@opt_args, h => \$show_hostmask,
'h' => \$show_hostmask, t => \$actual_timestamp,
't' => \$actual_timestamp
); );
return "/say $getopt_error -- $usage" if defined $getopt_error; my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
return "Too many arguments -- $usage" if @opt_args > 2; $context->{arguments},
return "Missing argument -- $usage" if not @opt_args; \%opts,
['bundling'],
qw(h t),
);
my $args = join(' ', map { $_ = "'$_'" if $_ =~ m/ /; $_; } @opt_args); return "/say $opt_error -- $usage" if defined $opt_error;
return "Too many arguments -- $usage" if @$opt_args > 2;
return "Missing argument -- $usage" if not @$opt_args;
my $args = join(' ', map { $_ = "'$_'" if $_ =~ m/ /; $_; } @$opt_args);
my ($channel, $trigger) = $self->find_factoid_with_optional_channel($context->{from}, $args, 'factlog', usage => $usage, exact_channel => 1); my ($channel, $trigger) = $self->find_factoid_with_optional_channel($context->{from}, $args, 'factlog', usage => $usage, exact_channel => 1);

View File

@ -10,7 +10,6 @@ package PBot::Core::Commands::MessageHistory;
use PBot::Imports; use PBot::Imports;
use parent 'PBot::Core::Class'; use parent 'PBot::Core::Class';
use Getopt::Long qw(GetOptionsFromArray);
use Time::HiRes qw(time tv_interval); use Time::HiRes qw(time tv_interval);
use Time::Duration; use Time::Duration;
@ -40,33 +39,30 @@ sub cmd_list_also_known_as {
return $usage; return $usage;
} }
my $getopt_error; my ($show_hostmasks, $show_gecos, $show_nickserv, $show_id, $show_relationship, $show_weak, $show_last_seen, $dont_use_aliases_table, $sort_method);
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
Getopt::Long::Configure("bundling_override"); my %opts = (
h => \$show_hostmasks,
my $sort_method = undef; i => \$show_id,
my ($show_hostmasks, $show_gecos, $show_nickserv, $show_id, $show_relationship, $show_weak, $show_last_seen, $dont_use_aliases_table); l => \$show_last_seen,
my @opt_args = $self->{pbot}->{interpreter}->split_line($context->{arguments}, strip_quotes => 1); n => \$show_nickserv,
GetOptionsFromArray( g => \$show_gecos,
\@opt_args, r => \$show_relationship,
'h' => \$show_hostmasks, w => \$show_weak,
'l' => \$show_last_seen, z => \$dont_use_aliases_table,
'n' => \$show_nickserv, sort => \$sort_method,
'r' => \$show_relationship,
'g' => \$show_gecos,
'w' => \$show_weak,
'z' => \$dont_use_aliases_table,
'i' => \$show_id,
'sort|s=s' => \$sort_method,
); );
return "/say $getopt_error -- $usage" if defined $getopt_error; my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
return "Too many arguments -- $usage" if @opt_args > 1; $context->{arguments},
return "Missing argument -- $usage" if @opt_args != 1; \%opts,
['bundling_override'],
qw(h i l n g r w z sort|s=s),
);
return "/say $opt_error -- $usage" if defined $opt_error;
return "Too many arguments -- $usage" if @$opt_args > 1;
return "Missing argument -- $usage" if @$opt_args != 1;
$sort_method = 'seen' if $show_last_seen and not defined $sort_method; $sort_method = 'seen' if $show_last_seen and not defined $sort_method;
$sort_method = 'nick' if not defined $sort_method; $sort_method = 'nick' if not defined $sort_method;
@ -146,10 +142,10 @@ sub cmd_list_also_known_as {
return "Invalid sort method '$sort_method'; valid methods are: " . join(', ', sort keys %sort) . "; prefix with - to invert sort direction."; return "Invalid sort method '$sort_method'; valid methods are: " . join(', ', sort keys %sort) . "; prefix with - to invert sort direction.";
} }
my %akas = $self->{pbot}->{messagehistory}->{database}->get_also_known_as($opt_args[0], $dont_use_aliases_table); my %akas = $self->{pbot}->{messagehistory}->{database}->get_also_known_as($opt_args->[0], $dont_use_aliases_table);
if (%akas) { if (%akas) {
my $result = "$opt_args[0] also known as:\n"; my $result = "$opt_args->[0] also known as:\n";
my %nicks; my %nicks;
my $sep = ""; my $sep = "";
@ -195,7 +191,7 @@ sub cmd_list_also_known_as {
} }
return $result; return $result;
} else { } else {
return "I don't know anybody named $opt_args[0]."; return "I don't know anybody named $opt_args->[0].";
} }
} }
@ -214,14 +210,7 @@ sub cmd_recall_message {
my @recalls = split /\s\+\s/, $arguments; my @recalls = split /\s\+\s/, $arguments;
my $getopt_error;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
my $result = ''; my $result = '';
Getopt::Long::Configure("bundling_override");
# global state # global state
my ($recall_channel, $raw, $random); my ($recall_channel, $raw, $random);
@ -229,21 +218,34 @@ sub cmd_recall_message {
foreach my $recall (@recalls) { foreach my $recall (@recalls) {
my ($recall_nick, $recall_text, $recall_history, $recall_before, $recall_after, $recall_context, $recall_count); my ($recall_nick, $recall_text, $recall_history, $recall_before, $recall_after, $recall_context, $recall_count);
my @opt_args = $self->{pbot}->{interpreter}->split_line($recall, strip_quotes => 1); my %opts = (
GetOptionsFromArray( 'channel' => \$recall_channel,
\@opt_args, 'history' => \$recall_history,
'channel|c=s' => \$recall_channel, 'text' => \$recall_text,
'history|h=s' => \$recall_history, 'before' => \$recall_before,
'text|t=s' => \$recall_text, 'after' => \$recall_after,
'before|b=i' => \$recall_before, 'count' => \$recall_count,
'after|a=i' => \$recall_after, 'context' => \$recall_context,
'count|n=i' => \$recall_count, 'raw' => \$raw,
'context|x=s' => \$recall_context,
'raw|r' => \$raw,
'random' => \$random, 'random' => \$random,
); );
return "/say $getopt_error -- $usage" if defined $getopt_error; my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
$recall,
\%opts,
['bundling_override'],
'channel|c=s',
'history|h=s',
'text|t=s',
'before|b=i',
'after|a=i',
'count|n=i',
'context|x=s',
'raw|r',
'random',
);
return "/say $opt_error -- $usage" if defined $opt_error;
if (defined $recall_history and defined $recall_text) { if (defined $recall_history and defined $recall_text) {
return "/say $context->{nick}: The -h and -t options cannot be used together."; return "/say $context->{nick}: The -h and -t options cannot be used together.";
@ -254,16 +256,16 @@ sub cmd_recall_message {
my $channel_arg = 1 if defined $recall_channel; my $channel_arg = 1 if defined $recall_channel;
my $history_arg = 1 if defined $recall_history; my $history_arg = 1 if defined $recall_history;
$recall_nick = shift @opt_args if @opt_args; $recall_nick = shift @$opt_args if @$opt_args;
$recall_history = shift @opt_args if @opt_args and not $history_arg and not defined $recall_text; $recall_history = shift @$opt_args if @$opt_args and not $history_arg and not defined $recall_text;
if (not $channel_arg) { if (not $channel_arg) {
$recall_channel = "@opt_args" if @opt_args; $recall_channel = "@$opt_args" if @$opt_args;
} else { } else {
if (defined $recall_history) { if (defined $recall_history) {
$recall_history .= ' '; $recall_history .= ' ';
} }
$recall_history .= "@opt_args" if @opt_args; $recall_history .= "@$opt_args" if @$opt_args;
} }
if (defined $recall_text and not defined $recall_history) { if (defined $recall_text and not defined $recall_history) {

View File

@ -13,8 +13,6 @@ use parent 'PBot::Core::Class';
use Time::HiRes qw/gettimeofday/; use Time::HiRes qw/gettimeofday/;
use Time::Duration qw/concise ago/; use Time::Duration qw/concise ago/;
use Getopt::Long qw/GetOptionsFromArray/;
sub initialize { sub initialize {
my ($self, %conf) = @_; my ($self, %conf) = @_;
$self->{pbot}->{commands}->register(sub { $self->cmd_nicklist(@_) }, "nicklist", 1); $self->{pbot}->{commands}->register(sub { $self->cmd_nicklist(@_) }, "nicklist", 1);
@ -25,30 +23,28 @@ sub cmd_nicklist {
my $usage = "Usage: nicklist (<channel [nick]> | <nick>) [-sort <by>] [-hostmask] [-join]; -hostmask shows hostmasks instead of nicks; -join includes join time"; my $usage = "Usage: nicklist (<channel [nick]> | <nick>) [-sort <by>] [-hostmask] [-join]; -hostmask shows hostmasks instead of nicks; -join includes join time";
my $getopt_error;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
Getopt::Long::Configure("bundling_override");
my $sort_method = 'nick'; my $sort_method = 'nick';
my $full_hostmask = 0; my $full_hostmask = 0;
my $include_join = 0; my $include_join = 0;
my @args = $self->{pbot}->{interpreter}->split_line($context->{arguments}, strip_quotes => 1); my %opts = (
sort => \$sort_method,
GetOptionsFromArray( hostmask => \$full_hostmask,
\@args, join => \$include_join,
'sort|s=s' => \$sort_method,
'hostmask|hm' => \$full_hostmask,
'join|j' => \$include_join,
); );
return "$getopt_error; $usage" if defined $getopt_error; my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
return "Too many arguments -- $usage" if @args > 2; $context->{arguments},
return $usage if @args == 0 or not length $args[0]; \%opts,
['bundling_override'],
'sort|s=s',
'hostmask|hm',
'join|j',
);
return "$opt_error; $usage" if defined $opt_error;
return "Too many arguments -- $usage" if @$opt_args > 2;
return $usage if @$opt_args == 0 or not length $opt_args->[0];
my %sort = ( my %sort = (
'spoken' => sub { 'spoken' => sub {
@ -96,57 +92,57 @@ sub cmd_nicklist {
} }
# insert from channel as first argument if first argument is not a channel # insert from channel as first argument if first argument is not a channel
if ($args[0] !~ /^#/) { if ($opt_args->[0] !~ /^#/) {
unshift @args, $context->{from}; unshift @$opt_args, $context->{from};
} }
my $nicklist = $self->{pbot}->{nicklist}->{nicklist}; my $nicklist = $self->{pbot}->{nicklist}->{nicklist};
# ensure channel has a nicklist # ensure channel has a nicklist
if (not exists $nicklist->{lc $args[0]}) { if (not exists $nicklist->{lc $opt_args->[0]}) {
return "No nicklist for channel $args[0]."; return "No nicklist for channel $opt_args->[0].";
} }
my $result; my $result;
if (@args == 1) { if (@$opt_args == 1) {
# nicklist for a specific channel # nicklist for a specific channel
my $count = keys %{$nicklist->{lc $args[0]}}; my $count = keys %{$nicklist->{lc $opt_args->[0]}};
$result = "$count nick" . ($count == 1 ? '' : 's') . " in $args[0]:\n"; $result = "$count nick" . ($count == 1 ? '' : 's') . " in $opt_args->[0]:\n";
foreach my $entry ( foreach my $entry (
sort { sort {
$sort{$sort_method}->($nicklist->{lc $args[0]}, $sort_direction) $sort{$sort_method}->($nicklist->{lc $opt_args->[0]}, $sort_direction)
} keys %{$nicklist->{lc $args[0]}} } keys %{$nicklist->{lc $opt_args->[0]}}
) { ) {
if ($full_hostmask) { if ($full_hostmask) {
$result .= " $nicklist->{lc $args[0]}->{$entry}->{hostmask}"; $result .= " $nicklist->{lc $opt_args->[0]}->{$entry}->{hostmask}";
} else { } else {
$result .= " $nicklist->{lc $args[0]}->{$entry}->{nick}"; $result .= " $nicklist->{lc $opt_args->[0]}->{$entry}->{nick}";
} }
my $sep = ': '; my $sep = ': ';
if ($nicklist->{lc $args[0]}->{$entry}->{timestamp} > 0) { if ($nicklist->{lc $opt_args->[0]}->{$entry}->{timestamp} > 0) {
my $duration = concise ago (gettimeofday - $nicklist->{lc $args[0]}->{$entry}->{timestamp}); my $duration = concise ago (gettimeofday - $nicklist->{lc $opt_args->[0]}->{$entry}->{timestamp});
$result .= "${sep}last spoken $duration"; $result .= "${sep}last spoken $duration";
$sep = ', '; $sep = ', ';
} }
if ($include_join and $nicklist->{lc $args[0]}->{$entry}->{join} > 0) { if ($include_join and $nicklist->{lc $opt_args->[0]}->{$entry}->{join} > 0) {
my $duration = concise ago (gettimeofday - $nicklist->{lc $args[0]}->{$entry}->{join}); my $duration = concise ago (gettimeofday - $nicklist->{lc $opt_args->[0]}->{$entry}->{join});
$result .= "${sep}joined $duration"; $result .= "${sep}joined $duration";
$sep = ', '; $sep = ', ';
} }
foreach my $key (sort keys %{$nicklist->{lc $args[0]}->{$entry}}) { foreach my $key (sort keys %{$nicklist->{lc $opt_args->[0]}->{$entry}}) {
next if grep { $key eq $_ } qw/nick user host join timestamp hostmask/; next if grep { $key eq $_ } qw/nick user host join timestamp hostmask/;
if ($nicklist->{lc $args[0]}->{$entry}->{$key} == 1) { if ($nicklist->{lc $opt_args->[0]}->{$entry}->{$key} == 1) {
$result .= "$sep$key"; $result .= "$sep$key";
} else { } else {
$result .= "$sep$key => $nicklist->{lc $args[0]}->{$entry}->{$key}"; $result .= "$sep$key => $nicklist->{lc $opt_args->[0]}->{$entry}->{$key}";
} }
$sep = ', '; $sep = ', ';
} }
@ -155,28 +151,28 @@ sub cmd_nicklist {
} else { } else {
# nicklist for a specific user # nicklist for a specific user
if (not exists $nicklist->{lc $args[0]}->{lc $args[1]}) { if (not exists $nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}) {
return "No such nick $args[1] in channel $args[0]."; return "No such nick $opt_args->[1] in channel $opt_args->[0].";
} }
$result = "Nicklist information for $nicklist->{lc $args[0]}->{lc $args[1]}->{hostmask} in $args[0]: "; $result = "Nicklist information for $nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{hostmask} in $opt_args->[0]: ";
my $sep = ''; my $sep = '';
if ($nicklist->{lc $args[0]}->{lc $args[1]}->{timestamp} > 0) { if ($nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{timestamp} > 0) {
my $duration = concise ago (gettimeofday - $nicklist->{lc $args[0]}->{lc $args[1]}->{timestamp}); my $duration = concise ago (gettimeofday - $nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{timestamp});
$result .= "last spoken $duration"; $result .= "last spoken $duration";
$sep = ', '; $sep = ', ';
} }
if ($nicklist->{lc $args[0]}->{lc $args[1]}->{join} > 0) { if ($nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{join} > 0) {
my $duration = concise ago (gettimeofday - $nicklist->{lc $args[0]}->{lc $args[1]}->{join}); my $duration = concise ago (gettimeofday - $nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{join});
$result .= "${sep}joined $duration"; $result .= "${sep}joined $duration";
$sep = ', '; $sep = ', ';
} }
foreach my $key (sort keys %{$nicklist->{lc $args[0]}->{lc $args[1]}}) { foreach my $key (sort keys %{$nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}}) {
next if grep { $key eq $_ } qw/nick user host join timestamp hostmask/; next if grep { $key eq $_ } qw/nick user host join timestamp hostmask/;
$result .= "$sep$key => $nicklist->{lc $args[0]}->{lc $args[1]}->{$key}"; $result .= "$sep$key => $nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{$key}";
$sep = ', '; $sep = ', ';
} }

View File

@ -12,7 +12,6 @@ use parent 'PBot::Core::Class';
use Time::Duration qw/concise duration/; use Time::Duration qw/concise duration/;
use Time::HiRes qw/gettimeofday/; use Time::HiRes qw/gettimeofday/;
use Getopt::Long qw/GetOptionsFromArray/;
sub initialize { sub initialize {
my ($self, %conf) = @_; my ($self, %conf) = @_;
@ -30,26 +29,24 @@ sub cmd_ps {
my $usage = 'Usage: ps [-atu]; -a show all information; -t show running time; -u show user/channel'; my $usage = 'Usage: ps [-atu]; -a show all information; -t show running time; -u show user/channel';
my $getopt_error;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
Getopt::Long::Configure("bundling");
my ($show_all, $show_user, $show_running_time); my ($show_all, $show_user, $show_running_time);
my @opt_args = $self->{pbot}->{interpreter}->split_line($context->{arguments}, strip_quotes => 1); my %opts = (
all => \$show_all,
GetOptionsFromArray( user => \$show_user,
\@opt_args, time => \$show_running_time,
'all|a' => \$show_all,
'user|u' => \$show_user,
'time|t' => \$show_running_time
); );
return "$getopt_error; $usage" if defined $getopt_error; my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
$context->{arguments},
\%opts,
['bundling'],
'all|a',
'user|u',
'time|t',
);
return "$opt_error; $usage" if defined $opt_error;
my @processes; my @processes;
@ -90,28 +87,26 @@ sub cmd_kill {
my $usage = 'Usage: kill [-a] [-t <seconds>] [-s <signal>] [pids...]; -a kill all processes; -t <seconds> kill processes running longer than <seconds>; -s send <signal> to processes'; my $usage = 'Usage: kill [-a] [-t <seconds>] [-s <signal>] [pids...]; -a kill all processes; -t <seconds> kill processes running longer than <seconds>; -s send <signal> to processes';
my $getopt_error;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
Getopt::Long::Configure("bundling");
my ($kill_all, $kill_time, $signal); my ($kill_all, $kill_time, $signal);
my @opt_args = $self->{pbot}->{interpreter}->split_line($context->{arguments}, preserve_escapes => 1, strip_quotes => 1); my %opts = (
all => \$kill_all,
GetOptionsFromArray( time => \$kill_time,
\@opt_args, signal => \$signal,
'all|a' => \$kill_all,
'time|t=i' => \$kill_time,
'signal|s=s' => \$signal,
); );
return "$getopt_error; $usage" if defined $getopt_error; my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
$context->{arguments},
\%opts,
['bundling'],
'all|a',
'time|t=i',
'signal|s=s',
);
if (not $kill_all and not $kill_time and not @opt_args) { return "$opt_error; $usage" if defined $opt_error;
if (not $kill_all and not $kill_time and not @$opt_args) {
return "Must specify PIDs to kill unless options -a or -t are provided."; return "Must specify PIDs to kill unless options -a or -t are provided.";
} }
@ -132,7 +127,7 @@ sub cmd_kill {
push @pids, $pid; push @pids, $pid;
} }
} else { } else {
foreach my $pid (@opt_args) { foreach my $pid (@$opt_args) {
return "No such pid $pid." if not exists $self->{pbot}->{process_manager}->{processes}->{$pid}; return "No such pid $pid." if not exists $self->{pbot}->{process_manager}->{processes}->{$pid};
push @pids, $pid; push @pids, $pid;
} }

View File

@ -15,15 +15,14 @@ use parent 'PBot::Core::Class', 'PBot::Core::Registerable';
use PBot::Imports; use PBot::Imports;
use PBot::Core::MessageHistory::Constants ':all'; use PBot::Core::MessageHistory::Constants ':all';
use PBot::Core::Utils::ValidateString;
use Time::HiRes qw/gettimeofday/;
use Time::Duration;
use Encode; use Encode;
use Getopt::Long qw(GetOptionsFromArray);
use Time::Duration;
use Time::HiRes qw(gettimeofday);
use Unicode::Truncate; use Unicode::Truncate;
use PBot::Core::Utils::ValidateString;
sub initialize { sub initialize {
my ($self, %conf) = @_; my ($self, %conf) = @_;
@ -422,7 +421,7 @@ sub interpret {
if (@factoids == 1) { if (@factoids == 1) {
# found the factoid's channel # found the factoid's channel
($fact_channel, $fact_trigger) = $factoids[0]; ($fact_channel, $fact_trigger) = @{$factoids[0]};
} else { } else {
# more than one factoid found, normally we would prompt to disambiguate # more than one factoid found, normally we would prompt to disambiguate
# but in this case we'll just go ahead and assume global # but in this case we'll just go ahead and assume global
@ -1380,4 +1379,38 @@ sub lc_args {
for (my $i = 0; $i < @$args; $i++) { $args->[$i] = lc $args->[$i]; } for (my $i = 0; $i < @$args; $i++) { $args->[$i] = lc $args->[$i]; }
} }
# getopt boilerplate in one place
# 99% of our getopt use is on a string
sub getopt {
my $self = shift;
$self->getopt_from_string(@_);
}
# getopt_from_string() uses our split_line() function instead of
# GetOpt::Long::GetOptionsFromString's Text::ParseWords
sub getopt_from_string {
my ($self, $string, $result, $config, @opts) = @_;
my @opt_args = $self->split_line($string, strip_quotes => 1);
return $self->getopt_from_array(\@opt_args, $result, $config, @opts);
}
sub getopt_from_array {
my ($self, $opt_args, $result, $config, @opts) = @_;
my $opt_error;
local $SIG{__WARN__} = sub {
$opt_error = shift;
chomp $opt_error;
};
Getopt::Long::Configure(@$config);
GetOptionsFromArray($opt_args, $result, @opts);
return ($opt_args, $opt_error);
}
1; 1;

View File

@ -10,8 +10,6 @@ use parent 'PBot::Plugin::Base';
use PBot::Imports; use PBot::Imports;
use Getopt::Long qw(GetOptionsFromArray);
sub initialize { sub initialize {
my ($self, %conf) = @_; my ($self, %conf) = @_;
@ -31,29 +29,24 @@ sub unload {
sub cmd_date { sub cmd_date {
my ($self, $context) = @_; my ($self, $context) = @_;
my $usage = "date [-u <user account>] [timezone]"; my $usage = "Usage: date [-u <user account>] [timezone]";
my $getopt_error; my %opts;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
my ($user_override, $show_usage); my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
my @opt_args = $self->{pbot}->{interpreter}->split_line($context->{arguments}, strip_quotes => 1); $context->{arguments},
\%opts,
Getopt::Long::Configure("bundling"); ['bundling'],
GetOptionsFromArray( 'u=s',
\@opt_args, 'h',
'u=s' => \$user_override,
'h' => \$show_usage
); );
return $usage if $show_usage; return $usage if $opts{h};
return "/say $getopt_error -- $usage" if defined $getopt_error; return "/say $opt_error -- $usage" if $opt_error;
$context->{arguments} = "@opt_args"; $context->{arguments} = "@$opt_args";
my $user_override = $opts{u};
my $tz_override; my $tz_override;
# check for user timezone metadata # check for user timezone metadata

View File

@ -11,8 +11,6 @@ use parent 'PBot::Plugin::Base';
use PBot::Imports; use PBot::Imports;
use Getopt::Long qw(GetOptionsFromArray);
sub initialize { sub initialize {
my ($self, %conf) = @_; my ($self, %conf) = @_;

View File

@ -16,7 +16,6 @@ use PBot::Imports;
use HTML::Entities; use HTML::Entities;
use Time::Duration; use Time::Duration;
use Time::HiRes qw(gettimeofday); use Time::HiRes qw(gettimeofday);
use Getopt::Long qw(GetOptionsFromArray);
use PBot::Plugin::Quotegrabs::Storage::SQLite; # use SQLite backend for quotegrabs database use PBot::Plugin::Quotegrabs::Storage::SQLite; # use SQLite backend for quotegrabs database
#use PBot::Plugin::Quotegrabs::Storage::Hashtable; # use Perl hashtable backend for quotegrabs database #use PBot::Plugin::Quotegrabs::Storage::Hashtable; # use Perl hashtable backend for quotegrabs database
@ -60,17 +59,20 @@ sub export_quotegrabs {
my $text; my $text;
my $table_id = 1; my $table_id = 1;
my $had_table = 0; my $had_table = 0;
open FILE, "> $self->{export_path}" or return "Could not open export path.";
my $time = localtime; my $time = localtime;
my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick'); my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick');
open FILE, "> $self->{export_path}" or return "Could not open export path.";
print FILE "<html>\n<head><link href=\"css/blue.css\" rel=\"stylesheet\" type=\"text/css\">\n"; print FILE "<html>\n<head><link href=\"css/blue.css\" rel=\"stylesheet\" type=\"text/css\">\n";
print FILE '<script type="text/javascript" src="js/jquery-latest.js"></script>' . "\n"; print FILE '<script type="text/javascript" src="js/jquery-latest.js"></script>' . "\n";
print FILE '<script type="text/javascript" src="js/jquery.tablesorter.js"></script>' . "\n"; print FILE '<script type="text/javascript" src="js/jquery.tablesorter.js"></script>' . "\n";
print FILE '<script type="text/javascript" src="js/picnet.table.filter.min.js"></script>' . "\n"; print FILE '<script type="text/javascript" src="js/picnet.table.filter.min.js"></script>' . "\n";
print FILE "</head>\n<body><i>Generated at $time</i><hr><h2>$botnick\'s Quotegrabs</h2>\n"; print FILE "</head>\n<body><i>Generated at $time</i><hr><h2>$botnick\'s Quotegrabs</h2>\n";
my $i = 0;
my $last_channel = ""; my $i = 0;
my $last_channel = '';
foreach my $quotegrab (sort { $$a{channel} cmp $$b{channel} or $$a{nick} cmp $$b{nick} } @$quotegrabs) { foreach my $quotegrab (sort { $$a{channel} cmp $$b{channel} or $$a{nick} cmp $$b{nick} } @$quotegrabs) {
if (not $quotegrab->{channel} =~ /^$last_channel$/i) { if (not $quotegrab->{channel} =~ /^$last_channel$/i) {
print FILE "<a href='#" . encode_entities($quotegrab->{channel}) . "'>" . encode_entities($quotegrab->{channel}) . "</a><br>\n"; print FILE "<a href='#" . encode_entities($quotegrab->{channel}) . "'>" . encode_entities($quotegrab->{channel}) . "</a><br>\n";
@ -78,7 +80,7 @@ sub export_quotegrabs {
} }
} }
$last_channel = ""; $last_channel = '';
foreach my $quotegrab (sort { $$a{channel} cmp $$b{channel} or lc $$a{nick} cmp lc $$b{nick} } @$quotegrabs) { foreach my $quotegrab (sort { $$a{channel} cmp $$b{channel} or lc $$a{nick} cmp lc $$b{nick} } @$quotegrabs) {
if (not $quotegrab->{channel} =~ /^$last_channel$/i) { if (not $quotegrab->{channel} =~ /^$last_channel$/i) {
print FILE "</tbody>\n</table>\n" if $had_table; print FILE "</tbody>\n</table>\n" if $had_table;
@ -99,8 +101,11 @@ sub export_quotegrabs {
$last_channel = $quotegrab->{channel}; $last_channel = $quotegrab->{channel};
$i++; $i++;
if ($i % 2) { print FILE "<tr bgcolor=\"#dddddd\">\n"; } if ($i % 2) {
else { print FILE "<tr>\n"; } print FILE "<tr bgcolor=\"#dddddd\">\n";
} else {
print FILE "<tr>\n";
}
print FILE "<td>" . ($quotegrab->{id}) . "</td>"; print FILE "<td>" . ($quotegrab->{id}) . "</td>";
@ -111,8 +116,11 @@ sub export_quotegrabs {
my $nick; my $nick;
$text = $quotegrab->{text}; $text = $quotegrab->{text};
if ($text =~ s/^\/me\s+//) { $nick = "* $nicks[0]"; } if ($text =~ s/^\/me\s+//) {
else { $nick = "<$nicks[0]>"; } $nick = "* $nicks[0]";
} else {
$nick = "<$nicks[0]>";
}
$text = "<td><b>" . encode_entities($nick) . "</b> " . encode_entities($text) . "</td>\n"; $text = "<td><b>" . encode_entities($nick) . "</b> " . encode_entities($text) . "</td>\n";
print FILE $text; print FILE $text;
@ -124,29 +132,30 @@ sub export_quotegrabs {
print FILE "</tbody>\n</table>\n" if $had_table; print FILE "</tbody>\n</table>\n" if $had_table;
print FILE "<script type='text/javascript'>\n"; print FILE "<script type='text/javascript'>\n";
$table_id--; $table_id--;
print FILE '$(document).ready(function() {' . "\n"; print FILE '$(document).ready(function() {' . "\n";
while ($table_id > 0) { while ($table_id > 0) {
print FILE '$("#table' . $table_id . '").tablesorter();' . "\n"; print FILE '$("#table' . $table_id . '").tablesorter();' . "\n";
print FILE '$("#table' . $table_id . '").tableFilter();' . "\n"; print FILE '$("#table' . $table_id . '").tableFilter();' . "\n";
$table_id--; $table_id--;
} }
print FILE "});\n"; print FILE "});\n";
print FILE "</script>\n"; print FILE "</script>\n";
print FILE "</body>\n</html>\n"; print FILE "</body>\n</html>\n";
close(FILE);
close FILE;
return "$i quotegrabs exported."; return "$i quotegrabs exported.";
} }
sub cmd_grab_quotegrab { sub cmd_grab_quotegrab {
my ($self, $context) = @_; my ($self, $context) = @_;
if (not defined $context->{from}) { if (not length $context->{arguments}) {
$self->{pbot}->{logger}->log("Command missing ~from parameter!\n");
return "";
}
if (not defined $context->{arguments} or not length $context->{arguments}) {
return return
"Usage: grab <nick> [history [channel]] [+ <nick> [history [channel]] ...] -- where [history] is an optional regex argument; e.g., to grab a message containing 'pizza', use `grab nick pizza`; you can chain grabs with + to grab multiple messages"; "Usage: grab <nick> [history [channel]] [+ <nick> [history [channel]] ...] -- where [history] is an optional regex argument; e.g., to grab a message containing 'pizza', use `grab nick pizza`; you can chain grabs with + to grab multiple messages";
} }
@ -160,8 +169,12 @@ sub cmd_grab_quotegrab {
foreach my $grab (@grabs) { foreach my $grab (@grabs) {
($grab_nick, $grab_history, $channel) = $self->{pbot}->{interpreter}->split_line($grab, strip_quotes => 1); ($grab_nick, $grab_history, $channel) = $self->{pbot}->{interpreter}->split_line($grab, strip_quotes => 1);
$grab_history = $context->{nick} eq $grab_nick ? 2 : 1 if not defined $grab_history; # skip grab command if grabbing self without arguments if (not defined $grab_history) {
$channel = $context->{from} if not defined $channel; # skip grab command if grabbing self without arguments
$grab_history = lc $context->{nick} eq $grab_nick ? 2 : 1;
}
$channel //= $context->{from};
if (not $channel =~ m/^#/) { if (not $channel =~ m/^#/) {
return "'$channel' is not a valid channel; usage: grab <nick> [[history] channel] (you must specify a history parameter before the channel parameter)"; return "'$channel' is not a valid channel; usage: grab <nick> [[history] channel] (you must specify a history parameter before the channel parameter)";
@ -169,7 +182,9 @@ sub cmd_grab_quotegrab {
my ($account, $found_nick) = $self->{pbot}->{messagehistory}->{database}->find_message_account_by_nick($grab_nick); my ($account, $found_nick) = $self->{pbot}->{messagehistory}->{database}->find_message_account_by_nick($grab_nick);
if (not defined $account) { return "I don't know anybody named $grab_nick"; } if (not defined $account) {
return "I don't know anybody named $grab_nick";
}
$found_nick =~ s/!.*$//; $found_nick =~ s/!.*$//;
@ -180,7 +195,10 @@ sub cmd_grab_quotegrab {
if ($grab_history =~ /^\d+$/) { if ($grab_history =~ /^\d+$/) {
# integral history # integral history
my $max_messages = $self->{pbot}->{messagehistory}->{database}->get_max_messages($account, $channel); my $max_messages = $self->{pbot}->{messagehistory}->{database}->get_max_messages($account, $channel);
if ($grab_history < 1 || $grab_history > $max_messages) { return "Please choose a history between 1 and $max_messages"; }
if ($grab_history < 1 || $grab_history > $max_messages) {
return "Please choose a history between 1 and $max_messages";
}
$grab_history--; $grab_history--;
@ -189,20 +207,29 @@ sub cmd_grab_quotegrab {
# regex history # regex history
$message = $self->{pbot}->{messagehistory}->{database}->recall_message_by_text($account, $channel, $grab_history, 'grab'); $message = $self->{pbot}->{messagehistory}->{database}->recall_message_by_text($account, $channel, $grab_history, 'grab');
if (not defined $message) { return "No such message for nick $grab_nick in channel $channel containing text '$grab_history'"; } if (not defined $message) {
return "No such message for nick $grab_nick in channel $channel containing text '$grab_history'";
}
} }
$self->{pbot}->{logger}->log("$context->{nick} ($context->{from}) grabbed <$grab_nick/$channel> $message->{msg}\n"); $self->{pbot}->{logger}->log("$context->{nick} ($context->{from}) grabbed <$grab_nick/$channel> $message->{msg}\n");
if (not defined $grab_nicks) { $grab_nicks = $grab_nick; } if (not defined $grab_nicks) {
else { $grab_nicks .= "+$grab_nick"; } $grab_nicks = $grab_nick;
} else {
$grab_nicks .= "+$grab_nick";
}
my $text = $message->{msg}; my $text = $message->{msg};
if (not defined $grab_text) { $grab_text = $text; } if (not defined $grab_text) {
else { $grab_text = $text;
if ($text =~ s/^\/me\s+//) { $grab_text .= " * $grab_nick $text"; } } else {
else { $grab_text .= " <$grab_nick> $text"; } if ($text =~ s/^\/me\s+//) {
$grab_text .= " * $grab_nick $text";
} else {
$grab_text .= " <$grab_nick> $text";
}
} }
} }
@ -216,9 +243,11 @@ sub cmd_grab_quotegrab {
$quotegrab->{id} = $self->{database}->add_quotegrab($quotegrab); $quotegrab->{id} = $self->{database}->add_quotegrab($quotegrab);
if (not defined $quotegrab->{id}) { return "Failed to grab quote."; } if (not defined $quotegrab->{id}) {
return "Failed to grab quote.";
}
$self->export_quotegrabs(); $self->export_quotegrabs;
my $text = $quotegrab->{text}; my $text = $quotegrab->{text};
($grab_nick) = split /\+/, $grab_nicks, 2; ($grab_nick) = split /\+/, $grab_nicks, 2;
@ -239,21 +268,28 @@ sub cmd_delete_quotegrab {
my $quotegrab = $self->{database}->get_quotegrab($context->{arguments}); my $quotegrab = $self->{database}->get_quotegrab($context->{arguments});
if (not defined $quotegrab) { return "/msg $context->{nick} No quotegrab matching id $context->{arguments} found."; } if (not defined $quotegrab) {
return "/msg $context->{nick} No quotegrab matching id $context->{arguments} found.";
}
if (not $self->{pbot}->{users}->loggedin_admin($context->{from}, $context->{hostmask}) and $quotegrab->{grabbed_by} ne $context->{hostmask}) { if (not $self->{pbot}->{users}->loggedin_admin($context->{from}, $context->{hostmask})
and $quotegrab->{grabbed_by} ne $context->{hostmask})
{
return "You are not the grabber of this quote."; return "You are not the grabber of this quote.";
} }
$self->{database}->delete_quotegrab($context->{arguments}); $self->{database}->delete_quotegrab($context->{arguments});
$self->export_quotegrabs(); $self->export_quotegrabs;
my $text = $quotegrab->{text}; my $text = $quotegrab->{text};
my ($first_nick) = split /\+/, $quotegrab->{nick}, 2; my ($first_nick) = split /\+/, $quotegrab->{nick}, 2;
if ($text =~ s/^\/me\s+//) { return "Deleted $context->{arguments}: * $first_nick $text"; } if ($text =~ s/^\/me\s+//) {
else { return "Deleted $context->{arguments}: <$first_nick> $text"; } return "Deleted $context->{arguments}: * $first_nick $text";
} else {
return "Deleted $context->{arguments}: <$first_nick> $text";
}
} }
sub cmd_show_quotegrab { sub cmd_show_quotegrab {
@ -261,63 +297,72 @@ sub cmd_show_quotegrab {
my $quotegrab = $self->{database}->get_quotegrab($context->{arguments}); my $quotegrab = $self->{database}->get_quotegrab($context->{arguments});
if (not defined $quotegrab) { return "/msg $context->{nick} No quotegrab matching id $context->{arguments} found."; } if (not defined $quotegrab) {
return "/msg $context->{nick} No quotegrab matching id $context->{arguments} found.";
}
my $timestamp = $quotegrab->{timestamp}; my $timestamp = $quotegrab->{timestamp};
my $ago = ago(gettimeofday - $timestamp); my $ago = ago(gettimeofday - $timestamp);
my $text = $quotegrab->{text}; my $text = $quotegrab->{text};
my ($first_nick) = split /\+/, $quotegrab->{nick}, 2; my ($first_nick) = split /\+/, $quotegrab->{nick}, 2;
my $result = "$context->{arguments}: grabbed by $quotegrab->{grabbed_by} in $quotegrab->{channel} on " . localtime($timestamp) . " [$ago]";
if ($text =~ s/^\/me\s+//) { if ($text =~ s/^\/me\s+//) {
return "$context->{arguments}: grabbed by $quotegrab->{grabbed_by} in $quotegrab->{channel} on " . localtime($timestamp) . " [$ago] * $first_nick $text"; return "$result * $first_nick $text";
} else { } else {
return "$context->{arguments}: grabbed by $quotegrab->{grabbed_by} in $quotegrab->{channel} on " . localtime($timestamp) . " [$ago] <$first_nick> $text"; return "$result <$first_nick> $text";
} }
} }
sub cmd_show_random_quotegrab { sub cmd_show_random_quotegrab {
my ($self, $context) = @_; my ($self, $context) = @_;
my @quotes = ();
my ($nick_search, $channel_search, $text_search);
if (not defined $context->{from}) {
$self->{pbot}->{logger}->log("Command missing ~from parameter!\n");
return "";
}
my $usage = 'Usage: rq [nick [channel [text]]] [-c <channel>] [-t <text>]'; my $usage = 'Usage: rq [nick [channel [text]]] [-c <channel>] [-t <text>]';
if (defined $context->{arguments}) { my ($nick_search, $channel_search, $text_search);
my $getopt_error;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
my @opt_args = $self->{pbot}->{interpreter}->split_line($context->{arguments}, preserve_escapes => 1, strip_quotes => 1); if (length $context->{arguments}) {
GetOptionsFromArray( my %opts = (
\@opt_args, channel => \$channel_search,
'channel|c=s' => \$channel_search, text => \$text_search,
'text|t=s' => \$text_search
); );
return "$getopt_error -- $usage" if defined $getopt_error; my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
$context->{arguments},
\%opts,
['bundling'],
'channel|c=s',
'text|t=s',
);
$nick_search = shift @opt_args; return "$opt_error -- $usage" if defined $opt_error;
$channel_search = shift @opt_args if not defined $channel_search;
$text_search = shift @opt_args if not defined $text_search;
if ($nick_search =~ m/^#/) { $nick_search = shift @$opt_args;
if (not defined $channel_search) {
$channel_search = shift @$opt_args;
}
if (not defined $text_search) {
$text_search = shift @$opt_args;
}
if (defined $nick_search and $nick_search =~ m/^#/) {
my $tmp = $channel_search; my $tmp = $channel_search;
$channel_search = $nick_search; $channel_search = $nick_search;
$nick_search = $tmp; $nick_search = $tmp;
} }
if (not defined $channel_search) { $channel_search = $context->{from}; } if (not defined $channel_search) {
$channel_search = $context->{from};
}
} }
if (defined $channel_search and $channel_search !~ /^#/) { if (defined $channel_search and $channel_search !~ /^#/) {
if ($channel_search eq $context->{nick}) { $channel_search = undef; } if ($channel_search eq $context->{nick}) {
$channel_search = undef;
}
elsif ($channel_search =~ m/^\./) { elsif ($channel_search =~ m/^\./) {
# do nothing # do nothing
} else { } else {
@ -330,11 +375,17 @@ sub cmd_show_random_quotegrab {
if (not defined $quotegrab) { if (not defined $quotegrab) {
my $result = "No quotes grabbed "; my $result = "No quotes grabbed ";
if (defined $nick_search) { $result .= "for nick $nick_search "; } if (defined $nick_search) {
$result .= "for nick $nick_search ";
}
if (defined $channel_search) { $result .= "in channel $channel_search "; } if (defined $channel_search) {
$result .= "in channel $channel_search ";
}
if (defined $text_search) { $result .= "matching text '$text_search' "; } if (defined $text_search) {
$result .= "matching text '$text_search' ";
}
return $result . "yet ($usage)."; return $result . "yet ($usage).";
} }
@ -342,10 +393,18 @@ sub cmd_show_random_quotegrab {
my $text = $quotegrab->{text}; my $text = $quotegrab->{text};
my ($first_nick) = split /\+/, $quotegrab->{nick}, 2; my ($first_nick) = split /\+/, $quotegrab->{nick}, 2;
my $channel = '';
$channel_search //= '';
if ($channel_search eq '.*' or $quotegrab->{channel} ne $context->{from}) {
$channel = "[$quotegrab->{channel}] ";
}
if ($text =~ s/^\/me\s+//) { if ($text =~ s/^\/me\s+//) {
return "$quotegrab->{id}: " . (($channel_search eq '.*' or $quotegrab->{channel} ne $context->{from}) ? "[$quotegrab->{channel}] " : "") . "* $first_nick $text"; return "$quotegrab->{id}: $channel" . "* $first_nick $text";
} else { } else {
return "$quotegrab->{id}: " . (($channel_search eq '.*' or $quotegrab->{channel} ne $context->{from}) ? "[$quotegrab->{channel}] " : "") . "<$first_nick> $text"; return "$quotegrab->{id}: $channel" . "<$first_nick> $text";
} }
} }

View File

@ -12,9 +12,8 @@ use parent 'PBot::Plugin::Base';
use PBot::Imports; use PBot::Imports;
use DBI; use DBI;
use Time::Duration qw/ago concise duration/; use Time::Duration qw(ago concise duration);
use Time::HiRes qw/time/; use Time::HiRes qw(time);
use Getopt::Long qw/GetOptionsFromArray/;
sub initialize { sub initialize {
my ($self, %conf) = @_; my ($self, %conf) = @_;
@ -62,26 +61,28 @@ sub cmd_remindme {
my ($channel, $repeats, $text, $time, $list_reminders, $delete_id); my ($channel, $repeats, $text, $time, $list_reminders, $delete_id);
my $getopt_error; my %opts = (
local $SIG{__WARN__} = sub { c => \$channel,
$getopt_error = shift; r => \$repeats,
chomp $getopt_error; m => \$text,
}; t => \$time,
l => \$list_reminders,
my @opt_args = $self->{pbot}->{interpreter}->split_line($context->{arguments}, strip_quotes => 1); d => \$delete_id,
Getopt::Long::Configure("bundling");
GetOptionsFromArray(
\@opt_args,
'r=i' => \$repeats,
't=s' => \$time,
'c=s' => \$channel,
'm=s' => \$text,
'l:s' => \$list_reminders,
'd=i' => \$delete_id
); );
return "$getopt_error -- $usage" if defined $getopt_error; my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
$context->{arguments},
\%opts,
['bundling'],
'r=i',
't=s',
'c=s',
'm=s',
'l:s',
'd=i',
);
return "$opt_error -- $usage" if defined $opt_error;
# option -l was provided; list reminders # option -l was provided; list reminders
if (defined $list_reminders) { if (defined $list_reminders) {
@ -187,9 +188,9 @@ sub cmd_remindme {
$text //= ''; $text //= '';
# add to the reminder text anything left in the arguments # add to the reminder text anything left in the arguments
if (@opt_args) { if (@$opt_args) {
$text .= ' ' if length $text; $text .= ' ' if length $text;
$text .= join ' ', @opt_args; $text .= "@$opt_args";
} }
return "Please use -t to specify a time for this reminder." if not $time; return "Please use -t to specify a time for this reminder." if not $time;

View File

@ -12,7 +12,6 @@ use PBot::Imports;
use PBot::Core::Utils::LWPUserAgentCached; use PBot::Core::Utils::LWPUserAgentCached;
use XML::LibXML; use XML::LibXML;
use Getopt::Long qw(GetOptionsFromArray);
sub initialize { sub initialize {
my ($self, %conf) = @_; my ($self, %conf) = @_;
@ -26,28 +25,27 @@ sub unload {
sub cmd_weather { sub cmd_weather {
my ($self, $context) = @_; my ($self, $context) = @_;
my $usage = "Usage: weather (<location> | -u <user account>)"; my $usage = "Usage: weather (<location> | -u <user account>)";
my $getopt_error;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
my $arguments = $context->{arguments}; my $arguments = $context->{arguments};
Getopt::Long::Configure("bundling"); my %opts;
my ($user_override, $show_usage); my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
my @opt_args = $self->{pbot}->{interpreter}->split_line($arguments, strip_quotes => 1); $arguments,
GetOptionsFromArray( \%opts,
\@opt_args, ['bundling'],
'u=s' => \$user_override, 'u=s',
'h' => \$show_usage 'h',
); );
return $usage if $show_usage; return $usage if $opts{h};
return "/say $getopt_error -- $usage" if defined $getopt_error; return "/say $opt_error -- $usage" if defined $opt_error;
$arguments = "@opt_args";
$arguments = "@$opt_args";
my $user_override = $opts{u};
if (defined $user_override) { if (defined $user_override) {
my $userdata = $self->{pbot}->{users}->{storage}->get_data($user_override); my $userdata = $self->{pbot}->{users}->{storage}->get_data($user_override);

View File

@ -13,7 +13,6 @@ use PBot::Core::Utils::LWPUserAgentCached;
use JSON; use JSON;
use URI::Escape qw/uri_escape_utf8/; use URI::Escape qw/uri_escape_utf8/;
use Getopt::Long qw(GetOptionsFromArray);
sub initialize { sub initialize {
my ($self, %conf) = @_; my ($self, %conf) = @_;
@ -31,50 +30,45 @@ sub cmd_wttr {
my $arguments = $context->{arguments}; my $arguments = $context->{arguments};
my @wttr_options = ( my @wttr_options = (
"default", 'default',
"all", 'all',
"conditions", 'conditions',
"forecast", 'forecast',
"feelslike", 'feelslike',
"uvindex", 'uvindex',
"visibility", 'visibility',
"dewpoint", 'dewpoint',
"heatindex", 'heatindex',
"cloudcover", 'cloudcover',
"wind", 'wind',
"sun", 'sun',
"sunhours", 'sunhours',
"moon", 'moon',
"chances", 'chances',
"snowfall", 'snowfall',
"location", 'location',
"qlocation", 'qlocation',
"time", 'time',
"population", 'population',
); );
my $usage = "Usage: wttr (<location> | -u <user account>) [" . join(' ', map { "-$_" } @wttr_options) . "]; to have me remember your location, use `my location <location>`."; my $usage = "Usage: wttr (<location> | -u <user account>) [" . join(' ', map { "-$_" } @wttr_options) . "]; to have me remember your location, use `my location <location>`.";
my $getopt_error;
local $SIG{__WARN__} = sub {
$getopt_error = shift;
chomp $getopt_error;
};
Getopt::Long::Configure("bundling_override", "ignorecase_always");
my %options; my %options;
my @opt_args = $self->{pbot}->{interpreter}->split_line($arguments, strip_quotes => 1);
GetOptionsFromArray( my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
\@opt_args, $arguments,
\%options, \%options,
['bundling_override', 'ignorecase_always'],
'u=s', 'u=s',
'h', 'h',
@wttr_options @wttr_options,
); );
return "/say $getopt_error -- $usage" if defined $getopt_error; return "/say $opt_error -- $usage" if defined $opt_error;
return $usage if exists $options{h}; return $usage if exists $options{h};
$arguments = "@opt_args";
$arguments = "@$opt_args";
if (defined $options{u}) { if (defined $options{u}) {
my $username = delete $options{u}; my $username = delete $options{u};

View File

@ -25,8 +25,8 @@ use PBot::Imports;
# These are set by the /misc/update_version script # These are set by the /misc/update_version script
use constant { use constant {
BUILD_NAME => "PBot", BUILD_NAME => "PBot",
BUILD_REVISION => 4327, BUILD_REVISION => 4328,
BUILD_DATE => "2021-07-28", BUILD_DATE => "2021-07-30",
}; };
sub initialize {} sub initialize {}