diff --git a/docs/supportedsites.md b/docs/supportedsites.md index 4f06028f..14f62e08 100644 --- a/docs/supportedsites.md +++ b/docs/supportedsites.md @@ -1138,25 +1138,25 @@ Consider all listed sites to potentially be NSFW. Danbooru https://danbooru.donmai.us/ - Pools, Popular Images, Posts, Tag Searches + Artists, Artist Searches, Pools, Popular Images, Posts, Tag Searches Supported ATFBooru https://booru.allthefallen.moe/ - Pools, Popular Images, Posts, Tag Searches + Artists, Artist Searches, Pools, Popular Images, Posts, Tag Searches Supported Aibooru https://aibooru.online/ - Pools, Popular Images, Posts, Tag Searches + Artists, Artist Searches, Pools, Popular Images, Posts, Tag Searches Supported Booruvar https://booru.borvar.art/ - Pools, Popular Images, Posts, Tag Searches + Artists, Artist Searches, Pools, Popular Images, Posts, Tag Searches Supported diff --git a/gallery_dl/extractor/danbooru.py b/gallery_dl/extractor/danbooru.py index 815efbce..1f33f9fb 100644 --- a/gallery_dl/extractor/danbooru.py +++ b/gallery_dl/extractor/danbooru.py @@ -108,6 +108,13 @@ class DanbooruExtractor(BaseExtractor): yield Message.Directory, post yield Message.Url, url, post + def items_artists(self): + for artist in self.artists(): + artist["_extractor"] = DanbooruTagExtractor + url = "{}/posts?tags={}".format( + self.root, text.quote(artist["name"])) + yield Message.Queue, url, artist + def metadata(self): return () @@ -302,15 +309,31 @@ class DanbooruArtistExtractor(DanbooruExtractor): pattern = BASE_PATTERN + r"/artists/(\d+)" example = "https://danbooru.donmai.us/artists/12345" - def items(self): - url = "{}/artists/{}.json".format(self.root, self.groups[-1]) - artist = self.request(url).json() + items = DanbooruExtractor.items_artists - url = "{}/posts?tags={}".format( - self.root, text.quote(artist["name"])) - data = { - "_extractor": DanbooruTagExtractor, - "artist" : artist, - } - yield Message.Directory, data - yield Message.Queue, url, data + def artists(self): + url = "{}/artists/{}.json".format(self.root, self.groups[-1]) + return (self.request(url).json(),) + + +class DanbooruArtistSearchExtractor(DanbooruExtractor): + """Extractor for danbooru artist searches""" + subcategory = "artist-search" + pattern = BASE_PATTERN + r"/artists/?\?([^#]+)" + example = "https://danbooru.donmai.us/artists?QUERY" + + items = DanbooruExtractor.items_artists + + def artists(self): + url = self.root + "/artists.json" + params = text.parse_query(self.groups[-1]) + params["page"] = text.parse_int(params.get("page"), 1) + + while True: + artists = self.request(url, params=params).json() + + yield from artists + + if len(artists) < 20: + return + params["page"] += 1 diff --git a/scripts/supportedsites.py b/scripts/supportedsites.py index 4ba5a763..357d7c39 100755 --- a/scripts/supportedsites.py +++ b/scripts/supportedsites.py @@ -217,6 +217,9 @@ SUBCATEGORY_MAP = { "discord-server": "", "posts" : "", }, + "Danbooru": { + "artist-search": "Artist Searches", + }, "desktopography": { "site": "", }, diff --git a/test/results/danbooru.py b/test/results/danbooru.py index bad66413..3a857dbb 100644 --- a/test/results/danbooru.py +++ b/test/results/danbooru.py @@ -231,4 +231,40 @@ __tests__ = ( "#count" : 120, }, +{ + "#url" : "https://danbooru.donmai.us/artists/288683", + "#category": ("Danbooru", "danbooru", "artist"), + "#class" : danbooru.DanbooruArtistExtractor, + "#urls" : "https://danbooru.donmai.us/posts?tags=kaori_%28vuoian_appxv%29", + + "created_at" : "2022-05-12T16:00:40.852-04:00", + "updated_at" : "2022-05-12T22:10:51.917-04:00", + "group_name" : "", + "id" : 288683, + "is_banned" : False, + "is_deleted" : False, + "name" : "kaori_(vuoian_appxv)", + "other_names": [ + "香", + "vuoian_appxv", + ], +}, + +{ + "#url" : "https://danbooru.donmai.us/artists?commit=Search&search%5Bany_name_matches%5D=yu&search%5Border%5D=created_at", + "#category": ("Danbooru", "danbooru", "artist-search"), + "#class" : danbooru.DanbooruArtistSearchExtractor, + "#pattern" : danbooru.DanbooruTagExtractor.pattern, + "#count" : "> 50", + + "created_at" : str, + "updated_at" : str, + "group_name" : str, + "id" : int, + "is_banned" : bool, + "is_deleted" : bool, + "name" : str, + "other_names": list, +}, + )