File Coverage

blib/lib/WWW/NicoVideo/Download.pm
Criterion Covered Total %
statement 18 50 36.0
branch 0 16 0.0
condition n/a
subroutine 6 10 60.0
pod 2 4 50.0
total 26 80 32.5


line stmt bran cond sub pod time code
1             package WWW::NicoVideo::Download;
2              
3 1     1   5 use strict;
  1         2  
  1         40  
4 1     1   15 use 5.8.1;
  1         9  
  1         66  
5             our $VERSION = '0.06';
6              
7 1     1   5 use Carp;
  1         3  
  1         94  
8 1     1   2133 use LWP::UserAgent;
  1         59346  
  1         46  
9 1     1   1675 use CGI::Simple;
  1         15751  
  1         9  
10              
11 1     1   1103 use Any::Moose;
  1         38064  
  1         19  
12             has 'email', is => 'rw', isa => 'Str';
13             has 'password', is => 'rw', isa => 'Str';
14             has 'user_agent', is => 'rw', isa => 'LWP::UserAgent', default => sub {
15             my $ua = LWP::UserAgent->new( cookie_jar => {} );
16             push @{ $ua->requests_redirectable }, 'POST';
17             $ua;
18             };
19              
20             sub download {
21 0     0 1   my $self = shift;
22 0           my($video_id, @args) = @_;
23              
24 0           my $url = $self->prepare_download($video_id);
25 0           my $res = $self->user_agent->request( HTTP::Request->new( GET => $url ), @args );
26              
27 0 0         croak "Download failed: ", $res->status_line if $res->is_error;
28             }
29              
30             sub prepare_download {
31 0     0 1   my($self, $video_id) = @_;
32              
33 0 0         if ($video_id =~ m!/watch/(\w+)!) {
34 0           $video_id = $1;
35             }
36              
37 0           my $ua = $self->user_agent;
38 0           my $res = $ua->get("http://www.nicovideo.jp/watch/$video_id");
39              
40 0 0         if ( $self->is_logged_out($res) ) {
41 0           $self->login($video_id);
42             }
43              
44 0 0         if ($video_id =~ m/so\d+/){
45 0           my $u = $res->request->uri->as_string;
46 0           $u =~ m|.+/([^?]+)|;
47 0           $video_id = $1;
48             }
49              
50 0           my $time = scalar time;
51 0           $res = $ua->get("http://flapi.nicovideo.jp/api/getflv?v=$video_id&ts=$time&as3=1");
52 0 0         if ($res->is_error) {
53 0           croak "getflv API error: ", $res->status_line;
54             }
55              
56 0           my $params = CGI::Simple->new($res->content);
57 0 0         my $url = $params->param('url')
58             or croak "URL not found in getflv response";
59              
60             # Not sure why, but you need to get the page again
61 0           $ua->get("http://www.nicovideo.jp/watch/$video_id");
62              
63 0           return $url;
64             }
65              
66             sub is_logged_out {
67 0     0 0   my($self, $res) = @_;
68 0           $res->headers->header('x-niconico-authflag') eq '0';
69             }
70              
71             sub login {
72 0     0 0   my($self, $video_id) = @_;
73              
74 0           my $res = $self->user_agent->post("https://secure.nicovideo.jp/secure/login?site=niconico", {
75             next_url => "/watch/$video_id",
76             mail => $self->email,
77             password => $self->password,
78             });
79              
80 0 0         if ($res->is_error) {
    0          
81 0           croak "Login failed: " . $res->status_line;
82             } elsif ( $self->is_logged_out($res) ) {
83 0           croak "Login failed because of bad email and password combination.";
84             }
85              
86 0           return 1;
87             }
88              
89             1;
90             __END__