]> git.donarmstrong.com Git - infobot.git/blobdiff - src/CommandStubs.pl
news: added news->factoid redirection
[infobot.git] / src / CommandStubs.pl
index 4495e10e2fd9e9a216cd96fde377fdd29900b555..a4c3679c315e2c49f88d9efe248a5f19c79d7a10 100644 (file)
@@ -4,9 +4,9 @@
 
 if (&IsParam("useStrict")) { use strict; }
 
-$babel::lang_regex = "";       # lame fix.
+$babel_lang_regex = "fr|sp|po|pt|it|ge|de|gr|en";
 
-### PROPOSED COMMAND HOOK IMPLEMENTATION.
+### COMMAND HOOK IMPLEMENTATION.
 # addCmdHook("SECTION", 'TEXT_HOOK',
 #      (CODEREF        => 'Blah', 
 #      Forker          => 1,
@@ -35,9 +35,9 @@ sub addCmdHook {
 sub parseCmdHook {
     my ($hashname, $line) = @_;
     $line =~ /^(\S+)( (.*))?$/;
-    my @args   = split(' ', $3 || '');
-    my $flatarg        = $3;
     my $cmd    = $1;   # command name is whitespaceless.
+    my $flatarg        = $3;
+    my @args   = split(/\s+/, $flatarg || '');
     my $done   = 0;
 
     &shmFlush();
@@ -57,7 +57,7 @@ sub parseCmdHook {
            next;
        }
 
-       &DEBUG("pCH(hooks_$hashname): $cmd matched $ident");
+       &status("hooks($hashname): $cmd matched '$ident'");
        my %hash = %{ ${"hooks_$hashname"}{$ident} };
 
        if (!scalar keys %hash) {
@@ -65,6 +65,11 @@ sub parseCmdHook {
            return 1;
        }
 
+       if ($hash{NoArgs} and $flatarg) {
+           &DEBUG("cmd $ident does not take args; skipping.");
+           next;
+       }
+
        if (!exists $hash{CODEREF}) {
            &ERROR("CODEREF undefined for $cmd or $ident.");
            return 1;
@@ -72,7 +77,7 @@ sub parseCmdHook {
 
        ### DEBUG.
        foreach (keys %hash) {
-           &DEBUG(" $cmd->$_ => '$hash{$_}'.");
+           &VERB(" $cmd->$_ => '$hash{$_}'.",2);
        }
 
        ### HELP.
@@ -83,30 +88,36 @@ sub parseCmdHook {
 
        ### IDENTIFIER.
        if (exists $hash{'Identifier'}) {
-           return unless (&hasParam($hash{'Identifier'}));
+           return unless (&hasParam($hash{'Identifier'}));
        }
 
        ### USER FLAGS.
        if (exists $hash{'UserFlag'}) {
-           return unless (&hasFlag($hash{'UserFlag'}));
+           return unless (&hasFlag($hash{'UserFlag'}));
        }
 
        ### FORKER,IDENTIFIER,CODEREF.
        if (exists $hash{'Forker'}) {
            $hash{'Identifier'} .= "-" if ($hash{'Forker'} eq "NULL");
 
-           ### FLAT_ARG / ARRAY option.
+           if (exists $hash{'ArrayArgs'}) {
+               &Forker($hash{'Identifier'}, sub { \&{$hash{'CODEREF'}}(@args) } );
+           } else {
+               &Forker($hash{'Identifier'}, sub { \&{$hash{'CODEREF'}}($flatarg) } );
+           }
 
-           &Forker($hash{'Identifier'}, sub { \&{$hash{'CODEREF'}}(@args) } );
        } else {
            if (exists $hash{'Module'}) {
                &loadMyModule($myModules{ $hash{'Module'} });
            }
 
-           ### TODO: check if CODEREF exists.
+           # check if CODEREF exists.
+           if (!defined &{ $hash{'CODEREF'} }) {
+               &WARN("coderef $hash{'CODEREF'} don't exist.");
+               return 1;
+           }
 
-           if (exists $hash{'FlatArg'} and $hash{'FlatArg'} == 0) {
-               &status("CmdHook: using args as array.");
+           if (exists $hash{'ArrayArgs'}) {
                &{$hash{'CODEREF'}}(@args);
            } else {
                &{$hash{'CODEREF'}}($flatarg);
@@ -118,7 +129,7 @@ sub parseCmdHook {
            $cmdstats{ $hash{'Cmdstats'} }++;
        }
 
-       &DEBUG("pCH: ended.");
+       &VERB("hooks: End of command.",2);
 
        $done = 1;
     }
@@ -136,7 +147,7 @@ sub parseCmdHook {
 &addCmdHook("extra", 'dauthor', ('CODEREF' => 'Debian::searchAuthor',
        'Forker' => 1, 'Identifier' => 'debian',
        'Cmdstats' => 'Debian Author Search', 'Help' => "dauthor" ) );
-&addCmdHook("extra", '(d|search)desc', ('CODEREF' => 'Debian::searchDesc',
+&addCmdHook("extra", '(d|search)desc', ('CODEREF' => 'Debian::searchDescFE',
        'Forker' => 1, 'Identifier' => 'debian',
        'Cmdstats' => 'Debian Desc Search', 'Help' => "ddesc" ) );
 &addCmdHook("extra", 'dnew', ('CODEREF' => 'DebianNew',
@@ -156,7 +167,7 @@ sub parseCmdHook {
        'Forker' => 1, 'Identifier' => 'insult', 'Help' => "insult" ) );
 &addCmdHook("extra", 'kernel', ('CODEREF' => 'Kernel::Kernel',
        'Forker' => 1, 'Identifier' => 'kernel',
-       'Cmdstats' => 'Kernel') );
+       'Cmdstats' => 'Kernel', 'NoArgs' => 1) );
 &addCmdHook("extra", 'listauth', ('CODEREF' => 'CmdListAuth',
        'Identifier' => 'search', Module => 'factoids', 
        'Help' => 'listauth') );
@@ -189,7 +200,6 @@ sub parseCmdHook {
 &addCmdHook("extra", 'uptime', ('CODEREF' => 'uptime', 'Identifier' => 'uptime',
        'Cmdstats' => 'Uptime') );
 &addCmdHook("extra", 'nullski', ('CODEREF' => 'nullski', ) );
-       sub nullski { my ($arg) = @_; foreach (`$arg`) { &msg($who,$_); } }
 &addCmdHook("extra", '(fm|freshmeat)', ('CODEREF' => 'Freshmeat::Freshmeat',
        'Identifier' => 'freshmeat', 'Cmdstats' => 'Freshmeat',
        'Forker' => 1, 'Help' => 'freshmeat') );
@@ -207,13 +217,13 @@ sub Modules {
     }
 
     # babel bot: Jonathan Feinberg++
-    if (&IsParam("babelfish") and $message =~ m{
+    if (&IsChanConf("babelfish") and $message =~ m{
                ^\s*
                (?:babel(?:fish)?|x|xlate|translate)
                \s+
                (to|from)               # direction of translation (through)
                \s+
-               ($babel::lang_regex)\w* # which language?
+               ($babel_lang_regex)\w*  # which language?
                \s*
                (.+)                    # The phrase to be translated
        }xoi) {
@@ -224,7 +234,7 @@ sub Modules {
        return;
     }
 
-    if (&IsParam("debian")) {
+    if (&IsChanConf("debian")) {
        my $debiancmd    = 'conflicts?|depends?|desc|file|info|provides?';
        $debiancmd      .= '|recommends?|suggests?|maint|maintainer';
        if ($message =~ /^($debiancmd)(\s+(.*))?$/i) {
@@ -241,7 +251,7 @@ sub Modules {
     }
 
     # google searching. Simon++
-    if (&IsParam("wwwsearch") and $message =~ /^(?:search\s+)?(\S+)\s+for\s+['"]?(.*?)['"]?\s*\?*$/i) {
+    if (&IsChanConf("wwwsearch") and $message =~ /^(?:search\s+)?(\S+)\s+for\s+['"]?(.*?)['"]?\s*\?*$/i) {
        return unless (&hasParam("wwwsearch"));
 
        &Forker("wwwsearch", sub { &W3Search::W3Search($1,$2); } );
@@ -256,6 +266,12 @@ sub Modules {
 
        my $thiscmd     = lc($1);
        my $args        = $3;
+       $args           =~ s/\s+$//g;
+       # suggested by asuffield nad \broken.
+       if ($args =~ /^["']/ and $args =~ /["']$/) {
+           &DEBUG("list*: removed quotes.");
+           $args       =~ s/^["']|["']$//g;
+       }
 
        $thiscmd =~ s/^vals$/values/;
        return if ($thiscmd ne "keys" && $thiscmd ne "values");
@@ -296,23 +312,22 @@ sub Modules {
            # step 1.
            my %nickometer;
            foreach (keys %{ $channels{lc $term}{''} }) {
-               my $value = &nickometer($_);
-
-               if (!defined $value) {
-                   &WARN("nickometer: value is undefined.");
+               my $str   = $_;
+               if (!defined $str) {
+                   &WARN("nickometer: nick in chan $term undefined?");
                    next;
                }
-               &DEBUG("value => $value.");
 
-               $nickometer{$value}{$_} = 1;
+               my $value = &nickometer($str);
+               $nickometer{$value}{$str} = 1;
            }
 
            # step 2.
            ### TODO: compact with map?
            my @list;
-           foreach (sort {$a <=> $b} keys %nickometer) {
+           foreach (sort {$b <=> $a} keys %nickometer) {
                my $str = join(", ", sort keys %{$nickometer{$_}});
-               push(@list, "$str ($_ %)");
+               push(@list, "$str ($_%)");
            }
 
            &pSReply( &formListReply(0, "Nickometer list for $term ", @list) );
@@ -346,7 +361,7 @@ sub Modules {
        return unless (&hasParam("topic"));
 
        my $chan        = $talkchannel;
-       my @args        = split(/ /, $2);
+       my @args        = split / /, $2 || "";
 
        if (!scalar @args) {
            &msg($who,"Try 'help topic'");
@@ -664,20 +679,29 @@ sub do_verstats {
     }
 
     if (!&validChan($chan)) {
-       &pSReply("chan $chan is invalid.");
+       &msg($who, "chan $chan is invalid.");
        return;
     }
 
-    if (scalar keys %ver or scalar @vernick) {
-       &DEBUG("verstats already in progress.");
+    if (scalar @vernick > scalar(keys %{ $channels{lc $chan}{''} })/4) {
+       &msg($who, "verstats already in progress for someone else.");
        return;
     }
 
     &msg($who, "Sending CTCP VERSION...");
     $conn->ctcp("VERSION", $chan);
+    $cache{verstats}{chan}     = $chan;
+    $cache{verstats}{who}      = $who;
+    $cache{verstats}{msgType}  = $msgType;
+
     $conn->schedule(60, sub {
        my $vtotal      = 0;
-       my $total       = keys %{ $channels{lc $chan}{''} };
+       my $c           = lc $cache{verstats}{chan};
+       my $total       = keys %{ $channels{$c}{''} };
+       $chan           = $c;
+       $who            = $cache{verstats}{who};
+       $msgType        = $cache{verstats}{msgType};
+       delete $cache{verstats};        # sufficient?
 
        foreach (keys %ver) {
            $vtotal     += scalar keys %{ $ver{$_} };
@@ -686,28 +710,27 @@ sub do_verstats {
        my %sorted;
        my $unknown     = $total - $vtotal;
        my $perc        = sprintf("%.1f", $unknown * 100 / $total);
-       $sorted{$perc}  = "unknown/cloak - $unknown ($perc %)";
        $perc           =~ s/.0$//;
+       $sorted{$perc}{"unknown/cloak"} = "$unknown ($perc%)";
 
        foreach (keys %ver) {
            my $count   = scalar keys %{ $ver{$_} };
            $perc       = sprintf("%.01f", $count * 100 / $total);
            $perc       =~ s/.0$//;     # lame compression.
 
-           if (exists $sorted{$perc}) {
-               &WARN("sorted{$perc} already exists; FIXME.");
-           }
-
-           $sorted{$perc} = "$_ - $count ($perc %)";
+           $sorted{$perc}{$_} = "$count ($perc%)";
        }
 
        ### can be compressed to a map?
        my @list;
-       foreach ( sort { $a <=> $b } keys %sorted ) {
-           push(@list, $sorted{$_});
+       foreach ( sort { $b <=> $a } keys %sorted ) {
+           my $perc = $_;
+           foreach (sort keys %{ $sorted{$perc} }) {
+               push(@list, "$_ - $sorted{$perc}{$_}");
+           }
        }
 
-       &pSReply( &formListReply(0, "IRC Client versions for $chan ", @list) );
+       &pSReply( &formListReply(0, "IRC Client versions for $c ", @list) );
 
        # clean up not-needed data structures.
        undef %ver;
@@ -717,4 +740,7 @@ sub do_verstats {
     return;
 }
 
+sub nullski { my ($arg) = @_; return unless (defined $arg);
+       foreach (`$arg`) { &msg($who,$_); } }
+
 1;