| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Net::Google::Code::Role::Pageable; |
|
2
|
10
|
|
|
10
|
|
7516
|
use Any::Moose 'Role'; |
|
|
10
|
|
|
|
|
21
|
|
|
|
10
|
|
|
|
|
70
|
|
|
3
|
10
|
|
|
10
|
|
4187
|
use Params::Validate ':all'; |
|
|
10
|
|
|
|
|
19
|
|
|
|
10
|
|
|
|
|
2350
|
|
|
4
|
10
|
|
|
10
|
|
57
|
use WWW::Mechanize; |
|
|
10
|
|
|
|
|
34
|
|
|
|
10
|
|
|
|
|
413
|
|
|
5
|
|
|
|
|
|
|
with 'Net::Google::Code::Role::Fetchable'; |
|
6
|
|
|
|
|
|
|
with 'Net::Google::Code::Role::HTMLTree'; |
|
7
|
10
|
|
|
10
|
|
62
|
use Scalar::Util qw/blessed/; |
|
|
10
|
|
|
|
|
28
|
|
|
|
10
|
|
|
|
|
10967
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
sub rows { |
|
10
|
4
|
|
|
4
|
1
|
10
|
my $self = shift; |
|
11
|
4
|
|
|
|
|
751
|
my %args = validate( |
|
12
|
|
|
|
|
|
|
@_, |
|
13
|
|
|
|
|
|
|
{ |
|
14
|
|
|
|
|
|
|
html => { type => SCALAR | OBJECT }, |
|
15
|
|
|
|
|
|
|
limit => { |
|
16
|
|
|
|
|
|
|
type => SCALAR | UNDEF, |
|
17
|
|
|
|
|
|
|
optional => 1, |
|
18
|
|
|
|
|
|
|
}, |
|
19
|
|
|
|
|
|
|
} |
|
20
|
|
|
|
|
|
|
); |
|
21
|
|
|
|
|
|
|
|
|
22
|
4
|
|
100
|
|
|
44
|
$args{limit} ||= 999_999_999; # the impossible huge limit |
|
23
|
4
|
|
|
|
|
8
|
my $tree = $args{html}; |
|
24
|
4
|
|
|
|
|
21
|
my $need_delete = not blessed $tree; |
|
25
|
4
|
50
|
|
|
|
44
|
$tree = $self->html_tree( html => $tree ) unless blessed $tree; |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# assuming there's at most 20 columns |
|
28
|
4
|
|
|
|
|
14
|
my @titles; |
|
29
|
|
|
|
|
|
|
my $label_column; |
|
30
|
4
|
|
|
|
|
19
|
for my $num ( 0 .. 20 ) { |
|
31
|
30
|
|
|
|
|
141
|
my $title_tag = $tree->look_down( class => "col_$num" ); |
|
32
|
30
|
100
|
|
|
|
43184
|
if ( $title_tag ) { |
|
33
|
26
|
|
|
|
|
102
|
my $title = $title_tag->as_text; |
|
34
|
26
|
100
|
|
|
|
756
|
if ( $title eq "\x{a0}" ) { |
|
35
|
3
|
|
|
|
|
16
|
$title_tag = ($tree->look_down( class => "col_$num" ))[1]; |
|
36
|
3
|
|
|
|
|
12612
|
$title = $title_tag->as_text; |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
26
|
50
|
|
|
|
240
|
if ( $title =~ /(\w+)/ ) { |
|
40
|
26
|
|
|
|
|
85
|
push @titles, lc $1; |
|
41
|
|
|
|
|
|
|
|
|
42
|
26
|
100
|
|
|
|
98
|
if ( $title =~ /label/i ) { |
|
43
|
4
|
|
|
|
|
18
|
$label_column = $num; |
|
44
|
|
|
|
|
|
|
} |
|
45
|
|
|
|
|
|
|
} |
|
46
|
|
|
|
|
|
|
} |
|
47
|
|
|
|
|
|
|
else { |
|
48
|
4
|
|
|
|
|
16
|
last; |
|
49
|
|
|
|
|
|
|
} |
|
50
|
|
|
|
|
|
|
} |
|
51
|
|
|
|
|
|
|
|
|
52
|
4
|
50
|
|
|
|
21
|
die "no idea what the column spec is" unless @titles; |
|
53
|
|
|
|
|
|
|
|
|
54
|
4
|
|
|
|
|
9
|
my @rows; |
|
55
|
|
|
|
|
|
|
|
|
56
|
4
|
|
|
|
|
27
|
my $pagination = $tree->look_down( class => 'pagination' ); |
|
57
|
4
|
50
|
|
|
|
4159
|
return unless $pagination; |
|
58
|
|
|
|
|
|
|
|
|
59
|
4
|
50
|
|
|
|
26
|
if ( $pagination->as_text =~ /\d+\s+-\s+\d+\s+of\s+\d+/ ) { |
|
60
|
|
|
|
|
|
|
# all the rows in a page |
|
61
|
4
|
|
|
|
|
178
|
push @rows, $self->_rows( |
|
62
|
|
|
|
|
|
|
html => $tree, |
|
63
|
|
|
|
|
|
|
titles => \@titles, |
|
64
|
|
|
|
|
|
|
label_column => $label_column, |
|
65
|
|
|
|
|
|
|
); |
|
66
|
|
|
|
|
|
|
|
|
67
|
4
|
|
|
|
|
24
|
while ( scalar @rows < $args{limit} ) { |
|
68
|
4
|
|
|
|
|
42
|
my $next_link = $self->mech->find_link( text_regex => qr/Next\s+/ ); |
|
69
|
4
|
50
|
|
|
|
450
|
if ($next_link) { |
|
70
|
0
|
|
|
|
|
0
|
$self->mech->get( $next_link->url ); |
|
71
|
0
|
0
|
|
|
|
0
|
if ( $self->mech->response->is_success ) { |
|
72
|
0
|
|
|
|
|
0
|
push @rows, $self->_rows( |
|
73
|
|
|
|
|
|
|
html => $self->mech->content, |
|
74
|
|
|
|
|
|
|
titles => \@titles, |
|
75
|
|
|
|
|
|
|
label_column => $label_column, |
|
76
|
|
|
|
|
|
|
); |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
else { |
|
79
|
0
|
|
|
|
|
0
|
die "failed to follow 'Next' link"; |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
} |
|
82
|
|
|
|
|
|
|
else { |
|
83
|
4
|
|
|
|
|
13
|
last; |
|
84
|
|
|
|
|
|
|
} |
|
85
|
|
|
|
|
|
|
} |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
|
|
88
|
4
|
50
|
|
|
|
38
|
$tree->delete if $need_delete; |
|
89
|
4
|
50
|
|
|
|
23189
|
if ( scalar @rows > $args{limit} ) { |
|
90
|
|
|
|
|
|
|
# this happens when limit is less than the 1st page's number, so in |
|
91
|
|
|
|
|
|
|
# some similar situations |
|
92
|
0
|
|
|
|
|
0
|
return @rows[0 .. $args{limit}-1]; |
|
93
|
|
|
|
|
|
|
} |
|
94
|
|
|
|
|
|
|
else { |
|
95
|
4
|
|
|
|
|
107
|
return @rows; |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
} |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub _rows { |
|
100
|
4
|
|
|
4
|
|
9
|
my $self = shift; |
|
101
|
4
|
|
|
|
|
245
|
my %args = validate( |
|
102
|
|
|
|
|
|
|
@_, |
|
103
|
|
|
|
|
|
|
{ |
|
104
|
|
|
|
|
|
|
html => { type => SCALAR | OBJECT }, |
|
105
|
|
|
|
|
|
|
titles => { type => ARRAYREF, }, |
|
106
|
|
|
|
|
|
|
label_column => { optional => 1 }, |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
); |
|
109
|
4
|
|
|
|
|
36
|
my $tree = $args{html}; |
|
110
|
4
|
|
|
|
|
30
|
my $need_delete = not blessed $tree; |
|
111
|
4
|
50
|
|
|
|
29
|
$tree = $self->html_tree( html => $tree ) unless blessed $tree; |
|
112
|
4
|
|
|
|
|
12
|
my @titles = @{$args{titles}}; |
|
|
4
|
|
|
|
|
24
|
|
|
113
|
4
|
|
|
|
|
10
|
my $label_column = $args{label_column}; |
|
114
|
|
|
|
|
|
|
|
|
115
|
4
|
|
|
|
|
9
|
my @columns; |
|
116
|
|
|
|
|
|
|
my @rows; |
|
117
|
|
|
|
|
|
|
|
|
118
|
4
|
|
|
|
|
27
|
for ( my $i = 0 ; $i < @titles ; $i++ ) { |
|
119
|
26
|
|
|
|
|
1027
|
my @tags = $tree->look_down( class => qr/^vt (id )?col_$i/ ); |
|
120
|
26
|
|
|
|
|
100110
|
my $k = 0; |
|
121
|
26
|
|
|
|
|
131
|
for ( my $j = 0 ; $j < @tags ; $j++ ) { |
|
122
|
202
|
|
|
|
|
695
|
my $column = $tags[$j]->as_text; |
|
123
|
202
|
100
|
|
|
|
5929
|
next unless $column =~ /[-\w]/; # skip the '›' thing or alike |
|
124
|
|
|
|
|
|
|
|
|
125
|
178
|
|
|
|
|
488
|
my @elements = split /\x{a0}/, $column; |
|
126
|
178
|
|
|
|
|
306
|
for ( @elements ) { |
|
127
|
186
|
|
|
|
|
497
|
s/^\s+//; |
|
128
|
186
|
|
|
|
|
671
|
s/\s+$//; |
|
129
|
|
|
|
|
|
|
} |
|
130
|
178
|
|
|
|
|
267
|
$column = shift @elements; |
|
131
|
178
|
100
|
|
|
|
357
|
$column = '' if $column eq '----'; |
|
132
|
|
|
|
|
|
|
|
|
133
|
178
|
100
|
|
|
|
322
|
if ( $i == 0 ) { |
|
134
|
26
|
|
|
|
|
80
|
push @rows, { $titles[0] => $column }; |
|
135
|
|
|
|
|
|
|
} |
|
136
|
|
|
|
|
|
|
else { |
|
137
|
152
|
|
|
|
|
401
|
$rows[$k]{ $titles[$i] } = $column; |
|
138
|
|
|
|
|
|
|
} |
|
139
|
|
|
|
|
|
|
|
|
140
|
178
|
100
|
66
|
|
|
767
|
if ( $label_column && $i == $label_column ) { |
|
141
|
26
|
|
|
|
|
35
|
my @labels; |
|
142
|
26
|
100
|
|
|
|
47
|
if (@elements) { |
|
143
|
8
|
|
|
|
|
30
|
@labels = split /\s+/, shift @elements; |
|
144
|
|
|
|
|
|
|
} |
|
145
|
26
|
100
|
|
|
|
95
|
$rows[$k]{labels} = \@labels if @labels; |
|
146
|
|
|
|
|
|
|
} |
|
147
|
178
|
|
|
|
|
548
|
$k++; |
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
} |
|
150
|
4
|
50
|
|
|
|
16
|
$tree->delete if $need_delete; |
|
151
|
4
|
|
|
|
|
37
|
return @rows; |
|
152
|
|
|
|
|
|
|
} |
|
153
|
|
|
|
|
|
|
|
|
154
|
10
|
|
|
10
|
|
66
|
no Any::Moose; |
|
|
10
|
|
|
|
|
19
|
|
|
|
10
|
|
|
|
|
56
|
|
|
155
|
|
|
|
|
|
|
1; |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
__END__ |