Remove exclamation mark in --restrict-filenames mode
[youtube-dl] / youtube_dl / utils.py
index 56d0461456fe7e96a259100d7e60bdf2f1dc87a2..a0c41081acb10b48c052b8c2d0eb79de8cc4eb0a 100644 (file)
@@ -26,6 +26,11 @@ std_headers = {
        'Accept-Language': 'en-us,en;q=0.5',
 }
 
+try:
+    compat_str = unicode # Python 2
+except NameError:
+    compat_str = str
+
 def preferredencoding():
        """Get preferred encoding.
 
@@ -83,7 +88,6 @@ class IDParser(HTMLParser.HTMLParser):
                HTMLParser.HTMLParser.__init__(self)
 
        def error(self, message):
-               #print >> sys.stderr, self.getpos()
                if self.error_count > 10 or self.started:
                        raise HTMLParser.HTMLParseError(message, self.getpos())
                self.rawdata = '\n'.join(self.html.split('\n')[self.getpos()[0]:]) # skip one line
@@ -190,24 +194,36 @@ def timeconvert(timestr):
        if timetuple is not None:
                timestamp = email.utils.mktime_tz(timetuple)
        return timestamp
-       
-def sanitize_filename(s):
-       """Sanitizes a string so it could be used as part of a filename."""
+
+def sanitize_filename(s, restricted=False):
+       """Sanitizes a string so it could be used as part of a filename.
+       If restricted is set, use a stricter subset of allowed characters.
+       """
        def replace_insane(char):
                if char == '?' or ord(char) < 32 or ord(char) == 127:
                        return ''
                elif char == '"':
-                       return '\''
+                       return '' if restricted else '\''
                elif char == ':':
-                       return ' -'
+                       return '_-' if restricted else ' -'
                elif char in '\\/|*<>':
-                       return '-'
+                       return '_'
+               if restricted and (char in '!&\'' or char.isspace()):
+                       return '_'
+               if restricted and ord(char) > 127:
+                       return '_'
                return char
 
        result = u''.join(map(replace_insane, s))
-       while '--' in result:
-               result = result.replace('--', '-')
-       return result.strip('-')
+       while '__' in result:
+               result = result.replace('__', '_')
+       result = result.strip('_')
+       # Common case of "Foreign band name - English song title"
+       if restricted and result.startswith('-_'):
+               result = result[2:]
+       if not result:
+               result = '_'
+       return result
 
 def orderedSet(iterable):
        """ Remove all duplicates from the input iterable """
@@ -300,7 +316,7 @@ class ContentTooShortError(Exception):
 
 class Trouble(Exception):
        """Trouble helper exception
-       
+
        This is an exception to be handled with
        FileDownloader.trouble
        """