[dankefuerslesen] add support (#7669)
This commit is contained in:
@@ -2037,6 +2037,16 @@ Description
|
||||
batch. The value cannot be less than 1.
|
||||
|
||||
|
||||
extractor.dankefuerslesen.zip
|
||||
-----------------------------
|
||||
Type
|
||||
``bool``
|
||||
Default
|
||||
``false``
|
||||
Description
|
||||
Download each chapter as a single ZIP archive instead of individual images.
|
||||
|
||||
|
||||
extractor.deviantart.auto-watch
|
||||
-------------------------------
|
||||
Type
|
||||
|
||||
@@ -220,6 +220,10 @@
|
||||
{
|
||||
"domain": null
|
||||
},
|
||||
"dankefuerslesen":
|
||||
{
|
||||
"zip": false
|
||||
},
|
||||
"deviantart":
|
||||
{
|
||||
"client-id" : null,
|
||||
|
||||
@@ -199,6 +199,12 @@ Consider all listed sites to potentially be NSFW.
|
||||
<td>Albums, Media Files</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Danke fürs Lesen</td>
|
||||
<td>https://danke.moe/</td>
|
||||
<td>Chapters, Manga</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Desktopography</td>
|
||||
<td>https://desktopography.net/</td>
|
||||
|
||||
@@ -43,6 +43,7 @@ modules = [
|
||||
"comicvine",
|
||||
"cyberdrop",
|
||||
"danbooru",
|
||||
"dankefuerslesen",
|
||||
"desktopography",
|
||||
"deviantart",
|
||||
"discord",
|
||||
|
||||
123
gallery_dl/extractor/dankefuerslesen.py
Normal file
123
gallery_dl/extractor/dankefuerslesen.py
Normal file
@@ -0,0 +1,123 @@
|
||||
# -*- 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://danke.moe/"""
|
||||
|
||||
from .common import ChapterExtractor, MangaExtractor
|
||||
from .. import text
|
||||
from ..cache import memcache
|
||||
|
||||
BASE_PATTERN = r"(?:https?://)?(?:www\.)?danke\.moe"
|
||||
|
||||
|
||||
class DankefuerslesenBase():
|
||||
"""Base class for dankefuerslesen extractors"""
|
||||
category = "dankefuerslesen"
|
||||
root = "https://danke.moe"
|
||||
|
||||
@memcache(keyarg=1)
|
||||
def _manga_info(self, slug):
|
||||
url = f"{self.root}/api/series/{slug}/"
|
||||
return self.request_json(url)
|
||||
|
||||
|
||||
class DankefuerslesenChapterExtractor(DankefuerslesenBase, ChapterExtractor):
|
||||
"""Extractor for Danke fürs Lesen manga chapters"""
|
||||
pattern = BASE_PATTERN + r"/read/manga/([\w-]+)/([\w-]+)"
|
||||
example = "https://danke.moe/read/manga/TITLE/123/1/"
|
||||
|
||||
def __init__(self, match):
|
||||
ChapterExtractor.__init__(self, match, False)
|
||||
|
||||
def _init(self):
|
||||
self.zip = self.config("zip", False)
|
||||
if self.zip:
|
||||
self.filename_fmt = f"{self.directory_fmt[-1]}.{{extension}}"
|
||||
self.directory_fmt = self.directory_fmt[:-1]
|
||||
|
||||
def metadata(self, page):
|
||||
slug, ch = self.groups
|
||||
manga = self._manga_info(slug)
|
||||
|
||||
if "-" in ch:
|
||||
chapter, sep, minor = ch.rpartition("-")
|
||||
ch = ch.replace("-", ".")
|
||||
minor = "." + minor
|
||||
else:
|
||||
chapter = ch
|
||||
minor = ""
|
||||
|
||||
data = manga["chapters"][ch]
|
||||
group_id, self._files = data["groups"].popitem()
|
||||
|
||||
if not self.zip:
|
||||
self.base = (f"{self.root}/media/manga/{slug}/chapters"
|
||||
f"/{data['folder']}/{group_id}/")
|
||||
|
||||
return {
|
||||
"manga" : manga["title"],
|
||||
"manga_slug": manga["slug"],
|
||||
"title" : data["title"],
|
||||
"volume" : text.parse_int(data["volume"]),
|
||||
"chapter" : text.parse_int(chapter),
|
||||
"chapter_minor": minor,
|
||||
"group" : manga["groups"][group_id],
|
||||
"group_id" : text.parse_int(group_id),
|
||||
"date" : text.parse_timestamp(data["release_date"][group_id]),
|
||||
"lang" : "en",
|
||||
"language" : "English",
|
||||
}
|
||||
|
||||
def images(self, page):
|
||||
if self.zip:
|
||||
return ()
|
||||
|
||||
base = self.base
|
||||
return [(base + file, None) for file in self._files]
|
||||
|
||||
def assets(self, page):
|
||||
if self.zip:
|
||||
slug, ch = self.groups
|
||||
url = f"{self.root}/api/download_chapter/{slug}/{ch}/"
|
||||
return ({
|
||||
"type" : "archive",
|
||||
"extension": "zip",
|
||||
"url" : url,
|
||||
},)
|
||||
|
||||
|
||||
class DankefuerslesenMangaExtractor(DankefuerslesenBase, MangaExtractor):
|
||||
"""Extractor for Danke fürs Lesen manga"""
|
||||
chapterclass = DankefuerslesenChapterExtractor
|
||||
pattern = BASE_PATTERN + r"/read/manga/([^/?#]+)"
|
||||
example = "https://danke.moe/read/manga/TITLE/"
|
||||
|
||||
def __init__(self, match):
|
||||
MangaExtractor.__init__(self, match, False)
|
||||
|
||||
def chapters(self, page):
|
||||
results = []
|
||||
|
||||
manga = self._manga_info(self.groups[0]).copy()
|
||||
base = f"{self.root}/read/manga/{manga['slug']}/"
|
||||
for ch, data in manga.pop("chapters").items():
|
||||
|
||||
if "." in ch:
|
||||
chapter, sep, minor = ch.rpartition(".")
|
||||
ch = ch.replace('.', '-')
|
||||
data["chapter"] = text.parse_int(chapter)
|
||||
data["chapter-minor"] = sep + minor
|
||||
else:
|
||||
data["chapter"] = text.parse_int(ch)
|
||||
data["chapter-minor"] = ""
|
||||
|
||||
url = f"{base}{ch}/1/"
|
||||
manga.update(data)
|
||||
results.append((url, manga))
|
||||
|
||||
return results
|
||||
@@ -40,6 +40,7 @@ CATEGORY_MAP = {
|
||||
"cien" : "Ci-en",
|
||||
"cohost" : "cohost!",
|
||||
"comicvine" : "Comic Vine",
|
||||
"dankefuerslesen": "Danke fürs Lesen",
|
||||
"deviantart" : "DeviantArt",
|
||||
"drawfriends" : "Draw Friends",
|
||||
"dynastyscans" : "Dynasty Reader",
|
||||
|
||||
80
test/results/dankefuerslesen.py
Normal file
80
test/results/dankefuerslesen.py
Normal file
@@ -0,0 +1,80 @@
|
||||
# -*- 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 dankefuerslesen
|
||||
|
||||
|
||||
__tests__ = (
|
||||
{
|
||||
"#url" : "https://danke.moe/read/manga/awana-chan-wa-kyou-mo-shiawase/2/1/",
|
||||
"#class" : dankefuerslesen.DankefuerslesenChapterExtractor,
|
||||
"#pattern" : r"https://danke.moe/media/manga/awana-chan-wa-kyou-mo-shiawase/chapters/0002_m9inbehz/69/\d+\.png",
|
||||
"#count" : 22,
|
||||
|
||||
"volume" : 1,
|
||||
"chapter" : 2,
|
||||
"chapter_minor": "",
|
||||
"count" : 22,
|
||||
"page" : range(1, 22),
|
||||
"date" : "dt:2025-02-09 19:03:08",
|
||||
"extension" : "png",
|
||||
"filename" : str,
|
||||
"group" : "Good Try Scans",
|
||||
"group_id" : 69,
|
||||
"lang" : "en",
|
||||
"language" : "English",
|
||||
"manga" : "Awana-chan wa Kyou mo Shiawase",
|
||||
"manga_slug": "awana-chan-wa-kyou-mo-shiawase",
|
||||
"title" : "Eat some ramen!",
|
||||
},
|
||||
|
||||
{
|
||||
"#url" : "https://danke.moe/read/manga/awana-chan-wa-kyou-mo-shiawase/2/1/",
|
||||
"#comment" : "ZIP archive download",
|
||||
"#class" : dankefuerslesen.DankefuerslesenChapterExtractor,
|
||||
"#options" : {"zip": True},
|
||||
"#results" : "https://danke.moe/api/download_chapter/awana-chan-wa-kyou-mo-shiawase/2/",
|
||||
|
||||
"count" : 0,
|
||||
"page" : 0,
|
||||
"extension": "zip",
|
||||
},
|
||||
|
||||
{
|
||||
"#url" : "https://danke.moe/read/manga/raul-and-the-vampire/7-5/1/",
|
||||
"#comment" : "minor chapter version",
|
||||
"#class" : dankefuerslesen.DankefuerslesenChapterExtractor,
|
||||
"#pattern" : r"https://danke.moe/media/manga/raul-and-the-vampire/chapters/0009-5_efnaqvlj/56/\d+\.png",
|
||||
"#count" : 20,
|
||||
|
||||
"volume" : 1,
|
||||
"chapter" : 7,
|
||||
"chapter_minor": ".5",
|
||||
"count" : 20,
|
||||
"page" : range(1, 20),
|
||||
"date" : "dt:2024-10-10 07:12:44",
|
||||
"extension" : "png",
|
||||
"filename" : str,
|
||||
"group" : "Danke fürs Lesen & Senko-san's Abode",
|
||||
"group_id" : 56,
|
||||
"lang" : "en",
|
||||
"language" : "English",
|
||||
"manga" : "Raul and The Vampire",
|
||||
"manga_slug": "raul-and-the-vampire",
|
||||
"title" : "Volume 1 Extras",
|
||||
},
|
||||
|
||||
{
|
||||
"#url" : "https://danke.moe/read/manga/awana-chan-wa-kyou-mo-shiawase/",
|
||||
"#class" : dankefuerslesen.DankefuerslesenMangaExtractor,
|
||||
"#pattern" : dankefuerslesen.DankefuerslesenChapterExtractor.pattern,
|
||||
"#count" : 4,
|
||||
|
||||
"chapter": range(1, 4),
|
||||
"chapter_minor": "",
|
||||
},
|
||||
|
||||
)
|
||||
Reference in New Issue
Block a user