File Coverage

blib/lib/WWW/NicoVideo.pm
Criterion Covered Total %
statement 39 101 38.6
branch 0 36 0.0
condition 0 27 0.0
subroutine 13 19 68.4
pod 4 5 80.0
total 56 188 29.7


line stmt bran cond sub pod time code
1             # -*- mode: perl; coding: utf-8 -*-
2            
3             package WWW::NicoVideo;
4 1     1   25717 use utf8;
  1         12  
  1         5  
5 1     1   33 use strict;
  1         2  
  1         35  
6 1     1   6 use warnings;
  1         6  
  1         38  
7 1     1   5 use base qw[Class::Accessor];
  1         1  
  1         1254  
8            
9 1     1   3268 use Encode;
  1         14739  
  1         95  
10 1     1   9 use Carp;
  1         2  
  1         71  
11 1     1   1095 use LWP::UserAgent;
  1         71455  
  1         52  
12 1     1   1054 use HTTP::Cookies;
  1         9336  
  1         33  
13 1     1   8 use URI;
  1         2  
  1         25  
14 1     1   965 use URI::QueryParam;
  1         968  
  1         29  
15 1     1   668 use WWW::NicoVideo::Entry;
  1         3  
  1         8  
16 1     1   539 use WWW::NicoVideo::Scraper;
  1         3  
  1         6  
17 1     1   6 use WWW::NicoVideo::URL;
  1         2  
  1         1217  
