]> git.donarmstrong.com Git - infobot.git/blobdiff - src/Modules/News.pl
A round of fixes:
[infobot.git] / src / Modules / News.pl
index c21799aa363bce36347936d41adf1eea397c1142..b9cd1beb9f947a9caf3f511637343549177d5c0d 100644 (file)
@@ -11,7 +11,7 @@
 ### where items is:
 #      Time    - when it was added (used for sorting)
 #      Author  - Who by.
-#      Expire  - Time to expire
+#      Expire  - Time to expire.
 #      Text    - Actual text.
 ###
 
@@ -21,15 +21,25 @@ sub Parse {
     my($what)  = @_;
     $chan      = undef;
 
-    if ($::msgType eq "private") {
-       # todo: check if the channel exists aswell.
-       if (defined $what and $what =~ s/^($::mask{chan})\s*//) {
-           $chan = $1;
+    if (!keys %::news) {
+       if (!exists $cache{newsFirst}) {
+           &::DEBUG("looks like we enabled news option just then; loading up news file just in case.");
+           $cache{newsFirst} = 1;
        }
+
+       &readNews();
+    }
+
+    if ($::msgType eq "private") {
     } else {
        $chan = $::chan;
     }
 
+    if (defined $what and $what =~ s/^($::mask{chan})\s*//) {
+       # todo: check if the channel exists aswell.
+       $chan = $1;
+    }
+
     if (!defined $chan) {
        my @chans = &::GetNickInChans($::who);
 
@@ -65,6 +75,9 @@ sub Parse {
        &read($1);
     } elsif ($what =~ /^read(\s+(.*))?$/i) {
        &read($2);
+    } elsif ($what =~ /^(latest|new)(\s+(.*))?$/i) {
+       &::DEBUG("latest called... hrm");
+       &latest($3 || $chan, 1);
     } elsif ($what =~ /^list$/i) {
        &::DEBUG("list longcut called.");
        &list();
@@ -72,7 +85,7 @@ sub Parse {
        # shortcut/link.
        # nice hack.
        my($arg1,$arg2) = split(/\s+/, $3, 2);
-       &set("$arg1 Text $arg2");
+       &set("$arg1 $1 $arg2");
     } elsif ($what =~ /^help(\s+(.*))?$/i) {
        &::help("news$1");
     } else {
@@ -130,6 +143,11 @@ sub readNews {
 }
 
 sub writeNews {
+    if (!scalar keys %::news) {
+       &::DEBUG("wN: nothing to write.");
+       return;
+    }
+
     my $file = "$::bot_base_dir/blootbot-news.txt";
 
     if (fileno NEWS) {
@@ -140,6 +158,7 @@ sub writeNews {
     # todo: add commands to output file.
     my $c = 0;
     my($cc,$ci,$cu) = (0,0,0);
+
     open(NEWS, ">$file");
     foreach $chan (sort keys %::news) {
        $c = scalar keys %{ $::news{$chan} };
@@ -163,11 +182,10 @@ sub writeNews {
     if (&::getChanConfList("newsKeepRead")) {
        # old users are removed in newsFlush(), perhaps it should be
        # done here.
-       &::DEBUG("newsuser cache...");
+
        foreach $chan (sort keys %::newsuser) {
-           &::DEBUG("newsuser cache: chan => $chan");
+
            foreach (sort keys %{ $::newsuser{$chan} }) {
-               &::DEBUG("newsuser cache: user => $_");
                print NEWS "U $chan $_ $::newsuser{$chan}{$_}\n";
                $cu++;
            }
@@ -203,13 +221,15 @@ sub add {
     $::news{$chan}{$str}{Author}       = $::who;
 
     my $agestr = &::Time2String($::news{$chan}{$str}{Expire} - time() );
-    my $item   = &getNewsItem($str);
+    my $item   = &newsS2N($str);
     &::msg($::who, "Added '\037$str\037' at [".localtime(time).
                "] by \002$::who\002 for item #\002$item\002.");
     &::msg($::who, "Now do 'news text $item <your_description>'");
     &::msg($::who, "This item will expire at \002".
-       localtime($::news{$chan}{$str}{Expire})."\002 [$agestr] "
+       localtime($::news{$chan}{$str}{Expire})."\002 [$agestr from now] "
     );
+
+    &writeNews();
 }
 
 sub del {
@@ -233,9 +253,8 @@ sub del {
            return;
        }
 
-       $item = &getNewsItem($what);
-       &::DEBUG("del: num: item => $item ($what)");
-       $what   = $item;        # hack hack hack.
+       $item   = &getNewsItem($what);
+       $what   = $item;                # hack hack hack.
 
     } else {
        $_      = &getNewsItem($what);  # hack hack hack.
@@ -297,9 +316,9 @@ sub list {
        my $t   = $::news{$chan}{$_}{Time};
        $newest = $t if ($t > $newest);
     }
-    &::msg($::who, "|= Last updated ".
-               &::Time2String(time() - $newest). " ago.");
-    &::msg($::who, " \037No\037  \037Item ".(" "x40)." \037");
+    my $timestr = &::Time2String(time() - $newest);
+    &::msg($::who, "|= Last updated $timestr ago.");
+    &::msg($::who, " \037Num\037 \037Item ".(" "x40)." \037");
 
     my $i = 1;
     foreach ( &getNewsAll() ) {
@@ -316,10 +335,9 @@ sub list {
                                $i, $subtopic));
        $i++;
     }
+
     &::msg($::who, "|= End of News.");
     &::msg($::who, "use 'news read <#>' or 'news read <keyword>'");
-
-    &::DEBUG("news cache => ".scalar(keys %::newsuser) );
 }
 
 sub read {
@@ -567,6 +585,54 @@ sub set {
     &::msg($::who, "Setting [$chan]/{$news}/<$what> to '$value'.");
 }
 
+sub latest {
+    my($tchan, $flag) = @_;
+
+    $chan ||= $tchan;  # hack hack hack.
+
+    # todo: if chan = undefined, guess.
+    if (!exists $::news{$chan}) {
+       &::msg($::who, "invalid chan $chan");
+       return;
+    }
+
+    my @new;
+    foreach (keys %{ $::news{$chan} }) {
+       my $t = $::newsuser{$chan}{$::who};
+       next if (!defined $t);
+       next if ($t > $::news{$chan}{$_}{Time});
+
+       push(@new, $_);
+    }
+
+    if (!scalar @new and $flag) {
+       &::msg($::who, "no new news for $chan.");
+       return;
+    }
+
+    if (scalar @new) {
+       &::msg($::who, "+==== New news for \002$chan\002 (".
+               scalar(@new)." new items):");
+
+       my $timestr = &::Time2String( time() - $::newsuser{$chan}{$::who} );
+       &::msg($::who, "|= Last time read $timestr ago");
+
+       foreach (@new) {
+           my $i   = &newsS2N($_);
+           &::DEBUG("i = $i, _ => $_");
+           my $age = time() - $::news{$chan}{$_}{Time};
+           &::msg($::who, sprintf("\002[\002%2d\002]\002 %s",
+               $i, $_) );
+#              $i, $_, &::Time2String($age) ) );
+       }
+
+       &::msg($::who, "|= to read, do 'news read <#>' or 'news read <keyword>'");
+
+       # lame hack to prevent dupes if we just ignore it.
+       $::newsuser{$chan}{$::who} = time();
+    }
+}
+
 ###
 ### helpers...
 ###
@@ -585,6 +651,32 @@ sub getNewsAll {
     return @items;
 }
 
+sub newsS2N {
+    my($what)  = @_;
+    my @items;
+    my $no;
+
+    my %time;
+    foreach (keys %{ $::news{$chan} }) {
+       my $t = $::news{$chan}{$_}{Time};
+
+       if (!defined $t or $t !~ /^\d+$/) {
+           &::DEBUG("warn: t is undefined for news{$chan}{$_}{Time}; removing item.");
+           delete $::news{$chan}{$_};
+           next;
+       }
+
+       $time{$t} = $_;
+    }
+
+    foreach (sort { $a <=> $b } keys %time) {
+       $item++;
+       return $item if ($time{$_} eq $what);
+    }
+
+    &::DEBUG("newsS2N($what): failed...");
+}
+
 sub getNewsItem {
     my($what)  = @_;
     my $item   = 0;
@@ -616,7 +708,12 @@ sub getNewsItem {
        my $no;
        foreach (sort { $a <=> $b } keys %time) {
            $item++;
-           $no = $item if ($time{$_} eq $what);
+#          $no = $item if ($time{$_} eq $what);
+           if ($time{$_} eq $what) {
+               $no = $item;
+               next;
+           }
+
            push(@items, $time{$_}) if ($time{$_} =~ /\Q$what\E/i);
        }
 
@@ -625,6 +722,7 @@ sub getNewsItem {
        # todo: split this command in the future into:
        #       full_string->number and number->string
        #       partial_string->full_string
+       &::DEBUG("no => $no, items => @items.");
        if (defined $no and !@items) {
            &::DEBUG("string->number resolution.");
            return $no;
@@ -636,6 +734,7 @@ sub getNewsItem {
            return;
        }
 
+       &::DEBUG("gNI: string->number(??): $what->$items[0]");
        if (@items) {
            &::DEBUG("gNI: Guessed '$items[0]'.");
            return $items[0];