File Coverage

blib/lib/Mail/SpamAssassin/Bayes.pm
Criterion Covered Total %
statement 63 67 94.0
branch 12 26 46.1
condition 2 6 33.3
subroutine 15 16 93.7
pod 0 9 0.0
total 92 124 74.1


line stmt bran cond sub pod time code
1             # <@LICENSE>
2             # Licensed to the Apache Software Foundation (ASF) under one or more
3             # contributor license agreements. See the NOTICE file distributed with
4             # this work for additional information regarding copyright ownership.
5             # The ASF licenses this file to you under the Apache License, Version 2.0
6             # (the "License"); you may not use this file except in compliance with
7             # the License. You may obtain a copy of the License at:
8             #
9             # http://www.apache.org/licenses/LICENSE-2.0
10             #
11             # Unless required by applicable law or agreed to in writing, software
12             # distributed under the License is distributed on an "AS IS" BASIS,
13             # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14             # See the License for the specific language governing permissions and
15             # limitations under the License.
16             # </@LICENSE>
17              
18             =head1 NAME
19              
20             Mail::SpamAssassin::Bayes - support for learning classifiers
21              
22             =head1 DESCRIPTION
23              
24             This is the general class used to train a learning classifier with new samples
25             of spam and ham mail, and classify based on prior training.
26              
27             Prior to version 3.3.0, the default Bayes implementation was here; if you're
28             looking for information on that, it has moved to
29             C<Mail::SpamAssassin::Plugin::Bayes>.
30              
31             =cut
32              
33             package Mail::SpamAssassin::Bayes;
34              
35 21     21   169 use strict;
  21         54  
  21         902  
36 21     21   134 use warnings;
  21         45  
  21         827  
37             # use bytes;
38 21     21   128 use re 'taint';
  21         48  
  21         873  
39              
40 21     21   136 use Mail::SpamAssassin;
  21         43  
  21         662  
41 21     21   120 use Mail::SpamAssassin::PerMsgStatus;
  21         44  
  21         432  
42 21     21   116 use Mail::SpamAssassin::Logger;
  21         43  
  21         1575  
43 21     21   145 use Mail::SpamAssassin::Util qw(untaint_var);
  21         42  
  21         12559  
44              
45             our @ISA = qw();
46              
47             ###########################################################################
48              
49             sub new {
50 63     63 0 215 my $class = shift;
51 63   33     402 $class = ref($class) || $class;
52              
53 63         207 my ($main) = @_;
54             my $self = {
55             'main' => $main,
56             'conf' => $main->{conf},
57 63         368 'use_ignores' => 1,
58             };
59 63         228 bless ($self, $class);
60              
61 63         370 $self->{main}->call_plugins("learner_new");
62 63         338 $self;
63             }
64              
65             ###########################################################################
66              
67             sub finish {
68 40     40 0 98 my $self = shift;
69             # we don't need to do the plugin; Mail::SpamAssassin::finish() does
70             # that for us
71 40         81 %{$self} = ();
  40         129  
72             }
73              
74             ###########################################################################
75              
76             # force the Bayes dbs to be closed, if they haven't already been; called
77             # at the end of scan operation, or when switching between user IDs,
78             # or when C<Mail::SpamAssassin::finish_learner()> is called.
79             #
80             sub force_close {
81 6     6 0 13 my $self = shift;
82 6         10 my $quiet = shift;
83 6         25 $self->{main}->call_plugins("learner_close", { quiet => $quiet });
84             }
85              
86             ###########################################################################
87              
88             sub ignore_message {
89 14     14 0 46 my ($self,$PMS) = @_;
90              
91 14 50       66 return 0 unless $self->{use_ignores};
92              
93 14         133 my $ig_from = $self->{main}->call_plugins ("check_wb_list",
94             { permsgstatus => $PMS, type => 'from', list => 'bayes_ignore_from' });
95 14         123 my $ig_to = $self->{main}->call_plugins ("check_wb_list",
96             { permsgstatus => $PMS, type => 'to', list => 'bayes_ignore_to' });
97              
98 14   33     122 my $ignore = $ig_from || $ig_to;
99 14 50       49 dbg("bayes: not using bayes, bayes_ignore_from or _to rule") if $ignore;
100 14         49 return $ignore;
101             }
102              
103             ###########################################################################
104              
105             sub learn {
106 10     10 0 2285 my ($self, $isspam, $msg, $id) = @_;
107 10 50       56 return unless $self->{conf}->{use_learner};
108 10 50       37 return unless defined $msg;
109              
110 10 50       44 if( $self->{use_ignores} ) # Remove test when PerMsgStatus available.
111             {
112             # DMK, koppel@ece.lsu.edu: Hoping that the ultimate fix to bug 2263 will
113             # make it unnecessary to construct a PerMsgStatus here.
114 10         103 my $PMS = new Mail::SpamAssassin::PerMsgStatus $self->{main}, $msg;
115 10         51 my $ignore = $self->ignore_message($PMS);
116 10         68 $PMS->finish();
117 10 50       73 return 0 if $ignore;
118             }
119              
120 10         87 return $self->{main}->call_plugins("learn_message", { isspam => $isspam, msg => $msg, id => $id });
121             }
122              
123             ###########################################################################
124              
125             sub forget {
126 4     4 0 14 my ($self, $msg, $id) = @_;
127 4 50       21 return unless $self->{conf}->{use_learner};
128 4 50       17 return unless defined $msg;
129 4         30 return $self->{main}->call_plugins("forget_message", { msg => $msg, id => $id });
130             }
131              
132             ###########################################################################
133              
134             sub sync {
135 2     2 0 8 my ($self, $sync, $expire, $opts) = @_;
136 2 50       11 return 0 unless $self->{conf}->{use_learner};
137              
138 2 50       8 if ($sync) {
139 2         19 $self->{main}->call_plugins("learner_sync", $opts );
140             }
141 2 50       10 if ($expire) {
142 0         0 $self->{main}->call_plugins("learner_expire_old_training", $opts );
143             }
144              
145 2         13 return 0;
146             }
147              
148             ###########################################################################
149              
150             sub is_scan_available {
151 143     143 0 352 my $self = shift;
152 143 50       566 return 0 unless $self->{conf}->{use_learner};
153 143         545 return $self->{main}->call_plugins("learner_is_scan_available");
154             }
155              
156             ###########################################################################
157              
158             sub dump_bayes_db {
159 0     0 0   my($self, $magic, $toks, $regex) = @_;
160 0 0         return 0 unless $self->{conf}->{use_learner};
161 0           return $self->{main}->call_plugins("learner_dump_database", {
162             magic => $magic, toks => $toks, regex => $regex });
163             }
164              
165             1;