#!/usr/bin/perl -w
######################################################################
# wna.pl
######################################################################
# Perl Power! - Michael Schilli 1998
######################################################################

use Net::NNTP;                           # news communication
use POSIX;                               # for O_RDWRetc.
use SDBM_File;                           # persistent hash
use News::Newsrc;                        # read and write .newsrc
use Set::IntSpan;                        # additional range handler
use strict;

my $newsanswers = "news.answers";        # newsgroup
my $newshost    = "$ENV{NNTPSERVER}";    # news server from Env variable

my ($subject, %db);                      # local variables
my ($stat_new, $stat_archived, $stat_replay) = (0,0,0);

my $newsrc = News::Newsrc->new();        # new Newsrc object

print "Reading file .newsrc ...\n";
$newsrc->load();  

print "NNTP with $newshost ...\n";
my $na = Net::NNTP->new($newshost); 

   ### create or open persistent hash for subject lines
tie(%db, "SDBM_File", "$ENV{HOME}/.$newsanswers", 
    O_CREAT|O_RDWR, 0644) || die "Persistency error";

   ### fetch newsgroup news.answers article numbers via NNTP
print "Group information $newsanswers ...\n";
my ($total, $first, $last) = $na->group("$newsanswers");

   ### build intervals of unread articles in a Set::IntSpan object
my $intervals = Set::IntSpan->new(
          join(',', $newsrc->unmarked_articles($newsanswers, 
                                               $first, $last)));
print "Fetching subjects ...\n";

   ### store intervals of unread articles 
for (split(/,/, $intervals->run_list())) {
    my ($from, $to) = split(/-/, $_);

       ### amend intervals ($to == $from means  
       ### _all_ available articles for xhdr())
    $to = $from +1 if(!defined $to || $to == $from);

       ### fetch subjects of unread articles
    my $subjects = $na->xhdr('Subject', [$from, $to]);

    foreach $subject (keys %{$subjects}) {
        $stat_new++;                     # total no. of articles

                                         # already archived?
        if(defined($db{"$subjects->{$subject}"})) {  
                                         # mark as read because,
                                         # already archived
            $newsrc->mark($newsanswers, $subject);
            $stat_replay++;
        } else {                         # not yet archived?
            $db{"$subjects->{$subject}"} = 1;
            $stat_archived++;
        }
    }
}

$na->quit();                             # close NNTP connection
print "NNTP Verbindung geschlossen.\n";

print <<"EOT";                           # output statistics
$total articles available
of which $stat_new unread ones analyzed
         $stat_replay repetitions eliminated
         $stat_archived new ones archived
EOT

$newsrc->save();                         # write back .newsrc

