#!/usr/bin/perl -w =pod =head1 NAME getsadata - Determine ratio of spam to ham (via SpamAssassin) =head1 SYNOPSIS getsadata [--nosync | --sync] [--sa-learn=/path/to/sa-learn] [--output=/path/to/output | -o /path/to/output] [--ham=color] [--spam=color] [--format=format | -f format] By default, C will output a PNG to STDOUT. =head1 DESCRIPTION This program will run B to determine the number of messages which have been learned as ham or spam, and generate a little pie graph with GD::Graph::pie. If the B<--sync> option is given, SpamAssassin's Bayes database will be synchronized before attempting to grab statistics (via C). If the B<--format> option is given, output is set to that image format. If no argument is given, a list of supported formats is dumped to STDERR, and the program exits with a nonzero exit status. =head1 AUTHOR Johnny Cuervo =head1 LICENSE Public domain, 21 Dec 2007 =cut use GD::Graph::pie; use Getopt::Long; use Pod::Usage; sub check_good_format ($$) { my @formats = ${_[0]}->export_format; map { return 1 if ($_[1] eq $_) } @formats if ($_[1] ne ''); # # Not reached if we have a good format. # push @formats, "and " . pop @formats; # :-) exit print STDERR "GD::Graph says supported formats are ", join(", ", @formats), "\n(\"jpg\" is an alias for \"jpeg\")\n"; } # # main # my $sa_learn = "/usr/bin/sa-learn"; my $output = undef; my $ham_color = 'lgreen'; my $spam_color = 'dred'; my $sync = 0; my $fmt = 'png'; GetOptions( 'sync!' => \$sync, # Sync Bayes DB first 'sa-learn=s' => \$sa_learn, # Path to sa-learn 'output=s' => \$output, # Output file 'format:s' => \$fmt, # Image file format 'ham=s' => \$ham_color, 'spam=s' => \$spam_color, 'help' => sub { pod2usage('-exitstatus' => 0); }, ) || pod2usage('-exitstatus' => 1); my $graph = GD::Graph::pie->new; $fmt = 'jpeg' if ($fmt eq 'jpg'); check_good_format $graph, $fmt; # # Grab the output from sa-learn. I suppose the "right" way to do it would # be to go through Mail::SpamAssassin, but this is three lines of code, # versus however many /that/ would take # open SA, "$sa_learn --dump magic |"; while () { $$1 = (split /\s+/, $_)[2] if (/n(ham|spam)$/) } close SA; # # Got it, make the graph and bail # $total = $ham + $spam; $pcnt_h = sprintf("%.1f", ($ham / $total) * 100); $pcnt_s = sprintf("%.1f", ($spam / $total) * 100); @data = ( ["Ham ($pcnt_h\%)", "Spam ($pcnt_s\%)"], [$ham, $spam], ); $graph->set( 'title' => 'Signal-to-noise ratio', '3d' => 1, 'dclrs' => [ $ham_color, $spam_color ], ); $graph->set_value_font(GD::gdMediumBoldFont); $img = $graph->plot(\@data); if (defined $output) { die "Couldn't open $output for writing: $!" if (! open STDOUT, ">", $output); } print $img->$fmt; exit 0;