line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Parse::BACKPAN::Packages; |
2
|
1
|
|
|
1
|
|
1386
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
39
|
|
3
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
37
|
|
4
|
1
|
|
|
1
|
|
743
|
use App::Cache; |
|
1
|
|
|
|
|
196050
|
|
|
1
|
|
|
|
|
13
|
|
5
|
1
|
|
|
1
|
|
2859
|
use CPAN::DistnameInfo; |
|
1
|
|
|
|
|
1647
|
|
|
1
|
|
|
|
|
40
|
|
6
|
1
|
|
|
1
|
|
8047
|
use Compress::Zlib; |
|
1
|
|
|
|
|
93939
|
|
|
1
|
|
|
|
|
320
|
|
7
|
1
|
|
|
1
|
|
10
|
use IO::File; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
188
|
|
8
|
1
|
|
|
1
|
|
1699
|
use IO::Zlib; |
|
1
|
|
|
|
|
6061
|
|
|
1
|
|
|
|
|
7
|
|
9
|
1
|
|
|
1
|
|
57
|
use LWP::UserAgent; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
29
|
|
10
|
1
|
|
|
1
|
|
1050
|
use Parse::BACKPAN::Packages::File; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
14
|
|
11
|
1
|
|
|
1
|
|
1023
|
use Parse::BACKPAN::Packages::Distribution; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
6
|
|
12
|
1
|
|
|
1
|
|
26
|
use base qw( Class::Accessor::Fast ); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
1109
|
|
13
|
|
|
|
|
|
|
__PACKAGE__->mk_accessors(qw( files dists_by no_cache )); |
14
|
|
|
|
|
|
|
our $VERSION = '0.36'; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
sub new { |
17
|
1
|
|
|
1
|
1
|
816
|
my $class = shift; |
18
|
1
|
|
|
|
|
9
|
my $self = $class->SUPER::new(@_); |
19
|
|
|
|
|
|
|
|
20
|
1
|
50
|
|
|
|
12
|
if ( !$self->no_cache ) { |
21
|
0
|
|
|
|
|
0
|
my $cache = App::Cache->new( { ttl => 60 * 60 } ); |
22
|
|
|
|
|
|
|
$self->files( |
23
|
0
|
|
|
0
|
|
0
|
$cache->get_code( 'files', sub { $self->_init_files() } ) ); |
|
0
|
|
|
|
|
0
|
|
24
|
|
|
|
|
|
|
$self->dists_by( |
25
|
0
|
|
|
0
|
|
0
|
$cache->get_code( 'dists_by', sub { $self->_init_dists_by() } ) ); |
|
0
|
|
|
|
|
0
|
|
26
|
|
|
|
|
|
|
} else { |
27
|
1
|
|
|
|
|
14
|
$self->files( $self->_init_files() ); |
28
|
1
|
|
|
|
|
3347
|
$self->dists_by( $self->_init_dists_by() ); |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
|
31
|
1
|
|
|
|
|
49
|
return $self; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub _init_files { |
35
|
1
|
|
|
1
|
|
1
|
my $self = shift; |
36
|
1
|
|
|
|
|
2
|
my $files; |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
my $data; |
39
|
1
|
|
|
|
|
1
|
my $url = "http://www.astray.com/tmp/backpan.txt.gz"; |
40
|
1
|
|
|
|
|
11
|
my $ua = LWP::UserAgent->new; |
41
|
1
|
|
|
|
|
3497
|
$ua->env_proxy(); |
42
|
1
|
|
|
|
|
40057
|
$ua->timeout(180); |
43
|
1
|
|
|
|
|
26
|
my $response = $ua->get($url); |
44
|
|
|
|
|
|
|
|
45
|
1
|
50
|
|
|
|
4351740
|
if ( $response->is_success ) { |
46
|
1
|
|
|
|
|
26
|
my $gzipped = $response->content; |
47
|
1
|
|
|
|
|
158920
|
$data = Compress::Zlib::memGunzip($gzipped); |
48
|
1
|
50
|
|
|
|
2486354
|
die "Error uncompressing data from $url" unless $data; |
49
|
|
|
|
|
|
|
} else { |
50
|
0
|
|
|
|
|
0
|
die "Error fetching $url"; |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
1
|
|
|
|
|
600733
|
foreach my $line ( split "\n", $data ) { |
54
|
1160823
|
|
|
|
|
9189825
|
my ( $prefix, $date, $size ) = split ' ', $line; |
55
|
1160823
|
100
|
|
|
|
2373945
|
next unless $size; |
56
|
1159243
|
|
|
|
|
24174785
|
my $file = Parse::BACKPAN::Packages::File->new( |
57
|
|
|
|
|
|
|
{ prefix => $prefix, |
58
|
|
|
|
|
|
|
date => $date, |
59
|
|
|
|
|
|
|
size => $size, |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
); |
62
|
1159243
|
|
|
|
|
36522942
|
$files->{$prefix} = $file; |
63
|
|
|
|
|
|
|
} |
64
|
1
|
|
|
|
|
173227
|
return $files; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub file { |
68
|
1
|
|
|
1
|
1
|
390
|
my ( $self, $prefix ) = @_; |
69
|
1
|
|
|
|
|
6
|
return $self->files->{$prefix}; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub distributions { |
73
|
1
|
|
|
1
|
1
|
520
|
my ( $self, $name ) = @_; |
74
|
1
|
|
|
|
|
10
|
my @files; |
75
|
|
|
|
|
|
|
|
76
|
1
|
|
|
|
|
3
|
while ( my ( $prefix, $file ) = each %{ $self->files } ) { |
|
1159243
|
|
|
|
|
2757970
|
|
77
|
1159242
|
|
|
|
|
8619456
|
my $prefix = $file->prefix; |
78
|
1159242
|
100
|
|
|
|
8584900
|
next unless $prefix =~ m{\/$name-}; |
79
|
64
|
100
|
|
|
|
938
|
next if $prefix =~ /\.(readme|meta)$/; |
80
|
31
|
|
|
|
|
155
|
push @files, $file; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
1
|
|
|
|
|
20
|
@files = sort { $a->date <=> $b->date } @files; |
|
122
|
|
|
|
|
702
|
|
84
|
|
|
|
|
|
|
|
85
|
1
|
|
|
|
|
26
|
my @dists; |
86
|
1
|
|
|
|
|
9
|
foreach my $file (@files) { |
87
|
31
|
|
|
|
|
74
|
my $i = CPAN::DistnameInfo->new( $file->prefix ); |
88
|
31
|
|
50
|
|
|
1673
|
my $dist = $i->dist || ''; |
89
|
31
|
100
|
|
|
|
170
|
next unless $dist eq $name; |
90
|
24
|
|
|
|
|
83
|
my $d = Parse::BACKPAN::Packages::Distribution->new( |
91
|
|
|
|
|
|
|
{ prefix => $file->prefix, |
92
|
|
|
|
|
|
|
date => $file->date, |
93
|
|
|
|
|
|
|
dist => $dist, |
94
|
|
|
|
|
|
|
version => $i->version, |
95
|
|
|
|
|
|
|
maturity => $i->maturity, |
96
|
|
|
|
|
|
|
filename => $i->filename, |
97
|
|
|
|
|
|
|
cpanid => $i->cpanid, |
98
|
|
|
|
|
|
|
distvname => $i->distvname, |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
); |
101
|
24
|
|
|
|
|
2127
|
push @dists, $d; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
1
|
|
|
|
|
28
|
return @dists; |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub distributions_by { |
108
|
4
|
|
|
4
|
1
|
47576
|
my ( $self, $author ) = @_; |
109
|
4
|
100
|
|
|
|
25
|
return unless $author; |
110
|
|
|
|
|
|
|
|
111
|
3
|
|
|
|
|
22
|
my $dists_by = $self->dists_by; |
112
|
|
|
|
|
|
|
|
113
|
3
|
100
|
|
|
|
21
|
my @dists = @{ $dists_by->{$author} || [] }; |
|
3
|
|
|
|
|
113
|
|
114
|
3
|
|
|
|
|
302
|
return sort @dists; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub authors { |
118
|
1
|
|
|
1
|
1
|
556
|
my $self = shift; |
119
|
1
|
|
|
|
|
6
|
my $dists_by = $self->dists_by; |
120
|
1
|
|
|
|
|
17458
|
return sort keys %$dists_by; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub _init_dists_by { |
124
|
1
|
|
|
1
|
|
5
|
my ($self) = shift; |
125
|
1
|
|
|
|
|
3
|
my @files; |
126
|
|
|
|
|
|
|
|
127
|
1
|
|
|
|
|
4
|
while ( my ( $prefix, $file ) = each %{ $self->files } ) { |
|
1159243
|
|
|
|
|
2902851
|
|
128
|
1159242
|
|
|
|
|
9046880
|
my $prefix = $file->prefix; |
129
|
1159242
|
100
|
|
|
|
8640271
|
next if $prefix =~ /\.(readme|meta)$/; |
130
|
527749
|
|
|
|
|
1198728
|
push @files, $file; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
1
|
|
|
|
|
9172
|
@files = sort { $a->date <=> $b->date } @files; |
|
9376451
|
|
|
|
|
71533187
|
|
134
|
|
|
|
|
|
|
|
135
|
1
|
|
|
|
|
15
|
my $dist_by; |
136
|
1
|
|
|
|
|
7
|
foreach my $file (@files) { |
137
|
527749
|
|
|
|
|
1681593
|
my $i = CPAN::DistnameInfo->new( $file->prefix ); |
138
|
527749
|
|
|
|
|
32887410
|
my ( $dist, $cpanid ) = ( $i->dist, $i->cpanid ); |
139
|
527749
|
100
|
100
|
|
|
4758186
|
next unless $dist && $cpanid; |
140
|
|
|
|
|
|
|
|
141
|
235882
|
|
|
|
|
1778044
|
$dist_by->{$cpanid}{$dist}++; |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
1
|
|
|
|
|
5022
|
my %dists_by = map { $_ => [ keys %{ $dist_by->{$_} } ] } keys %$dist_by; |
|
6623
|
|
|
|
|
8599
|
|
|
6623
|
|
|
|
|
178932
|
|
145
|
|
|
|
|
|
|
|
146
|
1
|
|
|
|
|
187246
|
return \%dists_by; |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
sub size { |
150
|
1
|
|
|
1
|
1
|
214491
|
my $self = shift; |
151
|
1
|
|
|
|
|
10
|
my $size; |
152
|
|
|
|
|
|
|
|
153
|
1
|
|
|
|
|
4
|
foreach my $file ( values %{ $self->files } ) { |
|
1
|
|
|
|
|
12
|
|
154
|
1159242
|
|
|
|
|
9463256
|
$size += $file->size; |
155
|
|
|
|
|
|
|
} |
156
|
1
|
|
|
|
|
75595
|
return $size; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
1; |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
__END__ |