/[mws]/trunk/MWS.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/MWS.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 14 - (show annotations)
Thu May 6 19:46:58 2004 UTC (19 years, 11 months ago) by dpavlin
File size: 4826 byte(s)
Make mbox2swish universal for all indexer (moving index-specific
thinks in own .pm) -- after MWS_plucene.pm update it should work with it.
Use Text::AutoFormat to re-format messages wider than wrap_margin
(from global.conf). Hard-coded ISO-8859-2 encoding now works correctly,
Subject searches now remove common subject prefixes, template updates.

1 #!/usr/bin/perl -w
2
3 package MWS;
4
5 use strict;
6 use warnings;
7 use Carp;
8
9 use Mail::Box::Manager;
10 use Config::IniFiles;
11 use POSIX qw(strftime);
12 use Text::Autoformat;
13
14 #use MWS_plucene;
15 use MWS_swish;
16
17 require Exporter;
18
19 our @ISA = qw(Exporter);
20
21 our %EXPORT_TAGS = ();
22 our @EXPORT_OK;
23 our @EXPORT;
24
25 our $VERSION = '1.00';
26
27 my $folder; # placeholder for folders
28
29 my $debug = 2;
30
31 sub new {
32 my $class = shift;
33 my $self = {};
34 bless($self, $class);
35
36 my $config_file = shift || die "need index file";
37
38 $self->{config} = new Config::IniFiles( -file => $config_file );
39
40 my $index_file = $self->{config}->val('global', 'index') || croak "can't find [index] section in config file with path of index";
41
42 $self->{mgr} = Mail::Box::Manager->new(access => 'r');
43 $self->{index_file} = $index_file;
44
45 # placeholder for opened folders
46 $self->{folder} = {};
47
48 $self->{wrap_margin} = $self->{config}->val('global', 'wrap_margin');
49
50 return $self;
51 }
52
53 sub mbox_name2path {
54 my $self = shift;
55
56 my $mbox = shift || croak "folder_name2path needs mbox name";
57
58 return $self->{config}->val('folders', $mbox) || croak "comeone removed folder $mbox from config?";
59 }
60
61 sub open_folder {
62 my $self = shift;
63
64 my $mbox = shift || croak "open_folder needs mbox name";
65
66 if (! $self->{folder}->{$mbox}) {
67 my $mbox_path = $self->mbox_name2path($mbox);
68
69 print STDERR "about to open_folder($mbox)\n" if ($debug == 2);
70
71 $self->{folder}->{$mbox} = $self->{mgr}->open($mbox_path) || croak "can't open folder $mbox at '$mbox_path': $!";
72
73 print STDERR "open_folder($mbox) ok\n" if ($debug);
74 }
75
76 return $self->{folder}->{$mbox};
77
78 }
79
80 sub close_folder {
81 my $self = shift;
82
83 my $mbox = shift || croak "open_folder needs mbox name";
84
85 return $self->{folder}->{$mbox}->close(write => 'NEVER');
86 }
87
88 sub fetch_message {
89 my $self = shift;
90
91 my $mbox_id = shift || die "need mbox_id!";
92 my ($mbox,$id) = split(/ /,$mbox_id);
93
94 # return message with ID
95 print STDERR "fetch $id from $mbox\n" if ($debug);
96 return $self->open_folder($mbox)->find($id) ||
97 print STDERR "can't find message $id in $mbox. Time to re-index?\n";
98 }
99
100
101 sub search {
102 my $self = shift;
103
104 my $s = shift || carp "search called without argument!";
105
106 print STDERR "search_index($s)\n" if ($debug == 2);
107 my @index_ids = $self->search_index($s);
108
109 $self->{'index_ids'} = \@index_ids;
110
111 my $results = $#index_ids + 1;
112 $self->{'results'} = $results;
113
114 $self->{'curr_result'} = 0;
115
116 print STDERR "$results results\n" if ($debug == 2);
117
118 return $results || 'error';
119 }
120
121 sub unroll($$$) {
122 my $self = shift;
123
124 my ($message,$part,$sub) = @_;
125
126 my @arr;
127
128 foreach my $from ($message->$part) {
129 my $tmp = $from->$sub;
130 if ($tmp) {
131 $tmp =~ s/^\s*["'](.*)["']\s*$/$1/;
132 push @arr, $tmp;
133 }
134 }
135
136 return @arr;
137 }
138
139 sub fetch_all_results {
140 my $self = shift;
141
142 croak "results called before search!" if (! $self->{'index_ids'});
143
144 print STDERR "fetch_all_results [",scalar @{$self->{'index_ids'}},"]\n" if ($debug == 2);
145
146 my @arr;
147
148 foreach my $id (@{$self->{'index_ids'}}) {
149 push @arr, $self->fetch_result_by_id($id);
150 }
151
152 return @arr;
153 }
154
155 sub fetch_result {
156 my $self = shift;
157
158 my $args = {@_};
159
160 croak "results called before search!" if (! $self->{'index_ids'});
161
162 my $curr = $self->{'curr_result'}++;
163
164 my $id = $self->{'index_ids'}->[$curr];
165
166 print STDERR "fetch_result: $curr = $id\n" if ($debug == 2);
167
168 return $self->fetch_result_by_id($id);
169 }
170
171 sub plain_text_body {
172 my $self = shift;
173 my $message = shift || croak "plain_text_body needs message!";
174
175 my $body;
176
177 if (! $message->isMultipart) {
178 $body = $message->decoded->string;
179 } else {
180 foreach my $part ($message->parts) {
181 if ($part->body->mimeType eq 'text/plain') {
182 $body = $part->decoded->string;
183 last;
184 }
185 }
186 }
187
188 # reformat with Text::Autoformat
189 my $wrap = $self->{wrap_margin};
190 if ($wrap && $body && $body =~ m/^.{$wrap}..*$/m) {
191 $body = autoformat $body;
192 $body .="\n[reformated using autoformat, margin at $wrap]" if ($debug == 2);
193 }
194
195 return $body;
196 }
197
198
199 sub fetch_result_by_id {
200 my $self = shift;
201
202 my $id = shift || return;
203
204 my $row = $self->{cache}->{$id};
205
206 if (! $row) {
207
208 print STDERR "fetch_result_by_id($id) not in cache, hitting disk\n" if ($debug == 2);
209
210 my $message = $self->fetch_message($id) || print STDERR "can't fetch message '$id'";
211
212 $row->{'id'} = $id;
213 @{$row->{'from'}} = $self->unroll($message,'from','phrase');
214 @{$row->{'to'}} = $self->unroll($message,'to','phrase');
215 @{$row->{'cc'}} = $self->unroll($message,'cc','phrase');
216 $row->{'subject'} = $message->subject;
217 $row->{'body'} = $self->plain_text_body($message);
218 $row->{'date'} = $message->date;
219
220 # XXX store in cache?
221 $self->{cache}->{$id} = $row;
222 print STDERR "$id stored in cache\n" if ($debug == 2);
223 } else {
224 print STDERR "fetch_result_by_id($id) in cache\n" if ($debug == 2);
225 }
226
227 return $row;
228
229 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26