Add support for new Youtube login
authorMaximilian Rehkopf <otakon@gmx.net>
Mon, 31 May 2010 19:14:34 +0000 (21:14 +0200)
committerRalf Ertzinger <ralf@skytale.net>
Mon, 31 May 2010 19:20:39 +0000 (21:20 +0200)
videosite/AsyncFileGetter.pm
videosite/AsyncWgetFileGetter.pm [new file with mode: 0644]
videosite/YouTubeGrabber.pm

index 56aa835..7a67b43 100644 (file)
@@ -35,6 +35,7 @@ sub get {
     my $video = shift;
     my $dlfile;
     my $dirname;
+    my $cookie = "";
 
     $dlfile = sprintf($self->_getval('FILEPATTERN'),
         $self->_encode($video->{'SOURCE'}),
@@ -53,7 +54,8 @@ sub get {
 
     my (undef, $tmpfile) = tempfile('videosite.tmp.XXXXXXXXXXXX', DIR => $dirname);
 
-    my $cmdline = "( GET \"$video->{'DLURL'}\" > \"$tmpfile\" && mv \"$tmpfile\" \"$dlfile\" && chmod =rw \"$dlfile\" || rm -f \"$tmpfile\" ) &";
+    $cookie = "-H \"Cookie: $video->{'COOKIE'}\"" if (defined $video->{'COOKIE'});
+    my $cmdline = "( GET $cookie \"$video->{'DLURL'}\" > \"$tmpfile\" && mv \"$tmpfile\" \"$dlfile\" && chmod =rw \"$dlfile\" || rm -f \"$tmpfile\" ) &";
     $self->debug(encode_base64($cmdline));
     system($cmdline);
 
diff --git a/videosite/AsyncWgetFileGetter.pm b/videosite/AsyncWgetFileGetter.pm
new file mode 100644 (file)
index 0000000..ce68046
--- /dev/null
@@ -0,0 +1,62 @@
+# (c) 2007 by Ralf Ertzinger <ralf@camperquake.de>
+#     2008-2009 by Christian Garbs <mitch@cgarbs.de>
+#     2010 by Maximilian Rehkopf <otakon@gmx.net>
+# licensed under GNU GPL v2
+#
+# A getter which will download the media to a local file storage
+# in the background using wget
+#
+
+package videosite::AsyncWgetFileGetter;
+
+use videosite::FileGetter;
+@ISA = qw(videosite::FileGetter);
+
+use strict;
+use File::Basename;
+use File::Temp qw(tempfile);
+use MIME::Base64;
+
+sub new {
+    my $class = shift;
+    my $self = $class->SUPER::new();
+
+    $self->{'NAME'} = 'asyncwgetfilegetter';
+
+    bless($self, $class);
+    $self->_prepare_parameters();
+
+    return $self;
+}
+
+sub get {
+    my $self = shift;
+    my $video = shift;
+    my $dlfile;
+    my $dirname;
+    my $cookie = "";
+
+    $dlfile = sprintf($self->_getval('FILEPATTERN'),
+        $self->_encode($video->{'SOURCE'}),
+        $self->_encode($video->{'ID'}),
+        $self->_encode($video->{'TITLE'}),
+        $self->_encode($video->{'DLURL'}),
+        $self->_encode($video)->{'URL'});
+
+    $dirname = dirname($dlfile);
+    if ($self->_diskfree($dirname) < $self->_getval('MINFREE')) {
+        $self->error("Not enough free space to download");
+        return 0;
+    }
+
+    $self->debug('Going to download %s to %s', $video->{'DLURL'}, $dlfile);
+
+    my (undef, $tmpfile) = tempfile('videosite.tmp.XXXXXXXXXXXX', DIR => $dirname);
+
+    $cookie = "--header=\"Cookie: $video->{'COOKIE'}\"" if (defined $video->{'COOKIE'});
+    my $cmdline = "( wget -q -O\"$tmpfile\" $cookie \"$video->{'DLURL'}\" && mv \"$tmpfile\" \"$dlfile\" && chmod =rw \"$dlfile\" || rm -f \"$tmpfile\" ) &";
+    $self->debug(encode_base64($cmdline));
+    system($cmdline);
+
+    return 1;
+}
index 5d328de..86b21bd 100644 (file)
@@ -77,6 +77,7 @@ sub _parse {
     $metadata->{'SOURCE'} = $self->{'NAME'};
     $metadata->{'TITLE'} = undef;
     $metadata->{'DLURL'} = undef;
+    $metadata->{'COOKIE'} = undef;
 
     $self->debug("Matched id %s from pattern %s", $2, $pattern);
 
@@ -93,7 +94,9 @@ sub _parse {
     if ($r->base->as_string() =~ m,/verify_age,) {
         $self->debug('Video requires age verification');
         $ua->cookie_jar($jar);
-        $r = $self->__login($videourl, $ua);
+        my @logindata = $self->__login($videourl, $ua);
+        $r = $logindata[0];
+        $metadata->{'COOKIE'} = $logindata[1];
         unless(defined($r)) {
             $self->error('Could not log into YouTube');
             return undef;
@@ -153,7 +156,7 @@ sub _parse {
                         $fmt =~ s/%([[:xdigit:]]{2})/chr(hex($1))/ge;
                         @fmt = split(/,/, $fmt);
                         foreach (@fmt) {
-                            split(/\//);
+                            @_=split(/\//);
                             $urls{$_[0]} =  sprintf('http://www.youtube.com/get_video?video_id=%s&fmt=%d&t=%s', 
                                 $metadata->{'ID'},
                                 $_[0],
@@ -249,14 +252,43 @@ sub __login {
         return $found;
     }
 
+    sub get_all_cookies {
+
+        my $jar = shift;
+        my $key = shift;
+        my $val = "";
+        $jar->scan(sub { $val .= "; " if !( $val eq "" ); $val .= "$_[1]=$_[2]" });
+
+        return $val;
+    }
+
     if (($user eq '') or ($pass eq '')) {
         $self->error('No username or password defined for YouTube');
         return undef;
     }
 
     $self->debug('Logging in');
-    $r = $ua->post('http://www.youtube.com/signup', { 'next' => '/', 'current_form' => 'login', 'action_login' => '1', 'username' => $user, 'password' => $pass });
-
+    $r = $ua->get('https://www.google.com/accounts/ServiceLoginAuth?service=youtube');
+    $c = $r->decoded_content();
+    $p = HTML::TokeParser->new(\$c);
+    while (my $tag = $p->get_tag('input')) {
+        if ($tag->[1]{name} eq 'GALX') {
+            $token = $tag->[1]{value};
+            last;
+        }
+    }
+    $self->debug("GALX = .$token");
+    $r = $ua->post('https://www.google.com/accounts/ServiceLoginAuth?service=youtube', { 'service' => 'youtube', 'Email' => $user, 'Passwd' => $pass, 'GALX' => $token });
+    $c = $r -> decoded_content();
+    $p = HTML::TokeParser->new(\$c);
+    while (my $tag = $p->get_tag('script')) {
+        if($p->get_text() =~ /location\.replace\("(.+)"\)/) {
+            $token = $1;
+            $token =~ s/\\x([A-Fa-f0-9]{2})/pack('C', hex($1))/seg;
+            last;
+        }
+    }
+    $r = $ua->get($token);
     unless(check_cookie($ua->cookie_jar, 'LOGIN_INFO')) {
         $self->error('Could not log into YouTube');
         return undef;
@@ -270,7 +302,7 @@ sub __login {
         $c = $r->decoded_content();
         $p = HTML::TokeParser->new(\$c);
         while (my $tag = $p->get_tag('script')) {
-            if ($p->get_text() =~ /gXSRF_token = '(.+)'/) {
+            if ($p->get_text() =~ /'XSRF_TOKEN': '(.+)'/) {
                 $token = $1;
                 last;
             }
@@ -285,12 +317,16 @@ sub __login {
         $r = $ua->post($r->base->as_string, { 'next_url' => $r->base->path, 'action_confirm' => 'Confirm Birth Date', 'session_token' => $token });
     }
 
-    unless(check_cookie($ua->cookie_jar, 'is_adult')) {
-        $self->error('Could not authenticate session');
-        return undef;
-    }
+# Apparently there is no longer a specific "is_adult" cookie
+# or, by the looks of it, anything similar
+#
+#    unless(check_cookie($ua->cookie_jar, 'is_adult')) {
+#        $self->error('Could not authenticate session');
+#        return undef;
+#    }
 
-    return $ua->get($videourl);
+    my $cookie = get_all_cookies($ua->cookie_jar);
+    return ($ua->get($videourl), $cookie);
 }
 
 1;