diff --git a/dart/manga/manga_source_list.dart b/dart/manga/manga_source_list.dart index 5265b6eb..59f16583 100644 --- a/dart/manga/manga_source_list.dart +++ b/dart/manga/manga_source_list.dart @@ -4,7 +4,6 @@ import 'multisrc/mangabox/sources.dart'; import 'multisrc/mangareader/sources.dart'; import 'multisrc/mmrcms/sources.dart'; import 'multisrc/nepnep/sources.dart'; -import 'src/en/mangabuddy/source.dart'; import 'src/en/mangahere/source.dart'; List dartMangasourceList = [ @@ -14,5 +13,4 @@ List dartMangasourceList = [ mangahereSource, ...nepnepSourcesList, ...mangaboxSourcesList, - mangabuddySource, ]; diff --git a/dart/manga/src/en/mangabuddy/icon.png b/dart/manga/src/en/mangabuddy/icon.png deleted file mode 100644 index 9f7260b2..00000000 Binary files a/dart/manga/src/en/mangabuddy/icon.png and /dev/null differ diff --git a/dart/manga/src/en/mangabuddy/mangabuddy.dart b/dart/manga/src/en/mangabuddy/mangabuddy.dart deleted file mode 100644 index 64be85fe..00000000 --- a/dart/manga/src/en/mangabuddy/mangabuddy.dart +++ /dev/null @@ -1,360 +0,0 @@ -import 'package:mangayomi/bridge_lib.dart'; -import 'dart:convert'; - -class MangaBuddy extends MProvider { - MangaBuddy({required this.source}); - - MSource source; - - final Client client = Client(); - - @override - bool get supportsLatest => true; - - @override - Map get headers => {}; - - MPages mangaFromElements(List elements, bool hasNextPage) { - List mangaList = []; - - for (var i = 0; i < elements.length; i++) { - final title = elements[i].selectFirst("div.meta > div.title > h3 > a"); - final imageElement = elements[i].selectFirst("div.thumb > a > img"); - final image = - imageElement?.attr("data-src") ?? imageElement?.getSrc ?? ""; - - MManga manga = MManga(); - manga.name = title.text ?? title.attr("title"); - manga.imageUrl = image; - manga.link = title.attr("href").contains(source.baseUrl) - ? title.attr("href") - : "${source.baseUrl}${title.attr("href")}"; - mangaList.add(manga); - } - - return MPages(mangaList, hasNextPage); - } - - @override - Future getPopular(int page) async { - final res = await client.get( - Uri.parse("${source.baseUrl}/popular?page=$page"), - ); - final doc = parseHtml(res.body); - - final nextElement = doc.selectFirst("a.page-link[title='Next']"); - bool hasNext = nextElement.text != null; - - return mangaFromElements( - doc.select( - "div.list.manga-list > div.book-item > div.book-detailed-item", - ), - true, - ); - } - - @override - Future getLatestUpdates(int page) async { - final res = await client.get( - Uri.parse("${source.baseUrl}/latest?page=$page"), - ); - final doc = parseHtml(res.body); - - final nextElement = doc.selectFirst("a.page-link[title='Next']"); - bool hasNext = nextElement.text != null; - - return mangaFromElements( - doc.select( - "div.list.manga-list > div.book-item > div.book-detailed-item", - ), - true, - ); - } - - @override - Future search( - String initialQuery, - int page, - FilterList filterList, - ) async { - final filters = filterList.filters; - String filterString = ""; - String query = initialQuery; - for (var filter in filters) { - if (filter.type == "SearchFilter") { - query = filter.state.toString(); - } else if (filter.type == "GenresFilter") { - for (var genre in filter.state) { - if (genre.state == true) { - filterString += ("&genre[]=${genre.value.toString()}"); - } - } - } else if (filter.type == "StatusFilter") { - filterString += - ("&status=${filter.values[filter.state].value.toString()}"); - } else if (filter.type == "OrderFilter") { - filterString += - ("&sort=${filter.values[filter.state].value.toString()}"); - } - } - - final res = await client.get( - Uri.parse("${source.baseUrl}/search?$filterString&q=$query&page=$page"), - ); - final doc = parseHtml(res.body); - - return mangaFromElements( - doc.select( - "div.list.manga-list > div.book-item > div.book-detailed-item", - ), - true, - ); - } - - @override - Future getDetail(String url) async { - final statusList = [ - {"Ongoing": 0, "Completed": 1}, - ]; - final res = await client.get(Uri.parse(url)); - final doc = parseHtml(res.body); - - MManga manga = MManga(); - - final chapterIdElement = doc.selectFirst("div.layout > script"); - final idRegex = RegExp(r"var\s+bookId\s*=\s*(\d+);"); - - final imageElement = doc.selectFirst("div.book-info div.img-cover > img"); - final statusElement = doc.selectFirst( - "div.book-info div.detail > div.meta.box.mt-1.p-10 > p > a[href^='/status/'] > span", - ); - final authorElements = doc.select( - "div.book-info div.detail > div.meta.box.mt-1.p-10 > p > a[href^='/authors/'] > span", - ); - final genreList = doc.select( - "div.book-info div.detail > div.meta.box.mt-1.p-10 > p > a[href^='/genres/']", - ); - final descriptionElement = doc.selectFirst( - "div.section-body.summary > p.content", - ); - - final chapterIdMatch = idRegex.firstMatch(chapterIdElement?.text); - final chapterId = chapterIdMatch != null - ? chapterIdMatch.group(1) ?? "" - : ""; - - final image = imageElement?.attr("data-src") ?? imageElement?.getSrc ?? ""; - final status = statusElement.text ?? "Ongoing"; - final author = authorElements.isNotEmpty - ? authorElements.map((e) => e.text).join(" | ") - : "unknown"; - final genres = genreList - .map((e) => (e.text as String).replaceAll(",", "").trim()) - .toList(); - - final description = descriptionElement?.text ?? ""; - - manga.author = author; - manga.description = description; - manga.imageUrl = image; - manga.genre = genres; - - manga.chapters = await getChapters(chapterId); - manga.status = parseStatus(status, statusList); - return manga; - } - - @override - Future> getChapters(String chapterId) async { - List chapters = []; - - final res = await client.get( - Uri.parse( - "${source.baseUrl}/api/manga/$chapterId/chapters?source=detail", - ), - ); - MDocument doc = parseHtml(res.body); - - MElement chapterList = doc.selectFirst("ul.chapter-list"); - - for (MElement chapterElement in chapterList.select("li")) { - var chapter = MChapter(); - - final name = chapterElement.selectFirst("strong.chapter-title")?.text; - final url = chapterElement.selectFirst("a")?.attr("href"); - final uploadDate = chapterElement - .selectFirst("time.chapter-update") - ?.text; - - chapter.name = name; - chapter.url = url; - chapter.dateUpload = parseDateToUnix(uploadDate).toString(); - - chapters.add(chapter); - } - - return chapters; - } - - int parseDateToUnix(String dateStr) { - const monthMap = { - 'Jan': 1, - 'Feb': 2, - 'Mar': 3, - 'Apr': 4, - 'May': 5, - 'Jun': 6, - 'Jul': 7, - 'Aug': 8, - 'Sep': 9, - 'Oct': 10, - 'Nov': 11, - 'Dec': 12, - }; - - final parts = dateStr.split(' '); - if (parts.length != 3) return DateTime.now().millisecondsSinceEpoch; - - final monthStr = parts[0]; - final dayStr = parts[1].replaceAll(',', ''); - final yearStr = parts[2]; - - final month = monthMap[monthStr] ?? 1; - final day = int.tryParse(dayStr) ?? 1; - final year = int.tryParse(yearStr) ?? DateTime.now().year; - - final dt = DateTime(year, month, day); - return dt.millisecondsSinceEpoch; - } - - @override - Future>> getPageList(String url) async { - List> images = []; - - final res = await client.get(Uri.parse("${source.baseUrl}$url")); - final doc = parseHtml(res.body); - - final imageScript = doc.select( - "div#viewer-page.main-container.viewer > script", - ); - - final rawImageText = imageScript[imageScript.length - 1]?.text ?? ""; - - final imageList = rawImageText - .replaceAll("var chapImages =", "") - .replaceAll("'", "") - .trim() - .split(","); - - for (final image in imageList) { - images.add({ - "url": image.trim(), - "headers": {"Referer": source.baseUrl}, - }); - } - - return images; - } - - @override - List getFilterList() { - return [ - TextFilter("SearchFilter", "Search..."), - GroupFilter("GenresFilter", "Genres A-M", [ - CheckBoxFilter("Action", "action"), - CheckBoxFilter("Adaptation", "adaptation"), - CheckBoxFilter("Adult", "adult"), - CheckBoxFilter("Adventure", "adventure"), - CheckBoxFilter("Animal", "animal"), - CheckBoxFilter("Anthology", "anthology"), - CheckBoxFilter("Cartoon", "cartoon"), - CheckBoxFilter("Comedy", "comedy"), - CheckBoxFilter("Comic", "comic"), - CheckBoxFilter("Cooking", "cooking"), - CheckBoxFilter("Demons", "demons"), - CheckBoxFilter("Doujinshi", "doujinshi"), - CheckBoxFilter("Drama", "drama"), - CheckBoxFilter("Ecchi", "ecchi"), - CheckBoxFilter("Fantasy", "fantasy"), - CheckBoxFilter("Full Color", "full-color"), - CheckBoxFilter("Game", "game"), - CheckBoxFilter("Gender bender", "gender-bender"), - CheckBoxFilter("Ghosts", "ghosts"), - CheckBoxFilter("Harem", "harem"), - CheckBoxFilter("Historical", "historical"), - CheckBoxFilter("Horror", "horror"), - CheckBoxFilter("Isekai", "isekai"), - CheckBoxFilter("Josei", "josei"), - CheckBoxFilter("Long strip", "long-strip"), - CheckBoxFilter("Mafia", "mafia"), - CheckBoxFilter("Magic", "magic"), - CheckBoxFilter("Manga", "manga"), - CheckBoxFilter("Manhua", "manhua"), - CheckBoxFilter("Manhwa", "manhwa"), - CheckBoxFilter("Martial arts", "martial-arts"), - CheckBoxFilter("Mature", "mature"), - CheckBoxFilter("Mecha", "mecha"), - CheckBoxFilter("Medical", "medical"), - CheckBoxFilter("Military", "military"), - CheckBoxFilter("Monster", "monster"), - CheckBoxFilter("Monster girls", "monster-girls"), - CheckBoxFilter("Monsters", "monsters"), - CheckBoxFilter("Music", "music"), - CheckBoxFilter("Mystery", "mystery"), - ]), - GroupFilter("GenresFilter", "Genres N-Z", [ - CheckBoxFilter("Office", "office"), - CheckBoxFilter("Office workers", "office-workers"), - CheckBoxFilter("One shot", "one-shot"), - CheckBoxFilter("Police", "police"), - CheckBoxFilter("Psychological", "psychological"), - CheckBoxFilter("Reincarnation", "reincarnation"), - CheckBoxFilter("Romance", "romance"), - CheckBoxFilter("School life", "school-life"), - CheckBoxFilter("Sci fi", "sci-fi"), - CheckBoxFilter("Science fiction", "science-fiction"), - CheckBoxFilter("Seinen", "seinen"), - CheckBoxFilter("Shoujo", "shoujo"), - CheckBoxFilter("Shoujo ai", "shoujo-ai"), - CheckBoxFilter("Shounen", "shounen"), - CheckBoxFilter("Shounen ai", "shounen-ai"), - CheckBoxFilter("Slice of life", "slice-of-life"), - CheckBoxFilter("Smut", "smut"), - CheckBoxFilter("Soft Yaoi", "soft-yaoi"), - CheckBoxFilter("Sports", "sports"), - CheckBoxFilter("Super Power", "super-power"), - CheckBoxFilter("Superhero", "superhero"), - CheckBoxFilter("Supernatural", "supernatural"), - CheckBoxFilter("Thriller", "thriller"), - CheckBoxFilter("Time travel", "time-travel"), - CheckBoxFilter("Tragedy", "tragedy"), - CheckBoxFilter("Vampire", "vampire"), - CheckBoxFilter("Vampires", "vampires"), - CheckBoxFilter("Video games", "video-games"), - CheckBoxFilter("Villainess", "villainess"), - CheckBoxFilter("Web comic", "web-comic"), - CheckBoxFilter("Webtoons", "webtoons"), - CheckBoxFilter("Yaoi", "yaoi"), - CheckBoxFilter("Yuri", "yuri"), - CheckBoxFilter("Zombies", "zombies"), - ]), - SeparatorFilter(), - SelectFilter("StatusFilter", "Status", 0, [ - SelectFilterOption("All (Default)", "all"), - SelectFilterOption("Ongoing", "ongoing"), - SelectFilterOption("Completed", "completed"), - ]), - SelectFilter("OrderFilter", "Order By", 0, [ - SelectFilterOption("Views (Default)", "views"), - SelectFilterOption("Latest Updated", "updated_at"), - SelectFilterOption("Creation Date", "created_at"), - SelectFilterOption("Name A-Z", "name"), - SelectFilterOption("Rating", "rating"), - ]), - ]; - } -} - -MangaBuddy main(MSource source) { - return MangaBuddy(source: source); -} diff --git a/dart/manga/src/en/mangabuddy/source.dart b/dart/manga/src/en/mangabuddy/source.dart deleted file mode 100644 index 064de9d0..00000000 --- a/dart/manga/src/en/mangabuddy/source.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../../../../../model/source.dart'; - -Source get mangabuddySource => _mangabuddySource; -const _mangabuddyVersion = "0.0.1"; -const _mangabuddySourceCodeUrl = - "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/src/en/mangabuddy/mangabuddy.dart"; -Source _mangabuddySource = Source( - name: "MangaBuddy", - baseUrl: "http://www.mangabuddy.com", - lang: "en", - typeSource: "single", - isNsfw: true, - iconUrl: "https://github.com/KptnFishy/mangayomi-extensions/blob/patch-1/dart/manga/src/en/mangabuddy/icon.png", - sourceCodeUrl: _mangabuddySourceCodeUrl, - itemType: ItemType.manga, - version: _mangabuddyVersion, - dateFormat: "MMM dd,yyyy", - dateFormatLocale: "en", -);