package Plagger::Plugin::CustomFeed::YouTube_dev; use strict; use warnings; use base qw( Plagger::Plugin ); use Plagger::Enclosure; use Plagger::UserAgent; use Plagger::Date; use LWP::Simple; use XML::Simple; sub register { my($self, $context) = @_; $context->register_hook( $self, 'subscription.load' => \&load, ); } sub load { my($self, $context) = @_; my $feed = Plagger::Feed->new; $feed->aggregator(sub { $self->aggregate(@_) }); $context->subscription->add($feed); } sub aggregate { my($self, $context, $args) = @_; my $q = $self->conf->{query}; $q =~ s/\s/\+/g; my $file = $self->cache->path_to('youtube_search_result.html'); $context->log( info => 'Getting YouTube search results for ' . $self->conf->{query} ); my $ua = Plagger::UserAgent->new; my $feed = Plagger::Feed->new; $feed->type('youtubesearch'); $feed->title('YouTube Search - ' . $self->conf->{query}); my $page = $self->conf->{page} || 1; my $sort = $self->conf->{sort} || 'video_date_uploaded'; for ( 1 .. $page ){ my $res = $ua->mirror("http://youtube.com/results?search=$q&sort=$sort&page=$_"=>$file); if($res->is_error){ $context->log( error => $res->status_line ); return; } open my $fh, "<:encoding(utf-8)", $file or return $context->log(error => "$file: $!"); my (@videos, $data, $title_flag, $tag_flag, $video_details, $video_id); while (<$fh>) { # get id m!
! and $title_flag = 1; m!(.+)! and do { if($title_flag){ $data->{id} = $1; $title_flag = 0; } }; m!profile\?user=! and do { my $dev_id = $self->conf->{dev_id} || 'zlKBJU0dhdM'; $video_details = get_details($dev_id,$data->{id}); $data->{title} = $video_details->{title}; $data->{image}->{url} = $video_details->{thumbnail_url}; $data->{description} = $video_details->{description}; $data->{tags} = $video_details->{tags}; $data->{author} = $video_details->{author}; $data->{date} = Plagger::Date->from_epoch($video_details->{upload_time}); $context->log( info => 'Got ' . $data->{title}); my $entry = Plagger::Entry->new; $entry->title($data->{title}); $entry->link('http://youtube.com/watch?v=' . $data->{id}); $entry->icon({ url => $data->{image}->{url}, }); $entry->summary($data->{description}); $entry->body($data->{description}); $entry->author($data->{author}); $entry->date($data->{date}); # tags while( $data->{tags} =~ /(.*)<\/a>/gms){ $entry->add_tag($1); } # enclosure my $video_url = $self->cache->get_callback( "item-" . $entry->link, sub { my $res = $ua->fetch($entry->link); if ($res->is_error){ $context->log( error => $res->status_line ); return; } my $url; if ($res->content =~ /&t=([^&]+)/gms){ $url = 'http://youtube.com/get_video?video_id=' . $data->{id} . "&t=$1"; } return $url; }, '24 hours', ); if ($video_url) { my $video_id = ( $video_url =~ /video_id=(\w+)/ )[0]; my $enclosure = Plagger::Enclosure->new; $enclosure->url( URI->new($video_url) ); $enclosure->type('video/x-flv'); $enclosure->filename("$video_id.flv"); $entry->add_enclosure($enclosure); } $feed->add_entry($entry); $data = {}; }; } } $context->update->add($feed); } sub get_details{ my($dev_id,$video_id) = @_; my $youtube_url = "http://www.youtube.com/api2_rest?method=youtube.videos.get_details&dev_id=$dev_id&video_id=$video_id"; my $youtube_xml = get ($youtube_url) or die("can't get xml"); my $parser = XML::Simple->new(); my $xml_ref = $parser->XMLin("$youtube_xml"); return $xml_ref->{'video_details'}; } 1; __END__ =head1 NAME Plagger::Plugin::CustomFeed::YouTube_dev - Get YouTube search result or rss =head1 SYNOPSIS - module: CustomFeed::YouTube config: query: Twenty Four sort: video_date_uploaded page: 5 =head1 DESCRIPTION This plugin fetches the result of YouTube search or the rss of a specified tag and get the details of the video via YouTube API. =head1 CONFIG =over 4 =item query Specify search query. =item sort Set sort condition. Available condisions are below. Default is video_date_uploaded. relevance video_date_uploaded title_sort n video_view_count rating_sort =item page Number of pages of search result you get. Default is 1. =item dev_id YouTube Developer ID =back =head1 AUTHOR Gosuke Miyashita =head1 SEE ALSO L =cut