#
# News.pl: Advanced news management
# Author: dms
-# Version: v0.2 (20010326)
+# Version: v0.3 (20014012)
# Created: 20010326
# Notes: Testing done by greycat, kudos!
#
### structure:
-# news{ channel }{ string } { items }
+# news{ channel }{ string } { item }
# newsuser{ channel }{ user } = time()
-### where items is:
+### where item is:
# Time - when it was added (used for sorting)
# Author - Who by.
# Expire - Time to expire.
my($what) = @_;
$chan = undef;
- if ($::msgType eq "private") {
- } else {
+ 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 ne "private") {
$chan = $::chan;
}
my @chans = &::GetNickInChans($::who);
if (scalar @chans > 1) {
- &::msg($::who, "error: I dunno which channel you are referring to since you're on more than one.");
+ &::msg($::who, "error: I dunno which channel you are referring to since you're on more than one. Try 'news #chan ...' instead");
return;
}
&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();
# 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 {
&::DEBUG("!defined item, never happen!");
next;
}
+
$::news{$chan}{$item}{$1} = $2;
next;
}
$::news{$chan}{$str}{Author} = $::who;
my $agestr = &::Time2String($::news{$chan}{$str}{Expire} - time() );
- my $item = &getNewsItem($str);
- if ($item eq $str) {
- &::DEBUG("item eq str ($item): should never happen.");
- }
+ 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 from now] "
);
+
+ &writeNews();
}
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.
return;
}
-# my $item = (exists $::news{$chan}{$str}) ? $str : &getNewsItem($str);
my $item = &getNewsItem($str);
if (!defined $item or !scalar keys %{ $::news{$chan}{$item} }) {
&::msg($::who, "No news item called '$str'");
return;
}
- # todo: show item number.
- # todo: show ago-time aswell?
- # todo: show request stats aswell.
- my $t = localtime($::news{$chan}{$item}{Time});
- my $a = $::news{$chan}{$item}{Author};
- &::msg($::who, "+- News \002$chan\002 ##, item '\037$item\037':");
+ my $t = localtime( $::news{$chan}{$item}{Time} );
+ my $a = $::news{$chan}{$item}{Author};
+ my $text = $::news{$chan}{$item}{Text};
+ my $num = &newsS2N($item);
+ my $rwho = $::news{$chan}{$item}{Request_By} || $::who;
+ my $rcount = $::news{$chan}{$item}{Request_Count} || 0;
+
+ if (length $text < $::param{maxKeySize}) {
+ &::DEBUG("NEWS: Possible news->factoid redirection.");
+ my $f = &::getFactoid($text);
+
+ if (defined $f) {
+ &::DEBUG("NEWS: ok, $text is factoid redirection.");
+ $f =~ s/^<REPLY>\s*//i; # anything else?
+ $text = $f;
+ }
+ }
+
+ &::msg($::who, "+- News \002$chan\002 #$num: \037$item\037");
&::msg($::who, "| Added by $a at $t");
- &::msg($::who, $::news{$chan}{$item}{Text});
+ &::msg($::who, "| Requested $rcount times, last by $rwho");
+ &::msg($::who, $text);
$::news{$chan}{$item}{'Request_By'} = $::who;
$::news{$chan}{$item}{'Request_Time'} = time();
return;
}
+ # todo: clean this up.
my $old = $::news{$chan}{$news}{$what};
if (defined $old) {
&::DEBUG("old => $old.");
&::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 (!$flag) {
+ my $unread = scalar @new;
+ my $total = scalar keys %{ $::news{$chan} };
+ &::msg($::who, "There are unread news in $chan ($unread unread, $total, total). /msg $::ident news latest");
+ 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($_);
+ 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...
###
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;
} else {
# partial string to full string resolution
+ # in some cases, string->number resolution.
my @items;
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);
}
- # since we have so much built into this function, there is so
- # many guesses we can make.
- # todo: split this command in the future into:
- # full_string->number and number->string
- # partial_string->full_string
if (defined $no and !@items) {
- &::DEBUG("string->number resolution.");
+ &::DEBUG("string->number resolution: $what->$no.");
return $no;
}
return;
}
+ &::DEBUG("gNI: part_string->full_string: $what->$items[0]");
if (@items) {
&::DEBUG("gNI: Guessed '$items[0]'.");
return $items[0];