Mailing List Archive

svn commit: rev 6531 - in incubator/spamassassin/trunk/lib/Mail: . SpamAssassin
Author: jm
Date: Thu Feb 5 20:04:28 2004
New Revision: 6531

Modified:
incubator/spamassassin/trunk/lib/Mail/SpamAssassin.pm
incubator/spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm
incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm
Log:
added a whole load more plugin APIs, for scanning start/end events, autolearning, and when the user is changed

Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin.pm (original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin.pm Thu Feb 5 20:04:28 2004
@@ -578,6 +578,11 @@

$self->{conf}->set_score_set ($set);

+ $self->call_plugins ("signal_user_changed", {
+ username => $self->{username},
+ userdir => $self->{user_dir},
+ });
+
1;
}


Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm (original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm Thu Feb 5 20:04:28 2004
@@ -112,6 +112,13 @@
my ($self) = @_;
local ($_);

+ $self->{learned_hits} = 0;
+ $self->{body_only_hits} = 0;
+ $self->{head_only_hits} = 0;
+ $self->{hits} = 0;
+
+ $self->{main}->call_plugins ("check_start", { permsgstatus => $self });
+
# in order of slowness; fastest first, slowest last.
# we do ALL the tests, even if a spam triggers lots of them early on.
# this lets us see ludicrously spammish mails (score: 40) etc., which
@@ -123,11 +130,6 @@
# TVD: we may want to do more than just clearing out the headers, but ...
$self->{msg}->delete_header('X-Spam-.*');

- $self->{learned_hits} = 0;
- $self->{body_only_hits} = 0;
- $self->{head_only_hits} = 0;
- $self->{hits} = 0;
-
# Resident Mail::SpamAssassin code will possibly never change score
# sets, even if bayes becomes available. So we should do a quick check
# to see if we should go from {0,1} to {2,3}. We of course don't need
@@ -149,6 +151,9 @@
undef $decoded; # this is cached anyway for the main set
}

+ # allow plugins to add more metadata, read the stuff that's there, etc.
+ $self->{main}->call_plugins ("parsed_metadata", { permsgstatus => $self });
+
{
# Here, we launch all the DNS RBL queries and let them run while we
# inspect the message
@@ -229,6 +234,7 @@
$report =~ s/\n*$/\n\n/s;
$self->{report} = $report;

+ $self->{main}->call_plugins ("check_end", { permsgstatus => $self });
}

###########################################################################
@@ -331,6 +337,12 @@
}

