]> git.donarmstrong.com Git - infobot.git/commitdiff
- irctextcounters: add percentile/ranking.
authordms <dms@c11ca15a-4712-0410-83d8-924469b57eb5>
Mon, 6 Aug 2001 14:55:24 +0000 (14:55 +0000)
committerdms <dms@c11ca15a-4712-0410-83d8-924469b57eb5>
Mon, 6 Aug 2001 14:55:24 +0000 (14:55 +0000)
- 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/blootbot@512 c11ca15a-4712-0410-83d8-924469b57eb5

src/CommandStubs.pl
src/Factoids/Question.pl
src/IRC/Irc.pl
src/IRC/IrcHooks.pl
src/IRC/Schedulers.pl
src/Misc.pl
src/Modules/News.pl
src/Modules/UserDCC.pl
src/Process.pl
src/core.pl
src/db_mysql.pl

index eba7a50462bfee29f81632a2eec40bc92d167eb3..91dfc721ffeee61586670b7885d10a3c81456b2a 100644 (file)
@@ -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<scalar @array; $i++) {
+                   next unless ($array[0] =~ /^\Q$who\E$/);
+                   $good++;
+                   last;
                }
+               $i++;
+
+               my $total = scalar(@array);
+               my $xtra = "";
+               if ($total and $good) {
+                   my $pct = sprintf("%.01f", 100*(1+$total-$i)/$total);
+                   $xtra = ", ranked $i/$total (percentile: $pct %)";
+               }
+
+               my $pct1 = sprintf("%.01f", 100*$x/$sum);
+               &pSReply("$arg has said $type $x times ($pct1 %)$xtra");
            }
 
            return;
index e61b30fa8fc51d84aa9fa571bb5f3b9414e98baa..93725e553cfd1a0b253c6d40decc27bf82c815f0 100644 (file)
@@ -87,6 +87,7 @@ sub doQuestion {
 
     if (&IsChanConf("factoidArguments")) {
        $result = &factoidArgs($query[0]);
+
        return $result if (defined $result);
     }
 
@@ -186,6 +187,9 @@ sub factoidArgs {
        my @vals;
        my $arg = $_;
 
+       # todo: <greycat> ~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;
index a5c0ca48250b9ca6c93e9b210341afbc849517dd..d6f81b6cb1b1ec31a0a2bd6b5ef80c4997dd9d14 100644 (file)
@@ -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++;
        }
index b1817147c5c9ed7ecfe80eb13b29d75449747a8c..7f2e7f874438a36e3bb035f76da254db2b0462da 100644 (file)
@@ -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.
 ###
index fd19da2698b552ab2e93aa93fe5bf9039ea32367..a7d38c4b796270f6d2911810f5077f64fdb4be5f 100644 (file)
@@ -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
index ffc6fb6467a5f19784abed4c9969873d57b82998..a598234f515f5cfa340ffef4cfb358818c9d36d5 100644 (file)
@@ -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);
     }
 }
 
index 58d33d58f1098556f5f8b0619346517b90b273e6..bb2e6f28b43f520cefe4f71442d8e4169ebe5847 100644 (file)
@@ -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;
index 195fdf846d0d0d548a2da50af88c3dd90b8b3674..b5b64a63b8dfb073925ce328eb042524b3466424 100644 (file)
@@ -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, $_);
index 8133d7ac9380c3bafd2e11872c2deab1c4c41c71..255730f270f79bc23712d796f6d78f5321d54667 100644 (file)
@@ -72,6 +72,7 @@ sub process {
        &joinchan($chankey);
        &status("JOIN $chankey <$who>");
        &msg($who, "joining $chankey");
+       &joinNextChan();        # hack.
 
        return;
     }
index 63c840663942ea1c7d344fefc4dc721ddca70487..4bda8023d257a06ff050472fe116d045755a382d 100644 (file)
@@ -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] || "";
 
index 185a5bf5b521f5c591591637265dba598e204b78..357f4a894938621bf5d4a6355f40285eac5cb392 100644 (file)
@@ -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;
     }