[civitai] add 'collection' extractor (#8005)

This commit is contained in:
Mike Fährmann
2025-08-10 17:37:48 +02:00
parent 5ffe432b95
commit 2b03843092
3 changed files with 162 additions and 5 deletions

View File

@@ -190,7 +190,7 @@ Consider all listed sites to potentially be NSFW.
<tr> <tr>
<td>Civitai</td> <td>Civitai</td>
<td>https://www.civitai.com/</td> <td>https://www.civitai.com/</td>
<td>Generated Files, individual Images, Image Listings, Models, Model Listings, Posts, Post Listings, Image Searches, Model Searches, Tag Searches, User Profiles, User Images, Image Reactions, User Models, User Posts, User Videos, Video Reactions</td> <td>Collections, Generated Files, individual Images, Image Listings, Models, Model Listings, Posts, Post Listings, Image Searches, Model Searches, Tag Searches, User Profiles, User Images, Image Reactions, User Models, User Posts, User Videos, Video Reactions</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>

View File

@@ -377,6 +377,28 @@ class CivitaiImageExtractor(CivitaiExtractor):
return self.api.image(self.groups[0]) return self.api.image(self.groups[0])
class CivitaiCollectionExtractor(CivitaiExtractor):
subcategory = "collection"
directory_fmt = ("{category}", "{user_collection[username]}",
"collections", "{collection[id]}{collection[name]:? //}")
pattern = BASE_PATTERN + r"/collections/(\d+)"
example = "https://civitai.com/collections/12345"
def images(self):
cid = int(self.groups[0])
self.kwdict["collection"] = col = self.api.collection(cid)
self.kwdict["user_collection"] = col.pop("user", None)
params = {
"collectionId" : cid,
"period" : "AllTime",
"sort" : "Newest",
"browsingLevel" : self.api.nsfw,
"include" : ("cosmetics",),
}
return self.api.images(params, defaults=False)
class CivitaiPostExtractor(CivitaiExtractor): class CivitaiPostExtractor(CivitaiExtractor):
subcategory = "post" subcategory = "post"
directory_fmt = ("{category}", "{username|user[username]}", "posts", directory_fmt = ("{category}", "{username|user[username]}", "posts",
@@ -635,7 +657,7 @@ class CivitaiTrpcAPI():
self.root = extractor.root + "/api/trpc/" self.root = extractor.root + "/api/trpc/"
self.headers = { self.headers = {
"content-type" : "application/json", "content-type" : "application/json",
"x-client-version": "5.0.920", "x-client-version": "5.0.954",
"x-client-date" : "", "x-client-date" : "",
"x-client" : "web", "x-client" : "web",
"x-fingerprint" : "undefined", "x-fingerprint" : "undefined",
@@ -758,6 +780,11 @@ class CivitaiTrpcAPI():
params = self._type_params(params) params = self._type_params(params)
return self._pagination(endpoint, params, meta) return self._pagination(endpoint, params, meta)
def collection(self, collection_id):
endpoint = "collection.getById"
params = {"id": int(collection_id)}
return self._call(endpoint, params)["collection"]
def user(self, username): def user(self, username):
endpoint = "user.getCreator" endpoint = "user.getCreator"
params = {"username": username} params = {"username": username}
@@ -783,9 +810,8 @@ class CivitaiTrpcAPI():
params = {"input": util.json_dumps(input)} params = {"input": util.json_dumps(input)}
headers["x-client-date"] = str(int(time.time() * 1000)) headers["x-client-date"] = str(int(time.time() * 1000))
response = self.extractor.request(url, params=params, headers=headers) return self.extractor.request_json(
url, params=params, headers=headers)["result"]["data"]["json"]
return response.json()["result"]["data"]["json"]
def _pagination(self, endpoint, params, meta=None): def _pagination(self, endpoint, params, meta=None):
if "cursor" not in params: if "cursor" not in params:

View File

@@ -529,4 +529,135 @@ __tests__ = (
"#auth" : True, "#auth" : True,
}, },
{
"#url" : "https://civitai.com/collections/11035869",
"#class" : civitai.CivitaiCollectionExtractor,
"#results" : "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/9b9c64b4-60de-4a9c-becd-a386ecf3fa7a/original=true/DailyWorldMorphChallenge_Base_0003.png",
"filename" : "DailyWorldMorphChallenge_Base_0003",
"extension" : "png",
"url" : "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/9b9c64b4-60de-4a9c-becd-a386ecf3fa7a/original=true/DailyWorldMorphChallenge_Base_0003.png",
"collection" : {
"availability": "Public",
"description" : "",
"id" : 11035869,
"image" : None,
"metadata" : {},
"mode" : None,
"name" : "Trees, Bonsai, and so one",
"nsfw" : False,
"nsfwLevel" : 1,
"read" : "Public",
"tags" : [],
"type" : "Image",
"userId" : 4831516,
"write" : "Private",
},
"file" : {
"acceptableMinor": False,
"availability" : "Public",
"blockedFor" : None,
"cosmetic" : None,
"createdAt" : "2025-04-30T20:20:44.015Z",
"date" : "dt:2025-04-30 20:20:44",
"hasMeta" : True,
"hasPositivePrompt": True,
"hash" : "UHEfvNWC?dof00oc4Uae$,ofV}WFxeWCxwWV",
"height" : 1152,
"hideMeta" : False,
"id" : 73339178,
"index" : 1,
"ingestion" : "Scanned",
"metadata" : {
"hash" : "UHEfvNWC?dof00oc4Uae$,ofV}WFxeWCxwWV",
"height": 1152,
"size" : 1523677,
"width" : 896,
},
"mimeType" : "image/png",
"minor" : False,
"modelVersionId" : None,
"modelVersionIds": [],
"modelVersionIdsManual": [],
"name" : "DailyWorldMorphChallenge_Base_0003.png",
"needsReview" : None,
"nsfwLevel" : 1,
"onSite" : False,
"poi" : False,
"postId" : 16290779,
"postTitle" : None,
"publishedAt" : "2025-04-30T20:23:40.409Z",
"reactions" : [],
"remixOfId" : None,
"scannedAt" : "2025-04-30T20:20:48.072Z",
"sortAt" : "2025-04-30T20:23:40.409Z",
"stats" : {
"collectedCountAllTime": 1,
"commentCountAllTime": 0,
"cryCountAllTime" : 1,
"dislikeCountAllTime": 0,
"heartCountAllTime": 1,
"laughCountAllTime": 0,
"likeCountAllTime": 5,
"tippedAmountCountAllTime": 0,
"viewCountAllTime": 0,
},
"tagIds" : [
5248,
9143,
111839,
112019,
116352,
120250,
161904,
234268,
],
"tags" : None,
"thumbnailUrl" : None,
"type" : "image",
"url" : "9b9c64b4-60de-4a9c-becd-a386ecf3fa7a",
"uuid" : "9b9c64b4-60de-4a9c-becd-a386ecf3fa7a",
"width" : 896,
},
"user" : {
"cosmetics" : list,
"deletedAt" : None,
"id" : 2624648,
"image" : "ce0f7d5e-cc4a-41e2-8587-75d823c85ce9",
"profilePicture": None,
"username" : "AIArtsChannel",
},
"user_collection": {
"cosmetics" : [],
"deletedAt" : None,
"id" : 4831516,
"image" : "https://lh3.googleusercontent.com/a/ACg8ocKeClAsD6kmHOATnC4Li1PLYw9-J41LCaVHdzcLLGZi9ElNUQ=s96-c",
"profilePicture": None,
"username" : "TettyCo",
},
},
{
"#url" : "https://civitai.com/collections/11453135",
"#class" : civitai.CivitaiCollectionExtractor,
"#count" : 12,
"collection" : {
"availability": "Public",
"description" : "",
"id" : 11453135,
"image" : None,
"metadata" : {},
"mode" : None,
"name" : "Sakura Trees",
"nsfw" : False,
"nsfwLevel" : 3,
"read" : "Public",
"tags" : [],
"type" : "Image",
"userId" : 8511981,
"write" : "Private",
},
},
) )