root/lang/perl/plagger/lib/Plagger/Plugin/Filter/FetchNicoVideo.pm

Revision 25022, 5.1 kB (checked in by mattn, 15 months ago)

File::Pathを追加しないと動かなくなってたので修正。

Line 
1package Plagger::Plugin::Filter::FetchNicoVideo;
2use strict;
3use base qw( Plagger::Plugin );
4
5our $VERSION = 0.02;
6
7use URI::Escape;
8use File::Path qw(mkpath);
9use File::Spec;
10use HTTP::Request;
11use Time::HiRes qw(sleep);
12use Plagger::Enclosure;
13use Plagger::UserAgent;
14use CGI;
15
16sub register {
17    my ( $self, $context ) = @_;
18    $context->register_hook( $self, 'update.entry.fixup' => \&filter, );
19     my $ua = Plagger::UserAgent->new( keep_alive => 1 );
20    $ua->cookie_jar( {} );
21    $ua->post( "https://secure.nicovideo.jp/secure/login?site=niconico" => $self->conf );
22    $self->{ua} = $ua;
23}
24
25sub init {
26    my $self = shift;
27    $self->SUPER::init(@_);
28
29    defined $self->conf->{mail}
30      or Plagger->context->error("conifg 'mail' is not set.");
31    defined $self->conf->{password}
32      or Plagger->context->error("config 'password' is not set.");
33    defined $self->conf->{dir}
34      or Plagger->context->error("config 'dir' is not set.");
35
36    if ( $self->conf->{dir} =~ /^[a-zA-Z]/ && $self->conf->{dir} !~ /:/ ) {
37        $self->conf->{dir} =
38          File::Spec->catfile( Cwd::cwd, $self->conf->{dir} );
39    }
40
41    unless ( -e $self->conf->{dir} && -d _ ) {
42        Plagger->context->log(
43            warn => $self->conf->{dir} . " does not exist. Creating" );
44        mkpath $self->conf->{dir};
45    }
46}
47
48sub filter {
49    my ( $self, $context, $args ) = @_;
50    my $ua    = $self->{ua};
51    my $entry = $args->{entry};
52
53    #get video_id
54    my ($video_id) = $entry->link =~ m!www.nicovideo.jp/watch/(.*)!;
55
56    #get flv url
57    my $res = $ua->get("http://www.nicovideo.jp/api/getflv?v=$video_id");
58    my $q   = CGI->new( $res->content );
59    my $flv_url = $q->param('url');
60
61    unless ($flv_url) {
62        $context->log( warn => "Not Found FLV URL : $video_id" );
63        return;
64    }
65    $context->log( info => "Found FLV URL $flv_url" );
66
67    my $enclosure = Plagger::Enclosure->new;
68    $enclosure->url( URI->new($flv_url) );
69    $enclosure->media_type("video/x-flv");
70
71    #set local path
72    my $filename = $self->conf->{id_as_filename} ? $video_id : $entry->title;
73    utf8::encode($filename);
74    if ( $self->conf->{filename_encode} ) {
75        Encode::from_to( $filename, "utf-8", $self->conf->{filename_encode} );
76    }
77
78    $enclosure->url =~ m!^http://[^/]+(?:smilevideo|nicovideo)\.jp/smile\?(\w)=(?:[^.]+)\.\d+(?:low)?!;
79    my %video_type_of = (
80                         v => 'flv',
81                         m => 'mp4',
82                         s => 'swf',
83                      );
84    my $ext = exists( $video_type_of{$1} ) ? $video_type_of{$1} : "flv";
85   
86    my $path = File::Spec->catfile( $self->conf->{dir}, $filename . ".$ext" );
87
88    unless ( -e $path ) {
89        #access video page
90        $ua->get("http://www.nicovideo.jp/watch/$video_id");
91
92        #download flv file
93        my $req = HTTP::Request->new(GET => $enclosure->url);
94        $context->log(info => "Fetching $video_id FLV File from " . $enclosure->url . "..." );
95        my $res = $ua->request($req, $path);
96        $context->log(warn => "Fetch FLV Error: $video_id" ) if $res->is_error;
97    }else{
98        $context->log(info => "Exist FLV File: $video_id");
99        my $sleeping_time = $self->conf->{interval} || 15;
100        $context->log(info => "sleep $sleeping_time.");
101        sleep( $sleeping_time );
102    }
103
104    #download xml file
105    if ( $self->conf->{download_comment} ) {
106        $path = File::Spec->catfile( $self->conf->{dir}, $filename . ".xml" );
107        unless ( -e $path ) {
108            my $thread_id = $q->param('thread_id');
109            my $post_data =
110                qq!<thread res_from="-500" version="20061206" thread="$thread_id" />"!;
111            my $header = HTTP::Headers->new;
112            $header->header( 'Content-Type' => 'text/xml' );
113            my $req = HTTP::Request->new( 'POST', $q->param('ms'), $header, $post_data );
114            $context->log( info => "Fetching $video_id XML File ... " );
115            $res = $ua->request( $req, $path );
116            $context->log( warn => "Fetch XML Error: $video_id" ) if $res->is_error;
117        }
118    }
119
120    $enclosure->filename($filename);
121    $enclosure->local_path($path);    # set to be used in later plugins
122    if  ($res->header('Content-Length') ) {
123        $enclosure->length( $res->header('Content-Length') );
124    }
125    $enclosure->type( Plagger::Util::mime_type_of($path) );
126    $entry->add_enclosure($enclosure);
127}
128
1291;
130
131__END__
132
133=head1 NAME
134
135Plagger::Plugin::Filter::FetchNicoVideo - Fetch flv file from NicoVideo link
136
137=head1 SYNOPSIS
138
139  - module: Filter::FetchNicoVideo
140    config:
141      mail: your@mailadddres
142      password: yourpassword
143      dir: /path/to/files
144      download_xml: 1 #optional default is 0
145      filename_encode: euc-jp #optional default is utf-8
146      interval: 60 #optional default is 15
147
148=head1 DESCRIPTION
149
150This plugin downloads flv file for each entry which has NicoVideo link.
151
152=head1 CONFIG
153
154=over 4
155
156=item mail password
157
158Your NicoVideo login mail address and password.
159
160=item dir
161
162Directory to store downloaded enclosures. Required.
163
164=item download_xml
165
166IF set, download comment xml file. Optional. Default is off.
167
168=item filename_encode
169
170File name encode. Example: euc-jp / shift_jis. Optional. Default is utf-8.
171
172=item id_as_filename
173
174IF set, set video id as flv file. Default file name is entry title. Optional.
175
176=back
177
178=head1 AUTHOR
179
180Yusuke Wada
181
182=head1 SEE ALSO
183
184L<Plagger>, L<http://www.nicovideo.jp/>
185
186=cut
187
Note: See TracBrowser for help on using the browser.