import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class Filma24 extends MProvider { Filma24(); @override Future getPopular(MSource source, int page) async { String pageNu = page == 1 ? "" : "/page/$page/"; final data = {"url": "${preferenceBaseUrl(source.id)}$pageNu"}; final res = await http('GET', json.encode(data)); return animeFromRes(res); } @override Future getLatestUpdates(MSource source, int page) async { String pageNu = page == 1 ? "" : "page/$page/"; final data = {"url": "${preferenceBaseUrl(source.id)}/$pageNu?sort=trendy"}; final res = await http('GET', json.encode(data)); return animeFromRes(res); } @override Future search( MSource source, String query, int page, FilterList filterList) async { final filters = filterList.filters; String url = ""; String pageNu = page == 1 ? "" : "page/$page/"; if (query.isNotEmpty) { url += "${preferenceBaseUrl(source.id)}/search/$query/"; } else { for (var filter in filters) { if (filter.type == "ReleaseFilter") { final year = filter.values[filter.state].value; if (year.isNotEmpty) { url = "/released-year/?release=$year/"; } } else if (filter.type == "GenreFilter") { final genre = filter.values[filter.state].value; if (genre.isNotEmpty) { url = genre; } } } url = "${preferenceBaseUrl(source.id)}$url"; } url += pageNu; final data = {"url": url}; final res = await http('GET', json.encode(data)); return animeFromRes(res); } @override Future getDetail(MSource source, String url) async { List? episodesList = []; if (!url.contains("seriale")) { MChapter episode = MChapter(); episode.name = "Filma"; episode.url = url; episodesList.add(episode); } else { final data = {"url": url}; final res = await http('GET', json.encode(data)); final document = parseHtml(res); final resultElements = document.select("div.row"); for (var result in resultElements) { final elements = result?.select("div.movie-thumb") ?? []; for (var i = 0; i < elements.length; i++) { MChapter ep = MChapter(); ep.name = elements[i].selectFirst("div > span").text; ep.url = elements[i].selectFirst("a").getHref; episodesList.add(ep); } } } MManga anime = MManga(); anime.chapters = episodesList; return anime; } @override Future> getVideoList(MSource source, String url) async { final data = {"url": url}; final res = await http('GET', json.encode(data)); List videos = []; final serverUrls = xpath(res, '//*[@class="player"]/div[1]/a/@href'); for (var serverUrl in serverUrls) { List a = []; final serVdata = {"url": "$url/$serverUrl"}; final serVres = await http('GET', json.encode(serVdata)); List iframe = xpath(serVres, '//*[@id="plx"]/p/iframe/@src'); if (iframe.isNotEmpty) { String i = iframe.first; if (i.startsWith("//")) { i = "https:$i"; } if (i.contains("vidmoly")) { a = await vidmolyExtractor(i); } else if (i.contains("dood")) { a = await doodExtractor(i, "DoodStream"); } else if (i.contains("oneupload")) { a = await oneuploadExtractor(i); } else if (i.contains("uqload")) { a = await uqloadExtractor(i); } else if (i.contains("voe.sx")) { a = await voeExtractor(i, "Voe"); } videos.addAll(a); } } return videos; } @override List getSourcePreferences(MSource source) { return [ EditTextPreference( key: "pref_domain", title: "Domeni i përdorur aktualisht", summary: "", value: "https://www.filma24.pl", dialogTitle: "Domeni i përdorur aktualisht", dialogMessage: "", text: "https://www.filma24.pl"), ]; } String preferenceBaseUrl(int sourceId) { return getPreferenceValue(sourceId, "pref_domain"); } @override List getFilterList(MSource source) { return [ SelectFilter("ReleaseFilter", "Viti", 0, [ SelectFilterOption("", ""), SelectFilterOption("SË SHPEJTI", "/se-shpejti/"), SelectFilterOption("Aksion", "/aksion/"), SelectFilterOption("Animuar", "/animuar/"), SelectFilterOption("Aventurë", "/aventure/"), SelectFilterOption("Aziatik", "/aziatik/"), SelectFilterOption("Biografi", "/biografi/"), SelectFilterOption("Nordik", "/nordik/"), SelectFilterOption("Dokumentar", "/dokumentar/"), SelectFilterOption("Dramë", "/drame/"), SelectFilterOption("Erotik +18", "/erotik/"), SelectFilterOption("Familjar", "/familjar/"), SelectFilterOption("Fantashkencë", "/fantashkence/"), SelectFilterOption("Fantazi", "/fantazi/"), SelectFilterOption("Francez", "/francez/"), SelectFilterOption("Gjerman", "/gjerman/"), SelectFilterOption("Hindi", "/hindi/"), SelectFilterOption("Histori", "/histori/"), SelectFilterOption("Horror", "/horror/"), SelectFilterOption("Italian", "/italian/"), SelectFilterOption("Komedi", "/komedi/"), SelectFilterOption("Krim", "/krim/"), SelectFilterOption("Luftë", "/lufte/"), SelectFilterOption("Mister", "/mister/"), SelectFilterOption("Muzikë", "/muzik/"), SelectFilterOption("NETFLIX", "/netflix/"), SelectFilterOption("Romancë", "/romance/"), SelectFilterOption("Rus", "/rus/"), SelectFilterOption("Shqiptar", "/shqiptar/"), SelectFilterOption("Spanjoll", "/spanjoll/"), SelectFilterOption("Sport", "/sport/"), SelectFilterOption("Thriller", "/thriller/"), SelectFilterOption("Turk", "/turk/"), SelectFilterOption("Western", "/western/"), ]), ]; } Future> vidmolyExtractor(String url) async { final headers = { 'Referer': 'https://vidmoly.to', }; List videos = []; final playListUrlResponse = await http('GET', json.encode({"url": url})); final playlistUrl = RegExp(r'file:"(\S+?)"').firstMatch(playListUrlResponse)?.group(1) ?? ""; final masterPlaylistRes = await http( 'GET', json.encode({"url": playlistUrl, "headers": headers})); if (masterPlaylistRes != "error") { for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:") .split("#EXT-X-STREAM-INF:")) { final quality = "${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p"; String videoUrl = substringBefore(substringAfter(it, "\n"), "\n"); MVideo video = MVideo(); video ..url = videoUrl ..originalUrl = videoUrl ..quality = "Vidmoly $quality" ..headers = headers; videos.add(video); } } return videos; } Future> oneuploadExtractor(String url) async { List videos = []; final playListUrlResponse = await http('GET', json.encode({"url": url})); final playlistUrl = RegExp(r'file:"(\S+?)"').firstMatch(playListUrlResponse)?.group(1) ?? ""; final masterPlaylistRes = await http('GET', json.encode({"url": playlistUrl})); for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:") .split("#EXT-X-STREAM-INF:")) { final quality = "${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p"; String videoUrl = substringBefore(substringAfter(it, "\n"), "\n"); MVideo video = MVideo(); video ..url = videoUrl ..originalUrl = videoUrl ..quality = "OneUploader $quality"; videos.add(video); } return videos; } Future> uqloadExtractor(String url) async { final res = await http('GET', json.encode({"url": url})); final js = xpath(res, '//script[contains(text(), "sources:")]/text()'); if (js.isEmpty) { return []; } final videoUrl = substringBefore(substringAfter(js.first, "sources: [\""), '"'); MVideo video = MVideo(); video ..url = videoUrl ..originalUrl = videoUrl ..quality = "Uqload" ..headers = {"Referer": "${Uri.parse(url).origin}/"}; return [video]; } MPages animeFromRes(String res) { final document = parseHtml(res); final result = document.selectFirst("div.row"); final elements = result?.select("div.movie-thumb") ?? []; List mangaList = []; for (var i = 0; i < elements.length; i++) { MManga manga = MManga(); manga.name = elements[i].selectFirst("div > a > h4").text; manga.imageUrl = elements[i].selectFirst("a").getSrc; manga.link = elements[i].selectFirst("a").getHref; mangaList.add(manga); } return MPages(mangaList, document.selectFirst("div > a.nextpostslink")?.attr("href") != null); } } Filma24 main() { return Filma24(); }