| 1 | # |
|---|
| 2 | # $Id: Util.pm 11 2007-04-09 04:34:01Z hironori.yoshida $ |
|---|
| 3 | # |
|---|
| 4 | package WebService::YouTube::Util; |
|---|
| 5 | use strict; |
|---|
| 6 | use warnings; |
|---|
| 7 | use version; our $VERSION = qv('1.0.1'); |
|---|
| 8 | |
|---|
| 9 | use Carp; |
|---|
| 10 | use LWP::UserAgent; |
|---|
| 11 | use URI::Escape qw(uri_escape uri_escape_utf8); |
|---|
| 12 | use Encode; |
|---|
| 13 | |
|---|
| 14 | sub rss_uri { |
|---|
| 15 | my ( $class, $type, $arg ) = @_; |
|---|
| 16 | |
|---|
| 17 | if ( $type ne 'global' && $type ne 'tag' && $type ne 'user' ) { |
|---|
| 18 | croak "type of $type is not supported"; |
|---|
| 19 | } |
|---|
| 20 | |
|---|
| 21 | if ( Encode::is_utf8($arg) ) { |
|---|
| 22 | $arg = uri_escape_utf8($arg); |
|---|
| 23 | } |
|---|
| 24 | else { |
|---|
| 25 | $arg = uri_escape($arg); |
|---|
| 26 | } |
|---|
| 27 | |
|---|
| 28 | if ( $type eq 'user' ) { |
|---|
| 29 | $arg = lc $arg . '/videos'; |
|---|
| 30 | } |
|---|
| 31 | return "http://www.youtube.com/rss/$type/$arg.rss"; |
|---|
| 32 | } |
|---|
| 33 | |
|---|
| 34 | sub rest_uri { |
|---|
| 35 | my ( $class, $dev_id, $method, $fields ) = @_; |
|---|
| 36 | |
|---|
| 37 | my $query = q{}; |
|---|
| 38 | if ($fields) { |
|---|
| 39 | foreach my $key ( keys %{$fields} ) { |
|---|
| 40 | my $value = $fields->{$key}; |
|---|
| 41 | if ( Encode::is_utf8($value) ) { |
|---|
| 42 | $value = uri_escape_utf8($value); |
|---|
| 43 | } |
|---|
| 44 | else { |
|---|
| 45 | $value = uri_escape($value); |
|---|
| 46 | } |
|---|
| 47 | $query .= sprintf '&%s=%s', $key, $value; |
|---|
| 48 | } |
|---|
| 49 | } |
|---|
| 50 | return |
|---|
| 51 | "http://www.youtube.com/api2_rest?dev_id=$dev_id&method=$method$query"; |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | sub get_video_uri { |
|---|
| 55 | my ( $class, $video, $args ) = @_; |
|---|
| 56 | |
|---|
| 57 | if ( !$video ) { |
|---|
| 58 | return; |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | $args->{ua} ||= LWP::UserAgent->new; |
|---|
| 62 | |
|---|
| 63 | my ( $video_id, $video_uri ); |
|---|
| 64 | if ( ref $video ) { |
|---|
| 65 | $video_id = $video->id; |
|---|
| 66 | $video_uri = $video->url; |
|---|
| 67 | } |
|---|
| 68 | else { |
|---|
| 69 | $video_id = $video; |
|---|
| 70 | } |
|---|
| 71 | $video_uri ||= "http://youtube.com/?v=$video_id"; |
|---|
| 72 | |
|---|
| 73 | my $res = $args->{ua}->get($video_uri); |
|---|
| 74 | if ( !$res->is_success ) { |
|---|
| 75 | carp $res->status_line; |
|---|
| 76 | return; |
|---|
| 77 | } |
|---|
| 78 | |
|---|
| 79 | my $content = $res->content; |
|---|
| 80 | if ( $content =~ m{"/player2\.swf\?([^"]+)",\s*"movie_player"}msx ) { |
|---|
| 81 | return "http://youtube.com/get_video.php?$1"; |
|---|
| 82 | } |
|---|
| 83 | if ( $content =~ m{class="errorBox"[^>]*>\s*([^<]+?)\s*<}msx ) { |
|---|
| 84 | carp "$video_id: $1"; |
|---|
| 85 | return; |
|---|
| 86 | } |
|---|
| 87 | carp "$video_id: got a page but it is invalid page\n$content"; |
|---|
| 88 | return; |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | sub get_video { |
|---|
| 92 | my ( $class, $video, $args ) = @_; |
|---|
| 93 | |
|---|
| 94 | if ( !$video ) { |
|---|
| 95 | return; |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | $args->{ua} ||= LWP::UserAgent->new; |
|---|
| 99 | |
|---|
| 100 | my $video_uri = $class->get_video_uri( $video, $args ); |
|---|
| 101 | if ( !$video_uri ) { |
|---|
| 102 | return; |
|---|
| 103 | } |
|---|
| 104 | my $res = $args->{ua}->get($video_uri); |
|---|
| 105 | if ( !$res->is_success ) { |
|---|
| 106 | carp $res->status_line; |
|---|
| 107 | return; |
|---|
| 108 | } |
|---|
| 109 | return $res->content; |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | 1; |
|---|
| 113 | |
|---|
| 114 | __END__ |
|---|
| 115 | |
|---|
| 116 | =head1 NAME |
|---|
| 117 | |
|---|
| 118 | WebService::YouTube::Util - Utility for WebService::YouTube |
|---|
| 119 | |
|---|
| 120 | =head1 VERSION |
|---|
| 121 | |
|---|
| 122 | This document describes WebService::YouTube::Util version 1.0.1 |
|---|
| 123 | |
|---|
| 124 | =head1 SYNOPSIS |
|---|
| 125 | |
|---|
| 126 | use WebService::YouTube::Util; |
|---|
| 127 | |
|---|
| 128 | # Get an URI of RSS |
|---|
| 129 | my $uri = WebService::YouTube::Util->rss_uri( 'global', 'recently_added' ); |
|---|
| 130 | |
|---|
| 131 | # Get an URI of REST API |
|---|
| 132 | my $uri = WebService::YouTube::Util->rest_uri( $dev_id, |
|---|
| 133 | 'youtube.videos.list_by_tag', |
|---|
| 134 | { tag => 'monkey' } |
|---|
| 135 | ); |
|---|
| 136 | |
|---|
| 137 | # Get a downloadable URI |
|---|
| 138 | my $uri = WebService::YouTube::Util->get_video_uri('rdwz7QiG0lk'); |
|---|
| 139 | |
|---|
| 140 | # Get a video which type is .flv |
|---|
| 141 | my $content = WebService::YouTube::Util->get_video('rdwz7QiG0lk'); |
|---|
| 142 | |
|---|
| 143 | =head1 DESCRIPTION |
|---|
| 144 | |
|---|
| 145 | This is an utility for L<WebService::YouTube>. |
|---|
| 146 | |
|---|
| 147 | =head1 SUBROUTINES/METHODS |
|---|
| 148 | |
|---|
| 149 | =head2 rss_uri( $type, $arg ) |
|---|
| 150 | |
|---|
| 151 | Returns a URI of RSS. |
|---|
| 152 | $type should be 'global' or 'tag' or 'user'. |
|---|
| 153 | $arg is required when $type is 'tag' or 'user'. |
|---|
| 154 | |
|---|
| 155 | =head2 rest_uri( $dev_id, $method, \%fields ) |
|---|
| 156 | |
|---|
| 157 | Returns a URI of REST API. |
|---|
| 158 | $dev_id is your developer ID of YouTube. |
|---|
| 159 | $method is a method name like a 'youtube.*.*'. |
|---|
| 160 | %fields can contain optional parameter. |
|---|
| 161 | |
|---|
| 162 | =head2 get_video_uri( $video, \%args ) |
|---|
| 163 | |
|---|
| 164 | Returns a downloadable URI of $video. |
|---|
| 165 | $video should be a video ID or a L<WebService::YouTube::Video> object. |
|---|
| 166 | %args can contain some optional arguments. |
|---|
| 167 | |
|---|
| 168 | =over |
|---|
| 169 | |
|---|
| 170 | =item ua |
|---|
| 171 | |
|---|
| 172 | L<LWP::UserAgent> object |
|---|
| 173 | |
|---|
| 174 | =back |
|---|
| 175 | |
|---|
| 176 | =head2 get_video( $video, \%args ) |
|---|
| 177 | |
|---|
| 178 | Returns a downloaded content of $video. |
|---|
| 179 | $video should be a video ID or a L<WebService::YouTube::Video> object. |
|---|
| 180 | %args can contain some optional arguments. |
|---|
| 181 | |
|---|
| 182 | =over |
|---|
| 183 | |
|---|
| 184 | =item ua |
|---|
| 185 | |
|---|
| 186 | L<LWP::UserAgent> object |
|---|
| 187 | |
|---|
| 188 | =back |
|---|
| 189 | |
|---|
| 190 | =head1 DIAGNOSTICS |
|---|
| 191 | |
|---|
| 192 | =over |
|---|
| 193 | |
|---|
| 194 | =item type of ... is not supported |
|---|
| 195 | |
|---|
| 196 | No such RSS. The type should be 'global' or 'tag' or 'user'. |
|---|
| 197 | |
|---|
| 198 | =item got a page but it is invalid page |
|---|
| 199 | |
|---|
| 200 | Maybe, YouTube is being maintained. :-) |
|---|
| 201 | |
|---|
| 202 | =back |
|---|
| 203 | |
|---|
| 204 | =head1 CONFIGURATION AND ENVIRONMENT |
|---|
| 205 | |
|---|
| 206 | WebService::YouTube::Util requires no configuration files or environment variables. |
|---|
| 207 | |
|---|
| 208 | =head1 DEPENDENCIES |
|---|
| 209 | |
|---|
| 210 | L<WebService::YouTube>, L<LWP::UserAgent>, L<URI::Escape> |
|---|
| 211 | |
|---|
| 212 | =head1 INCOMPATIBILITIES |
|---|
| 213 | |
|---|
| 214 | None reported. |
|---|
| 215 | |
|---|
| 216 | =head1 BUGS AND LIMITATIONS |
|---|
| 217 | |
|---|
| 218 | No bugs have been reported. |
|---|
| 219 | |
|---|
| 220 | Please report any bugs or feature requests to |
|---|
| 221 | C<bug-webservice-youtube@rt.cpan.org>, or through the web interface at |
|---|
| 222 | L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=WebService-YouTube>. |
|---|
| 223 | I will be notified, and then you'll automatically be notified of progress on |
|---|
| 224 | your bug as I make changes. |
|---|
| 225 | |
|---|
| 226 | =head1 AUTHOR |
|---|
| 227 | |
|---|
| 228 | Hironori Yoshida <yoshida@cpan.org> |
|---|
| 229 | |
|---|
| 230 | =head1 LICENSE AND COPYRIGHT |
|---|
| 231 | |
|---|
| 232 | Copyright 2006, Hironori Yoshida <yoshida@cpan.org>. All rights reserved. |
|---|
| 233 | |
|---|
| 234 | This program is free software; you can redistribute it and/or modify it |
|---|
| 235 | under the same terms as Perl itself. See L<perlartistic>. |
|---|
| 236 | |
|---|
| 237 | =cut |
|---|