From 926d57990b51d04b224fd6bf2ada5520feb8bc5c Mon Sep 17 00:00:00 2001 From: Pragmatic Software Date: Fri, 30 Jul 2021 19:01:24 -0700 Subject: [PATCH] Support named-parameters in command registration - convert several plugins to use named-parameters - misc clean-ups in unrelated files --- lib/PBot/Core.pm | 2 +- lib/PBot/Core/Commands.pm | 46 +++++++++++++++++++++++++++----- lib/PBot/Core/Handlers.pm | 4 --- lib/PBot/Plugin/ActionTrigger.pm | 9 +++++-- lib/PBot/Plugin/Battleship.pm | 8 ++++-- lib/PBot/Plugin/Connect4.pm | 9 +++++-- lib/PBot/Plugin/Date.pm | 8 ++++-- lib/PBot/Plugin/GoogleSearch.pm | 10 ++++--- lib/PBot/Plugin/ParseDate.pm | 8 ++++-- lib/PBot/Plugin/Plang.pm | 7 ++--- lib/PBot/Plugin/Quotegrabs.pm | 8 +++--- lib/PBot/Plugin/RemindMe.pm | 8 ++++-- lib/PBot/Plugin/RestrictedMod.pm | 11 ++++---- lib/PBot/Plugin/RunCommand.pm | 9 +++++-- lib/PBot/Plugin/Spinach.pm | 3 ++- lib/PBot/Plugin/Weather.pm | 9 +++++-- lib/PBot/Plugin/Wolfram.pm | 9 +++++-- lib/PBot/Plugin/Wttr.pm | 9 +++++-- lib/PBot/VERSION.pm | 2 +- 19 files changed, 130 insertions(+), 49 deletions(-) diff --git a/lib/PBot/Core.pm b/lib/PBot/Core.pm index d42b709e..32191a4b 100644 --- a/lib/PBot/Core.pm +++ b/lib/PBot/Core.pm @@ -82,7 +82,7 @@ sub initialize { # process command-line arguments for path and registry overrides foreach my $arg (@ARGV) { - if ($arg =~ m/^-?(?:general\.)?((?:data|module|plugin|update)_dir)=(.*)$/) { + if ($arg =~ m/^-?(?:general\.)?((?:data|module|update)_dir)=(.*)$/) { # check command-line arguments for directory overrides my $override = $1; my $value = $2; diff --git a/lib/PBot/Core/Commands.pm b/lib/PBot/Core/Commands.pm index f5470e8b..8c25bde1 100644 --- a/lib/PBot/Core/Commands.pm +++ b/lib/PBot/Core/Commands.pm @@ -10,13 +10,12 @@ package PBot::Core::Commands; use parent 'PBot::Core::Class'; use PBot::Imports; - use PBot::Core::Utils::LoadModules qw/load_modules/; sub initialize { my ($self, %conf) = @_; - # registered commands hash table + # registered commands hashtable $self->{commands} = {}; # command metadata stored as a HashObject @@ -31,20 +30,45 @@ sub initialize { sub load_commands { my ($self) = @_; - # load commands in Commands directory $self->{pbot}->{logger}->log("Loading commands:\n"); load_modules($self, 'PBot::Core::Commands'); } +# named parameters interface to register() +sub add { + my ($self, %args) = @_; + + $self->register( + delete $args{subref}, + delete $args{name}, + delete $args{requires_cap}, + delete $args{help}, + ); + + # die if any unhandled arguments were passed + foreach my $key (keys %args) { + $self->{pbot}->{logger}->log("Commands: error: extra arguments provided to add(): $key\n"); + die; + } +} + +# alias to unregister() for conisistency +sub remove { + my ($self) = @_; + $self->unregister(@_); +} + sub register { - my ($self, $subref, $name, $requires_cap) = @_; + my ($self, $subref, $name, $requires_cap, $help) = @_; if (not defined $subref or not defined $name) { Carp::croak("Missing parameters to Commands::register"); } $name = lc $name; + $requires_cap //= 0; + $help //= ''; if (exists $self->{commands}->{$name}) { $self->{pbot}->{logger}->log("Commands: warning: overwriting existing command $name\n"); @@ -52,19 +76,27 @@ sub register { # register command $self->{commands}->{$name} = { - requires_cap => $requires_cap // 0, + requires_cap => $requires_cap, subref => $subref, }; # update command metadata if (not $self->{metadata}->exists($name)) { # create new metadata - $self->{metadata}->add($name, { requires_cap => $requires_cap, help => '' }, 1); + $self->{metadata}->add($name, { requires_cap => $requires_cap, help => $help }, 1); } else { - # metadata already exists, just update requires_cap unless it's already set. + # metadata already exists + # we update data unless it's already set so the metadata file can be edited manually. + + # update requires_cap unless it's already set. if (not defined $self->get_meta($name, 'requires_cap')) { $self->{metadata}->set($name, 'requires_cap', $requires_cap, 1); } + + # update help text unless it's already set. + if (not $self->get_meta($name, 'help')) { + $self->{metadata}->set($name, 'help', $help, 1); + } } # add can- capability to PBot capabilities if required diff --git a/lib/PBot/Core/Handlers.pm b/lib/PBot/Core/Handlers.pm index 6f009c62..996c69bc 100644 --- a/lib/PBot/Core/Handlers.pm +++ b/lib/PBot/Core/Handlers.pm @@ -9,19 +9,15 @@ package PBot::Core::Handlers; use parent 'PBot::Core::Class'; use PBot::Imports; - use PBot::Core::Utils::LoadModules qw/load_modules/; sub initialize { my ($self, %conf) = @_; - - # load the handlers in the Handlers directory $self->load_handlers(%conf); } sub load_handlers { my ($self, %conf) = @_; - $self->{pbot}->{logger}->log("Loading handlers:\n"); load_modules($self, 'PBot::Core::Handlers'); } diff --git a/lib/PBot/Plugin/ActionTrigger.pm b/lib/PBot/Plugin/ActionTrigger.pm index ef4a314e..9cef0982 100644 --- a/lib/PBot/Plugin/ActionTrigger.pm +++ b/lib/PBot/Plugin/ActionTrigger.pm @@ -47,7 +47,12 @@ sub initialize { my ($self, %conf) = @_; # register bot command - $self->{pbot}->{commands}->register(sub { $self->cmd_actiontrigger(@_) }, 'actiontrigger', 1); + $self->{pbot}->{commands}->add( + name => 'actiontrigger', + help => 'Manages regular expression triggers to invoke bot commands', + requires_cap => 1, + subref => sub { $self->cmd_actiontrigger(@_) }, + ); # add capability to admin group $self->{pbot}->{capabilities}->add('admin', 'can-actiontrigger', 1); @@ -75,7 +80,7 @@ sub unload { $self->dbi_end; # unregister bot command - $self->{pbot}->{commands}->unregister('actiontrigger'); + $self->{pbot}->{commands}->remove('actiontrigger'); # remove capability $self->{pbot}->{capabilities}->remove('can-actiontrigger'); diff --git a/lib/PBot/Plugin/Battleship.pm b/lib/PBot/Plugin/Battleship.pm index 1a2513be..b9a84330 100644 --- a/lib/PBot/Plugin/Battleship.pm +++ b/lib/PBot/Plugin/Battleship.pm @@ -63,7 +63,11 @@ sub initialize { my ($self, %conf) = @_; # register `battleship` bot command - $self->{pbot}->{commands}->register(sub { $self->cmd_battleship(@_) }, 'battleship', 0); + $self->{pbot}->{commands}->add( + name => 'battleship', + help => 'Battleship board game, simplified for IRC', + subref => sub { $self->cmd_battleship(@_) }, + ); # set the channel where to send game messages $self->{channel} = $self->{pbot}->{registry}->get_value('battleship', 'channel') // '##battleship'; @@ -128,7 +132,7 @@ sub unload { my ($self) = @_; # unregister `battleship` bot command - $self->{pbot}->{commands}->unregister('battleship'); + $self->{pbot}->{commands}->remove('battleship'); # remove battleship loop event from event queue $self->end_game_loop; diff --git a/lib/PBot/Plugin/Connect4.pm b/lib/PBot/Plugin/Connect4.pm index 11c4d2f5..2c0d9dfa 100644 --- a/lib/PBot/Plugin/Connect4.pm +++ b/lib/PBot/Plugin/Connect4.pm @@ -19,7 +19,12 @@ $Data::Dumper::Sortkeys = 1; sub initialize { my ($self, %conf) = @_; - $self->{pbot}->{commands}->register(sub { $self->cmd_connect4(@_) }, 'connect4', 0); + + $self->{pbot}->{commands}->add( + name => 'connect4', + help => 'Connect-4 board game', + subref => sub { $self->cmd_connect4(@_) }, + ); $self->{pbot}->{event_dispatcher}->register_handler('irc.part', sub { $self->on_departure(@_) }); $self->{pbot}->{event_dispatcher}->register_handler('irc.quit', sub { $self->on_departure(@_) }); @@ -32,7 +37,7 @@ sub initialize { sub unload { my $self = shift; - $self->{pbot}->{commands}->unregister('connect4'); + $self->{pbot}->{commands}->remove('connect4'); $self->{pbot}->{event_dispatcher}->remove_handler('irc.part'); $self->{pbot}->{event_dispatcher}->remove_handler('irc.quit'); $self->{pbot}->{event_dispatcher}->remove_handler('irc.kick'); diff --git a/lib/PBot/Plugin/Date.pm b/lib/PBot/Plugin/Date.pm index f6b3dbf6..57989c95 100644 --- a/lib/PBot/Plugin/Date.pm +++ b/lib/PBot/Plugin/Date.pm @@ -18,12 +18,16 @@ sub initialize { $self->{pbot}->{registry}->add_default('text', 'date', 'default_timezone', 'UTC'); # register `date` bot command - $self->{pbot}->{commands}->register(sub { $self->cmd_date(@_) }, "date", 0); + $self->{pbot}->{commands}->add( + name => 'date', + help => 'Show date and time', + subref => sub { $self->cmd_date(@_) }, + ); } sub unload { my $self = shift; - $self->{pbot}->{commands}->unregister("date"); + $self->{pbot}->{commands}->remove('date'); } sub cmd_date { diff --git a/lib/PBot/Plugin/GoogleSearch.pm b/lib/PBot/Plugin/GoogleSearch.pm index 9500983b..a474ba03 100644 --- a/lib/PBot/Plugin/GoogleSearch.pm +++ b/lib/PBot/Plugin/GoogleSearch.pm @@ -22,12 +22,16 @@ sub initialize { $self->{pbot}->{registry}->set_default('googlesearch', 'api_key', 'private', 1); $self->{pbot}->{registry}->set_default('googlesearch', 'context', 'private', 1); - $self->{pbot}->{commands}->register(sub { $self->cmd_googlesearch(@_) }, 'google', 0); + $self->{pbot}->{commands}->add( + name => 'google', + help => 'Google search', + subref => sub { $self->cmd_googlesearch(@_) }, + ); } sub unload { - my $self = shift; - $self->{pbot}->{commands}->unregister('google'); + my ($self) = @_; + $self->{pbot}->{commands}->remove('google'); } sub cmd_googlesearch { diff --git a/lib/PBot/Plugin/ParseDate.pm b/lib/PBot/Plugin/ParseDate.pm index 283f6436..401e6def 100644 --- a/lib/PBot/Plugin/ParseDate.pm +++ b/lib/PBot/Plugin/ParseDate.pm @@ -15,12 +15,16 @@ use Time::Duration qw/duration/; sub initialize { my ($self, %conf) = @_; - $self->{pbot}->{commands}->register(sub { return $self->cmd_parsedate(@_) }, "pd", 0); + $self->{pbot}->{commands}->add( + name => 'pd', + help => 'Simple command to test ParseDate interface', + subref =>sub { return $self->cmd_parsedate(@_) }, + ); } sub unload { my $self = shift; - $self->{pbot}->{commands}->unregister("pd"); + $self->{pbot}->{commands}->remove('pd'); } sub cmd_parsedate { diff --git a/lib/PBot/Plugin/Plang.pm b/lib/PBot/Plugin/Plang.pm index 0bcb929c..496748d4 100644 --- a/lib/PBot/Plugin/Plang.pm +++ b/lib/PBot/Plugin/Plang.pm @@ -90,16 +90,17 @@ sub initialize { ); # register the `plang` command - $self->{pbot}->{commands}->register(sub { $self->cmd_plang(@_) }, "plang", 0); + $self->{pbot}->{commands}->register(sub { $self->cmd_plang(@_) }, 'plang'); # register the `plangrepl` command (does not reset environment) - $self->{pbot}->{commands}->register(sub { $self->cmd_plangrepl(@_) }, "plangrepl", 0); + $self->{pbot}->{commands}->register(sub { $self->cmd_plangrepl(@_) }, 'plangrepl'); } # runs when plugin is unloaded sub unload { my $self = shift; - $self->{pbot}->{commands}->unregister("plang"); + $self->{pbot}->{commands}->unregister('plang'); + $self->{pbot}->{commands}->unregister('plangrepl'); } sub cmd_plang { diff --git a/lib/PBot/Plugin/Quotegrabs.pm b/lib/PBot/Plugin/Quotegrabs.pm index 149d7dfd..408d4361 100644 --- a/lib/PBot/Plugin/Quotegrabs.pm +++ b/lib/PBot/Plugin/Quotegrabs.pm @@ -33,10 +33,10 @@ sub initialize { $self->{pbot}->{atexit}->register(sub { $self->{database}->end(); return; }); - $self->{pbot}->{commands}->register(sub { $self->cmd_grab_quotegrab(@_) }, 'grab', 0); - $self->{pbot}->{commands}->register(sub { $self->cmd_show_quotegrab(@_) }, 'getq', 0); - $self->{pbot}->{commands}->register(sub { $self->cmd_delete_quotegrab(@_) }, 'delq', 0); - $self->{pbot}->{commands}->register(sub { $self->cmd_show_random_quotegrab(@_) }, 'rq', 0); + $self->{pbot}->{commands}->register(sub { $self->cmd_grab_quotegrab(@_) }, 'grab'); + $self->{pbot}->{commands}->register(sub { $self->cmd_show_quotegrab(@_) }, 'getq'); + $self->{pbot}->{commands}->register(sub { $self->cmd_delete_quotegrab(@_) }, 'delq'); + $self->{pbot}->{commands}->register(sub { $self->cmd_show_random_quotegrab(@_) }, 'rq' ); } sub unload { diff --git a/lib/PBot/Plugin/RemindMe.pm b/lib/PBot/Plugin/RemindMe.pm index 2c492131..02b606d4 100644 --- a/lib/PBot/Plugin/RemindMe.pm +++ b/lib/PBot/Plugin/RemindMe.pm @@ -19,7 +19,11 @@ sub initialize { my ($self, %conf) = @_; # register `remindme` bot command - $self->{pbot}->{commands}->register(sub { $self->cmd_remindme(@_) }, 'remindme', 0); + $self->{pbot}->{commands}->add( + name => 'remindme', + help => 'Manage personal reminder notifications', + subref => sub { $self->cmd_remindme(@_) }, + ); # set location of sqlite database $self->{filename} = $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/reminders.sqlite3'; @@ -41,7 +45,7 @@ sub unload { $self->dbi_end; # unregister `remindme` command - $self->{pbot}->{commands}->unregister('remindme'); + $self->{pbot}->{commands}->remove('remindme'); # remove all reminder events from event queue $self->{pbot}->{event_queue}->dequeue_event('reminder .*'); diff --git a/lib/PBot/Plugin/RestrictedMod.pm b/lib/PBot/Plugin/RestrictedMod.pm index 60b8fd4e..632fa7a4 100644 --- a/lib/PBot/Plugin/RestrictedMod.pm +++ b/lib/PBot/Plugin/RestrictedMod.pm @@ -18,10 +18,11 @@ use Storable qw/dclone/; sub initialize { my ($self, %conf) = @_; - $self->{pbot}->{commands}->register(sub { $self->cmd_mod(@_) }, 'mod', 0); - $self->{pbot}->{commands}->set_meta( - 'mod', 'help', - 'Provides restricted moderation abilities to voiced users. They can kick/ban/etc only users that are not admins, whitelisted, voiced or opped.' + + $self->{pbot}->{commands}->add( + name => 'mod', + help => 'Provides restricted moderation abilities to voiced users. They can kick/ban/etc only users that are not admins, whitelisted, voiced or opped.', + subref => sub { $self->cmd_mod(@_) }, ); $self->{pbot}->{capabilities}->add('chanmod', 'can-mod', 1); @@ -42,7 +43,7 @@ sub initialize { sub unload { my ($self) = @_; - $self->{pbot}->{commands}->unregister('mod'); + $self->{pbot}->{commands}->remove('mod'); $self->{pbot}->{capabilities}->remove('chanmod'); } diff --git a/lib/PBot/Plugin/RunCommand.pm b/lib/PBot/Plugin/RunCommand.pm index e0c97810..5ea47637 100644 --- a/lib/PBot/Plugin/RunCommand.pm +++ b/lib/PBot/Plugin/RunCommand.pm @@ -30,12 +30,17 @@ use IPC::Run qw/start pump finish/; sub initialize { my ($self, %conf) = @_; - $self->{pbot}->{commands}->register(sub { $self->cmd_runcmd(@_) }, "runcmd", 1); + $self->{pbot}->{commands}->add( + name => 'runcmd', + help => 'Executes a system command and outputs each line in real-time', + requires_cap => 1, + subref => sub { $self->cmd_runcmd(@_) }, + ); } sub unload { my $self = shift; - $self->{pbot}->{commands}->unregister("runcmd"); + $self->{pbot}->{commands}->remove('runcmd'); } sub cmd_runcmd { diff --git a/lib/PBot/Plugin/Spinach.pm b/lib/PBot/Plugin/Spinach.pm index fccf057a..b122594f 100644 --- a/lib/PBot/Plugin/Spinach.pm +++ b/lib/PBot/Plugin/Spinach.pm @@ -41,7 +41,8 @@ $Data::Dumper::Useqq = 1; sub initialize { my ($self, %conf) = @_; - $self->{pbot}->{commands}->register(sub { $self->cmd_spinach(@_) }, 'spinach', 0); + + $self->{pbot}->{commands}->register(sub { $self->cmd_spinach(@_) }, 'spinach'); $self->{pbot}->{event_dispatcher}->register_handler('irc.part', sub { $self->on_departure(@_) }); $self->{pbot}->{event_dispatcher}->register_handler('irc.quit', sub { $self->on_departure(@_) }); diff --git a/lib/PBot/Plugin/Weather.pm b/lib/PBot/Plugin/Weather.pm index 0a4bf795..57d96cf2 100644 --- a/lib/PBot/Plugin/Weather.pm +++ b/lib/PBot/Plugin/Weather.pm @@ -15,12 +15,17 @@ use XML::LibXML; sub initialize { my ($self, %conf) = @_; - $self->{pbot}->{commands}->register(sub { $self->cmd_weather(@_) }, "weather", 0); + + $self->{pbot}->{commands}->add( + name => 'weather', + help => 'Provides weather service via AccuWeather', + subref => sub { $self->cmd_weather(@_) }, + ); } sub unload { my $self = shift; - $self->{pbot}->{commands}->unregister("weather"); + $self->{pbot}->{commands}->remove('weather'); } sub cmd_weather { diff --git a/lib/PBot/Plugin/Wolfram.pm b/lib/PBot/Plugin/Wolfram.pm index 2d1f1061..f452cb07 100644 --- a/lib/PBot/Plugin/Wolfram.pm +++ b/lib/PBot/Plugin/Wolfram.pm @@ -22,12 +22,17 @@ sub initialize { # make `wolfram.appid` registry entry private by default $self->{pbot}->{registry}->set_default('wolfram', 'appid', 'private', 1); - $self->{pbot}->{commands}->register(sub { $self->cmd_wolfram(@_) }, 'wolfram', 0); + # add wolfram command + $self->{pbot}->{commands}->add( + name => 'wolfram', + help => 'Queries Wolfram|Alpha Short Answers API', + subref => sub { $self->cmd_wolfram(@_) }, + ); } sub unload { my ($self) = @_; - $self->{pbot}->{commands}->unregister('wolfram'); + $self->{pbot}->{commands}->remove('wolfram'); } sub cmd_wolfram { diff --git a/lib/PBot/Plugin/Wttr.pm b/lib/PBot/Plugin/Wttr.pm index 2eca99f8..a1e85693 100644 --- a/lib/PBot/Plugin/Wttr.pm +++ b/lib/PBot/Plugin/Wttr.pm @@ -16,12 +16,17 @@ use URI::Escape qw/uri_escape_utf8/; sub initialize { my ($self, %conf) = @_; - $self->{pbot}->{commands}->register(sub { $self->cmd_wttr(@_) }, "wttr", 0); + + $self->{pbot}->{commands}->add( + name => 'wttr', + help => 'Provides weather information via wttr.in', + subref => sub { $self->cmd_wttr(@_) }, + ); } sub unload { my $self = shift; - $self->{pbot}->{commands}->unregister("wttr"); + $self->{pbot}->{commands}->remove('wttr'); } sub cmd_wttr { diff --git a/lib/PBot/VERSION.pm b/lib/PBot/VERSION.pm index 230a85f1..f3e294fc 100644 --- a/lib/PBot/VERSION.pm +++ b/lib/PBot/VERSION.pm @@ -25,7 +25,7 @@ use PBot::Imports; # These are set by the /misc/update_version script use constant { BUILD_NAME => "PBot", - BUILD_REVISION => 4328, + BUILD_REVISION => 4329, BUILD_DATE => "2021-07-30", };