[patreon] add 'collection' extractor (#8286)
This commit is contained in:
@@ -700,7 +700,7 @@ Consider all listed sites to potentially be NSFW.
|
|||||||
<tr id="patreon" title="patreon">
|
<tr id="patreon" title="patreon">
|
||||||
<td>Patreon</td>
|
<td>Patreon</td>
|
||||||
<td>https://www.patreon.com/</td>
|
<td>https://www.patreon.com/</td>
|
||||||
<td>Creators, Posts, User Profiles</td>
|
<td>Collections, Creators, Posts, User Profiles</td>
|
||||||
<td><a href="https://github.com/mikf/gallery-dl#cookies">Cookies</a></td>
|
<td><a href="https://github.com/mikf/gallery-dl#cookies">Cookies</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr id="pexels" title="pexels">
|
<tr id="pexels" title="pexels">
|
||||||
|
|||||||
@@ -230,6 +230,16 @@ class PatreonExtractor(Extractor):
|
|||||||
attr["created"], "%Y-%m-%dT%H:%M:%S.%f%z")
|
attr["created"], "%Y-%m-%dT%H:%M:%S.%f%z")
|
||||||
return attr
|
return attr
|
||||||
|
|
||||||
|
def _collection(self, collection_id):
|
||||||
|
url = f"{self.root}/api/collection/{collection_id}"
|
||||||
|
data = self.request_json(url)
|
||||||
|
coll = data["data"]
|
||||||
|
attr = coll["attributes"]
|
||||||
|
attr["id"] = coll["id"]
|
||||||
|
attr["date"] = text.parse_datetime(
|
||||||
|
attr["created_at"], "%Y-%m-%dT%H:%M:%S.%f%z")
|
||||||
|
return attr
|
||||||
|
|
||||||
def _filename(self, url):
|
def _filename(self, url):
|
||||||
"""Fetch filename from an URL's Content-Disposition header"""
|
"""Fetch filename from an URL's Content-Disposition header"""
|
||||||
response = self.request(url, method="HEAD", fatal=False)
|
response = self.request(url, method="HEAD", fatal=False)
|
||||||
@@ -333,6 +343,33 @@ class PatreonExtractor(Extractor):
|
|||||||
raise exception.AbortExtraction("Unable to extract bootstrap data")
|
raise exception.AbortExtraction("Unable to extract bootstrap data")
|
||||||
|
|
||||||
|
|
||||||
|
class PatreonCollectionExtractor(PatreonExtractor):
|
||||||
|
"""Extractor for a patreon collection"""
|
||||||
|
subcategory = "collection"
|
||||||
|
directory_fmt = ("{category}", "{creator[full_name]}",
|
||||||
|
"Collections", "{collection[title]} ({collection[id]})")
|
||||||
|
pattern = r"(?:https?://)?(?:www\.)?patreon\.com/collection/(\d+)"
|
||||||
|
example = "https://www.patreon.com/collection/12345"
|
||||||
|
|
||||||
|
def posts(self):
|
||||||
|
collection_id = self.groups[0]
|
||||||
|
self.kwdict["collection"] = collection = \
|
||||||
|
self._collection(collection_id)
|
||||||
|
campaign_id = text.extr(
|
||||||
|
collection["thumbnail"]["url"], "/campaign/", "/")
|
||||||
|
|
||||||
|
url = self._build_url("posts", (
|
||||||
|
# patreon returns '400 Bad Request' without campaign_id filter
|
||||||
|
f"&filter[campaign_id]={campaign_id}"
|
||||||
|
"&filter[contains_exclusive_posts]=true"
|
||||||
|
"&filter[is_draft]=false"
|
||||||
|
f"&filter[collection_id]={collection_id}"
|
||||||
|
"&filter[include_drops]=true"
|
||||||
|
"&sort=collection_order"
|
||||||
|
))
|
||||||
|
return self._pagination(url)
|
||||||
|
|
||||||
|
|
||||||
class PatreonCreatorExtractor(PatreonExtractor):
|
class PatreonCreatorExtractor(PatreonExtractor):
|
||||||
"""Extractor for a creator's works"""
|
"""Extractor for a creator's works"""
|
||||||
subcategory = "creator"
|
subcategory = "creator"
|
||||||
|
|||||||
@@ -191,4 +191,45 @@ __tests__ = (
|
|||||||
"#exception": exception.NotFoundError,
|
"#exception": exception.NotFoundError,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"#url" : "https://www.patreon.com/collection/15764",
|
||||||
|
"#class" : patreon.PatreonCollectionExtractor,
|
||||||
|
"#range" : "1-3",
|
||||||
|
"#pattern" : (
|
||||||
|
r"https://c10.patreonusercontent.com/4/patreon-media/p/post/32798362/957d49296e4f48ef80718d0de98c15a4/eyJhIjoxLCJwIjoxfQ%3D%3D/2.jpg\?token-hash=.+",
|
||||||
|
r"ytdl:https://stream.mux.com/h4DYqFU901qkkAwYmRWZPraVk5DvTJTlcSdhGV00006KBE.m3u8\?token=ey.+",
|
||||||
|
r"https://c10.patreonusercontent.com/4/patreon-media/p/post/32798374/357b0133a476427a99169b4400ee03d4/eyJhIjoxLCJwIjoxfQ%3D%3D/2.jpg\?token-hash=.+",
|
||||||
|
),
|
||||||
|
|
||||||
|
"campaign" : {
|
||||||
|
"currency" : "USD",
|
||||||
|
"is_monthly" : True,
|
||||||
|
"is_nsfw" : False,
|
||||||
|
"name" : "YaBoyRoshi",
|
||||||
|
},
|
||||||
|
"collection" : {
|
||||||
|
"created_at" : "2023-08-31T14:10:41.000+00:00",
|
||||||
|
"date" : "dt:2023-08-31 14:10:41",
|
||||||
|
"default_layout" : "grid",
|
||||||
|
"description" : "",
|
||||||
|
"edited_at" : "2025-07-16T22:58:10.834+00:00",
|
||||||
|
"id" : "15764",
|
||||||
|
"num_draft_posts": 0,
|
||||||
|
"num_posts" : 207,
|
||||||
|
"num_posts_visible_for_creation": 207,
|
||||||
|
"num_scheduled_posts": 8,
|
||||||
|
"post_sort_type" : "custom",
|
||||||
|
"title" : "JoJo's Bizarre Adventure",
|
||||||
|
"post_ids" : list,
|
||||||
|
"thumbnail" : dict,
|
||||||
|
},
|
||||||
|
"creator" : {
|
||||||
|
"date" : "dt:2018-10-17 05:45:19",
|
||||||
|
"first_name": "YaBoyRoshi",
|
||||||
|
"full_name" : "YaBoyRoshi",
|
||||||
|
"id" : "14264111",
|
||||||
|
"vanity" : "yaboyroshi",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user