diff --git a/docs/supportedsites.md b/docs/supportedsites.md
index 1eeb2a33..0f7d40b4 100644
--- a/docs/supportedsites.md
+++ b/docs/supportedsites.md
@@ -1252,25 +1252,25 @@ Consider all listed sites to potentially be NSFW.
| Danbooru |
https://danbooru.donmai.us/ |
- Artists, Artist Searches, Favorite Groups, Pools, Popular Images, Posts, Tag Searches |
+ Artists, Artist Searches, Favorite Groups, Pools, Popular Images, Posts, Random Posts, Tag Searches |
Supported |
| ATFBooru |
https://booru.allthefallen.moe/ |
- Artists, Artist Searches, Favorite Groups, Pools, Popular Images, Posts, Tag Searches |
+ Artists, Artist Searches, Favorite Groups, Pools, Popular Images, Posts, Random Posts, Tag Searches |
Supported |
| AIBooru |
https://aibooru.online/ |
- Artists, Artist Searches, Favorite Groups, Pools, Popular Images, Posts, Tag Searches |
+ Artists, Artist Searches, Favorite Groups, Pools, Popular Images, Posts, Random Posts, Tag Searches |
Supported |
| Booruvar |
https://booru.borvar.art/ |
- Artists, Artist Searches, Favorite Groups, Pools, Popular Images, Posts, Tag Searches |
+ Artists, Artist Searches, Favorite Groups, Pools, Popular Images, Posts, Random Posts, Tag Searches |
Supported |
diff --git a/gallery_dl/extractor/danbooru.py b/gallery_dl/extractor/danbooru.py
index f8ad07a8..29c77634 100644
--- a/gallery_dl/extractor/danbooru.py
+++ b/gallery_dl/extractor/danbooru.py
@@ -278,6 +278,23 @@ class DanbooruTagExtractor(DanbooruExtractor):
return self._pagination("/posts.json", {"tags": self.tags}, prefix)
+class DanbooruRandomExtractor(DanbooruTagExtractor):
+ """Extractor for a random danbooru post"""
+ subcategory = "random"
+ pattern = BASE_PATTERN + r"/posts/random(?:\?(?:[^]*&)*tags=([^]*))?"
+ example = "https://danbooru.donmai.us/posts/random?tags=TAG"
+
+ def metadata(self):
+ tags = self.groups[-1] or ""
+ self.tags = text.unquote(tags.replace("+", " "))
+ return {"search_tags": self.tags}
+
+ def posts(self):
+ posts = self.request_json(self.root + "/posts/random.json",
+ params={"tags": self.tags or None})
+ return (posts,) if isinstance(posts, dict) else posts
+
+
class DanbooruPoolExtractor(DanbooruExtractor):
"""Extractor for Danbooru pools"""
subcategory = "pool"
diff --git a/scripts/supportedsites.py b/scripts/supportedsites.py
index 3963bd3d..e816ad59 100755
--- a/scripts/supportedsites.py
+++ b/scripts/supportedsites.py
@@ -264,6 +264,7 @@ SUBCATEGORY_MAP = {
},
"Danbooru": {
"favgroup": "Favorite Groups",
+ "random" : "Random Posts",
},
"desktopography": {
"site": "",
diff --git a/test/results/aibooru.py b/test/results/aibooru.py
index 73951bc6..e735a351 100644
--- a/test/results/aibooru.py
+++ b/test/results/aibooru.py
@@ -80,4 +80,24 @@ __tests__ = (
"#class" : danbooru.DanbooruPopularExtractor,
},
+{
+ "#url" : "https://aibooru.online/posts/random?tags=center_frills&z=1",
+ "#category": ("Danbooru", "aibooru", "random"),
+ "#class" : danbooru.DanbooruRandomExtractor,
+ "#pattern" : "https://cdn.aibooru.download/original/.+",
+ "#count" : 1,
+
+ "search_tags": "center_frills",
+},
+
+{
+ "#url" : "https://aibooru.online/posts/random",
+ "#category": ("Danbooru", "aibooru", "random"),
+ "#class" : danbooru.DanbooruRandomExtractor,
+ "#pattern" : "https://cdn.aibooru.download/original/.+",
+ "#count" : 1,
+
+ "search_tags": "",
+},
+
)
diff --git a/test/results/atfbooru.py b/test/results/atfbooru.py
index 4bdd1b6d..8f5495f7 100644
--- a/test/results/atfbooru.py
+++ b/test/results/atfbooru.py
@@ -36,4 +36,16 @@ __tests__ = (
"#class" : danbooru.DanbooruPopularExtractor,
},
+{
+ "#url" : "https://booru.allthefallen.moe/posts/random?tags=yume_shokunin",
+ "#category": ("Danbooru", "atfbooru", "random"),
+ "#class" : danbooru.DanbooruRandomExtractor,
+},
+
+{
+ "#url" : "https://booru.allthefallen.moe/posts/random",
+ "#category": ("Danbooru", "atfbooru", "random"),
+ "#class" : danbooru.DanbooruRandomExtractor,
+},
+
)
diff --git a/test/results/booruvar.py b/test/results/booruvar.py
index 8beb45e1..c221392c 100644
--- a/test/results/booruvar.py
+++ b/test/results/booruvar.py
@@ -37,4 +37,16 @@ __tests__ = (
"#class" : danbooru.DanbooruPopularExtractor,
},
+{
+ "#url" : "https://booru.borvar.art/posts/random?tags=chibi&z=1",
+ "#category": ("Danbooru", "booruvar", "random"),
+ "#class" : danbooru.DanbooruRandomExtractor,
+},
+
+{
+ "#url" : "https://booru.borvar.art/posts/random",
+ "#category": ("Danbooru", "booruvar", "random"),
+ "#class" : danbooru.DanbooruRandomExtractor,
+},
+
)
diff --git a/test/results/danbooru.py b/test/results/danbooru.py
index 74fbd17e..cec5abea 100644
--- a/test/results/danbooru.py
+++ b/test/results/danbooru.py
@@ -382,4 +382,24 @@ __tests__ = (
"other_names": list,
},
+{
+ "#url" : "https://danbooru.donmai.us/posts/random?tags=bonocho",
+ "#category": ("Danbooru", "danbooru", "random"),
+ "#class" : danbooru.DanbooruRandomExtractor,
+ "#pattern" : "https://cdn.donmai.us/original/.+",
+ "#count" : 1,
+
+ "search_tags": "bonocho",
+},
+
+{
+ "#url" : "https://danbooru.donmai.us/posts/random",
+ "#category": ("Danbooru", "danbooru", "random"),
+ "#class" : danbooru.DanbooruRandomExtractor,
+ "#pattern" : "https://cdn.donmai.us/original/.+",
+ "#count" : 1,
+
+ "search_tags": "",
+},
+
)