Replace use of LWP::Simple in all grabbers by $self->simple_get()
[videosite.git] / videosite / BlipTVGrabber.pm
1 # (c) 2007 by Ralf Ertzinger <ralf@camperquake.de>
2 # licensed under GNU GPL v2
3 #
4 # Grabber for blip.tv
5
6 package videosite::BlipTVGrabber;
7
8 use videosite::GrabberBase;
9 @ISA = qw(videosite::GrabberBase);
10
11 use URI;
12 use URI::QueryParam;
13 use HTML::Parser;
14 use XML::Simple;
15 use Data::Dumper;
16
17 use strict;
18
19 sub new {
20     my $class = shift;
21     my $self = $class->SUPER::new();
22
23     $self->{'NAME'} = 'bliptv';
24     $self->{'PATTERNS'} = ['(http://(?:[-a-zA-Z0-9_.]+\.)*blip.tv/file/(\d+)(?:\?\S+)?)',
25                            '(http://blip\.tv/play/(\w+)$)'];
26
27     bless($self, $class);
28     $self->_prepare_parameters();
29
30     return $self;
31 }
32
33 sub _parse {
34     my $self = shift;
35     my $url = shift;
36     my $pattern = shift;
37     my $content;
38     my $metadata = {};
39     my $p = HTML::Parser->new(api_version => 3);
40     my @accum;
41     my @text;
42     my $e;
43     my $xml = undef;
44     my $ua = $self->ua();
45
46     $url =~ m|$pattern|;
47     $url = $1;
48
49     $metadata->{'URL'} = $url;
50     $metadata->{'ID'} = $2;
51     $metadata->{'TYPE'} = 'video';
52     $metadata->{'SOURCE'} = $self->{"NAME"};
53     $metadata->{'TITLE'} = undef;
54     $metadata->{'DLURL'} = undef;
55
56     if ($pattern eq $self->{'PATTERNS'}->[0]) {
57         # blip.tv/file pattern
58         unless(defined($content = $self->simple_get(sprintf('http://blip.tv/file/%s', $2), $ua))) {
59             $self->error('Could not download page');
60             return undef;
61         }
62
63         $p->handler(start => \@accum, "tagname, attr");
64         $p->handler(text => \@text, "text");
65         $p->report_tags(qw(script));
66         $p->utf8_mode(1);
67         $p->parse($content);
68
69         # Look for the post id in the javascript code
70         foreach $e (@text) {
71             if ($e->[0] =~ m|player.setPostsId\((\d+)\)|s) {
72                 $xml = $1;
73             }
74         }
75     } elsif ($pattern eq $self->{'PATTERNS'}->[1]) {
76         my $r;
77         my $u;
78
79         $ua->max_redirect(0);
80         $r = $ua->get(sprintf('http://blip.tv/play/%s', $2));
81
82         unless(defined($r)) {
83             $self->error('Could not download page');
84             return undef;
85         }
86         unless($r->is_redirect()) {
87             $self->error('Expected redirect, but got none');
88             return undef;
89         }
90         $u = URI->new($r->header('Location'));
91         $u = $u->query_param("file");
92
93         unless(defined($u)) {
94             $self->error('Did not find file parameter in URL');
95             return undef;
96         }
97         $u =~ m|^http://blip.tv/rss/flash/(\d+)$|;
98         $xml = $1;
99
100     } else {
101         $self->error("Don't know how to handle that pattern yet");
102         return undef;
103     }
104
105     unless(defined($xml)) { 
106         $self->error("Could not find post id");
107         return undef;
108     }
109
110     # Download the XML file containing the stream information
111     $ua->max_redirect(7);
112     unless(defined($content = $self->simple_get(sprintf('http://blip.tv/rss/flash/%s', $xml), $ua))) {
113         $self->error('Could not download XML metadata');
114         return undef;
115     }
116
117     $xml = XML::Simple::XMLin($content, KeepRoot => 1);
118     $metadata->{'DLURL'} = $xml->{'rss'}->{'channel'}->{'item'}->{'enclosure'}->{'url'};
119     $metadata->{'TITLE'} = $xml->{'rss'}->{'channel'}->{'item'}->{'media:title'};
120
121     unless(defined($metadata->{'DLURL'}) && defined($metadata->{'TITLE'})) {
122         $self->error('Could not determine download URL');
123         return undef;
124     }
125
126     return $metadata;
127 }
128
129 1;