#!/usr/bin/perl =head1 NAME wari.pl --- A shimbun implemention to post messages to NNTP server =cut use strict; use lib qw#./lib/#; use vars qw/$MYNAME $NNTP_SERVER $VERSION/; $VERSION=do{my @r=(q$Revision: 1.2 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; $MYNAME = 'Suikawari'; use Bunshin; use Message::Header; use Getopt::Long; $NNTP_SERVER = 'localhost'; $Bunshin::DEBUG = 0; my $VERBOSE; my $directory = './module/'; my $posted_log = '.posted'; GetOptions ( debug => \$Bunshin::DEBUG, 'module-dir=s' => \$directory, 'nntp-server=s' => \$NNTP_SERVER, 'posted-log=s' => \$posted_log, verbose => \$VERBOSE, ) or die; sub dprint (@); sub vprint (@); binmode STDOUT; opendir DIR, $directory; my @module = sort map {s/\.sb$//; $_} grep /^[A-Za-z0-9_]+\.sb$/, readdir DIR; close DIR; die "$0: $directory: No suikawari definition" if @module == 0; push @main::INC, $directory; my $plog; { &posted_log_ns::import; open LOG, $posted_log; binmode LOG; local $/ = undef; $plog = parse Message::Header scalar , -format => 'x-internal-logfile', -ns_default_phuri => $posted_log_ns::OPTION{namespace_uri}, ; close LOG; } for (@module) { vprint $_; my $module = "Suikawari::$_"; require "$_.sb"; my $b = new Bunshin; my @msgreg = $module->msg_regex; my @metareg = $module->meta_regex; $b->set_regex (message => shift (@msgreg)); $b->set_elements (message => @msgreg); $b->set_regex (metainfo => shift (@metareg)); $b->set_elements (metainfo => @metareg); my %face = $module->face; for (keys %face) { $b->default_parameter ($_ => $face{$_}); } $module->on_load_source ($b); $b->set_source ($module->source); $module->on_make ($b); my ($nntp, $time); my $latest_time = $plog->field ($_, -new_item_unless_exist => 0); dprint 'Latest-Posted-Date: '.$latest_time; for ($b->make_msgs) { $_->option (format => 'news-usefor', -recursive => 1); $_->header->field ('x-shimbun-agent')->add ($MYNAME => $VERSION); my $t = $_->header->field ('date'); next if $latest_time >= $t; $nntp = open_nntp () unless ref $nntp; dprint 'Date: '.$t; send_msg ($_ => $nntp); $time = $t if $t > $time || !$time; } close_nntp ($nntp); $plog->replace ($_ => $time) if $time > $latest_time; } open LOG, '> '.$posted_log or die "$0: $posted_log: $!"; binmode LOG; print LOG $plog; close LOG; sub send_msg ($$) { my $msg = shift; my $nntp = shift; dprint "Posting Message..."; my @m = map {$_."\n"} split /\x0D\x0A/, $msg; my $r = $nntp->post (@m); vprint ${*$nntp}{'net_cmd_code'}, @{${*$nntp}{'net_cmd_resp'}}; unless ($r) { close_nntp ($nntp); die; } } sub open_nntp () { require Net::NNTP; vprint "Connecting to $NNTP_SERVER..."; my $nntp = Net::NNTP->new ($NNTP_SERVER) or die "$0: open_nntp: $!"; vprint ${*$nntp}{'net_cmd_code'}, @{${*$nntp}{'net_cmd_resp'}}; $nntp; } sub close_nntp ($) { my $nntp = shift; return unless ref $nntp; $nntp->quit; vprint ${*$nntp}{'net_cmd_code'}, @{${*$nntp}{'net_cmd_resp'}}; } sub dprint (@) { print shift, ' ' if $Bunshin::DEBUG && @_ > 1; print map {/\n$/s? $_: $_."\n"} @_ if $Bunshin::DEBUG; } sub vprint (@) { print shift, ' ' if ($VERBOSE || $Bunshin::DEBUG) && @_ > 1; print map {/\n$/s? $_: $_."\n"} @_ if $VERBOSE || $Bunshin::DEBUG; } package posted_log_ns; use vars qw/%OPTION/; sub import () { require Message::Header::Default; %OPTION = %Message::Header::Default::OPTION; $OPTION{namespace_uri} = 'urn:x-temp:x-posted-log'; $OPTION{namespace_phname} = 'posted'; $OPTION{namespace_phname_goodcase} = 'Posted'; $OPTION{case_sensible} = 1; $OPTION{value_type} = { ':default' => ['Message::Field::Date'], }; $Message::Header::NS_phname2uri{$OPTION{namespace_phname}} = $OPTION{namespace_uri}; $Message::Header::NS_uri2phpackage{$OPTION{namespace_uri}} = __PACKAGE__; } =head1 SEE ALSO Bunshin L =head1 LICENSE Copyright 2002 wakaba Ew@suika.fam.cxE. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. =head1 CHANGE See F. $Date: 2002/06/16 11:06:45 $ =cut 1; ### wari.pl ends here