18            
19             __PACKAGE__->mk_accessors(qw[agent retry retryInterval mail passwd]);
20            
21             our $VERSION = "0.03";
22             our $AGENT_NAME = "@{[__PACKAGE__]}/$VERSION)";
23            
24             sub new
25             {
26 0     0 1   my $pkg = shift;
27 0           my %opts = @_;
28            
29             my $ua = $opts{agent} || new LWP::UserAgent(agent => $AGENT_NAME,
30             timeout => 30,
31 0   0       %{$opts{agentOpts}});
32             $ua->cookie_jar($opts{cookies} ||
33 0   0       new HTTP::Cookies(%{$opts{cookiesOpts}}));
34            
35 0   0       bless {agent => $ua,
      0        
36             retry => $opts{retry} || 5,
37             retryInterval => $opts{retryInterval} || 30,
38             mail => $opts{mail},
39             passwd => $opts{passwd}}, $pkg;
40             }
41            
42             sub login
43             {
44 0     0 1   my $self = shift;
45 0           my $ua = $self->{agent};
46 0           my $cj = $ua->cookie_jar;
47 0           my $has_cookie = 0;
48            
49 0 0 0       if(not defined $self->{mail} or
50             not defined $self->{passwd}) {
51 0           confess "mail and passwd required";
52             }
53            
54             $cj->scan(sub {
55 0     0     my($key, $val, $domain, $expires) = @_[1, 2, 4, 8];
56 0 0 0       if($domain eq ".nicovideo.jp" and
57             time + 60 < $expires) {
58 0           $has_cookie = 1;
59             }
60 0           });
61            
62 0           my $login_ok = 0;
63 0 0         if($has_cookie) {
64 0           my $res = $ua->get(nicoURL("top"));
65 0 0 0       if($res->is_success and
66             not $res->as_string =~ /
]*name="login"/) {
67 0           $login_ok = 1;
68             }
69             }
70            
71 0 0         if($login_ok) {
72 0           $self->{loginOk} = 1;
73 0           return 1;
74             } else {
75 0           my $res = $ua->post(nicoURL("login"),
76             {mail => $self->{mail},
77             password => $self->{passwd}});
78            
79 0 0         if($res->is_redirect) {
80 0           $self->{loginOk} = 1;
81 0           return 1;
82             } else {
83 0           return 0;
84             }
85             }
86             }
87            
88             sub getEntriesByTagNames
89             {
90 0     0 1   my $self = shift;
91 0           $self->getEntries("tag", @_);
92             }
93            
94             *getEntriesByTagName = \&getEntriesByTagNames;
95            
96             sub getEntriesByKeywords
97             {
98 0     0 1   my $self = shift;
99 0           $self->getEntries("search", @_);
100             }
101            
102             *getEntriesByKeyword = \&getEntriesByKeywords;
103            
104             sub getEntries
105             {
106 0     0 0   my $self = shift;
107 0           my $type = shift;
108 0           my %opts = @_;
109 0 0         my @keys = (@{$opts{keys} || []},
  0 0          
110             (defined $opts{key}? $opts{key}: ()));
111 0           my $page = $opts{page};
112 0           my $sort = $opts{sort};
113 0           my $order = $opts{order};
114            
115 0           my $ua = $self->{agent};
116            
117 0 0         if(!$self->{loginOk}) {
118 0 0         return wantarray? (): undef;
119             }
120            
121 0           my $url = new URI(nicoURL($type, @keys));
122 0 0         $url->query_param_append(sort => $sort) if(defined $sort);
123 0 0         $url->query_param_append(order => $order) if(defined $order);
124 0 0         $url->query_param_append(page => $page) if(defined $page);
125            
126 0           my $count = 0;
127 0           my $res;
128             my $html;
129            
130 0   0       do {
      0        
131 0 0         if($count) {
132             # busy
133 0   0       sleep($self->{retryInterval} || 30);
134             }
135            
136 0           $res = $ua->get($url);
137            
138 0 0         if($res->is_success) {
    0          
139 0           $html = decode_utf8($res->content);
140             } elsif($opts{verbose}) {
141 0           carp "Could not get $url (status: ", $res->status_line, ")";
142             }
143            
144 0           $count++;
145             } while(not $res->is_success and
146             $count < $self->{retry} and
147             $html =~ m{^

【ご注意】
}m # access blocking

148             );
149            
150 0           my $scraper = scraper_entries();
151 0 0         my @res = (map { WWW::NicoVideo::Entry->new($_) }
  0            
152 0           @{$scraper->scrape($html)->{entries} || []});
153 0 0         wantarray? @res: \@res;
154             }
155            
156             "Ritsuko";
157            
158             =encoding utf-8
159            
160             =head1 NAME
161            
162             WWW::NicoVideo - Perl interface to Nico Nico Video service
163            
164             =head1 SYNOPSIS
165            
166             use utf8;
167             use WWW::NicoVideo;
168             binmode STDOUT, ":encoding(euc-jp)";
169            
170             my $nv = new WWW::NicoVideo(mail => 'ritsuko@ritsuko.org',
171             passwd => "ritchan-wa-kawaiidesuyo");
172             $nv->login or die "Login failed";
173            
174             my @entries = $nv->getEntriesByTagNames("律子ソロ") or die "get failed";
175             foreach my $e (@entries) {
176             print $e->title, "\n";
177             }
178            
179             =head1 DESCRIPTION
180            
181             This module allows you to get information from
182             Nico Nico Video service (L)
183             and also allows you to search from it.
184            
185             =head1 METHODS
186            
187             =over 4
188            
189             =item $nv = new WWW::NicoVideo(%OPTS)
190            
191             Constructs a new WWW::NicoVideo object and returns it.
192             Key/value pair options may be provided to set the default value.
193             Following options are accepted:
194            
195             =over 4
196            
197             =item agent / cookies
198            
199             LWP::UserAgent / HTTP::Cookies object.
200            
201             =item retry / retryInterval
202            
203             Retry count / retry interval in second.
204             As Nico Nico Video rejects mass access,
205             you have to give appropriate interval between accesses.
206            
207             =item mail / passwd
208            
209             Mail address / password to access Nico Nico Video.
210            
211             =back
212            
213             All options except "cookies" can be accessed via accessor methods.
214             (e.g. $nv->agent)
215             You may access cookies via "agent".
216             (e.g. $nv->agent->cookie_jar)
217            
218             =item $nv->login
219            
220             Login to Nico Nico Video. You have to call this method before
221             calling getEntries* methods;
222            
223             =item $nv->getEntriesByTagNames(%OPTS) / $nv->getEntriesByKeywords(%OPTS)
224            
225             Returns entry list for given tag name(s) / keyword(s).
226             In scalar context, this method returns a reference to array of
227             WWW::NicoVideo::Entry or undef on errors.
228             In list context, this method returns list of WWW::NicoVideo::Entry
229             or null list on errors.
230             Following options are accepted:
231            
232             =over 4
233            
234             =item key / keys
235            
236             Tagname(s) or keyword(s).
237             "key" takes a scalar value, "keys" takes a reference to array.
238            
239             =item page
240            
241             Page number.
242            
243             =item sort
244            
245             Sort type. "f" for post date, "v" for number of views,
246             "r" for number of comments, undef for last comment date.
247            
248             =item order
249            
250             Sort order. "a" for ASC, "d" or undef for DESC.
251            
252             =back
253            
254             =back
255            
256             =head1 SEE ALSO
257            
258             L, L, L
259            
260             =head1 AUTHOR
261            
262             HIRATA Yasuyuki, Eyasu@REMOVE-THIS-PART.asuka.netE
263            
264             =head1 COPYRIGHT AND LICENSE
265            
266             This library is free software; you can redistribute it and/or modify
267             it under the same terms as Perl itself, either Perl version 5.8.8 or,
268             at your option, any later version of Perl 5 you may have available.
269            
270             =head1 SUBVERSION REPOSITORY
271            
272             The latest version of this module is available
273             from our Subversion repository at:
274             L
275            
276             =cut