import cookielib
import ctypes
import datetime
+import gzip
import htmlentitydefs
import httplib
import locale
import re
import socket
import string
+import StringIO
import subprocess
import sys
import time
import urllib
import urllib2
+import zlib
# parse_qs was moved from the cgi module to the urlparse module recently.
try:
self.downloaded = downloaded
self.expected = expected
+class YoutubeDLHandler(urllib2.HTTPHandler):
+ """Handler for HTTP requests and responses.
+
+ This class, when installed with an OpenerDirector, automatically adds
+ the standard headers to every HTTP request and handles gzipped and
+ deflated responses from web servers. If compression is to be avoided in
+ a particular request, the original request in the program code only has
+ to include the HTTP header "Youtubedl-No-Compression", which will be
+ removed before making the real request.
+
+ Part of this code was copied from:
+
+ http://techknack.net/python-urllib2-handlers/
+
+ Andrew Rowls, the author of that code, agreed to release it to the
+ public domain.
+ """
+
+ @staticmethod
+ def deflate(data):
+ try:
+ return zlib.decompress(data, -zlib.MAX_WBITS)
+ except zlib.error:
+ return zlib.decompress(data)
+
+ def http_request(self, req):
+ for h in std_headers:
+ if h in req.headers:
+ del req.headers[h]
+ req.add_header(h, std_headers[h])
+ if 'Youtubedl-no-compression' in req.headers:
+ if 'Accept-encoding' in req.headers:
+ del req.headers['Accept-encoding']
+ del req.headers['Youtubedl-no-compression']
+ return req
+
+ def http_response(self, req, resp):
+ old_resp = resp
+ # gzip
+ if resp.headers.get('Content-encoding', '') == 'gzip':
+ gz = gzip.GzipFile(fileobj=StringIO.StringIO(resp.read()), mode='r')
+ resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code)
+ resp.msg = old_resp.msg
+ # deflate
+ if resp.headers.get('Content-encoding', '') == 'deflate':
+ gz = StringIO.StringIO(self.deflate(resp.read()))
+ resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code)
+ resp.msg = old_resp.msg
+ return resp
+
class FileDownloader(object):
"""File Downloader class.
tmpfilename = self.temp_name(filename)
stream = None
open_mode = 'wb'
- basic_request = urllib2.Request(url, None, std_headers)
- request = urllib2.Request(url, None, std_headers)
+
+ # Do not include the Accept-Encoding header
+ headers = {'Youtubedl-no-compression': 'True'}
+ basic_request = urllib2.Request(url, None, headers)
+ request = urllib2.Request(url, None, headers)
# Establish possible resume length
if os.path.isfile(tmpfilename):
return
# Set language
- request = urllib2.Request(self._LANG_URL, None, std_headers)
+ request = urllib2.Request(self._LANG_URL)
try:
self.report_lang()
urllib2.urlopen(request).read()
'username': username,
'password': password,
}
- request = urllib2.Request(self._LOGIN_URL, urllib.urlencode(login_form), std_headers)
+ request = urllib2.Request(self._LOGIN_URL, urllib.urlencode(login_form))
try:
self.report_login()
login_results = urllib2.urlopen(request).read()
'next_url': '/',
'action_confirm': 'Confirm',
}
- request = urllib2.Request(self._AGE_URL, urllib.urlencode(age_form), std_headers)
+ request = urllib2.Request(self._AGE_URL, urllib.urlencode(age_form))
try:
self.report_age_confirmation()
age_results = urllib2.urlopen(request).read()
# Get video webpage
self.report_video_webpage_download(video_id)
- request = urllib2.Request('http://www.youtube.com/watch?v=%s&gl=US&hl=en&has_verified=1' % video_id, None, std_headers)
+ request = urllib2.Request('http://www.youtube.com/watch?v=%s&gl=US&hl=en&has_verified=1' % video_id)
try:
video_webpage = urllib2.urlopen(request).read()
except (urllib2.URLError, httplib.HTTPException, socket.error), err:
for el_type in ['&el=embedded', '&el=detailpage', '&el=vevo', '']:
video_info_url = ('http://www.youtube.com/get_video_info?&video_id=%s%s&ps=default&eurl=&gl=US&hl=en'
% (video_id, el_type))
- request = urllib2.Request(video_info_url, None, std_headers)
+ request = urllib2.Request(video_info_url)
try:
video_info_webpage = urllib2.urlopen(request).read()
video_info = parse_qs(video_info_webpage)
def _real_initialize(self):
# Retrieve disclaimer
- request = urllib2.Request(self._DISCLAIMER, None, std_headers)
+ request = urllib2.Request(self._DISCLAIMER)
try:
self.report_disclaimer()
disclaimer = urllib2.urlopen(request).read()
'filters': '0',
'submit': "Continue - I'm over 18",
}
- request = urllib2.Request(self._FILTER_POST, urllib.urlencode(disclaimer_form), std_headers)
+ request = urllib2.Request(self._FILTER_POST, urllib.urlencode(disclaimer_form))
try:
self.report_age_confirmation()
disclaimer = urllib2.urlopen(request).read()
while True:
self.report_download_page(query, pagenum)
result_url = self._TEMPLATE_URL % (urllib.quote_plus(query), pagenum)
- request = urllib2.Request(result_url, None, std_headers)
+ request = urllib2.Request(result_url)
try:
page = urllib2.urlopen(request).read()
except (urllib2.URLError, httplib.HTTPException, socket.error), err:
while True:
self.report_download_page(query, pagenum)
result_url = self._TEMPLATE_URL % (urllib.quote_plus(query), pagenum)
- request = urllib2.Request(result_url, None, std_headers)
+ request = urllib2.Request(result_url)
try:
page = urllib2.urlopen(request).read()
except (urllib2.URLError, httplib.HTTPException, socket.error), err:
while True:
self.report_download_page(query, pagenum)
result_url = self._TEMPLATE_URL % (urllib.quote_plus(query), pagenum)
- request = urllib2.Request(result_url, None, std_headers)
+ request = urllib2.Request(result_url)
try:
page = urllib2.urlopen(request).read()
except (urllib2.URLError, httplib.HTTPException, socket.error), err:
while True:
self.report_download_page(playlist_id, pagenum)
- request = urllib2.Request(self._TEMPLATE_URL % (playlist_id, pagenum), None, std_headers)
+ request = urllib2.Request(self._TEMPLATE_URL % (playlist_id, pagenum))
try:
page = urllib2.urlopen(request).read()
except (urllib2.URLError, httplib.HTTPException, socket.error), err:
pagenum = 1
self.report_download_page(username)
- request = urllib2.Request(self._TEMPLATE_URL % (username), None, std_headers)
+ request = urllib2.Request(self._TEMPLATE_URL % (username))
try:
page = urllib2.urlopen(request).read()
except (urllib2.URLError, httplib.HTTPException, socket.error), err:
# Retrieve file webpage with 'Free download' button pressed
free_download_indication = { 'gateway_result' : '1' }
- request = urllib2.Request(url, urllib.urlencode(free_download_indication), std_headers)
+ request = urllib2.Request(url, urllib.urlencode(free_download_indication))
try:
self.report_download_webpage(file_id)
webpage = urllib2.urlopen(request).read()
# General configuration
cookie_processor = urllib2.HTTPCookieProcessor(jar)
- urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()))
- urllib2.install_opener(urllib2.build_opener(cookie_processor))
+ urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler(), cookie_processor, YoutubeDLHandler()))
socket.setdefaulttimeout(300) # 5 minutes should be enough (famous last words)
# Batch file verification