diff options
Diffstat (limited to 'youtube_dl/utils.py')
| -rw-r--r-- | youtube_dl/utils.py | 87 | 
1 files changed, 83 insertions, 4 deletions
| diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index d7ae5a90a..9287edd8d 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -203,6 +203,82 @@ def compat_ord(c):      if type(c) is int: return c      else: return ord(c) + +if sys.version_info >= (3, 0): +    compat_getenv = os.getenv +    compat_expanduser = os.path.expanduser +else: +    # Environment variables should be decoded with filesystem encoding. +    # Otherwise it will fail if any non-ASCII characters present (see #3854 #3217 #2918) + +    def compat_getenv(key, default=None): +        env = os.getenv(key, default) +        if env: +            env = env.decode(get_filesystem_encoding()) +        return env + +    # HACK: The default implementations of os.path.expanduser from cpython do not decode +    # environment variables with filesystem encoding. We will work around this by +    # providing adjusted implementations. +    # The following are os.path.expanduser implementations from cpython 2.7.8 stdlib +    # for different platforms with correct environment variables decoding. + +    if os.name == 'posix': +        def compat_expanduser(path): +            """Expand ~ and ~user constructions.  If user or $HOME is unknown, +            do nothing.""" +            if not path.startswith('~'): +                return path +            i = path.find('/', 1) +            if i < 0: +                i = len(path) +            if i == 1: +                if 'HOME' not in os.environ: +                    import pwd +                    userhome = pwd.getpwuid(os.getuid()).pw_dir +                else: +                    userhome = compat_getenv('HOME') +            else: +                import pwd +                try: +                    pwent = pwd.getpwnam(path[1:i]) +                except KeyError: +                    return path +                userhome = pwent.pw_dir +            userhome = userhome.rstrip('/') +            return (userhome + path[i:]) or '/' +    elif os.name == 'nt' or os.name == 'ce': +        def compat_expanduser(path): +            """Expand ~ and ~user constructs. + +            If user or $HOME is unknown, do nothing.""" +            if path[:1] != '~': +                return path +            i, n = 1, len(path) +            while i < n and path[i] not in '/\\': +                i = i + 1 + +            if 'HOME' in os.environ: +                userhome = compat_getenv('HOME') +            elif 'USERPROFILE' in os.environ: +                userhome = compat_getenv('USERPROFILE') +            elif not 'HOMEPATH' in os.environ: +                return path +            else: +                try: +                    drive = compat_getenv('HOMEDRIVE') +                except KeyError: +                    drive = '' +                userhome = os.path.join(drive, compat_getenv('HOMEPATH')) + +            if i != 1: #~user +                userhome = os.path.join(os.path.dirname(userhome), path[1:i]) + +            return userhome + path[i:] +    else: +        compat_expanduser = os.path.expanduser + +  # This is not clearly defined otherwise  compiled_regex_type = type(re.compile('')) @@ -1207,11 +1283,14 @@ class locked_file(object):          return self.f.read(*args) +def get_filesystem_encoding(): +    encoding = sys.getfilesystemencoding() +    return encoding if encoding is not None else 'utf-8' + +  def shell_quote(args):      quoted_args = [] -    encoding = sys.getfilesystemencoding() -    if encoding is None: -        encoding = 'utf-8' +    encoding = get_filesystem_encoding()      for a in args:          if isinstance(a, bytes):              # We may get a filename encoded with 'encodeFilename' @@ -1261,7 +1340,7 @@ def format_bytes(bytes):  def get_term_width(): -    columns = os.environ.get('COLUMNS', None) +    columns = compat_getenv('COLUMNS', None)      if columns:          return int(columns) | 
