From ba87aef5243e275242e0adfd986b8d5ff6a92f7b Mon Sep 17 00:00:00 2001 From: Pragmatic Software Date: Tue, 21 Jul 2015 15:07:56 -0700 Subject: [PATCH] Improve factshow/factfind behavior factshow's and factfind's channel argument is now optional. The commands will now automatically determine the channel a factoid lives in if it is the only factoid of that name. If there are multiple factoids existing in different channels then the commands will display a disambiguation message and require an explicit channel argument to choose a specific channel's factoid. --- PBot/FactoidCommands.pm | 74 +++++++++++++++++++++++++++++++---- PBot/FactoidModuleLauncher.pm | 7 +++- PBot/Factoids.pm | 31 +++++++++++---- 3 files changed, 95 insertions(+), 17 deletions(-) diff --git a/PBot/FactoidCommands.pm b/PBot/FactoidCommands.pm index 59b146ee..912e1ca0 100644 --- a/PBot/FactoidCommands.pm +++ b/PBot/FactoidCommands.pm @@ -560,16 +560,45 @@ sub factshow { my ($chan, $trig) = split / /, $arguments; - if(not defined $chan or not defined $trig) { - return "Usage: factshow "; + if(not defined $chan and not defined $trig) { + return "Usage: factshow [channel] "; } - my ($channel, $trigger) = $self->{pbot}->{factoids}->find_factoid($chan, $trig, undef, 1, 1); + my $needs_disambig; - if(not defined $trigger) { + if (not defined $trig) { + $trig = $chan; + $chan = '.*'; + $needs_disambig = 1; + } + + $chan = '.*' if $chan eq 'global'; + + $chan = lc $chan; + + my @factoids = $self->{pbot}->{factoids}->find_factoid($chan, $trig); + + if(not @factoids) { return "$trig not found in channel $chan"; } + my ($channel, $trigger); + + if (@factoids > 1) { + if ($needs_disambig or not grep { $_->[0] eq $chan } @factoids) { + return "$trig found in multiple channels: " . (join ', ', sort map { $_->[0] eq '.*' ? 'global' : $_->[0] } @factoids) . "; use `factshow $trig` to disambiguate."; + } else { + foreach my $factoid (@factoids) { + if ($factoid->[0] eq $chan) { + ($channel, $trigger) = ($factoid->[0], $factoid->[1]); + last; + } + } + } + } else { + ($channel, $trigger) = ($factoids[0]->[0], $factoids[0]->[1]); + } + my $result = "$trigger: " . $factoids->{$channel}->{$trigger}->{action}; if($factoids->{$channel}->{$trigger}->{type} eq 'module') { @@ -586,16 +615,45 @@ sub factinfo { my ($chan, $trig) = split / /, $arguments; - if(not defined $chan or not defined $trig) { - return "Usage: factinfo "; + if(not defined $chan and not defined $trig) { + return "Usage: factinfo [channel] "; } - my ($channel, $trigger) = $self->{pbot}->{factoids}->find_factoid($chan, $trig, undef, 1, 1); + my $needs_disambig; - if(not defined $trigger) { + if (not defined $trig) { + $trig = $chan; + $chan = '.*'; + $needs_disambig = 1; + } + + $chan = '.*' if $chan eq 'global'; + + $chan = lc $chan; + + my @factoids = $self->{pbot}->{factoids}->find_factoid($chan, $trig); + + if(not @factoids) { return "$trig not found in channel $chan"; } + my ($channel, $trigger); + + if (@factoids > 1) { + if ($needs_disambig or not grep { $_->[0] eq $chan } @factoids) { + return "$trig found in multiple channels: " . (join ', ', sort map { $_->[0] eq '.*' ? 'global' : $_->[0] } @factoids) . "; use `factinfo $trig` to disambiguate."; + } else { + foreach my $factoid (@factoids) { + if ($factoid->[0] eq $chan) { + ($channel, $trigger) = ($factoid->[0], $factoid->[1]); + last; + } + } + } + } else { + ($channel, $trigger) = ($factoids[0]->[0], $factoids[0]->[1]); + } + my $created_ago = ago(gettimeofday - $factoids->{$channel}->{$trigger}->{created_on}); my $ref_ago = ago(gettimeofday - $factoids->{$channel}->{$trigger}->{last_referenced_on}) if defined $factoids->{$channel}->{$trigger}->{last_referenced_on}; diff --git a/PBot/FactoidModuleLauncher.pm b/PBot/FactoidModuleLauncher.pm index 6cd9f940..bccdb9e5 100644 --- a/PBot/FactoidModuleLauncher.pm +++ b/PBot/FactoidModuleLauncher.pm @@ -44,13 +44,16 @@ sub execute_module { $arguments = "" if not defined $arguments; - my ($channel, $trigger) = $self->{pbot}->{factoids}->find_factoid($from, $keyword); + my @factoids = $self->{pbot}->{factoids}->find_factoid($from, $keyword); - if(not defined $trigger) { + + if(not @factoids) { $self->{pbot}->{interpreter}->handle_result($from, $nick, $user, $host, $command, "$keyword $arguments", "/msg $nick Failed to find module for '$keyword' in channel $from\n", 1, 0); return; } + my ($channel, $trigger) = ($factoids[0]->[0], $factoids[0]->[1]); + my $module = $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{action}; my $module_dir = $self->{pbot}->{registry}->get_value('general', 'module_dir'); diff --git a/PBot/Factoids.pm b/PBot/Factoids.pm index f3d99141..61cbb5a5 100644 --- a/PBot/Factoids.pm +++ b/PBot/Factoids.pm @@ -252,6 +252,7 @@ sub find_factoid { $self->{pbot}->{logger}->log("string: $string\n") if $debug; my @result = eval { + my @results; for (my $depth = 0; $depth < 5; $depth++) { if ($self->{pbot}->{commands}->exists($keyword)) { return undef; @@ -282,7 +283,11 @@ sub find_factoid { goto NEXT_DEPTH; } - return ($channel, $trigger); + if ($exact_channel) { + return ($channel, $trigger); + } else { + push @results, [$channel, $trigger]; + } } } } @@ -296,7 +301,7 @@ sub find_factoid { foreach my $trigger (sort keys %{ $self->{factoids}->hash->{$channel} }) { if($self->{factoids}->hash->{$channel}->{$trigger}->{type} eq 'regex') { - $self->{pbot}->{logger}->log("checking regex $string =~ m/$trigger/i\n") if $debug; + $self->{pbot}->{logger}->log("checking regex $string =~ m/$trigger/i\n") if $debug >= 2; if($string =~ m/$trigger/i) { $self->{pbot}->{logger}->log("return regex $channel: $trigger\n") if $debug; @@ -307,7 +312,11 @@ sub find_factoid { goto NEXT_DEPTH; } - return ($channel, $trigger); + if ($exact_channel) { + return ($channel, $trigger); + } else { + push @results, [$channel, $trigger]; + } } } } @@ -318,8 +327,14 @@ sub find_factoid { last if not $find_alias; } - $self->{pbot}->{logger}->log("find_factoid: no match\n") if $debug; - return undef; + if ($debug) { + if (not @results) { + $self->{pbot}->{logger}->log("find_factoid: no match\n"); + } else { + $self->{pbot}->{logger}->log("find_factoid: got results: " . (join ', ', map { "$_->[0] -> $_->[1]" } @results) . "\n"); + } + } + return @results; }; if($@) { @@ -336,9 +351,11 @@ sub expand_factoid_vars { while ($action =~ /(?find_factoid($from, $v, undef, 0, 1); + my @factoids = $self->find_factoid($from, $v, undef, 0, 1); + next if not @factoids; + my ($var_chan, $var) = ($factoids[0]->[0], $factoids[0]->[1]); - if(defined $var && $self->{factoids}->hash->{$var_chan}->{$var}->{type} eq 'text') { + if(@factoids && $self->{factoids}->hash->{$var_chan}->{$var}->{type} eq 'text') { my $change = $self->{factoids}->hash->{$var_chan}->{$var}->{action}; my @list = split(/\s|(".*?")/, $change); my @mylist;