X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=src%2FModules%2FNews.pl;h=e9a1ef29ac6ffaef59a34cfff26a49741de59a19;hb=02dd5778cf86851ed8158551400149133843516a;hp=ee223621fd116ea7c32fa4714fde4cc67e7db6f4;hpb=ff1e8c763cb99edae62d7d63ddb32963c076e04e;p=infobot.git diff --git a/src/Modules/News.pl b/src/Modules/News.pl index ee22362..e9a1ef2 100644 --- a/src/Modules/News.pl +++ b/src/Modules/News.pl @@ -15,15 +15,18 @@ # Text - Actual text. ### +use vars qw($who); + package News; sub Parse { my($what) = @_; $chan = undef; + $who = lc $::who; if (!keys %::news) { if (!exists $::cache{newsFirst}) { - &::DEBUG("looks like we enabled news option just then; loading up news file just in case."); + &::DEBUG("news: looks like we enabled news option just then; loading up news file just in case."); $::cache{newsFirst} = 1; } @@ -36,16 +39,16 @@ sub Parse { if (defined $what and $what =~ s/^($::mask{chan})\s*//) { # todo: check if the channel exists aswell. - $chan = $1; + $chan = lc $1; - if (!&::IsNickInChan($::who, $chan)) { + if (!&::IsNickInChan($who, $chan)) { &::notice($::who, "sorry but you're not on $chan."); return; } } if (!defined $chan) { - my @chans = &::GetNickInChans($::who); + my @chans = &::getNickInChans($::who); if (scalar @chans > 1) { &::notice($::who, "error: I dunno which channel you are referring to since you're on more than one. Try 'news #chan ...' instead"); @@ -58,7 +61,7 @@ sub Parse { } $chan = $chans[0]; - &::DEBUG("Guessed $::who being on chan $chan"); + &::DEBUG("Guessed $::who being on chan $chan",2); $::chan = $chan; # hack for IsChanConf(). } @@ -80,7 +83,7 @@ sub Parse { &set($2); } elsif ($what =~ /^(\d+)$/i) { - &::DEBUG("read shortcut called."); + &::VERB("News: read shortcut called.",2); &read($1); } elsif ($what =~ /^read(\s+(.*))?$/i) { @@ -88,9 +91,12 @@ sub Parse { } elsif ($what =~ /^(latest|new)(\s+(.*))?$/i) { &latest($3 || $chan, 1); +# $::cmdstats{'News latest'}++; + + } elsif ($what =~ /^stats?$/i) { + &stats(); } elsif ($what =~ /^list$/i) { - &::DEBUG("list longcut called."); &list(); } elsif ($what =~ /^(expire|text|desc)(\s+(.*))?$/i) { @@ -102,44 +108,48 @@ sub Parse { } elsif ($what =~ /^help(\s+(.*))?$/i) { &::help("news$1"); + } elsif ($what =~ /^newsflush$/i) { + &::msg($::who, "newsflush called... check out the logs!"); + &::newsFlush(); + } elsif ($what =~ /^(un)?notify$/i) { my $state = ($1) ? 0 : 1; # todo: don't notify even if "news" is called. if (!&::IsChanConf("newsNotifyAll")) { - &::DEBUG("chan => $chan, ::chan => $::chan."); + &::DEBUG("news: chan => $chan, ::chan => $::chan."); &::notice($::who, "not available for this channel or disabled altogether."); return; } - my $t = $::newsuser{$chan}{$::who}; + my $t = $::newsuser{$chan}{$who}; if ($state) { # state = 1 if (defined $t and ($t == 0 or $t == -1)) { &::notice($::who, "enabled notify."); - delete $::newsuser{$chan}{$::who}; + delete $::newsuser{$chan}{$who}; return; } &::notice($::who, "already enabled."); } else { # state = 0 - my $x = $::newsuser{$chan}{$::who}; + my $x = $::newsuser{$chan}{$who}; if (defined $x and ($x == 0 or $x == -1)) { &::notice($::who, "notify already disabled"); return; } - $::newsuser{$chan}{$::who} = -1; + $::newsuser{$chan}{$who} = -1; &::notice($::who, "notify is now disabled."); } } else { - &::DEBUG("could not parse '$what'."); + &::DEBUG("news: could not parse '$what'"); &::notice($::who, "unknown command: $what"); } } sub readNews { my $file = "$::bot_base_dir/blootbot-news.txt"; - if (! -f $file) { + if (! -f $file or -z $file) { return; } @@ -159,7 +169,7 @@ sub readNews { if (/^[\s\t]+(\S+):[\s\t]+(.*)$/) { if (!defined $item) { - &::DEBUG("!defined item, never happen!"); + &::DEBUG("news: !defined item, never happen!"); next; } @@ -182,13 +192,17 @@ sub readNews { } close NEWS; - &::status("News: Read $ci items for ".scalar(keys %::news) - ." chans, $cu users cache"); + my $cn = scalar(keys %::news); + &::status("News: Read ". + $ci. &::fixPlural(" item", $ci). " for ". + $cn. &::fixPlural(" chan", $cn). ", ". + $cu. &::fixPlural(" user", $cu), " cache" + ) if ($ci or $cn or $cu); } sub writeNews { - if (!scalar keys %::news) { - &::DEBUG("wN: nothing to write."); + if (!scalar keys %::news and !scalar keys %::newsuser) { + &::VERB("wN: nothing to write.",2); return; } @@ -322,7 +336,7 @@ sub del { } $what = $found[0]; - &::DEBUG("del: str: guessed what => $what"); + &::DEBUG("news: del: str: guessed what => $what"); } } @@ -351,25 +365,30 @@ sub list { } if (&::IsChanConf("newsKeepRead")) { - my $x = $::newsuser{$chan}{$::who}; + my $x = $::newsuser{$chan}{$who}; if (defined $x and ($x == 0 or $x == -1)) { - &::DEBUG("not updating time for $::who."); + &::DEBUG("news: not updating time for $::who."); } else { - $::newsuser{$chan}{$::who} = time(); + if (!scalar keys %{ $::news{$chan} }) { + &::DEBUG("news: should not add $chan/$::who to cache!"); + } + + $::newsuser{$chan}{$who} = time(); } } + # ¬ice() breaks OPN :( - using msg() instead! my $count = scalar keys %{ $::news{$chan} }; - &::notice($::who, "|==== News for \002$chan\002: ($count items)"); + &::msg($::who, "|==== News for \002$chan\002: ($count items)"); my $newest = 0; foreach (keys %{ $::news{$chan} }) { my $t = $::news{$chan}{$_}{Time}; $newest = $t if ($t > $newest); } my $timestr = &::Time2String(time() - $newest); - &::notice($::who, "|= Last updated $timestr ago."); - &::notice($::who, " \037Num\037 \037Item ".(" "x40)." \037"); + &::msg($::who, "|= Last updated $timestr ago."); + &::msg($::who, " \037Num\037 \037Item ".(" "x40)." \037"); my $i = 1; foreach ( &getNewsAll() ) { @@ -377,18 +396,18 @@ sub list { my $setby = $::news{$chan}{$subtopic}{Author}; if (!defined $subtopic) { - &::DEBUG("warn: subtopic == undef."); + &::DEBUG("news: warn: subtopic == undef."); next; } # todo: show request stats aswell. - &::notice($::who, sprintf("\002[\002%2d\002]\002 %s", + &::msg($::who, sprintf("\002[\002%2d\002]\002 %s", $i, $subtopic)); $i++; } - &::notice($::who, "|= End of News."); - &::notice($::who, "use 'news read <#>' or 'news read '"); + &::msg($::who, "|= End of News."); + &::msg($::who, "use 'news read <#>' or 'news read '"); } sub read { @@ -423,20 +442,30 @@ sub read { my $rcount = $::news{$chan}{$item}{Request_Count} || 0; if (length $text < $::param{maxKeySize}) { - &::DEBUG("NEWS: Possible news->factoid redirection."); + &::VERB("NEWS: Possible news->factoid redirection.",2); my $f = &::getFactoid($text); if (defined $f) { - &::DEBUG("NEWS: ok, $text is factoid redirection."); + &::VERB("NEWS: ok, $text is factoid redirection.",2); $f =~ s/^\s*//i; # anything else? $text = $f; } } - &::notice($::who, "+- News \002$chan\002 #$num: \037$item\037"); - &::notice($::who, "| Added by $a at $t"); - &::notice($::who, "| Requested $rcount times, last by $rwho") if ($rcount); + $_ = $::news{$chan}{$item}{'Expire'}; + my $e; + if ($_) { + $e = sprintf("\037%s\037 [%s from now]", + scalar(localtime($_)), + &::Time2String($_ - time()) + ); + } + + &::notice($::who, "+- News \002$chan\002 #$num: $item"); + &::notice($::who, "| Added by $a at \037$t\037"); + &::notice($::who, "| Expire: $e") if (defined $e); &::notice($::who, $text); + &::notice($::who, "| Requested \002$rcount\002 times, last by \002$rwho\002") if ($rcount and $rwho); $::news{$chan}{$item}{'Request_By'} = $::who; $::news{$chan}{$item}{'Request_Time'} = time(); @@ -454,7 +483,7 @@ sub mod { my $news = &getNewsItem($item); if (!defined $news) { - &::DEBUG("error: mod: news == undefined."); + &::DEBUG("news: error: mod: news == undefined."); return; } my $nnews = $::news{$chan}{$news}{Text}; @@ -525,16 +554,15 @@ sub set { $args =~ /^(\S+)\s+(\S+)\s+(.*)$/; my($item, $what, $value) = ($1,$2,$3); - &::DEBUG("set called."); + &::DEBUG("news: set called."); if ($item eq "") { &::help("news set"); return; } - &::DEBUG("item => '$item'."); + &::DEBUG("news: set: item => '$item'."); my $news = &getNewsItem($item); - &::DEBUG("news => '$news'"); if (!defined $news) { &::notice($::who, "Could not find item '$item' substring or # in news list."); @@ -543,7 +571,7 @@ sub set { # list all values for chan. if (!defined $what) { - &::DEBUG("set: 1"); + &::DEBUG("news: set: 1"); return; } @@ -563,7 +591,7 @@ sub set { # show (read) what. if (!defined $value) { - &::DEBUG("set: 2"); + &::DEBUG("news: set: 2"); return; } @@ -599,21 +627,21 @@ sub set { } if (!$time or ($value and $value !~ /^never$/i)) { - &::DEBUG("set: Expire... need to parse."); + &::DEBUG("news: set: Expire... need to parse."); return; } if ($time == -1) { &::notice($::who, "Set never expire for \002$item\002." ); } elsif ($time < -1) { - &::DEBUG("time should never be negative ($time)."); + &::DEBUG("news: time should never be negative ($time)."); return; } else { &::notice($::who, "Set expire for \002$item\002, to ". localtime($time) ." [".&::Time2String($time - time())."]" ); if (time() > $time) { - &::DEBUG("hrm... time() > $time, should expire."); + &::DEBUG("news: hrm... time() > $time, should expire."); } } @@ -624,12 +652,12 @@ sub set { } my $auth = 0; - &::DEBUG("who => '$::who'"); + &::DEBUG("news: who => '$::who'"); my $author = $::news{$chan}{$news}{Author}; $auth++ if ($::who eq $author); $auth++ if (&::IsFlag("o")); if (!defined $author) { - &::DEBUG("news{$chan}{$news}{Author} is not defined! auth'd anyway"); + &::DEBUG("news: news{$chan}{$news}{Author} is not defined! auth'd anyway"); $::news{$chan}{$news}{Author} = $::who; $author = $::who; $auth++; @@ -644,7 +672,7 @@ sub set { # todo: clean this up. my $old = $::news{$chan}{$news}{$what}; if (defined $old) { - &::DEBUG("old => $old."); + &::DEBUG("news: old => $old."); } $::news{$chan}{$news}{$what} = $value; &::notice($::who, "Setting [$chan]/{$news}/<$what> to '$value'."); @@ -653,33 +681,37 @@ sub set { sub latest { my($tchan, $flag) = @_; - $chan ||= $tchan; # hack hack hack. + # hack hack hack. + $chan ||= $tchan; + $who ||= $::who; # todo: if chan = undefined, guess. - if (!exists $::news{$chan}) { - &::notice($::who, "invalid chan $chan"); +# if (!exists $::news{$chan}) { + if (!exists $::channels{$chan}) { + &::notice($::who, "invalid chan $chan") if ($flag); return; } - my $t = $::newsuser{$chan}{$::who}; + my $t = $::newsuser{$chan}{$who}; if (defined $t and ($t == 0 or $t == -1)) { if ($flag) { &::notice($::who, "if you want to read news, try /msg $::ident news or /msg $::ident news notify"); } else { - &::DEBUG("not displaying any new news for $::who"); + &::DEBUG("news: not displaying any new news for $::who"); return; } } + $::chan = $chan; my $x = &::IsChanConf("newsNotifyAll"); if (&::IsChanConf("newsNotifyAll") and !defined $t) { $t = 1; } if (!defined $t) { - &::DEBUG("something went really wrong."); - &::DEBUG("chan => $chan, ::chan => $::chan"); - &::notice($::who, "something went really wrong."); + &::DEBUG("news: something went really wrong."); + &::DEBUG("news: chan => $chan, ::chan => $::chan"); +# &::notice($::who, "something went really wrong."); return; } @@ -688,6 +720,16 @@ sub latest { next if (!defined $t); next if ($t > $::news{$chan}{$_}{Time}); + # don't list new items if they don't have Text. + if (!exists $::news{$chan}{$_}{Text}) { + if (time() - $::news{$chan}{$_}{Time} > 60*60*24*3) { + &::DEBUG("deleting news{$chan}{$_} because it was too old and had no text info."); + delete $::news{$chan}{$_}; + } + + next; + } + push(@new, $_); } @@ -703,7 +745,7 @@ sub latest { if (!$flag) { return unless ($unread); - my $reply = "There are unread news in $chan ($unread unread, $total total). /msg $::ident news latest."; + my $reply = "There are unread news in $chan ($unread unread, $total total). /msg $::ident news $::chan latest"; $reply .= " If you don't want further news notification, /msg $::ident news unnotify" if ($unread == $total); &::notice($::who, $reply); @@ -714,7 +756,7 @@ sub latest { if (scalar @new) { &::notice($::who, "+==== New news for \002$chan\002 ($unread new; $total total):"); - my $t = $::newsuser{$chan}{$::who}; + my $t = $::newsuser{$chan}{$who}; if (defined $t and $t > 1) { my $timestr = &::Time2String( time() - $t ); &::notice($::who, "|= Last time read $timestr ago"); @@ -739,11 +781,11 @@ sub latest { &::notice($::who, "|= to read, do 'news read <#>' or 'news read '"); # lame hack to prevent dupes if we just ignore it. - my $x = $::newsuser{$chan}{$::who}; + my $x = $::newsuser{$chan}{$who}; if (defined $x and ($x == 0 or $x == -1)) { - &::DEBUG("not updating time for $::who. (2)"); + &::DEBUG("news: not updating time for $::who. (2)"); } else { - $::newsuser{$chan}{$::who} = time(); + $::newsuser{$chan}{$who} = time(); } } } @@ -777,7 +819,7 @@ sub newsS2N { my $t = $::news{$chan}{$_}{Time}; if (!defined $t or $t !~ /^\d+$/) { - &::DEBUG("warn: t is undefined for news{$chan}{$_}{Time}; removing item."); + &::DEBUG("news: warn: t is undefined for news{$chan}{$_}{Time}; removing item."); delete $::news{$chan}{$_}; next; } @@ -802,7 +844,7 @@ sub getNewsItem { my $t = $::news{$chan}{$_}{Time}; if (!defined $t or $t !~ /^\d+$/) { - &::DEBUG("warn: t is undefined for news{$chan}{$_}{Time}; removing item."); + &::DEBUG("news: warn: t is undefined for news{$chan}{$_}{Time}; removing item."); delete $::news{$chan}{$_}; next; } @@ -835,22 +877,21 @@ sub getNewsItem { } if (defined $no and !@items) { - &::DEBUG("string->number resolution: $what->$no."); + &::DEBUG("news: string->number resolution: $what->$no."); return $no; } if (scalar @items > 1) { - &::DEBUG("Multiple matches, not guessing."); + &::DEBUG("news: Multiple matches, not guessing."); &::notice($::who, "Multiple matches, not guessing."); return; } - &::DEBUG("gNI: part_string->full_string: $what->$items[0]"); if (@items) { - &::DEBUG("gNI: Guessed '$items[0]'."); + &::DEBUG("news: gNI: part_string->full_string: $what->$items[0]"); return $items[0]; } else { - &::DEBUG("gNI: No match."); + &::DEBUG("news: gNI: No match for '$what'"); return; } } @@ -863,20 +904,55 @@ sub do_set { my($what,$value) = @_; if (!defined $chan) { - &::DEBUG("do_set: chan not defined."); + &::DEBUG("news: do_set: chan not defined."); return; } if (!defined $what or $what =~ /^\s*$/) { - &::DEBUG("what $what is not defined."); + &::DEBUG("news: what $what is not defined."); return; } + if (!defined $value or $value =~ /^\s*$/) { - &::DEBUG("value $value is not defined."); + &::DEBUG("news: value $value is not defined."); return; } - &::DEBUG("do_set: TODO..."); + &::DEBUG("news: do_set: TODO..."); +} + +sub stats { + &::DEBUG("News: stats called."); + &::msg($::who, "check my logs/console."); + my($i,$j) = (0,0); + + # total request count. + foreach $chan (keys %::news) { + foreach (keys %{ $::news{$chan} }) { + $i += $::news{$chan}{$_}{Request_Count}; + } + } + &::DEBUG("news: stats: total request count => $i"); + $i = 0; + + # total user cached. + foreach $chan (keys %::newsuser) { + $i += $::newsuser{$chan}{$_}; + } + &::DEBUG("news: stats: total user cache => $i"); + $i = 0; + + # average latest time read. + my $t = time(); + foreach $chan (keys %::newsuser) { + $i += $t - $::newsuser{$chan}{$_}; + &DEBUG(" i = $i"); + $j++; + } + &::DEBUG("news: stats: average latest time read: total time: $i"); + &::DEBUG("news: ... count: $j"); + &::DEBUG("news: average: ".sprintf("%.02f", $i/($j||1))." sec/user"); + $i = $j = 0; } 1;