fix quoting in AsyncWgetFileGetter again
[videosite.git] / videosite / VimeoGrabber.pm
1 # (c) 2007 by Ralf Ertzinger <ralf@camperquake.de>
2 # licensed under GNU GPL v2
3 #
4 # Grabber for vimeo.com
5
6 package videosite::VimeoGrabber;
7
8 use videosite::GrabberBase;
9 @ISA = qw(videosite::GrabberBase);
10
11 use HTML::TokeParser;
12 use videosite::JSArrayParser;
13 use Data::Dumper;
14
15 use strict;
16
17 sub new {
18     my $class = shift;
19     my $self = $class->SUPER::new(
20         NAME => 'vimeo',
21         _SELFTESTURL => 'http://vimeo.com/35055590',
22         _SELFTESTTITLE => 'Hello',
23         PATTERNS => ['(http://(?:[-a-zA-Z0-9_.]+\.)*vimeo.com/(?:m/)?(\d+))'],
24         @_,
25     );
26
27     return bless($self, $class);
28 }
29
30 sub _parse {
31     my $self = shift;
32     my $url = shift;
33     my $pattern = shift;
34     my $content;
35     my $metadata = {};
36     my $p;
37     my $e;
38     my $dlurl;
39     my $hd;
40     my $dlpath;
41     my $timestamp;
42     my $hash;
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     # Get the XML file containing the video metadata
55     unless(defined($content = $self->simple_get(sprintf('http://vimeo.com/%s', $2)))) {
56         $self->error('Could not download site');
57         return undef;
58     }
59
60     $p = HTML::TokeParser->new(\$content);
61
62     while ($e = $p->get_tag('script')) {
63         if ($e->[0] eq 'script') {
64             my $t = $p->get_text();
65
66             if ($t =~ m|clip\d+_\d+ = (.*\});Player|s) {
67                 my $jsp = videosite::JSArrayParser->new();
68                 my $r;
69
70                 $self->debug("Found raw config: %s", $1);
71                 $r = $jsp->parse($1);
72
73                 unless(defined($r)) {
74                     $self->error("Found information hash, but could not parse");
75                     return undef;
76                 }
77
78                 $self->debug("Found parsed config: %s", Dumper($r));
79
80                 unless(exists($r->{'config'}->{'request'})) {
81                     $self->error("Required information not found in hash");
82                     return undef;
83                 }
84
85                 $metadata->{'TITLE'} = $r->{'config'}->{'video'}->{'title'};
86                 $hd = grep { $_ eq 'hd' } @{$r->{'config'}->{'video'}->{'files'}->{'h264'}};
87                 $self->debug("HD: %d", $hd);
88                 $r = $r->{'config'}->{'request'};
89
90                 $metadata->{'DLURL'} = sprintf("http://%s/play_redirect?clip_id=%d&sig=%s&time=%d&quality=%s&codecs=H264,VP8,VP6",
91                         $r->{'player_url'},
92                         $metadata->{'ID'},
93                         $r->{'signature'},
94                         $r->{'timestamp'},
95                         $hd?'hd':'sd',
96                         );
97             }
98         }
99     }
100
101     unless(defined($metadata->{'DLURL'}) && defined($metadata->{'TITLE'})) {
102         $self->error('Could not extract download URL and title');
103         return undef;
104     }
105
106     return $metadata;
107 }
108
109 1;