diff --git a/docs/supportedsites.md b/docs/supportedsites.md
index e810f42215..1e29c868e2 100644
--- a/docs/supportedsites.md
+++ b/docs/supportedsites.md
@@ -535,12 +535,6 @@ Consider all listed sites to potentially be NSFW.
Chapters, Manga |
|
-
- MangaRead |
- https://mangaread.org/ |
- Chapters, Manga |
- |
-
MangaSee |
https://mangasee123.com/ |
@@ -1723,5 +1717,27 @@ Consider all listed sites to potentially be NSFW.
Albums |
|
+
+
+ WordPressMadara based websites |
+
+
+ MangaRead |
+ https://mangaread.org/ |
+ Chapters, Manga |
+ |
+
+
+ Toonily |
+ https://toonily.com/ |
+ Chapters, Manga |
+ |
+
+
+ WebtoonXYZ |
+ https://www.webtoon.xyz/ |
+ Chapters, Manga |
+ |
+
diff --git a/gallery_dl/extractor/__init__.py b/gallery_dl/extractor/__init__.py
index d624736211..72aee020ee 100644
--- a/gallery_dl/extractor/__init__.py
+++ b/gallery_dl/extractor/__init__.py
@@ -95,7 +95,7 @@
"mangakakalot",
"manganelo",
"mangapark",
- "mangaread",
+ "wpmadara",
"mangasee",
"mangoxo",
"misskey",
diff --git a/gallery_dl/extractor/mangaread.py b/gallery_dl/extractor/wpmadara.py
similarity index 58%
rename from gallery_dl/extractor/mangaread.py
rename to gallery_dl/extractor/wpmadara.py
index 4b017dca00..79b145c2b1 100644
--- a/gallery_dl/extractor/mangaread.py
+++ b/gallery_dl/extractor/wpmadara.py
@@ -4,16 +4,16 @@
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
-"""Extractors for https://mangaread.org/"""
+"""Extractors for WordPressMadara based websites."""
-from .common import ChapterExtractor, MangaExtractor
+from .common import BaseExtractor, ChapterExtractor, MangaExtractor
from .. import text, exception
import re
-class MangareadBase():
- """Base class for Mangaread extractors"""
- category = "mangaread"
+class WPMadaraBase(BaseExtractor):
+ """Base class for WordPressMadara based extractors"""
+ basecategory = "wpmadara"
root = "https://www.mangaread.org"
@staticmethod
@@ -31,12 +31,37 @@ def parse_chapter_string(chapter_string, data):
data["language"] = "English"
-class MangareadChapterExtractor(MangareadBase, ChapterExtractor):
- """Extractor for manga-chapters from mangaread.org"""
- pattern = (r"(?:https?://)?(?:www\.)?mangaread\.org"
- r"(/manga/[^/?#]+/[^/?#]+)")
+BASE_PATTERN = WPMadaraBase.update({
+ "mangaread": {
+ "root": "https://www.mangaread.org",
+ "pattern": r"(?:https?://)?(?:www\.)?mangaread\.org",
+ },
+ "toonily": {
+ "root": "https://www.toonily.com",
+ "pattern": r"(?:https?://)?(?:www\.)?toonily\.com",
+ },
+ "webtoonxyz": {
+ "root": "https://www.webtoon.xyz",
+ "pattern": r"(?:https?://)?(?:www\.)?webtoon\.xyz",
+ },
+})
+
+
+class WPMadaraChapterExtractor(WPMadaraBase, ChapterExtractor):
+ """Extractor for manga-chapters from WordPressMadara based websites."""
+ subcategory = "chapter"
+ pattern = BASE_PATTERN + r"(/(manga|webtoon|read)/[^/?#]+/[^/?#]+)"
example = "https://www.mangaread.org/manga/MANGA/chapter-01/"
+ def __init__(self, match, url=None):
+ WPMadaraBase.__init__(self, match)
+ self.chapter = match.group(match.lastindex)
+ self.log.debug("chapter: %s", self.chapter)
+ self.gallery_url = self.root + match.group(match.lastindex)
+
+ if self.config("chapter-reverse", False):
+ self.reverse = not self.reverse
+
def metadata(self, page):
tags = text.extr(page, 'class="wp-manga-tags-list">', '')
data = {"tags": list(text.split_html(tags)[::2])}
@@ -44,23 +69,31 @@ def metadata(self, page):
if not info:
raise exception.NotFoundError("chapter")
self.parse_chapter_string(info, data)
+ self.log.debug("data: %s", data)
return data
def images(self, page):
page = text.extr(
page, '', '", page.index("summary__content"))[0])),
- "rating" : text.parse_float(
- extr('total_votes">', "").strip()),
+ "rating" : rating,
"manga_alt" : text.remove_html(
extr("Alternative \n
", "")).split("; "),
"author" : list(text.extract_iter(
diff --git a/test/results/mangaread.py b/test/results/mangaread.py
index 4330a13d36..de2ae68752 100644
--- a/test/results/mangaread.py
+++ b/test/results/mangaread.py
@@ -4,15 +4,15 @@
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
-from gallery_dl.extractor import mangaread
+from gallery_dl.extractor import wpmadara
from gallery_dl import exception
__tests__ = (
{
"#url" : "https://www.mangaread.org/manga/one-piece/chapter-1053-3/",
- "#category": ("", "mangaread", "chapter"),
- "#class" : mangaread.MangareadChapterExtractor,
+ "#category": ("wpmadara", "mangaread", "chapter"),
+ "#class" : wpmadara.WPMadaraChapterExtractor,
"#pattern" : r"https://www\.mangaread\.org/wp-content/uploads/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+",
"#count" : 11,
@@ -27,15 +27,15 @@
{
"#url" : "https://www.mangaread.org/manga/one-piece/chapter-1000000/",
- "#category": ("", "mangaread", "chapter"),
- "#class" : mangaread.MangareadChapterExtractor,
+ "#category": ("wpmadara", "mangaread", "chapter"),
+ "#class" : wpmadara.WPMadaraChapterExtractor,
"#exception": exception.NotFoundError,
},
{
"#url" : "https://www.mangaread.org/manga/kanan-sama-wa-akumade-choroi/chapter-10/",
- "#category": ("", "mangaread", "chapter"),
- "#class" : mangaread.MangareadChapterExtractor,
+ "#category": ("wpmadara", "mangaread", "chapter"),
+ "#class" : wpmadara.WPMadaraChapterExtractor,
"#pattern" : r"https://www\.mangaread\.org/wp-content/uploads/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+",
"#count" : 9,
@@ -51,8 +51,8 @@
{
"#url" : "https://www.mangaread.org/manga/above-all-gods/chapter146-5/",
"#comment" : "^^ no whitespace",
- "#category": ("", "mangaread", "chapter"),
- "#class" : mangaread.MangareadChapterExtractor,
+ "#category": ("wpmadara", "mangaread", "chapter"),
+ "#class" : wpmadara.WPMadaraChapterExtractor,
"#pattern" : r"https://www\.mangaread\.org/wp-content/uploads/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+",
"#count" : 6,
@@ -67,8 +67,8 @@
{
"#url" : "https://www.mangaread.org/manga/kanan-sama-wa-akumade-choroi",
- "#category": ("", "mangaread", "manga"),
- "#class" : mangaread.MangareadMangaExtractor,
+ "#category": ("wpmadara", "mangaread", "manga"),
+ "#class" : wpmadara.WPMadaraMangaExtractor,
"#pattern" : r"https://www\.mangaread\.org/manga/kanan-sama-wa-akumade-choroi/chapter-\d+([_-].+)?/",
"#count" : ">= 13",
@@ -93,8 +93,8 @@
{
"#url" : "https://www.mangaread.org/manga/one-piece",
- "#category": ("", "mangaread", "manga"),
- "#class" : mangaread.MangareadMangaExtractor,
+ "#category": ("wpmadara", "mangaread", "manga"),
+ "#class" : wpmadara.WPMadaraMangaExtractor,
"#pattern" : r"https://www\.mangaread\.org/manga/one-piece/chapter-\d+(-.+)?/",
"#count" : ">= 1066",
@@ -114,8 +114,8 @@
{
"#url" : "https://www.mangaread.org/manga/doesnotexist",
- "#category": ("", "mangaread", "manga"),
- "#class" : mangaread.MangareadMangaExtractor,
+ "#category": ("wpmadara", "mangaread", "manga"),
+ "#class" : wpmadara.WPMadaraMangaExtractor,
"#exception": exception.HttpError,
},
diff --git a/test/results/toonily.py b/test/results/toonily.py
new file mode 100644
index 0000000000..b2f29b98b6
--- /dev/null
+++ b/test/results/toonily.py
@@ -0,0 +1,64 @@
+# -*- 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 wpmadara
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://toonily.com/webtoon/such-a-cute-spy/chapter-36/",
+ "#category": ("wpmadara", "toonily", "chapter"),
+ "#class" : wpmadara.WPMadaraChapterExtractor,
+ "#pattern" : r"https://toonily\.com/wp-content/uploads/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+",
+ "#count" : 11,
+
+ "manga" : "Jinxed",
+ "title" : "",
+ "chapter" : 36,
+ "tags" : ["harem"],
+ "lang" : "en",
+ "language" : "English",
+},
+
+{
+ "#url" : "https://toonily.com/webtoon/such-a-cute-spy/chapter-1000000/",
+ "#category": ("wpmadara", "toonily", "chapter"),
+ "#class" : wpmadara.WPMadaraChapterExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://toonily.com/webtoon/such-a-cute-spy",
+ "#category": ("wpmadara", "toonily", "manga"),
+ "#class" : wpmadara.WPMadaraMangaExtractor,
+ "#pattern" : r"https://toonily\.com/webtoon/such-a-cute-spy/chapter-\d+([_-].+)?/",
+ "#count" : ">= 13",
+
+ "manga" : "Such a Cute Spy",
+ "author" : ["Life of Ruin"],
+ "artist" : ["Ganghyeon Yeo"],
+ "genres" : [
+ "Action",
+ "Comedy",
+ "Romance",
+ "School Life",
+ ],
+ "rating" : float,
+ "status" : "End",
+ "lang" : "en",
+ "language" : "English",
+ "manga_alt" : list,
+},
+
+{
+ "#url" : "https://toonily.com/webtoon/doesnotexist",
+ "#category": ("wpmadara", "toonily", "manga"),
+ "#class" : wpmadara.WPMadaraMangaExtractor,
+ "#exception": exception.HttpError,
+},
+
+)
diff --git a/test/results/webtoonxyz.py b/test/results/webtoonxyz.py
new file mode 100644
index 0000000000..18aa89faf9
--- /dev/null
+++ b/test/results/webtoonxyz.py
@@ -0,0 +1,62 @@
+# -*- 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 wpmadara
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.webtoon.xyz/read/the-world-after-the-end/chapter-105/",
+ "#category": ("wpmadara", "webtoonxyz", "chapter"),
+ "#class" : wpmadara.WPMadaraChapterExtractor,
+ "#pattern" : r"https://www\.webtoon\.xyz/wp-content/uploads/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+",
+ "#count" : 11,
+
+ "manga" : "The World After The End",
+ "title" : "",
+ "chapter" : 105,
+ "lang" : "en",
+ "language" : "English",
+},
+
+{
+ "#url" : "https://www.webtoon.xyz/read/the-world-after-the-end/chapter-1000000/",
+ "#category": ("wpmadara", "webtoonxyz", "chapter"),
+ "#class" : wpmadara.WPMadaraChapterExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.webtoon.xyz/read/the-world-after-the-end/",
+ "#category": ("wpmadara", "webtoonxyz", "manga"),
+ "#class" : wpmadara.WPMadaraMangaExtractor,
+ "#pattern" : r"https://www\.webtoon\.xyz/read/such-a-cute-spy/chapter-\d+([_-].+)?/",
+ "#count" : ">= 13",
+
+ "manga" : "The World After The End",
+ "author" : ["S-Cynaan", "Sing Shong"],
+ "artist" : ["Undead Potato"],
+ "genres" : [
+ "Action",
+ "Adventure",
+ "Fantasy",
+ ],
+ "rating" : float,
+ "status" : "OnGoing",
+ "lang" : "en",
+ "language" : "English",
+ "manga_alt" : list,
+},
+
+{
+ "#url" : "https://www.webtoon.xyz/read/doesnotexist",
+ "#category": ("wpmadara", "webtoonxyz", "manga"),
+ "#class" : wpmadara.WPMadaraMangaExtractor,
+ "#exception": exception.HttpError,
+},
+
+)