diff --git a/docs/configuration.rst b/docs/configuration.rst
index a35968ab..03ae9cfe 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -1677,9 +1677,11 @@ Description
when processing a user profile.
Possible values are
- ``"user-models"``,
- ``"user-posts"``,
- ``"user-images"``.
+
+ * ``"user-models"``
+ * ``"user-posts"``
+ * ``"user-images"``
+ * ``"user-videos"``
It is possible to use ``"all"`` instead of listing all values separately.
@@ -1698,7 +1700,7 @@ Example
Description
Extract additional ``generation`` metadata.
- Note: This requires 1 additional HTTP request per image.
+ Note: This requires 1 additional HTTP request per image or video.
extractor.civitai.nsfw
diff --git a/docs/supportedsites.md b/docs/supportedsites.md
index 3ba8b2b2..3820d5ee 100644
--- a/docs/supportedsites.md
+++ b/docs/supportedsites.md
@@ -172,7 +172,7 @@ Consider all listed sites to potentially be NSFW.
| Civitai |
https://www.civitai.com/ |
- individual Images, Image Listings, Models, Model Listings, Posts, Search Results, Tag Searches, User Profiles, User Images, User Models, User Posts |
+ individual Images, Image Listings, Models, Model Listings, Posts, Search Results, Tag Searches, User Profiles, User Images, User Models, User Posts, User Videos |
|
diff --git a/gallery_dl/extractor/civitai.py b/gallery_dl/extractor/civitai.py
index 1e8cb424..36efcfed 100644
--- a/gallery_dl/extractor/civitai.py
+++ b/gallery_dl/extractor/civitai.py
@@ -338,6 +338,7 @@ class CivitaiUserExtractor(CivitaiExtractor):
(CivitaiUserModelsExtractor, base + "models"),
(CivitaiUserPostsExtractor , base + "posts"),
(CivitaiUserImagesExtractor, base + "images"),
+ (CivitaiUserVideosExtractor, base + "videos"),
), ("user-models", "user-posts"))
@@ -400,6 +401,20 @@ class CivitaiUserImagesExtractor(CivitaiExtractor):
return self.api.images(params)
+class CivitaiUserVideosExtractor(CivitaiExtractor):
+ subcategory = "user-videos"
+ directory_fmt = ("{category}", "{username|user[username]}", "videos")
+ pattern = USER_PATTERN + r"/videos/?(?:\?([^#]+))?"
+ example = "https://civitai.com/user/USER/videos"
+
+ def images(self):
+ self._image_ext = "mp4"
+ params = text.parse_query(self.groups[1])
+ params["types"] = ["video"]
+ params["username"] = text.unquote(self.groups[0])
+ return self.api.images(params)
+
+
class CivitaiRestAPI():
"""Interface for the Civitai Public REST API
@@ -484,7 +499,7 @@ class CivitaiTrpcAPI():
self.root = extractor.root + "/api/trpc/"
self.headers = {
"content-type" : "application/json",
- "x-client-version": "5.0.211",
+ "x-client-version": "5.0.394",
"x-client-date" : "",
"x-client" : "web",
"x-fingerprint" : "undefined",
diff --git a/scripts/supportedsites.py b/scripts/supportedsites.py
index 2bbf9f6f..bea3064b 100755
--- a/scripts/supportedsites.py
+++ b/scripts/supportedsites.py
@@ -213,6 +213,7 @@ SUBCATEGORY_MAP = {
"user-models": "User Models",
"user-images": "User Images",
"user-posts" : "User Posts",
+ "user-videos": "User Videos",
},
"coomerparty": {
"discord" : "",
diff --git a/test/results/civitai.py b/test/results/civitai.py
index 24976749..38b62db7 100644
--- a/test/results/civitai.py
+++ b/test/results/civitai.py
@@ -241,4 +241,12 @@ __tests__ = (
"#exception": exception.AuthorizationError,
},
+{
+ "#url" : "https://civitai.com/user/jboogx_creative/videos",
+ "#class": civitai.CivitaiUserVideosExtractor,
+ "#pattern": r"https://image\.civitai\.com/xG1nkqKTMzGDvpLrqFT7WA/[0-9a-f-]+/original=true/\S+\.mp4",
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
)