From 46387b1b949ca7861b97dfe8e54b8ae6bc863c8a Mon Sep 17 00:00:00 2001 From: Roland Crosby Date: Tue, 18 Mar 2025 23:10:29 -0400 Subject: [PATCH 1/4] Add "Where from" metadata on macOS --- yt_dlp/postprocessor/xattrpp.py | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/yt_dlp/postprocessor/xattrpp.py b/yt_dlp/postprocessor/xattrpp.py index e486b797b7..92e8e83d97 100644 --- a/yt_dlp/postprocessor/xattrpp.py +++ b/yt_dlp/postprocessor/xattrpp.py @@ -1,4 +1,5 @@ import os +import sys from .common import PostProcessor from ..utils import ( @@ -35,15 +36,38 @@ class XAttrMetadataPP(PostProcessor): # 'user.xdg.comment': 'description', } + PLATFORM_XATTR_MAPPING = { + 'darwin': { + 'com.apple.metadata:kMDItemWhereFroms': 'webpage_url', + }, + } + + APPLE_PLIST_TEMPLATE = ''' + + + +\t%s + +''' + + def format_value(self, xattrname, infoname, value): + if infoname == 'upload_date': + return hyphenate_date(value) + if xattrname == 'com.apple.metadata:kMDItemWhereFroms': + return self.APPLE_PLIST_TEMPLATE % value + return value + def run(self, info): mtime = os.stat(info['filepath']).st_mtime self.to_screen('Writing metadata to file\'s xattrs') - for xattrname, infoname in self.XATTR_MAPPING.items(): + + mapping = dict(self.XATTR_MAPPING) + mapping.update(self.PLATFORM_XATTR_MAPPING.get(sys.platform, {})) + for xattrname, infoname in mapping.items(): try: value = info.get(infoname) if value: - if infoname == 'upload_date': - value = hyphenate_date(value) + value = self.format_value(xattrname, infoname, value) write_xattr(info['filepath'], xattrname, value.encode()) except XAttrUnavailableError as e: From bac71d6a7513e4b69f01572bc25d25962c6a59d9 Mon Sep 17 00:00:00 2001 From: Roland Crosby Date: Wed, 19 Mar 2025 09:26:34 -0400 Subject: [PATCH 2/4] Write macOS metadata regardless of platform --- yt_dlp/postprocessor/xattrpp.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/yt_dlp/postprocessor/xattrpp.py b/yt_dlp/postprocessor/xattrpp.py index 92e8e83d97..8bbd0ffd3b 100644 --- a/yt_dlp/postprocessor/xattrpp.py +++ b/yt_dlp/postprocessor/xattrpp.py @@ -1,5 +1,4 @@ import os -import sys from .common import PostProcessor from ..utils import ( @@ -30,18 +29,13 @@ class XAttrMetadataPP(PostProcessor): 'user.dublincore.date': 'upload_date', 'user.dublincore.contributor': 'uploader', 'user.dublincore.format': 'format', + 'com.apple.metadata:kMDItemWhereFroms': 'webpage_url', # We do this last because it may get us close to the xattr limits # (e.g., 4kB on ext4), and we don't want to have the other ones fail 'user.dublincore.description': 'description', # 'user.xdg.comment': 'description', } - PLATFORM_XATTR_MAPPING = { - 'darwin': { - 'com.apple.metadata:kMDItemWhereFroms': 'webpage_url', - }, - } - APPLE_PLIST_TEMPLATE = ''' @@ -60,10 +54,7 @@ def format_value(self, xattrname, infoname, value): def run(self, info): mtime = os.stat(info['filepath']).st_mtime self.to_screen('Writing metadata to file\'s xattrs') - - mapping = dict(self.XATTR_MAPPING) - mapping.update(self.PLATFORM_XATTR_MAPPING.get(sys.platform, {})) - for xattrname, infoname in mapping.items(): + for xattrname, infoname in self.XATTR_MAPPING.items(): try: value = info.get(infoname) if value: From 2737255d943a34032bb299ecf3e40625b1c224a2 Mon Sep 17 00:00:00 2001 From: Roland Crosby Date: Wed, 19 Mar 2025 18:34:29 -0400 Subject: [PATCH 3/4] Inline value formatting --- yt_dlp/postprocessor/xattrpp.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/yt_dlp/postprocessor/xattrpp.py b/yt_dlp/postprocessor/xattrpp.py index 8bbd0ffd3b..c2fdefe495 100644 --- a/yt_dlp/postprocessor/xattrpp.py +++ b/yt_dlp/postprocessor/xattrpp.py @@ -44,13 +44,6 @@ class XAttrMetadataPP(PostProcessor): ''' - def format_value(self, xattrname, infoname, value): - if infoname == 'upload_date': - return hyphenate_date(value) - if xattrname == 'com.apple.metadata:kMDItemWhereFroms': - return self.APPLE_PLIST_TEMPLATE % value - return value - def run(self, info): mtime = os.stat(info['filepath']).st_mtime self.to_screen('Writing metadata to file\'s xattrs') @@ -58,7 +51,10 @@ def run(self, info): try: value = info.get(infoname) if value: - value = self.format_value(xattrname, infoname, value) + if infoname == 'upload_date': + value = hyphenate_date(value) + elif xattrname == 'com.apple.metadata:kMDItemWhereFroms': + value = self.APPLE_PLIST_TEMPLATE % value write_xattr(info['filepath'], xattrname, value.encode()) except XAttrUnavailableError as e: From a6bede39b8c2bee4786de42fb8ae3dfbaf608116 Mon Sep 17 00:00:00 2001 From: Roland Crosby Date: Sat, 22 Mar 2025 14:41:43 -0700 Subject: [PATCH 4/4] Move macOS metadata after description --- yt_dlp/postprocessor/xattrpp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yt_dlp/postprocessor/xattrpp.py b/yt_dlp/postprocessor/xattrpp.py index c2fdefe495..fd83d783ba 100644 --- a/yt_dlp/postprocessor/xattrpp.py +++ b/yt_dlp/postprocessor/xattrpp.py @@ -29,11 +29,11 @@ class XAttrMetadataPP(PostProcessor): 'user.dublincore.date': 'upload_date', 'user.dublincore.contributor': 'uploader', 'user.dublincore.format': 'format', - 'com.apple.metadata:kMDItemWhereFroms': 'webpage_url', # We do this last because it may get us close to the xattr limits # (e.g., 4kB on ext4), and we don't want to have the other ones fail 'user.dublincore.description': 'description', # 'user.xdg.comment': 'description', + 'com.apple.metadata:kMDItemWhereFroms': 'webpage_url', } APPLE_PLIST_TEMPLATE = '''