ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/FreeBSDAdmin/Mail/SpamUpdate.pl
Revision: 1135
Committed: 2009-01-09T22:05:37-08:00 (16 years, 5 months ago) by douglas
Content type: text/x-perl
File size: 3583 byte(s)
Log Message:
Switch to a different IMAP client API, grr!

File Contents

# Content
1 #!/usr/bin/perl
2 # Spam Update
3 #
4 # Douglas Thrift
5 #
6 # $Id$
7
8 use strict;
9 use warnings;
10
11 use IO::Socket::SSL;
12 use Mail::IMAPClient;
13 use IPC::Open2;
14 use Mail::SpamAssassin;
15 use MIME::Base64;
16
17 my $debug = 0;
18
19 for my $arg (@ARGV)
20 {
21 if ($arg eq "-debug")
22 {
23 $debug = 1;
24 }
25 else
26 {
27 print "Usage: $0 [-debug]\n";
28
29 exit 1;
30 }
31 }
32
33 my $negative = 'Spam.False Negative';
34 my $positive = 'Spam.False Positive';
35 my $spamc = '/usr/local/bin/spamc';
36
37 print "Information:
38 If you receive spam in your Inbox mailbox, copy it to the $negative mailbox.
39
40 If you receive mail that is not spam in your Spam mailbox, copy it to the $positive mailbox.
41 ";
42
43 my $socket = new IO::Socket::SSL(Proto => 'tcp', PeerAddr => 'mail.douglasthrift.net', PeerPort => 993) or die "$0: $@\n";
44 my $imap = new Mail::IMAPClient(Debug => $debug, Socket => $socket);
45
46 {
47 my $user = getpwuid $<;
48
49 open PASS, "$ENV{HOME}/.SpamUpdate.pass" or die "$0: $!\n";
50
51 my $pass = <PASS>;
52
53 chomp $pass;
54 close PASS;
55
56 $pass =~ tr/A-Za-z/N-ZA-Mn-za-m/;
57
58 $imap->User($user);
59 $imap->Password(decode_base64($pass));
60 }
61
62 sub error
63 {
64 die "$0: " . $imap->LastError;
65 }
66
67 $imap->login or error;
68
69 for my $job (new Job($negative), new Job($positive))
70 {
71 $imap->select($job->mailbox) or error;
72
73 printf '
74 %s and %s from the %s mailbox:
75 ', ucfirst $job->learning, $job->collabing, $job->mailbox;
76
77 my @messages = $imap->search('UNDELETED');
78
79 error if ($@);
80
81 my $total = 0;
82 my $learned = 0;
83 my $collabed = 0;
84
85 if ($#messages != -1)
86 {
87 for my $message (@messages)
88 {
89 my @result = $imap->fetch($message, '(BODY[])') or error;
90
91 die "$0: no message $message\n" if ($result[0] !~ /UID $message/);
92
93 my $body = $result[1];
94
95 ++$total;
96
97 my $learn = open2(\*LEARN_OUT, \*LEARN_IN, $spamc, '-L', $job->learn);
98 my $collab = open2(\*COLLAB_OUT, \*COLLAB_IN, $spamc, '-C', $job->collab);
99
100 print LEARN_IN $body;
101 print COLLAB_IN $body;
102 close LEARN_IN;
103 close COLLAB_IN;
104
105 my $learn_out = <LEARN_OUT>;
106 my $collab_out = <COLLAB_OUT>;
107
108 close LEARN_OUT;
109 close COLLAB_OUT;
110 chomp($learn_out, $collab_out);
111
112 print "learn_out = $learn_out\ncollab_out = $collab_out\n" if ($debug);
113
114 ++$learned if ($learn_out eq "Message successfully un/learned");
115 ++$collabed if ($collab_out eq "Message successfully reported/revoked");
116
117 $imap->delete_message($message) or error;
118
119 waitpid $learn, 0;
120 waitpid $collab, 0;
121 }
122 }
123
124 sub plural
125 {
126 my $number = shift;
127
128 return $number != 1 ? 's' : '';
129 }
130
131 printf " $learned message%s %s and $collabed message%s %s ($total message%s total).
132 ", plural($learned), $job->learned, plural($collabed), $job->collabed, plural($total);
133 }
134
135 $imap->logout or error;
136
137 {
138 package Job;
139
140 sub new
141 {
142 my $class = shift;
143 my $self = {};
144
145 $self->{mailbox} = shift;
146 $self->{negative} = $self->{mailbox} eq $negative;
147
148 bless $self, $class;
149 }
150
151 sub learning
152 {
153 my $self = shift;
154
155 return $self->_learn . 'ing';
156 }
157
158 sub collabing
159 {
160 my $self = shift;
161
162 return $self->_collab . 'ing';
163 }
164
165 sub learned
166 {
167 my $self = shift;
168
169 return $self->_learn . 'ed';
170 }
171
172 sub collabed
173 {
174 my $self = shift;
175
176 return $self->_collab . 'ed';
177 }
178
179 sub learn
180 {
181 my $self = shift;
182
183 return $self->{negative} ? 'spam' : 'ham';
184 }
185
186 sub collab
187 {
188 my $self = shift;
189
190 return $self->{negative} ? 'report' : 'revoke';
191 }
192
193 sub mailbox
194 {
195 my $self = shift;
196
197 return $self->{mailbox};
198 }
199
200 sub _learn
201 {
202 my $self = shift;
203
204 return ($self->{negative} ? '' : 'un') . 'learn';
205 }
206
207 sub _collab
208 {
209 my $self = shift;
210
211 return 're' . ($self->{negative} ? 'port' : 'vok');
212 }
213 }

Properties

Name Value
svn:executable *
svn:keywords Id