]> git.donarmstrong.com Git - infobot.git/blob - src/CommandStubs.pl
lame warning fix for babel
[infobot.git] / src / CommandStubs.pl
1 #
2 # User Command Extension Stubs
3 #
4
5 if (&IsParam("useStrict")) { use strict; }
6
7 use vars qw(@W3Search_engines $W3Search_regex);
8 @W3Search_engines = qw(AltaVista Dejanews Excite Gopher HotBot Infoseek
9                         Lycos Magellan PLweb SFgate Simple Verity Google);
10 $W3Search_regex = join '|', @W3Search_engines;
11 $babel::lang_regex = "";        # lame fix.
12
13 ### PROPOSED COMMAND HOOK IMPLEMENTATION.
14 # addCmdHook('TEXT_HOOK', $code_ref,
15 #       (Forker         => 1,
16 #       Identifier      => 'config_label',
17 #       Help            => 'help_label',
18 #       Cmdstats        => 'text_label',)
19 #}
20 ### EXAMPLE
21 # addCmdHook('d?find', (
22 #       CODEREF => \&debianFind(),
23 #       Forker => 1,
24 #       Identifier => "debian",
25 #       Help => "dfind",
26 #       Cmdstats => "Debian Search",) );
27 ### NOTES:
28 #   * viable solution?
29 ###
30
31 sub addCmdHook {
32     my ($ident, %hash) = @_;
33
34     &DEBUG("aCH: added $ident to command hooks.");
35     $cmdhooks{$ident} = \%hash;
36 }
37
38 # RUN IF ADDRESSED.
39 sub parseCmdHook {
40     foreach (keys %cmdhooks) {
41         &DEBUG("cmdhooks{$_} => ...");
42         my %hash = \%{ $cmdhooks{$_} };
43         foreach (keys %hash) {
44             &DEBUG("   '$_' => '$hash{$_}'.");
45         }
46     }
47
48     &DEBUG("pCH: ended.");
49 }
50
51 sub Modules {
52     if (!defined $message) {
53         &WARN("Modules: message is undefined. should never happen.");
54         return;
55     }
56
57     # babel bot: Jonathan Feinberg++
58     if (&IsParam("babelfish") and $message =~ m{
59                 ^\s*
60                 (?:babel(?:fish)?|x|xlate|translate)
61                 \s+
62                 (to|from)               # direction of translation (through)
63                 \s+
64                 ($babel::lang_regex)\w* # which language?
65                 \s*
66                 (.+)                    # The phrase to be translated
67         }xoi) {
68
69         &Forker("babelfish", sub { &babel::babelfish(lc $1, lc $2, $3); } );
70
71         $cmdstats{'BabelFish'}++;
72         return $noreply;
73     }
74
75     # cookie (random). xk++
76     if ($message =~ /^(cookie|random)(\s+(.*))?$/i) {
77         return $noreply unless (&hasParam("cookie"));
78
79         my $arg = $3;
80
81         # lets find that secret cookie.
82         my $target      = $talkchannel;
83         $target         = $who          if ($msgType ne 'public');
84
85         my $cookiemsg   = &getRandom(keys %{$lang{'cookie'}});
86         my ($key,$value);
87         ### WILL CHEW TONS OF MEM.
88         ### TODO: convert this to a Forker function!
89         if ($arg) {
90             my @list = &searchTable("factoids", "factoid_key", "factoid_value", $arg);
91             $key  = &getRandom(@list);
92             $val  = &getFactInfo("factoids", $key, "factoid_value");
93         } else {
94             ($key,$value) = &randKey("factoids","factoid_key,factoid_value");
95         }
96
97         $cookiemsg      =~ s/##KEY/\002$key\002/;
98         $cookiemsg      =~ s/##VALUE/$value/;
99         $cookiemsg      =~ s/##WHO/$who/;
100         $cookiemsg      =~ s/\$who/$who/;       # cheap fix.
101         $cookiemsg      =~ s/(\S+)?\s*<\S+>/$1 /;
102         $cookiemsg      =~ s/\s+/ /g;
103
104         if ($cookiemsg =~ s/^ACTION //i) {
105             &action($target, $cookiemsg);
106         } else {
107             &msg($target, $cookiemsg);
108         }
109
110         $cmdstats{'Random Cookie'}++;
111         return $noreply;
112     }
113
114     if ($message =~ /^d?bugs$/i) {
115         return $noreply unless (&hasParam("debianExtra"));
116
117         &Forker("debianExtra", sub { &debianBugs(); } );
118
119         $cmdstats{'Debian Bugs'}++;
120         return $noreply;
121     }
122
123     # Debian Author Search.
124     if ($message =~ /^dauthor(\s+(.*))?$/i) {
125         return $noreply unless (&hasParam("debian"));
126
127         my $query = $2;
128         if (!defined $query) {
129             &help("dauthor");
130             return $noreply;
131         }
132
133         &Forker("debian", sub { &Debian::searchAuthor($query); } );
134
135         $cmdstats{'Debian Author Search'}++;
136         return $noreply;
137     }
138
139     # Debian Incoming Search.
140     if ($message =~ /^dincoming$/i) {
141         return $noreply unless (&hasParam("debian"));
142
143         &Forker("debian", sub { &Debian::generateIncoming(); } );
144
145         $cmdstats{'Debian Incoming Search'}++;
146         return $noreply;
147     }
148
149     # Debian Distro(Package) Stats
150     if ($message =~ /^dstats(\s+(.*))?$/i) {
151         return $noreply unless (&hasParam("debian"));
152         my $dist = $2 || $Debian::defaultdist;
153
154         &Forker("debian", sub { &Debian::infoStats($dist); } );
155
156         $cmdstats{'Debian Statistics'}++;
157         return $noreply;
158     }
159
160     # Debian Contents search.
161     if ($message =~ /^d?contents(\s+(.*))?$/i) {
162         return $noreply unless (&hasParam("debian"));
163
164         my $query = $2;
165         if (!defined $query) {
166             &help("contents");
167             return $noreply;
168         }
169
170         &Forker("debian", sub { &Debian::searchContents($query); } );
171
172         $cmdstats{'Debian Contents Search'}++;
173         return $noreply;
174     }
175
176     # Debian Package info.
177     if ($message =~ /^d?find(\s+(.*))?$/i and &IsParam("debian")) {
178         my $string = $2;
179
180         if (!defined $string) {
181             &help("find");
182             return $noreply;
183         }
184
185         &Forker("debian", sub { &Debian::DebianFind($string); } );
186         return $noreply;
187     }
188
189     if (&IsParam("debian")) {
190         my $debiancmd    = 'conflicts?|depends?|desc|file|info|provides?';
191         $debiancmd      .= '|recommends?|suggests?|maint|maintainer';
192         if ($message =~ /^($debiancmd)(\s+(.*))?$/i) {
193             my $package = lc $3;
194
195             if (defined $package) {
196                 &Forker("debian", sub { &Debian::infoPackages($1, $package); } );
197             } else {
198                 &help($1);
199             }
200
201             return $noreply;
202         }
203     }
204
205     # Dict. xk++
206     if ($message =~ /^dict(\s+(.*))?$/i) {
207         return $noreply unless (&hasParam("dict"));
208
209         my $query = $2;
210         $query =~ s/^[\s\t]+//;
211         $query =~ s/[\s\t]+$//;
212         $query =~ s/[\s\t]+/ /;
213
214         if (!defined $query) {
215             &help("dict");
216             return $noreply;
217         }
218
219         if (length $query > 30) {
220             &msg($who,"dictionary word is too long.");
221             return $noreply;
222         }
223
224         &Forker("dict", sub { &Dict::Dict($query); } );
225
226         $cmdstats{'Dict'}++;
227         return $noreply;
228     }
229
230     # Freshmeat. xk++
231     if ($message =~ /^(fm|freshmeat)(\s+(.*))?$/i) {
232         return $noreply unless (&hasParam("freshmeat"));
233
234         my $query = $3;
235
236         if (!defined $query) {
237             &help("freshmeat");
238             &msg($who, "I have \002".&countKeys("freshmeat")."\002 entries.");
239             return $noreply;
240         }
241
242         &loadMyModule($myModules{'freshmeat'});
243         &Freshmeat::Freshmeat($query);
244
245         $cmdstats{'Freshmeat'}++;
246         return $noreply;
247     }
248
249     # google searching. Simon++
250     if (&IsParam("wwwsearch") and $message =~ /^(?:search\s+)?($W3Search_regex)\s+for\s+['"]?(.*?)['"]?\s*\?*$/i) {
251         return $noreply unless (&hasParam("wwwsearch"));
252
253         &Forker("wwwsearch", sub { &W3Search::W3Search($1,$2,$param{'wwwsearch'}); } );
254
255         $cmdstats{'WWWSearch'}++;
256         return $noreply;
257     }
258
259     # insult server. patch thanks to michael@limit.org
260     if ($message =~ /^insult(\s+(\S+))?$/) {
261         return $noreply unless (&hasParam("insult"));
262
263         my $person      = $2;
264         if (!defined $person) {
265             &help("insult");
266             return $noreply;
267         }
268
269         &Forker("insult", sub { &Insult::Insult($person); } );
270
271         return $noreply;
272     }
273
274     # Kernel. xk++
275     if ($message =~ /^kernel$/i) {
276         return $noreply unless (&hasParam("kernel"));
277
278         &Forker("kernel", sub { &Kernel::Kernel(); } );
279
280         $cmdstats{'Kernel'}++;
281         return $noreply;
282     }
283
284     # LART. originally by larne/cerb.
285     if ($message =~ /^lart(\s+(.*))?$/i) {
286         return $noreply unless (&hasParam("lart"));
287         my ($target) = &fixString($2);
288
289         if (!defined $target) {
290             &help("lart");
291             return $noreply;
292         }
293         my $extra = 0;
294
295         my $chan = $talkchannel;
296         if ($msgType eq 'private') {
297             if ($target =~ /^($mask{chan})\s+(.*)$/) {
298                 $chan   = $1;
299                 $target = $2;
300                 $extra  = 1;
301             } else {
302                 &msg($who, "error: invalid format or missing arguments.");
303                 &help("lart");
304                 return $noreply;
305             }
306         }
307
308         my $line = &getRandomLineFromFile($bot_misc_dir. "/blootbot.lart");
309         if (defined $line) {
310             if ($target =~ /^(me|you|itself|\Q$ident\E)$/i) {
311                 $line =~ s/WHO/$who/g;
312             } else {
313                 $line =~ s/WHO/$target/g;
314             }
315             $line .= ", courtesy of $who" if ($extra);
316
317             &action($chan, $line);
318         } else {
319             &status("lart: error reading file?");
320         }
321
322         return $noreply;
323     }
324
325     # Search factoid extensions by 'author'. xk++
326     if ($message =~ /^listauth(\s+(\S+))?$/i) {
327         return $noreply unless (&hasParam("search"));
328
329         my $query = $2;
330
331         if (!defined $query) {
332             &help("listauth");
333             return $noreply;
334         }
335
336         &loadMyModule($myModules{'factoids'});
337         &performStrictReply( &CmdListAuth($query) );
338         return $noreply;
339     }
340
341     # list{keys|values}. xk++. Idea taken from #linuxwarez@EFNET
342     if ($message =~ /^list(\S+)( (.*))?$/i) {
343         return $noreply unless (&hasParam("search"));
344
345         my $thiscmd     = lc($1);
346         my $args        = $3;
347
348         $thiscmd =~ s/^vals$/values/;
349         return $noreply if ($thiscmd ne "keys" && $thiscmd ne "values");
350
351         # Usage:
352         if (!defined $args) {
353             &help("list". $thiscmd);
354             return $noreply;
355         }
356
357         if (length $args == 1) {
358             &msg($who,"search string is too short.");
359             return $noreply;
360         }
361
362         ### chews up to 4megs => use forker :)
363         &Forker("search", sub { &Search::Search($thiscmd, $args); } );
364 #       &loadMyModule($myModules{'search'});
365 #       &Search::Search($thiscmd, $args);
366
367         $cmdstats{'Factoid Search'}++;
368         return $noreply;
369     }
370
371     # Nickometer. Adam Spiers++
372     if ($message =~ /^(?:lame|nick)ometer(?: for)? (\S+)/i) {
373         return $noreply unless (&hasParam("nickometer"));
374
375         my $term = (lc $1 eq 'me') ? $who : $1;
376         $term =~ s/\?+\s*//;
377
378         &loadMyModule($myModules{'nickometer'});
379         my $percentage = &nickometer($term);
380
381         if ($percentage =~ /NaN/) {
382             $percentage = "off the scale";
383         } else {
384             $percentage = sprintf("%0.4f", $percentage);
385             $percentage =~ s/\.?0+$//;
386             $percentage .= '%';
387         }
388
389         if ($msgType eq 'public') {
390             &say("'$term' is $percentage lame, $who");
391         } else {
392             &msg($who, "the 'lame nick-o-meter' reading for $term is $percentage, $who");
393         }
394
395         return $noreply;
396     }
397
398     # Quotes. mu++
399     if ($message =~ /^quote(\s+(\S+))?$/i) {
400         return $noreply unless (&hasParam("quote"));
401
402         my $query = $2;
403
404         if ($query eq "") {
405             &help("quote");
406             return $noreply;
407         }
408
409         &Forker("quote", sub { &Quote::Quote($query); } );
410
411         $cmdstats{'Quote'}++;
412         return $noreply;
413     }
414
415     # rootWarn. xk++
416     if ($message =~ /^rootWarn$/i) {
417         return $noreply unless (&hasParam("rootWarn"));
418
419         &loadMyModule($myModules{'rootwarn'});
420         &performStrictReply( &CmdrootWarn() );
421         return $noreply;
422     }
423
424     # seen.
425     if ($message =~ /^seen(\s+(\S+))?$/) {
426         return $noreply unless (&hasParam("seen"));
427
428         my $person = $2;
429         if (!defined $person) {
430             &help("seen");
431
432             my $i = &countKeys("seen");
433             &msg($who,"there ". &fixPlural("is",$i) ." \002$i\002 ".
434                 "seen ". &fixPlural("entry",$i) ." that I know of.");
435
436             return $noreply;
437         }
438
439         my @seen;
440         $person =~ s/\?*$//;
441
442         &seenFlush();   # very evil hack. oh well, better safe than sorry.
443
444         ### TODO: Support &dbGetRowInfo(); like in &FactInfo();
445         my $select = "nick,time,channel,host,message";
446         if ($person eq "random") {
447             @seen = &randKey("seen", $select);
448         } else {
449             @seen = &dbGet("seen", "nick", $person, $select);
450         }
451
452         if (scalar @seen < 2) {
453             foreach (@seen) {
454                 &DEBUG("seen: _ => '$_'.");
455             }
456             &performReply("i haven't seen '$person'");
457             return $noreply;
458         }
459
460         # valid seen.
461         my $reply;
462         ### TODO: multi channel support. may require &IsNick() to return
463         ###     all channels or something.
464         my @chans = &GetNickInChans($seen[0]);
465         if (scalar @chans) {
466             $reply = "$seen[0] is currently on";
467
468             foreach (@chans) {
469                 $reply .= " ".$_;
470                 next unless (exists $userstats{lc $seen[0]}{'Join'});
471                 $reply .= " (".&Time2String(time() - $userstats{lc $seen[0]}{'Join'}).")";
472             }
473
474             if (&IsParam("seenStats")) {
475                 my $i;
476                 $i = $userstats{lc $seen[0]}{'Count'};
477                 $reply .= ".  Has said a total of \002$i\002 messages" if (defined $i);
478                 $i = $userstats{lc $seen[0]}{'Time'};
479                 $reply .= ".  Is idling for ".&Time2String(time() - $i) if (defined $i);
480             }
481         } else {
482             my $howlong = &Time2String(time() - $seen[1]);
483             $reply = "$seen[0] <$seen[3]> was last seen on IRC ".
484                         "in channel $seen[2], $howlong ago, ".
485                         "saying\002:\002 '$seen[4]'.";
486         }
487
488         &performStrictReply($reply);
489         return $noreply;
490     }
491
492     # slashdot headlines: from Chris Tessone.
493     if ($message =~ /^slashdot$/i) {
494         return $noreply unless (&hasParam("slashdot"));
495
496         &Forker("slashdot", sub { &Slashdot::Slashdot() });
497
498         $cmdstats{'Slashdot'}++;
499         return $noreply;
500     }
501
502     # Topic management. xk++
503     # may want to add a flag(??) for topic in the near future. -xk
504     if ($message =~ /^topic(\s+(.*))?$/i) {
505         return $noreply unless (&hasParam("topic"));
506
507         my $chan        = $talkchannel;
508         my @args        = split(/ /, $2);
509
510         if (!scalar @args) {
511             &msg($who,"Try 'help topic'");
512             return $noreply;
513         }
514
515         $chan           = lc(shift @args) if ($msgType eq 'private');
516         my $thiscmd     = shift @args;
517
518         # topic over public:
519         if ($msgType eq 'public' && $thiscmd =~ /^#/) {
520             &msg($who, "error: channel argument is not required.");
521             &msg($who, "\002Usage\002: topic <CMD>");
522             return $noreply;
523         }
524
525         # topic over private:
526         if ($msgType eq 'private' && $chan !~ /^#/) {
527             &msg($who, "error: channel argument is required.");
528             &msg($who, "\002Usage\002: topic #channel <CMD>");
529             return $noreply;
530         }
531
532         if (&validChan($chan) == 0) {
533             &msg($who,"error: invalid channel \002$chan\002");
534             return $noreply;
535         }
536
537         # for semi-outsiders.
538         if (!&IsNickInChan($who,$chan)) {
539             &msg($who, "Failed. You ($who) are not in $chan, hey?");
540             return $noreply;
541         }
542
543         # now lets do it.
544         &loadMyModule($myModules{'topic'});
545         &Topic($chan, $thiscmd, join(' ', @args));
546         $cmdstats{'Topic'}++;
547         return $noreply;
548     }
549
550     # Countdown.
551     if ($message =~ /^countdown(\s+(\S+))?$/i) {
552         return $noreply unless (&hasParam("countdown"));
553
554         my $query = $2;
555
556         &loadMyModule($myModules{'countdown'});
557         &Countdown($query);
558
559         $cmdstats{'Countdown'}++;
560
561         return $noreply;
562     }
563
564     # User Information Services. requested by Flugh.
565     if ($message =~ /^u(ser)?info(\s+(.*))?$/i) {
566         return $noreply unless (&hasParam("userinfo"));
567         &loadMyModule($myModules{'userinfo'});
568
569         my $arg = $3;
570         if (!defined $arg or $arg eq "") {
571             &help("userinfo");
572             return $noreply;
573         }
574
575         if ($arg =~ /^set(\s+(.*))?$/i) {
576             $arg = $2;
577             if (!defined $arg) {
578                 &help("userinfo set");
579                 return $noreply;
580             }
581
582             &UserInfoSet(split /\s+/, $arg, 2);
583         } elsif ($arg =~ /^unset(\s+(.*))?$/i) {
584             $arg = $2;
585             if (!defined $arg) {
586                 &help("userinfo unset");
587                 return $noreply;
588             }
589
590             &UserInfoSet($arg, "");
591         } else {
592             &UserInfoGet($arg);
593         }
594
595         $cmdstats{'UIS'}++;
596         return $noreply;
597     }
598
599     # Uptime. xk++
600     if ($message =~ /^uptime$/i) {
601         return $noreply unless (&hasParam("uptime"));
602
603         my $count = 1;
604         &msg($who, "- Uptime for $ident -");
605         &msg($who, "Now: ". &Time2String(&uptimeNow()) ." running $bot_version");
606         foreach (&uptimeGetInfo()) {
607             /^(\d+)\.\d+ (.*)/;
608             my $time = &Time2String($1);
609             my $info = $2;
610
611             &msg($who, "$count: $time $2");
612             $count++;
613         }
614
615         $cmdstats{'Uptime'}++;
616         return $noreply;
617     }
618
619     # wingate.
620     if ($message =~ /^wingate$/i) {
621         return $noreply unless (&hasParam("wingate"));
622
623         my $reply = "Wingate statistics: scanned \002"
624                         .scalar(keys %wingate)."\002 hosts";
625         my $queue = scalar(keys %wingateToDo);
626         if ($queue) {
627             $reply .= ".  I have \002$queue\002 hosts in the queue";
628             $reply .= ".  Started the scan ".&Time2String(time() - $wingaterun)." ago";
629         }
630
631         &performStrictReply("$reply.");
632
633         return $noreply;
634     }
635
636     # convert.
637     if ($message =~ /^convert(\s+(.*))?$/i) {
638         return $noreply unless (&hasParam("units"));
639
640         my $str = $2;
641         if (!defined $str) {
642             &help("convert");
643             return $noreply;
644         }
645
646         my ($from,$to);
647         ($from,$to) = ($1,$2) if ($str =~ /^(.*) to (.*)$/);
648         ($from,$to) = ($2,$1) if ($str =~ /^(.*) from (.*)$/);
649         if (!defined $from or !defined $to or $to eq "" or $from eq "") {
650             &msg($who, "Invalid format!");
651             &help("convert");
652             return $noreply;
653         }
654
655         &Forker("units", sub { &Units::convertUnits($from, $to); } );
656
657         return $noreply;
658     }
659
660     # do nothing and let the other routines have a go
661     return '';
662 }
663
664 1;