Ok, the Escapist test was passing only in my Travis repo, do not ask me why; also...
[youtube-dl] / youtube_dl / FileDownloader.py
index 48c8eb1261a9c68453c85bfce6286f4d83b2b623..ebc2552dfc0933306a2e50b1e4a9b0bc8e501270 100644 (file)
@@ -4,12 +4,14 @@
 from __future__ import absolute_import
 
 import math
+import io
 import os
 import re
 import socket
 import subprocess
 import sys
 import time
+import traceback
 
 if os.name == 'nt':
     import ctypes
@@ -78,6 +80,7 @@ class FileDownloader(object):
     writeinfojson:     Write the video description to a .info.json file
     writesubtitles:    Write the video subtitles to a .srt file
     subtitleslang:     Language of the subtitles to download
+    test:              Download only first bytes to test the downloader.
     """
 
     params = None
@@ -216,6 +219,8 @@ class FileDownloader(object):
         """
         if message is not None:
             self.to_stderr(message)
+        if self.params.get('verbose'):
+            self.to_stderr(u''.join(traceback.format_list(traceback.extract_stack())))
         if not self.params.get('ignoreerrors', False):
             raise DownloadError(message)
         self._download_retcode = 1
@@ -334,8 +339,11 @@ class FileDownloader(object):
             template_dict['epoch'] = int(time.time())
             template_dict['autonumber'] = u'%05d' % self._num_downloads
 
-            template_dict = dict((key, u'NA' if val is None else val) for key, val in template_dict.items())
-            template_dict = dict((k, sanitize_filename(compat_str(v), self.params.get('restrictfilenames'))) for k,v in template_dict.items())
+            sanitize = lambda k,v: sanitize_filename(
+                u'NA' if v is None else compat_str(v),
+                restricted=self.params.get('restrictfilenames'),
+                is_id=(k==u'id'))
+            template_dict = dict((k, sanitize(k, v)) for k,v in template_dict.items())
 
             filename = self.params['outtmpl'] % template_dict
             return filename
@@ -413,11 +421,8 @@ class FileDownloader(object):
             try:
                 descfn = filename + u'.description'
                 self.report_writedescription(descfn)
-                descfile = open(encodeFilename(descfn), 'wb')
-                try:
-                    descfile.write(info_dict['description'].encode('utf-8'))
-                finally:
-                    descfile.close()
+                with io.open(encodeFilename(descfn), 'w', encoding='utf-8') as descfile:
+                    descfile.write(info_dict['description'])
             except (OSError, IOError):
                 self.trouble(u'ERROR: Cannot write description file ' + descfn)
                 return
@@ -428,11 +433,8 @@ class FileDownloader(object):
             try:
                 srtfn = filename.rsplit('.', 1)[0] + u'.srt'
                 self.report_writesubtitles(srtfn)
-                srtfile = open(encodeFilename(srtfn), 'wb')
-                try:
-                    srtfile.write(info_dict['subtitles'].encode('utf-8'))
-                finally:
-                    srtfile.close()
+                with io.open(encodeFilename(srtfn), 'w', encoding='utf-8') as srtfile:
+                    srtfile.write(info_dict['subtitles'])
             except (OSError, IOError):
                 self.trouble(u'ERROR: Cannot write subtitles file ' + descfn)
                 return
@@ -441,17 +443,8 @@ class FileDownloader(object):
             infofn = filename + u'.info.json'
             self.report_writeinfojson(infofn)
             try:
-                json.dump
-            except (NameError,AttributeError):
-                self.trouble(u'ERROR: No JSON encoder found. Update to Python 2.6+, setup a json module, or leave out --write-info-json.')
-                return
-            try:
-                infof = open(encodeFilename(infofn), 'wb')
-                try:
-                    json_info_dict = dict((k,v) for k,v in info_dict.iteritems() if not k in ('urlhandle',))
-                    json.dump(json_info_dict, infof)
-                finally:
-                    infof.close()
+                json_info_dict = dict((k, v) for k,v in info_dict.items() if not k in ['urlhandle'])
+                write_json_file(json_info_dict, encodeFilename(infofn))
             except (OSError, IOError):
                 self.trouble(u'ERROR: Cannot write metadata to JSON file ' + infofn)
                 return
@@ -500,6 +493,10 @@ class FileDownloader(object):
 
                 # Extract information from URL and process it
                 videos = ie.extract(url)
+
+                if len(videos or []) > 1 and self.fixed_template():
+                    raise SameFileError(self.params['outtmpl'])
+
                 for video in videos or []:
                     video['extractor'] = ie.IE_NAME
                     try:
@@ -591,6 +588,9 @@ class FileDownloader(object):
         basic_request = compat_urllib_request.Request(url, None, headers)
         request = compat_urllib_request.Request(url, None, headers)
 
+        if self.params.get('test', False):
+            request.add_header('Range','bytes=0-10240')
+
         # Establish possible resume length
         if os.path.isfile(encodeFilename(tmpfilename)):
             resume_len = os.path.getsize(encodeFilename(tmpfilename))