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 22     22   157 use strict;
  22         46  
  22         767  
36 22     22   150 use warnings;
  22         55  
  22         1045  
37             # use bytes;
38 22     22   149 use re 'taint';
  22         49  
  22         1000  
39              
40 22     22   136 use Mail::SpamAssassin;
  22         63  
  22         615  
41 22     22   140 use Mail::SpamAssassin::PerMsgStatus;
  22         55  
  22         686  
42 22     22   117 use Mail::SpamAssassin::Logger;
  22         67  
  22         1828  
43 22     22   144 use Mail::SpamAssassin::Util qw(untaint_var);
  22         56  
  22         15937  
44              
45             our @ISA = qw();
46              
47             ###########################################################################
48              
49             sub new {
50 64     64 0 182 my $class = shift;
51 64   33     401 $class = ref($class) || $class;
52              
53 64         178 my ($main) = @_;
54             my $self = {
55             'main' => $main,
56             'conf' => $main->{conf},
57 64         348 'use_ignores' => 1,
58             };
59 64         202 bless ($self, $class);
60              
61 64         423 $self->{main}->call_plugins("learner_new");
62 64         342 $self;
63             }
64              
65             ###########################################################################
66              
67             sub finish {
68 40     40 0 105 my $self = shift;
69             # we don't need to do the plugin; Mail::SpamAssassin::finish() does
70             # that for us
71 40         94 %{$self} = ();
  40         125  
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         9 my $quiet = shift;
83 6         19 $self->{main}->call_plugins("learner_close", { quiet => $quiet });
84             }
85              
86             ###########################################################################
87              
88             sub ignore_message {
89 14     14 0 50 my ($self,$PMS) = @_;
90              
91 14 50       46 return 0 unless $self->{use_ignores};
92              
93 14         127 my $ig_from = $self->{main}->call_plugins ("check_wb_list",
94             { permsgstatus => $PMS, type => 'from', list => 'bayes_ignore_from' });
95 14         107 my $ig_to = $self->{main}->call_plugins ("check_wb_list",
96             { permsgstatus => $PMS, type => 'to', list => 'bayes_ignore_to' });
97              
98 14   33     126 my $ignore = $ig_from || $ig_to;
99 14 50       50 dbg("bayes: not using bayes, bayes_ignore_from or _to rule") if $ignore;
100 14         46 return $ignore;
101             }
102              
103             ###########################################################################
104              
105             sub learn {
106 10     10 0 2112 my ($self, $isspam, $msg, $id) = @_;
107 10 50       55 return unless $self->{conf}->{use_learner};
108 10 50       33 return unless defined $msg;
109              
110 10 50       36 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         90 my $PMS = new Mail::SpamAssassin::PerMsgStatus $self->{main}, $msg;
115 10         56 my $ignore = $self->ignore_message($PMS);
116 10         77 $PMS->finish();
117 10 50       68 return 0 if $ignore;
118             }
119              
120 10         81 return $self->{main}->call_plugins("learn_message", { isspam => $isspam, msg => $msg, id => $id });
121             }
122              
123             ###########################################################################
124              
125             sub forget {
126 4     4 0 16 my ($self, $msg, $id) = @_;
127 4 50       21 return unless $self->{conf}->{use_learner};
128 4 50       14 return unless defined $msg;
129 4         26 return $self->{main}->call_plugins("forget_message", { msg => $msg, id => $id });
130             }
131              
132             ###########################################################################
133              
134             sub sync {
135 2     2 0 7 my ($self, $sync, $expire, $opts) = @_;
136 2 50       25 return 0 unless $self->{conf}->{use_learner};
137              
138 2 50       11 if ($sync) {
139 2         10 $self->{main}->call_plugins("learner_sync", $opts );
140             }
141 2 50       12 if ($expire) {
142 0         0 $self->{main}->call_plugins("learner_expire_old_training", $opts );
143             }
144              
145 2         11 return 0;
146             }
147              
148             ###########################################################################
149              
150             sub is_scan_available {
151 144     144 0 333 my $self = shift;
152 144 50       596 return 0 unless $self->{conf}->{use_learner};
153 144         518 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;