diff --git a/docs/configuration.rst b/docs/configuration.rst index a71ac9b6..cd47dfa0 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -3631,9 +3631,27 @@ Description `revisions `__ are returned. - * ``"asc"``: Ascending order (oldest first) - * ``"desc"``: Descending order (newest first) - * ``"reverse"``: Same as ``"asc"`` + ``"asc"`` | ``"reverse"`` + Ascending order (oldest first) + ``"desc"`` + Descending order (newest first) + + +extractor.kemono.discord.order-posts +------------------------------------ +Type + ``string`` +Default + ``"asc"`` +Description + Controls the order in which + ``discord`` posts + are returned. + + ``"asc"`` + Ascending order (oldest first) + ``"desc"`` | ``"reverse"`` + Descending order (newest first) extractor.khinsider.covers diff --git a/docs/gallery-dl.conf b/docs/gallery-dl.conf index d03effd1..1ce8e9f2 100644 --- a/docs/gallery-dl.conf +++ b/docs/gallery-dl.conf @@ -488,7 +488,11 @@ "max-posts" : null, "metadata" : true, "revisions" : false, - "order-revisions": "desc" + "order-revisions": "desc", + + "discord": { + "order-posts": "asc" + } }, "khinsider": { diff --git a/gallery_dl/extractor/kemono.py b/gallery_dl/extractor/kemono.py index fc5972c6..1f700311 100644 --- a/gallery_dl/extractor/kemono.py +++ b/gallery_dl/extractor/kemono.py @@ -407,7 +407,11 @@ class KemonoDiscordExtractor(KemonoExtractor): r"(/[A-Za-z0-9-._~:/?#\[\]@!$&'()*+,;%=]+)").findall find_hash = util.re(HASH_PATTERN).match - posts = self.api.discord_channel(channel_id) + if (order := self.config("order-posts")) and order[0] in ("r", "d"): + posts = self.api.discord_channel(channel_id, channel["post_count"]) + else: + posts = self.api.discord_channel(channel_id) + if max_posts := self.config("max-posts"): posts = itertools.islice(posts, max_posts) @@ -627,9 +631,12 @@ class KemonoAPI(): endpoint = f"/{service}/user/{creator_id}/tags" return self._call(endpoint) - def discord_channel(self, channel_id): + def discord_channel(self, channel_id, post_count=None): endpoint = f"/discord/channel/{channel_id}" - return self._pagination(endpoint, {}, 150) + if post_count is None: + return self._pagination(endpoint, {}, 150) + else: + return self._pagination_reverse(endpoint, {}, 150, post_count) def discord_channel_lookup(self, server_id): endpoint = f"/discord/channel/lookup/{server_id}" @@ -670,3 +677,18 @@ class KemonoAPI(): if len(data) < batch: return params["o"] += batch + + def _pagination_reverse(self, endpoint, params, batch, count): + params["o"] = count // batch * batch + + while True: + data = self._call(endpoint, params) + + if not data: + return + data.reverse() + yield from data + + if not params["o"]: + return + params["o"] -= batch diff --git a/test/results/kemono.py b/test/results/kemono.py index d385ace0..ace42e4a 100644 --- a/test/results/kemono.py +++ b/test/results/kemono.py @@ -535,7 +535,33 @@ __tests__ = ( "#url" : "https://kemono.cr/discord/server/488668827274444803/608504710906904576", "#category": ("", "kemono", "discord"), "#class" : kemono.KemonoDiscordExtractor, - "#count" : 4, + "#results" : ( + "https://kemono.cr/data/6e/6a/6e6a4a048e6f3c047edac851d1f66eca4a4f0a823faa1d9395892378fcb700b1.png", + "https://kemono.cr/data/55/e1/55e1ddf540ded5e6651de65c059529d1f51451cde523ec103dc696f1cc3595a4.png", + "https://kemono.cr/data/9d/98/9d983fd163d5f5335c896c93b9f363198d6ca14a7e5bf0fa823aa86268732f85.png", + "https://kemono.cr/data/fb/54/fb54ff75f1c879b25bf031a55a1730002049337693443f1b57c08b07e35c452f.png", + ), + + "channel" : "finish-work", + "channel_id" : "608504710906904576", + "channel_nsfw" : False, + "channel_topic": None, + "channel_type" : 0, + "server" : "ABFMMD NSFW Server", + "server_id" : "488668827274444803", +}, + +{ + "#url" : "https://kemono.cr/discord/server/488668827274444803/608504710906904576", + "#category": ("", "kemono", "discord"), + "#class" : kemono.KemonoDiscordExtractor, + "#options" : {"order-posts": "reverse"}, + "#results" : ( + "https://kemono.cr/data/fb/54/fb54ff75f1c879b25bf031a55a1730002049337693443f1b57c08b07e35c452f.png", + "https://kemono.cr/data/9d/98/9d983fd163d5f5335c896c93b9f363198d6ca14a7e5bf0fa823aa86268732f85.png", + "https://kemono.cr/data/55/e1/55e1ddf540ded5e6651de65c059529d1f51451cde523ec103dc696f1cc3595a4.png", + "https://kemono.cr/data/6e/6a/6e6a4a048e6f3c047edac851d1f66eca4a4f0a823faa1d9395892378fcb700b1.png", + ), "channel" : "finish-work", "channel_id" : "608504710906904576",