]> git.donarmstrong.com Git - infobot.git/blobdiff - blootbot/src/Factoids/Core.pl
* Moved old /trunk/www out of trunk
[infobot.git] / blootbot / src / Factoids / Core.pl
index 067e49428e3c8d399f71737093c265c6c6d99d78..a43a3d6e7eee63cfe840c2bc22e745d2dbbcc2a2 100644 (file)
@@ -5,7 +5,11 @@
 #   Created: 20010906
 #
 
-if (&IsParam("useStrict")) { use strict; }
+# use strict;  # TODO
+
+use vars qw(%param %cache %lang %cmdstats %bots);
+use vars qw($message $who $addressed $chan $h $nuh $ident $msgType
+       $correction_plausable);
 
 # Usage: &validFactoid($lhs,$rhs);
 sub validFactoid {
@@ -14,7 +18,7 @@ sub validFactoid {
 
     for (lc $lhs) {
        # allow the following only if they have been made on purpose.
-       if ($rhs ne "" and $rhs !~ /^</) {
+       if ($rhs ne '' and $rhs !~ /^</) {
            / \Q$ident$/i and last;     # someone said i'm something.
            /^i('m)? / and last;
            /^(it|that|there|what)('s)?(\s+|$)/ and last;
@@ -33,7 +37,6 @@ sub validFactoid {
        /^learn / and last;             # teach. damn morons.
        /^tell (\S+) about / and last;  # tell.
        /\=\~/ and last;                # substituition.
-       /^\S+ to \S+ \S+/ and last;     # babelfish.
 
        /^\=/ and last;                 # botnick = heh is.
        /wants you to know/ and last;
@@ -120,9 +123,9 @@ sub FactoidStuff {
            if ($param{'acceptUrl'} !~ /REQUIRE/ or $rhs =~ /(http|ftp|mailto|telnet|file):/) {
                &msg($target, "$who knew: $lhs $mhs $rhs");
 
-               # "are" hack :)
-               $rhs = "<REPLY> are" if ($mhs eq "are");
-               &setFactInfo($lhs, "factoid_value", $rhs);
+               # 'are' hack :)
+               $rhs = "<REPLY> are" if ($mhs eq 'are');
+               &setFactInfo($lhs, 'factoid_value', $rhs);
            }
 
            return 'INFOBOT REPLY';
@@ -137,136 +140,146 @@ sub FactoidStuff {
        return 'forget: no addr' unless ($addressed);
 
        my $faqtoid = $message;
-       if ($faqtoid eq "") {
-           &help("forget");
+       if ($faqtoid eq '') {
+           &help('forget');
            return;
        }
 
        $faqtoid =~ tr/A-Z/a-z/;
        my $result = &getFactoid($faqtoid);
 
-       if (defined $result) {
-           my $author  = &getFactInfo($faqtoid, "created_by");
-           my $count   = &getFactInfo($faqtoid, "requested_count") || 0;
-           my $limit   = &getChanConfDefault(
-                               "factoidPreventForgetLimit", 100, $chan);
-           my $limitage = &getChanConfDefault(
-                               "factoidPreventForgetLimitTime", 180, $chan);
-           my $age     = time() - &getFactInfo($faqtoid, "created_time");
-
-           if (IsFlag("r") ne "r") {
-               &msg($who, "you don't have access to remove factoids");
-               return;
-           }
+       # if it doesn't exist, well... it doesn't!
+       if (!defined $result) {
+           &performReply("i didn't have anything called '$faqtoid' to forget");
+           return;
+       }
 
-           return 'locked factoid' if (&IsLocked($faqtoid) == 1);
-           my $isop = (&IsFlag("o") eq "o") ? 1 : 0;
+       # TODO: squeeze 3 getFactInfo calls into one?
+       my $author      = &getFactInfo($faqtoid, 'created_by');
+       my $count       = &getFactInfo($faqtoid, 'requested_count') || 0;
+       # don't delete if requested $limit times
+       my $limit       = &getChanConfDefault('factoidPreventForgetLimit', 100, $chan);
+       # don't delete if older than $limitage seconds (modified by requests below)
+       my $limitage    = &getChanConfDefault('factoidPreventForgetLimitTime', 7 * 24 * 60 * 60, $chan);
+       my $t           = &getFactInfo($faqtoid, 'created_time') || 0;
+       my $age         = time() - $t;
+
+       # lets scale limitage from 1 (nearly 0) to $limit (full time).
+       $limitage       = $limitage*($count+1)/$limit if ($count < $limit);
+       # isauthor and isop.
+       my $isau        = (defined $author and &IsHostMatch($author) == 2) ? 1 : 0;
+       my $isop        = (&IsFlag('o') eq 'o') ? 1 : 0;
+
+       if (IsFlag('r') ne 'r' && !$isop) {
+           &msg($who, "you don't have access to remove factoids");
+           return;
+       }
 
-           ### lets go do some checking.
+       return 'locked factoid' if (&IsLocked($faqtoid) == 1);
 
-           # factoidPreventForgetLimitTime:
-           if (!$isop and $age/(60*60*24) > $limitage) {
-               &msg($who, "cannot remove factoid since it is protected by Time.");
-               return;
-           }
+       ###
+       ### lets go do some checking.
+       ###
 
-           # factoidPreventForgetLimit:
-           if (!$isop and $limit and $count > $limit) {
-               &msg($who, "will not delete '$faqtoid', count > limit ($count > $limit)");
-               return;
-           }
+       # factoidPreventForgetLimitTime:
+       if (!($isop or $isau) and $age/(60*60*24) > $limitage) {
+           &msg($who, "cannot remove factoid '$faqtoid', too old. (" .
+                   $age/(60*60*24) . ">$limitage) use 'no,' instead");
+           return;
+       }
 
-           # this may eat some memory.
-           # prevent deletion if other factoids redirect to it.
-           # todo: use hash instead of array.
-           my @list;
-           if (&getChanConf("factoidPreventForgetRedirect")) {
-               &status("Factoids/Core: forget: checking for redirect factoids");
-               @list = &searchTable("factoids", "factoid_key",
-                               "factoid_value", "^<REPLY> see ");
-           }
+       # factoidPreventForgetLimit:
+       if (!($isop or $isau) and $limit and $count > $limit) {
+           &msg($who, "will not delete '$faqtoid', count > limit ($count > $limit) use 'no, ' instead.");
+           return;
+       }
 
-           my $match = 0;
-           for (@list) {
-               my $f = $_;
-               my $v = &getFactInfo($f, "factoid_value");
-               my $fsafe = quotemeta($faqtoid);
-               next unless ($v =~ /^<REPLY> ?see( also)? $fsafe\.?$/i);
+       # this may eat some memory.
+       # prevent deletion if other factoids redirect to it.
+       # TODO: use hash instead of array.
+       my @list;
+       if (&getChanConf('factoidPreventForgetRedirect')) {
+           &status("Factoids/Core: forget: checking for redirect factoids");
+           @list = &searchTable('factoids', 'factoid_key',
+                       'factoid_value', "^<REPLY> see ");
+       }
 
-               &DEBUG("Factoids/Core: match! ($f || $faqtoid)");
+       my $match = 0;
+       for (@list) {
+           my $f = $_;
+           my $v = &getFactInfo($f, 'factoid_value');
+           my $fsafe = quotemeta($faqtoid);
+           next unless ($v =~ /^<REPLY> ?see( also)? $fsafe\.?$/i);
 
-               $match++;
-           }
-           # todo: warn for op aswell, but allow force delete.
-           if (!$isop and $match) {
-               &msg($who, "uhm, other (redirection) factoids depend on this one.");
-               return;
-           }
+           &DEBUG("Factoids/Core: match! ($f || $faqtoid)");
 
-           # minimize abuse.
-           my $faqauth = &getFactInfo($faqtoid, "created_by");
-           if (!$isop and &IsHostMatch($faqauth) != 2) {
-               $cache{forget}{$h}++;
+           $match++;
+       }
+       # TODO: warn for op aswell, but allow force delete.
+       if (!$isop and $match) {
+           &msg($who, "uhm, other (redirection) factoids depend on this one.");
+           return;
+       }
 
-               # warn.
-               if ($cache{forget}{$h} > 3) {
-                   &msg($who, "Stop abusing forget!");
-               }
+       # minimize abuse.
+       if (!$isop and &IsHostMatch($author) != 2) {
+           $cache{forget}{$h}++;
 
-               # ignore.
-               # todo: make forget limit configurable.
-               # todo: make forget ignore time configurable.
-               if ($cache{forget}{$h} > 5) {
-                   &ignoreAdd(&makeHostMask($nuh), "*", 3*24*60*60, "abuse of forget");
-                   &msg($who, "forget: Suck it!");
-               }
+           # warn.
+           if ($cache{forget}{$h} > 3) {
+               &msg($who, "Stop abusing forget!");
            }
 
-           # lets do it!
+           # ignore.
+           # TODO: make forget limit configurable.
+           # TODO: make forget ignore time configurable.
+           if ($cache{forget}{$h} > 5) {
+               &ignoreAdd(&makeHostMask($nuh), '*', 3*24*60, "abuse of forget");
+               &msg($who, "forget: Ignoring you for abuse!");
+           }
+       }
 
-           if (&IsParam("factoidDeleteDelay") or &IsChanConf("factoidDeleteDelay")) {
-               if (!$isop and $faqtoid =~ / #DEL#$/) {
-                   &msg($who, "cannot delete it ($faqtoid).");
-                   return;
-               }
+       # lets do it!
 
-               &status("forgot (safe delete): '$faqtoid' - ". scalar(localtime));
-               ### TODO: check if the "backup" exists and overwrite it
-               my $check = &getFactoid("$faqtoid #DEL#");
+       if (&IsParam('factoidDeleteDelay') or &IsChanConf('factoidDeleteDelay') > 0) {
+           if (!($isop or $isau) and $faqtoid =~ / #DEL#$/) {
+               &msg($who, "cannot delete it ($faqtoid).");
+               return;
+           }
 
-               if (!defined $check or $check =~ /^\s*$/) {
-                   if ($faqtoid !~ / #DEL#$/) {
-                       my $new = $faqtoid." #DEL#";
+           &status("forgot (safe delete): '$faqtoid' - ". scalar(gmtime));
+           ### TODO: check if the 'backup' exists and overwrite it
+           my $check = &getFactoid("$faqtoid #DEL#");
 
-                       my $backup = &getFactoid($new);
-                       if ($backup) {
-                           &DEBUG("forget: not overwriting backup: $faqtoid");
-                       } else {
-                           &status("forget: backing up '$faqtoid'");
-                           &setFactInfo($faqtoid, "factoid_key", $new);
-                           &setFactInfo($new, "modified_by", $who);
-                           &setFactInfo($new, "modified_time", time());
-                       }
+           if (!defined $check or $check =~ /^\s*$/) {
+               if ($faqtoid !~ / #DEL#$/) {
+                   my $new = $faqtoid." #DEL#";
 
+                   my $backup = &getFactoid($new);
+                   if ($backup) {
+                       &DEBUG("forget: not overwriting backup: $faqtoid");
                    } else {
-                       &status("forget: not backing up $faqtoid.");
+                       &status("forget: backing up '$faqtoid'");
+                       &setFactInfo($faqtoid, 'factoid_key', $new);
+                       &setFactInfo($new, 'modified_by', $who);
+                       &setFactInfo($new, 'modified_time', time());
                    }
 
                } else {
-                   &status("forget: not overwriting backup!");
+                   &status("forget: not backing up $faqtoid.");
                }
-           }
 
-           &status("forget: <$who> '$faqtoid' =is=> '$result'");
-           &delFactoid($faqtoid);
+           } else {
+               &status("forget: not overwriting backup!");
+           }
+       }
 
-           &performReply("i forgot $faqtoid");
+       &status("forget: <$who> '$faqtoid' =is=> '$result'");
+       &delFactoid($faqtoid);
 
-           $count{'Update'}++;
+       &performReply("i forgot $faqtoid");
 
-       } else {
-           &performReply("i didn't have anything called '$faqtoid'");
-       }
+       $count{'Update'}++;
 
        return;
     }
@@ -276,16 +289,16 @@ sub FactoidStuff {
        return 'unforget: no addr' unless ($addressed);
 
        my $i = 0;
-       $i++ if (&IsParam("factoidDeleteDelay"));
-       $i++ if (&IsChanConf("factoidDeleteDelay"));
+       $i++ if (&IsParam('factoidDeleteDelay'));
+       $i++ if (&IsChanConf('factoidDeleteDelay') > 0);
        if (!$i) {
            &performReply("safe delete has been disable so what is there to undelete?");
            return;
        }
 
        my $faqtoid = $message;
-       if ($faqtoid eq "") {
-           &help("undelete");
+       if ($faqtoid eq '') {
+           &help('unforget');
            return;
        }
 
@@ -293,25 +306,28 @@ sub FactoidStuff {
        my $result = &getFactoid($faqtoid." #DEL#");
        my $check  = &getFactoid($faqtoid);
 
-       if (!defined $result) {
-           &performReply("that factoid was not backedup :/");
-           return;
-       }
-
        if (defined $check) {
            &performReply("cannot undeleted '$faqtoid' because it already exists!");
            return;
        }
 
-       &setFactInfo($faqtoid." #DEL#", "factoid_key", $faqtoid);
-
-       ### delete info. modified_ isn't really used.
-       &setFactInfo($faqtoid, "modified_by",  "");
-       &setFactInfo($faqtoid, "modified_time", 0);
+       if (!defined $result) {
+           &performReply("that factoid was not backedup :/");
+           return;
+       }
 
-       &performReply("Successfully recovered '$faqtoid'.  Have fun now.");
+       &setFactInfo($faqtoid." #DEL#", 'factoid_key',   $faqtoid);
+#      &setFactInfo($faqtoid, 'modified_by',   '');
+#      &setFactInfo($faqtoid, 'modified_time', 0);
 
-       $count{'Undelete'}++;
+       $check  = &getFactoid($faqtoid);
+       # TODO: check if $faqtoid." #DEL#" exists?
+       if (defined $check) {
+           &performReply("Successfully recovered '$faqtoid'.  Have fun now.");
+           $count{'Undelete'}++;
+       } else {
+           &performReply("did not recover '$faqtoid'.  What happened?");
+       }
 
        return;
     }
@@ -323,19 +339,19 @@ sub FactoidStuff {
        my $function = lc $1;
        my $faqtoid  = lc $4;
 
-       if ($faqtoid eq "") {
+       if ($faqtoid eq '') {
            &help($function);
            return;
        }
 
-       if (&getFactoid($faqtoid) eq "") {
+       if (&getFactoid($faqtoid) eq '') {
            &msg($who, "factoid \002$faqtoid\002 does not exist");
            return;
        }
 
-       if ($function eq "lock") {
+       if ($function eq 'lock') {
            # strongly requested by #debian on 19991028. -xk
-           if (1 and $faqtoid !~ /^\Q$who\E$/i and &IsFlag("o") ne "o") {
+           if (1 and $faqtoid !~ /^\Q$who\E$/i and &IsFlag('o') ne 'o') {
                &msg($who,"sorry, locking cannot be used since it can be abused unneccesarily.");
                &status("Replace 1 with 0 in Process.pl#~324 for locking support.");
                return;
@@ -353,35 +369,35 @@ sub FactoidStuff {
     if ($message =~ s/^rename(\s+|$)//) {
        return 'rename: no addr' unless ($addressed);
 
-       if ($message eq "") {
-           &help("rename");
+       if ($message eq '') {
+           &help('rename');
            return;
        }
 
        if ($message =~ /^'(.*)'\s+'(.*)'$/) {
-           my($from,$to) = (lc $1, lc $2);
+           my ($from,$to) = (lc $1, lc $2);
 
            my $result = &getFactoid($from);
-           if (defined $result) {
-               my $author = &getFactInfo($from, "created_by");
+           if (!defined $result) {
+               &performReply("i didn't have anything called '$from' to rename");
+               return;
+           }
 
-               if (0 and !&IsFlag("m") or $author !~ /^\Q$who\E\!/i) {
-                   &msg($who, "It's not yours to modify.");
-                   return;
-               }
+           # who == nick!user@host.
+           if (&IsFlag('m') ne 'm' and $author !~ /^\Q$who\E\!/i) {
+               &msg($who, "factoid '$from' is not yours to modify.");
+               return;
+           }
 
-               if ($_ = &getFactoid($to)) {
-                   &performReply("destination factoid already exists.");
-                   return;
-               }
+           if ($_ = &getFactoid($to)) {
+               &performReply("destination factoid already exists.");
+               return;
+           }
 
-               &setFactInfo($from,"factoid_key",$to);
+           &setFactInfo($from,'factoid_key',$to);
 
-               &status("rename: <$who> '$from' is now '$to'");
-               &performReply("i renamed '$from' to '$to'");
-           } else {
-               &performReply("i didn't have anything called '$from'");
-           }
+           &status("rename: <$who> '$from' is now '$to'");
+           &performReply("i renamed '$from' to '$to'");
        } else {
            &msg($who,"error: wrong format. ask me about 'help rename'.");
        }
@@ -405,29 +421,34 @@ sub FactoidStuff {
            return 'subst: locked' if (&IsLocked($faqtoid) == 1);
            my $was = $result;
 
-           if (($flags eq "g" && $result =~ s/\Q$op/$np/gi) || $result =~ s/\Q$op/$np/i) {
+           if (($flags eq 'g' && $result =~ s/\Q$op/$np/gi) || $result =~ s/\Q$op/$np/i) {
                # excessive length.
                if (length $result > $param{'maxDataSize'}) {
                    &performReply("that's too long");
                    return;
                }
+               # empty
+               if (length $result == 0) {
+                   &performReply("factoid would be empty. use forget?");
+                   return;
+               }
                # min length.
-               my $faqauth = &getFactInfo($faqtoid, "created_by");
+               my $faqauth = &getFactInfo($faqtoid, 'created_by');
                if ((length $result)*2 < length $was and
-                       &IsFlag("o") ne "o" and
-                       &IsHostMask($faqauth) != 2
+                       &IsFlag('o') ne 'o' and
+                       &IsHostMatch($faqauth) != 2
                ) {
                    &performReply("too drastic change of factoid.");
                }
 
-               &setFactInfo($faqtoid, "factoid_value", $result);
+               &setFactInfo($faqtoid, 'factoid_value', $result);
                &status("update: '$faqtoid' =is=> '$result'; was '$was'");
-               &performReply("OK");
+               &performReply('OK');
            } else {
                &performReply("that doesn't contain '$op'");
            }
        } else {
-           &performReply("i didn't have anything called '$faqtoid'");
+           &performReply("i didn't have anything called '$faqtoid' to modify");
        }
 
        return;
@@ -439,7 +460,7 @@ sub FactoidStuff {
        # fix the string.
        s/^hey([, ]+)where/where/i;
        s/\s+\?$/?/;
-       s/whois/who is/ig;
+       s/^whois /who is /i; # Must match ^, else factoids with "whois" anywhere break
        s/where can i find/where is/i;
        s/how about/where is/i;
        s/ da / the /ig;
@@ -476,11 +497,11 @@ sub FactoidStuff {
     if (defined $result and $result !~ /^0?$/) {       # question.
        &status("question: <$who> $message");
        $count{'Question'}++;
-    } elsif (&IsChanConf("perlMath") > 0 and $addressed) { # perl math.
-       &loadMyModule("perlMath");
+    } elsif (&IsChanConf('Math') > 0 and $addressed) { # perl math.
+       &loadMyModule('Math');
        my $newresult = &perlMath();
 
-       if (defined $newresult and $newresult ne "") {
+       if (defined $newresult and $newresult ne '') {
            $cmdstats{'Maths'}++;
            $result = $newresult;
            &status("math: <$who> $message => $result");
@@ -493,7 +514,7 @@ sub FactoidStuff {
     }
 
     # why would a friendly bot get passed here?
-    if (&IsParam("friendlyBots")) {
+    if (&IsParam('friendlyBots')) {
        return if (grep lc($_) eq lc($who), split(/\s+/, $param{'friendlyBots'}));
     }
 
@@ -502,7 +523,7 @@ sub FactoidStuff {
        return;
     }
 
-    return unless ($addressed);
+    return unless ($addressed and !$addrchar);
 
     if (length $message > 64) {
        &status("unparseable-moron: $message");