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

Contents of /messaging/bunshin/Bunshin.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Sun Jun 16 02:50:54 2002 UTC (21 years, 11 months ago) by wakaba
Branch: MAIN
2002-06-16  wakaba <w@suika.fam.cx>

	* Bunshin.pm: New module.
	* ChangeLog: New file.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24