[weebdex] add support (#8722)
This commit is contained in:
@@ -1213,6 +1213,12 @@ Consider all listed sites to potentially be NSFW.
|
||||
<td>Chapters, Manga</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr id="weebdex" title="weebdex">
|
||||
<td>WeebDex</td>
|
||||
<td>https://weebdex.org/</td>
|
||||
<td>Chapters, Manga</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr id="weibo" title="weibo">
|
||||
<td>Weibo</td>
|
||||
<td>https://www.weibo.com/</td>
|
||||
|
||||
@@ -231,6 +231,7 @@ modules = [
|
||||
"webmshare",
|
||||
"webtoons",
|
||||
"weebcentral",
|
||||
"weebdex",
|
||||
"weibo",
|
||||
"wikiart",
|
||||
"wikifeet",
|
||||
|
||||
132
gallery_dl/extractor/weebdex.py
Normal file
132
gallery_dl/extractor/weebdex.py
Normal file
@@ -0,0 +1,132 @@
|
||||
# -*- 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://weebdex.org/"""
|
||||
|
||||
from .common import ChapterExtractor, MangaExtractor
|
||||
from .. import text
|
||||
from ..cache import memcache
|
||||
|
||||
BASE_PATTERN = r"(?:https?://)?weebdex\.org"
|
||||
|
||||
|
||||
class WeebdexBase():
|
||||
"""Base class for weebdex extractors"""
|
||||
category = "weebdex"
|
||||
root = "https://weebdex.org"
|
||||
root_api = "https://api.weebdex.org"
|
||||
request_interval = 0.2 # 5 requests per second
|
||||
|
||||
def _init(self):
|
||||
self.headers_api = {
|
||||
"Referer": self.root + "/",
|
||||
"Origin" : self.root,
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Site": "same-site",
|
||||
}
|
||||
|
||||
|
||||
class WeebdexChapterExtractor(WeebdexBase, ChapterExtractor):
|
||||
"""Extractor for weebdex manga chapters"""
|
||||
archive_fmt = "{chapter_id}_{version}_{page}"
|
||||
pattern = BASE_PATTERN + r"/chapter/(\w+)"
|
||||
example = "https://weebdex.org/chapter/ID/PAGE"
|
||||
|
||||
def metadata(self, _):
|
||||
cid = self.groups[0]
|
||||
url = f"{self.root_api}/chapter/{cid}"
|
||||
self.data = data = self.request_json(url, headers=self.headers_api)
|
||||
|
||||
rel = data.pop("relationships")
|
||||
chapter, sep, minor = data["chapter"].partition(".")
|
||||
|
||||
return {
|
||||
**_manga_info(self, rel["manga"]["id"]),
|
||||
"title" : data.get("title", ""),
|
||||
"version" : data["version"],
|
||||
"volume" : text.parse_int(data["volume"]),
|
||||
"chapter" : text.parse_int(chapter),
|
||||
"chapter_minor": sep + minor,
|
||||
"chapter_id" : cid,
|
||||
"date" : self.parse_datetime_iso(data["created_at"]),
|
||||
"date_updated" : self.parse_datetime_iso(data["updated_at"]),
|
||||
"lang" : data["language"],
|
||||
"uploader": rel["uploader"]["name"] if "uploader" in rel else "",
|
||||
"group" : [g["name"] for g in rel.get("groups") or ()],
|
||||
}
|
||||
|
||||
def images(self, _):
|
||||
data = self.data
|
||||
base = f"{data['node']}/data/{data['id']}/"
|
||||
|
||||
return [
|
||||
(base + page["name"], {
|
||||
"width" : page["dimensions"][0],
|
||||
"height": page["dimensions"][1],
|
||||
})
|
||||
for page in data["data"]
|
||||
]
|
||||
|
||||
|
||||
class WeebdexMangaExtractor(WeebdexBase, MangaExtractor):
|
||||
"""Extractor for weebdex manga"""
|
||||
chapterclass = WeebdexChapterExtractor
|
||||
pattern = BASE_PATTERN + r"/title/(\w+)"
|
||||
example = "https://weebdex.org/title/ID/SLUG"
|
||||
|
||||
def chapters(self, page):
|
||||
mid = self.groups[0]
|
||||
url = f"{self.root_api}/manga/{mid}/chapters"
|
||||
params = {
|
||||
"limit": 100,
|
||||
"order": "asc" if self.config("chapter-reverse") else "desc",
|
||||
}
|
||||
|
||||
base = self.root + "/chapter/"
|
||||
manga = _manga_info(self, mid)
|
||||
results = []
|
||||
|
||||
while True:
|
||||
data = self.request_json(
|
||||
url, params=params, headers=self.headers_api)
|
||||
|
||||
for ch in data["data"]:
|
||||
chapter, sep, minor = ch["chapter"].partition(".")
|
||||
ch["volume"] = text.parse_int(ch["volume"])
|
||||
ch["chapter"] = text.parse_int(chapter)
|
||||
ch["chapter_minor"] = sep + minor
|
||||
ch.update(manga)
|
||||
results.append((base + ch["id"], ch))
|
||||
|
||||
if data["total"] <= data["page"] * params["limit"]:
|
||||
break
|
||||
params["page"] = data["page"] + 1
|
||||
|
||||
return results
|
||||
|
||||
|
||||
@memcache(keyarg=1)
|
||||
def _manga_info(self, mid):
|
||||
url = f"{self.root_api}/manga/{mid}"
|
||||
manga = self.request_json(url, headers=self.headers_api)
|
||||
rel = manga["relationships"]
|
||||
|
||||
return {
|
||||
"manga" : manga["title"],
|
||||
"manga_id": manga["id"],
|
||||
"manga_date": self.parse_datetime_iso(manga["created_at"]),
|
||||
"year" : manga["year"],
|
||||
"status" : manga["status"],
|
||||
"origin" : manga["language"],
|
||||
"description": manga["description"],
|
||||
"demographic": manga["demographic"],
|
||||
"tags" : [f"{t['group']}:{t['name']}" for t in rel["tags"]],
|
||||
"author" : [a["name"] for a in rel["authors"]],
|
||||
"artist" : [a["name"] for a in rel["artists"]],
|
||||
}
|
||||
@@ -207,6 +207,7 @@ CATEGORY_MAP = {
|
||||
"webmshare" : "webmshare",
|
||||
"webtoons" : "WEBTOON",
|
||||
"weebcentral" : "Weeb Central",
|
||||
"weebdex" : "WeebDex",
|
||||
"wikiart" : "WikiArt.org",
|
||||
"wikigg" : "wiki.gg",
|
||||
"wikimediacommons": "Wikimedia Commons",
|
||||
|
||||
136
test/results/weebdex.py
Normal file
136
test/results/weebdex.py
Normal file
@@ -0,0 +1,136 @@
|
||||
# -*- 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 weebdex
|
||||
|
||||
|
||||
__tests__ = (
|
||||
{
|
||||
"#url" : "https://weebdex.org/chapter/f6c0awnrba",
|
||||
"#class" : weebdex.WeebdexChapterExtractor,
|
||||
"#pattern" : r"https://s\d+\.notdelta\.xyz/data/f6c0awnrba/\d+-\w{64}\.png",
|
||||
"#count" : 14,
|
||||
|
||||
"artist" : ["Nokomi (のこみ)"],
|
||||
"author" : ["Tanabata Satori"],
|
||||
"chapter" : 11,
|
||||
"chapter_id" : "f6c0awnrba",
|
||||
"chapter_minor": ".5",
|
||||
"count" : 14,
|
||||
"page" : range(1, 14),
|
||||
"date" : "dt:2025-10-13 10:47:26",
|
||||
"date_updated" : "type:datetime",
|
||||
"demographic" : "shoujo",
|
||||
"extension" : "png",
|
||||
"filename" : str,
|
||||
"group" : ["Knights of Earl Grey"],
|
||||
"width" : range(800, 2800),
|
||||
"height" : range(800, 2800),
|
||||
"lang" : "en",
|
||||
"manga" : "Akuyaku Reijou Level 99 ~Watashi wa UraBoss desu ga Maou de wa Arimasen~",
|
||||
"manga_date" : "dt:2025-10-09 07:32:07",
|
||||
"manga_id" : "raa6dfy3da",
|
||||
"origin" : "ja",
|
||||
"status" : "ongoing",
|
||||
"title" : "[Extra] A Day In The Life Of Patrick",
|
||||
"uploader" : "system",
|
||||
"version" : 1,
|
||||
"volume" : 2,
|
||||
"year" : 2020,
|
||||
"description" : """\
|
||||
I reincarnated as the "Villainess Eumiella" from an RPG Otome game. In the main story, Eumiella is merely a side character, but after the ending, she re-enters the story as the Hidden Boss, a character boasting high stats on par with the heroes! Lighting a fire in my gamer's soul, and taking advantage of being left on my own in my parent's territory, I trained, trained, and trained! As a result of my training... by the time I enrolled in the academy, I managed to reach level 99. Though I had planned to live out my days as inconspicuously and peacefully as possible, soon after entering the school, I'm suspected by the Heroine and Love Interests of being the "Demon Lord"...?
|
||||
___
|
||||
**Links:**
|
||||
- Alternative Official Raw - [Niconico](https://manga.nicovideo.jp/comic/46067)\
|
||||
""",
|
||||
"tags" : [
|
||||
"format:Adaptation",
|
||||
"genre:Action",
|
||||
"genre:Comedy",
|
||||
"genre:Fantasy",
|
||||
"genre:Isekai",
|
||||
"genre:Romance",
|
||||
"theme:Demons",
|
||||
"theme:Magic",
|
||||
"theme:Monsters",
|
||||
"theme:Reincarnation",
|
||||
"theme:School Life",
|
||||
"theme:Video Games",
|
||||
"theme:Villainess",
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
"#url" : "https://weebdex.org/chapter/itizot1rxc",
|
||||
"#class" : weebdex.WeebdexChapterExtractor,
|
||||
"#pattern" : r"https://s\d+\.notdelta\.xyz/data/itizot1rxc/\d+\-\w+\.jpg",
|
||||
"#count" : 17,
|
||||
|
||||
"artist" : ["Matsuda Minoru"],
|
||||
"author" : ["Matsuda Minoru"],
|
||||
"chapter" : 10,
|
||||
"chapter_id" : "itizot1rxc",
|
||||
"chapter_minor": "",
|
||||
"count" : 17,
|
||||
"demographic" : "seinen",
|
||||
"group" : ["BBB Translation (Big Beaming Bluewhale)"],
|
||||
"lang" : "vi",
|
||||
"manga" : "Ani Datta Mono",
|
||||
"manga_date" : "dt:2025-10-09 19:02:04",
|
||||
"manga_id" : "3o0icxno26",
|
||||
"origin" : "ja",
|
||||
"title" : "Cuộc hẹn tại phía Đông vườn địa đàng",
|
||||
"uploader" : "sMrBjZf",
|
||||
"version" : 1,
|
||||
"volume" : 2,
|
||||
"year" : 2021,
|
||||
},
|
||||
|
||||
{
|
||||
"#url" : "https://weebdex.org/title/3o0icxno26/ani-datta-mono",
|
||||
"#class" : weebdex.WeebdexMangaExtractor,
|
||||
"#pattern" : weebdex.WeebdexChapterExtractor.pattern,
|
||||
"#count" : range(120, 300),
|
||||
|
||||
"artist" : ["Matsuda Minoru"],
|
||||
"author" : ["Matsuda Minoru"],
|
||||
"volume" : int,
|
||||
"chapter" : int,
|
||||
"chapter_minor": {"", ".5"},
|
||||
"created_at" : "iso:dt",
|
||||
"published_at" : "iso:dt",
|
||||
"updated_at" : "iso:dt",
|
||||
"demographic" : "seinen",
|
||||
"id" : str,
|
||||
"language" : {"en", "vi"},
|
||||
"manga" : "Ani Datta Mono",
|
||||
"manga_date" : "dt:2025-10-09 19:02:04",
|
||||
"manga_id" : "3o0icxno26",
|
||||
"origin" : "ja",
|
||||
"status" : "ongoing",
|
||||
"version" : {1, 2},
|
||||
"year" : 2021,
|
||||
"description" : """\
|
||||
My brother died. When I went to visit my brother's grave with my brother's lover——……
|
||||
|
||||
This is the story of my brother's lover, me, and “the thing that was my brother”.
|
||||
___
|
||||
**Additional Links:**
|
||||
- [Official TikTok](http://tiktok.com/@anidattamono)
|
||||
- [Official X](https://x.com/anidattamono)\
|
||||
""",
|
||||
"tags" : [
|
||||
"genre:Drama",
|
||||
"genre:Horror",
|
||||
"genre:Psychological",
|
||||
"genre:Romance",
|
||||
"genre:Thriller",
|
||||
"theme:Ghosts",
|
||||
"theme:Supernatural",
|
||||
],
|
||||
},
|
||||
|
||||
)
|
||||
Reference in New Issue
Block a user