if (&IsParam("useStrict")) { use strict; }
-$babel::lang_regex = ""; # lame fix.
+$babel_lang_regex = "fr|sp|po|pt|it|ge|de|gr|en";
-### PROPOSED COMMAND HOOK IMPLEMENTATION.
+### COMMAND HOOK IMPLEMENTATION.
# addCmdHook("SECTION", 'TEXT_HOOK',
# (CODEREF => 'Blah',
# Forker => 1,
sub parseCmdHook {
my ($hashname, $line) = @_;
$line =~ /^(\S+)( (.*))?$/;
- my @args = split(' ', $3 || '');
- my $flatarg = $3;
my $cmd = $1; # command name is whitespaceless.
+ my $flatarg = $3;
+ my @args = split(/\s+/, $flatarg || '');
my $done = 0;
&shmFlush();
next;
}
- &DEBUG("pCH(hooks_$hashname): $cmd matched $ident");
+ &status("hooks($hashname): $cmd matched '$ident'");
my %hash = %{ ${"hooks_$hashname"}{$ident} };
if (!scalar keys %hash) {
return 1;
}
+ if ($hash{NoArgs} and $flatarg) {
+ &DEBUG("cmd $ident does not take args; skipping.");
+ next;
+ }
+
if (!exists $hash{CODEREF}) {
&ERROR("CODEREF undefined for $cmd or $ident.");
return 1;
### DEBUG.
foreach (keys %hash) {
- &DEBUG(" $cmd->$_ => '$hash{$_}'.");
+ &VERB(" $cmd->$_ => '$hash{$_}'.",2);
}
### HELP.
### IDENTIFIER.
if (exists $hash{'Identifier'}) {
- return unless (&hasParam($hash{'Identifier'}));
+ return 1 unless (&hasParam($hash{'Identifier'}));
}
### USER FLAGS.
if (exists $hash{'UserFlag'}) {
- return unless (&hasFlag($hash{'UserFlag'}));
+ return 1 unless (&hasFlag($hash{'UserFlag'}));
}
### FORKER,IDENTIFIER,CODEREF.
if (exists $hash{'Forker'}) {
$hash{'Identifier'} .= "-" if ($hash{'Forker'} eq "NULL");
- ### FLAT_ARG / ARRAY option.
+ if (exists $hash{'ArrayArgs'}) {
+ &Forker($hash{'Identifier'}, sub { \&{$hash{'CODEREF'}}(@args) } );
+ } else {
+ &Forker($hash{'Identifier'}, sub { \&{$hash{'CODEREF'}}($flatarg) } );
+ }
- &Forker($hash{'Identifier'}, sub { \&{$hash{'CODEREF'}}(@args) } );
} else {
if (exists $hash{'Module'}) {
&loadMyModule($myModules{ $hash{'Module'} });
}
- ### TODO: check if CODEREF exists.
+ # check if CODEREF exists.
+ if (!defined &{ $hash{'CODEREF'} }) {
+ &WARN("coderef $hash{'CODEREF'} don't exist.");
+ return 1;
+ }
- if (exists $hash{'FlatArg'} and $hash{'FlatArg'} == 0) {
- &status("CmdHook: using args as array.");
+ if (exists $hash{'ArrayArgs'}) {
&{$hash{'CODEREF'}}(@args);
} else {
&{$hash{'CODEREF'}}($flatarg);
$cmdstats{ $hash{'Cmdstats'} }++;
}
- &DEBUG("pCH: ended.");
+ &VERB("hooks: End of command.",2);
$done = 1;
}
&addCmdHook("extra", 'dauthor', ('CODEREF' => 'Debian::searchAuthor',
'Forker' => 1, 'Identifier' => 'debian',
'Cmdstats' => 'Debian Author Search', 'Help' => "dauthor" ) );
-&addCmdHook("extra", '(d|search)desc', ('CODEREF' => 'Debian::searchDesc',
+&addCmdHook("extra", '(d|search)desc', ('CODEREF' => 'Debian::searchDescFE',
'Forker' => 1, 'Identifier' => 'debian',
'Cmdstats' => 'Debian Desc Search', 'Help' => "ddesc" ) );
&addCmdHook("extra", 'dnew', ('CODEREF' => 'DebianNew',
'Forker' => 1, 'Identifier' => 'insult', 'Help' => "insult" ) );
&addCmdHook("extra", 'kernel', ('CODEREF' => 'Kernel::Kernel',
'Forker' => 1, 'Identifier' => 'kernel',
- 'Cmdstats' => 'Kernel') );
+ 'Cmdstats' => 'Kernel', 'NoArgs' => 1) );
&addCmdHook("extra", 'listauth', ('CODEREF' => 'CmdListAuth',
'Identifier' => 'search', Module => 'factoids',
'Help' => 'listauth') );
&addCmdHook("extra", 'uptime', ('CODEREF' => 'uptime', 'Identifier' => 'uptime',
'Cmdstats' => 'Uptime') );
&addCmdHook("extra", 'nullski', ('CODEREF' => 'nullski', ) );
- sub nullski { my ($arg) = @_; foreach (`$arg`) { &msg($who,$_); } }
&addCmdHook("extra", '(fm|freshmeat)', ('CODEREF' => 'Freshmeat::Freshmeat',
'Identifier' => 'freshmeat', 'Cmdstats' => 'Freshmeat',
'Forker' => 1, 'Help' => 'freshmeat') );
}
# babel bot: Jonathan Feinberg++
- if (&IsParam("babelfish") and $message =~ m{
+ if (&IsChanConf("babelfish") and $message =~ m{
^\s*
(?:babel(?:fish)?|x|xlate|translate)
\s+
(to|from) # direction of translation (through)
\s+
- ($babel::lang_regex)\w* # which language?
+ ($babel_lang_regex)\w* # which language?
\s*
(.+) # The phrase to be translated
}xoi) {
return;
}
- if (&IsParam("debian")) {
+ if (&IsChanConf("debian")) {
my $debiancmd = 'conflicts?|depends?|desc|file|info|provides?';
$debiancmd .= '|recommends?|suggests?|maint|maintainer';
if ($message =~ /^($debiancmd)(\s+(.*))?$/i) {
}
# google searching. Simon++
- if (&IsParam("wwwsearch") and $message =~ /^(?:search\s+)?(\S+)\s+for\s+['"]?(.*?)['"]?\s*\?*$/i) {
+ if (&IsChanConf("wwwsearch") and $message =~ /^(?:search\s+)?(\S+)\s+for\s+['"]?(.*?)['"]?\s*\?*$/i) {
return unless (&hasParam("wwwsearch"));
&Forker("wwwsearch", sub { &W3Search::W3Search($1,$2); } );
my $thiscmd = lc($1);
my $args = $3;
+ $args =~ s/\s+$//g;
+ # suggested by asuffield nad \broken.
+ if ($args =~ /^["']/ and $args =~ /["']$/) {
+ &DEBUG("list*: removed quotes.");
+ $args =~ s/^["']|["']$//g;
+ }
$thiscmd =~ s/^vals$/values/;
return if ($thiscmd ne "keys" && $thiscmd ne "values");
# step 1.
my %nickometer;
foreach (keys %{ $channels{lc $term}{''} }) {
- my $value = &nickometer($_);
-
- if (!defined $value) {
- &WARN("nickometer: value is undefined.");
+ my $str = $_;
+ if (!defined $str) {
+ &WARN("nickometer: nick in chan $term undefined?");
next;
}
- &DEBUG("value => $value.");
- $nickometer{$value}{$_} = 1;
+ my $value = &nickometer($str);
+ $nickometer{$value}{$str} = 1;
}
# step 2.
### TODO: compact with map?
my @list;
- foreach (sort {$a <=> $b} keys %nickometer) {
+ foreach (sort {$b <=> $a} keys %nickometer) {
my $str = join(", ", sort keys %{$nickometer{$_}});
- push(@list, "$str ($_ %)");
+ push(@list, "$str ($_%)");
}
&pSReply( &formListReply(0, "Nickometer list for $term ", @list) );
return unless (&hasParam("topic"));
my $chan = $talkchannel;
- my @args = split(/ /, $2);
+ my @args = split / /, $2 || "";
if (!scalar @args) {
&msg($who,"Try 'help topic'");
}
if (!&validChan($chan)) {
- &pSReply("chan $chan is invalid.");
+ &msg($who, "chan $chan is invalid.");
return;
}
- if (scalar keys %ver or scalar @vernick) {
- &DEBUG("verstats already in progress.");
+ if (scalar @vernick > scalar(keys %{ $channels{lc $chan}{''} })/4) {
+ &msg($who, "verstats already in progress for someone else.");
return;
}
&msg($who, "Sending CTCP VERSION...");
$conn->ctcp("VERSION", $chan);
+ $cache{verstats}{chan} = $chan;
+ $cache{verstats}{who} = $who;
+ $cache{verstats}{msgType} = $msgType;
+
$conn->schedule(60, sub {
my $vtotal = 0;
- my $total = keys %{ $channels{lc $chan}{''} };
+ my $c = lc $cache{verstats}{chan};
+ my $total = keys %{ $channels{$c}{''} };
+ $chan = $c;
+ $who = $cache{verstats}{who};
+ $msgType = $cache{verstats}{msgType};
+ delete $cache{verstats}; # sufficient?
foreach (keys %ver) {
$vtotal += scalar keys %{ $ver{$_} };
my %sorted;
my $unknown = $total - $vtotal;
my $perc = sprintf("%.1f", $unknown * 100 / $total);
- $sorted{$perc} = "unknown/cloak - $unknown ($perc %)";
$perc =~ s/.0$//;
+ $sorted{$perc}{"unknown/cloak"} = "$unknown ($perc%)";
foreach (keys %ver) {
my $count = scalar keys %{ $ver{$_} };
$perc = sprintf("%.01f", $count * 100 / $total);
$perc =~ s/.0$//; # lame compression.
- if (exists $sorted{$perc}) {
- &WARN("sorted{$perc} already exists; FIXME.");
- }
-
- $sorted{$perc} = "$_ - $count ($perc %)";
+ $sorted{$perc}{$_} = "$count ($perc%)";
}
### can be compressed to a map?
my @list;
- foreach ( sort { $a <=> $b } keys %sorted ) {
- push(@list, $sorted{$_});
+ foreach ( sort { $b <=> $a } keys %sorted ) {
+ my $perc = $_;
+ foreach (sort keys %{ $sorted{$perc} }) {
+ push(@list, "$_ - $sorted{$perc}{$_}");
+ }
}
- &pSReply( &formListReply(0, "IRC Client versions for $chan ", @list) );
+ &pSReply( &formListReply(0, "IRC Client versions for $c ", @list) );
# clean up not-needed data structures.
undef %ver;
return;
}
+sub nullski { my ($arg) = @_; return unless (defined $arg);
+ foreach (`$arg`) { &msg($who,$_); } }
+
1;