/[suikacvs]/messaging/bunshin/Bunshin.pm
Suika

Contents of /messaging/bunshin/Bunshin.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations) (download)
Thu Jun 20 11:36:32 2002 UTC (22 years, 5 months ago) by wakaba
Branch: MAIN
Changes since 1.2: +21 -12 lines
2002-06-20  wakaba <w@suika.fam.cx>

	* Bunshin.pm (_make_a_msg): Message-id algorithm
	is revised to avoid conflict.

1 wakaba 1.1
2     =head1 NAME
3    
4 wakaba 1.2 Bunshin --- A shimbun implemrntion written in Perl
5 wakaba 1.1
6     =cut
7    
8     package Bunshin;
9     use strict;
10     use vars qw($DEBUG $MYNAME $VERSION);
11 wakaba 1.3 $VERSION=do{my @r=(q$Revision: 1.2 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
12 wakaba 1.1 $MYNAME = 'Bunshin';
13     $DEBUG = 0;
14     use FileHandle;
15     require Message::Entity;
16     require Message::Util;
17     require Message::Field::Date;
18    
19     sub new ($;%) {
20     my $class = shift;
21     my $self = bless {}, $class;
22     $self->{fmt2str} = Message::Util::make_clone
23     ($Message::Field::Date::DEFAULT{-fmt2str});
24     $self;
25     }
26    
27     =item $b->msg_regex ($regex)
28    
29     Set regex used to cut a message.
30    
31     =cut
32    
33     sub set_regex ($$$) {
34     my $self = shift;
35     my $name = shift;
36     my $regex = shift;
37     $regex =~ s/\x20/\\x20/g;
38     $regex =~ s/\x09/\\x09/g;
39     $regex =~ s/\x0D(?!\x0A)/\x0D\x0A/g;
40     $regex =~ s/(?<!\x0D)\x0A/\x0D\x0A/g;
41     $regex =~ s/\x0D/\\x0D/g;
42     $regex =~ s/\x0A/\\x0A/g;
43     $regex =~ s/\x23/\\x23/g;
44     $self->{'regex_'.$name} = $regex;
45     }
46    
47     sub set_hook_function ($$\&) {
48     my $self = shift;
49     my $name = shift;
50     my $function = shift;
51     $self->{'hook_'.$name} = $function;
52     }
53    
54     sub set_format ($$\&) {
55     my $self = shift;
56     my $name = shift;
57     my $function = shift;
58     $self->{fmt2str}->{$name} = $function;
59     }
60    
61     sub set_elements ($$@) {
62     my $self = shift;
63     my $name = shift;
64     $self->{'elements_'.$name} = \@_;
65     }
66    
67     sub set_source ($%) {
68     my $self = shift;
69     my %option = @_;
70     if (defined $option{value}) {
71     $self->{source} = $option{value};
72     } elsif ($option{uri}) {
73     require Message::Field::UA;
74     require LWP::UserAgent;
75     my $ua = Message::Field::UA->new;
76     $ua->add_our_name;
77     $ua->add ('libwww-perl' => $LWP::VERSION);
78     my $lwp = LWP::UserAgent->new;
79     $lwp->agent ($ua->stringify);
80     my $req = HTTP::Request->new (GET => $option{uri});
81     my $res = $lwp->request ($req);
82     my $c = $self->{hook_code_conversion} || \&_code_conversion;
83     $self->{source} = &$c ($self, $res->content, \%option);
84     $self->default_parameter (base_uri => $option{uri});
85     } elsif ($option{file}) {
86     my $f = new FileHandle $option{file} => 'r';
87     Carp::croak "set_source: $option{file}: $!" unless defined $f;
88     my $c = $self->{hook_code_conversion} || \&_code_conversion;
89     local $/ = undef;
90     $self->{source} = &$c ($self, $f->getline, \%option);
91     } else {
92     Carp::croak "set_source: $_[0]: Unsupported data source type";
93     }
94     $self->{source} =~ s/\x0D(?!\x0A)/\x0D\x0A/g;
95     $self->{source} =~ s/(?<!\x0D)\x0A/\x0D\x0A/g;
96     $self;
97     }
98    
99     ## $self->_code_conversion ($string, \%option)
100     sub _code_conversion ($$\%) {
101     $_[1];
102     }
103    
104     sub make_msgs ($) {
105     my $self = shift;
106     my $s = $self->{source};
107     my $f = $self->{hook_make_msg} || \&_make_a_msg;
108     my @msg;
109     my %param = %{$self->{default_parameter}};
110     if ($self->{regex_metainfo} && ref $self->{elements_metainfo}) {
111     $s =~ s{ $self->{regex_metainfo} }{
112     no strict 'refs';
113     for my $i (0..$#{$self->{elements_metainfo}}) {
114     $param{$self->{elements_metainfo}->[$i]} = ${$i+1};
115     }
116     $&;
117     }esx;
118     }
119     $s =~ s{ $self->{regex_message} }{
120     no strict 'refs';
121     my %p = %param;
122     for my $i (0..$#{$self->{elements_message}}) {
123     $p{$self->{elements_message}->[$i]} = ${$i+1};
124     }
125     my $msg = &$f ($self, %p);
126     push @msg, $msg;
127     }gesx;
128     @msg;
129     }
130    
131     ## Default function for "make_msg"
132     sub _make_a_msg ($@) {
133     my $self = shift;
134     my %p = @_;
135     my $msg = new Message::Entity
136     -fill_date => 0,
137     -fill_msgid => 0,
138     -fill_ua_name => 'x-shimbun-agent',
139     -parse_all => 1,
140     ;
141     my $hdr = $msg->header;
142     ## Originator and date
143 wakaba 1.3 my $from = $hdr->field ('from')->add ($p{from_mail} || 'foo@bar.invalid');
144 wakaba 1.1 $from->display_name ($p{from_name}) if length $p{from_name};
145     my $date = $hdr->field ('date');
146     $p{date_year} ||= (gmtime)[5];
147     $date->set_datetime (@p{qw/date_year date_month
148     date_day date_hour date_minute date_second/},
149     zone => $p{date_zone});
150 wakaba 1.3 $hdr->add (x_uri => $p{from_uri}) if $p{from_uri};
151 wakaba 1.1 if ($p{from_face}) {
152     $msg->header->field ('x-face')->value ($p{from_face});
153     } elsif ($p{faces}->{$p{from_mail}}) {
154     $msg->header->field ('x-face')->value ($p{faces}->{$p{from_mail}});
155     } elsif ($p{list_face}) {
156     $msg->header->field ('x-face')->value ($p{list_face});
157     }
158     ## Message attribute
159     if (length $p{msg_id}) {
160     $hdr->add ('message-id' => $p{msg_id});
161 wakaba 1.3 } elsif ($p{msg_id_from} || $p{msg_id_right} || $p{list_id}) {
162 wakaba 1.1 my $c = $p{msg_count};
163     $c = '.d'.(0+$date) unless defined $p{msg_count};
164 wakaba 1.3 my $mid;
165     if ($p{msg_id_from}) {
166     $mid = sprintf '<msg%s.BS%%%s%%%s>', $c, $p{list_id}, $p{msg_id_from};
167     } elsif ($p{msg_id_right}) {
168     $mid = sprintf '<msg%s.BS%%%s%%list@%s>', $c, $p{list_id}, $p{msg_id_right};
169     } else { #if ($p{list_id}) {
170     $mid = sprintf '<msg%s.BS%%list@%s>', $c, $p{list_id};
171     }
172 wakaba 1.1 $hdr->add (($DEBUG?'x-':'').'message-id' => $mid);
173     }
174 wakaba 1.3 if (length $p{subject}) {
175     $hdr->add (subject => $p{subject});
176     } elsif (length $p{DEFAULT_subject}) {
177     $hdr->add (subject => $p{DEFAULT_subject});
178     }
179 wakaba 1.1 my $a;
180     for (grep {/^misc_/} keys %p) {
181     $a = $hdr->field ('content-x-properties') unless ref $a;
182     my $name = substr ($_, 5);
183     $name =~ tr/_/-/;
184     if ($p{base_uri} && /uri/ && length $p{$_}) {
185     require URI::WithBase;
186 wakaba 1.2 $a->add ($name => URI::WithBase->new ($p{$_}, $p{base_uri})->abs);
187 wakaba 1.1 } else {
188     $a->add ($name => $p{$_}) if length $p{$_};
189     }
190     }
191     ## Body and body information
192     my $b = $self->{hook_msg_body} || \&_make_a_msg_body;
193     &$b ($self, $msg, $p{body}, \%p);
194     ## List information
195     if (length $p{list_id}) {
196     my $lid = $hdr->field ('list-id');
197     $lid->value ($p{list_id});
198     $lid->display_name ($p{list_name}) if length $p{list_name};
199     }
200 wakaba 1.3 $hdr->add (x_mail_count => $p{msg_count}) if defined $p{msg_count};
201     $hdr->add (x_ml_info => $p{list_info}) if defined $p{list_info};
202 wakaba 1.1 if ($p{base_uri}) {
203     my $uri = $hdr->add (x_uri => '');
204     $uri->value ($p{base_uri});
205     $uri->display_name ($p{list_name}) if length $p{list_name};
206     }
207     if ($p{urn_template}) {
208     my $urn = $self->Message::Field::Date::_date2str ({
209     format_template => $p{urn_template},
210     date_time => $date->unix_time,
211     zone => $date->zone,
212     fmt2str => $self->{fmt2str},
213 wakaba 1.3 }, \%p);
214 wakaba 1.1 $hdr->add ('x-uri')->value ($urn);
215     }
216     ## Additional information
217     my $u = $self->{hook_msg_header_add};
218     &$u ($self, $msg, \%p) if ref $u;
219     $hdr->field ('x-shimbun-agent')->add ($MYNAME => $VERSION);
220     $msg;
221     }
222    
223     sub _make_a_msg_body ($$$\%) {
224     my $self = shift;
225     my ($msg, $body, $param) = @_;
226     if (length $body) {
227     $body =~ s/(?<!\x0D\x0A)\z/\x0D\x0A/s;
228     $msg->body ($body);
229     }
230     }
231    
232     sub default_parameter ($@) {
233     my $self = shift;
234     if (@_ == 1) {
235     return $self->{default_parameter}->{ $_[0] };
236     }
237     while (my ($name, $value) = splice (@_, 0, 2)) {
238     $self->{default_parameter}->{$name} = $value;
239     }
240     $self;
241     }
242    
243     =head1 LICENSE
244    
245     Copyright 2002 wakaba E<lt>w@suika.fam.cxE<gt>.
246    
247     This program is free software; you can redistribute it and/or modify
248     it under the terms of the GNU General Public License as published by
249     the Free Software Foundation; either version 2 of the License, or
250     (at your option) any later version.
251    
252     This program is distributed in the hope that it will be useful,
253     but WITHOUT ANY WARRANTY; without even the implied warranty of
254     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
255     GNU General Public License for more details.
256    
257     You should have received a copy of the GNU General Public License
258     along with this program; see the file COPYING. If not, write to
259     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
260     Boston, MA 02111-1307, USA.
261    
262     =head1 CHANGE
263    
264     See F<ChangeLog>.
265 wakaba 1.3 $Date: 2002/06/16 10:46:29 $
266 wakaba 1.1
267     =cut
268    
269     1;

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24