From 4ccc6aae9652e82ef04be78c4b5f39a77ca88704 Mon Sep 17 00:00:00 2001 From: kodjomoustapha Date: Wed, 18 Oct 2023 13:21:55 +0100 Subject: [PATCH] New source (Multi: NepNep) --- icons/mangayomi-en-mangalife.png | Bin 0 -> 2762 bytes icons/mangayomi-en-mangasee.png | Bin 0 -> 3022 bytes index.json | 2 +- manga/multisrc/nepnep/nepnep-v0.0.1.dart | 215 +++++++++++++++++++++++ manga/multisrc/nepnep/sources.dart | 34 ++++ manga/sources_generator.dart | 4 +- 6 files changed, 253 insertions(+), 2 deletions(-) create mode 100644 icons/mangayomi-en-mangalife.png create mode 100644 icons/mangayomi-en-mangasee.png create mode 100644 manga/multisrc/nepnep/nepnep-v0.0.1.dart create mode 100644 manga/multisrc/nepnep/sources.dart diff --git a/icons/mangayomi-en-mangalife.png b/icons/mangayomi-en-mangalife.png new file mode 100644 index 0000000000000000000000000000000000000000..12a1276e50a5e755d38b465d040d2d992ea4e37b GIT binary patch literal 2762 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 Qk literal 0 HcmV?d00001 diff --git a/icons/mangayomi-en-mangasee.png b/icons/mangayomi-en-mangasee.png new file mode 100644 index 0000000000000000000000000000000000000000..55ca7d908b70a7d6c3bb36195bc11b04fa0b6732 GIT binary patch literal 3022 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 50) { + manga.hasNextPage = true; + } + return parseDirectory(json.encode(queryRes), manga); +} + +getMangaDetail(MangaModel manga) async { + final statusList = [ + {"Ongoing": 0, "Completed": 1, "Cancelled": 3, "Hiatus": 2} + ]; + final headers = getHeader(manga.baseUrl); + final url = '${manga.baseUrl}/manga/${manga.link}'; + final data = {"url": url, "headers": headers}; + final res = await MBridge.http('GET', json.encode(data)); + if (res.isEmpty) { + return manga; + } + manga.author = MBridge.xpath(res, + '//li[contains(@class,"list-group-item") and contains(text(),"Author")]/a/text()') + .first; + manga.description = MBridge.xpath(res, + '//li[contains(@class,"list-group-item") and contains(text(),"Description:")]/div/text()') + .first; + final status = MBridge.xpath(res, + '//li[contains(@class,"list-group-item") and contains(text(),"Status")]/a/text()') + .first; + manga.status = MBridge.parseStatus(toStatus(status), statusList); + manga.genre = MBridge.xpath(res, + '//li[contains(@class,"list-group-item") and contains(text(),"Genre(s)")]/a/text()'); + + final script = + MBridge.xpath(res, '//script[contains(text(), "MainFunction")]/text()') + .first; + final vmChapters = MBridge.substringBefore( + MBridge.substringAfter(script, "vm.Chapters = "), ";"); + final chapters = json.decode(vmChapters) as List; + manga.names = chapters.map((ch) { + String name = ch['ChapterName'] ?? ""; + String indexChapter = ch['Chapter']; + if (name.isEmpty) { + name = '${ch['Type']} ${chapterImage(indexChapter, true)}'; + } + return name; + }).toList(); + + manga.urls = chapters + .map((ch) => + '/read-online/${MBridge.substringAfter(manga.link, "/manga/")}${chapterURLEncode(ch['Chapter'])}') + .toList(); + final chapterDates = chapters.map((ch) => ch['Date']).toList(); + manga.chaptersDateUploads = MBridge.listParseDateTime( + chapterDates, manga.dateFormat, manga.dateFormatLocale); + return manga; +} + +getChapterUrl(MangaModel manga) async { + final headers = getHeader(manga.baseUrl); + final url = '${manga.baseUrl}${manga.link}'; + List pages = []; + final data = {"url": url, "headers": headers}; + final res = await MBridge.http('GET', json.encode(data)); + final script = + MBridge.xpath(res, '//script[contains(text(), "MainFunction")]/text()') + .first; + final chapScript = json.decode(MBridge.substringBefore( + MBridge.substringAfter(script, "vm.CurChapter = "), ";")); + final pathName = MBridge.substringBefore( + MBridge.substringAfter(script, "vm.CurPathName = \"", ""), "\""); + var directory = chapScript['Directory'] ?? ''; + if (directory.length > 0) { + directory += '/'; + } + final mangaName = MBridge.substringBefore( + MBridge.substringAfter(manga.link, "/read-online/"), "-chapter"); + var chNum = chapterImage(chapScript['Chapter'], false); + var totalPages = MBridge.intParse(chapScript['Page']); + for (int page = 1; page <= totalPages; page++) { + String paddedPageNumber = "$page".padLeft(3, '0'); + String pageUrl = + 'https://$pathName/manga/$mangaName/$directory$chNum-$paddedPageNumber.png'; + + pages.add(pageUrl); + } + return pages; +} + +String chapterImage(String e, bool cleanString) { + var a = e.substring(1, e.length - 1); + if (cleanString) { + a = MBridge.regExp(a, r'^0+', "", 0, 0); + } + + var b = MBridge.intParse(e.substring(e.length - 1)); + + if (b == 0 && a.isNotEmpty) { + return a; + } else if (b == 0 && a.isEmpty) { + return '0'; + } else { + return '$a.$b'; + } +} + +String toStatus(String status) { + if (status.contains("Ongoing")) { + return "Ongoing"; + } else if (status.contains("Complete")) { + return "Complete"; + } else if (status.contains("Cancelled")) { + return "Cancelled"; + } else if (status.contains("Hiatus")) { + return "Hiatus"; + } + return ""; +} + +String directoryFromDocument(String res) { + final script = + MBridge.xpath(res, '//script[contains(text(), "MainFunction")]/text()') + .first; + return MBridge.substringBefore( + MBridge.substringAfter(script, "vm.Directory = "), "vm.GetIntValue") + .replaceAll(";", " "); +} + +MangaModel parseDirectory(String resSort, MangaModel manga) { + final datas = json.decode(resSort) as List; + manga.names = datas.map((e) => e["s"]).toList(); + manga.images = datas + .map((e) => 'https://temp.compsci88.com/cover/${e['i']}.jpg') + .toList(); + manga.urls = datas.map((e) => e["i"]).toList(); + return manga; +} + +Map getHeader(String url) { + final headers = { + 'Referer': '$url/', + "User-Agent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/77.0" + }; + return headers; +} + +String chapterURLEncode(String e) { + var index = ''.toString(); + var t = MBridge.intParse(e.substring(0, 1)); + + if (t != 1) { + index = '-index-$t'; + } + + var dgt = 0; + var inta = MBridge.intParse(e); + if (inta < 100100) { + dgt = 4; + } else if (inta < 101000) { + dgt = 3; + } else if (inta < 110000) { + dgt = 2; + } else { + dgt = 1; + } + + final n = e.substring(dgt, e.length - 1); + var suffix = ''.toString(); + final path = MBridge.intParse(e.substring(e.length - 1)); + + if (path != 0) { + suffix = '.$path'; + } + + return '-chapter-$n$suffix$index.html'; +} diff --git a/manga/multisrc/nepnep/sources.dart b/manga/multisrc/nepnep/sources.dart new file mode 100644 index 00000000..9f5f7e1a --- /dev/null +++ b/manga/multisrc/nepnep/sources.dart @@ -0,0 +1,34 @@ +import '../../../model/source.dart'; +import '../../../utils/utils.dart'; + +const nepnepVersion = "0.0.1"; +const nepnepSourceCodeUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/manga/multisrc/nepnep/nepnep-v$nepnepVersion.dart"; +const defaultDateFormat = "yyyy-MM-dd HH:mm:ss"; +const defaultDateFormatLocale = "en"; + +List get nepnepSourcesList => _nepnepSourcesList; +List _nepnepSourcesList = [ + Source( + name: "MangaSee", + baseUrl: "https://mangasee123.com", + lang: "en", + typeSource: "nepnep", + iconUrl: getIconUrl("mangasee", "fr"), + dateFormat: defaultDateFormat, + dateFormatLocale: defaultDateFormatLocale, + version: nepnepVersion, + sourceCodeUrl: nepnepSourceCodeUrl, + ), + Source( + name: "MangaLife", + baseUrl: "https://manga4life.com", + lang: "en", + typeSource: "nepnep", + iconUrl: getIconUrl("mangalife", "id"), + dateFormat: defaultDateFormat, + dateFormatLocale: defaultDateFormatLocale, + version: nepnepVersion, + sourceCodeUrl: nepnepSourceCodeUrl, + ), +]; diff --git a/manga/sources_generator.dart b/manga/sources_generator.dart index 2e479fc6..02482e70 100644 --- a/manga/sources_generator.dart +++ b/manga/sources_generator.dart @@ -7,6 +7,7 @@ import 'multisrc/heancms/sources.dart'; import 'multisrc/madara/sources.dart'; import 'multisrc/mangareader/sources.dart'; import 'multisrc/mmrcms/sources.dart'; +import 'multisrc/nepnep/sources.dart'; import 'src/all/batoto/sources.dart'; import 'src/all/comick/sources.dart'; import 'src/all/mangadex/sources.dart'; @@ -21,7 +22,8 @@ void main() { ...mmrcmsSourcesList, ...heanCmsSourcesList, mangahereSource, - ...batotoSourcesList + ...batotoSourcesList, + ...nepnepSourcesList ]; final List> jsonList = _sourcesList.map((source) => source.toJson()).toList();