| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package CPAN::Testers::WWW::Reports::Parser; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 6 |  |  | 6 |  | 86834 | use strict; | 
|  | 6 |  |  |  |  | 12 |  | 
|  | 6 |  |  |  |  | 207 |  | 
| 4 | 6 |  |  | 6 |  | 25 | use warnings; | 
|  | 6 |  |  |  |  | 10 |  | 
|  | 6 |  |  |  |  | 243 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 | 6 |  |  | 6 |  | 24 | use vars qw($VERSION); | 
|  | 6 |  |  |  |  | 13 |  | 
|  | 6 |  |  |  |  | 359 |  | 
| 7 |  |  |  |  |  |  | $VERSION = '0.06'; | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | #---------------------------------------------------------------------------- | 
| 10 |  |  |  |  |  |  | # Library Modules | 
| 11 |  |  |  |  |  |  |  | 
| 12 | 6 |  |  | 6 |  | 35 | use Carp; | 
|  | 6 |  |  |  |  | 8 |  | 
|  | 6 |  |  |  |  | 3118 |  | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | #---------------------------------------------------------------------------- | 
| 15 |  |  |  |  |  |  | # Variables | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | my $WEB = 'http://www.cpantesters.org/cpan/report/'; | 
| 18 |  |  |  |  |  |  | my @valid_fields = qw(  id distribution dist distname version distversion perl | 
| 19 |  |  |  |  |  |  | state status grade action osname ostext osvers platform | 
| 20 |  |  |  |  |  |  | archname url csspatch cssperl guid ); | 
| 21 |  |  |  |  |  |  | my %valid_fields = map {$_ => 1} @valid_fields; | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | #---------------------------------------------------------------------------- | 
| 24 |  |  |  |  |  |  | # The Application Programming Interface | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | sub new { | 
| 27 | 8 |  |  | 8 | 1 | 4205 | my $class = shift; | 
| 28 | 8 |  |  |  |  | 25 | my %hash  = @_; | 
| 29 |  |  |  |  |  |  |  | 
| 30 | 8 | 100 |  |  |  | 172 | croak "No data format specified\n"                      unless($hash{format}); | 
| 31 | 7 | 100 |  |  |  | 123 | croak "Unknown data format specified\n"                 unless($hash{format} =~ /^(yaml|json)$/i); | 
| 32 | 6 | 100 | 100 |  |  | 120 | croak "Must specify a file or data block to parse\n"    unless($hash{data} || $hash{file}); | 
| 33 | 5 | 100 | 100 |  |  | 180 | croak "Cannot access file [$hash{file}]\n"              if(defined $hash{file} && ! -f $hash{file}); | 
| 34 |  |  |  |  |  |  |  | 
| 35 | 4 |  |  |  |  | 23 | my $self = { | 
| 36 |  |  |  |  |  |  | 'format'    => uc $hash{'format'}, | 
| 37 |  |  |  |  |  |  | 'data'      =>    $hash{'data'}, | 
| 38 |  |  |  |  |  |  | 'file'      =>    $hash{'file'}, | 
| 39 |  |  |  |  |  |  | 'objects'   =>    $hash{'objects'}, | 
| 40 |  |  |  |  |  |  | }; | 
| 41 | 4 |  |  |  |  | 15 | bless $self, $class; | 
| 42 |  |  |  |  |  |  |  | 
| 43 | 4 | 100 |  |  |  | 14 | if($self->{objects}) { | 
| 44 | 1 |  |  | 1 |  | 64 | eval "use CPAN::Testers::WWW::Reports::Report"; | 
|  | 1 |  |  |  |  | 547 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 18 |  | 
| 45 |  |  |  |  |  |  | } | 
| 46 |  |  |  |  |  |  |  | 
| 47 | 4 |  |  |  |  | 12 | my $parser = 'CPAN::Testers::WWW::Reports::Parser::' . $self->{'format'}; | 
| 48 | 4 |  |  | 1 |  | 260 | eval "use $parser"; | 
|  | 1 |  |  | 1 |  | 478 |  | 
|  | 1 |  |  | 1 |  | 2 |  | 
|  | 1 |  |  | 1 |  | 16 |  | 
|  | 1 |  |  |  |  | 4 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 11 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 12 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 10 |  | 
| 49 | 4 | 50 |  |  |  | 12 | croak "Cannot access $self->{'format'} parser, have you installed the necessary support modules?\n" | 
| 50 |  |  |  |  |  |  | if($@); | 
| 51 |  |  |  |  |  |  |  | 
| 52 | 4 |  |  |  |  | 16 | $self->{parser} = $parser->new(); | 
| 53 | 4 |  |  |  |  | 20 | $self->{parser}->register( file => $self->{file}, data => $self->{data} ); | 
| 54 | 4 |  |  |  |  | 6 | $self->{current} = {}; | 
| 55 |  |  |  |  |  |  |  | 
| 56 | 4 |  |  |  |  | 9 | return $self; | 
| 57 |  |  |  |  |  |  | } | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | sub DESTROY { | 
| 60 | 4 |  |  | 4 |  | 8482 | my $self = shift; | 
| 61 |  |  |  |  |  |  | } | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | sub filter { | 
| 64 | 13 |  |  | 13 | 1 | 6803 | my $self = shift; | 
| 65 |  |  |  |  |  |  |  | 
| 66 | 13 | 100 |  |  |  | 40 | if(@_) { | 
| 67 | 9 | 100 |  |  |  | 37 | $self->{all} = $_[0] =~ /^ALL$/i ? shift : 0; | 
| 68 | 9 |  |  |  |  | 24 | $self->{fields}{$_} = 1 for(grep {$valid_fields{$_}} @_); | 
|  | 51 |  |  |  |  | 136 |  | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | # if no arguments, reset to default | 
| 71 |  |  |  |  |  |  | } else { | 
| 72 | 4 |  |  |  |  | 8 | $self->{all} = 1; | 
| 73 | 4 |  |  |  |  | 10 | $self->{fields} = {}; | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  | } | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | # full data set methods | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | sub reports { | 
| 80 | 9 |  |  | 9 | 1 | 13109 | my $self = shift; | 
| 81 |  |  |  |  |  |  |  | 
| 82 | 9 | 100 |  |  |  | 41 | $self->filter(@_)  if(@_); | 
| 83 |  |  |  |  |  |  |  | 
| 84 |  |  |  |  |  |  | #use Data::Dumper; | 
| 85 |  |  |  |  |  |  | #print STDERR (Dumper($self->{fields})); | 
| 86 |  |  |  |  |  |  |  | 
| 87 | 9 |  |  |  |  | 41 | my $data = $self->{parser}->raw_data(); | 
| 88 | 9 | 100 |  |  |  | 61 | return $data    unless(defined $self->{fields}); | 
| 89 |  |  |  |  |  |  |  | 
| 90 | 6 |  |  | 6 |  | 33 | no strict 'refs'; | 
|  | 6 |  |  |  |  | 7 |  | 
|  | 6 |  |  |  |  | 1328 |  | 
| 91 |  |  |  |  |  |  |  | 
| 92 | 6 |  |  |  |  | 19 | for my $report (@$data) { | 
| 93 | 3222 |  |  |  |  | 2830 | $self->{current} = $report; | 
| 94 | 3222 |  |  |  |  | 2400 | for my $field (keys %{ $self->{fields} }) { | 
|  | 3222 |  |  |  |  | 4805 |  | 
| 95 |  |  |  |  |  |  | #print STDERR "field=$field\n"; | 
| 96 | 12888 |  |  |  |  | 8823 | eval { $report->{$field} = $self->$field(); }; | 
|  | 12888 |  |  |  |  | 15140 |  | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  |  | 
| 99 | 3222 | 100 |  |  |  | 6272 | next    if($self->{all}); | 
| 100 |  |  |  |  |  |  |  | 
| 101 | 1611 |  |  |  |  | 4486 | for my $key (keys %$report) { | 
| 102 | 28998 | 100 |  |  |  | 46180 | delete $report->{$key}  unless($self->{fields}{$key}); | 
| 103 |  |  |  |  |  |  | } | 
| 104 |  |  |  |  |  |  | } | 
| 105 |  |  |  |  |  |  |  | 
| 106 | 6 |  |  |  |  | 27 | return $data; | 
| 107 |  |  |  |  |  |  | } | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  |  | 
| 110 |  |  |  |  |  |  | # iterate through data set | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | sub report { | 
| 113 | 545 |  |  | 545 | 1 | 2514 | my $self = shift; | 
| 114 |  |  |  |  |  |  |  | 
| 115 | 545 | 100 |  |  |  | 768 | unless($self->{loaded}) { | 
| 116 | 8 |  |  |  |  | 37 | $self->{reports} = $self->{parser}->raw_data(); | 
| 117 | 8 |  |  |  |  | 2241 | $self->{loaded} = 1; | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  |  | 
| 120 | 545 | 100 |  |  |  | 370 | return  unless(scalar(@{ $self->{reports} })); | 
|  | 545 |  |  |  |  | 831 |  | 
| 121 |  |  |  |  |  |  |  | 
| 122 | 544 |  |  |  |  | 360 | $self->{current} = shift @{ $self->{reports} }; | 
|  | 544 |  |  |  |  | 622 |  | 
| 123 | 544 |  |  |  |  | 1047 | my %report = map {$_ => $self->{current}{$_}} keys %{$self->{current}}; | 
|  | 8160 |  |  |  |  | 10512 |  | 
|  | 544 |  |  |  |  | 1564 |  | 
| 124 |  |  |  |  |  |  |  | 
| 125 | 544 | 100 |  |  |  | 1169 | if(scalar(keys %{ $self->{fields} })) { | 
|  | 544 |  |  |  |  | 886 |  | 
| 126 | 6 |  |  | 6 |  | 28 | no strict 'refs'; | 
|  | 6 |  |  |  |  | 12 |  | 
|  | 6 |  |  |  |  | 3454 |  | 
| 127 |  |  |  |  |  |  |  | 
| 128 | 3 |  |  |  |  | 4 | for my $field (keys %{ $self->{fields} }) { | 
|  | 3 |  |  |  |  | 10 |  | 
| 129 | 27 |  |  |  |  | 20 | eval { $report{$field} = $self->$field(); }; | 
|  | 27 |  |  |  |  | 64 |  | 
| 130 |  |  |  |  |  |  | } | 
| 131 |  |  |  |  |  |  |  | 
| 132 | 3 | 100 |  |  |  | 14 | unless($self->{all}) { | 
| 133 | 2 |  |  |  |  | 10 | for my $key (keys %report) { | 
| 134 | 38 | 100 |  |  |  | 67 | delete $report{$key}  unless($self->{fields}{$key}); | 
| 135 |  |  |  |  |  |  | } | 
| 136 |  |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  | } | 
| 138 |  |  |  |  |  |  |  | 
| 139 | 544 | 100 |  |  |  | 781 | if($self->{objects}) { | 
| 140 | 1 |  |  |  |  | 11 | my $rep = CPAN::Testers::WWW::Reports::Report->new(\%report); | 
| 141 | 1 |  |  |  |  | 5 | return $rep; | 
| 142 |  |  |  |  |  |  | } | 
| 143 |  |  |  |  |  |  |  | 
| 144 | 543 |  |  |  |  | 788 | return \%report; | 
| 145 |  |  |  |  |  |  | } | 
| 146 |  |  |  |  |  |  |  | 
| 147 |  |  |  |  |  |  | sub reload { | 
| 148 | 4 |  |  | 4 | 1 | 4659 | my $self = shift; | 
| 149 | 4 |  |  |  |  | 9 | $self->{loaded} = 0; | 
| 150 |  |  |  |  |  |  | } | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  | # transpose legacy field names to current field names | 
| 154 |  |  |  |  |  |  |  | 
| 155 | 0 |  |  | 0 | 1 | 0 | sub guid         { my $self = shift; return $self->{current}->{guid}         } | 
|  | 0 |  |  |  |  | 0 |  | 
| 156 | 2 |  |  | 2 | 1 | 9 | sub id           { my $self = shift; return $self->{current}->{id}           } | 
|  | 2 |  |  |  |  | 8 |  | 
| 157 | 2 |  |  | 2 | 1 | 443 | sub distribution { my $self = shift; return $self->{current}->{distribution} } | 
|  | 2 |  |  |  |  | 7 |  | 
| 158 | 2 |  |  | 2 | 1 | 480 | sub dist         { my $self = shift; return $self->{current}->{distribution} } | 
|  | 2 |  |  |  |  | 8 |  | 
| 159 | 3226 |  |  | 3226 | 1 | 2602 | sub distname     { my $self = shift; return $self->{current}->{distribution} } | 
|  | 3226 |  |  |  |  | 5595 |  | 
| 160 | 3226 |  |  | 3226 | 1 | 2765 | sub version      { my $self = shift; return $self->{current}->{version}      } | 
|  | 3226 |  |  |  |  | 6123 |  | 
| 161 | 2 |  |  | 2 | 1 | 416 | sub distversion  { my $self = shift; return $self->{current}->{distversion}  } | 
|  | 2 |  |  |  |  | 7 |  | 
| 162 | 2 |  |  | 2 | 1 | 412 | sub perl         { my $self = shift; return $self->{current}->{perl}         } | 
|  | 2 |  |  |  |  | 7 |  | 
| 163 |  |  |  |  |  |  |  | 
| 164 | 2 |  |  | 2 | 1 | 377 | sub state        { my $self = shift; return $self->{current}->{state}        } | 
|  | 2 |  |  |  |  | 7 |  | 
| 165 | 2 |  |  | 2 | 1 | 376 | sub status       { my $self = shift; return $self->{current}->{status}       } | 
|  | 2 |  |  |  |  | 8 |  | 
| 166 | 3226 |  |  | 3226 | 1 | 2640 | sub grade        { my $self = shift; return $self->{current}->{status}       } | 
|  | 3226 |  |  |  |  | 6853 |  | 
| 167 | 2 |  |  | 2 | 1 | 387 | sub action       { my $self = shift; return $self->{current}->{status}       } | 
|  | 2 |  |  |  |  | 8 |  | 
| 168 |  |  |  |  |  |  |  | 
| 169 | 2 |  |  | 2 | 1 | 407 | sub osname       { my $self = shift; return $self->{current}->{osname}       } | 
|  | 2 |  |  |  |  | 11 |  | 
| 170 | 2 |  |  | 2 | 1 | 380 | sub ostext       { my $self = shift; return $self->{current}->{ostext}       } | 
|  | 2 |  |  |  |  | 6 |  | 
| 171 | 2 |  |  | 2 | 1 | 377 | sub osvers       { my $self = shift; return $self->{current}->{osvers}       } | 
|  | 2 |  |  |  |  | 7 |  | 
| 172 | 2 |  |  | 2 | 1 | 421 | sub platform     { my $self = shift; return $self->{current}->{platform}     } | 
|  | 2 |  |  |  |  | 7 |  | 
| 173 | 2 |  |  | 2 | 1 | 407 | sub archname     { my $self = shift; return $self->{current}->{platform}     } | 
|  | 2 |  |  |  |  | 9 |  | 
| 174 |  |  |  |  |  |  |  | 
| 175 | 3226 |  | 33 | 3226 | 1 | 2675 | sub url          { my $self = shift; return $WEB . ($self->{current}->{guid} || $self->{current}->{id}) } | 
|  | 3226 |  |  |  |  | 11834 |  | 
| 176 |  |  |  |  |  |  |  | 
| 177 | 2 |  |  | 2 | 1 | 396 | sub csspatch     { my $self = shift; return $self->{current}->{csspatch}     } | 
|  | 2 |  |  |  |  | 7 |  | 
| 178 | 2 |  |  | 2 | 1 | 376 | sub cssperl      { my $self = shift; return $self->{current}->{cssperl}      } | 
|  | 2 |  |  |  |  | 8 |  | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | q{ another hope, another dream, another truth ... installed by the machine }; | 
| 182 |  |  |  |  |  |  |  | 
| 183 |  |  |  |  |  |  | __END__ |