[weebdex] add support (#8722)

This commit is contained in:
Mike Fährmann
2025-12-19 19:54:24 +01:00
parent e971b4c989
commit afe867361f
5 changed files with 276 additions and 0 deletions

View File

@@ -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>

View File

@@ -231,6 +231,7 @@ modules = [
"webmshare",
"webtoons",
"weebcentral",
"weebdex",
"weibo",
"wikiart",
"wikifeet",

View 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"]],
}

View File

@@ -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
View 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",
],
},
)