dbg ("auto-learn? yes, ".($isspam?"spam ($hits > $max)":"ham ($hits < $min)"));
+
+ $self->{main}->call_plugins ("autolearn", {
+ permsgstatus => $self,
+ isspam => $isspam
+ });
+
eval {
my $learnstatus = $self->{main}->learn ($self->{msg}, undef, $isspam, 0);
$learnstatus->finish();
@@ -502,6 +514,19 @@

###########################################################################

+=item $msg = $status->get_message()
+
+Return the object representing the message being scanned.
+
+=cut
+
+sub get_message {
+ my ($self) = @_;
+ return $self->{msg};
+}
+
+###########################################################################
+
=item $status->rewrite_mail ()

Rewrite the mail message. This will at minimum add headers, and at
@@ -881,6 +906,10 @@

sub finish {
my ($self) = @_;
+
+ $self->{main}->call_plugins ("per_msg_finish", {
+ permsgstatus => $self
+ });

delete $self->{body_text_array};
delete $self->{main};

Modified: incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm
==============================================================================
--- incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm (original)
+++ incubator/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm Thu Feb 5 20:04:28 2004
@@ -61,11 +61,26 @@
later plugins in the chain. This is useful if the plugin has handled the
event, and there will be no need for later plugins to handle it as well.

+=head1 INTERFACE
+
+In all the plugin APIs below, C<options> refers to a reference to a hash
+containing name-value pairs. This is used to ensure future-compatibility, in
+that we can add new options in future without affecting objects built to an
+earlier version of the API.
+
+For example, here would be how to print out the C<line> item in a
+C<parse_config()> method:
+
+ sub parse_config {
+ my ($self, $opts) = @_;
+ print "MyPlugin: parse_config got ".$opts->{line}."\n";
+ }
+
+=head1 METHODS
+
The following methods can be overridden by subclasses to handle events
that SpamAssassin will call back to:

-=head1 INTERFACE
-
=over 4

=cut
@@ -115,6 +130,7 @@
$self;
}

+# ---------------------------------------------------------------------------
=item $plugin->parse_config ( { options ... } )

Parse a configuration line that hasn't already been handled. C<options>
@@ -150,10 +166,146 @@

sub parse_config {
my ($self, $opts) = @_;
- # implemented by subclasses, no-op by default
- return 0;
+ return 0; # implemented by subclasses, no-op by default
+}
+
+# ---------------------------------------------------------------------------
+=item $plugin->signal_user_changed ( { options ... } )
+
+Signals that the current user has changed for a new one.
+
+=over 4
+
+=item username
+
+The new user's username.
+
+=item user_dir
+
+The new user's storage directory.
+
+=back
+
+=cut
+
+sub signal_user_changed {
+ my ($self, $opts) = @_;
+ return 0; # implemented by subclasses, no-op by default
+}
+
+# ---------------------------------------------------------------------------
+=item $plugin->check_start ( { options ... } )
+
+Signals that a message check operation is starting.
+
+=over 4
+
+=item permsgstatus
+
+The C<Mail::SpamAssassin::PerMsgStatus> context object for this scan.
+
+=back
+
+=cut
+
+sub check_start {
+ my ($self, $opts) = @_;
+ return 0; # implemented by subclasses, no-op by default
+}
+
+# ---------------------------------------------------------------------------
+=item $plugin->parsed_metadata ( { options ... } )
+
+Signals that a message's metadata has been parsed, and can now be
+accessed, or supplemented, by the plugin.
+
+=over 4
+
+=item permsgstatus
+
+The C<Mail::SpamAssassin::PerMsgStatus> context object for this scan. (Note
+that the message being scanned is accessible through the
+C<$permsgstatus->get_message()> API.)
+
+=back
+
+=cut
+
+sub parsed_metadata {
+ my ($self, $opts) = @_;
+ return 0; # implemented by subclasses, no-op by default
+}
+
+# ---------------------------------------------------------------------------
+=item $plugin->check_end ( { options ... } )
+
+Signals that a message check operation has just finished, and the
+results are about to be returned to the caller.
+
+=over 4
+
+=item permsgstatus
+
+The C<Mail::SpamAssassin::PerMsgStatus> context object for this scan.
+The current hits, names of rules that hit, etc. can be retrieved
+using the APIs on this object.
+
+=back
+
+=cut
+
+sub check_end {
+ my ($self, $opts) = @_;
+ return 0; # implemented by subclasses, no-op by default
+}
+
+# ---------------------------------------------------------------------------
+=item $plugin->autolearn ( { options ... } )
+
+Signals that a message is about to be auto-learned as either ham or spam.
+
+=over 4
+
+=item permsgstatus
+
+The C<Mail::SpamAssassin::PerMsgStatus> context object for this scan.
+
+=item isspam
+
+C<1> if the message is spam, C<0> if ham.
+
+=back
+
+=cut
+
+sub autolearn {
+ my ($self, $opts) = @_;
+ return 0; # implemented by subclasses, no-op by default
+}
+
+# ---------------------------------------------------------------------------
+=item $plugin->per_msg_finish ( { options ... } )
+
+Signals that a C<Mail::SpamAssassin::PerMsgStatus> object is being
+destroyed, and any per-scan context held on that object by this
+plugin should be destroyed as well.
+
+=over 4
+
+=item permsgstatus
+
+The C<Mail::SpamAssassin::PerMsgStatus> context object for this scan.
+
+=back
+
+=cut
+
+sub per_msg_finish {
+ my ($self, $opts) = @_;
+ return 0; # implemented by subclasses, no-op by default
}

+# ---------------------------------------------------------------------------
=item $plugin->finish ()

Called when the C<Mail::SpamAssassin> object is destroyed.