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__ |