fix quoting in AsyncWgetFileGetter again
[videosite.git] / videosite / RedTubeGrabber.pm
1 # (c) 2008 by Ralf Ertzinger <ralf@camperquake.de>
2 # licensed under GNU GPL v2
3 #
4 # Grabber for redtube.com
5 #
6 # Algorithm for the file name hash reverse engineered by
7 # Maximilian Rehkopf  <otakon at gmx dot net>
8
9 package videosite::RedTubeGrabber;
10
11 use videosite::GrabberBase;
12 @ISA = qw(videosite::GrabberBase);
13
14 use HTML::TokeParser;
15 use Data::Dumper;
16
17 use strict;
18
19 sub new {
20     my $class = shift;
21     my $self = $class->SUPER::new(
22         NAME => 'redtube',
23         _SELFTESTURL => 'http://www.redtube.com/8269',
24         _SELFTESTTITLE => 'Porn bloopers with pretty girl',
25         PATTERNS => ['(http://(?:[-a-zA-Z0-9_.]+\.)*redtube.com/(\d+))'],
26         @_,
27     );
28
29     return bless($self, $class);
30 }
31
32 sub div($$) {
33     return ($_[0] - ($_[0] % $_[1])) / $_[1];
34 }
35
36 sub digitatindex($$) {
37     return div($_[0], 10**$_[1]) % 10;
38 }
39
40 sub mkfilename($) {
41     my $id = shift;
42     my $i = 7;
43     my $q = 0;
44     my $q2 = 0;
45     my @key = split(//, "R15342O7K9HBCDXFGAIJ8LMZ6PQ0STUVWEYN");
46     my $hash = "";
47
48     # Calculate a weighed digit sum of the id
49     $q += ($_*($i--)) for reverse(split(//, $id));
50
51     # Now calculate the digit sum of the digit sum
52     $q2 += $_ for split(//, $q);
53
54     # The rest are lookups into @key and the second digit sum,
55     # based on the second digit sum and the original id
56     $hash .= $key[digitatindex($id,3)+$q2+3];
57     $hash .= digitatindex($q2, 0);
58     $hash .= $key[digitatindex($id,6)+$q2+2];
59     $hash .= $key[digitatindex($id,4)+$q2+1];
60     $hash .= $key[digitatindex($id,1)+$q2+6];
61     $hash .= $key[digitatindex($id,5)+$q2+5];
62     $hash .= digitatindex($q2, 1);
63     $hash .= $key[digitatindex($id,2)+$q2+7];
64     $hash .= $key[digitatindex($id,0)+$q2+4];
65
66     return (sprintf("%07d", $id/1000), $hash);
67 }
68
69 sub _parse {
70     my $self = shift;
71     my $url = shift;
72     my $pattern = shift;
73     my $ua = $self->ua();
74     my $content;
75     my $metadata = {};
76     my $p;
77     my $r;
78     my $tag;
79     my $dir;
80     my $hash;
81
82     $url =~ m|$pattern|;
83     $url = $1;
84
85     $metadata->{'URL'} = $url;
86     $metadata->{'ID'} = $2;
87     $metadata->{'TYPE'} = 'video';
88     $metadata->{'SOURCE'} = $self->{'NAME'};
89     $metadata->{'TITLE'} = undef;
90     $metadata->{'DLURL'} = undef;
91
92     # Set the cookies necessary to get the video data
93     $ua->cookie_jar->set_cookie(undef, 'pp', '1', '/', '.redtube.com');
94
95     unless(defined($content = $self->simple_get(sprintf("http://www.redtube.com/%s", $2), $ua))) {
96         $self->error('Could not download page');
97         return undef;
98     }
99
100     $p = HTML::TokeParser->new(\$content);
101
102     # Look for the title
103     while ($tag = $p->get_tag('title', 'script')) {
104         if ('title' eq $tag->[0]) {
105             my $t = $p->get_text();
106             $metadata->{'TITLE'} = $t;
107             $metadata->{'TITLE'} =~ s/ \| Redtube.*//;
108         } elsif ('script' eq $tag->[0]) {
109             my $t = $p->get_text();
110
111             if ($t =~ m|so\.addParam\("flashvars","([^\x22]+)"|) {
112                 my %h;
113
114                 $self->debug("Found flashvars: %s", $1);
115                 %h = map { $self->decode_hexurl($_) } split(/[&=]/, $1);
116
117                 $self->debug("Decoded flashvars: %s", Dumper(\%h));
118
119                 if (exists($h{mp4_url})) {
120                     $metadata->{'DLURL'} = $h{mp4_url};
121                 }
122             }
123         }
124     }
125
126     unless(defined($metadata->{'DLURL'}) && defined($metadata->{'TITLE'})) {
127         $self->error('Could not extract download URL and title');
128         return undef;
129     }
130
131     return $metadata;
132 }
133
134 1;