Ticker1.pm
package Ticker1;
use strict;
use warnings;
use base 'Mail::SpamAssassin::Plugin';
use Mail::SpamAssassin::Logger qw(:DEFAULT log_message);
sub new {
my ( $class, $mailsa ) = @_;
$class = ref($class) || $class;
my $self = $class->SUPER::new($mailsa);
bless $self, $class;
### register the eval rule
$self->register_eval_rule("check_stockspam");
### store configuration on $conf
my $conf = $self->{main}->{conf};
my $ticker_conf = $conf->{Ticker1} ||= {};
### initialize list of symbols
$ticker_conf->{symbols} = {};
return $self;
}
my $stock_token_regex = qr{
(?:\b|_) # word boundary, or _
(?i:Inc|Corp(?:oration)?|Gr[0o]up) # "inc" or something
[.,]? # optional dot or comma
\s*\n # match to end of line
^\s*(?i:Sym\w*\s*:\s*)? # next line optional sym(bol):
( # start capture
(?:[A-Z]\s{0,3}){3} # match three letters, optional spaces
[A-Z] # match last letter
) # end capture
\s*$ # match until end of line
}xsm;
sub parse_config {
my ( $self, $opts ) = @_;
my $key = $opts->{key};
my $value = $opts->{value};
my $ticker_conf = $self->{main}->{conf}->{Ticker1};
if ( $key eq "ticker_symbol" ) {
### ticker symbol can be list of words
for my $w ( split ' ', $value ) {
if ( $w !~ /^[A-Z]{4}$/ ) {
log_message( "warn", "Ticker1: Invalid ticker symbol: $w" );
next;
}
dbg("Ticker1: Adding ticker symbol $w");
$ticker_conf->{symbols}{$w} = 1;
}
$self->inhibit_further_callbacks();
}
}
sub check_stockspam {
my ( $self, $per_msg_status, $body_ref ) = @_;
my $ticker_conf = $self->{main}->{conf}->{Ticker1};
my $symbol_ref = $ticker_conf->{symbols};
my $msg_text = join( '', @$body_ref );
dbg("Ticker1: check_stockspam called");
while ( my ($possible_symbol) = $msg_text =~ /$stock_token_regex/ ) {
### trim all non-letters
$possible_symbol =~ tr/A-Za-z//cd;
dbg("Ticker1: testing possible symbol: $possible_symbol");
return 1 if exists $symbol_ref->{$possible_symbol};
}
return 0;
}
1;