diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt index 4a3be71f..f0394476 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt @@ -60,7 +60,7 @@ class DubbedAnimeProvider : MainAPI() { return document.select("li > a").map { val href = fixUrl(it.attr("href")) val title = it.selectFirst("> div > div.cittx").text() - val poster = fixUrl(it.selectFirst("> div > div.imghddde > img").attr("src")) + val poster = fixUrlNull(it.selectFirst("> div > div.imghddde > img")?.attr("src")) AnimeSearchResponse( title, href, @@ -136,7 +136,7 @@ class DubbedAnimeProvider : MainAPI() { for (i in items) { val href = fixUrl(i.attr("href")) val title = i.selectFirst("div.gridtitlek").text() - val img = fixUrl(i.selectFirst("img.grid__img").attr("src")) + val img = fixUrlNull(i.selectFirst("img.grid__img")?.attr("src")) returnValue.add( if (getIsMovie(href)) { MovieSearchResponse( diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt index c7db1ec3..0760ff92 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt @@ -172,9 +172,8 @@ class GogoanimeProvider : MainAPI() { val animeId = doc.selectFirst("#movie_id").attr("value") val params = mapOf("ep_start" to "0", "ep_end" to "2000", "id" to animeId) - val responseHTML = app.get(episodeloadApi, params = params).text - val epiDoc = Jsoup.parse(responseHTML) - val episodes = epiDoc.select("a").map { + + val episodes = app.get(episodeloadApi, params = params).document.select("a").map { AnimeEpisode( fixUrl(it.attr("href").trim()), "Episode " + it.selectFirst(".name").text().replace("EP", "").trim() diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt index 0a3120ba..e89de672 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt @@ -104,7 +104,7 @@ class WatchCartoonOnlineProvider : MainAPI() { return if (!isMovie) { val title = document.selectFirst("td.vsbaslik > h2").text() - val poster = fixUrl(document.selectFirst("div#cat-img-desc > div > img").attr("src")) + val poster = fixUrlNull(document.selectFirst("div#cat-img-desc > div > img")?.attr("src")) val plot = document.selectFirst("div.iltext").text() val genres = document.select("div#cat-genre > div.wcobtn > a").map { it.text() } val episodes = document.select("div#catlist-listview > ul > li > a").reversed().map { diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/WatchSB.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/WatchSB.kt index 2e052ad9..720ccbd9 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/WatchSB.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/WatchSB.kt @@ -8,12 +8,9 @@ import com.lagradost.cloudstream3.utils.M3u8Helper import com.lagradost.cloudstream3.utils.getQualityFromName open class WatchSB : ExtractorApi() { - override val name: String - get() = "WatchSB" - override val mainUrl: String - get() = "https://watchsb.com" - override val requiresReferer: Boolean - get() = false + override val name = "WatchSB" + override val mainUrl = "https://watchsb.com" + override val requiresReferer = false override fun getUrl(url: String, referer: String?): List { val response = app.get( 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 d95b20bc..6e00ee75 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt @@ -3,6 +3,7 @@ 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 okio.Buffer import org.jsoup.Jsoup import org.jsoup.nodes.Document @@ -29,8 +30,7 @@ class AllMoviesForYouProvider : MainAPI() { override fun search(query: String): List { val url = "$mainUrl/?s=$query" - val response = app.get(url).text - val document = Jsoup.parse(response) + val document = app.get(url).document val items = document.select("ul.MovieList > li > article > a") val returnValue = ArrayList() @@ -42,7 +42,17 @@ class AllMoviesForYouProvider : MainAPI() { if (type == TvType.Movie) { returnValue.add(MovieSearchResponse(title, href, this.name, type, img, null)) } else if (type == TvType.TvSeries) { - returnValue.add(TvSeriesSearchResponse(title, href, this.name, type, img, null, null)) + returnValue.add( + TvSeriesSearchResponse( + title, + href, + this.name, + type, + img, + null, + null + ) + ) } } return returnValue @@ -69,16 +79,17 @@ class AllMoviesForYouProvider : MainAPI() { override fun load(url: String): LoadResponse { val type = getType(url) - val response = app.get(url).text - val document = Jsoup.parse(response) + val document = app.get(url).document val title = document.selectFirst("h1.Title").text() val descipt = document.selectFirst("div.Description > p").text() val rating = - document.selectFirst("div.Vote > div.post-ratings > span")?.text()?.toFloatOrNull()?.times(1000)?.toInt() + document.selectFirst("div.Vote > div.post-ratings > span")?.text()?.toFloatOrNull() + ?.times(1000)?.toInt() val year = document.selectFirst("span.Date")?.text() val duration = document.selectFirst("span.Time").text() - val backgroundPoster = fixUrl(document.selectFirst("div.Image > figure > img").attr("data-src")) + val backgroundPoster = + fixUrlNull(document.selectFirst("div.Image > figure > img")?.attr("data-src")) if (type == TvType.TvSeries) { val list = ArrayList>() @@ -112,7 +123,7 @@ class AllMoviesForYouProvider : MainAPI() { season.first, epNum, href, - if (poster != null) fixUrl(poster) else null, + fixUrlNull(poster), date ) ) @@ -136,8 +147,13 @@ class AllMoviesForYouProvider : MainAPI() { val data = getLink(document) ?: throw ErrorLoadingException("No Links Found") - return newMovieLoadResponse(title,url,type,mapper.writeValueAsString(data.filter { it != "about:blank" })) { - posterUrl = backgroundPoster + return newMovieLoadResponse( + title, + url, + type, + data.filter { it != "about:blank" }.toJson() + ) { + posterUrl = backgroundPoster this.year = year?.toIntOrNull() this.plot = descipt this.rating = rating @@ -152,7 +168,6 @@ class AllMoviesForYouProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - if (data == "about:blank") return false if (data.startsWith("$mainUrl/episode/")) { val response = app.get(data).text getLink(Jsoup.parse(response))?.let { links -> @@ -184,7 +199,15 @@ class AllMoviesForYouProvider : MainAPI() { val postDocument = Jsoup.parse(form) postDocument.selectFirst("a.downloadbtn")?.attr("href")?.let { url -> - callback(ExtractorLink(this.name, this.name, url, mainUrl, Qualities.Unknown.value)) + callback( + ExtractorLink( + this.name, + this.name, + url, + mainUrl, + Qualities.Unknown.value + ) + ) } } } else if (requestUrl.startsWith("https://dood")) { @@ -197,7 +220,15 @@ class AllMoviesForYouProvider : MainAPI() { } } } else { - callback(ExtractorLink(this.name, this.name, realDataUrl, mainUrl, Qualities.Unknown.value)) + callback( + ExtractorLink( + this.name, + this.name, + realDataUrl, + mainUrl, + Qualities.Unknown.value + ) + ) } return true } 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 f6bd2bef..0d26a5de 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.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.* @@ -156,10 +155,6 @@ class DramaSeeProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - if (data.isEmpty()) return false - if (data == "[]") return false - if (data == "about:blank") return false - mapper.readValue>(data).forEach { item -> if (item.isNotEmpty()) { var url = item.trim() 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 61242a17..cb526bcd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt @@ -186,10 +186,6 @@ class KdramaHoodProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - if (data.isEmpty()) return false - if (data == "[]") return false - if (data == "about:blank") return false - var count = 0 mapper.readValue>(data).forEach { item -> if (item.isNotEmpty()) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt index efa64525..cfd3125f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt @@ -5,6 +5,7 @@ import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.APIHolder.unixTime import com.lagradost.cloudstream3.extractors.M3u8Manifest +import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import org.jsoup.Jsoup @@ -146,7 +147,10 @@ class LookMovieProvider : MainAPI() { data class LookMovieLinkLoad(val url: String, val extraUrl: String, val isMovie: Boolean) - private fun addSubtitles(subs: List?, subtitleCallback: (SubtitleFile) -> Unit) { + private fun addSubtitles( + subs: List?, + subtitleCallback: (SubtitleFile) -> Unit + ) { if (subs == null) return subs.forEach { if (it.file.endsWith(".vtt")) @@ -203,13 +207,16 @@ class LookMovieProvider : MainAPI() { val nameHeader = watchHeader.selectFirst("> h1.bd-hd") val year = nameHeader.selectFirst("> span")?.text()?.toIntOrNull() val title = nameHeader.ownText() - val rating = parseRating(watchHeader.selectFirst("> div.movie-rate > div.rate > p > span").text()) + val rating = + parseRating(watchHeader.selectFirst("> div.movie-rate > div.rate > p > span").text()) val imgElement = document.selectFirst("div.movie-img > p.movie__poster") val img = imgElement?.attr("style") - var poster = if (img.isNullOrEmpty()) null else "url\\((.*?)\\)".toRegex().find(img)?.groupValues?.get(1) + var poster = if (img.isNullOrEmpty()) null else "url\\((.*?)\\)".toRegex() + .find(img)?.groupValues?.get(1) if (poster.isNullOrEmpty()) poster = imgElement?.attr("data-background-image") val descript = document.selectFirst("p.description-short").text() - val id = "${if (isMovie) "id_movie" else "id_show"}:(.*?),".toRegex().find(response)?.groupValues?.get(1) + val id = "${if (isMovie) "id_movie" else "id_show"}:(.*?),".toRegex() + .find(response)?.groupValues?.get(1) ?.replace(" ", "") ?: return null val realSlug = url.replace("$mainUrl/${if (isMovie) "movies" else "shows"}/view/", "") @@ -217,13 +224,13 @@ class LookMovieProvider : MainAPI() { "$mainUrl/api/v1/security/${if (isMovie) "movie" else "show"}-access?${if (isMovie) "id_movie=$id" else "slug=$realSlug"}&token=1&sk=&step=1" if (isMovie) { - val localData = mapper.writeValueAsString( + val localData = LookMovieLinkLoad( realUrl, "$mainUrl/manifests/movies/json/$id/\$unixtime/\$accessToken/master.m3u8", true - ) - ) + ).toJson() + return MovieLoadResponse( title, url, @@ -242,10 +249,14 @@ class LookMovieProvider : MainAPI() { val accessToken = root.data?.accessToken ?: return null val window = - "window\\['show_storage'] =((.|\\n)*?<)".toRegex().find(response)?.groupValues?.get(1) + "window\\['show_storage'] =((.|\\n)*?<)".toRegex().find(response)?.groupValues?.get( + 1 + ) ?: return null // val id = "id_show:(.*?),".toRegex().find(response.text)?.groupValues?.get(1) ?: return null - val season = "seasons:.*\\[((.|\\n)*?)]".toRegex().find(window)?.groupValues?.get(1) ?: return null + val season = "seasons:.*\\[((.|\\n)*?)]".toRegex().find(window)?.groupValues?.get(1) + ?: return null + fun String.fixSeasonJson(replace: String): String { return this.replace("$replace:", "\"$replace\":") } @@ -260,13 +271,13 @@ class LookMovieProvider : MainAPI() { val realJson = "[" + json.substring(0, json.lastIndexOf(',')) + "]" val episodes = mapper.readValue>(realJson).map { - val localData = mapper.writeValueAsString( + val localData = LookMovieLinkLoad( "$mainUrl/manifests/shows/json/$accessToken/\$unixtime/${it.idEpisode}/master.m3u8", "https://lookmovie.io/api/v1/shows/episode-subtitles/?id_episode=${it.idEpisode}", false - ) - ) + ).toJson() + TvSeriesEpisode( it.title, diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt index 04471892..60dece8e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt @@ -3,6 +3,8 @@ package com.lagradost.cloudstream3.movieproviders import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import org.jsoup.Jsoup @@ -93,7 +95,7 @@ class MeloMovieProvider : MainAPI() { MeloMovieLink("", "") } }.filter { it.link != "" && it.name != "" } - return mapper.writeValueAsString(parsed) + return parsed.toJson() } override fun loadLinks( @@ -102,7 +104,7 @@ class MeloMovieProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - val links = mapper.readValue>(data) + val links = parseJson>(data) for (link in links) { callback.invoke(ExtractorLink(this.name, link.name, link.link, "", getQualityFromName(link.name), false)) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProvider.kt index 45000a81..9aa6c321 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProvider.kt @@ -7,14 +7,12 @@ import com.lagradost.cloudstream3.TvType */ class PelisplusProvider : PelisplusProviderTemplate() { // mainUrl is good to have as a holder for the url to make future changes easier. - override val mainUrl: String - get() = "https://pelisplus.icu" + override val mainUrl = "https://pelisplus.icu" // name is for how the provider will be named which is visible in the UI, no real rules for this. - override val name: String - get() = "Pelisplus" + override val name = "Pelisplus" - override val homePageUrlList: List = listOf( + override val homePageUrlList = listOf( mainUrl, "$mainUrl/movies", "$mainUrl/series", @@ -24,6 +22,5 @@ class PelisplusProvider : PelisplusProviderTemplate() { // This is just extra metadata about what type of movies the provider has. // Needed for search functionality. - override val supportedTypes: Set - get() = setOf(TvType.TvSeries, TvType.Movie) + override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) } 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 07bd186c..bfd7a3dd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt @@ -1,12 +1,10 @@ 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 import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor -import java.lang.Exception class PinoyHDXyzProvider : MainAPI() { override val name = "Pinoy-HD" @@ -211,10 +209,6 @@ class PinoyHDXyzProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - if (data.isEmpty()) return false - if (data == "about:blank") return false - if (data == "[]") return false - mapper.readValue>(data).forEach { item -> if (item.isNotEmpty()) { val url = item.trim() 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 4b8cc45b..93ebffee 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt @@ -1,13 +1,11 @@ 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.FEmbed import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor -import java.lang.Exception class PinoyMoviePediaProvider : MainAPI() { override val name = "Pinoy Moviepedia" @@ -179,10 +177,6 @@ class PinoyMoviePediaProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - if (data.isEmpty()) return false - if (data == "[]") return false - if (data == "about:blank") return false - // parse movie servers mapper.readValue>(data).forEach { link -> if (link.contains("fembed.com")) { 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 ffa8e853..8d318796 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt @@ -2,7 +2,7 @@ package com.lagradost.cloudstream3.movieproviders import android.util.Log import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.extractors.* +import com.lagradost.cloudstream3.extractors.FEmbed import com.lagradost.cloudstream3.network.DdosGuardKiller import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor @@ -191,8 +191,6 @@ class PinoyMoviesEsProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - if (data == "about:blank") return false - if (data.isEmpty()) return false val sources = mutableListOf() try { if (data.contains("playcontainer")) { 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 3bfe2dac..148c318a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt @@ -24,6 +24,7 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { TvType.Movie, TvType.TvSeries, ) + override val vpnStatus = VPNStatus.None private fun Element.toSearchResult(): SearchResponse { val img = this.select("img") @@ -83,9 +84,6 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { return HomePageResponse(all) } - override val vpnStatus: VPNStatus - get() = VPNStatus.None - override fun search(query: String): List { val url = "$mainUrl/search/${query.replace(" ", "-")}" val html = app.get(url).text 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 29b75d99..5bc0f175 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.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.* @@ -170,9 +169,6 @@ class WatchAsianProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - if (data == "about:blank") return false - if (data == "[]") return false - if (data.isEmpty()) return false val links = if (data.startsWith(mainUrl)) { getServerLinks(data) } else { data } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/french-stream.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/french-stream.kt index 2b559b6a..967cc988 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/french-stream.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/french-stream.kt @@ -1,10 +1,8 @@ package com.lagradost.cloudstream3.movieproviders -import org.jsoup.Jsoup import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.utils.extractorApis import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.extractorApis class FrenchStreamProvider : MainAPI() { @@ -24,7 +22,11 @@ class FrenchStreamProvider : MainAPI() { val poster = li.selectFirst("img")?.attr("src") val title = li.selectFirst("> a.short-poster").text().toString().replace(". ", "") val year = li.selectFirst(".date")?.text()?.split("-")?.get(0)?.toIntOrNull() - if (title.contains("saison", ignoreCase = true)) { // if saison in title ==> it's a TV serie + if (title.contains( + "saison", + ignoreCase = true + ) + ) { // if saison in title ==> it's a TV serie TvSeriesSearchResponse( title, href, @@ -47,7 +49,7 @@ class FrenchStreamProvider : MainAPI() { }) } - override fun load(url: String): LoadResponse? { + override fun load(url: String): LoadResponse { val soup = app.get(url).document val title = soup.selectFirst("h1#s-title").text().toString() @@ -55,7 +57,7 @@ class FrenchStreamProvider : MainAPI() { val description = soup.selectFirst("div.fdesc").text().toString() .split("streaming", ignoreCase = true)[1].replace(" : ", "") - var poster: String? = soup.selectFirst("div.fposter > img").attr("src").toString() + var poster = fixUrlNull(soup.selectFirst("div.fposter > img")?.attr("src")) val listEpisode = soup.selectFirst("div.elink") if (isMovie) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/AniListApi.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/AniListApi.kt index 44e3e9f9..5765307b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/AniListApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/AniListApi.kt @@ -19,6 +19,7 @@ import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.maxStale import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.unixTime import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.utils.AppUtils.splitQuery +import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject import java.net.URL @@ -128,7 +129,8 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI { private val mapper = JsonMapper.builder().addModule(KotlinModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()!! - private val aniListStatusString = arrayOf("CURRENT", "COMPLETED", "PAUSED", "DROPPED", "PLANNING", "REPEATING") + private val aniListStatusString = + arrayOf("CURRENT", "COMPLETED", "PAUSED", "DROPPED", "PLANNING", "REPEATING") const val ANILIST_UNIXTIME_KEY: String = "anilist_unixtime" // When token expires const val ANILIST_TOKEN_KEY: String = "anilist_token" // anilist token for api @@ -137,7 +139,8 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI { const val ANILIST_SHOULD_UPDATE_LIST: String = "anilist_should_update_list" private fun fixName(name: String): String { - return name.lowercase(Locale.ROOT).replace(" ", "").replace("[^a-zA-Z0-9]".toRegex(), "") + return name.lowercase(Locale.ROOT).replace(" ", "") + .replace("[^a-zA-Z0-9]".toRegex(), "") } private fun searchShows(name: String): GetSearchRoot? { @@ -200,13 +203,12 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI { val data = mapOf( "query" to query, - "variables" to mapper.writeValueAsString( - mapOf( - "search" to name, - "page" to 1, - "type" to "ANIME" - ) - ) + "variables" to + mapOf( + "search" to name, + "page" to 1, + "type" to "ANIME" + ).toJson() ) val res = app.post( @@ -235,7 +237,12 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI { "(\\d+)" // year ) val blackListRegex = - Regex(""" (${blackList.joinToString(separator = "|").replace("(", "\\(").replace(")", "\\)")})""") + Regex( + """ (${ + blackList.joinToString(separator = "|").replace("(", "\\(") + .replace(")", "\\)") + })""" + ) //println("NAME $name NEW NAME ${name.replace(blackListRegex, "")}") val shows = searchShows(name.replace(blackListRegex, "")) @@ -607,7 +614,12 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI { return data != "" } - private fun postDataAboutId(id: Int, type: AniListStatusType, score: Int?, progress: Int?): Boolean { + private fun postDataAboutId( + id: Int, + type: AniListStatusType, + score: Int?, + progress: Int? + ): Boolean { try { val q = """mutation (${'$'}id: Int = $id, ${'$'}status: MediaListStatus = ${ diff --git a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/MALApi.kt b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/MALApi.kt index 09833da1..a48b68ac 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/MALApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/MALApi.kt @@ -36,8 +36,7 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI { override val redirectUrl = "mallogin" override val idPrefix = "mal" override val mainUrl = "https://myanimelist.net" - override val icon: Int - get() = R.drawable.mal_logo + override val icon = R.drawable.mal_logo override fun logOut() { removeAccountKeys() diff --git a/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt index 8ebbce8e..79402304 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt @@ -9,8 +9,6 @@ class NyaaProvider : MainAPI() { override val name = "Nyaa" override val hasChromecastSupport = false - // override val hasDownloadSupport: Boolean - // get() = false override val mainUrl = "https://nyaa.si" override val supportedTypes = setOf(TvType.Torrent) override val vpnStatus = VPNStatus.Torrent diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/APIRepository.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/APIRepository.kt index 0f36a99f..ae13b09b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/APIRepository.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/APIRepository.kt @@ -21,21 +21,28 @@ class APIRepository(val api: MainAPI) { override val supportedTypes = emptySet() } - val noneRepo = APIRepository(noneApi) + fun isInvalidData(data : String): Boolean { + return data.isEmpty() || data == "[]" || data == "about:blank" + } } - val hasMainPage: Boolean get() = api.hasMainPage - val name: String get() = api.name - val mainUrl: String get() = api.mainUrl - val hasQuickSearch: Boolean get() = api.hasQuickSearch + val hasMainPage = api.hasMainPage + val name = api.name + val mainUrl = api.mainUrl + val hasQuickSearch = api.hasQuickSearch suspend fun load(url: String): Resource { + if(isInvalidData(url)) throw ErrorLoadingException() + return safeApiCall { api.load(api.fixUrl(url)) ?: throw ErrorLoadingException() } } suspend fun search(query: String): Resource> { + if (query.isEmpty()) + return Resource.Success(emptyList()) + return safeApiCall { return@safeApiCall (api.search(query) ?: throw ErrorLoadingException()) @@ -45,6 +52,9 @@ class APIRepository(val api: MainAPI) { } suspend fun quickSearch(query: String): Resource> { + if (query.isEmpty()) + return Resource.Success(emptyList()) + return safeApiCall { api.quickSearch(query) ?: throw ErrorLoadingException() } @@ -62,6 +72,9 @@ class APIRepository(val api: MainAPI) { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - return normalSafeApiCall { api.loadLinks(data, isCasting, subtitleCallback, callback) } ?: false + if (isInvalidData(data)) return false // this makes providers cleaner + + return normalSafeApiCall { api.loadLinks(data, isCasting, subtitleCallback, callback) } + ?: false } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt index f8927793..6d47ee72 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt @@ -28,6 +28,7 @@ import com.lagradost.cloudstream3.sortUrls import com.lagradost.cloudstream3.ui.player.RepoLinkGenerator import com.lagradost.cloudstream3.ui.player.SubtitleData import com.lagradost.cloudstream3.ui.result.ResultEpisode +import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.CastHelper.awaitLinks import com.lagradost.cloudstream3.utils.CastHelper.getMediaInfo import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject @@ -294,7 +295,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi ) val done = - JSONObject(mapper.writeValueAsString(jsonCopy)) + JSONObject(jsonCopy.toJson()) val mediaInfo = getMediaInfo( epData, diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt index ac63ed41..645757f9 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt @@ -107,7 +107,6 @@ class HomeFragment : Fragment() { } fun Context.selectHomepage(selectedApiName: String?, callback: (String) -> Unit) { - println("CURRENT $selectedApiName") val validAPIs = filterProviderByPreferredMedia().toMutableList() validAPIs.add(0, randomApi) @@ -303,9 +302,9 @@ class HomeFragment : Fragment() { super.onViewCreated(view, savedInstanceState) fixGrid() - home_change_api.setOnClickListener(apiChangeClickListener) - home_change_api_loading.setOnClickListener(apiChangeClickListener) - home_api_fab.setOnClickListener(apiChangeClickListener) + home_change_api?.setOnClickListener(apiChangeClickListener) + home_change_api_loading?.setOnClickListener(apiChangeClickListener) + home_api_fab?.setOnClickListener(apiChangeClickListener) observe(homeViewModel.apiName) { apiName -> currentApiName = apiName diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt index f5f2b5ed..da16820f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt @@ -1048,6 +1048,21 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) { return@setOnTouchListener handleMotionEvent(callView, event) } + exo_progress?.setOnTouchListener { _, event -> + // this makes the bar not disappear when sliding + when (event.action) { + MotionEvent.ACTION_DOWN -> { + currentTapIndex++ + } + MotionEvent.ACTION_MOVE -> { + currentTapIndex++ + } + MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_BUTTON_RELEASE -> { + autoHide() + } + } + return@setOnTouchListener false + } // init UI try { uiReset() diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/AppUtils.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/AppUtils.kt index cfc33d62..64010874 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/AppUtils.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/AppUtils.kt @@ -19,6 +19,7 @@ import android.os.ParcelFileDescriptor import android.provider.MediaStore import android.util.Log import androidx.appcompat.app.AppCompatActivity +import com.fasterxml.jackson.module.kotlin.readValue import com.google.android.gms.cast.framework.CastContext import com.google.android.gms.cast.framework.CastState import com.google.android.gms.common.ConnectionResult @@ -28,6 +29,7 @@ import com.lagradost.cloudstream3.MainActivity import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.mapper +import com.lagradost.cloudstream3.movieproviders.MeloMovieProvider import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.ui.result.ResultFragment import com.lagradost.cloudstream3.utils.FillerEpisodeCheck.toClassDir @@ -92,6 +94,10 @@ object AppUtils { return mapper.writeValueAsString(this) } + inline fun parseJson(value : String): T { + return mapper.readValue(value) + } + /**| S1:E2 Hello World * | Episode 2. Hello world * | Hello World diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt index f74f6320..68ca6798 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt @@ -13,6 +13,7 @@ import com.google.android.gms.common.images.WebImage import com.lagradost.cloudstream3.ui.MetadataHolder import com.lagradost.cloudstream3.ui.player.SubtitleData import com.lagradost.cloudstream3.ui.result.ResultEpisode +import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.Coroutines.main import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -107,7 +108,7 @@ object CastHelper { val index = if (startIndex == null || startIndex < 0) 0 else startIndex val mediaItem = - getMediaInfo(epData, holder, index, JSONObject(mapper.writeValueAsString(holder)), subtitles) + getMediaInfo(epData, holder, index, JSONObject(holder.toJson()), subtitles) awaitLinks( this.remoteMediaClient?.load( diff --git a/app/src/main/res/layout/home_select_mainpage.xml b/app/src/main/res/layout/home_select_mainpage.xml index 20eeac01..bb28d68f 100644 --- a/app/src/main/res/layout/home_select_mainpage.xml +++ b/app/src/main/res/layout/home_select_mainpage.xml @@ -12,6 +12,7 @@ android:nextFocusLeft="@id/apply_btt" android:id="@+id/listview1" + android:layout_marginBottom="60dp" android:minHeight="0dp" android:layout_marginTop="10dp" android:requiresFadingEdge="vertical" @@ -21,6 +22,7 @@ android:layout_rowWeight="1" />