From 838edbef8b358e7175badabeeb89044c60edb95c Mon Sep 17 00:00:00 2001 From: dms Date: Mon, 6 Aug 2001 14:55:24 +0000 Subject: [PATCH] - irctextcounters: add percentile/ranking. - irctextcounters: added channel support. - added command stats counter to be logged to sql table. - added findChanConf() - hack to get any conf value. - update stats when requesting factoid args factoid. - added irc hooks for whoischannels,useronchannel,whois,422. git-svn-id: https://svn.code.sf.net/p/infobot/code/trunk@512 c11ca15a-4712-0410-83d8-924469b57eb5 --- blootbot/src/CommandStubs.pl | 65 +++++++++++++++++++++++-------- blootbot/src/Factoids/Question.pl | 19 +++++++-- blootbot/src/IRC/Irc.pl | 23 ++++++++--- blootbot/src/IRC/IrcHooks.pl | 63 ++++++++++++++++++++++++------ blootbot/src/IRC/Schedulers.pl | 3 +- blootbot/src/Misc.pl | 26 ++++++++++--- blootbot/src/Modules/News.pl | 4 +- blootbot/src/Modules/UserDCC.pl | 5 +-- blootbot/src/Process.pl | 1 + blootbot/src/core.pl | 25 ++++++++++++ blootbot/src/db_mysql.pl | 3 -- 11 files changed, 189 insertions(+), 48 deletions(-) diff --git a/blootbot/src/CommandStubs.pl b/blootbot/src/CommandStubs.pl index eba7a50..91dfc72 100644 --- a/blootbot/src/CommandStubs.pl +++ b/blootbot/src/CommandStubs.pl @@ -272,21 +272,33 @@ sub Modules { return; } - # text counters. - # warn: lets process it anyway. - if (1 and $_ = &getChanConf("ircTextCounters")) { - s/([^\w\s])/\\$1/g; - my $z = join '|', split ' '; + # text counters. (eg: hehstats) + my $itc; + $itc = &getChanConf("ircTextCounters"); + $itc = &findChanConf("ircTextCounters") unless ($itc); + if ($itc) { + $itc =~ s/([^\w\s])/\\$1/g; + my $z = join '|', split ' ', $itc; if ($message =~ /^($z)stats(\s+(\S+))?$/i) { my $type = $1; my $arg = $3; + # even more uglier with channel/time arguments. + my $c = $chan; +# my $c = $chan || "PRIVATE"; + my $where = "type=".&dbQuote($type); + $where .= " AND channel=".&dbQuote($c) if (defined $c); + &DEBUG("not using chan arg") if (!defined $c); + my $sum = (&dbRawReturn("SELECT SUM(counter) FROM stats" + ." WHERE ".$where ))[0]; + &DEBUG("type => $type, arg => $arg"); + if (!defined $arg or $arg =~ /^\s*$/) { # this is way fucking ugly. - my $x = (&dbRawReturn("SELECT SUM(counter) FROM stats WHERE type=".&dbQuote($type) ))[0]; - my %hash = &dbGetCol("stats", "nick,counter", "type=".&dbQuote($type). - " ORDER BY counter DESC LIMIT 3", 1); + + my %hash = &dbGetCol("stats", "nick,counter", + $where." ORDER BY counter DESC LIMIT 3", 1); my $i; my @top; @@ -295,7 +307,7 @@ sub Modules { my $tp = 0; foreach $i (sort { $b <=> $a } keys %hash) { foreach (keys %{ $hash{$i} }) { - my $p = sprintf("%.01f", 100*$i/$x); + my $p = sprintf("%.01f", 100*$i/$sum); $tp += $p; push(@top, "\002$_\002 -- $i ($p%)"); } @@ -306,20 +318,41 @@ sub Modules { $topstr = ". Top ".scalar(@top).": ".join(', ', @top); } - if (defined $x) { - &pSReply("total count of '$type': $x$topstr"); + if (defined $sum) { + &pSReply("total count of '$type' on $c: $sum$topstr"); } else { &pSReply("zero counter for '$type'."); } } else { - my $x = (&dbRawReturn("SELECT SUM(counter) FROM stats WHERE type=". - &dbQuote($type)." AND nick=".&dbQuote($arg) ))[0]; + my $x = (&dbRawReturn("SELECT SUM(counter) FROM stats". + " WHERE $where AND nick=".&dbQuote($arg) ))[0]; - if (defined $x) { # defined. - &pSReply("$arg has said $type $x times"); - } else { # !defined. + if (!defined $x) { # !defined. &pSReply("$arg has not said $type yet."); + return; + } + + # defined. + my @array = &dbGet("stats", "nick", + $where." ORDER BY counter", 1); + my $good = 0; + my $i = 0; + for($i=0; $i ~punish apt for (Eating) (Parentheses) + # how the hell do I fix the above? + # todo: make eval work with $$i's :( # fuck this is an ugly hack. it works though. eval { @@ -216,12 +220,21 @@ sub factoidArgs { &status("Question: factoid Arguments for '$str'"); # todo: use getReply() - need to modify it :( my $i = 0; - my $r = &getFactoid("CMD: $_"); + my $q = "CMD: $_"; + my $r = &getFactoid($q); if (!defined $r) { &DEBUG("question: !result... should this happen?"); return; } + # update stats. + my $count = &getFactInfo($q, "requested_count") || 0; + $count++; + &setFactInfo($q, "requested_by", $nuh); + &setFactInfo($q, "requested_time", time()); + &setFactInfo($q, "requested_count", $count); + # end of update stats. + $result = $r; $result =~ s/^\((.*?)\): //; @@ -237,9 +250,9 @@ sub factoidArgs { my $done = 0; my $old = $result; while (1) { -# &DEBUG("Q: result => $result (1)"); +# &DEBUG("Q: result => $result (1before)"); $result = &substVars($result); -# &DEBUG("Q: result => $result (1)"); +# &DEBUG("Q: result => $result (1after)"); last if ($old eq $result); $old = $result; diff --git a/blootbot/src/IRC/Irc.pl b/blootbot/src/IRC/Irc.pl index a5c0ca4..d6f81b6 100644 --- a/blootbot/src/IRC/Irc.pl +++ b/blootbot/src/IRC/Irc.pl @@ -135,12 +135,15 @@ sub irc { $conn->add_handler('nick', \&on_nick); $conn->add_handler('quit', \&on_quit); $conn->add_handler('notice', \&on_notice); - $conn->add_handler('whoisuser', \&on_whoisuser); + $conn->add_handler('whoischannels', \&on_whoischannels); + $conn->add_handler('useronchannel', \&on_useronchannel); + $conn->add_handler('whois', \&on_whois); $conn->add_handler('other', \&on_other); $conn->add_global_handler('disconnect', \&on_disconnect); $conn->add_global_handler([251,252,253,254,255], \&on_init); ### $conn->add_global_handler([251,252,253,254,255,302], \&on_init); $conn->add_global_handler(315, \&on_endofwho); + $conn->add_global_handler(422, \&on_endofwho); # nomotd. $conn->add_global_handler(324, \&on_modeis); $conn->add_global_handler(333, \&on_topicinfo); $conn->add_global_handler(352, \&on_who); @@ -430,11 +433,11 @@ sub joinchan { $chan = lc $1; } - &status("joining $b_blue$chan$ob"); - + # hopefully validChan is right. if (&validChan($chan)) { &status("join: already on $chan"); } else { + &status("joining $b_blue$chan$ob"); if (!$conn->join($chan)) { &DEBUG("joinchan: join failed. trying connect!"); $conn->connect(); @@ -449,6 +452,11 @@ sub part { next if ($chan eq ""); $chan =~ tr/A-Z/a-z/; # lowercase. + if ($chan !~ /^$mask{chan}$/) { + &WARN("part: chan is invalid ($chan)"); + next; + } + &status("parting $chan"); if (!&validChan($chan)) { &WARN("part: not on $chan; doing anyway"); @@ -845,10 +853,15 @@ sub joinfloodCheck { ### Clean it up. my $delete = 0; + my $time = time(); foreach $chan (keys %floodjoin) { foreach $who (keys %{ $floodjoin{$chan} }) { - my $time = time() - $floodjoin{$chan}{$who}{Time}; - next unless ($time > 10); + my $t = $floodjoin{$chan}{$who}{Time}; + next unless (defined $t); + + my $delta = $time - $t; + next unless ($delta > 10); + delete $floodjoin{$chan}{$who}; $delete++; } diff --git a/blootbot/src/IRC/IrcHooks.pl b/blootbot/src/IRC/IrcHooks.pl index b181714..7f2e7f8 100644 --- a/blootbot/src/IRC/IrcHooks.pl +++ b/blootbot/src/IRC/IrcHooks.pl @@ -374,7 +374,7 @@ sub on_endofnames { # sync time should be done in on_endofwho like in BitchX if (exists $cache{jointime}{$chan}) { my $delta_time = sprintf("%.03f", &timedelta($cache{jointime}{$chan}) ); - $delta_time = 0 if ($delta_time < 0); + $delta_time = 0 if ($delta_time <= 0); if ($delta_time > 100) { &WARN("endofnames: delta_time > 100 ($delta_time)"); } @@ -382,7 +382,7 @@ sub on_endofnames { &status("$b_blue$chan$ob: sync in ${delta_time}s."); } - rawout("MODE $chan"); + &rawout("MODE $chan"); my $txt; my @array; @@ -756,6 +756,11 @@ sub on_part { $who = $nick; $msgType = "public"; + if (0 and !exists $channels{$chan}) { + &DEBUG("on_part: found out we're on $chan!"); + $channels{$chan} = 1; + } + if (exists $floodjoin{$chan}{$nick}{Time}) { delete $floodjoin{$chan}{$nick}; } @@ -818,17 +823,40 @@ sub on_public { # would this slow things down? if ($_ = &getChanConf("ircTextCounters")) { + my $time = time(); + foreach (split /[\s]+/) { - next unless ($msg =~ /^\Q$_\E$/i); - &VERB("textcounters: $_ matched for $who",2); + my $x = $_; + + # either full word or ends with a space, etc... + next unless ($msg =~ /^\Q$x\E[\$\s!.]/i); + + &VERB("textcounters: $x matched for $who",2); + my $c = $chan || "PRIVATE"; - my $v = &dbGet("stats", "counter", "nick=".&dbQuote($who). - " AND type='$msg'"); + my ($v,$t) = &dbGet("stats", "counter,time", + "nick=". &dbQuote($who) + ." AND type=".&dbQuote($x) + ." AND channel=".&dbQuote($c) + ); $v++; - &dbReplace("stats", (nick => $who, type => $_, counter => $v) ); + # don't allow ppl to cheat the stats :-) + next unless ($time - $t > 10); + + my %hash = ( + nick => $who, + type => $x, + channel => $c, + + time => $time, + counter => $v, + ); + + + &dbReplace("stats", %hash); # does not work, atleast with old mysql!!! :( -# &dbReplace("stats", (nick => $who, type => $_, -counter => "counter+1") ); +# &dbReplace("stats", (nick => $who, type => $x, -counter => "counter+1") ); } } @@ -1076,15 +1104,28 @@ sub on_who { $nuh{lc $args[5]} = $args[5]."!".$args[2]."\@".$args[3]; } -sub on_whoisuser { +sub on_whois { my ($self, $event) = @_; my @args = $event->args; - &DEBUG("on_whoisuser: @args"); - $nuh{lc $args[1]} = $args[1]."!".$args[2]."\@".$args[3]; } +sub on_whoischannels { + my ($self, $event) = @_; + my @args = $event->args; + + &DEBUG("on_whoischannels: @args"); +} + +sub on_useronchannel { + my ($self, $event) = @_; + my @args = $event->args; + + &DEBUG("on_useronchannel: @args"); + &joinNextChan(); +} + ### ### since joinnextchan is hooked onto on_endofnames, these are needed. ### diff --git a/blootbot/src/IRC/Schedulers.pl b/blootbot/src/IRC/Schedulers.pl index fd19da2..a7d38c4 100644 --- a/blootbot/src/IRC/Schedulers.pl +++ b/blootbot/src/IRC/Schedulers.pl @@ -29,7 +29,8 @@ sub setupSchedulers { &leakCheck(2); # mandatory &ignoreCheck(1); # mandatory &seenFlushOld(2); - &ircCheck(2); # mandatory +# &ircCheck(2); # mandatory + &ircCheck(1); # mandatory &miscCheck(1); # mandatory &miscCheck2(2); # mandatory &shmFlush(1); # mandatory diff --git a/blootbot/src/Misc.pl b/blootbot/src/Misc.pl index ffc6fb6..a598234 100644 --- a/blootbot/src/Misc.pl +++ b/blootbot/src/Misc.pl @@ -212,6 +212,11 @@ sub fixFileList { my @keys = sort keys %{ $files{$file} }; my $i = scalar(@keys); + if (scalar @keys > 3) { + pop @keys while (scalar @keys > 3); + push(@keys, "..."); + } + if ($i > 1) { $file .= "\002{\002". join("\002|\002", @keys) ."\002}\002"; } else { @@ -572,7 +577,8 @@ sub validFactoid { # symbols. /(\"\*)/ and last; /, / and last; - /^\'/ and last; + (/^'/ and /'$/) and last; + (/^"/ and /"$/) and last; # delimiters. /\=\>/ and last; # '=>'. @@ -587,11 +593,13 @@ sub validFactoid { / also$/ and last; / and$/ and last; /^because / and last; + /^but / and last; /^gives / and last; /^h(is|er) / and last; /^if / and last; / is,/ and last; / it$/ and last; + /^or / and last; / says$/ and last; /^should / and last; /^so / and last; @@ -704,13 +712,21 @@ sub closeStats { foreach (keys %cmdstats) { my $type = $_; - my $i = &dbGet("stats", "counter", "nick=".&dbQuote($type). + my $i = &dbGet("stats", "counter", "nick=".&dbQuote($type). " AND type='cmdstats'"); + my $z = 0; + $z++ unless ($i); + $i += $cmdstats{$type}; - &dbReplace("stats", - (nick => $type, type => "cmdstats", counter => $i) - ); + my %hash = ( + nick => $type, + type => "cmdstats", + counter => $i + ); + $hash{time} = time() if ($z); + + &dbReplace("stats", %hash); } } diff --git a/blootbot/src/Modules/News.pl b/blootbot/src/Modules/News.pl index 58d33d5..bb2e6f2 100644 --- a/blootbot/src/Modules/News.pl +++ b/blootbot/src/Modules/News.pl @@ -396,7 +396,7 @@ sub list { &::msg($::who, "|= Last updated $timestr ago."); &::msg($::who, " \037Num\037 \037Item ".(" "x40)." \037"); - &::DEBUG("list: expire = $expire"); + &DEBUG("list: expire = $expire"); &::DEBUG("list: eno = $eno"); my $i = 1; @@ -983,4 +983,6 @@ sub stats { $i = $j = 0; } +sub AUTOLOAD { &::AUTOLOAD(@_); } + 1; diff --git a/blootbot/src/Modules/UserDCC.pl b/blootbot/src/Modules/UserDCC.pl index 195fdf8..b5b64a6 100644 --- a/blootbot/src/Modules/UserDCC.pl +++ b/blootbot/src/Modules/UserDCC.pl @@ -444,10 +444,9 @@ sub userDCC { &msg($who,"resetting..."); my @done; foreach ( keys %channels, keys %chanconf ) { - &DEBUG("reset: c => $c"); - next if (grep /^\Q$_\E$/i, @done); + my $c = $_; + next if (grep /^\Q$c\E$/i, @done); - &DEBUG("reset: should part... c => $c"); &part($_); push(@done, $_); diff --git a/blootbot/src/Process.pl b/blootbot/src/Process.pl index 8133d7a..255730f 100644 --- a/blootbot/src/Process.pl +++ b/blootbot/src/Process.pl @@ -72,6 +72,7 @@ sub process { &joinchan($chankey); &status("JOIN $chankey <$who>"); &msg($who, "joining $chankey"); + &joinNextChan(); # hack. return; } diff --git a/blootbot/src/core.pl b/blootbot/src/core.pl index 63c8406..4bda802 100644 --- a/blootbot/src/core.pl +++ b/blootbot/src/core.pl @@ -299,6 +299,31 @@ sub getChanConf { return $chanconf{"_default"}{$param}; } +##### +# Usage: &findChanConf($param); +# About: Retrieve value for 'param' value from any chan. +# Return: scalar for success, undef for failure. +sub findChanConf { + my($param) = @_; + + if (!defined $param) { + &WARN("param == NULL."); + return 0; + } + + my $c; + foreach $c (keys %chanconf) { + foreach (keys %{ $chanconf{$c} }) { + next unless (/^$param$/); + + &DEBUG("chanconf{$c}{$_} ..."); + return $chanconf{$c}{$_}; + } + } + + return; +} + sub showProc { my ($prefix) = $_[0] || ""; diff --git a/blootbot/src/db_mysql.pl b/blootbot/src/db_mysql.pl index 185a5bf..357f4a8 100644 --- a/blootbot/src/db_mysql.pl +++ b/blootbot/src/db_mysql.pl @@ -88,13 +88,10 @@ sub dbGetCol { $query .= " WHERE ".$where if ($where); my %retval; - &DEBUG("dbGetCol: query => '$query'."); - my $sth = $dbh->prepare($query); &SQLDebug($query); if (!$sth->execute) { &ERROR("GetCol: execute: '$query'"); -# &ERROR("GetCol => $DBI::errstr"); $sth->finish; return; } -- 2.39.5