diff options
Diffstat (limited to 'youtube_dl/postprocessor/xattrpp.py')
| -rw-r--r-- | youtube_dl/postprocessor/xattrpp.py | 74 | 
1 files changed, 62 insertions, 12 deletions
| diff --git a/youtube_dl/postprocessor/xattrpp.py b/youtube_dl/postprocessor/xattrpp.py index 93d0abcf6..7d88e1308 100644 --- a/youtube_dl/postprocessor/xattrpp.py +++ b/youtube_dl/postprocessor/xattrpp.py @@ -3,18 +3,34 @@ from __future__ import unicode_literals  import os  import subprocess  import sys +import errno  from .common import PostProcessor -from ..compat import ( -    subprocess_check_output -)  from ..utils import (      check_executable,      hyphenate_date,      version_tuple, +    PostProcessingError, +    encodeArgument, +    encodeFilename,  ) +class XAttrMetadataError(PostProcessingError): +    def __init__(self, code=None, msg='Unknown error'): +        super(XAttrMetadataError, self).__init__(msg) +        self.code = code + +        # Parsing code and msg +        if (self.code in (errno.ENOSPC, errno.EDQUOT) or +                'No space left' in self.msg or 'Disk quota excedded' in self.msg): +            self.reason = 'NO_SPACE' +        elif self.code == errno.E2BIG or 'Argument list too long' in self.msg: +            self.reason = 'VALUE_TOO_LONG' +        else: +            self.reason = 'NOT_SUPPORTED' + +  class XAttrMetadataPP(PostProcessor):      # @@ -51,7 +67,10 @@ class XAttrMetadataPP(PostProcessor):                  raise ImportError              def write_xattr(path, key, value): -                return xattr.setxattr(path, key, value) +                try: +                    xattr.set(path, key, value) +                except EnvironmentError as e: +                    raise XAttrMetadataError(e.errno, e.strerror)          except ImportError:              if os.name == 'nt': @@ -62,8 +81,11 @@ class XAttrMetadataPP(PostProcessor):                      assert os.path.exists(path)                      ads_fn = path + ":" + key -                    with open(ads_fn, "wb") as f: -                        f.write(value) +                    try: +                        with open(ads_fn, "wb") as f: +                            f.write(value) +                    except EnvironmentError as e: +                        raise XAttrMetadataError(e.errno, e.strerror)              else:                  user_has_setfattr = check_executable("setfattr", ['--version'])                  user_has_xattr = check_executable("xattr", ['-h']) @@ -71,12 +93,27 @@ class XAttrMetadataPP(PostProcessor):                  if user_has_setfattr or user_has_xattr:                      def write_xattr(path, key, value): +                        value = value.decode('utf-8')                          if user_has_setfattr: -                            cmd = ['setfattr', '-n', key, '-v', value, path] +                            executable = 'setfattr' +                            opts = ['-n', key, '-v', value]                          elif user_has_xattr: -                            cmd = ['xattr', '-w', key, value, path] - -                        subprocess_check_output(cmd) +                            executable = 'xattr' +                            opts = ['-w', key, value] + +                        cmd = ([encodeFilename(executable, True)] + +                               [encodeArgument(o) for o in opts] + +                               [encodeFilename(path, True)]) + +                        try: +                            p = subprocess.Popen( +                                cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) +                        except EnvironmentError as e: +                            raise XAttrMetadataError(e.errno, e.strerror) +                        stdout, stderr = p.communicate() +                        stderr = stderr.decode('utf-8', 'replace') +                        if p.returncode != 0: +                            raise XAttrMetadataError(p.returncode, stderr)                  else:                      # On Unix, and can't find pyxattr, setfattr, or xattr. @@ -121,6 +158,19 @@ class XAttrMetadataPP(PostProcessor):              return [], info -        except (subprocess.CalledProcessError, OSError): -            self._downloader.report_error("This filesystem doesn't support extended attributes. (You may have to enable them in your /etc/fstab)") +        except XAttrMetadataError as e: +            if e.reason == 'NO_SPACE': +                self._downloader.report_warning( +                    'There\'s no disk space left or disk quota exceeded. ' + +                    'Extended attributes are not written.') +            elif e.reason == 'VALUE_TOO_LONG': +                self._downloader.report_warning( +                    'Unable to write extended attributes due to too long values.') +            else: +                msg = 'This filesystem doesn\'t support extended attributes. ' +                if os.name == 'nt': +                    msg += 'You need to use NTFS.' +                else: +                    msg += '(You may have to enable them in your /etc/fstab)' +                self._downloader.report_error(msg)              return [], info | 
