diff --git a/yt_dlp/extractor/patreon.py b/yt_dlp/extractor/patreon.py index 1828b81c52..94cf425f2d 100644 --- a/yt_dlp/extractor/patreon.py +++ b/yt_dlp/extractor/patreon.py @@ -65,8 +65,9 @@ class PatreonBaseIE(InfoExtractor): class PatreonIE(PatreonBaseIE): IE_NAME = 'patreon' - _VALID_URL = r'https?://(?:www\.)?patreon\.com/(?:creation\?hid=|posts/(?:[\w-]+-)?)(?P\d+)' + _VALID_URL = r'https?://(?:www\.)?patreon\.com/(?:creation\?hid=|(?:[^/?#]+/)?posts/(?:[\w-]+-)?)(?P\d+)' _TESTS = [{ + # FIXME: Fails due to no description extracted 'url': 'http://www.patreon.com/creation?hid=743933', 'md5': 'e25505eec1053a6e6813b8ed369875cc', 'info_dict': { @@ -107,17 +108,17 @@ class PatreonIE(PatreonBaseIE): 'id': 'SU4fj_aEMVw', 'ext': 'mp4', 'title': 'I\'m on Patreon!', - 'uploader': 'TraciJHines', + 'uploader': 'Traci Oden', 'thumbnail': 're:^https?://.*$', 'upload_date': '20150211', 'description': 'md5:8af6425f50bd46fbf29f3db0fc3a8364', - 'uploader_id': '@TraciHinesMusic', + 'uploader_id': '@TraciOden', 'categories': ['Entertainment'], 'duration': 282, 'view_count': int, 'tags': 'count:39', 'age_limit': 0, - 'channel': 'TraciJHines', + 'channel': 'Traci Oden', 'channel_url': 'https://www.youtube.com/channel/UCGLim4T2loE5rwCMdpCIPVg', 'live_status': 'not_live', 'like_count': int, @@ -125,7 +126,7 @@ class PatreonIE(PatreonBaseIE): 'availability': 'public', 'channel_follower_count': int, 'playable_in_embed': True, - 'uploader_url': 'https://www.youtube.com/@TraciHinesMusic', + 'uploader_url': 'https://www.youtube.com/@TraciOden', 'comment_count': int, 'channel_is_verified': True, 'chapters': 'count:4', @@ -157,6 +158,7 @@ class PatreonIE(PatreonBaseIE): }, 'skip': 'Patron-only content', }, { + # FIXME: Fails due to no description extracted # m3u8 video (https://github.com/yt-dlp/yt-dlp/issues/2277) 'url': 'https://www.patreon.com/posts/video-sketchbook-32452882', 'info_dict': { @@ -220,6 +222,7 @@ class PatreonIE(PatreonBaseIE): 'channel_id': '2147162', 'uploader_url': 'https://www.patreon.com/yaboyroshi', }, + 'skip': 'HTTP Error 401 for m3u8 request; site now requires login to play the video', }, { # NSFW vimeo embed URL 'url': 'https://www.patreon.com/posts/4k-spiderman-4k-96414599', @@ -242,6 +245,7 @@ class PatreonIE(PatreonBaseIE): }, 'params': {'skip_download': 'm3u8'}, 'expected_warnings': ['Failed to parse XML: not well-formed'], + 'skip': 'Video removed', }, { # multiple attachments/embeds 'url': 'https://www.patreon.com/posts/holy-wars-solos-100601977', @@ -285,6 +289,7 @@ class PatreonIE(PatreonBaseIE): }, 'params': {'getcomments': True}, }, { + # FIXME: Error: No supported media found in this post # Inlined media in post; uses _extract_from_media_api 'url': 'https://www.patreon.com/posts/scottfalco-146966245', 'info_dict': { @@ -304,6 +309,26 @@ class PatreonIE(PatreonBaseIE): 'timestamp': 1767061800, 'upload_date': '20251230', }, + }, { + # FIXME: need to extract description + 'url': 'https://www.patreon.com/Insanimate/posts/meatcanyon-in-142663524', + 'md5': '132332e3bb345f75d8b471242346dee6', + 'info_dict': { + 'id': '142663524', + 'ext': 'mp4', + 'title': 'Meatcanyon in Playground', + 'uploader': 'Insanimate', + 'uploader_id': '2828146', + 'uploader_url': 'https://www.patreon.com/Insanimate', + 'channel_id': '6260877', + 'channel_url': 'https://www.patreon.com/Insanimate', + 'channel_follower_count': int, + 'comment_count': int, + 'like_count': int, + 'thumbnail': 're:^https?://.*$', + 'timestamp': 1762101034, + 'upload_date': '20251102', + }, }] _RETURN_TYPE = 'video' _HTTP_HEADERS = { @@ -357,7 +382,7 @@ class PatreonIE(PatreonBaseIE): post = self._call_api( f'posts/{video_id}', video_id, query={ 'fields[media]': 'download_url,mimetype,size_bytes,file_name', - 'fields[post]': 'comment_count,content,embed,image,like_count,post_file,published_at,title,current_user_can_view', + 'fields[post]': 'comment_count,content,content_teaser_text,cleaned_teaser_text,embed,image,like_count,post_file,published_at,title,current_user_can_view', 'fields[user]': 'full_name,url', 'fields[post_tag]': 'value', 'fields[campaign]': 'url,name,patron_count', @@ -367,7 +392,7 @@ class PatreonIE(PatreonBaseIE): attributes = post['data']['attributes'] info = traverse_obj(attributes, { 'title': ('title', {str.strip}), - 'description': ('content', {clean_html}), + 'description': (('content', 'content_teaser_text', 'cleaned_teaser_text'), {clean_html}, any), 'thumbnail': ('image', ('large_url', 'url'), {url_or_none}, any), 'timestamp': ('published_at', {parse_iso8601}), 'like_count': ('like_count', {int_or_none}),