CPAN-Testers-WWW-Statistics
view release on metacpan or search on metacpan
lib/CPAN/Testers/WWW/Statistics/Graphs.pm view on Meta::CPAN
package CPAN::Testers::WWW::Statistics::Graphs;
use warnings;
use strict;
use vars qw($VERSION);
$VERSION = '1.23';
#----------------------------------------------------------------------------
=head1 NAME
CPAN::Testers::WWW::Statistics::Graphs - CPAN Testers Statistics graphs.
=head1 SYNOPSIS
my %hash = { config => 'options' };
my $obj = CPAN::Testers::WWW::Statistics->new(%hash);
my $ct = CPAN::Testers::WWW::Statistics::Graphs->new(parent => $obj);
$ct->create();
=head1 DESCRIPTION
Using previously formatted data, generate graphs using the Google Chart API.
Note that this package should not be called directly, but via its parent as:
my %hash = { config => 'options' };
my $obj = CPAN::Testers::WWW::Statistics->new(%hash);
$obj->make_graphs();
=cut
# -------------------------------------
# Library Modules
use File::Basename;
use File::Path;
use HTML::Entities;
use IO::File;
use LWP::UserAgent;
use HTTP::Request;
# -------------------------------------
# Variables
my %month = (
0 => 'January', 1 => 'February', 2 => 'March', 3 => 'April',
4 => 'May', 5 => 'June', 6 => 'July', 7 => 'August',
8 => 'September', 9 => 'October', 10 => 'November', 11 => 'December'
);
my ($backg,$foreg) = ('black','white');
my @graphs = (
['stats/stats1' ,'CPAN Testers Statistics - Reports' ,[qw(UPLOADS REPORTS PASS FAIL)],'TEST_RANGES' ,'month'],
['stats/stats2' ,'CPAN Testers Statistics - Attributes' ,[qw(TESTERS PLATFORMS PERLS)] ,'TEST_RANGES' ,'month'],
['stats/stats3' ,'CPAN Testers Statistics - Non-Passes' ,[qw(FAIL NA UNKNOWN)] ,'TEST_RANGES' ,'month'],
['stats/stats4' ,'CPAN Testers Statistics - Testers' ,[qw(ALL FIRST LAST)] ,'TEST_RANGES' ,'month'],
['stats/stats6' ,'CPAN Statistics - Uploads' ,[qw(AUTHORS DISTROS)] ,'CPAN_RANGES' ,'month'],
['stats/stats12' ,'CPAN Statistics - New Uploads' ,[qw(AUTHORS DISTROS)] ,'CPAN_RANGES' ,'month'],
['stats/build1' ,'CPAN Testers Performance Graph' ,[qw(REQUESTS PAGES REPORTS)] ,'NONE' ,'daily'],
['stats/pcent1' ,'CPAN Testers Statistics - Percentages' ,[qw(FAIL OTHER PASS)] ,'TEST_RANGES' ,'month'],
['rates/submit1' ,'CPAN Submissions - By Month' ,[qw(EXCLUSIVE INCLUSIVE)] ,'NONE' ,'index'],
['rates/submit2' ,'CPAN Submissions - By Day of the Week' ,[qw(EXCLUSIVE INCLUSIVE)] ,'NONE' ,'index'],
['rates/submit3' ,'CPAN Submissions - By Day of the Month' ,[qw(EXCLUSIVE INCLUSIVE)] ,'NONE' ,'index'],
['rates/submit4' ,'CPAN Submissions - By Hour' ,[qw(EXCLUSIVE INCLUSIVE)] ,'NONE' ,'index'],
);
my $lwp = LWP::UserAgent->new();
$lwp->agent( 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624' );
my $chart_api = 'http://chart.apis.google.com/chart?chs=640x300&cht=lc';
my $chart_titles = 'chtt=%s&chdl=%s';
my $chart_labels = 'chxt=x,x,y,r&chxl=0:|%s|1:|%s|2:|%s|3:|%s';
my $chart_data = 'chd=t:%s';
my $chart_colour = 'chco=%s';
my $chart_filler = 'chf=bg,s,dddddd';
my %COLOURS = (
white => [255,255,255],
black => [0,0,0],
red => [255,0,0],
blue => [0,0,255],
purple => [230,0,230],
green => [0,255,0],
grey => [128,128,128],
light_grey => [170,170,170],
dark_grey => [75,75,75],
cream => [200,200,240],
yellow => [255,255,0],
orange => [255,128,0],
);
my @COLOURS = map {sprintf "%s%s%s", _dec2hex($COLOURS{$_}->[0]),_dec2hex($COLOURS{$_}->[1]),_dec2hex($COLOURS{$_}->[2])} qw(red blue green orange purple grey);
my @MONTH = qw( - JANUARY FEBRUARY MARCH APRIL MAY JUNE JULY AUGUST SEPTEMBER OCTOBER NOVEMBER DECEMBER );
my @MONTHS = map {my @x = split(//); my $x = join(' ',@x); [split(//,$x)]} @MONTH;
# -------------------------------------
# Subroutines
=head1 INTERFACE
lib/CPAN/Testers/WWW/Statistics/Graphs.pm view on Meta::CPAN
=cut
sub new {
my $class = shift;
my %hash = @_;
die "Must specify the parent statistics object\n" unless(defined $hash{parent});
my $self = {parent => $hash{parent}};
bless $self, $class;
$self->{parent}->_log("GRAPHS: new");
return $self;
}
=head2 Methods
=over 4
=item * create
Method to facilitate the creation of graphs.
=back
=cut
sub create {
my $self = shift;
my $status = 0; # assume success
my $directory = $self->{parent}->directory;
$self->{parent}->_log("create start");
for my $g (@graphs) {
my $results = "$directory/$g->[0]";
my ($path,$file) = (dirname($results),basename($results));
mkpath($path);
$g->[0] = $file;
$g->[5] = $path;
my $ranges = $self->{parent}->ranges($g->[3]);
$self->{parent}->_log("writing graph - got range [$g->[3]] = " . (scalar(@$ranges)) . ", latest=$ranges->[-1]");
my $latest = $ranges->[-1];
for my $r (@$ranges) {
$self->{parent}->_log("writing graph - $g->[0]-$r");
my $url = $self->_make_graph($r,@$g);
next unless($url);
$self->{parent}->_log("url - [".(length $url)."] $url");
# print "$url\n";
my $res;
eval {
my $req = HTTP::Request->new(GET => $url);
$res = $lwp->request($req);
};
if($@ || !$res->is_success()) {
$file = "$results-$r.html";
$self->{parent}->_log("FAIL: $0 - Cannot access page - see '$file' [$url] [" . length($url) . "] [$@]\n");
_save_content($res,$file);
$status = 1;
} elsif($res->header('Content-Type') =~ /html/) {
$file = "$results-$r.html";
$self->{parent}->_log("FAIL: $0 - request failed - see '$file'\n");
_save_content($res,$file);
$status = 1;
} else {
$file = "$results-$r.png";
_save_content($res,$file);
if($r eq $latest) {
$file = "$results.png";
_save_content($res,$file);
}
}
}
}
$self->{parent}->_log("finish = $status");
return $status;
}
sub _save_content {
my ($res,$file) = @_;
my $fh = IO::File->new(">$file") or die "$0 - Cannot write file [$file]: $!\n";
binmode($fh) if($file =~ /\.png$/);
print $fh $res->content;
$fh->close;
}
#=item _make_graph
#
#Creates and writes out a single graph.
#
#=cut
sub _make_graph {
my ($self,$r,$file,$title,$legend,$rcode,$type,$path) = @_;
my (@dates1,@dates2);
my $yr = 0;
my @data = $self->_get_data("$path/$file.txt",$r);
#use Data::Dumper;
#print STDERR "#type=$type, file=$file.txt, data=".Dumper(\@data);
$self->{parent}->_log("checkpoint 1");
return unless(@data);
$self->{parent}->_log("checkpoint 2");
for my $date (@{$data[0]}) {
if($type eq 'index') {
push @dates1, "'";
push @dates2, $date;
( run in 1.454 second using v1.01-cache-2.11-cpan-437f7b0c052 )