diff --git a/anime/source_generator.dart b/anime/source_generator.dart index 1e81ad5d..da5df896 100644 --- a/anime/source_generator.dart +++ b/anime/source_generator.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'dart:io'; import '../model/source.dart'; import 'src/en/gogoanime/source.dart'; +import 'src/en/wcostream/source.dart'; import 'src/fr/franime/source.dart'; import 'src/fr/otakufr/source.dart'; import 'src/fr/universanime/source.dart'; @@ -12,7 +13,8 @@ void main() { gogoanimeSource, franimeSource, universanimeSource, - otakufr + otakufr, + wcostreamSource ]; final List> jsonList = _sourcesList.map((source) => source.toJson()).toList(); diff --git a/anime/src/en/wcostream/source.dart b/anime/src/en/wcostream/source.dart new file mode 100644 index 00000000..37776f08 --- /dev/null +++ b/anime/src/en/wcostream/source.dart @@ -0,0 +1,17 @@ +import '../../../../model/source.dart'; + +Source get wcostreamSource => _wcostreamSource; +const wcostreamVersion = "0.0.1"; +const wcostreamSourceCodeUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/fr/wcostream/wcostream-v$wcostreamVersion.dart"; +Source _wcostreamSource = Source( + name: "WCOStream", + baseUrl: "https://wcostream.fr", + apiUrl: "https://api.wcostream.fr", + lang: "en", + typeSource: "single", + iconUrl: '', + sourceCodeUrl: wcostreamSourceCodeUrl, + version: wcostreamVersion, + isManga: false, + isFullData: false); diff --git a/anime/src/en/wcostream/wcostream-v0.0.1.dart b/anime/src/en/wcostream/wcostream-v0.0.1.dart new file mode 100644 index 00000000..935246e8 --- /dev/null +++ b/anime/src/en/wcostream/wcostream-v0.0.1.dart @@ -0,0 +1,218 @@ +import 'dart:convert'; +import 'package:bridge_lib/bridge_lib.dart'; + +getPopularAnime(MangaModel anime) async { + return await getLatestUpdatesAnime(anime); +} + +Future getLatestUpdatesAnime(MangaModel anime) async { + final data = { + "url": "https://www.wcostream.org", + "headers": {"Referer": "https://wcostream.org/"}, + "sourceId": anime.sourceId + }; + final res = await MBridge.http(json.encode(data), 0); + if (res.isEmpty) { + return anime; + } + anime.urls = MBridge.xpath( + res, + '//*[@id="content"]/div/div[contains(text(),"Recent Releases")]/div/ul/li/div[@class="img"]/a/@href', + '._') + .split('._'); + + final imagess = MBridge.xpath( + res, + '//*[@id="content"]/div/div[contains(text(),"Recent Releases")]/div/ul/li/div[@class="img"]/a/img/@src', + '._') + .split('._'); + List images = []; + for (var image in MBridge.listParse(imagess, 0)) { + images.add(fixUrl(image)); + } + anime.images = images; + final namess = MBridge.xpath( + res, + '//*[@id="content"]/div/div[contains(text(),"Recent Releases")]/div/ul/li/div[@class="recent-release-episodes"]/a/text()', + '._') + .split('._'); + List names = []; + for (var name in MBridge.listParse(namess, 0)) { + names.add(MBridge.subString(name, ' Episode', 0)); + } + anime.names = names; + anime.hasNextPage = false; + return anime; +} + +String fixUrl(String url) { + return MBridge.regExp(url, r"^(?:(?:https?:)?//|www\.)", 'https://', 0, 0); +} + +getAnimeDetail(MangaModel anime) async { + final url = 'https://www.wcostream.org${anime.link}'; + print(url); + final data = { + "url": url, + "headers": {"referer": "https://wcostream.org/"} + }; + final res = await MBridge.http(json.encode(data), 0); + if (res.isEmpty) { + return anime; + } + + anime.status = 5; + anime.description = MBridge.xpath( + res, + '//*[@class="katcont"]/div/p[contains(text(),"Plot Summary:")]/text()', + '') + .replaceAll('Plot Summary: ', ''); + + anime.genre = MBridge.xpath( + res, '//*[@id="cat-genre"]/div[@class="wcobtn"]/a/text()', '._') + .split('._'); + + anime.urls = MBridge.xpath( + res, + '//*[@id="catlist-listview" and @class^="cat-listview"]/ul/li/a/@href', + '._') + .split('._'); + anime.names = MBridge.xpath( + res, + '//*[@id="catlist-listview" and @class^="cat-listview"]/ul/li/a/text()', + '._') + .split('._'); + anime.chaptersDateUploads = []; + return anime; +} + +searchAnime(MangaModel anime) async { + final data = { + "url": "https://www.wcostream.org/search", + "fields": {'catara': anime.query.replaceAll(" ", "+"), 'konuara': 'series'}, + "headers": {"Referer": "https://www.wcostream.org/"}, + "sourceId": anime.sourceId + }; + final res = await MBridge.httpMultiparFormData(json.encode(data), 1); + if (res.isEmpty) { + return anime; + } + + anime.urls = MBridge.xpath( + res, + '//*[@id="blog"]/div[@class="cerceve"]/div[@class="iccerceve"]/a/@href', + '._') + .split('._'); + + anime.names = MBridge.xpath( + res, + '//*[@id="blog"]/div[@class="cerceve"]/div[@class="iccerceve"]/a/@title', + '._') + .split('._'); + anime.images = MBridge.xpath( + res, + '//*[@id="blog"]/div[@class="cerceve"]/div[@class="iccerceve"]/a/img/@src', + '._') + .split('._'); + anime.hasNextPage = false; + return anime; +} + +getVideoList(MangaModel anime) async { + final datas = { + "url": anime.link, + "headers": null, + "sourceId": anime.sourceId + }; + + final res = await MBridge.http(json.encode(datas), 0); + + if (res.isEmpty) { + return []; + } + final script = MBridge.xpath( + res, '//script[contains(text(), "decodeURIComponent")]/text()', ""); + final stringList = MBridge.jsonDecodeToList( + "[${MBridge.subString(MBridge.subString(script, '[', 2), ']', 0)}]", 0); + final shiftNumber = MBridge.intParse( + MBridge.subString(MBridge.subString(script, '- ', 1), ')', 0)); + + print(shiftNumber - 1); + List iframeStuff = []; + for (var i = 0; i < stringList.length; i++) { + final decoded = MBridge.bAse64(MBridge.listParse(stringList, 0)[i], 0); + final intValue = + MBridge.intParse(MBridge.regExp(decoded, r"""\D""", '', 0, 0)); + iframeStuff + .add(MBridge.stringParse("${intValue - shiftNumber}".toString(), 1)); + } + + final iframeUrl = + MBridge.xpath(MBridge.listParse(iframeStuff, 6)[0], '//iframe/@src', ""); + final iframeHeaders = { + 'Accept': + 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', + 'Connection': 'keep-alive', + 'Host': MBridge.listParse(iframeUrl.split('/'), 0)[2], + 'Referer': 'https://www.wcostream.org/', + 'Sec-Fetch-Dest': 'iframe', + 'Sec-Fetch-Mode': 'navigate', + 'Sec-Fetch-Site': 'cross-site', + 'Upgrade-Insecure-Requests': '1', + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63', + }; + final datasIframe = {"url": iframeUrl, "headers": iframeHeaders}; + + final resIframe = await MBridge.http(json.encode(datasIframe), 0); + final getVideoLinkScript = MBridge.xpath( + resIframe, '//script[contains(text(), "getJSON")]/text()', ""); + + final getVideoLinkUrl = MBridge.subString( + MBridge.subString(getVideoLinkScript, "getJSON(\"", 2), "\"", 0); + final getVideoHeaders = { + 'Accept': 'application/json, text/javascript, */*; q=0.01', + 'Host': MBridge.listParse(iframeUrl.split('/'), 0)[2], + 'Referer': iframeUrl, + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63', + 'X-Requested-With': 'XMLHttpRequest', + }; + final datasVideoLink = { + "url": + 'https://${MBridge.listParse(iframeUrl.split('/'), 0)[2]}$getVideoLinkUrl', + "headers": getVideoHeaders + }; + + final resVideoLink = await MBridge.http(json.encode(datasVideoLink), 0); + final server = MBridge.getMapValue(resVideoLink, "server", 0); + final enc = MBridge.getMapValue(resVideoLink, "enc", 0); + final hd = MBridge.getMapValue(resVideoLink, "hd", 0); + final fhd = MBridge.getMapValue(resVideoLink, "fhd", 0); + final videoUrl = "$server/getvid?evid=$enc"; + + final videoHeaders = { + 'Accept': + 'video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5', + 'Host': MBridge.listParse(videoUrl.split('/'), 0)[2], + 'Referer': MBridge.listParse(iframeUrl.split('/'), 0)[2], + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63', + }; + List videos = []; + videos.add(MBridge.toVideo( + videoUrl, "Video 480p", videoUrl, json.encode(videoHeaders))); + if (hd.isEmpty) { + } else { + final hdVideoUrl = "$server/getvid?evid=$hd"; + videos.add(MBridge.toVideo( + hdVideoUrl, "Video 720p", hdVideoUrl, json.encode(videoHeaders))); + } + if (fhd.isEmpty) { + } else { + final fhdVideoUrl = "$server/getvid?evid=$fhd"; + videos.add(MBridge.toVideo( + fhdVideoUrl, "Video 1080p", fhdVideoUrl, json.encode(videoHeaders))); + } + return videos; +} diff --git a/anime/src/fr/franime/franime-v0.0.13.dart b/anime/src/fr/franime/franime-v0.0.14.dart similarity index 99% rename from anime/src/fr/franime/franime-v0.0.13.dart rename to anime/src/fr/franime/franime-v0.0.14.dart index fc615202..4ed0be18 100644 --- a/anime/src/fr/franime/franime-v0.0.13.dart +++ b/anime/src/fr/franime/franime-v0.0.14.dart @@ -388,7 +388,7 @@ getVideoList(MangaModel anime) async { final playerUrl = await MBridge.http(json.encode(data), 0); List a = []; if (playerName.contains("franime_myvi")) { - a = MBridge.toVideos(playerUrl, "FRAnime", playerUrl, null); + videos.add(MBridge.toVideo(playerUrl, "FRAnime", playerUrl, null)); } else if (playerName.contains("myvi")) { a = await MBridge.myTvExtractor(playerUrl); } else if (playerName.contains("sendvid")) { diff --git a/anime/src/fr/franime/source.dart b/anime/src/fr/franime/source.dart index 40835d8a..ca8f9090 100644 --- a/anime/src/fr/franime/source.dart +++ b/anime/src/fr/franime/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get franimeSource => _franimeSource; -const franimeVersion = "0.0.13"; +const franimeVersion = "0.0.14"; const franimeSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/fr/franime/franime-v$franimeVersion.dart"; Source _franimeSource = Source( diff --git a/manga/multisrc/mmrcms/mmrcms-v0.0.1.dart b/manga/multisrc/mmrcms/mmrcms-v0.0.1.dart index 7ee70c86..92140484 100644 --- a/manga/multisrc/mmrcms/mmrcms-v0.0.1.dart +++ b/manga/multisrc/mmrcms/mmrcms-v0.0.1.dart @@ -51,10 +51,10 @@ getPopularManga(MangaModel manga) async { for (var url in manga.urls) { if (manga.source == "Manga-FR") { images.add( - "${manga.baseUrl}/uploads/manga/${MBridge.listParse(MBridge.stringParse(url).split('/'), 2)[0]}.jpg"); + "${manga.baseUrl}/uploads/manga/${MBridge.listParse(MBridge.stringParse(url, 0).split('/'), 2)[0]}.jpg"); } else { images.add( - "${manga.baseUrl}/uploads/manga/${MBridge.listParse(MBridge.stringParse(url).split('/'), 2)[0]}/cover/cover_250x350.jpg"); + "${manga.baseUrl}/uploads/manga/${MBridge.listParse(MBridge.stringParse(url, 0).split('/'), 2)[0]}/cover/cover_250x350.jpg"); } } manga.images = images; @@ -135,10 +135,10 @@ getLatestUpdatesManga(MangaModel manga) async { for (var url in manga.urls) { if (manga.source == "Manga-FR") { images.add( - "${manga.baseUrl}/uploads/manga/${MBridge.listParse(MBridge.stringParse(url).split('/'), 2)[0]}.jpg"); + "${manga.baseUrl}/uploads/manga/${MBridge.listParse(MBridge.stringParse(url, 0).split('/'), 2)[0]}.jpg"); } else { images.add( - "${manga.baseUrl}/uploads/manga/${MBridge.listParse(MBridge.stringParse(url).split('/'), 2)[0]}/cover/cover_250x350.jpg"); + "${manga.baseUrl}/uploads/manga/${MBridge.listParse(MBridge.stringParse(url, 0).split('/'), 2)[0]}/cover/cover_250x350.jpg"); } } manga.images = images; diff --git a/manga/src/all/mangadex/mangadex-v0.0.11.dart b/manga/src/all/mangadex/mangadex-v0.0.11.dart index 47b7a3e2..5c203c49 100644 --- a/manga/src/all/mangadex/mangadex-v0.0.11.dart +++ b/manga/src/all/mangadex/mangadex-v0.0.11.dart @@ -3,7 +3,8 @@ import 'dart:convert'; String getMDXContentRating() { String ctnRating = MBridge.stringParse( - "&contentRating[]=suggestive&contentRating[]=safe&contentRating[]=erotica&contentRating[]=pornographic"); + "&contentRating[]=suggestive&contentRating[]=safe&contentRating[]=erotica&contentRating[]=pornographic", + 0); return ctnRating; } @@ -38,34 +39,35 @@ getPopularManga(MangaModel manga) async { MangaModel getChapters( MangaModel manga, int length, String paginatedChapterListA) { - String scanlators = MBridge.stringParse(""); - String chapNames = MBridge.stringParse(""); - String chapDate = MBridge.stringParse(""); - String chapterUrl = MBridge.stringParse(""); - String paginatedChapterList = MBridge.stringParse(paginatedChapterListA); - final dataList = MBridge.jsonPathToList(paginatedChapterList, r'$.data[*]',0); + String scanlators = MBridge.stringParse("", 0); + String chapNames = MBridge.stringParse("", 0); + String chapDate = MBridge.stringParse("", 0); + String chapterUrl = MBridge.stringParse("", 0); + String paginatedChapterList = MBridge.stringParse(paginatedChapterListA, 0); + final dataList = + MBridge.jsonPathToList(paginatedChapterList, r'$.data[*]', 0); for (var res in dataList) { - String scan = MBridge.stringParse(""); - final groups = MBridge.jsonPathToList( - res, r'$.relationships[?@.id!="00e03853-1b96-4f41-9542-c71b8692033b"]',0); - String chapName = MBridge.stringParse(""); + String scan = MBridge.stringParse("", 0); + final groups = MBridge.jsonPathToList(res, + r'$.relationships[?@.id!="00e03853-1b96-4f41-9542-c71b8692033b"]', 0); + String chapName = MBridge.stringParse("", 0); for (var element in groups) { final data = MBridge.getMapValue(element, "attributes", 1); if (data.isEmpty) { } else { final name = MBridge.getMapValue(data, "name", 0); - scan += MBridge.stringParse("$name"); + scan += MBridge.stringParse("$name", 0); final username = MBridge.getMapValue(data, "username", 0); if (username.isEmpty) { } else { if (scan.isEmpty) { - scan += MBridge.stringParse("Uploaded by $username"); + scan += MBridge.stringParse("Uploaded by $username", 0); } } } } if (scan.isEmpty) { - scan = MBridge.stringParse("No Group"); + scan = MBridge.stringParse("No Group", 0); } final dataRes = MBridge.getMapValue(res, "attributes", 1); if (dataRes.isEmpty) { @@ -76,7 +78,7 @@ MangaModel getChapters( } else { if (volume == "null") { } else { - chapName = MBridge.stringParse("Vol.$volume "); + chapName = MBridge.stringParse("Vol.$volume ", 0); } } final chapter = MBridge.getMapValue(data, "chapter", 0); @@ -84,7 +86,7 @@ MangaModel getChapters( } else { if (chapter == "null") { } else { - chapName += MBridge.stringParse("Ch.$chapter "); + chapName += MBridge.stringParse("Ch.$chapter ", 0); } } final title = MBridge.getMapValue(data, "title", 0); @@ -94,13 +96,13 @@ MangaModel getChapters( } else { if (chapName.isEmpty) { } else { - chapName += MBridge.stringParse("- "); + chapName += MBridge.stringParse("- ", 0); } - chapName += MBridge.stringParse("$title"); + chapName += MBridge.stringParse("$title", 0); } } if (chapName.isEmpty) { - chapName += MBridge.stringParse("Oneshot"); + chapName += MBridge.stringParse("Oneshot", 0); } final date = MBridge.getMapValue(data, "publishAt", 0); final id = MBridge.getMapValue(res, "id", 0); @@ -261,7 +263,7 @@ getLatestUpdatesManga(MangaModel manga) async { MBridge.jsonPathToString(ress, r'$.data[*].relationships[*].id', '.--') .split('.--'), 3); - String mangaa = MBridge.stringParse(""); + String mangaa = MBridge.stringParse("", 0); for (var id in mangaIds) { mangaa += "&ids[]=$id"; } @@ -383,7 +385,7 @@ String getCover(String dataRes, int mangaIndex, String mangaId) { MBridge.jsonPathToString(dataRes, expressionRelationAll, '_.') .split("_."), 0); - String coverFileName = MBridge.stringParse(""); + String coverFileName = MBridge.stringParse("", 0); for (var j = 0; j < relationDatas.length; j++) { final expressionData = MBridge.regExp( r'$.data[a].relationships[b]', r'\[a\]', "[$mangaIndex]", 0, 1); diff --git a/manga/src/en/mangahere/mangahere-v0.0.1.dart b/manga/src/en/mangahere/mangahere-v0.0.1.dart index 6b02e709..df664603 100644 --- a/manga/src/en/mangahere/mangahere-v0.0.1.dart +++ b/manga/src/en/mangahere/mangahere-v0.0.1.dart @@ -164,7 +164,7 @@ getChapterUrl(MangaModel manga) async { for (int i = 1; i <= manga.status; i++) { String pageLink = "$pageBase/chapterfun.ashx?cid=$chapterId&page=$i&key=$secretKey"; - String responseText = MBridge.stringParse(""); + String responseText = MBridge.stringParse("", 0); for (int tr = 1; tr <= 3; tr++) { if (responseText.isEmpty) { final headers = { @@ -177,7 +177,7 @@ getChapterUrl(MangaModel manga) async { }; final data = {"url": pageLink, "headers": headers}; final response = await MBridge.http(json.encode(data), 0); - responseText = MBridge.stringParse(response); + responseText = MBridge.stringParse(response, 0); if (responseText.isEmpty) { secretKey = "";