X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=src%2FCommandStubs.pl;h=1a583dd4399af473c8f20b2ea17b6d44cf9a557b;hb=02dd5778cf86851ed8158551400149133843516a;hp=c9a19f039ccdc553ab364ddc7d895f8fa555b5ab;hpb=d801b40749049f6833deb3b5d30188ce7b61a1b5;p=infobot.git diff --git a/src/CommandStubs.pl b/src/CommandStubs.pl index c9a19f0..1a583dd 100644 --- a/src/CommandStubs.pl +++ b/src/CommandStubs.pl @@ -1,5 +1,6 @@ # # User Command Extension Stubs +# WARN: this file does not reload on HUP. # if (&IsParam("useStrict")) { use strict; } @@ -35,9 +36,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(); @@ -48,6 +49,7 @@ sub parseCmdHook { } foreach (keys %{"hooks_$hashname"}) { + # rename to something else! my $ident = $_; next unless ($cmd =~ /^$ident$/i); @@ -57,7 +59,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 +67,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 +79,7 @@ sub parseCmdHook { ### DEBUG. foreach (keys %hash) { - &DEBUG(" $cmd->$_ => '$hash{$_}'."); + &VERB(" $cmd->$_ => '$hash{$_}'.",2); } ### HELP. @@ -95,21 +102,31 @@ sub parseCmdHook { 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."); + if (defined $who) { + &msg($who, "coderef does not exist for $ident."); + } + + return 1; + } - if (exists $hash{'FlatArg'} and $hash{'FlatArg'} == 0) { - &status("CmdHook: using args as array."); - &{$hash{'CODEREF'}}(@args); + if (exists $hash{'ArrayArgs'}) { + &{ $hash{'CODEREF'} }(@args); } else { - &{$hash{'CODEREF'}}($flatarg); + &{ $hash{'CODEREF'} }($flatarg); } } @@ -118,7 +135,7 @@ sub parseCmdHook { $cmdstats{ $hash{'Cmdstats'} }++; } - &DEBUG("pCH: ended."); + &VERB("hooks: End of command.",2); $done = 1; } @@ -130,13 +147,13 @@ sub parseCmdHook { ### ### START ADDING HOOKS. ### -&addCmdHook("extra", 'd?bugs', ('CODEREF' => 'debianBugs', +&addCmdHook("extra", 'd?bugs', ('CODEREF' => 'DBugs::Parse', 'Forker' => 1, 'Identifier' => 'debianExtra', 'Cmdstats' => 'Debian Bugs') ); &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 +173,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 +206,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,7 +223,7 @@ sub Modules { } # babel bot: Jonathan Feinberg++ - if (&IsChanConf("babelfish") and $message =~ m{ + if ($message =~ m{ ^\s* (?:babel(?:fish)?|x|xlate|translate) \s+ @@ -216,7 +232,8 @@ sub Modules { ($babel_lang_regex)\w* # which language? \s* (.+) # The phrase to be translated - }xoi) { + }xoi) { + return unless (&hasParam("babelfish")); &Forker("babelfish", sub { &babel::babelfish(lc $1, lc $2, $3); } ); @@ -224,24 +241,24 @@ sub Modules { return; } - if (&IsChanConf("debian")) { - my $debiancmd = 'conflicts?|depends?|desc|file|info|provides?'; - $debiancmd .= '|recommends?|suggests?|maint|maintainer'; - if ($message =~ /^($debiancmd)(\s+(.*))?$/i) { - my $package = lc $3; + my $debiancmd = 'conflicts?|depends?|desc|file|info|provides?'; + $debiancmd .= '|recommends?|suggests?|maint|maintainer'; - if (defined $package) { - &Forker("debian", sub { &Debian::infoPackages($1, $package); } ); - } else { - &help($1); - } + if ($message =~ /^($debiancmd)(\s+(.*))?$/i) { + return unless (&hasParam("debian")); + my $package = lc $3; - return; + if (defined $package) { + &Forker("debian", sub { &Debian::infoPackages($1, $package); } ); + } else { + &help($1); } + + return; } # google searching. Simon++ - if (&IsChanConf("wwwsearch") and $message =~ /^(?:search\s+)?(\S+)\s+for\s+['"]?(.*?)['"]?\s*\?*$/i) { + if ($message =~ /^(?:search\s+)?(\S+)\s+for\s+['"]?(.*?)['"]?\s*\?*$/i) { return unless (&hasParam("wwwsearch")); &Forker("wwwsearch", sub { &W3Search::W3Search($1,$2); } ); @@ -250,22 +267,66 @@ sub Modules { return; } + # text counters. + if ($_ = &getChanConf("ircTextCounters")) { + s/([^\w\s])/\\$1/g; + my $z = join '|', split ' '; + + if ($message =~ /^($z)stats(\s+(\S+))?$/i) { + my $type = $1; + my $arg = $3; + + if (!defined $arg or $arg =~ /^\s*$/) { + my $x = (&dbRawReturn("SELECT SUM(counter) FROM stats WHERE type=".&dbQuote($type) ))[0]; + + if (defined $x) { + &pSReply("total count of '$type': $x"); + } else { + &pSReply("zero counter for '$type'."); + } + } else { + my $x = (&dbRawReturn("SELECT SUM(counter) FROM stats WHERE type=". + &dbQuote($type)." AND nick=".&dbQuote($arg) ))[0]; + + if (defined $x) { # defined. + &pSReply("$arg has said $type $x times"); + } else { # !defined. + &pSReply("$arg has not said $type yet."); + } + } + + return; + } + + if ($@) { + &DEBUG("regex failed: $@"); + return; + } + } + # list{keys|values}. xk++. Idea taken from #linuxwarez@EFNET if ($message =~ /^list(\S+)( (.*))?$/i) { return unless (&hasParam("search")); my $thiscmd = lc($1); - my $args = $3; - - $thiscmd =~ s/^vals$/values/; + $thiscmd =~ s/^vals$/values/; return if ($thiscmd ne "keys" && $thiscmd ne "values"); + my $args = $3 || ""; + $args =~ s/\s+$//g; + # Usage: - if (!defined $args) { + if (!defined $args or $args =~ /^\s*$/) { &help("list". $thiscmd); return; } + # suggested by asuffield and \broken. + if ($args =~ /^["']/ and $args =~ /["']$/) { + &DEBUG("list*: removed quotes."); + $args =~ s/^["']|["']$//g; + } + if (length $args == 1) { &msg($who,"search string is too short."); return; @@ -310,7 +371,7 @@ sub Modules { ### TODO: compact with map? my @list; foreach (sort {$b <=> $a} keys %nickometer) { - my $str = join(", ", sort keys %{$nickometer{$_}}); + my $str = join(", ", sort keys %{ $nickometer{$_} }); push(@list, "$str ($_%)"); } @@ -345,7 +406,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'"); @@ -441,7 +502,7 @@ sub uptime { sub seen { my($person) = @_; - if (!defined $person) { + if (!defined $person or $person =~ /^$/) { &help("seen"); my $i = &countKeys("seen"); @@ -456,12 +517,12 @@ sub seen { &seenFlush(); # very evil hack. oh well, better safe than sorry. - ### TODO: Support &dbGetRowInfo(); like in &FactInfo(); + ### TODO: Support &dbGetColInfo(); like in &FactInfo(); my $select = "nick,time,channel,host,message"; if ($person eq "random") { @seen = &randKey("seen", $select); } else { - @seen = &dbGet("seen", "nick", $person, $select); + @seen = &dbGet("seen", $select, "nick='$person'"); } if (scalar @seen < 2) { @@ -476,7 +537,7 @@ sub seen { my $reply; ### TODO: multi channel support. may require &IsNick() to return ### all channels or something. - my @chans = &GetNickInChans($seen[0]); + my @chans = &getNickInChans($seen[0]); if (scalar @chans) { $reply = "$seen[0] is currently on"; @@ -535,7 +596,7 @@ sub cookie { # lets find that secret cookie. my $target = ($msgType ne 'public') ? $who : $talkchannel; - my $cookiemsg = &getRandom(keys %{$lang{'cookie'}}); + my $cookiemsg = &getRandom(keys %{ $lang{'cookie'} }); my ($key,$value); ### WILL CHEW TONS OF MEM. @@ -674,14 +735,18 @@ sub do_verstats { &msg($who, "Sending CTCP VERSION..."); $conn->ctcp("VERSION", $chan); -# $cache{verstats} = $chan; + $cache{verstats}{chan} = $chan; + $cache{verstats}{who} = $who; + $cache{verstats}{msgType} = $msgType; $conn->schedule(60, sub { my $vtotal = 0; -# my $c = lc $cache{verstats}; - my $c = lc $chan; + my $c = lc $cache{verstats}{chan}; my $total = keys %{ $channels{$c}{''} }; -# delete $cache{verstats}; + $chan = $c; + $who = $cache{verstats}{who}; + $msgType = $cache{verstats}{msgType}; + delete $cache{verstats}; # sufficient? foreach (keys %ver) { $vtotal += scalar keys %{ $ver{$_} }; @@ -720,4 +785,7 @@ sub do_verstats { return; } +sub nullski { my ($arg) = @_; return unless (defined $arg); + foreach (`$arg`) { &msg($who,$_); } } + 1;