| 1 |
wakaba |
1.2 |
#!/usr/bin/perl |
| 2 |
wakaba |
1.1 |
|
| 3 |
|
|
=head1 NAME |
| 4 |
|
|
|
| 5 |
|
|
wari.pl --- A shimbun implemention to post messages to NNTP server |
| 6 |
|
|
|
| 7 |
|
|
=cut |
| 8 |
|
|
|
| 9 |
|
|
use strict; |
| 10 |
|
|
use lib qw#./lib/#; |
| 11 |
|
|
use vars qw/$MYNAME $NNTP_SERVER $VERSION/; |
| 12 |
wakaba |
1.6 |
$VERSION=do{my @r=(q$Revision: 1.5 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; |
| 13 |
wakaba |
1.1 |
$MYNAME = 'Suikawari'; |
| 14 |
|
|
use Bunshin; |
| 15 |
|
|
use Message::Header; |
| 16 |
|
|
|
| 17 |
|
|
use Getopt::Long; |
| 18 |
|
|
$NNTP_SERVER = 'localhost'; |
| 19 |
|
|
$Bunshin::DEBUG = 0; |
| 20 |
wakaba |
1.2 |
my $VERBOSE; |
| 21 |
wakaba |
1.1 |
my $directory = './module/'; |
| 22 |
|
|
my $posted_log = '.posted'; |
| 23 |
wakaba |
1.5 |
my $module_pattern = q([A-Za-z0-9_]+); |
| 24 |
wakaba |
1.1 |
GetOptions ( |
| 25 |
|
|
debug => \$Bunshin::DEBUG, |
| 26 |
|
|
'module-dir=s' => \$directory, |
| 27 |
wakaba |
1.5 |
'module-name=s' => \$module_pattern, |
| 28 |
wakaba |
1.1 |
'nntp-server=s' => \$NNTP_SERVER, |
| 29 |
|
|
'posted-log=s' => \$posted_log, |
| 30 |
wakaba |
1.2 |
verbose => \$VERBOSE, |
| 31 |
wakaba |
1.1 |
) or die; |
| 32 |
|
|
|
| 33 |
wakaba |
1.4 |
sub eprint (@); |
| 34 |
wakaba |
1.1 |
sub dprint (@); |
| 35 |
wakaba |
1.2 |
sub vprint (@); |
| 36 |
wakaba |
1.1 |
binmode STDOUT; |
| 37 |
|
|
|
| 38 |
|
|
opendir DIR, $directory; |
| 39 |
wakaba |
1.5 |
my @module = sort map {s/\.sb$//; $_} grep /^$module_pattern\.sb$/, readdir DIR; |
| 40 |
wakaba |
1.1 |
close DIR; |
| 41 |
|
|
die "$0: $directory: No suikawari definition" if @module == 0; |
| 42 |
|
|
push @main::INC, $directory; |
| 43 |
|
|
|
| 44 |
|
|
my $plog; |
| 45 |
|
|
{ |
| 46 |
|
|
&posted_log_ns::import; |
| 47 |
|
|
open LOG, $posted_log; |
| 48 |
|
|
binmode LOG; |
| 49 |
|
|
local $/ = undef; |
| 50 |
|
|
$plog = parse Message::Header scalar <LOG>, |
| 51 |
|
|
-format => 'x-internal-logfile', |
| 52 |
|
|
-ns_default_phuri => $posted_log_ns::OPTION{namespace_uri}, |
| 53 |
|
|
; |
| 54 |
|
|
close LOG; |
| 55 |
|
|
} |
| 56 |
|
|
|
| 57 |
wakaba |
1.5 |
my $nntp; |
| 58 |
wakaba |
1.1 |
for (@module) { |
| 59 |
wakaba |
1.4 |
vprint $_; |
| 60 |
wakaba |
1.1 |
my $module = "Suikawari::$_"; |
| 61 |
wakaba |
1.3 |
load_module ($_); |
| 62 |
wakaba |
1.1 |
my $b = new Bunshin; |
| 63 |
|
|
my @msgreg = $module->msg_regex; |
| 64 |
|
|
my @metareg = $module->meta_regex; |
| 65 |
|
|
$b->set_regex (message => shift (@msgreg)); |
| 66 |
|
|
$b->set_elements (message => @msgreg); |
| 67 |
wakaba |
1.3 |
$b->set_regex (metainfo => shift (@metareg)) if @metareg > 0; |
| 68 |
|
|
$b->set_elements (metainfo => @metareg) if @metareg > 0; |
| 69 |
wakaba |
1.1 |
my %face = $module->face; |
| 70 |
|
|
for (keys %face) { |
| 71 |
|
|
$b->default_parameter ($_ => $face{$_}); |
| 72 |
|
|
} |
| 73 |
|
|
$module->on_load_source ($b); |
| 74 |
|
|
$b->set_source ($module->source); |
| 75 |
|
|
$module->on_make ($b); |
| 76 |
wakaba |
1.5 |
my ($time); |
| 77 |
wakaba |
1.1 |
my $latest_time = $plog->field ($_, -new_item_unless_exist => 0); |
| 78 |
|
|
dprint 'Latest-Posted-Date: '.$latest_time; |
| 79 |
|
|
for ($b->make_msgs) { |
| 80 |
|
|
my $t = $_->header->field ('date'); |
| 81 |
wakaba |
1.6 |
next if 0+$latest_time >= 0+$t; |
| 82 |
|
|
$time = $t if $t > $time || !$time; |
| 83 |
wakaba |
1.3 |
vprint 'Date: '.$t; |
| 84 |
wakaba |
1.6 |
|
| 85 |
|
|
$_->header->field ('x-shimbun-agent')->add ($MYNAME => $VERSION); |
| 86 |
|
|
|
| 87 |
|
|
$_->option (format => 'news-usefor', -recursive => 1); |
| 88 |
|
|
send_msg_nntp ($_ => $nntp); |
| 89 |
wakaba |
1.1 |
} |
| 90 |
|
|
$plog->replace ($_ => $time) if $time > $latest_time; |
| 91 |
|
|
} |
| 92 |
wakaba |
1.5 |
close_nntp ($nntp); |
| 93 |
wakaba |
1.1 |
|
| 94 |
|
|
open LOG, '> '.$posted_log or die "$0: $posted_log: $!"; |
| 95 |
|
|
binmode LOG; |
| 96 |
|
|
print LOG $plog; |
| 97 |
|
|
close LOG; |
| 98 |
|
|
|
| 99 |
wakaba |
1.6 |
sub send_msg_nntp ($$) { |
| 100 |
wakaba |
1.1 |
my $msg = shift; |
| 101 |
wakaba |
1.6 |
$_[0] = open_nntp () unless ref $_[0]; |
| 102 |
wakaba |
1.1 |
my $nntp = shift; |
| 103 |
|
|
dprint "Posting Message..."; |
| 104 |
|
|
my @m = map {$_."\n"} split /\x0D\x0A/, $msg; |
| 105 |
|
|
my $r = $nntp->post (@m); |
| 106 |
wakaba |
1.4 |
if ($r) { |
| 107 |
|
|
vprint ${*$nntp}{'net_cmd_code'}, @{${*$nntp}{'net_cmd_resp'}}; |
| 108 |
|
|
} else { |
| 109 |
|
|
eprint ${*$nntp}{'net_cmd_code'}, @{${*$nntp}{'net_cmd_resp'}}; |
| 110 |
wakaba |
1.3 |
#close_nntp ($nntp); |
| 111 |
|
|
#die; |
| 112 |
wakaba |
1.4 |
eprint "send_msg: Can't post the message. Skiped"; |
| 113 |
wakaba |
1.1 |
} |
| 114 |
|
|
} |
| 115 |
|
|
|
| 116 |
|
|
sub open_nntp () { |
| 117 |
|
|
require Net::NNTP; |
| 118 |
wakaba |
1.2 |
vprint "Connecting to $NNTP_SERVER..."; |
| 119 |
wakaba |
1.1 |
my $nntp = Net::NNTP->new ($NNTP_SERVER) or die "$0: open_nntp: $!"; |
| 120 |
wakaba |
1.2 |
vprint ${*$nntp}{'net_cmd_code'}, @{${*$nntp}{'net_cmd_resp'}}; |
| 121 |
wakaba |
1.1 |
$nntp; |
| 122 |
|
|
} |
| 123 |
|
|
|
| 124 |
|
|
sub close_nntp ($) { |
| 125 |
|
|
my $nntp = shift; |
| 126 |
|
|
return unless ref $nntp; |
| 127 |
wakaba |
1.6 |
vprint "Disconnect to $NNTP_SERVER"; |
| 128 |
wakaba |
1.1 |
$nntp->quit; |
| 129 |
wakaba |
1.2 |
vprint ${*$nntp}{'net_cmd_code'}, @{${*$nntp}{'net_cmd_resp'}}; |
| 130 |
wakaba |
1.1 |
} |
| 131 |
|
|
|
| 132 |
wakaba |
1.3 |
sub load_module ($) { |
| 133 |
|
|
no strict 'refs'; |
| 134 |
|
|
my $m = shift; |
| 135 |
|
|
dprint qq{require "$m.sb"}; |
| 136 |
|
|
require "$m.sb"; |
| 137 |
|
|
if (defined &{ "Suikawari::${m}::require" }) { |
| 138 |
|
|
for (&{ "Suikawari::${m}::require" }) { |
| 139 |
|
|
load_module ($_) unless ${ "Suikawari::${_}::VERSION" }; |
| 140 |
|
|
push @{ "Suikawari::${m}::ISA" }, "Suikawari::${_}"; |
| 141 |
|
|
} |
| 142 |
|
|
} |
| 143 |
|
|
} |
| 144 |
|
|
|
| 145 |
wakaba |
1.4 |
sub eprint (@) { |
| 146 |
|
|
print shift, ' ' if @_ > 1; |
| 147 |
|
|
print map {/\n$/s? $_: $_."\n"} @_; |
| 148 |
|
|
} |
| 149 |
|
|
|
| 150 |
wakaba |
1.1 |
sub dprint (@) { |
| 151 |
|
|
print shift, ' ' if $Bunshin::DEBUG && @_ > 1; |
| 152 |
|
|
print map {/\n$/s? $_: $_."\n"} @_ if $Bunshin::DEBUG; |
| 153 |
|
|
} |
| 154 |
|
|
|
| 155 |
wakaba |
1.2 |
sub vprint (@) { |
| 156 |
|
|
print shift, ' ' if ($VERBOSE || $Bunshin::DEBUG) && @_ > 1; |
| 157 |
|
|
print map {/\n$/s? $_: $_."\n"} @_ if $VERBOSE || $Bunshin::DEBUG; |
| 158 |
|
|
} |
| 159 |
|
|
|
| 160 |
wakaba |
1.1 |
package posted_log_ns; |
| 161 |
|
|
use vars qw/%OPTION/; |
| 162 |
|
|
|
| 163 |
|
|
sub import () { |
| 164 |
|
|
require Message::Header::Default; |
| 165 |
|
|
%OPTION = %Message::Header::Default::OPTION; |
| 166 |
|
|
$OPTION{namespace_uri} = 'urn:x-temp:x-posted-log'; |
| 167 |
|
|
$OPTION{namespace_phname} = 'posted'; |
| 168 |
|
|
$OPTION{namespace_phname_goodcase} = 'Posted'; |
| 169 |
|
|
$OPTION{case_sensible} = 1; |
| 170 |
|
|
$OPTION{value_type} = { |
| 171 |
|
|
':default' => ['Message::Field::Date'], |
| 172 |
|
|
}; |
| 173 |
|
|
|
| 174 |
|
|
$Message::Header::NS_phname2uri{$OPTION{namespace_phname}} = $OPTION{namespace_uri}; |
| 175 |
|
|
$Message::Header::NS_uri2phpackage{$OPTION{namespace_uri}} = __PACKAGE__; |
| 176 |
|
|
} |
| 177 |
|
|
|
| 178 |
|
|
=head1 SEE ALSO |
| 179 |
|
|
|
| 180 |
|
|
Bunshin L<Shimbun> |
| 181 |
|
|
|
| 182 |
|
|
=head1 LICENSE |
| 183 |
|
|
|
| 184 |
|
|
Copyright 2002 wakaba E<lt>w@suika.fam.cxE<gt>. |
| 185 |
|
|
|
| 186 |
|
|
This program is free software; you can redistribute it and/or modify |
| 187 |
|
|
it under the terms of the GNU General Public License as published by |
| 188 |
|
|
the Free Software Foundation; either version 2 of the License, or |
| 189 |
|
|
(at your option) any later version. |
| 190 |
|
|
|
| 191 |
|
|
This program is distributed in the hope that it will be useful, |
| 192 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 193 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 194 |
|
|
GNU General Public License for more details. |
| 195 |
|
|
|
| 196 |
|
|
You should have received a copy of the GNU General Public License |
| 197 |
|
|
along with this program; see the file COPYING. If not, write to |
| 198 |
|
|
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 199 |
|
|
Boston, MA 02111-1307, USA. |
| 200 |
|
|
|
| 201 |
|
|
=head1 CHANGE |
| 202 |
|
|
|
| 203 |
|
|
See F<ChangeLog>. |
| 204 |
wakaba |
1.6 |
$Date: 2002/07/24 12:14:48 $ |
| 205 |
wakaba |
1.1 |
|
| 206 |
|
|
=cut |
| 207 |
|
|
|
| 208 |
|
|
1; |
| 209 |
|
|
### wari.pl ends here |