Add support for new Youtube login
[videosite.git] / videosite / YouTubeGrabber.pm
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;