dc6bba72c9ab1d5d3d58a064414e5d5fe09b50bc
[videosite.git] / videosite / YouTubeGrabber.pm
1 # (c) 2007 by Ralf Ertzinger <ralf@camperquake.de>
2 # licensed under GNU GPL v2
3 #
4 # Grabber for youtube.com/de/...
5 #
6 # download strategy revised using
7 # http://www.kde-apps.org/content/show.php?content=41456
8
9 package YouTubeGrabber;
10
11 use GrabberBase;
12 @ISA = qw(GrabberBase);
13
14 use LWP::Simple qw(!get);
15 use HTML::TokeParser;
16 use Data::Dumper;
17
18 use strict;
19
20 sub new {
21     my $class = shift;
22     my $self = $class->SUPER::new();
23
24     $self->{'NAME'} = 'youtube';
25     $self->{'PATTERNS'} = ['(http://(?:[-a-zA-Z0-9_.]+\.)*youtube.(?:com|de|co.uk)/watch\?(?:.+=.+&)*v=([-a-zA-Z0-9_]+))',
26                            '(http://(?:[-a-zA-Z0-9_.]+\.)*youtube.(?:com|de|co.uk)/v/([-a-zA-Z0-9_]+))'];
27
28     bless($self, $class);
29     $self->_prepare_parameters();
30
31     return $self;
32 }
33
34 sub _parse {
35     my $self = shift;
36     my $url = shift;
37     my $pattern = shift;
38     my $content;
39     my $metadata = {};
40     my $p;
41     my $e;
42     my $tag;
43
44     $url =~ m|$pattern|;
45     $url = $1;
46
47     $metadata->{'URL'} = $url;
48     $metadata->{'ID'} = $2;
49     $metadata->{'TYPE'} = 'video';
50     $metadata->{'SOURCE'} = $self->{'NAME'};
51     $metadata->{'TITLE'} = undef;
52     $metadata->{'DLURL'} = undef;
53
54     unless(defined($content = LWP::Simple::get(sprintf('http://youtube.com/watch?v=%s', $2)))) {
55         $self->error('Could not download %s', $url);
56         return undef;
57     }
58
59     $p = HTML::TokeParser->new(\$content);
60
61     while ($tag = $p->get_tag('div', 'meta', 'script')) {
62         if ('meta' eq $tag->[0]) {
63             if ('title' eq $tag->[1]->{'name'}) {
64                 $metadata->{'TITLE'} = $tag->[1]->{'content'};
65                 $self->debug('Title found: %s', $metadata->{'TITLE'});
66             }
67         } elsif ('script' eq $tag->[0]) {
68             $e = $p->get_text();
69             if ($e =~ m|/watch_fullscreen\?(.+)\x27|) {
70                 my %args = map { split(/=/, $_, 2); } split(/&/, $1);
71                 $metadata->{'DLURL'} = sprintf('http://www.youtube.com/get_video.php?video_id=%s&t=%s',
72                         $metadata->{'ID'}, $args{'t'});
73                 $self->debug('URL found: %s', $metadata->{'DLURL'});
74             }
75         } elsif ('div' eq $tag->[0]) {
76             if ('errorBox' eq $tag->[1]->{'class'}) {
77                 $self->error("Could not get video data for youtube %s: %s",
78                         $metadata->{'ID'}, $p->get_trimmed_text());
79                 return undef;
80             }
81         }
82     }
83
84     unless(defined($metadata->{'DLURL'}) && defined($metadata->{'TITLE'})) {
85         $self->error('Could not determine download URL');
86         return undef;
87     }
88
89     return $metadata;
90 }
91
92 1;