File Coverage

lib/WWW/Mixi/Scraper/Plugin.pm
Criterion Covered Total %
statement 48 121 39.6
branch 6 48 12.5
condition 0 17 0.0
subroutine 11 24 45.8
pod 7 7 100.0
total 72 217 33.1


line stmt bran cond sub pod time code
1             package WWW::Mixi::Scraper::Plugin;
2            
3 1     1   9 use strict;
  1         2  
  1         30  
4 1     1   5 use warnings;
  1         1  
  1         22  
5 1     1   869 use Web::Scraper;
  1         184574  
  1         6  
6 1     1   820 use String::CamelCase qw( decamelize );
  1         649  
  1         84  
7 1     1   389 use WWW::Mixi::Scraper::Utils qw( _force_arrayref _uri _datetime );
  1         2  
  1         182  
8            
9             sub import {
10 21     21   622 my $class = shift;
11 21         38 my $pkg = caller;
12            
13 21         131 my @subs = qw(
14             new parse
15             scraper process process_first result
16             get_content post_process
17             validator build_uri
18             html_or_text _extract_name
19             );
20            
21 1     1   17 no strict 'refs';
  1         2  
  1         28  
22 1     1   5 no warnings 'redefine';
  1         2  
  1         668  
23 21         33 foreach my $sub ( @subs ) {
24 252         232 *{"$pkg\::$sub"} = *{"$class\::$sub"};
  252         10282  
  252         1157  
25             }
26             }
27            
28             sub new {
29 0     0 1 0 my ($class, %options) = @_;
30            
31 0         0 bless \%options, $class;
32             }
33            
34 0 0   0 1 0 sub html_or_text { shift->{mode} || 'HTML' }
35            
36             sub parse {
37 0     0 1 0 my $self = shift;
38            
39 0         0 my $res = $self->scrape($self->get_content(@_));
40            
41 0 0       0 return ( wantarray and ref $res eq 'ARRAY' )
42 0 0 0     0 ? @{ $res || [] }
43             : $res;
44             }
45            
46             sub get_content {
47 0     0 1 0 my ($self, %options) = @_;
48            
49 0         0 my $content = delete $options{html};
50            
51 0 0       0 unless ( $content ) {
52 0         0 $content = $self->{mech}->get_content($self->build_uri(%options));
53             }
54 0 0       0 die "no content" unless $content;
55            
56             # XXX: preserve some tags like
?
57             # $content =~ s/]*)?>/\n/g; # at least preserve as a space
58 0         0 $content =~ s/ / /g; # as it'd be converted as '?'
59            
60 0         0 return $content;
61             }
62            
63             sub build_uri {
64 0     0 1 0 my ($self, %query) = @_;
65            
66 0         0 my ($name) = (ref $self) =~ /::(\w+)$/;
67 0         0 my $path = sprintf '/%s.pl', decamelize($name);
68 0         0 my $uri = URI->new($path);
69            
70 0         0 foreach my $key ( keys %query ) {
71 0 0       0 if ( $self->_is_valid( $key, $query{$key} ) ) {
72 0         0 $uri->query_param( $key => $query{$key} );
73             }
74             }
75            
76 0 0       0 $uri = $self->tweak_uri($uri) if $self->can('tweak_uri');
77            
78 0         0 $self->{uri} = $uri; # preserve for later use.
79            
80 0         0 return $uri;
81             }
82            
83             sub validator ($) {
84 12     12 1 28 my $hashref = shift;
85 12         27 my $pkg = caller;
86            
87 12         20 my %rules;
88 12         33 foreach my $key ( keys %{ $hashref } ) {
  12         45  
89 24         39 my $rule = $hashref->{$key};
90 24 100       72 if ( $rule eq 'is_number' ) {
91             $rules{$key} = sub {
92 0     0   0 my $value = shift;
93 0 0 0     0 $value && $value =~ /^\d+$/ ? 1 : 0;
94 16         62 };
95             }
96 24 100       57 if ( $rule eq 'is_number_or_all' ) {
97             $rules{$key} = sub {
98 0     0   0 my $value = shift;
99 0 0 0     0 $value && $value =~ /^(?:\d+|all)$/ ? 1 : 0;
100 2         15 };
101             }
102 24 100       63 if ( $rule eq 'is_anything' ) {
103 3     0   15 $rules{$key} = sub { 1 };
  0         0  
104             }
105             }
106            
107 1     1   6 no strict 'refs';
  1         1  
  1         32  
108 1     1   10 no warnings 'redefine';
  1         1  
  1         719  
109 12   0 0   44 *{"$pkg\::_is_valid"} = sub { return $rules{$_[1]} && $rules{$_[1]}->($_[2]) };
  12         101  
  0            
110             }
111            
112             sub post_process {
113 0     0 1   my ($self, $data, $callback) = @_;
114            
115 0           my $arrayref = _force_arrayref($data);
116            
117 0           foreach my $item ( @{ $arrayref } ) {
  0            
118 0 0         if ( ref $callback eq 'CODE' ) {
119 0           $callback->($item);
120             }
121 0           foreach my $key ( keys %{ $item } ) {
  0            
122 0 0         next unless $item->{$key};
123 0 0         if ( $key =~ /time$/ ) {
    0          
    0          
124 0           $item->{$key} = _datetime($item->{$key})
125             }
126             elsif ( $key =~ /(?:link|envelope|image|background|src|icon)$/ ) {
127 0           $item->{$key} = _uri($item->{$key});
128             }
129             elsif ( $key eq 'images' ) {
130 0           $item->{$key} = _images($item->{$key});
131             }
132             }
133             }
134            
135 0 0         $arrayref = [ grep { %{ $_ } && !$_->{_delete} } @{ $arrayref } ];
  0            
  0            
  0            
136            
137 0           return $arrayref;
138             }
139            
140             sub _images {
141 0     0     my $item = shift;
142            
143 0 0         $item = [ $item ] unless ref $item; # a thumbnail
144            
145 0           my @images;
146 0 0         foreach my $i ( @{ $item || [] } ) {
  0            
147 0 0         next unless $item;
148 0           push @images, __images($i);
149             }
150 0           return \@images;
151             }
152            
153             sub __images {
154 0     0     my $item = shift;
155 0           my ($link, $thumb);
156 0 0         unless ( ref $item eq 'HASH' ) {
157 0           $link = $thumb = $item;
158 0           $link =~ s/s\.jpg$/\.jpg/;
159 0           $thumb =~ s/(?:[^s])\.jpg$/s\.jpg/;
160             }
161             else {
162 0   0       $link = $item->{link} || '';
163 0           $thumb = $item->{thumb_link};
164            
165 0 0         if ( $link =~ /MM_openBrWindow\(\s*'([^']+)'/ ) { $link = $1; }
  0            
166             }
167 0           return { link => _uri($link), thumb_link => _uri($thumb) };
168             }
169            
170             sub _extract_name {
171 0     0     my $item = shift;
172            
173 0 0 0       return unless defined $item->{string} && defined $item->{subject};
174            
175 0           my $name = substr( delete $item->{string}, length $item->{subject} );
176 0           $name =~ s/^\s*\(//;
177 0           $name =~ s/\)\s*$//;
178 0           $item->{name} = $name;
179             }
180            
181             1;
182            
183             __END__