#!/usr/bin/perl -w
######################################################################
# (c) Michael Schilli 1999
######################################################################
###############################################################
# chknews.pl - Newsgroups nach neuen Titeln durchsuchen
###############################################################

#**************************************************************
# Erweiterte Newsrc-Klasse
#**************************************************************
package MyNewsrc;

use News::Newsrc;                 # Newsrc-Datei verwalten
use Set::IntSpan;                 # Zusätzlicher Range-Handler

@ISA = qw/News::Newsrc/;          # Basisklasse


###############################################################
# Liste unmarkierter Artikel holen. Format: Wie Newsrc.
###############################################################
sub get_unmarked_articles { 
###############################################################
    my ($self, $ng, $from, $to) = @_;
                                  # IntSpan-Objekt erzeugen
    my $intervals = Set::IntSpan->new(
        join(',', $self->unmarked_articles($ng, $from, $to)));
    $intervals->run_list();       # String zurückgeben
}

###############################################################
sub clear_old_ranges {                    # Bereiche limitieren
    my ($self, $ng, $article_limit) = @_;
###############################################################
                                  # Letzten Artikel ermitteln
    my $articles = $self->get_articles($ng);
    my ($last_article) = ($articles =~ /(\d+)$/);
                                  # Bereiche vor den letzten
                                  # N Artikeln übermalen
    if($last_article > $article_limit) {
        $self->mark_range($ng, 1, 
                          $last_article-$article_limit);
    }
}

#**************************************************************
# Hauptprogramm
#**************************************************************
package main;

my $newsrcfile    = "$ENV{HOME}/data/news.dat"; # "Gedächtnis"
my $newsserver    = "$ENV{NNTPSERVER}";         # Newsserver

my $article_limit = 10000;     # Länge des überwachten Bereichs
                               # am Ende des Nummernkreises
$| = 1;                        # Ausgaben nicht puffern

use Net::NNTP;                 # NNTP User Agent
use Getopt::Std;               # Kommandozeilen-Parameter
                               # Optionen -r, -h, -d, -v
$opt_r = $opt_h = $opt_v = $opt_d = undef;
getopts("rhvd");

my($ng, $pattern) = @ARGV;     # Kommandozeilen-Parameter
usage("Argument Error") unless defined $pattern;
usage() if defined $opt_h;     # -h gesetzt?

$newsrc = MyNewsrc->new();     # Newsrc-Objekt erzeugen

if(-f $newsrcfile) {           # Newsrc-Datei einlesen
    $newsrc->load($newsrcfile) || 
                            die "Cannot load $newsrcfile";
}

print "Scanning $ng for $pattern\n" if $opt_v;

                               # News-Agenten erzeugen
print "Connecting to $newsserver\n" if $opt_d;
($newsagent = Net::NNTP->new($newsserver)) ||
    die "Cannot connect to $newsserver";
                               # Nummern verfügbarer
                               # Artikel vom Server holen
(my ($total, $first, $last) = $newsagent->group($ng)) ||
    usage("Unknown newsgroup $ng");
                               # Bereiche noch nicht gele-
                               # sener Artikel definieren
print "$total ($first-$last) articles in $ng\n" if $opt_d;
$unmarked = $newsrc->get_unmarked_articles($ng, $first, $last);
                               # Re-check option: Alles
$unmarked = "$first-$last" if defined $opt_r;

foreach (split(/,/, $unmarked)) {        # Für jeden Bereich:
    my ($from, $to) = split(/-/, $_);
                                         # Intervall korrigieren      
    $to = $from +1 if(!defined $to || $to == $from);

    print "XHDR $from $to\n" if $opt_d;  # Subject-Zeilen holen
    (my $subjects = 
           $newsagent->xhdr('Subject', [$from, $to])) ||
        die "xhdr failed";

    while (($msgno, $subject) = each %$subjects) {
        $newsrc->mark($ng, $msgno);   # Als 'gelesen' markieren
                                      # Ausgeben, falls Match
        if($subject =~ /$pattern/i) {
            print "    " if($opt_d || $opt_v);
            print "$ng: $subject\n";
        }
    }
}
                                         # Bereiche begrenzen
$newsrc->clear_old_ranges($ng, $article_limit); 
$newsrc->save_as($newsrcfile);
$newsagent->quit();                      # Newsagent freigeben

###############################################################
sub usage {                              # Usage ausgeben
###############################################################
    (my $program = $0) =~ s,.*/,,g;      # Basename ermitteln
    print "$program: @_\n";
    print "usage: $program [-rvhd] newsgroup subject\n";
    print "           -r: re-check all Articles\n";
    print "           -v: verbose on\n";
    print "           -h: print out this message\n";
    print "           -d: debug on\n";
    exit 0;
}
