From 33f228756ace7efe282c924dbab4fb1c5801283a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20F=C3=A4hrmann?= Date: Sun, 7 Jan 2024 02:59:35 +0100 Subject: [PATCH] [mangadex] add 'list' extractor (#5025) supports listing manga and chapters from list feed --- docs/supportedsites.md | 2 +- gallery_dl/extractor/mangadex.py | 31 +++++++++++++++++++++++++++++++ test/results/mangadex.py | 27 +++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/docs/supportedsites.md b/docs/supportedsites.md index d046aad4..057515c9 100644 --- a/docs/supportedsites.md +++ b/docs/supportedsites.md @@ -502,7 +502,7 @@ Consider all listed sites to potentially be NSFW. MangaDex https://mangadex.org/ - Chapters, Followed Feed, Manga + Chapters, Followed Feed, Lists, Manga Supported diff --git a/gallery_dl/extractor/mangadex.py b/gallery_dl/extractor/mangadex.py index 94bea570..d287d5cf 100644 --- a/gallery_dl/extractor/mangadex.py +++ b/gallery_dl/extractor/mangadex.py @@ -148,6 +148,31 @@ class MangadexFeedExtractor(MangadexExtractor): return self.api.user_follows_manga_feed() +class MangadexListExtractor(MangadexExtractor): + """Extractor for mangadex lists""" + subcategory = "list" + pattern = (BASE_PATTERN + + r"/list/([0-9a-f-]+)(?:/[^/?#]*)?(?:\?tab=(\w+))?") + example = ("https://mangadex.org/list" + "/01234567-89ab-cdef-0123-456789abcdef/NAME") + + def __init__(self, match): + MangadexExtractor.__init__(self, match) + if match.group(2) != "feed": + self.subcategory = "list-feed" + self.items = self._items_titles + + def chapters(self): + return self.api.list_feed(self.uuid) + + def _items_titles(self): + data = {"_extractor": MangadexMangaExtractor} + for item in self.api.list(self.uuid)["relationships"]: + if item["type"] == "manga": + url = "{}/title/{}".format(self.root, item["id"]) + yield Message.Queue, url, data + + class MangadexAPI(): """Interface for the MangaDex API v5 @@ -173,6 +198,12 @@ class MangadexAPI(): params = {"includes[]": ("scanlation_group",)} return self._call("/chapter/" + uuid, params)["data"] + def list(self, uuid): + return self._call("/list/" + uuid)["data"] + + def list_feed(self, uuid): + return self._pagination("/list/" + uuid + "/feed") + @memcache(keyarg=1) def manga(self, uuid): params = {"includes[]": ("artist", "author")} diff --git a/test/results/mangadex.py b/test/results/mangadex.py index 17b2157c..ae1c7ab1 100644 --- a/test/results/mangadex.py +++ b/test/results/mangadex.py @@ -113,4 +113,31 @@ __tests__ = ( "#class" : mangadex.MangadexFeedExtractor, }, +{ + "#url" : "https://mangadex.org/list/3a0982c5-65aa-4de2-8a4a-2175be7383ab/test", + "#category": ("", "mangadex", "list"), + "#class" : mangadex.MangadexListExtractor, + "#urls" : ( + "https://mangadex.org/title/cba4e5d6-67a0-47a0-b37a-c06e9bf25d93", + "https://mangadex.org/title/cad76ec6-ca22-42f6-96f8-eca164da6545", + ), +}, + +{ + "#url" : "https://mangadex.org/list/3a0982c5-65aa-4de2-8a4a-2175be7383ab/test?tab=titles", + "#category": ("", "mangadex", "list"), + "#class" : mangadex.MangadexListExtractor, +}, + +{ + "#url" : "https://mangadex.org/list/3a0982c5-65aa-4de2-8a4a-2175be7383ab/test?tab=feed", + "#category": ("", "mangadex", "list-feed"), + "#class" : mangadex.MangadexListExtractor, + "#urls" : ( + "https://mangadex.org/chapter/c765d6d5-5712-4360-be0b-0c8e0914fc94", + "https://mangadex.org/chapter/fa8a695d-260f-4dcc-95a3-1f30e66d6571", + "https://mangadex.org/chapter/788766b9-41c6-422e-97ba-552f03ba9655", + ), +}, + )