File Coverage

blib/lib/WWW/AUR/Iterator.pm
Criterion Covered Total %
statement 80 80 100.0
branch 13 18 72.2
condition n/a
subroutine 15 15 100.0
pod 4 6 66.6
total 112 119 94.1


}gxs; }gxs;
line stmt bran cond sub pod time code
1             package WWW::AUR::Iterator;
2              
3 1     1   13010 use warnings 'FATAL' => 'all';
  1         1  
  1         28  
4 1     1   3 use strict;
  1         1  
  1         15  
5              
6 1     1   348 use WWW::AUR::Package qw();
  1         2  
  1         24  
7 1     1   4 use WWW::AUR::URI qw( pkg_uri );
  1         1  
  1         37  
8 1     1   3 use WWW::AUR qw( _path_params _category_name _useragent );
  1         1  
  1         603  
9              
10             sub new
11             {
12 4     4 0 1244 my $class = shift;
13 4         10 my $self = bless {}, $class;
14 4         15 $self->init( @_ );
15             }
16              
17             sub init
18             {
19 4     4 0 17 my $self = shift;
20              
21 4         6 my $startidx;
22 4 50       20 $startidx = shift if @_ % 2 == 1;
23              
24 4         25 %$self = ( %$self, _path_params( @_ ));
25 4         14 $self->reset();
26 4 50       11 $self->set_pos( $startidx ) if $startidx;
27              
28 4         10 return $self;
29             }
30              
31             sub set_pos
32             {
33 1     1 1 5 my ($self, $startidx) = @_;
34 1 50       7 Carp::croak 'Argument to set_pos() must an integer'
35             unless $startidx =~ /\A\d+\z/;
36              
37 1         2 $self->{'curridx'} = $startidx;
38 1         2 $self->{'finished'} = 0;
39 1         2 $self->{'packages'} = [];
40              
41 1         2 return;
42             }
43              
44             sub reset
45             {
46 4     4 1 8 my ($self) = @_;
47 4         7 $self->{'curridx'} = 0;
48 4         7 $self->{'finished'} = 0;
49 4         11 $self->{'packages'} = [];
50 4         14 $self->{'useragent'} = _useragent();
51 4         2846 return;
52             }
53              
54             #---HELPER FUNCTION---
55             sub _pkglist_uri
56             {
57 4     4   6 my ($startidx) = @_;
58 4         16 return pkg_uri( q{SB} => q{n}, q{O} => $startidx,
59             q{SO} => q{a}, q{PP} => 100 );
60             }
61              
62             #---PRIVATE METHOD---
63             sub _scrape_pkglist
64             {
65 4     4   6 my ($self) = @_;
66              
67 4         9 my $uri = _pkglist_uri( $self->{'curridx'} );
68 4         43 my $resp = $self->{'useragent'}->get( $uri );
69              
70 4 50       568745 Carp::croak 'Failed to GET package list webpage: ' . $resp->status_line
71             unless $resp->is_success;
72              
73 4         37 my @pkginfos;
74 4         17 my @rows = _splitrows( $resp->content );
75 4         13 shift @rows; # remove the header column
76              
77 4         13 for my $rowhtml ( @rows ) {
78 300         294 my @cols = _splitcols( $rowhtml );
79              
80             # cat, name, version, votes, desc, maintainer
81 300         560 push @pkginfos, @cols;
82             }
83              
84 4         90 return \@pkginfos;
85             }
86              
87             sub _splitrows
88             {
89 4     4   1652 my ($html) = @_;
90 4         851 my @rows = $html =~ m{ ]*> ( .*? )
91 4         54 return @rows;
92             }
93              
94             sub _splitcols
95             {
96 300     300   213 my ($rowhtml) = @_;
97 300         1918 my @cols = $rowhtml =~ m{ ]*> ( .*? )
98 300         325 for ( @cols ) {
99 1800         2170 s/<[^>]+>//g; # delete tags
100 1800         1454 s/\A\s+//; s/\s+\z//; # trim whitespace
  1800         1901  
101             }
102 300         659 return @cols;
103             }
104              
105             sub next
106             {
107 206     206 1 498 my ($self) = @_;
108              
109             # There are no more packages to iterate over...
110 206 100       548 return undef if $self->{'finished'};
111              
112 205         227 my @pkginfo = splice @{ $self->{'packages'} }, 0, 6;
  205         667  
113 205 100       437 if ( @pkginfo ) {
114 201         171 my $pkg;
115 201         390 my @k = qw/name version votes popularity desc/;
116 201         488 for my $i (0 .. $#k) {
117 1005         1292 $pkg->{$k[$i]} = $pkginfo[$i];
118             }
119              
120 201         227 my $maint = $pkginfo[5];
121 201 100       397 $pkg->{'maint'} = ($maint eq 'orphan' ? undef : $maint);
122 201         441 return $pkg;
123             }
124              
125             # Load a new batch of packages if our internal list is empty...
126 4         9 my $newpkgs = $self->_scrape_pkglist;
127              
128 4         11 $self->{'curridx'} += 100;
129 4         9 $self->{'packages'} = $newpkgs;
130 4 100       17 $self->{'finished'} = 1 if scalar @$newpkgs == 0;
131              
132             # Recurse, just avoids code copy/pasting...
133 4         14 return $self->next();
134             }
135              
136             sub next_obj
137             {
138 100     100 1 1088 my ($self) = @_;
139              
140 100         295 my $next = $self->next;
141             return ( $next
142 100 50       701 ? WWW::AUR::Package->new( $next->{'name'}, %$self )
143             : undef );
144             }
145              
146             1;
147              
148             __END__