1 #!/usr/bin/perl -w 2 use strict; 3 $|++; 4 5 use XML::RSS; 6 use LWP::Simple qw(mirror is_success); 7 8 ## BEGIN config 9 10 my $MAIL_TO = 'merlyn@XXstonehenge.comXX'; 11 my $MAIL_FROM = 'merlyn@XXstonehenge.comXX'; 12 my $MAIL_SUBJECT = "All the news that fits, we print!"; 13 my $MAILHOST = "localhost"; 14 my $DIR = "/home/merlyn/.rssnews"; 15 my @NEWS = 16 ( 17 ## Perl News 18 "http://www.news.perl.org/perl-news-short.rdf" => "perl-news-short.rdf", 19 ## Slashdot 20 "http://slashdot.org/slashdot.rdf" => "slashdot.rdf", 21 ## CNET computing news 22 "http://alchemy.openjava.org/rss/news-com.rdf" => "cnet-computing-news.rdf", 23 ## Freshmeat 24 "http://freshmeat.net/backend/fm.rdf" => "freshmeat.rdf", 25 ## Linux Today 26 "http://linuxtoday.com/backend/my-netscape.rdf" => "linuxtoday.rdf", 27 ## Linux Planet 28 "http://www.linuxplanet.com/rss" => "linuxplanet.rdf", 29 ## Mac Central 30 "http://www.maccentral.com/mnn.cgi" => "maccentral.rdf", 31 ## Macweek.com 32 "http://macweek.zdnet.com/macweek.xml" => "macweek.rdf", 33 ## Moreover Computer Security 34 "http://www.moreover.com/cgi-local/page?index_computersecurity+rss" 35 => "moreover-computer-security.rdf", 36 ); 37 38 ## END config 39 40 chdir $DIR or die "Cannot chdir $DIR: $!"; 41 my @output; 42 43 while (@NEWS >= 2) { 44 my ($url, $localname) = splice @NEWS, 0, 2; 45 dbmopen my %SAW, $localname, 0644 or warn "Cannot open %SAW for $localname: $!"; 46 47 next unless is_success(mirror($url, $localname)); 48 49 my $rss = XML::RSS->new or die "can't create XML::RSS?"; 50 eval {$rss->parsefile($localname)} and not $@ 51 or (warn "cannot parse $localname: $@"), next; 52 53 my %seen; 54 my @item_output; 55 for my $item (@{$rss->{items}}) { 56 my ($title, $link, $description) = @$item{qw(title link description)}; 57 $description = "" unless defined $description; 58 my $tag = "$title\0$link"; 59 $seen{$tag} = time; 60 next if $SAW{$tag}; 61 push @item_output, "$tag\0$description"; 62 } 63 %SAW = %seen; 64 if (@item_output) { 65 push @output, "== ".($rss->channel("title"))." ==\n", map { 66 my ($title, $link, $description) = split /\0/; 67 "$title\n", 68 " <URL:$link>\n", 69 (length $description ? " $description\n" : ()); 70 } @item_output; 71 } 72 } 73 74 if (@output) { 75 require Net::SMTP; 76 my $m = Net::SMTP->new($MAILHOST) 77 or die "Cannot connect to mail $MAILHOST: $!"; 78 $m->mail($MAIL_FROM) 79 or die "Cannot set mail from: $!"; 80 $m->to($MAIL_TO) 81 or die "Cannot set mail to: $!"; 82 $m->data("From: $MAIL_FROM\n", 83 "To: $MAIL_TO\n", 84 "Subject: $MAIL_SUBJECT\n", 85 "\n", 86 @output, 87 ) 88 or die "Cannot send contents: $!"; 89 $m->quit 90 or die "Cannot close mail: $!"; 91 }