diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 0c685488..455a6f3f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -115,13 +115,13 @@ object APIHolder { } fun Context.getApiSettings(): HashSet { - val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) + //val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) val hashSet = HashSet() val activeLangs = getApiProviderLangSettings() hashSet.addAll(apis.filter { activeLangs.contains(it.lang) }.map { it.name }) - val set = settingsManager.getStringSet( + /*val set = settingsManager.getStringSet( this.getString(R.string.search_providers_list_key), hashSet )?.toHashSet() ?: hashSet @@ -132,9 +132,10 @@ object APIHolder { if (activeLangs.contains(api.lang)) { list.add(name) } - } - if (list.isEmpty()) return hashSet - return list + }*/ + //if (list.isEmpty()) return hashSet + //return list + return hashSet } fun Context.getApiDubstatusSettings(): HashSet { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ParCollections.kt b/app/src/main/java/com/lagradost/cloudstream3/ParCollections.kt index c3a1bced..dc5aff1b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ParCollections.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ParCollections.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3 +import com.lagradost.cloudstream3.mvvm.logError import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking @@ -43,8 +44,17 @@ fun List.apmap(f: suspend (A) -> B): List = runBlocking { exec.awaitTermination(1, TimeUnit.DAYS) }*/ +// built in try catch fun argamap( vararg transforms: suspend () -> R, ) = runBlocking { - transforms.map { async { it.invoke() } }.map { it.await() } + transforms.map { + async { + try { + it.invoke() + } catch (e: Exception) { + logError(e) + } + } + }.map { it.await() } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AllAnimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AllAnimeProvider.kt index 046477c3..b29dfc49 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AllAnimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AllAnimeProvider.kt @@ -258,7 +258,7 @@ class AllAnimeProvider : MainAPI() { val sources = Regex("""sourceUrl[:=]"(.+?)"""").findAll(html).toList() .map { URLDecoder.decode(it.destructured.component1().sanitize(), "UTF-8") } - sources.forEach { + sources.apmap { var link = it if (URI(link).isAbsolute || link.startsWith("//")) { if (link.startsWith("//")) link = "https:$it" diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt index 650442ca..6b075fba 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt @@ -95,9 +95,7 @@ class AnimeFlickProvider : MainAPI() { var alreadyAdded = false for (extractor in extractorApis) { if (link.startsWith(extractor.mainUrl)) { - extractor.getSafeUrl(link, data)?.forEach { - callback(it) - } + extractor.getSafeUrl(link, data)?.forEach(callback) alreadyAdded = true break } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt index e2378c58..83f77631 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt @@ -52,8 +52,11 @@ class WcoProvider : MainAPI() { val nameHeader = filmDetail.selectFirst("> h3.film-name > a") val title = nameHeader.text().replace(" (Dub)", "") val href = - nameHeader.attr("href").replace("/watch/", "/anime/").replace("-episode-.*".toRegex(), "/") - val isDub = filmPoster.selectFirst("> div.film-poster-quality")?.text()?.contains("DUB") ?: false + nameHeader.attr("href").replace("/watch/", "/anime/") + .replace("-episode-.*".toRegex(), "/") + val isDub = + filmPoster.selectFirst("> div.film-poster-quality")?.text()?.contains("DUB") + ?: false val poster = filmPoster.selectFirst("> img").attr("data-src") val set: EnumSet = EnumSet.of(if (isDub) DubStatus.Dubbed else DubStatus.Subbed) @@ -84,8 +87,11 @@ class WcoProvider : MainAPI() { val img = fixUrl(i.selectFirst("img").attr("data-src")) val title = i.selectFirst("img").attr("title") val isDub = !i.select(".pick.film-poster-quality").isEmpty() - val year = i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(1)").text().toIntOrNull() - val type = i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(3)").text() + val year = + i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(1)").text() + .toIntOrNull() + val type = + i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(3)").text() returnValue.add( if (getType(type) == TvType.AnimeMovie) { @@ -174,8 +180,9 @@ class WcoProvider : MainAPI() { val response = app.get(url, timeout = 120).text val document = Jsoup.parse(response) - val japaneseTitle = document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(1)") - ?.text()?.trim()?.replace("Other names:", "")?.trim() + val japaneseTitle = + document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(1)") + ?.text()?.trim()?.replace("Other names:", "")?.trim() val canonicalTitle = document.selectFirst("meta[name=\"title\"]") ?.attr("content")?.split("| W")?.get(0).toString() @@ -187,22 +194,25 @@ class WcoProvider : MainAPI() { AnimeEpisode(it.attr("href")) } ?: ArrayList()) - val statusElem = document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(2)") + val statusElem = + document.selectFirst("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(2)") val status = when (statusElem?.text()?.replace("Status:", "")?.trim()) { "Ongoing" -> ShowStatus.Ongoing "Completed" -> ShowStatus.Completed else -> null } val yearText = - document.selectFirst("div.elements div.row > div:nth-child(2) > div.row-line:nth-child(4)")?.text() + document.selectFirst("div.elements div.row > div:nth-child(2) > div.row-line:nth-child(4)") + ?.text() val year = yearText?.replace("Date release:", "")?.trim()?.split("-")?.get(0)?.toIntOrNull() val poster = document.selectFirst(".film-poster-img")?.attr("src") val type = document.selectFirst("span.item.mr-1 > a")?.text()?.trim() val synopsis = document.selectFirst(".description > p")?.text()?.trim() - val genre = document.select("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(5) > a") - .map { it?.text()?.trim().toString() } + val genre = + document.select("div.elements div.row > div:nth-child(1) > div.row-line:nth-child(5) > a") + .map { it?.text()?.trim().toString() } return newAnimeLoadResponse(canonicalTitle, url, getType(type ?: "")) { japName = japaneseTitle @@ -231,9 +241,7 @@ class WcoProvider : MainAPI() { } for (server in servers) { - WcoStream().getSafeUrl(server["link"].toString(), "")?.forEach { - callback.invoke(it) - } + WcoStream().getSafeUrl(server["link"].toString(), "")?.forEach(callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt index b285b5d4..e961a966 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt @@ -2,7 +2,7 @@ package com.lagradost.cloudstream3.extractors import com.lagradost.cloudstream3.apmap import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall +import com.lagradost.cloudstream3.argamap import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.extractorApis import com.lagradost.cloudstream3.utils.getQualityFromName @@ -27,17 +27,22 @@ class Vidstream(val mainUrl: String) { private val normalApis = arrayListOf(MultiQuality()) // https://gogo-stream.com/streaming.php?id=MTE3NDg5 - suspend fun getUrl(id: String, isCasting: Boolean = false, callback: (ExtractorLink) -> Unit): Boolean { - try { - normalApis.apmap { api -> - val url = api.getExtractorUrl(id) - val source = api.getSafeUrl(url) - source?.forEach { callback.invoke(it) } - } - val extractorUrl = getExtractorUrl(id) - - /** Stolen from GogoanimeProvider.kt extractor */ - suspendSafeApiCall { + suspend fun getUrl( + id: String, + isCasting: Boolean = false, + callback: (ExtractorLink) -> Unit + ): Boolean { + println("VIDSTREAM:: $id") + val extractorUrl = getExtractorUrl(id) + argamap( + { + normalApis.apmap { api -> + val url = api.getExtractorUrl(id) + val source = api.getSafeUrl(url) + source?.forEach { callback.invoke(it) } + } + }, { + /** Stolen from GogoanimeProvider.kt extractor */ val link = getDownloadUrl(id) println("Generated vidstream download link: $link") val page = app.get(link, referer = extractorUrl) @@ -50,7 +55,8 @@ class Vidstream(val mainUrl: String) { val href = element.attr("href") ?: return@apmap val qual = if (element.text() .contains("HDP") - ) "1080" else qualityRegex.find(element.text())?.destructured?.component1().toString() + ) "1080" else qualityRegex.find(element.text())?.destructured?.component1() + .toString() if (!loadExtractor(href, link, callback)) { callback.invoke( @@ -65,34 +71,32 @@ class Vidstream(val mainUrl: String) { ) } } - } + }, { + with(app.get(extractorUrl)) { + val document = Jsoup.parse(this.text) + val primaryLinks = document.select("ul.list-server-items > li.linkserver") + //val extractedLinksList: MutableList = mutableListOf() - with(app.get(extractorUrl)) { - val document = Jsoup.parse(this.text) - val primaryLinks = document.select("ul.list-server-items > li.linkserver") - //val extractedLinksList: MutableList = mutableListOf() + // All vidstream links passed to extractors + primaryLinks.distinctBy { it.attr("data-video") }.forEach { element -> + val link = element.attr("data-video") + //val name = element.text() - // All vidstream links passed to extractors - primaryLinks.distinctBy { it.attr("data-video") }.forEach { element -> - val link = element.attr("data-video") - //val name = element.text() - - // Matches vidstream links with extractors - extractorApis.filter { !it.requiresReferer || !isCasting }.apmap { api -> - if (link.startsWith(api.mainUrl)) { - val extractedLinks = api.getSafeUrl(link, extractorUrl) - if (extractedLinks?.isNotEmpty() == true) { - extractedLinks.forEach { - callback.invoke(it) + // Matches vidstream links with extractors + extractorApis.filter { !it.requiresReferer || !isCasting }.apmap { api -> + if (link.startsWith(api.mainUrl)) { + val extractedLinks = api.getSafeUrl(link, extractorUrl) + if (extractedLinks?.isNotEmpty() == true) { + extractedLinks.forEach { + callback.invoke(it) + } } } } } } - return true } - } catch (e: Exception) { - return false - } + ) + return true } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/VoeExtractor.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/VoeExtractor.kt index c20fa28d..d3359507 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/VoeExtractor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/VoeExtractor.kt @@ -1,9 +1,8 @@ package com.lagradost.cloudstream3.extractors import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.mapper +import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName @@ -29,14 +28,14 @@ open class VoeExtractor : ExtractorApi() { .replace("0,", "0") .trim() //Log.i(this.name, "Result => (src) ${src}") - mapper.readValue(src)?.let { voelink -> + parseJson(src)?.let { voelink -> //Log.i(this.name, "Result => (voelink) ${voelink}") val linkUrl = voelink.url val linkLabel = voelink.label?.toString() ?: "" if (!linkUrl.isNullOrEmpty()) { extractedLinksList.add( ExtractorLink( - name = "Voe ${linkLabel}", + name = "Voe $linkLabel", source = this.name, url = linkUrl, quality = getQualityFromName(linkLabel), diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt index 15b6ee71..9d610039 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt @@ -2,8 +2,11 @@ package com.lagradost.cloudstream3.movieproviders import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.toJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.Qualities +import com.lagradost.cloudstream3.utils.getPostForm +import com.lagradost.cloudstream3.utils.loadExtractor import okio.Buffer import org.jsoup.Jsoup import org.jsoup.nodes.Document @@ -211,14 +214,7 @@ class AllMoviesForYouProvider : MainAPI() { } } } else if (requestUrl.startsWith("https://dood")) { - for (extractor in extractorApis) { - if (requestUrl.startsWith(extractor.mainUrl)) { - extractor.getSafeUrl(requestUrl)?.forEach { link -> - callback(link) - } - break - } - } + loadExtractor(requestUrl, null, callback) } else { callback( ExtractorLink( diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt index 1a1afc65..239271a1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt @@ -1,10 +1,11 @@ package com.lagradost.cloudstream3.movieproviders import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.utils.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.extractorApis import java.util.* -class CinecalidadProvider:MainAPI() { +class CinecalidadProvider : MainAPI() { override val mainUrl = "https://cinecalidad.lol" override val name = "Cinecalidad" override val lang = "es" @@ -15,6 +16,7 @@ class CinecalidadProvider:MainAPI() { TvType.Movie, TvType.TvSeries, ) + override suspend fun getMainPage(): HomePageResponse { val items = ArrayList() val urls = listOf( @@ -22,18 +24,22 @@ class CinecalidadProvider:MainAPI() { Pair("$mainUrl/genero-de-la-pelicula/peliculas-en-calidad-4k/", "4K UHD"), ) - items.add(HomePageList("Series",app.get("$mainUrl/ver-serie/").document.select(".item.tvshows").map{ - val title = it.selectFirst("div.in_title").text() - TvSeriesSearchResponse( - title, - it.selectFirst("a").attr("href"), - this.name, - TvType.TvSeries, - it.selectFirst(".poster.custom img").attr("data-src"), - null, - null, - ) - })) + items.add( + HomePageList( + "Series", + app.get("$mainUrl/ver-serie/").document.select(".item.tvshows").map { + val title = it.selectFirst("div.in_title").text() + TvSeriesSearchResponse( + title, + it.selectFirst("a").attr("href"), + this.name, + TvType.TvSeries, + it.selectFirst(".poster.custom img").attr("data-src"), + null, + null, + ) + }) + ) for (i in urls) { try { @@ -100,7 +106,9 @@ class CinecalidadProvider:MainAPI() { val soup = app.get(url, timeout = 120).document val title = soup.selectFirst(".single_left h1").text() - val description = soup.selectFirst(".single_left > table:nth-child(3) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(2) > p")?.text()?.trim() + val description = + soup.selectFirst(".single_left > table:nth-child(3) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(2) > p") + ?.text()?.trim() val poster: String? = soup.selectFirst(".alignnone").attr("data-src") val episodes = soup.select("div.se-c div.se-a ul.episodios li").map { li -> val href = li.selectFirst("a").attr("href") @@ -114,7 +122,8 @@ class CinecalidadProvider:MainAPI() { epThumb ) } - return when (val tvType = if (url.contains("/ver-pelicula/")) TvType.Movie else TvType.TvSeries) { + return when (val tvType = + if (url.contains("/ver-pelicula/")) TvType.Movie else TvType.TvSeries) { TvType.TvSeries -> { TvSeriesLoadResponse( title, @@ -157,9 +166,10 @@ class CinecalidadProvider:MainAPI() { val urlserver = app.get(url).text val serverRegex = Regex("(https:.*?\\\")") val videos = serverRegex.findAll(urlserver).map { - it.value.replace("\\/", "/").replace("\"","") + it.value.replace("\\/", "/").replace("\"", "") }.toList() - val serversRegex = Regex("(https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&\\/\\/=]*))") + val serversRegex = + Regex("(https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&\\/\\/=]*))") val links = serversRegex.findAll(videos.toString()).map { it.value }.toList() for (link in links) { for (extractor in extractorApis) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt index 4f17ced0..cd7778ee 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt @@ -1,16 +1,14 @@ package com.lagradost.cloudstream3.animeproviders import com.lagradost.cloudstream3.* -import java.util.* import com.lagradost.cloudstream3.extractors.FEmbed import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor +import java.util.* import kotlin.collections.ArrayList - -class DoramasYTProvider:MainAPI() { - +class DoramasYTProvider : MainAPI() { companion object { fun getType(t: String): TvType { return if (t.contains("OVA") || t.contains("Especial")) TvType.ONA @@ -33,31 +31,44 @@ class DoramasYTProvider:MainAPI() { override suspend fun getMainPage(): HomePageResponse { val urls = listOf( Pair("$mainUrl/emision", "En emisión"), - Pair("$mainUrl/doramas?categoria=pelicula&genero=false&fecha=false&letra=false", "Peliculas"), + Pair( + "$mainUrl/doramas?categoria=pelicula&genero=false&fecha=false&letra=false", + "Peliculas" + ), Pair("$mainUrl/doramas", "Doramas"), - Pair("$mainUrl/doramas?categoria=live-action&genero=false&fecha=false&letra=false", "Live Action"), + Pair( + "$mainUrl/doramas?categoria=live-action&genero=false&fecha=false&letra=false", + "Live Action" + ), ) val items = ArrayList() - items.add(HomePageList("Capítulos actualizados", app.get(mainUrl, timeout = 120).document.select(".col-6").map{ - val title = it.selectFirst("p").text() - val poster = it.selectFirst(".chapter img").attr("src") - val epRegex = Regex("episodio-(\\d+)") - val url = it.selectFirst("a").attr("href").replace("ver/","dorama/").replace(epRegex,"sub-espanol") - val epNum = it.selectFirst("h3").text().toIntOrNull() - AnimeSearchResponse( - title, - url, - this.name, - TvType.Anime, - poster, - null, - if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed), - subEpisodes = epNum, - dubEpisodes = epNum, - ) - })) + items.add( + HomePageList( + "Capítulos actualizados", + app.get(mainUrl, timeout = 120).document.select(".col-6").map { + val title = it.selectFirst("p").text() + val poster = it.selectFirst(".chapter img").attr("src") + val epRegex = Regex("episodio-(\\d+)") + val url = it.selectFirst("a").attr("href").replace("ver/", "dorama/") + .replace(epRegex, "sub-espanol") + val epNum = it.selectFirst("h3").text().toIntOrNull() + AnimeSearchResponse( + title, + url, + this.name, + TvType.Anime, + poster, + null, + if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of( + DubStatus.Dubbed + ) else EnumSet.of(DubStatus.Subbed), + subEpisodes = epNum, + dubEpisodes = epNum, + ) + }) + ) for (i in urls) { try { @@ -72,7 +83,9 @@ class DoramasYTProvider:MainAPI() { TvType.Anime, poster, null, - if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed), + if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of( + DubStatus.Dubbed + ) else EnumSet.of(DubStatus.Subbed), ) } @@ -87,28 +100,32 @@ class DoramasYTProvider:MainAPI() { } override suspend fun search(query: String): ArrayList { - val search = app.get("$mainUrl/buscar?q=$query", timeout = 120).document.select(".col-6").map { - val title = it.selectFirst(".animedtls p").text() - val href = it.selectFirst("a").attr("href") - val image = it.selectFirst(".animes img").attr("src") - AnimeSearchResponse( - title, - href, - this.name, - TvType.Anime, - image, - null, - if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed), - ) - } + val search = + app.get("$mainUrl/buscar?q=$query", timeout = 120).document.select(".col-6").map { + val title = it.selectFirst(".animedtls p").text() + val href = it.selectFirst("a").attr("href") + val image = it.selectFirst(".animes img").attr("src") + AnimeSearchResponse( + title, + href, + this.name, + TvType.Anime, + image, + null, + if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of( + DubStatus.Dubbed + ) else EnumSet.of(DubStatus.Subbed), + ) + } return ArrayList(search) } + override suspend fun load(url: String): LoadResponse { val doc = app.get(url, timeout = 120).document val poster = doc.selectFirst("div.flimimg img.img1").attr("src") val title = doc.selectFirst("h1").text() val type = doc.selectFirst("h4").text() - val description = doc.selectFirst("p.textComplete").text().replace("Ver menos","") + val description = doc.selectFirst("p.textComplete").text().replace("Ver menos", "") val genres = doc.select(".nobel a").map { it.text() } val status = when (doc.selectFirst(".state h6")?.text()) { "Estreno" -> ShowStatus.Ongoing @@ -129,13 +146,14 @@ class DoramasYTProvider:MainAPI() { tags = genres } } + override suspend fun loadLinks( data: String, isCasting: Boolean, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - app.get(data).document.select("div.playother p").forEach { + app.get(data).document.select("div.playother p").apmap { val encodedurl = it.select("p").attr("data-player") val urlDecoded = base64Decode(encodedurl) val url = (urlDecoded).replace("https://doramasyt.com/reproductor?url=", "") diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt index 7df30642..d04696bf 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt @@ -157,13 +157,10 @@ class DramaSeeProvider : MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { var count = 0 - mapper.readValue>(data).forEach { item -> + mapper.readValue>(data).apmap { item -> if (item.isNotEmpty()) { count++ - var url = item.trim() - if (url.startsWith("//")) { - url = "https:$url" - } + var url = fixUrl(item.trim()) //Log.i(this.name, "Result => (url) ${url}") when { url.startsWith("https://asianembed.io") -> { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt index a203cdd1..e083846f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt @@ -69,7 +69,17 @@ class FilmanProvider : MainAPI() { val img = i.selectFirst("> img").attr("src").replace("/thumb/", "/big/") val name = i.selectFirst(".title").text() if (type === TvType.TvSeries) { - returnValue.add(TvSeriesSearchResponse(name, href, this.name, type, img, null, null)) + returnValue.add( + TvSeriesSearchResponse( + name, + href, + this.name, + type, + img, + null, + null + ) + ) } else { returnValue.add(MovieSearchResponse(name, href, this.name, type, img, null)) } @@ -98,15 +108,26 @@ class FilmanProvider : MainAPI() { val regex = Regex("""\[s(\d{1,3})e(\d{1,3})]""").find(e) if (regex != null) { val eid = regex.groups - episodes.add(TvSeriesEpisode( - e.split("]")[1].trim(), - eid[1]?.value?.toInt(), - eid[2]?.value?.toInt(), - episode.attr("href"), - )) + episodes.add( + TvSeriesEpisode( + e.split("]")[1].trim(), + eid[1]?.value?.toInt(), + eid[2]?.value?.toInt(), + episode.attr("href"), + ) + ) } } - return TvSeriesLoadResponse(title, url, name, TvType.TvSeries, episodes, posterUrl, year, plot) + return TvSeriesLoadResponse( + title, + url, + name, + TvType.TvSeries, + episodes, + posterUrl, + year, + plot + ) } override suspend fun loadLinks( @@ -115,20 +136,16 @@ class FilmanProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - if(data.isEmpty()) { - return false - } val document = if (data.startsWith("http")) - Jsoup.parse(app.get(data).text).select("#links").first() - else Jsoup.parse(data) + app.get(data).document.select("#links").first() + else Jsoup.parse(data) - val items = document.select(".link-to-video") - for (i in items) { - val decoded = base64Decode(i.select("a").attr("data-iframe")) + document.select(".link-to-video")?.apmap { item -> + val decoded = base64Decode(item.select("a").attr("data-iframe")) val link = mapper.readValue(decoded).src loadExtractor(link, null, callback) } - return true + return true } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt index faa0c09c..bf82cf07 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt @@ -1,8 +1,8 @@ package com.lagradost.cloudstream3.movieproviders import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.extractors.StreamTape import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.Jsoup import java.net.URLEncoder @@ -18,8 +18,23 @@ class IHaveNoTvProvider : MainAPI() { // Uhh, I am too lazy to scrape the "latest documentaries" and "recommended documentaries", // so I am just scraping 3 random categories val allCategories = listOf( - "astronomy", "brain", "creativity", "design", "economics", "environment", "health", "history", - "lifehack", "math", "music", "nature", "people", "physics", "science", "technology", "travel" + "astronomy", + "brain", + "creativity", + "design", + "economics", + "environment", + "health", + "history", + "lifehack", + "math", + "music", + "nature", + "people", + "physics", + "science", + "technology", + "travel" ) val categories = allCategories.asSequence().shuffled().take(3) @@ -82,7 +97,9 @@ class IHaveNoTvProvider : MainAPI() { res.selectFirst("a[href][title]") } val year = - Regex("""•?\s+(\d{4})\s+•""").find(res.selectFirst(".episodeMeta").text())?.destructured?.component1() + Regex("""•?\s+(\d{4})\s+•""").find( + res.selectFirst(".episodeMeta").text() + )?.destructured?.component1() ?.toIntOrNull() val title = aTag.attr("title") @@ -138,7 +155,8 @@ class IHaveNoTvProvider : MainAPI() { ep.selectFirst(".episodeMeta").text() )?.destructured?.component1()?.toIntOrNull() - categories.addAll(ep.select(".episodeMeta > a[href*=\"/category/\"]").map { it.text().trim() }) + categories.addAll( + ep.select(".episodeMeta > a[href*=\"/category/\"]").map { it.text().trim() }) TvSeriesEpisode( epTitle, @@ -165,7 +183,8 @@ class IHaveNoTvProvider : MainAPI() { description, null, null, - soup.selectFirst(".videoDetails").select("a[href*=\"/category/\"]").map { it.text().trim() } + soup.selectFirst(".videoDetails").select("a[href*=\"/category/\"]") + .map { it.text().trim() } )) } @@ -201,9 +220,7 @@ class IHaveNoTvProvider : MainAPI() { val iframe = soup.selectFirst("#videoWrap iframe") if (iframe != null) { - if (iframe.attr("src").startsWith("https://streamtape.com")) { - StreamTape().getSafeUrl(iframe.attr("src"))?.forEach(callback) - } + loadExtractor(iframe.attr("src"), null, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt index 2ea99a84..1685cc9f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt @@ -1,6 +1,5 @@ package com.lagradost.cloudstream3.movieproviders -import android.util.Log import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.extractors.* @@ -9,7 +8,6 @@ import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.Jsoup -import kotlin.Exception class KdramaHoodProvider : MainAPI() { override val mainUrl = "https://kdramahood.com" @@ -131,13 +129,10 @@ class KdramaHoodProvider : MainAPI() { if (!epLinksContent.isNullOrEmpty()) { //Log.i(this.name, "Result => (epLinksContent) ${Jsoup.parse(epLinksContent)?.select("div")}") Jsoup.parse(epLinksContent)?.select("div")?.forEach { em -> - var href = em?.html()?.trim()?.removePrefix("'") ?: return@forEach - if (href.startsWith("//")) { - href = "https:$href" - } + val href = em?.html()?.trim()?.removePrefix("'") ?: return@forEach //Log.i(this.name, "Result => (ep#$count link) $href") if (href.isNotEmpty()) { - listOfLinks.add(href) + listOfLinks.add(fixUrl(href)) } } /* Doesn't get all links for some reasons @@ -188,7 +183,7 @@ class KdramaHoodProvider : MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { var count = 0 - mapper.readValue>(data).forEach { item -> + mapper.readValue>(data).apmap { item -> if (item.isNotEmpty()) { count++ var url = item.trim() diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt index 1825344c..372d2c57 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt @@ -231,7 +231,7 @@ open class PelisplusProviderTemplate : MainAPI() { null } } - servers.forEach { + servers.apmap { // When checking strings make sure to make them lowercase and trimmed because edgecases like "beta server " wouldn't work otherwise. if (it.first.trim().equals("beta server", ignoreCase = true)) { // Group 1: link, Group 2: Label diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt index e51b10c4..5df06a98 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt @@ -1,6 +1,5 @@ package com.lagradost.cloudstream3.movieproviders -import android.util.Log import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.AppUtils.toJson @@ -192,7 +191,7 @@ class PinoyHDXyzProvider : MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { var count = 0 - mapper.readValue>(data).forEach { item -> + mapper.readValue>(data).apmap { item -> if (item.isNotEmpty()) { val url = item.trim() loadExtractor(url, mainUrl, callback) diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt index cd52c653..71874ff5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt @@ -179,7 +179,7 @@ class PinoyMoviePediaProvider : MainAPI() { ): Boolean { // parse movie servers var count = 0 - mapper.readValue>(data).forEach { link -> + mapper.readValue>(data).apmap { link -> count++ if (link.contains("fembed.com")) { val extractor = FEmbed() diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt index d2774d37..9b4c98f0 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt @@ -136,7 +136,7 @@ class PinoyMoviesEsProvider : MainAPI() { it?.attr("data-post") ?: return@mapNotNull null }?.filter { it.isNotEmpty() }?.distinct() ?: listOf() - postlist.forEach { datapost -> + postlist.apmap { datapost -> //Log.i(this.name, "Result => (datapost) ${datapost}") val content = mapOf( Pair("action", "doo_player_ajax"), @@ -163,7 +163,7 @@ class PinoyMoviesEsProvider : MainAPI() { ): Boolean { // parse movie servers var count = 0 - mapper.readValue>(data).forEach { link -> + mapper.readValue>(data).apmap { link -> count++ //Log.i(this.name, "Result => (link) $link") if (link.startsWith("https://vstreamhub.com")) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt index d65fcda9..c286704a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt @@ -215,10 +215,9 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { ): Boolean { val urls = (tryParseJson>(data)?.let { (prefix, server) -> val episodesUrl = "$mainUrl/ajax/v2/episode/servers/$server" - val episodes = app.get(episodesUrl).text // Supported streams, they're identical - Jsoup.parse(episodes).select("a").mapNotNull { element -> + app.get(episodesUrl).document.select("a").mapNotNull { element -> val id = element?.attr("data-id") ?: return@mapNotNull null if (element.select("span")?.text()?.trim()?.isValidServer() == true) { "$prefix.$id".replace("/tv/", "/watch-tv/") @@ -250,7 +249,6 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { mapped.sources2 to "source 3", mapped.sourcesBackup to "source backup" ).forEach { (sources, sourceName) -> - println("SOURCE:::: $sourceName $sources") sources?.forEach { it?.toExtractorLink(this, sourceName)?.forEach(callback) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt index b7e9a85e..d2851673 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt @@ -77,36 +77,40 @@ open class VidstreamProviderTemplate : MainAPI() { val description = soup.selectFirst(".post-entry")?.text()?.trim() var poster: String? = null - val episodes = soup.select(".listing.items.lists > .video-block").withIndex().map { (_, li) -> - val epTitle = if (li.selectFirst(".name") != null) - if (li.selectFirst(".name").text().contains("Episode")) - "Episode " + li.selectFirst(".name").text().split("Episode")[1].trim() - else - li.selectFirst(".name").text() - else "" - val epThumb = li.selectFirst("img")?.attr("src") - val epDate = li.selectFirst(".meta > .date").text() + val episodes = + soup.select(".listing.items.lists > .video-block").withIndex().map { (_, li) -> + val epTitle = if (li.selectFirst(".name") != null) + if (li.selectFirst(".name").text().contains("Episode")) + "Episode " + li.selectFirst(".name").text().split("Episode")[1].trim() + else + li.selectFirst(".name").text() + else "" + val epThumb = li.selectFirst("img")?.attr("src") + val epDate = li.selectFirst(".meta > .date").text() - if (poster == null) { - poster = li.selectFirst("img")?.attr("onerror")?.split("=")?.get(1)?.replace(Regex("[';]"), "") - } + if (poster == null) { + poster = li.selectFirst("img")?.attr("onerror")?.split("=")?.get(1) + ?.replace(Regex("[';]"), "") + } - val epNum = Regex("""Episode (\d+)""").find(epTitle)?.destructured?.component1()?.toIntOrNull() + val epNum = Regex("""Episode (\d+)""").find(epTitle)?.destructured?.component1() + ?.toIntOrNull() - TvSeriesEpisode( - epTitle, - null, - epNum, - fixUrl(li.selectFirst("a").attr("href")), - epThumb, - epDate - ) - }.reversed() + TvSeriesEpisode( + epTitle, + null, + epNum, + fixUrl(li.selectFirst("a").attr("href")), + epThumb, + epDate + ) + }.reversed() val year = episodes.first().date?.split("-")?.get(0)?.toIntOrNull() // Make sure to get the type right to display the correct UI. - val tvType = if (episodes.size == 1 && episodes[0].name == title) TvType.Movie else TvType.TvSeries + val tvType = + if (episodes.size == 1 && episodes[0].name == title) TvType.Movie else TvType.TvSeries return when (tvType) { TvType.TvSeries -> { @@ -157,7 +161,8 @@ open class VidstreamProviderTemplate : MainAPI() { val elements = inner.select(".video-block").map { val link = fixUrl(it.select("a").attr("href")) val image = it.select(".picture > img").attr("src") - val name = it.select("div.name").text().trim().replace(Regex("""[Ee]pisode \d+"""), "") + val name = + it.select("div.name").text().trim().replace(Regex("""[Ee]pisode \d+"""), "") val isSeries = (name.contains("Season") || name.contains("Episode")) if (isSeries) { @@ -188,9 +193,7 @@ open class VidstreamProviderTemplate : MainAPI() { title, elements ) ) - } - } return HomePageResponse(homePageList) } @@ -206,7 +209,8 @@ open class VidstreamProviderTemplate : MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { // "?: return" is a very useful statement which returns if the iframe link isn't found. - val iframeLink = Jsoup.parse(app.get(data).text).selectFirst("iframe")?.attr("src") ?: return false + val iframeLink = + Jsoup.parse(app.get(data).text).selectFirst("iframe")?.attr("src") ?: return false // In this case the video player is a vidstream clone and can be handled by the vidstream extractor. // This case is a both unorthodox and you normally do not call extractors as they detect the url returned and does the rest. @@ -228,13 +232,15 @@ open class VidstreamProviderTemplate : MainAPI() { null } } - servers.forEach { + servers.apmap { // When checking strings make sure to make them lowercase and trimmed because edgecases like "beta server " wouldn't work otherwise. - if (it.first.trim().equals( "beta server", ignoreCase = true)) { + if (it.first.trim().equals("beta server", ignoreCase = true)) { // Group 1: link, Group 2: Label // Regex can be used to effectively parse small amounts of json without bothering with writing a json class. - val sourceRegex = Regex("""sources:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""") - val trackRegex = Regex("""tracks:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""") + val sourceRegex = + Regex("""sources:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""") + val trackRegex = + Regex("""tracks:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""") // Having a referer is often required. It's a basic security check most providers have. // Try to replicate what your browser does. diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt index 0a27e4c8..f2436812 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt @@ -174,12 +174,9 @@ class WatchAsianProvider : MainAPI() { getServerLinks(data) } else { data } var count = 0 - mapper.readValue>(links).forEach { item -> + mapper.readValue>(links).apmap { item -> count++ - var url = item.trim() - if (url.startsWith("//")) { - url = "https:$url" - } + val url = fixUrl(item.trim()) //Log.i(this.name, "Result => (url) $url") if (url.startsWith("https://asianembed.io")) { // Fetch links diff --git a/app/src/main/java/com/lagradost/cloudstream3/network/DohProviders.kt b/app/src/main/java/com/lagradost/cloudstream3/network/DohProviders.kt index 65f1a49d..5372d0be 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/network/DohProviders.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/network/DohProviders.kt @@ -9,7 +9,7 @@ import java.net.InetAddress * Based on https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/main/java/eu/kanade/tachiyomi/network/DohProviders.kt */ - fun OkHttpClient.Builder.addGenericDns(url: String, ips: List) = dns( +fun OkHttpClient.Builder.addGenericDns(url: String, ips: List) = dns( DnsOverHttps .Builder() .client(build()) diff --git a/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt b/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt index d3b56ac0..36ca3d3f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt @@ -1,6 +1,7 @@ package com.lagradost.cloudstream3.network import android.content.Context +import android.util.Log import androidx.preference.PreferenceManager import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.R @@ -286,6 +287,7 @@ open class Requests { timeout: Long = 0L, interceptor: Interceptor? = null, ): AppResponse { + Log.i("GET", url) val client = baseClient .newBuilder() .followRedirects(allowRedirects) @@ -315,6 +317,7 @@ open class Requests { cacheUnit: TimeUnit = DEFAULT_TIME_UNIT, timeout: Long = 0L, ): AppResponse { + Log.i("POST", url) val client = baseClient .newBuilder() .followRedirects(allowRedirects) @@ -339,6 +342,7 @@ open class Requests { cacheUnit: TimeUnit = DEFAULT_TIME_UNIT, timeout: Long = 0L ): AppResponse { + Log.i("PUT", url) val client = baseClient .newBuilder() .followRedirects(allowRedirects) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt index e06aae76..97b415d5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt @@ -22,6 +22,7 @@ import com.google.android.material.button.MaterialButton import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia import com.lagradost.cloudstream3.APIHolder.getApiFromName +import com.lagradost.cloudstream3.APIHolder.getApiSettings import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.observe @@ -93,6 +94,22 @@ class SearchFragment : Fragment() { var selectedSearchTypes = mutableListOf() var selectedApis = mutableSetOf() + fun search(query: String?) { + if (query == null) return + context?.getApiSettings()?.let { settings -> + searchViewModel.searchAndCancel( + query = query, + providersActive = selectedApis.filter { name -> + settings.contains(name) && getApiFromName(name).supportedTypes.any { + selectedSearchTypes.contains( + it + ) + } + }.toSet() + ) + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -274,6 +291,7 @@ class SearchFragment : Fragment() { button?.isSelected = buttonContains() button?.setOnClickListener { + val last = selectedSearchTypes.toSet() selectedSearchTypes.clear() selectedSearchTypes.addAll(validTypes) for ((otherButton, _) in pairList) { @@ -281,6 +299,8 @@ class SearchFragment : Fragment() { } it?.context?.setKey(SEARCH_PREF_TAGS, selectedSearchTypes) it?.isSelected = true + if (last != selectedSearchTypes.toSet()) // if you click the same button again the it does nothing + search(main_search?.query?.toString()) } button?.setOnLongClickListener { @@ -292,6 +312,7 @@ class SearchFragment : Fragment() { selectedSearchTypes.removeAll(validTypes) } it?.context?.setKey(SEARCH_PREF_TAGS, selectedSearchTypes) + search(main_search?.query?.toString()) return@setOnLongClickListener true } } @@ -305,12 +326,7 @@ class SearchFragment : Fragment() { main_search.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String): Boolean { - searchViewModel.searchAndCancel( - query = query, - providersActive = selectedApis.filter { name -> - getApiFromName(name).supportedTypes.any { selectedSearchTypes.contains(it) } - }.toSet() - ) + search(query) main_search?.let { hideKeyboard(it) diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStore.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStore.kt index 21e0b9b0..e4195b8b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStore.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStore.kt @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.json.JsonMapper import com.fasterxml.jackson.module.kotlin.KotlinModule const val DOWNLOAD_HEADER_CACHE = "download_header_cache" + //const val WATCH_HEADER_CACHE = "watch_header_cache" const val DOWNLOAD_EPISODE_CACHE = "download_episode_cache" const val VIDEO_PLAYER_BRIGHTNESS = "video_player_alpha_key" diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt index 51c82f92..342c15a6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -79,7 +79,7 @@ fun getAndUnpack(string: String): String { /** * Tries to load the appropriate extractor based on link, returns true if any extractor is loaded. * */ -suspend fun loadExtractor(url: String, referer: String?, callback: (ExtractorLink) -> Unit) : Boolean { +suspend fun loadExtractor(url: String, referer: String? = null, callback: (ExtractorLink) -> Unit) : Boolean { for (extractor in extractorApis) { if (url.startsWith(extractor.mainUrl)) { extractor.getSafeUrl(url, referer)?.forEach(callback)