import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class OploVerz extends MProvider { OploVerz({required this.source}); MSource source; final Client client = Client(); @override Future getPopular(int page) async { final res = (await client.get( Uri.parse("${source.baseUrl}/anime-list/page/$page/?order=popular"), )).body; return parseAnimeList(res); } @override Future getLatestUpdates(int page) async { final res = (await client.get( Uri.parse("${source.baseUrl}/anime-list/page/$page/?order=latest"), )).body; return parseAnimeList(res); } @override Future search(String query, int page, FilterList filterList) async { final res = (await client.get( Uri.parse("${source.baseUrl}/anime-list/page/$page/?title=$query"), )).body; return parseAnimeList(res); } @override Future getDetail(String url) async { final statusList = [ {"ongoing": 0, "completed": 1}, ]; final res = (await client.get(Uri.parse(url))).body; MManga anime = MManga(); final status = xpath(res, '//*[@class="alternati"]/span[2]/text()'); if (status.isNotEmpty) { anime.status = parseStatus(status.first, statusList); } anime.description = xpath(res, '//*[@class="desc"]/div/text()').first; anime.genre = xpath(res, '//*[@class="genre-info"]/a/text()'); final epUrls = xpath( res, '//div[@class="epsleft")]/span[@class="lchx"]/a/@href', ); final names = xpath( res, '//div[@class="epsleft")]/span[@class="lchx"]/a/text()', ); final dates = xpath( res, '//div[@class="epsleft")]/span[@class="date"]/text()', ); final dateUploads = parseDates(dates, "dd/MM/yyyy", "id"); List? episodesList = []; for (var i = 0; i < epUrls.length; i++) { MChapter episode = MChapter(); episode.name = names[i]; episode.dateUpload = dateUploads[i]; episode.url = epUrls[i]; episodesList.add(episode); } anime.chapters = episodesList; return anime; } @override Future> getVideoList(String url) async { final res = (await client.get(Uri.parse(url))).body; final dataPost = xpath( res, '//*[@id="server"]/ul/li/div[contains(@id,"player-option")]/@data-post', ).first; final dataNume = xpath( res, '//*[@id="server"]/ul/li/div[contains(@id,"player-option")]/@data-nume', ).first; final dataType = xpath( res, '//*[@id="server"]/ul/li/div[contains(@id,"player-option")]/@data-type', ).first; final ress = (await client.post( Uri.parse("${source.baseUrl}/wp-admin/admin-ajax.php"), headers: {"_": "_"}, body: { "action": "player_ajax", "post": dataPost, "nume": dataNume, "type": dataType, }, )).body; final playerLink = xpath(ress, '//iframe[@class="playeriframe"]/@src').first; final resPlayer = (await client.get(Uri.parse(playerLink))).body; var resJson = substringBefore(substringAfter(resPlayer, "= "), "<"); var streams = json.decode(resJson)["streams"] as List>; List videos = []; for (var stream in streams) { String videoUrl = stream["play_url"]; final quality = getQuality(stream["format_id"]); MVideo video = MVideo(); video ..url = videoUrl ..originalUrl = videoUrl ..quality = quality; videos.add(video); } return videos; } String getQuality(int formatId) { if (formatId == 18) { return "Google - 360p"; } else if (formatId == 22) { return "Google - 720p"; } return "Unknown Resolution"; } MPages parseAnimeList(String res) { List animeList = []; final urls = xpath(res, '//div[@class="relat"]/article/div/div/a/@href'); final names = xpath(res, '//div[@class="relat"]/article/div/div/a/@title'); final images = xpath( res, '//div[@class="relat"]/article/div/div/a/div/img/@src', ); for (var i = 0; i < names.length; i++) { MManga anime = MManga(); anime.name = names[i]; anime.imageUrl = images[i]; anime.link = urls[i]; animeList.add(anime); } final pages = xpath(res, '//div[@class="pagination"]/a/@href'); final pageNumberCurrent = xpath( res, '//div[@class="pagination"]/span[@class="page-numbers current"]/text()', ); bool hasNextPage = true; if (pageNumberCurrent.isNotEmpty && pages.isNotEmpty) { hasNextPage = !(pages.length == int.parse(pageNumberCurrent.first)); } return MPages(animeList, hasNextPage); } } OploVerz main(MSource source) { return OploVerz(source: source); }