diff --git a/docs/configuration.rst b/docs/configuration.rst
index 65e129b7..d021a9f0 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -468,6 +468,7 @@ Description
* ``inkbunny``
* ``iwara``
* ``kemono``
+ * ``madokami`` (R)
* ``mangadex``
* ``mangoxo``
* ``newgrounds``
diff --git a/docs/gallery-dl.conf b/docs/gallery-dl.conf
index 8a1d71cd..c2040bd1 100644
--- a/docs/gallery-dl.conf
+++ b/docs/gallery-dl.conf
@@ -447,6 +447,11 @@
{
"gif": false
},
+ "madokami":
+ {
+ "username": "",
+ "password": ""
+ },
"mangadex":
{
"client-id" : "",
diff --git a/docs/supportedsites.md b/docs/supportedsites.md
index 80e7653e..83580c03 100644
--- a/docs/supportedsites.md
+++ b/docs/supportedsites.md
@@ -583,6 +583,12 @@ Consider all listed sites to potentially be NSFW.
Albums, Search Results |
|
+
+ | Madokami |
+ https://manga.madokami.al/ |
+ Manga |
+ Required |
+
| Manga Fox |
https://fanfox.net/ |
diff --git a/gallery_dl/extractor/__init__.py b/gallery_dl/extractor/__init__.py
index 9142fd78..f51a6063 100644
--- a/gallery_dl/extractor/__init__.py
+++ b/gallery_dl/extractor/__init__.py
@@ -106,6 +106,7 @@ modules = [
"lofter",
"luscious",
"lynxchan",
+ "madokami",
"mangadex",
"mangafox",
"mangahere",
diff --git a/gallery_dl/extractor/madokami.py b/gallery_dl/extractor/madokami.py
new file mode 100644
index 00000000..3431cf9b
--- /dev/null
+++ b/gallery_dl/extractor/madokami.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2025 Mike Fährmann
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+"""Extractors for https://manga.madokami.al/"""
+
+from .common import Extractor, Message
+from .. import text, util, exception
+
+BASE_PATTERN = r"(?:https?://)?manga\.madokami\.al"
+
+
+class MadokamiExtractor(Extractor):
+ """Base class for madokami extractors"""
+ category = "madokami"
+ root = "https://manga.madokami.al"
+
+
+class MadokamiMangaExtractor(MadokamiExtractor):
+ """Extractor for madokami manga"""
+ subcategory = "manga"
+ directory_fmt = ("{category}", "{manga}")
+ archive_fmt = "{chapter_id}"
+ pattern = rf"{BASE_PATTERN}/Manga/(\w/\w{{2}}/\w{{4}}/.+)"
+ example = "https://manga.madokami.al/Manga/A/AB/ABCD/ABCDE_TITLE"
+
+ def items(self):
+ username, password = self._get_auth_info()
+ if not username:
+ raise exception.LoginRequired("Missing 'username' & 'password'")
+ self.session.auth = util.HTTPBasicAuth(username, password)
+
+ url = f"{self.root}/Manga/{self.groups[0]}"
+ page = self.request(url).text
+ extr = text.extract_from(page)
+
+ chapters = []
+ while True:
+ if not (cid := extr('
", "<")),
+ "size": text.parse_bytes(extr("| ", " | ")),
+ "date": text.parse_datetime(
+ extr("", " | ").strip(), "%Y-%m-%d %H:%M"),
+ })
+
+ if self.config("chapter-reverse"):
+ chapters.reverse()
+
+ self.kwdict.update({
+ "manga" : text.unescape(extr('itemprop="name">', "<")),
+ "year" : text.parse_int(extr(
+ 'itemprop="datePublished" content="', "-")),
+ "author": text.split_html(extr('"))[1::2],
+ "genre" : text.split_html(extr("
Genres
", "")),
+ "tags" : text.split_html(extr("Tags
", "")),
+ "complete": extr('span class="scanstatus">', "<").lower() == "yes",
+ })
+
+ parse_chinfo = text.re(
+ r"(?i).+?\s+("
+ r"(?:v(?:ol)?\.?\s*(\d+)\s+)?"
+ r"(?:ch?\.?\s*(\d+)(?:-(\d+))?)"
+ r")"
+ ).match
+
+ for ch in chapters:
+
+ chstr = ch["chapter_string"]
+ if match := parse_chinfo(chstr):
+ ch["chapter_string"], volume, chapter, end = match.groups()
+ ch["volume"] = text.parse_int(volume)
+ ch["chapter"] = text.parse_int(chapter)
+ ch["chapter_end"] = text.parse_int(end)
+ else:
+ ch["volume"] = ch["chapter"] = ch["chapter_end"] = 0
+
+ url = f"{self.root}{ch['path']}"
+ text.nameext_from_url(url, ch)
+
+ yield Message.Directory, ch
+ yield Message.Url, url, ch
diff --git a/scripts/supportedsites.py b/scripts/supportedsites.py
index 1dc2f007..f8f0fe54 100755
--- a/scripts/supportedsites.py
+++ b/scripts/supportedsites.py
@@ -482,6 +482,7 @@ AUTH_MAP = {
"instagram" : _COOKIES,
"iwara" : "Supported",
"kemono" : "Supported",
+ "madokami" : "Required",
"mangadex" : "Supported",
"mangoxo" : "Supported",
"mastodon.social": _OAUTH,
diff --git a/test/results/madokami.py b/test/results/madokami.py
new file mode 100644
index 00000000..78554bba
--- /dev/null
+++ b/test/results/madokami.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import madokami
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://manga.madokami.al/Manga/K/K_/K___/K%20-%20Memory%20of%20Red",
+ "#class" : madokami.MadokamiMangaExtractor,
+ "#auth" : True,
+ "#results" : (
+ "https://manga.madokami.al/Manga/K/K_/K___/K%20-%20Memory%20of%20Red/K%20-%20Memory%20of%20Red%20v01%20c01-02%20%281%20of%202%29.zip",
+ "https://manga.madokami.al/Manga/K/K_/K___/K%20-%20Memory%20of%20Red/K%20-%20Memory%20of%20Red%20v01%20c03-05%20%282%20of%202%29.zip",
+ "https://manga.madokami.al/Manga/K/K_/K___/K%20-%20Memory%20of%20Red/K%20-%20Memory%20of%20Red%20v02%20c06-10.zip",
+ "https://manga.madokami.al/Manga/K/K_/K___/K%20-%20Memory%20of%20Red/K%20-%20Memory%20of%20Red%20v03%20c11-13%20%281%20of%202%29.zip",
+ "https://manga.madokami.al/Manga/K/K_/K___/K%20-%20Memory%20of%20Red/K%20-%20Memory%20of%20Red%20v03%20c14-15%20%282%20of%202%29.zip",
+ ),
+
+ "chapter" : {1, 3, 6, 11, 14},
+ "chapter_end" : {2, 5, 10, 13, 15},
+ "chapter_id" : range(57413, 57417),
+ "chapter_string": r"re:v\d\d c\d\d-\d\d",
+ "complete" : True,
+ "date" : "type:datetime",
+ "extension" : "zip",
+ "filename" : r"re:K - Memory of Red .+",
+ "manga" : "K - Memory of Red",
+ "path" : r"re:/Manga/K/K_/K___/K%20-%20Memory%20of%20Red/K%20-%20Memory%20of%20Red%20.+\.zip",
+ "size" : range(57_986_253, 82_732_646),
+ "volume" : range(1, 3),
+ "year" : 2012,
+ "author" : [
+ "GoHands",
+ "GoRA",
+ "KUROE Yui",
+ ],
+ "genre" : [
+ "Action",
+ "Shoujo",
+ "Supernatural",
+ ],
+ "tags" : [
+ "Bar/s",
+ "Bartender/s",
+ "Based on an Anime",
+ "Bishounen",
+ "Gang/s",
+ "Multiple Protagonists",
+ "Mysterious Protagonist",
+ "Skateboarding",
+ "Street Fighting",
+ "Stubborn Protagonist",
+ ],
+},
+
+{
+ "#url" : "https://manga.madokami.al/Manga/K/K_/K___/K%20-%20Memory%20of%20Red",
+ "#comment" : "no username & password",
+ "#class" : madokami.MadokamiMangaExtractor,
+ "#auth" : False,
+ "#exception": exception.LoginRequired,
+},
+
+)