]> git.donarmstrong.com Git - infobot.git/blobdiff - src/CommandStubs.pl
- patch from Morten Brix Pedersen <morten@wtf.dk>. Thanks!
[infobot.git] / src / CommandStubs.pl
index 91dfc721ffeee61586670b7885d10a3c81456b2a..1a55669aef5b19ad323f1480aa82a45997506e3f 100644 (file)
@@ -73,7 +73,7 @@ sub parseCmdHook {
        }
 
        if ($hash{NoArgs} and $flatarg) {
-           &DEBUG("cmd $ident does not take args; skipping.");
+           &DEBUG("cmd $ident does not take args ('$flatarg'); skipping.");
            next;
        }
 
@@ -280,6 +280,16 @@ sub Modules {
        $itc =~ s/([^\w\s])/\\$1/g;
        my $z = join '|', split ' ', $itc;
 
+       if ($msgType eq "privmsg" and $message =~ / ($mask{chan})$/) {
+           &DEBUG("ircTC: privmsg detected; chan = $1");
+           $chan = $1;
+       }
+
+       if ($message =~ /^_stats(\s+(\S+))$/i) {
+           &textstats_main($2);
+           return;
+       }
+
        if ($message =~ /^($z)stats(\s+(\S+))?$/i) {
            my $type    = $1;
            my $arg     = $3;
@@ -292,7 +302,6 @@ sub Modules {
            &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.
@@ -313,15 +322,15 @@ sub Modules {
                    }
                }
                my $topstr = "";
-               &DEBUG("tp => $tp");
+               &DEBUG("*stats: tp => $tp");
                if (scalar @top) {
                    $topstr = ".  Top ".scalar(@top).": ".join(', ', @top);
                }
 
                if (defined $sum) {
-                   &pSReply("total count of '$type' on $c: $sum$topstr");
+                   &pSReply("total count of \037$type\037 on \002$c\002: $sum$topstr");
                } else {
-                   &pSReply("zero counter for '$type'.");
+                   &pSReply("zero counter for \037$type\037.");
                }
            } else {
                my $x = (&dbRawReturn("SELECT SUM(counter) FROM stats".
@@ -348,11 +357,11 @@ sub Modules {
                my $xtra = "";
                if ($total and $good) {
                    my $pct = sprintf("%.01f", 100*(1+$total-$i)/$total);
-                   $xtra = ", ranked $i/$total (percentile: $pct %)";
+                   $xtra = ", ranked $i\002/\002$total (percentile: \002$pct\002 %)";
                }
 
                my $pct1 = sprintf("%.01f", 100*$x/$sum);
-               &pSReply("$arg has said $type $x times ($pct1 %)$xtra");
+               &pSReply("\002$arg\002 has said \037$type\037 \002$x\002 times (\002$pct1\002 %)$xtra");
            }
 
            return;
@@ -560,7 +569,8 @@ sub uptime {
 
 # seen.
 sub seen {
-    my($person) = @_;
+    my($person) = lc shift;
+    $person =~ s/\?*$//;
 
     if (!defined $person or $person =~ /^$/) {
        &help("seen");
@@ -573,7 +583,6 @@ sub seen {
     }
 
     my @seen;
-    $person =~ s/\?*$//;
 
     &seenFlush();      # very evil hack. oh well, better safe than sorry.
 
@@ -720,7 +729,7 @@ sub lart {
        }
     }
 
-    my $line = &getRandomLineFromFile($bot_misc_dir. "/blootbot.lart");
+    my $line = &getRandomLineFromFile($bot_data_dir. "/blootbot.lart");
     if (defined $line) {
        if ($target =~ /^(me|you|itself|\Q$ident\E)$/i) {
            $line =~ s/WHO/$who/g;
@@ -793,12 +802,24 @@ sub do_verstats {
        return;
     }
 
-    &msg($who, "Sending CTCP VERSION...");
+    &msg($who, "Sending CTCP VERSION to #$chan...");
     $conn->ctcp("VERSION", $chan);
     $cache{verstats}{chan}     = $chan;
     $cache{verstats}{who}      = $who;
     $cache{verstats}{msgType}  = $msgType;
 
+    $conn->schedule(30, sub {
+       my $c           = lc $cache{verstats}{chan};
+       @vernicktodo    = ();
+
+       foreach (keys %{ $channels{$c}{''} } ) {
+           next if (grep /^\Q$_\E$/i, @vernick);
+           push(@vernicktodo, $_);
+       }
+
+       &verstats_flush();
+    } );
+
     $conn->schedule(60, sub {
        my $vtotal      = 0;
        my $c           = lc $cache{verstats}{chan};
@@ -816,7 +837,7 @@ sub do_verstats {
        my $unknown     = $total - $vtotal;
        my $perc        = sprintf("%.1f", $unknown * 100 / $total);
        $perc           =~ s/.0$//;
-       $sorted{$perc}{"unknown/cloak"} = "$unknown ($perc%)";
+       $sorted{$perc}{"unknown/cloak"} = "$unknown ($perc%)" if ($unknown);
 
        foreach (keys %ver) {
            my $count   = scalar keys %{ $ver{$_} };
@@ -845,6 +866,101 @@ sub do_verstats {
     return;
 }
 
+sub verstats_flush {
+    for (1..5) {
+       last unless (scalar @vernicktodo);
+
+       my $n = shift(@vernicktodo);
+       $conn->ctcp("VERSION", $n);
+    }
+
+    return unless (scalar @vernicktodo);
+
+    $conn->schedule(3, \&verstats_flush() );
+}
+
+sub textstats_main {
+    my($arg) = @_;
+
+    # even more uglier with channel/time arguments.
+    my $c      = $chan;
+#    my $c     = $chan || "PRIVATE";
+    my $where  = "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];
+
+    if (!defined $arg or $arg =~ /^\s*$/) {
+       # this is way fucking ugly.
+       &DEBUG("_stats: !arg");
+
+       my %hash = &dbGetCol("stats", "nick,counter",
+               $where." ORDER BY counter DESC LIMIT 3", 1);
+       my $i;
+       my @top;
+
+       # unfortunately we have to sort it again!
+       # todo: make dbGetCol return hash and array? too much effort.
+       my $tp = 0;
+       foreach $i (sort { $b <=> $a } keys %hash) {
+           foreach (keys %{ $hash{$i} }) {
+               my $p   = sprintf("%.01f", 100*$i/$sum);
+               $tp     += $p;
+               push(@top, "\002$_\002 -- $i ($p%)");
+           }
+       }
+
+       my $topstr = "";
+       &DEBUG("*stats: tp => $tp");
+       if (scalar @top) {
+           $topstr = ".  Top ".scalar(@top).": ".join(', ', @top);
+       }
+
+       if (defined $sum) {
+           &pSReply("total count of \037$type\037 on \002$c\002: $sum$topstr");
+       } else {
+           &pSReply("zero counter for \037$type\037.");
+       }
+    } else {
+       my %hash = &dbGetCol("stats", "type,counter",
+               "$where AND nick=".&dbQuote($arg) );
+
+       foreach (keys %hash) {
+           &DEBUG("_stats: hash{$_} => $hash{$_}");
+           # ranking.
+           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);
+           &DEBUG("   i => $i, good => $good, total => $total");
+       }
+
+       return;
+
+       if (!defined $x) {      # !defined.
+           &pSReply("$arg has not said $type yet.");
+           return;
+       }
+
+       my $xtra = "";
+       if ($total and $good) {
+           my $pct = sprintf("%.01f", 100*(1+$total-$i)/$total);
+           $xtra = ", ranked $i\002/\002$total (percentile: \002$pct\002 %)";
+       }
+
+       my $pct1 = sprintf("%.01f", 100*$x/$sum);
+       &pSReply("\002$arg\002 has said \037$type\037 \002$x\002 times (\002$pct1\002 %)$xtra");
+    }
+}
+
 sub nullski { my ($arg) = @_; return unless (defined $arg);
        foreach (`$arg`) { &msg($who,$_); } }