xattrpp.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import os
  2. from .common import PostProcessor
  3. from ..compat import compat_os_name
  4. from ..utils import (
  5. PostProcessingError,
  6. XAttrMetadataError,
  7. XAttrUnavailableError,
  8. hyphenate_date,
  9. write_xattr,
  10. )
  11. class XAttrMetadataPP(PostProcessor):
  12. """Set extended attributes on downloaded file (if xattr support is found)
  13. More info about extended attributes for media:
  14. http://freedesktop.org/wiki/CommonExtendedAttributes/
  15. http://www.freedesktop.org/wiki/PhreedomDraft/
  16. http://dublincore.org/documents/usageguide/elements.shtml
  17. TODO:
  18. * capture youtube keywords and put them in 'user.dublincore.subject' (comma-separated)
  19. * figure out which xattrs can be used for 'duration', 'thumbnail', 'resolution'
  20. """
  21. XATTR_MAPPING = {
  22. 'user.xdg.referrer.url': 'webpage_url',
  23. # 'user.xdg.comment': 'description',
  24. 'user.dublincore.title': 'title',
  25. 'user.dublincore.date': 'upload_date',
  26. 'user.dublincore.description': 'description',
  27. 'user.dublincore.contributor': 'uploader',
  28. 'user.dublincore.format': 'format',
  29. }
  30. def run(self, info):
  31. mtime = os.stat(info['filepath']).st_mtime
  32. self.to_screen('Writing metadata to file\'s xattrs')
  33. try:
  34. for xattrname, infoname in self.XATTR_MAPPING.items():
  35. value = info.get(infoname)
  36. if value:
  37. if infoname == 'upload_date':
  38. value = hyphenate_date(value)
  39. write_xattr(info['filepath'], xattrname, value.encode())
  40. except XAttrUnavailableError as e:
  41. raise PostProcessingError(str(e))
  42. except XAttrMetadataError as e:
  43. if e.reason == 'NO_SPACE':
  44. self.report_warning(
  45. 'There\'s no disk space left, disk quota exceeded or filesystem xattr limit exceeded. '
  46. 'Some extended attributes are not written')
  47. elif e.reason == 'VALUE_TOO_LONG':
  48. self.report_warning('Unable to write extended attributes due to too long values.')
  49. else:
  50. tip = ('You need to use NTFS' if compat_os_name == 'nt'
  51. else 'You may have to enable them in your "/etc/fstab"')
  52. raise PostProcessingError(f'This filesystem doesn\'t support extended attributes. {tip}')
  53. self.try_utime(info['filepath'], mtime, mtime)
  54. return [], info