Tweak final filename in the open attempt, to be platform and filename-agnostic
authorRicardo Garcia <sarbalap+freshmeat@gmail.com>
Sat, 13 Feb 2010 12:29:25 +0000 (13:29 +0100)
committerRicardo Garcia <sarbalap+freshmeat@gmail.com>
Sun, 31 Oct 2010 10:26:30 +0000 (11:26 +0100)
youtube-dl

index 3533c0f..c7d3752 100755 (executable)
@@ -78,16 +78,32 @@ def htmlentity_transform(matchobj):
        return (u'&%s;' % entity)
 
 def sanitize_title(utitle):
-       """Sanitizes a video title so it could be used as part of a filename.
-
-       This triggers different transformations based on the platform we
-       are running.
-       """
+       """Sanitizes a video title so it could be used as part of a filename."""
        utitle = re.sub(ur'(?u)&(.+?);', htmlentity_transform, utitle)
-       if sys.platform == 'win32':
-               utitle = re.replace(ur'<>:"\|\?\*\\', u'-', utitle)
        return utitle.replace(unicode(os.sep), u'%')
 
+def sanitize_open(filename, open_mode):
+       """Try to open the given filename, and slightly tweak it if this fails.
+
+       Attempts to open the given filename. If this fails, it tries to change
+       the filename slightly, step by step, until it's either able to open it
+       or it fails and raises a final exception, like the standard open()
+       function.
+
+       It returns the tuple (stream, definitive_file_name).
+       """
+       try:
+               stream = open(filename, open_mode)
+               return (stream, filename)
+       except (IOError, OSError), err:
+               # In case of error, try to remove win32 forbidden chars
+               filename = re.sub(ur'[<>:"\|\?\*]', u'#', filename)
+
+               # An exception here should be caught in the caller
+               stream = open(filename, open_mode)
+               return (stream, filename)
+
+
 class DownloadError(Exception):
        """Download Error exception.
        
@@ -522,7 +538,7 @@ class FileDownloader(object):
                        # Open file just in time
                        if stream is None:
                                try:
-                                       stream = open(filename, open_mode)
+                                       (stream, filename) = sanitize_open(filename, open_mode)
                                        self.report_destination(filename)
                                except (OSError, IOError), err:
                                        self.trouble('ERROR: unable to open for writing: %s' % str(err))