aboutsummaryrefslogtreecommitdiffstats
path: root/gallery_dl/extractor/madokami.py
blob: 0b90e8efd836fe2b9846189df74bb0c03a4bb05d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# -*- 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 = BASE_PATTERN + r"/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.AuthRequired("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('<tr data-record="', '"')):
                break
            chapters.append({
                "chapter_id": text.parse_int(cid),
                "path": text.unescape(extr('href="', '"')),
                "chapter_string": text.unescape(extr(">", "<")),
                "size": text.parse_bytes(extr("<td>", "</td>")),
                "date": self.parse_datetime_iso(extr("<td>", "</td>").strip()),
            })

        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('<p class="staff', "</p>"))[1::2],
            "genre" : text.split_html(extr("<h3>Genres</h3>", "</div>")),
            "tags"  : text.split_html(extr("<h3>Tags</h3>", "</div>")),
            "complete": extr('span class="scanstatus">', "<").lower() == "yes",
        })

        search_chstr = text.re(
            r"(?i)((?:v(?:ol)?\.?\s*(\d+))"
            r"(?:\s+ch?\.?\s*(\d+)(?:-(\d+))?)?)").search
        search_chstr_min = text.re(
            r"(?i)(ch?\.?\s*(\d+)(?:-(\d+))?)").search

        for ch in chapters:

            chstr = ch["chapter_string"]
            if match := search_chstr(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)
            elif match := search_chstr_min(chstr):
                ch["chapter_string"], chapter, end = match.groups()
                ch["volume"] = 0
                ch["chapter"] = text.parse_int(chapter)
                ch["chapter_end"] = text.parse_int(end)
            else:
                ch["volume"] = ch["chapter"] = ch["chapter_end"] = 0

            url = self.root + ch["path"]
            text.nameext_from_url(url, ch)

            yield Message.Directory, "", ch
            yield Message.Url, url, ch