[weboob] [PATCH 1/1] _play_proxy function to handle cookies and redirect using urllib2

Vincent Texier vit at free.fr
Sat Feb 15 21:12:36 CET 2014


Add an attribute "_play_proxy" to the video object to trigger _play_proxy.
First module requiring _play_proxy : dailymotion.

Signed-off-by: Vincent Texier <vit at free.fr>
---
 modules/dailymotion/pages.py             |    6 +++-
 weboob/tools/application/media_player.py |   55 ++++++++++++++++++++++++++++--
 2 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/modules/dailymotion/pages.py b/modules/dailymotion/pages.py
index fda40a4..a6c7b21 100644
--- a/modules/dailymotion/pages.py
+++ b/modules/dailymotion/pages.py
@@ -136,7 +136,11 @@ class VideoPage(BasePage):
         else:
             raise BrokenPageError(u'Unable to extract video URL')
 
-        video.url = info[max_quality]
+        video.url = unicode(info[max_quality])
+
+        # dailymotion video url is protected by a redirection with cookie verification
+        # so we need to do a "play_proxy" using urllib2 proxy streaming to handle this
+        video._play_proxy = True
 
         video.set_empty_fields(NotAvailable)
 
diff --git a/weboob/tools/application/media_player.py b/weboob/tools/application/media_player.py
index 47f4b80..9d44bb5 100644
--- a/weboob/tools/application/media_player.py
+++ b/weboob/tools/application/media_player.py
@@ -19,7 +19,9 @@
 
 
 import os
-from subprocess import PIPE, Popen
+import cookielib
+import urllib2
+from subprocess import Popen, PIPE
 
 from weboob.tools.log import getLogger
 
@@ -83,12 +85,18 @@ class MediaPlayer(object):
         if media.url.startswith('rtmp'):
             self._play_rtmp(media, player_name, args=player_args)
         else:
-            self._play_default(media, player_name)
+            self._play_default(media, player_name, args=player_args)
 
-    def _play_default(self, media, player_name):
+    def _play_default(self, media, player_name, args):
         """
         Play media.url with the media player.
         """
+        # if flag play_proxy...
+        if hasattr(media, '_play_proxy') and media._play_proxy == True:
+           # use wget to handle redirect and cookies
+            self._play_proxy(media, player_name, args)
+            return None
+
         args = player_name.split(' ')
 
         player_name = args[0]
@@ -97,6 +105,47 @@ class MediaPlayer(object):
         print 'Invoking "%s".' % (' '.join(args))
         os.spawnlp(os.P_WAIT, player_name, *args)
 
+    def _play_proxy(self, media, player_name, args):
+        """
+        Load data with python urllib2 and pipe data to a media player.
+
+        We need this function for url that use redirection and cookies.
+        This function is used if the non-standard
+        non-API compliant '_play_proxy' attribute of the 'media' object is defined and is True.
+        """
+        if args is None:
+            for (binary, stdin_args) in PLAYERS:
+                if binary == player_name:
+                    args = stdin_args
+
+        assert args is not None
+
+        print ':: Play_proxy streaming from %s' % media.url
+        print ':: to %s %s' % (player_name, args)
+        print player_name + ' ' + args
+        proc = Popen(player_name + ' ' + args, stdin=PIPE, shell=True)
+
+        # Handle cookies (and redirection 302...)
+        cj = cookielib.CookieJar()
+        url_opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
+
+        url_handler = url_opener.open(media.url)
+        file_size = int(url_handler.info().getheaders("Content-Length")[0])
+        file_size_dl = 0
+        block_sz = 8192
+        while file_size_dl < file_size:
+            _buffer = url_handler.read(block_sz)
+            if not buffer:
+                break
+
+            file_size_dl += len(_buffer)
+            try:
+                #print "DOWNLOAD SENDING TO TRANSCODER...DOWNLOADED=%d SIZE=%d" %(file_size_dl, file_size)
+                proc.stdin.write(_buffer)
+            except:
+                print "play_proxy broken pipe. Can't write anymore."
+                break
+
     def _play_rtmp(self, media, player_name, args):
         """
         Download data with rtmpdump and pipe them to a media player.
-- 
1.7.9.5




More information about the weboob mailing list