forked from recloudstream/cloudstream
		
	fixed #461
This commit is contained in:
		
							parent
							
								
									fd6eee635f
								
							
						
					
					
						commit
						44c7d5ff8c
					
				
					 46 changed files with 307 additions and 253 deletions
				
			
		|  | @ -231,24 +231,24 @@ abstract class MainAPI { | ||||||
|     open val vpnStatus = VPNStatus.None |     open val vpnStatus = VPNStatus.None | ||||||
|     open val providerType = ProviderType.DirectProvider |     open val providerType = ProviderType.DirectProvider | ||||||
| 
 | 
 | ||||||
|     open fun getMainPage(): HomePageResponse? { |     suspend open fun getMainPage(): HomePageResponse? { | ||||||
|         throw NotImplementedError() |         throw NotImplementedError() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     open fun search(query: String): List<SearchResponse>? { |     suspend open fun search(query: String): List<SearchResponse>? { | ||||||
|         throw NotImplementedError() |         throw NotImplementedError() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     open fun quickSearch(query: String): List<SearchResponse>? { |     suspend open fun quickSearch(query: String): List<SearchResponse>? { | ||||||
|         throw NotImplementedError() |         throw NotImplementedError() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     open fun load(url: String): LoadResponse? { |     suspend open fun load(url: String): LoadResponse? { | ||||||
|         throw NotImplementedError() |         throw NotImplementedError() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /**Callback is fired once a link is found, will return true if method is executed successfully*/ |     /**Callback is fired once a link is found, will return true if method is executed successfully*/ | ||||||
|     open fun loadLinks( |     suspend open fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -85,7 +85,7 @@ class AllAnimeProvider : MainAPI() { | ||||||
|         @JsonProperty("data") val data: Data |         @JsonProperty("data") val data: Data | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): ArrayList<SearchResponse> { |     override suspend fun search(query: String): ArrayList<SearchResponse> { | ||||||
|         val link = |         val link = | ||||||
|             """$mainUrl/graphql?variables=%7B%22search%22%3A%7B%22allowAdult%22%3Afalse%2C%22query%22%3A%22$query%22%7D%2C%22limit%22%3A26%2C%22page%22%3A1%2C%22translationType%22%3A%22sub%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%229343797cc3d9e3f444e2d3b7db9a84d759b816a4d84512ea72d079f85bb96e98%22%7D%7D""" |             """$mainUrl/graphql?variables=%7B%22search%22%3A%7B%22allowAdult%22%3Afalse%2C%22query%22%3A%22$query%22%7D%2C%22limit%22%3A26%2C%22page%22%3A1%2C%22translationType%22%3A%22sub%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%229343797cc3d9e3f444e2d3b7db9a84d759b816a4d84512ea72d079f85bb96e98%22%7D%7D""" | ||||||
|         var res = app.get(link).text |         var res = app.get(link).text | ||||||
|  | @ -123,7 +123,7 @@ class AllAnimeProvider : MainAPI() { | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse? { |     override suspend fun load(url: String): LoadResponse? { | ||||||
|         val rhino = Context.enter() |         val rhino = Context.enter() | ||||||
|         rhino.initStandardObjects() |         rhino.initStandardObjects() | ||||||
|         rhino.optimizationLevel = -1 |         rhino.optimizationLevel = -1 | ||||||
|  | @ -238,7 +238,7 @@ class AllAnimeProvider : MainAPI() { | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ class AnimeFlickProvider : MainAPI() { | ||||||
|         TvType.ONA |         TvType.ONA | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): ArrayList<SearchResponse> { |     override suspend fun search(query: String): ArrayList<SearchResponse> { | ||||||
|         val link = "https://animeflick.net/search.php?search=$query" |         val link = "https://animeflick.net/search.php?search=$query" | ||||||
|         val html = app.get(link).text |         val html = app.get(link).text | ||||||
|         val doc = Jsoup.parse(html) |         val doc = Jsoup.parse(html) | ||||||
|  | @ -48,7 +48,7 @@ class AnimeFlickProvider : MainAPI() { | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val html = app.get(url).text |         val html = app.get(url).text | ||||||
|         val doc = Jsoup.parse(html) |         val doc = Jsoup.parse(html) | ||||||
| 
 | 
 | ||||||
|  | @ -79,7 +79,7 @@ class AnimeFlickProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ class AnimePaheProvider : MainAPI() { | ||||||
|         TvType.ONA |         TvType.ONA | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         data class Data( |         data class Data( | ||||||
|             @JsonProperty("id") val id: Int, |             @JsonProperty("id") val id: Int, | ||||||
|             @JsonProperty("anime_id") val animeId: Int, |             @JsonProperty("anime_id") val animeId: Int, | ||||||
|  | @ -139,7 +139,7 @@ class AnimePaheProvider : MainAPI() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): ArrayList<SearchResponse> { |     override suspend fun search(query: String): ArrayList<SearchResponse> { | ||||||
|         val url = "$mainUrl/api?m=search&l=8&q=$query" |         val url = "$mainUrl/api?m=search&l=8&q=$query" | ||||||
|         val headers = mapOf("referer" to "$mainUrl/") |         val headers = mapOf("referer" to "$mainUrl/") | ||||||
| 
 | 
 | ||||||
|  | @ -242,7 +242,7 @@ class AnimePaheProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse? { |     override suspend fun load(url: String): LoadResponse? { | ||||||
|         return normalSafeApiCall { |         return normalSafeApiCall { | ||||||
| 
 | 
 | ||||||
|             val regex = Regex("""a/(\d+)\?slug=(.+)""") |             val regex = Regex("""a/(\d+)\?slug=(.+)""") | ||||||
|  | @ -541,7 +541,7 @@ class AnimePaheProvider : MainAPI() { | ||||||
|         return qualities |         return qualities | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -92,7 +92,7 @@ class DubbedAnimeProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val trendingUrl = "$mainUrl/xz/trending.php?_=$unixTimeMS" |         val trendingUrl = "$mainUrl/xz/trending.php?_=$unixTimeMS" | ||||||
|         val lastEpisodeUrl = "$mainUrl/xz/epgrid.php?p=1&_=$unixTimeMS" |         val lastEpisodeUrl = "$mainUrl/xz/epgrid.php?p=1&_=$unixTimeMS" | ||||||
|         val recentlyAddedUrl = "$mainUrl/xz/gridgrabrecent.php?p=1&_=$unixTimeMS" |         val recentlyAddedUrl = "$mainUrl/xz/gridgrabrecent.php?p=1&_=$unixTimeMS" | ||||||
|  | @ -126,7 +126,7 @@ class DubbedAnimeProvider : MainAPI() { | ||||||
|         return href.replace("$mainUrl/", "") |         return href.replace("$mainUrl/", "") | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun quickSearch(query: String): List<SearchResponse> { |     override suspend fun quickSearch(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/xz/searchgrid.php?p=1&limit=12&s=$query&_=$unixTime" |         val url = "$mainUrl/xz/searchgrid.php?p=1&limit=12&s=$query&_=$unixTime" | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|  | @ -158,7 +158,7 @@ class DubbedAnimeProvider : MainAPI() { | ||||||
|         return returnValue |         return returnValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/search/$query" |         val url = "$mainUrl/search/$query" | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|  | @ -193,7 +193,7 @@ class DubbedAnimeProvider : MainAPI() { | ||||||
|         return returnValue |         return returnValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  | @ -230,7 +230,7 @@ class DubbedAnimeProvider : MainAPI() { | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         if (getIsMovie(url)) { |         if (getIsMovie(url)) { | ||||||
|             val realSlug = url.replace("movies/", "") |             val realSlug = url.replace("movies/", "") | ||||||
|             val episode = getAnimeEpisode(realSlug, true) |             val episode = getAnimeEpisode(realSlug, true) | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ class GogoanimeProvider : MainAPI() { | ||||||
|         TvType.ONA |         TvType.ONA | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val headers = mapOf( |         val headers = mapOf( | ||||||
|             "authority" to "ajax.gogo-load.com", |             "authority" to "ajax.gogo-load.com", | ||||||
|             "sec-ch-ua" to "\"Google Chrome\";v=\"89\", \"Chromium\";v=\"89\", \";Not A Brand\";v=\"99\"", |             "sec-ch-ua" to "\"Google Chrome\";v=\"89\", \"Chromium\";v=\"89\", \";Not A Brand\";v=\"99\"", | ||||||
|  | @ -95,7 +95,7 @@ class GogoanimeProvider : MainAPI() { | ||||||
|         return HomePageResponse(items) |         return HomePageResponse(items) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): ArrayList<SearchResponse> { |     override suspend fun search(query: String): ArrayList<SearchResponse> { | ||||||
|         val link = "$mainUrl/search.html?keyword=$query" |         val link = "$mainUrl/search.html?keyword=$query" | ||||||
|         val html = app.get(link).text |         val html = app.get(link).text | ||||||
|         val doc = Jsoup.parse(html) |         val doc = Jsoup.parse(html) | ||||||
|  | @ -129,7 +129,7 @@ class GogoanimeProvider : MainAPI() { | ||||||
|         return uri |         return uri | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val link = getProperAnimeLink(url) |         val link = getProperAnimeLink(url) | ||||||
|         val episodeloadApi = "https://ajax.gogo-load.com/ajax/load-list-episode" |         val episodeloadApi = "https://ajax.gogo-load.com/ajax/load-list-episode" | ||||||
|         val html = app.get(link).text |         val html = app.get(link).text | ||||||
|  | @ -232,7 +232,7 @@ class GogoanimeProvider : MainAPI() { | ||||||
|             } |             } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ class KawaiifuProvider : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie, TvType.ONA) |     override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie, TvType.ONA) | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val items = ArrayList<HomePageList>() |         val items = ArrayList<HomePageList>() | ||||||
|         val resp = app.get(mainUrl).text |         val resp = app.get(mainUrl).text | ||||||
| 
 | 
 | ||||||
|  | @ -58,7 +58,7 @@ class KawaiifuProvider : MainAPI() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): ArrayList<SearchResponse> { |     override suspend fun search(query: String): ArrayList<SearchResponse> { | ||||||
|         val link = "$mainUrl/search-movie?keyword=${query}" |         val link = "$mainUrl/search-movie?keyword=${query}" | ||||||
|         val html = app.get(link).text |         val html = app.get(link).text | ||||||
|         val soup = Jsoup.parse(html) |         val soup = Jsoup.parse(html) | ||||||
|  | @ -80,7 +80,7 @@ class KawaiifuProvider : MainAPI() { | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val html = app.get(url).text |         val html = app.get(url).text | ||||||
|         val soup = Jsoup.parse(html) |         val soup = Jsoup.parse(html) | ||||||
| 
 | 
 | ||||||
|  | @ -110,7 +110,7 @@ class KawaiifuProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -45,7 +45,7 @@ class TenshiProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     }*/ |     }*/ | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val items = ArrayList<HomePageList>() |         val items = ArrayList<HomePageList>() | ||||||
|         val soup = app.get(mainUrl, interceptor = ddosGuardKiller).document |         val soup = app.get(mainUrl, interceptor = ddosGuardKiller).document | ||||||
|         for (section in soup.select("#content > section")) { |         for (section in soup.select("#content > section")) { | ||||||
|  | @ -152,7 +152,7 @@ class TenshiProvider : MainAPI() { | ||||||
| //        @JsonProperty("cen") var cen : String | //        @JsonProperty("cen") var cen : String | ||||||
| //    ) | //    ) | ||||||
| 
 | 
 | ||||||
| //    override fun quickSearch(query: String): ArrayList<SearchResponse>? { | //    override suspend fun quickSearch(query: String): ArrayList<SearchResponse>? { | ||||||
| //        if (!autoLoadToken()) return quickSearch(query) | //        if (!autoLoadToken()) return quickSearch(query) | ||||||
| //        val url = "$mainUrl/anime/search" | //        val url = "$mainUrl/anime/search" | ||||||
| //        val response = khttp.post( | //        val response = khttp.post( | ||||||
|  | @ -192,7 +192,7 @@ class TenshiProvider : MainAPI() { | ||||||
| //        return returnValue | //        return returnValue | ||||||
| //    } | //    } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): ArrayList<SearchResponse> { |     override suspend fun search(query: String): ArrayList<SearchResponse> { | ||||||
|         val url = "$mainUrl/anime" |         val url = "$mainUrl/anime" | ||||||
|         var document = app.get( |         var document = app.get( | ||||||
|             url, |             url, | ||||||
|  | @ -220,7 +220,7 @@ class TenshiProvider : MainAPI() { | ||||||
|         return ArrayList(returnValue) |         return ArrayList(returnValue) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         var document = app.get( |         var document = app.get( | ||||||
|             url, |             url, | ||||||
|             cookies = mapOf("loop-view" to "thumb"), |             cookies = mapOf("loop-view" to "thumb"), | ||||||
|  | @ -292,7 +292,7 @@ class TenshiProvider : MainAPI() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|         TvType.TvSeries |         TvType.TvSeries | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "https://www.wcostream.com/search" |         val url = "https://www.wcostream.com/search" | ||||||
| 
 | 
 | ||||||
|         var response = |         var response = | ||||||
|  | @ -97,7 +97,7 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|         return returnValue |         return returnValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val isMovie = !url.contains("/anime/") |         val isMovie = !url.contains("/anime/") | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|  | @ -183,7 +183,7 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|         val server: String, |         val server: String, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ class WcoProvider : MainAPI() { | ||||||
|         TvType.ONA |         TvType.ONA | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val urls = listOf( |         val urls = listOf( | ||||||
|             Pair("$mainUrl/ajax/list/recently_updated?type=tv", "Recently Updated Anime"), |             Pair("$mainUrl/ajax/list/recently_updated?type=tv", "Recently Updated Anime"), | ||||||
|             Pair("$mainUrl/ajax/list/recently_updated?type=movie", "Recently Updated Movies"), |             Pair("$mainUrl/ajax/list/recently_updated?type=movie", "Recently Updated Movies"), | ||||||
|  | @ -108,7 +108,7 @@ class WcoProvider : MainAPI() { | ||||||
|         return returnValue |         return returnValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/search" |         val url = "$mainUrl/search" | ||||||
|         val response = |         val response = | ||||||
|             app.get(url, params = mapOf("keyword" to query)) |             app.get(url, params = mapOf("keyword" to query)) | ||||||
|  | @ -128,7 +128,7 @@ class WcoProvider : MainAPI() { | ||||||
|         return returnValue |         return returnValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun quickSearch(query: String): List<SearchResponse> { |     override suspend fun quickSearch(query: String): List<SearchResponse> { | ||||||
|         val returnValue: ArrayList<SearchResponse> = ArrayList() |         val returnValue: ArrayList<SearchResponse> = ArrayList() | ||||||
| 
 | 
 | ||||||
|         val response = JSONObject( |         val response = JSONObject( | ||||||
|  | @ -170,7 +170,7 @@ class WcoProvider : MainAPI() { | ||||||
|         return returnValue |         return returnValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val response = app.get(url, timeout = 120).text |         val response = app.get(url, timeout = 120).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
| 
 | 
 | ||||||
|  | @ -216,7 +216,7 @@ class WcoProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -69,7 +69,7 @@ class ZoroProvider : MainAPI() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val html = app.get("$mainUrl/home").text |         val html = app.get("$mainUrl/home").text | ||||||
|         val document = Jsoup.parse(html) |         val document = Jsoup.parse(html) | ||||||
| 
 | 
 | ||||||
|  | @ -99,7 +99,7 @@ class ZoroProvider : MainAPI() { | ||||||
|         @JsonProperty("html") val html: String |         @JsonProperty("html") val html: String | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| //    override fun quickSearch(query: String): List<SearchResponse> { | //    override suspend fun quickSearch(query: String): List<SearchResponse> { | ||||||
| //        val url = "$mainUrl/ajax/search/suggest?keyword=${query}" | //        val url = "$mainUrl/ajax/search/suggest?keyword=${query}" | ||||||
| //        val html = mapper.readValue<Response>(khttp.get(url).text).html | //        val html = mapper.readValue<Response>(khttp.get(url).text).html | ||||||
| //        val document = Jsoup.parse(html) | //        val document = Jsoup.parse(html) | ||||||
|  | @ -126,7 +126,7 @@ class ZoroProvider : MainAPI() { | ||||||
| //        } | //        } | ||||||
| //    } | //    } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val link = "$mainUrl/search?keyword=$query" |         val link = "$mainUrl/search?keyword=$query" | ||||||
|         val html = app.get(link).text |         val html = app.get(link).text | ||||||
|         val document = Jsoup.parse(html) |         val document = Jsoup.parse(html) | ||||||
|  | @ -172,7 +172,7 @@ class ZoroProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val html = app.get(url).text |         val html = app.get(url).text | ||||||
|         val document = Jsoup.parse(html) |         val document = Jsoup.parse(html) | ||||||
| 
 | 
 | ||||||
|  | @ -274,7 +274,7 @@ class ZoroProvider : MainAPI() { | ||||||
|         @JsonProperty("link") val link: String |         @JsonProperty("link") val link: String | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -161,7 +161,7 @@ open class TmdbProvider : MainAPI() { | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
| 
 | 
 | ||||||
|         // SAME AS DISCOVER IT SEEMS |         // SAME AS DISCOVER IT SEEMS | ||||||
| //        val popularSeries = tmdb.tvService().popular(1, "en-US").execute().body()?.results?.map { | //        val popularSeries = tmdb.tvService().popular(1, "en-US").execute().body()?.results?.map { | ||||||
|  | @ -220,7 +220,7 @@ open class TmdbProvider : MainAPI() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Possible to add recommendations and such here. |     // Possible to add recommendations and such here. | ||||||
|     override fun load(url: String): LoadResponse? { |     override suspend fun load(url: String): LoadResponse? { | ||||||
|         // https://www.themoviedb.org/movie/7445-brothers |         // https://www.themoviedb.org/movie/7445-brothers | ||||||
|         // https://www.themoviedb.org/tv/71914-the-wheel-of-time |         // https://www.themoviedb.org/tv/71914-the-wheel-of-time | ||||||
| 
 | 
 | ||||||
|  | @ -262,7 +262,7 @@ open class TmdbProvider : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse>? { |     override suspend fun search(query: String): List<SearchResponse>? { | ||||||
|         return tmdb.searchService().multi(query, 1, "en-Us", "US", true).execute() |         return tmdb.searchService().multi(query, 1, "en-Us", "US", true).execute() | ||||||
|             .body()?.results?.mapNotNull { |             .body()?.results?.mapNotNull { | ||||||
|                 it.movie?.toSearchResponse() ?: it.tvShow?.toSearchResponse() |                 it.movie?.toSearchResponse() ?: it.tvShow?.toSearchResponse() | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ class AkwamProvider : MainAPI() { | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         // Title, Url |         // Title, Url | ||||||
|         val moviesUrl = listOf( |         val moviesUrl = listOf( | ||||||
|             "Movies" to "$mainUrl/movies", |             "Movies" to "$mainUrl/movies", | ||||||
|  | @ -51,7 +51,7 @@ class AkwamProvider : MainAPI() { | ||||||
|         return HomePageResponse(pages) |         return HomePageResponse(pages) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/search?q=$query" |         val url = "$mainUrl/search?q=$query" | ||||||
|         val doc = app.get(url).document |         val doc = app.get(url).document | ||||||
|         return doc.select("div.col-lg-auto").mapNotNull { |         return doc.select("div.col-lg-auto").mapNotNull { | ||||||
|  | @ -80,7 +80,7 @@ class AkwamProvider : MainAPI() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val doc = app.get(url).document |         val doc = app.get(url).document | ||||||
|         val isMovie = url.contains("/movie/") |         val isMovie = url.contains("/movie/") | ||||||
|         val title = doc.select("h1.entry-title").text() |         val title = doc.select("h1.entry-title").text() | ||||||
|  | @ -164,7 +164,7 @@ class AkwamProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ class AllMoviesForYouProvider : MainAPI() { | ||||||
|         TvType.TvSeries |         TvType.TvSeries | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/?s=$query" |         val url = "$mainUrl/?s=$query" | ||||||
|         val document = app.get(url).document |         val document = app.get(url).document | ||||||
| 
 | 
 | ||||||
|  | @ -76,7 +76,7 @@ class AllMoviesForYouProvider : MainAPI() { | ||||||
|         return if (list.isEmpty()) null else list |         return if (list.isEmpty()) null else list | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val type = getType(url) |         val type = getType(url) | ||||||
| 
 | 
 | ||||||
|         val document = app.get(url).document |         val document = app.get(url).document | ||||||
|  | @ -162,7 +162,7 @@ class AllMoviesForYouProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -112,7 +112,7 @@ class AsiaFlixProvider : MainAPI() { | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val headers = mapOf("X-Requested-By" to "asiaflix-web") |         val headers = mapOf("X-Requested-By" to "asiaflix-web") | ||||||
|         val response = app.get("$apiUrl/dashboard", headers = headers).text |         val response = app.get("$apiUrl/dashboard", headers = headers).text | ||||||
| 
 | 
 | ||||||
|  | @ -138,7 +138,7 @@ class AsiaFlixProvider : MainAPI() { | ||||||
|         @JsonProperty("url") val url: String?, |         @JsonProperty("url") val url: String?, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  | @ -162,14 +162,14 @@ class AsiaFlixProvider : MainAPI() { | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse>? { |     override suspend fun search(query: String): List<SearchResponse>? { | ||||||
|         val headers = mapOf("X-Requested-By" to "asiaflix-web") |         val headers = mapOf("X-Requested-By" to "asiaflix-web") | ||||||
|         val url = "$apiUrl/drama/search?q=$query" |         val url = "$apiUrl/drama/search?q=$query" | ||||||
|         val response = app.get(url, headers = headers).text |         val response = app.get(url, headers = headers).text | ||||||
|         return mapper.readValue<List<Data>?>(response)?.map { it.toSearchResponse() } |         return mapper.readValue<List<Data>?>(response)?.map { it.toSearchResponse() } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val headers = mapOf("X-Requested-By" to "asiaflix-web") |         val headers = mapOf("X-Requested-By" to "asiaflix-web") | ||||||
|         val requestUrl = "$apiUrl/drama?id=${url.split("/").lastOrNull()}" |         val requestUrl = "$apiUrl/drama?id=${url.split("/").lastOrNull()}" | ||||||
|         val response = app.get(requestUrl, headers = headers).text |         val response = app.get(requestUrl, headers = headers).text | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ class DramaSeeProvider : MainAPI() { | ||||||
|     override val hasDownloadSupport = true |     override val hasDownloadSupport = true | ||||||
|     override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) |     override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val headers = mapOf("X-Requested-By" to "dramasee.net") |         val headers = mapOf("X-Requested-By" to "dramasee.net") | ||||||
|         val document = app.get(mainUrl, headers = headers).document |         val document = app.get(mainUrl, headers = headers).document | ||||||
|         val mainbody = document.getElementsByTag("body") |         val mainbody = document.getElementsByTag("body") | ||||||
|  | @ -50,7 +50,7 @@ class DramaSeeProvider : MainAPI() { | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/search?q=$query" |         val url = "$mainUrl/search?q=$query" | ||||||
|         val html = app.get(url).document |         val html = app.get(url).document | ||||||
|         val document = html.getElementsByTag("body") |         val document = html.getElementsByTag("body") | ||||||
|  | @ -78,7 +78,7 @@ class DramaSeeProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val doc = app.get(url).document |         val doc = app.get(url).document | ||||||
|         val body = doc.getElementsByTag("body") |         val body = doc.getElementsByTag("body") | ||||||
|         val inner = body?.select("div.series-info") |         val inner = body?.select("div.series-info") | ||||||
|  | @ -149,7 +149,7 @@ class DramaSeeProvider : MainAPI() { | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ class FilmanProvider : MainAPI() { | ||||||
|         TvType.TvSeries |         TvType.TvSeries | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val response = app.get(mainUrl).text |         val response = app.get(mainUrl).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|         val lists = document.select(".item-list,.series-list") |         val lists = document.select(".item-list,.series-list") | ||||||
|  | @ -54,7 +54,7 @@ class FilmanProvider : MainAPI() { | ||||||
|         return HomePageResponse(categories) |         return HomePageResponse(categories) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/wyszukiwarka?phrase=$query" |         val url = "$mainUrl/wyszukiwarka?phrase=$query" | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|  | @ -79,7 +79,7 @@ class FilmanProvider : MainAPI() { | ||||||
|         return getVideos(TvType.Movie, movies) + getVideos(TvType.TvSeries, series) |         return getVideos(TvType.Movie, movies) + getVideos(TvType.TvSeries, series) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|         var title = document.select("span[itemprop=title]").text() |         var title = document.select("span[itemprop=title]").text() | ||||||
|  | @ -109,7 +109,7 @@ class FilmanProvider : MainAPI() { | ||||||
|         return TvSeriesLoadResponse(title, url, name, TvType.TvSeries, episodes, posterUrl, year, plot) |         return TvSeriesLoadResponse(title, url, name, TvType.TvSeries, episodes, posterUrl, year, plot) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ class HDMProvider : MainAPI() { | ||||||
|         TvType.Movie, |         TvType.Movie, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/search/$query" |         val url = "$mainUrl/search/$query" | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|  | @ -32,7 +32,7 @@ class HDMProvider : MainAPI() { | ||||||
|         return returnValue |         return returnValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  | @ -55,7 +55,7 @@ class HDMProvider : MainAPI() { | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse? { |     override suspend fun load(url: String): LoadResponse? { | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|         val title = document.selectFirst("h2.movieTitle")?.text() ?: throw ErrorLoadingException("No Data Found") |         val title = document.selectFirst("h2.movieTitle")?.text() ?: throw ErrorLoadingException("No Data Found") | ||||||
|  | @ -71,7 +71,7 @@ class HDMProvider : MainAPI() { | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val html = app.get("$mainUrl", timeout = 25).text |         val html = app.get("$mainUrl", timeout = 25).text | ||||||
|         val document = Jsoup.parse(html) |         val document = Jsoup.parse(html) | ||||||
|         val all = ArrayList<HomePageList>() |         val all = ArrayList<HomePageList>() | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ class IHaveNoTvProvider : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     override val supportedTypes = setOf(TvType.Documentary) |     override val supportedTypes = setOf(TvType.Documentary) | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         // Uhh, I am too lazy to scrape the "latest documentaries" and "recommended documentaries", |         // Uhh, I am too lazy to scrape the "latest documentaries" and "recommended documentaries", | ||||||
|         // so I am just scraping 3 random categories |         // so I am just scraping 3 random categories | ||||||
|         val allCategories = listOf( |         val allCategories = listOf( | ||||||
|  | @ -67,7 +67,7 @@ class IHaveNoTvProvider : MainAPI() { | ||||||
|         return HomePageResponse(items) |         return HomePageResponse(items) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): ArrayList<SearchResponse> { |     override suspend fun search(query: String): ArrayList<SearchResponse> { | ||||||
|         val url = """$mainUrl/search/${URLEncoder.encode(query, "UTF-8")}""" |         val url = """$mainUrl/search/${URLEncoder.encode(query, "UTF-8")}""" | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val soup = Jsoup.parse(response) |         val soup = Jsoup.parse(response) | ||||||
|  | @ -101,7 +101,7 @@ class IHaveNoTvProvider : MainAPI() { | ||||||
|         return ArrayList(searchResults.values) |         return ArrayList(searchResults.values) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val isSeries = url.contains("/series/") |         val isSeries = url.contains("/series/") | ||||||
|         val html = app.get(url).text |         val html = app.get(url).text | ||||||
|         val soup = Jsoup.parse(html) |         val soup = Jsoup.parse(html) | ||||||
|  | @ -190,7 +190,7 @@ class IHaveNoTvProvider : MainAPI() { | ||||||
|         ) else (episodes?.first() as MovieLoadResponse) |         ) else (episodes?.first() as MovieLoadResponse) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ class KdramaHoodProvider : MainAPI() { | ||||||
|     override val hasDownloadSupport = true |     override val hasDownloadSupport = true | ||||||
|     override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) |     override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val doc = app.get("$mainUrl/home2").document |         val doc = app.get("$mainUrl/home2").document | ||||||
|         val home = ArrayList<HomePageList>() |         val home = ArrayList<HomePageList>() | ||||||
| 
 | 
 | ||||||
|  | @ -59,7 +59,7 @@ class KdramaHoodProvider : MainAPI() { | ||||||
|         return HomePageResponse(home.filter { it.list.isNotEmpty() }) |         return HomePageResponse(home.filter { it.list.isNotEmpty() }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/?s=$query" |         val url = "$mainUrl/?s=$query" | ||||||
|         val html = app.get(url).document |         val html = app.get(url).document | ||||||
|         val document = html.getElementsByTag("body") |         val document = html.getElementsByTag("body") | ||||||
|  | @ -87,7 +87,7 @@ class KdramaHoodProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val doc = app.get(url).document |         val doc = app.get(url).document | ||||||
|         val inner = doc.selectFirst("div.central") |         val inner = doc.selectFirst("div.central") | ||||||
| 
 | 
 | ||||||
|  | @ -180,7 +180,7 @@ class KdramaHoodProvider : MainAPI() { | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -64,7 +64,7 @@ class LookMovieProvider : MainAPI() { | ||||||
|         @JsonProperty("season") var season: String, |         @JsonProperty("season") var season: String, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun quickSearch(query: String): List<SearchResponse> { |     override suspend fun quickSearch(query: String): List<SearchResponse> { | ||||||
|         val movieUrl = "$mainUrl/api/v1/movies/search/?q=$query" |         val movieUrl = "$mainUrl/api/v1/movies/search/?q=$query" | ||||||
|         val movieResponse = app.get(movieUrl).text |         val movieResponse = app.get(movieUrl).text | ||||||
|         val movies = mapper.readValue<LookMovieSearchResultRoot>(movieResponse).result |         val movies = mapper.readValue<LookMovieSearchResultRoot>(movieResponse).result | ||||||
|  | @ -109,7 +109,7 @@ class LookMovieProvider : MainAPI() { | ||||||
|         return returnValue |         return returnValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         fun search(query: String, isMovie: Boolean): ArrayList<SearchResponse> { |         fun search(query: String, isMovie: Boolean): ArrayList<SearchResponse> { | ||||||
|             val url = "$mainUrl/${if (isMovie) "movies" else "shows"}/search/?q=$query" |             val url = "$mainUrl/${if (isMovie) "movies" else "shows"}/search/?q=$query" | ||||||
|             val response = app.get(url).text |             val response = app.get(url).text | ||||||
|  | @ -174,7 +174,7 @@ class LookMovieProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  | @ -198,7 +198,7 @@ class LookMovieProvider : MainAPI() { | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse? { |     override suspend fun load(url: String): LoadResponse? { | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|         val isMovie = url.contains("/movies/") |         val isMovie = url.contains("/movies/") | ||||||
|  |  | ||||||
|  | @ -28,11 +28,11 @@ class MeloMovieProvider : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     data class MeloMovieLink(val name: String, val link: String) |     data class MeloMovieLink(val name: String, val link: String) | ||||||
| 
 | 
 | ||||||
|     override fun quickSearch(query: String): List<SearchResponse> { |     override suspend fun quickSearch(query: String): List<SearchResponse> { | ||||||
|         return search(query) |         return search(query) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/movie/search/?name=$query" |         val url = "$mainUrl/movie/search/?name=$query" | ||||||
|         val returnValue: ArrayList<SearchResponse> = ArrayList() |         val returnValue: ArrayList<SearchResponse> = ArrayList() | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|  | @ -98,7 +98,7 @@ class MeloMovieProvider : MainAPI() { | ||||||
|         return parsed.toJson() |         return parsed.toJson() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  | @ -111,7 +111,7 @@ class MeloMovieProvider : MainAPI() { | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse? { |     override suspend fun load(url: String): LoadResponse? { | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
| 
 | 
 | ||||||
|         //backdrop = imgurl |         //backdrop = imgurl | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ class PelisplusHDProvider:MainAPI() { | ||||||
|         TvType.TvSeries, |         TvType.TvSeries, | ||||||
|         TvType.Anime, |         TvType.Anime, | ||||||
|     ) |     ) | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val items = ArrayList<HomePageList>() |         val items = ArrayList<HomePageList>() | ||||||
|         val urls = listOf( |         val urls = listOf( | ||||||
|             Pair("$mainUrl/peliculas", "Peliculas"), |             Pair("$mainUrl/peliculas", "Peliculas"), | ||||||
|  | @ -55,7 +55,7 @@ class PelisplusHDProvider:MainAPI() { | ||||||
|         return HomePageResponse(items) |         return HomePageResponse(items) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "https://pelisplushd.net/search?s=${query}" |         val url = "https://pelisplushd.net/search?s=${query}" | ||||||
|         val html = app.get(url).text |         val html = app.get(url).text | ||||||
|         val document = Jsoup.parse(html) |         val document = Jsoup.parse(html) | ||||||
|  | @ -89,7 +89,7 @@ class PelisplusHDProvider:MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse? { |     override suspend fun load(url: String): LoadResponse? { | ||||||
|         val html = app.get(url).text |         val html = app.get(url).text | ||||||
|         val soup = Jsoup.parse(html) |         val soup = Jsoup.parse(html) | ||||||
| 
 | 
 | ||||||
|  | @ -146,7 +146,7 @@ class PelisplusHDProvider:MainAPI() { | ||||||
|             else -> null |             else -> null | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ open class PelisplusProviderTemplate : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     // Searching returns a SearchResponse, which can be one of the following: AnimeSearchResponse, MovieSearchResponse, TorrentSearchResponse, TvSeriesSearchResponse |     // Searching returns a SearchResponse, which can be one of the following: AnimeSearchResponse, MovieSearchResponse, TorrentSearchResponse, TvSeriesSearchResponse | ||||||
|     // Each of the classes requires some different data, but always has some critical things like name, poster and url. |     // Each of the classes requires some different data, but always has some critical things like name, poster and url. | ||||||
|     override fun search(query: String): ArrayList<SearchResponse> { |     override suspend fun search(query: String): ArrayList<SearchResponse> { | ||||||
|         // Simply looking at devtools network is enough to spot a request like: |         // Simply looking at devtools network is enough to spot a request like: | ||||||
|         // https://vidembed.cc/search.html?keyword=neverland where neverland is the query, can be written as below. |         // https://vidembed.cc/search.html?keyword=neverland where neverland is the query, can be written as below. | ||||||
|         val link = "$mainUrl/search.html?keyword=$query" |         val link = "$mainUrl/search.html?keyword=$query" | ||||||
|  | @ -68,7 +68,7 @@ open class PelisplusProviderTemplate : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     // Load, like the name suggests loads the info page, where all the episodes and data usually is. |     // Load, like the name suggests loads the info page, where all the episodes and data usually is. | ||||||
|     // Like search you should return either of: AnimeLoadResponse, MovieLoadResponse, TorrentLoadResponse, TvSeriesLoadResponse. |     // Like search you should return either of: AnimeLoadResponse, MovieLoadResponse, TorrentLoadResponse, TvSeriesLoadResponse. | ||||||
|     override fun load(url: String): LoadResponse? { |     override suspend fun load(url: String): LoadResponse? { | ||||||
|         // Gets the url returned from searching. |         // Gets the url returned from searching. | ||||||
|         val html = app.get(url).text |         val html = app.get(url).text | ||||||
|         val soup = Jsoup.parse(html) |         val soup = Jsoup.parse(html) | ||||||
|  | @ -147,7 +147,7 @@ open class PelisplusProviderTemplate : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     // This loads the homepage, which is basically a collection of search results with labels. |     // This loads the homepage, which is basically a collection of search results with labels. | ||||||
|     // Optional function, but make sure to enable hasMainPage if you program this. |     // Optional function, but make sure to enable hasMainPage if you program this. | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val urls = homePageUrlList |         val urls = homePageUrlList | ||||||
|         val homePageList = ArrayList<HomePageList>() |         val homePageList = ArrayList<HomePageList>() | ||||||
|         // .pmap {} is used to fetch the different pages in parallel |         // .pmap {} is used to fetch the different pages in parallel | ||||||
|  | @ -201,7 +201,7 @@ open class PelisplusProviderTemplate : MainAPI() { | ||||||
|     // loadLinks gets the raw .mp4 or .m3u8 urls from the data parameter in the episodes class generated in load() |     // loadLinks gets the raw .mp4 or .m3u8 urls from the data parameter in the episodes class generated in load() | ||||||
|     // See TvSeriesEpisode(...) in this provider. |     // See TvSeriesEpisode(...) in this provider. | ||||||
|     // The data are usually links, but can be any other string to help aid loading the links. |     // The data are usually links, but can be any other string to help aid loading the links. | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         // These callbacks are functions you should call when you get a link to a subtitle file or media file. |         // These callbacks are functions you should call when you get a link to a subtitle file or media file. | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ class PinoyHDXyzProvider : MainAPI() { | ||||||
|     override val hasQuickSearch = false |     override val hasQuickSearch = false | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val all = ArrayList<HomePageList>() |         val all = ArrayList<HomePageList>() | ||||||
|         val document = app.get(mainUrl, referer = mainUrl).document |         val document = app.get(mainUrl, referer = mainUrl).document | ||||||
|         val mainbody = document.getElementsByTag("body") |         val mainbody = document.getElementsByTag("body") | ||||||
|  | @ -65,7 +65,7 @@ class PinoyHDXyzProvider : MainAPI() { | ||||||
|         return HomePageResponse(all) |         return HomePageResponse(all) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/search/?q=${query.replace(" ", "+")}" |         val url = "$mainUrl/search/?q=${query.replace(" ", "+")}" | ||||||
|         val document = app.get(url).document.select("div.portfolio-thumb") |         val document = app.get(url).document.select("div.portfolio-thumb") | ||||||
|         return document?.mapNotNull { |         return document?.mapNotNull { | ||||||
|  | @ -88,7 +88,7 @@ class PinoyHDXyzProvider : MainAPI() { | ||||||
|         }?.distinctBy { c -> c.url } ?: listOf() |         }?.distinctBy { c -> c.url } ?: listOf() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val doc = app.get(url).document |         val doc = app.get(url).document | ||||||
|         val body = doc.getElementsByTag("body") |         val body = doc.getElementsByTag("body") | ||||||
|         val inner = body?.select("div.info") |         val inner = body?.select("div.info") | ||||||
|  | @ -203,7 +203,7 @@ class PinoyHDXyzProvider : MainAPI() { | ||||||
|         return MovieLoadResponse(title, url, this.name, tvtype, streamLinks, poster, year, descript, null, null) |         return MovieLoadResponse(title, url, this.name, tvtype, streamLinks, poster, year, descript, null, null) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ class PinoyMoviePediaProvider : MainAPI() { | ||||||
|     override val hasMainPage = true |     override val hasMainPage = true | ||||||
|     override val hasQuickSearch = false |     override val hasQuickSearch = false | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val all = ArrayList<HomePageList>() |         val all = ArrayList<HomePageList>() | ||||||
|         val document = app.get(mainUrl).document |         val document = app.get(mainUrl).document | ||||||
|         val mainbody = document.getElementsByTag("body") |         val mainbody = document.getElementsByTag("body") | ||||||
|  | @ -72,7 +72,7 @@ class PinoyMoviePediaProvider : MainAPI() { | ||||||
|         return HomePageResponse(all.filter { a -> a.list.isNotEmpty() }) |         return HomePageResponse(all.filter { a -> a.list.isNotEmpty() }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/?s=${query}" |         val url = "$mainUrl/?s=${query}" | ||||||
|         val document = app.get(url).document.selectFirst("div.search-page") |         val document = app.get(url).document.selectFirst("div.search-page") | ||||||
|             ?.select("div.result-item") |             ?.select("div.result-item") | ||||||
|  | @ -97,7 +97,7 @@ class PinoyMoviePediaProvider : MainAPI() { | ||||||
|         }?.distinctBy { c -> c.url } ?: listOf() |         }?.distinctBy { c -> c.url } ?: listOf() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val doc = app.get(url).document |         val doc = app.get(url).document | ||||||
|         val body = doc.getElementsByTag("body") |         val body = doc.getElementsByTag("body") | ||||||
|         val inner = body?.select("div.sheader") |         val inner = body?.select("div.sheader") | ||||||
|  | @ -171,7 +171,7 @@ class PinoyMoviePediaProvider : MainAPI() { | ||||||
|         return MovieLoadResponse(title, url, this.name, TvType.Movie, streamlinks, poster, year, descript, null, null) |         return MovieLoadResponse(title, url, this.name, TvType.Movie, streamlinks, poster, year, descript, null, null) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -58,7 +58,7 @@ class PinoyMoviesEsProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|         return all |         return all | ||||||
|     } |     } | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val all = ArrayList<HomePageList>() |         val all = ArrayList<HomePageList>() | ||||||
|         val html = app.get(mainUrl).text |         val html = app.get(mainUrl).text | ||||||
|         val document = Jsoup.parse(html) |         val document = Jsoup.parse(html) | ||||||
|  | @ -87,7 +87,7 @@ class PinoyMoviesEsProvider : MainAPI() { | ||||||
|         return HomePageResponse(all) |         return HomePageResponse(all) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/?s=${query}" |         val url = "$mainUrl/?s=${query}" | ||||||
|         val html = app.get(url, interceptor = DdosGuardKiller(true)).text |         val html = app.get(url, interceptor = DdosGuardKiller(true)).text | ||||||
|         //Log.i(this.name, "Result => (html) ${Jsoup.parse(html).getElementsByTag("body")}") |         //Log.i(this.name, "Result => (html) ${Jsoup.parse(html).getElementsByTag("body")}") | ||||||
|  | @ -115,7 +115,7 @@ class PinoyMoviesEsProvider : MainAPI() { | ||||||
|         return listOf() |         return listOf() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val doc = Jsoup.parse(response) |         val doc = Jsoup.parse(response) | ||||||
|         val body = doc.getElementsByTag("body") |         val body = doc.getElementsByTag("body") | ||||||
|  | @ -185,7 +185,7 @@ class PinoyMoviesEsProvider : MainAPI() { | ||||||
|         return MovieLoadResponse(title, url, this.name, TvType.Movie, streamlinks, poster, year, descript, null, null) |         return MovieLoadResponse(title, url, this.name, TvType.Movie, streamlinks, poster, year, descript, null, null) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|             data: String, |             data: String, | ||||||
|             isCasting: Boolean, |             isCasting: Boolean, | ||||||
|             subtitleCallback: (SubtitleFile) -> Unit, |             subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -1,9 +1,11 @@ | ||||||
| package com.lagradost.cloudstream3.movieproviders | package com.lagradost.cloudstream3.movieproviders | ||||||
| 
 | 
 | ||||||
| import com.fasterxml.jackson.annotation.JsonProperty | import com.fasterxml.jackson.annotation.JsonProperty | ||||||
| import com.fasterxml.jackson.module.kotlin.readValue |  | ||||||
| import com.lagradost.cloudstream3.* | import com.lagradost.cloudstream3.* | ||||||
| import com.lagradost.cloudstream3.network.WebViewResolver | import com.lagradost.cloudstream3.network.WebViewResolver | ||||||
|  | import com.lagradost.cloudstream3.utils.AppUtils.parseJson | ||||||
|  | import com.lagradost.cloudstream3.utils.AppUtils.toJson | ||||||
|  | import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.M3u8Helper | import com.lagradost.cloudstream3.utils.M3u8Helper | ||||||
| import com.lagradost.cloudstream3.utils.getQualityFromName | import com.lagradost.cloudstream3.utils.getQualityFromName | ||||||
|  | @ -26,35 +28,7 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|     ) |     ) | ||||||
|     override val vpnStatus = VPNStatus.None |     override val vpnStatus = VPNStatus.None | ||||||
| 
 | 
 | ||||||
|     private fun Element.toSearchResult(): SearchResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val img = this.select("img") |  | ||||||
|         val title = img.attr("title") |  | ||||||
|         val posterUrl = img.attr("data-src") |  | ||||||
|         val href = fixUrl(this.select("a").attr("href")) |  | ||||||
|         val isMovie = href.contains("/movie/") |  | ||||||
|         return if (isMovie) { |  | ||||||
|             MovieSearchResponse( |  | ||||||
|                 title, |  | ||||||
|                 href, |  | ||||||
|                 this@SflixProvider.name, |  | ||||||
|                 TvType.Movie, |  | ||||||
|                 posterUrl, |  | ||||||
|                 null |  | ||||||
|             ) |  | ||||||
|         } else { |  | ||||||
|             TvSeriesSearchResponse( |  | ||||||
|                 title, |  | ||||||
|                 href, |  | ||||||
|                 this@SflixProvider.name, |  | ||||||
|                 TvType.Movie, |  | ||||||
|                 posterUrl, |  | ||||||
|                 null, |  | ||||||
|                 null |  | ||||||
|             ) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     override fun getMainPage(): HomePageResponse { |  | ||||||
|         val html = app.get("$mainUrl/home").text |         val html = app.get("$mainUrl/home").text | ||||||
|         val document = Jsoup.parse(html) |         val document = Jsoup.parse(html) | ||||||
| 
 | 
 | ||||||
|  | @ -84,7 +58,7 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|         return HomePageResponse(all) |         return HomePageResponse(all) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/search/${query.replace(" ", "-")}" |         val url = "$mainUrl/search/${query.replace(" ", "-")}" | ||||||
|         val html = app.get(url).text |         val html = app.get(url).text | ||||||
|         val document = Jsoup.parse(html) |         val document = Jsoup.parse(html) | ||||||
|  | @ -119,7 +93,7 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val document = app.get(url).document |         val document = app.get(url).document | ||||||
| 
 | 
 | ||||||
|         val details = document.select("div.detail_page-watch") |         val details = document.select("div.detail_page-watch") | ||||||
|  | @ -151,15 +125,16 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|             val episodes = app.get(episodesUrl).text |             val episodes = app.get(episodesUrl).text | ||||||
| 
 | 
 | ||||||
|             // Supported streams, they're identical |             // Supported streams, they're identical | ||||||
|             val sourceId = Jsoup.parse(episodes).select("a").firstOrNull { |             val sourceIds = Jsoup.parse(episodes).select("a").mapNotNull { element -> | ||||||
|                 it.select("span").text().trim().equals("RapidStream", ignoreCase = true) |                 val sourceId = element.attr("data-id") ?: return@mapNotNull null | ||||||
|                         || it.select("span").text().trim().equals("Vidcloud", ignoreCase = true) |                 if(element.select("span")?.text()?.trim()?.isValidServer() == true) { | ||||||
|             }?.attr("data-id") |                     "$url.$sourceId".replace("/movie/", "/watch-movie/") | ||||||
|  |                 } else { | ||||||
|  |                     null | ||||||
|  |                 } | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             val webViewUrl = |             return newMovieLoadResponse(title, url, TvType.Movie, sourceIds.toJson()) { | ||||||
|                 "$url${sourceId?.let { ".$it" } ?: ""}".replace("/movie/", "/watch-movie/") |  | ||||||
| 
 |  | ||||||
|             return newMovieLoadResponse(title, url, TvType.Movie, webViewUrl) { |  | ||||||
|                 this.year = year |                 this.year = year | ||||||
|                 this.posterUrl = posterUrl |                 this.posterUrl = posterUrl | ||||||
|                 this.plot = plot |                 this.plot = plot | ||||||
|  | @ -186,7 +161,8 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|                             episode++ |                             episode++ | ||||||
| 
 | 
 | ||||||
|                             val episodeNum = |                             val episodeNum = | ||||||
|                                 (it.select("div.episode-number")?.text() ?: episodeTitle).let { str -> |                                 (it.select("div.episode-number")?.text() | ||||||
|  |                                     ?: episodeTitle).let { str -> | ||||||
|                                     Regex("""\d+""").find(str)?.groupValues?.firstOrNull() |                                     Regex("""\d+""").find(str)?.groupValues?.firstOrNull() | ||||||
|                                         ?.toIntOrNull() |                                         ?.toIntOrNull() | ||||||
|                                 } ?: episode |                                 } ?: episode | ||||||
|  | @ -231,39 +207,37 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|         @JsonProperty("tracks") val tracks: List<Tracks?>? |         @JsonProperty("tracks") val tracks: List<Tracks?>? | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|         callback: (ExtractorLink) -> Unit |         callback: (ExtractorLink) -> Unit | ||||||
|     ): Boolean { |     ): Boolean { | ||||||
| 
 |         val urls = (tryParseJson<Pair<String, String>>(data)?.let { (prefix, server) -> | ||||||
|         // To transfer url:::id |             val episodesUrl = "$mainUrl/ajax/v2/episode/servers/$server" | ||||||
|         val split = data.split(":::") |  | ||||||
|         // Only used for tv series |  | ||||||
|         val url = if (split.size == 2) { |  | ||||||
|             val episodesUrl = "$mainUrl/ajax/v2/episode/servers/${split[1]}" |  | ||||||
|             val episodes = app.get(episodesUrl).text |             val episodes = app.get(episodesUrl).text | ||||||
| 
 | 
 | ||||||
|             // Supported streams, they're identical |             // Supported streams, they're identical | ||||||
|             val sourceId = Jsoup.parse(episodes).select("a").firstOrNull { |             Jsoup.parse(episodes).select("a").mapNotNull { element -> | ||||||
|                 it.select("span").text().trim().equals("RapidStream", ignoreCase = true) |                 val id = element?.attr("data-id") ?: return@mapNotNull null | ||||||
|                         || it.select("span").text().trim().equals("Vidcloud", ignoreCase = true) |                 if(element.select("span")?.text()?.trim()?.isValidServer() == true) { | ||||||
|             }?.attr("data-id") |                     "$prefix.$id".replace("/tv/", "/watch-tv/") | ||||||
| 
 |  | ||||||
|             "${split[0]}${sourceId?.let { ".$it" } ?: ""}".replace("/tv/", "/watch-tv/") |  | ||||||
|                 } else { |                 } else { | ||||||
|             data |                     null | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|  |         } ?: tryParseJson<List<String>>(data))?.distinct() | ||||||
| 
 | 
 | ||||||
|  |         urls?.pmap { url -> | ||||||
|  |             println("FETCHING URL $url") | ||||||
|             val sources = app.get( |             val sources = app.get( | ||||||
|                 url, |                 url, | ||||||
|                 interceptor = WebViewResolver( |                 interceptor = WebViewResolver( | ||||||
|                 Regex("""/getSources""") |                     Regex("""/getSources"""), | ||||||
|                 ) |                 ) | ||||||
|             ).text |             ).text | ||||||
| 
 | 
 | ||||||
|         val mapped = mapper.readValue<SourceObject>(sources) |             val mapped = parseJson<SourceObject>(sources) | ||||||
| 
 | 
 | ||||||
|             mapped.tracks?.forEach { |             mapped.tracks?.forEach { | ||||||
|                 it?.toSubtitleFile()?.let { subtitleFile -> |                 it?.toSubtitleFile()?.let { subtitleFile -> | ||||||
|  | @ -272,7 +246,7 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             listOf( |             listOf( | ||||||
|             mapped.sources to "source 1", |                 mapped.sources to "", | ||||||
|                 mapped.sources1 to "source 2", |                 mapped.sources1 to "source 2", | ||||||
|                 mapped.sources2 to "source 3", |                 mapped.sources2 to "source 3", | ||||||
|                 mapped.sourcesBackup to "source backup" |                 mapped.sourcesBackup to "source backup" | ||||||
|  | @ -281,14 +255,54 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|                     it?.toExtractorLink(this, subList.second)?.forEach(callback) |                     it?.toExtractorLink(this, subList.second)?.forEach(callback) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         return true |         } | ||||||
|  | 
 | ||||||
|  |         return !urls.isNullOrEmpty() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun Element.toSearchResult(): SearchResponse { | ||||||
|  |         val img = this.select("img") | ||||||
|  |         val title = img.attr("title") | ||||||
|  |         val posterUrl = img.attr("data-src") | ||||||
|  |         val href = fixUrl(this.select("a").attr("href")) | ||||||
|  |         val isMovie = href.contains("/movie/") | ||||||
|  |         return if (isMovie) { | ||||||
|  |             MovieSearchResponse( | ||||||
|  |                 title, | ||||||
|  |                 href, | ||||||
|  |                 this@SflixProvider.name, | ||||||
|  |                 TvType.Movie, | ||||||
|  |                 posterUrl, | ||||||
|  |                 null | ||||||
|  |             ) | ||||||
|  |         } else { | ||||||
|  |             TvSeriesSearchResponse( | ||||||
|  |                 title, | ||||||
|  |                 href, | ||||||
|  |                 this@SflixProvider.name, | ||||||
|  |                 TvType.Movie, | ||||||
|  |                 posterUrl, | ||||||
|  |                 null, | ||||||
|  |                 null | ||||||
|  |             ) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     companion object { |     companion object { | ||||||
|         // For re-use in Zoro |         fun String?.isValidServer(): Boolean { | ||||||
|  |             if (this.isNullOrEmpty()) return false | ||||||
|  |             if (this.equals("UpCloud", ignoreCase = true) || this.equals( | ||||||
|  |                     "Vidcloud", | ||||||
|  |                     ignoreCase = true | ||||||
|  |                 ) || this.equals("RapidStream", ignoreCase = true) | ||||||
|  |             ) return true | ||||||
|  |             return true | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|  |         // For re-use in Zoro | ||||||
|         fun Sources.toExtractorLink(caller: MainAPI, name: String): List<ExtractorLink>? { |         fun Sources.toExtractorLink(caller: MainAPI, name: String): List<ExtractorLink>? { | ||||||
|             return this.file?.let { file -> |             return this.file?.let { file -> | ||||||
|  |                 //println("FILE::: $file") | ||||||
|                 val isM3u8 = URI(this.file).path.endsWith(".m3u8") || this.type.equals( |                 val isM3u8 = URI(this.file).path.endsWith(".m3u8") || this.type.equals( | ||||||
|                     "hls", |                     "hls", | ||||||
|                     ignoreCase = true |                     ignoreCase = true | ||||||
|  | @ -296,6 +310,7 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|                 if (isM3u8) { |                 if (isM3u8) { | ||||||
|                     M3u8Helper().m3u8Generation(M3u8Helper.M3u8Stream(this.file, null), true) |                     M3u8Helper().m3u8Generation(M3u8Helper.M3u8Stream(this.file, null), true) | ||||||
|                         .map { stream -> |                         .map { stream -> | ||||||
|  |                             //println("stream: ${stream.quality} at ${stream.streamUrl}") | ||||||
|                             val qualityString = if ((stream.quality ?: 0) == 0) label |                             val qualityString = if ((stream.quality ?: 0) == 0) label | ||||||
|                                 ?: "" else "${stream.quality}p" |                                 ?: "" else "${stream.quality}p" | ||||||
|                             ExtractorLink( |                             ExtractorLink( | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ class TrailersTwoProvider : TmdbProvider() { | ||||||
|         TvType.Cartoon |         TvType.Cartoon | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ class VMoveeProvider : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     override val supportedTypes = setOf(TvType.Movie) |     override val supportedTypes = setOf(TvType.Movie) | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/?s=$query" |         val url = "$mainUrl/?s=$query" | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|  | @ -60,7 +60,7 @@ class VMoveeProvider : MainAPI() { | ||||||
|         val data: List<ReeoovAPIData>, |         val data: List<ReeoovAPIData>, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  | @ -108,7 +108,7 @@ class VMoveeProvider : MainAPI() { | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ class VfFilmProvider : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     override val supportedTypes = setOf(TvType.Movie) |     override val supportedTypes = setOf(TvType.Movie) | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/?s=$query" |         val url = "$mainUrl/?s=$query" | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|  | @ -39,7 +39,7 @@ class VfFilmProvider : MainAPI() { | ||||||
|         return returnValue |         return returnValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  | @ -70,7 +70,7 @@ class VfFilmProvider : MainAPI() { | ||||||
|         return vudoUrl |         return vudoUrl | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|         val title = document?.selectFirst("div.SubTitle")?.text() |         val title = document?.selectFirst("div.SubTitle")?.text() | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ class VfSerieProvider : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     override val supportedTypes = setOf(TvType.TvSeries) |     override val supportedTypes = setOf(TvType.TvSeries) | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/?s=$query" |         val url = "$mainUrl/?s=$query" | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|  | @ -52,7 +52,7 @@ class VfSerieProvider : MainAPI() { | ||||||
|             .toString()  // direct mp4 link, https://m5.vudeo.net/2vp3xgpw2avjdohilpfbtyuxzzrqzuh4z5yxvztral5k3rjnba6f4byj3saa/v.mp4 for exemple |             .toString()  // direct mp4 link, https://m5.vudeo.net/2vp3xgpw2avjdohilpfbtyuxzzrqzuh4z5yxvztral5k3rjnba6f4byj3saa/v.mp4 for exemple | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  | @ -95,7 +95,7 @@ class VfSerieProvider : MainAPI() { | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|         val title = |         val title = | ||||||
|  |  | ||||||
|  | @ -33,7 +33,7 @@ open class VidstreamProviderTemplate : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     // Searching returns a SearchResponse, which can be one of the following: AnimeSearchResponse, MovieSearchResponse, TorrentSearchResponse, TvSeriesSearchResponse |     // Searching returns a SearchResponse, which can be one of the following: AnimeSearchResponse, MovieSearchResponse, TorrentSearchResponse, TvSeriesSearchResponse | ||||||
|     // Each of the classes requires some different data, but always has some critical things like name, poster and url. |     // Each of the classes requires some different data, but always has some critical things like name, poster and url. | ||||||
|     override fun search(query: String): ArrayList<SearchResponse> { |     override suspend fun search(query: String): ArrayList<SearchResponse> { | ||||||
|         // Simply looking at devtools network is enough to spot a request like: |         // Simply looking at devtools network is enough to spot a request like: | ||||||
|         // https://vidembed.cc/search.html?keyword=neverland where neverland is the query, can be written as below. |         // https://vidembed.cc/search.html?keyword=neverland where neverland is the query, can be written as below. | ||||||
|         val link = "$mainUrl/search.html?keyword=$query" |         val link = "$mainUrl/search.html?keyword=$query" | ||||||
|  | @ -66,7 +66,7 @@ open class VidstreamProviderTemplate : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     // Load, like the name suggests loads the info page, where all the episodes and data usually is. |     // Load, like the name suggests loads the info page, where all the episodes and data usually is. | ||||||
|     // Like search you should return either of: AnimeLoadResponse, MovieLoadResponse, TorrentLoadResponse, TvSeriesLoadResponse. |     // Like search you should return either of: AnimeLoadResponse, MovieLoadResponse, TorrentLoadResponse, TvSeriesLoadResponse. | ||||||
|     override fun load(url: String): LoadResponse? { |     override suspend fun load(url: String): LoadResponse? { | ||||||
|         // Gets the url returned from searching. |         // Gets the url returned from searching. | ||||||
|         val html = app.get(url).text |         val html = app.get(url).text | ||||||
|         val soup = Jsoup.parse(html) |         val soup = Jsoup.parse(html) | ||||||
|  | @ -144,7 +144,7 @@ open class VidstreamProviderTemplate : MainAPI() { | ||||||
| 
 | 
 | ||||||
|     // This loads the homepage, which is basically a collection of search results with labels. |     // This loads the homepage, which is basically a collection of search results with labels. | ||||||
|     // Optional function, but make sure to enable hasMainPage if you program this. |     // Optional function, but make sure to enable hasMainPage if you program this. | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val urls = homePageUrlList |         val urls = homePageUrlList | ||||||
|         val homePageList = ArrayList<HomePageList>() |         val homePageList = ArrayList<HomePageList>() | ||||||
|         // .pmap {} is used to fetch the different pages in parallel |         // .pmap {} is used to fetch the different pages in parallel | ||||||
|  | @ -198,7 +198,7 @@ open class VidstreamProviderTemplate : MainAPI() { | ||||||
|     // loadLinks gets the raw .mp4 or .m3u8 urls from the data parameter in the episodes class generated in load() |     // loadLinks gets the raw .mp4 or .m3u8 urls from the data parameter in the episodes class generated in load() | ||||||
|     // See TvSeriesEpisode(...) in this provider. |     // See TvSeriesEpisode(...) in this provider. | ||||||
|     // The data are usually links, but can be any other string to help aid loading the links. |     // The data are usually links, but can be any other string to help aid loading the links. | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         // These callbacks are functions you should call when you get a link to a subtitle file or media file. |         // These callbacks are functions you should call when you get a link to a subtitle file or media file. | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ class WatchAsianProvider : MainAPI() { | ||||||
|     override val hasDownloadSupport = true |     override val hasDownloadSupport = true | ||||||
|     override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) |     override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse { |     override suspend fun getMainPage(): HomePageResponse { | ||||||
|         val headers = mapOf("X-Requested-By" to mainUrl) |         val headers = mapOf("X-Requested-By" to mainUrl) | ||||||
|         val doc = app.get(mainUrl, headers = headers).document |         val doc = app.get(mainUrl, headers = headers).document | ||||||
|         val rowPair = mutableListOf<Pair<String, String>>() |         val rowPair = mutableListOf<Pair<String, String>>() | ||||||
|  | @ -64,7 +64,7 @@ class WatchAsianProvider : MainAPI() { | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/search?type=movies&keyword=$query" |         val url = "$mainUrl/search?type=movies&keyword=$query" | ||||||
|         val document = app.get(url).document.getElementsByTag("body") |         val document = app.get(url).document.getElementsByTag("body") | ||||||
|                 .select("div.block.tab-container > div > ul > li") ?: return listOf() |                 .select("div.block.tab-container > div > ul > li") ?: return listOf() | ||||||
|  | @ -89,7 +89,7 @@ class WatchAsianProvider : MainAPI() { | ||||||
|         }.distinctBy { a -> a.url } |         }.distinctBy { a -> a.url } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val body = app.get(url).document |         val body = app.get(url).document | ||||||
|         // Declare vars |         // Declare vars | ||||||
|         val isDramaDetail = url.contains("/drama-detail/") |         val isDramaDetail = url.contains("/drama-detail/") | ||||||
|  | @ -163,7 +163,7 @@ class WatchAsianProvider : MainAPI() { | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ class FrenchStreamProvider : MainAPI() { | ||||||
|     override val lang = "fr" |     override val lang = "fr" | ||||||
|     override val supportedTypes = setOf(TvType.AnimeMovie, TvType.TvSeries, TvType.Movie) |     override val supportedTypes = setOf(TvType.AnimeMovie, TvType.TvSeries, TvType.Movie) | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): ArrayList<SearchResponse> { |     override suspend fun search(query: String): ArrayList<SearchResponse> { | ||||||
|         val link = "$mainUrl/?do=search&subaction=search&story=$query" |         val link = "$mainUrl/?do=search&subaction=search&story=$query" | ||||||
|         val soup = app.post(link).document |         val soup = app.post(link).document | ||||||
| 
 | 
 | ||||||
|  | @ -49,7 +49,7 @@ class FrenchStreamProvider : MainAPI() { | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val soup = app.get(url).document |         val soup = app.get(url).document | ||||||
| 
 | 
 | ||||||
|         val title = soup.selectFirst("h1#s-title").text().toString() |         val title = soup.selectFirst("h1#s-title").text().toString() | ||||||
|  | @ -136,7 +136,7 @@ class FrenchStreamProvider : MainAPI() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  | @ -228,7 +228,7 @@ class FrenchStreamProvider : MainAPI() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     override fun getMainPage(): HomePageResponse? { |     override suspend fun getMainPage(): HomePageResponse? { | ||||||
|         val document = app.get(mainUrl).document |         val document = app.get(mainUrl).document | ||||||
|         val docs = document.select("div.sect") |         val docs = document.select("div.sect") | ||||||
|         val returnList = docs.mapNotNull { |         val returnList = docs.mapNotNull { | ||||||
|  |  | ||||||
|  | @ -13,7 +13,6 @@ import org.jsoup.Jsoup | ||||||
| import org.jsoup.nodes.Document | import org.jsoup.nodes.Document | ||||||
| import java.io.File | import java.io.File | ||||||
| import java.net.URI | import java.net.URI | ||||||
| import java.util.* |  | ||||||
| import java.util.concurrent.TimeUnit | import java.util.concurrent.TimeUnit | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -156,13 +155,13 @@ fun getHeaders( | ||||||
| 
 | 
 | ||||||
| fun postRequestCreator( | fun postRequestCreator( | ||||||
|     url: String, |     url: String, | ||||||
|     headers: Map<String, String>, |     headers: Map<String, String> = emptyMap(), | ||||||
|     referer: String?, |     referer: String? = null, | ||||||
|     params: Map<String, String>, |     params: Map<String, String> = emptyMap(), | ||||||
|     cookies: Map<String, String>, |     cookies: Map<String, String> = emptyMap(), | ||||||
|     data: Map<String, String>, |     data: Map<String, String> = emptyMap(), | ||||||
|     cacheTime: Int, |     cacheTime: Int = DEFAULT_TIME, | ||||||
|     cacheUnit: TimeUnit |     cacheUnit: TimeUnit = DEFAULT_TIME_UNIT | ||||||
| ): Request { | ): Request { | ||||||
|     return Request.Builder() |     return Request.Builder() | ||||||
|         .url(addParamsToUrl(url, params)) |         .url(addParamsToUrl(url, params)) | ||||||
|  | @ -174,12 +173,12 @@ fun postRequestCreator( | ||||||
| 
 | 
 | ||||||
| fun getRequestCreator( | fun getRequestCreator( | ||||||
|     url: String, |     url: String, | ||||||
|     headers: Map<String, String>, |     headers: Map<String, String> = emptyMap(), | ||||||
|     referer: String?, |     referer: String? = null, | ||||||
|     params: Map<String, String>, |     params: Map<String, String> = emptyMap(), | ||||||
|     cookies: Map<String, String>, |     cookies: Map<String, String> = emptyMap(), | ||||||
|     cacheTime: Int, |     cacheTime: Int = DEFAULT_TIME, | ||||||
|     cacheUnit: TimeUnit |     cacheUnit: TimeUnit = DEFAULT_TIME_UNIT | ||||||
| ): Request { | ): Request { | ||||||
|     return Request.Builder() |     return Request.Builder() | ||||||
|         .url(addParamsToUrl(url, params)) |         .url(addParamsToUrl(url, params)) | ||||||
|  | @ -213,6 +212,8 @@ open class Requests { | ||||||
|         val settingsManager = PreferenceManager.getDefaultSharedPreferences(context) |         val settingsManager = PreferenceManager.getDefaultSharedPreferences(context) | ||||||
|         val dns = settingsManager.getInt(context.getString(R.string.dns_pref), 0) |         val dns = settingsManager.getInt(context.getString(R.string.dns_pref), 0) | ||||||
|         baseClient = OkHttpClient.Builder() |         baseClient = OkHttpClient.Builder() | ||||||
|  |             .followRedirects(true) | ||||||
|  |             .followSslRedirects(true) | ||||||
|             .cache( |             .cache( | ||||||
|                 // Note that you need to add a ResponseInterceptor to make this 100% active. |                 // Note that you need to add a ResponseInterceptor to make this 100% active. | ||||||
|                 // The server response dictates if and when stuff should be cached. |                 // The server response dictates if and when stuff should be cached. | ||||||
|  | @ -235,10 +236,10 @@ open class Requests { | ||||||
| 
 | 
 | ||||||
|     fun get( |     fun get( | ||||||
|         url: String, |         url: String, | ||||||
|         headers: Map<String, String> = mapOf(), |         headers: Map<String, String> = emptyMap(), | ||||||
|         referer: String? = null, |         referer: String? = null, | ||||||
|         params: Map<String, String> = mapOf(), |         params: Map<String, String> = emptyMap(), | ||||||
|         cookies: Map<String, String> = mapOf(), |         cookies: Map<String, String> = emptyMap(), | ||||||
|         allowRedirects: Boolean = true, |         allowRedirects: Boolean = true, | ||||||
|         cacheTime: Int = DEFAULT_TIME, |         cacheTime: Int = DEFAULT_TIME, | ||||||
|         cacheUnit: TimeUnit = DEFAULT_TIME_UNIT, |         cacheUnit: TimeUnit = DEFAULT_TIME_UNIT, | ||||||
|  | @ -258,6 +259,10 @@ open class Requests { | ||||||
|         return AppResponse(response) |         return AppResponse(response) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     fun executeRequest(request : Request): AppResponse { | ||||||
|  |         return AppResponse(baseClient.newCall(request).execute()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     fun post( |     fun post( | ||||||
|         url: String, |         url: String, | ||||||
|         headers: Map<String, String> = mapOf(), |         headers: Map<String, String> = mapOf(), | ||||||
|  |  | ||||||
|  | @ -8,14 +8,12 @@ import com.lagradost.cloudstream3.USER_AGENT | ||||||
| import com.lagradost.cloudstream3.app | import com.lagradost.cloudstream3.app | ||||||
| import com.lagradost.cloudstream3.utils.Coroutines.main | import com.lagradost.cloudstream3.utils.Coroutines.main | ||||||
| import kotlinx.coroutines.delay | import kotlinx.coroutines.delay | ||||||
| import kotlinx.coroutines.flow.callbackFlow |  | ||||||
| import kotlinx.coroutines.runBlocking | import kotlinx.coroutines.runBlocking | ||||||
| import okhttp3.Interceptor | import okhttp3.Interceptor | ||||||
| import okhttp3.Request | import okhttp3.Request | ||||||
| import okhttp3.Response | import okhttp3.Response | ||||||
| import java.net.URI | import java.net.URI | ||||||
| import java.util.concurrent.TimeUnit | import java.util.concurrent.TimeUnit | ||||||
| import kotlin.concurrent.thread |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * When used as Interceptor additionalUrls cannot be returned, use WebViewResolver(...).resolveUsingWebView(...) |  * When used as Interceptor additionalUrls cannot be returned, use WebViewResolver(...).resolveUsingWebView(...) | ||||||
|  | @ -96,7 +94,34 @@ class WebViewResolver(val interceptUrl: Regex, val additionalUrls: List<Regex> = | ||||||
|                     // Suppress image requests as we don't display them anywhere |                     // Suppress image requests as we don't display them anywhere | ||||||
|                     // Less data, low chance of causing issues. |                     // Less data, low chance of causing issues. | ||||||
|                     // blockNetworkImage also does this job but i will keep it for the future. |                     // blockNetworkImage also does this job but i will keep it for the future. | ||||||
|                     val blacklistedFiles = listOf(".jpg", ".png", ".webp", ".jpeg", ".webm", ".mp4") |                     val blacklistedFiles = listOf( | ||||||
|  |                         ".jpg", | ||||||
|  |                         ".png", | ||||||
|  |                         ".webp", | ||||||
|  |                         ".mpg", | ||||||
|  |                         ".mpeg", | ||||||
|  |                         ".jpeg", | ||||||
|  |                         ".webm", | ||||||
|  |                         ".mp4", | ||||||
|  |                         ".mp3", | ||||||
|  |                         ".gifv", | ||||||
|  |                         ".flv", | ||||||
|  |                         ".asf", | ||||||
|  |                         ".mov", | ||||||
|  |                         ".mng", | ||||||
|  |                         ".mkv", | ||||||
|  |                         ".ogg", | ||||||
|  |                         ".avi", | ||||||
|  |                         ".wav", | ||||||
|  |                         ".woff2", | ||||||
|  |                         ".woff", | ||||||
|  |                         ".ttf", | ||||||
|  |                         ".css", | ||||||
|  |                         ".vtt", | ||||||
|  |                         ".srt", | ||||||
|  |                         ".ts", | ||||||
|  |                         ".gif", | ||||||
|  |                     ) | ||||||
| 
 | 
 | ||||||
|                     /** NOTE!  request.requestHeaders is not perfect! |                     /** NOTE!  request.requestHeaders is not perfect! | ||||||
|                      *  They don't contain all the headers the browser actually gives. |                      *  They don't contain all the headers the browser actually gives. | ||||||
|  | @ -105,7 +130,7 @@ class WebViewResolver(val interceptUrl: Regex, val additionalUrls: List<Regex> = | ||||||
|                      * **/ |                      * **/ | ||||||
|                     return try { |                     return try { | ||||||
|                         when { |                         when { | ||||||
|                             blacklistedFiles.any { URI(webViewUrl).path.endsWith(it) } || webViewUrl.endsWith( |                             blacklistedFiles.any { URI(webViewUrl).path.contains(it) } || webViewUrl.endsWith( | ||||||
|                                 "/favicon.ico" |                                 "/favicon.ico" | ||||||
|                             ) -> WebResourceResponse( |                             ) -> WebResourceResponse( | ||||||
|                                 "image/png", |                                 "image/png", | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ class NyaaProvider : MainAPI() { | ||||||
|     override val vpnStatus = VPNStatus.Torrent |     override val vpnStatus = VPNStatus.Torrent | ||||||
|     override val instantLinkLoading = true |     override val instantLinkLoading = true | ||||||
| 
 | 
 | ||||||
|     override fun search(query: String): List<SearchResponse> { |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|         val url = "$mainUrl/?f=0&c=0_0&q=$query&s=seeders&o=desc" |         val url = "$mainUrl/?f=0&c=0_0&q=$query&s=seeders&o=desc" | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|  | @ -35,7 +35,7 @@ class NyaaProvider : MainAPI() { | ||||||
|         return returnValues |         return returnValues | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val response = app.get(url).text |         val response = app.get(url).text | ||||||
|         val document = Jsoup.parse(response) |         val document = Jsoup.parse(response) | ||||||
|         val title = document.selectFirst("h3.panel-title").text() |         val title = document.selectFirst("h3.panel-title").text() | ||||||
|  | @ -47,7 +47,7 @@ class NyaaProvider : MainAPI() { | ||||||
|         return TorrentLoadResponse(title, url, this.name, magnet, fixUrl(torrent), description) |         return TorrentLoadResponse(title, url, this.name, magnet, fixUrl(torrent), description) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ package com.lagradost.cloudstream3.ui | ||||||
| 
 | 
 | ||||||
| import com.lagradost.cloudstream3.* | import com.lagradost.cloudstream3.* | ||||||
| import com.lagradost.cloudstream3.mvvm.Resource | import com.lagradost.cloudstream3.mvvm.Resource | ||||||
| import com.lagradost.cloudstream3.mvvm.normalSafeApiCall | import com.lagradost.cloudstream3.mvvm.logError | ||||||
| import com.lagradost.cloudstream3.mvvm.safeApiCall | import com.lagradost.cloudstream3.mvvm.safeApiCall | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| 
 | 
 | ||||||
|  | @ -66,15 +66,18 @@ class APIRepository(val api: MainAPI) { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun loadLinks( |     suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|         callback: (ExtractorLink) -> Unit |         callback: (ExtractorLink) -> Unit | ||||||
|     ): Boolean { |     ): Boolean { | ||||||
|         if (isInvalidData(data)) return false // this makes providers cleaner |         if (isInvalidData(data)) return false // this makes providers cleaner | ||||||
| 
 |         return try { | ||||||
|         return normalSafeApiCall { api.loadLinks(data, isCasting, subtitleCallback, callback) } |             api.loadLinks(data, isCasting, subtitleCallback, callback) | ||||||
|             ?: false |         } catch (throwable: Throwable) { | ||||||
|  |             logError(throwable) | ||||||
|  |             return false | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -22,7 +22,8 @@ import com.google.android.gms.cast.framework.media.RemoteMediaClient | ||||||
| import com.google.android.gms.cast.framework.media.uicontroller.UIController | import com.google.android.gms.cast.framework.media.uicontroller.UIController | ||||||
| import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity | import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity | ||||||
| import com.lagradost.cloudstream3.R | import com.lagradost.cloudstream3.R | ||||||
| import com.lagradost.cloudstream3.mvvm.normalSafeApiCall | import com.lagradost.cloudstream3.mvvm.Resource | ||||||
|  | import com.lagradost.cloudstream3.mvvm.safeApiCall | ||||||
| import com.lagradost.cloudstream3.sortSubs | import com.lagradost.cloudstream3.sortSubs | ||||||
| import com.lagradost.cloudstream3.sortUrls | import com.lagradost.cloudstream3.sortUrls | ||||||
| import com.lagradost.cloudstream3.ui.player.RepoLinkGenerator | import com.lagradost.cloudstream3.ui.player.RepoLinkGenerator | ||||||
|  | @ -31,11 +32,11 @@ import com.lagradost.cloudstream3.ui.result.ResultEpisode | ||||||
| import com.lagradost.cloudstream3.utils.AppUtils.toJson | import com.lagradost.cloudstream3.utils.AppUtils.toJson | ||||||
| import com.lagradost.cloudstream3.utils.CastHelper.awaitLinks | import com.lagradost.cloudstream3.utils.CastHelper.awaitLinks | ||||||
| import com.lagradost.cloudstream3.utils.CastHelper.getMediaInfo | import com.lagradost.cloudstream3.utils.CastHelper.getMediaInfo | ||||||
|  | import com.lagradost.cloudstream3.utils.Coroutines.ioSafe | ||||||
| import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject | import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe | import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe | ||||||
| import org.json.JSONObject | import org.json.JSONObject | ||||||
| import kotlin.concurrent.thread |  | ||||||
| 
 | 
 | ||||||
| /*class SkipOpController(val view: ImageView) : UIController() { | /*class SkipOpController(val view: ImageView) : UIController() { | ||||||
|     init { |     init { | ||||||
|  | @ -265,7 +266,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi | ||||||
| 
 | 
 | ||||||
|                 if (itemCount != null && itemCount - currentIdIndex == 1 && !isLoadingMore) { |                 if (itemCount != null && itemCount - currentIdIndex == 1 && !isLoadingMore) { | ||||||
|                     isLoadingMore = true |                     isLoadingMore = true | ||||||
|                     thread { |                     ioSafe { | ||||||
|                         val index = meta.currentEpisodeIndex + 1 |                         val index = meta.currentEpisodeIndex + 1 | ||||||
|                         val epData = meta.episodes[index] |                         val epData = meta.episodes[index] | ||||||
|                         val currentLinks = mutableSetOf<ExtractorLink>() |                         val currentLinks = mutableSetOf<ExtractorLink>() | ||||||
|  | @ -273,7 +274,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi | ||||||
| 
 | 
 | ||||||
|                         val generator = RepoLinkGenerator(listOf(epData)) |                         val generator = RepoLinkGenerator(listOf(epData)) | ||||||
| 
 | 
 | ||||||
|                         val isSuccessful = normalSafeApiCall { |                         val isSuccessful = safeApiCall { | ||||||
|                             generator.generateLinks(false, true, |                             generator.generateLinks(false, true, | ||||||
|                                 { |                                 { | ||||||
|                                     it.first?.let { link -> |                                     it.first?.let { link -> | ||||||
|  | @ -286,7 +287,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi | ||||||
| 
 | 
 | ||||||
|                         val sortedLinks = sortUrls(currentLinks) |                         val sortedLinks = sortUrls(currentLinks) | ||||||
|                         val sortedSubs = sortSubs(currentSubs) |                         val sortedSubs = sortSubs(currentSubs) | ||||||
|                         if (isSuccessful == true) { |                         if (isSuccessful == Resource.Success(true)) { | ||||||
|                             if (currentLinks.isNotEmpty()) { |                             if (currentLinks.isNotEmpty()) { | ||||||
|                                 val jsonCopy = meta.copy( |                                 val jsonCopy = meta.copy( | ||||||
|                                     currentLinks =  sortedLinks, |                                     currentLinks =  sortedLinks, | ||||||
|  | @ -319,13 +320,10 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi | ||||||
|                                 }*/ |                                 }*/ | ||||||
|                                 activity.runOnUiThread { |                                 activity.runOnUiThread { | ||||||
|                                     awaitLinks( |                                     awaitLinks( | ||||||
| 
 |  | ||||||
|                                         remoteMediaClient?.queueAppendItem( |                                         remoteMediaClient?.queueAppendItem( | ||||||
|                                             MediaQueueItem.Builder(mediaInfo).build(), |                                             MediaQueueItem.Builder(mediaInfo).build(), | ||||||
|                                             JSONObject() |                                             JSONObject() | ||||||
|                                         ) |                                         ) | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|                                     ) { |                                     ) { | ||||||
|                                         println("FAILED TO LOAD NEXT ITEM") |                                         println("FAILED TO LOAD NEXT ITEM") | ||||||
|                                         //  loadIndex(1) |                                         //  loadIndex(1) | ||||||
|  |  | ||||||
|  | @ -46,7 +46,7 @@ class DownloadFileGenerator( | ||||||
|         return episodes[currentIndex] |         return episodes[currentIndex] | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun generateLinks( |     override suspend fun generateLinks( | ||||||
|         clearCache: Boolean, |         clearCache: Boolean, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit, |         callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit, | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ interface IGenerator { | ||||||
|     fun getCurrent(): Any?     // this is used to get metadata about the current playing, can return null |     fun getCurrent(): Any?     // this is used to get metadata about the current playing, can return null | ||||||
| 
 | 
 | ||||||
|     /* not safe, must use try catch */ |     /* not safe, must use try catch */ | ||||||
|     fun generateLinks( |     suspend fun generateLinks( | ||||||
|         clearCache: Boolean, |         clearCache: Boolean, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit, |         callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit, | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ class PlayerGeneratorViewModel : ViewModel() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun preLoadNextLinks() = viewModelScope.launch { |     fun preLoadNextLinks() = viewModelScope.launch { | ||||||
|         normalSafeApiCall { |         safeApiCall { | ||||||
|             if (generator?.hasCache == true && generator?.hasNext() == true) { |             if (generator?.hasCache == true && generator?.hasNext() == true) { | ||||||
|                 generator?.next() |                 generator?.next() | ||||||
|                 generator?.generateLinks(clearCache = false, isCasting = false, {}, {}) |                 generator?.generateLinks(clearCache = false, isCasting = false, {}, {}) | ||||||
|  |  | ||||||
|  | @ -57,7 +57,7 @@ class PlayerSubtitleHelper { | ||||||
|                 endsWith("vtt", true) -> MimeTypes.TEXT_VTT |                 endsWith("vtt", true) -> MimeTypes.TEXT_VTT | ||||||
|                 endsWith("srt", true) -> MimeTypes.APPLICATION_SUBRIP |                 endsWith("srt", true) -> MimeTypes.APPLICATION_SUBRIP | ||||||
|                 endsWith("xml", true) || endsWith("ttml", true) -> MimeTypes.APPLICATION_TTML |                 endsWith("xml", true) || endsWith("ttml", true) -> MimeTypes.APPLICATION_TTML | ||||||
|                 else -> MimeTypes.APPLICATION_SUBRIP // TODO get request to see |                 else -> MimeTypes.APPLICATION_SUBRIP | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -46,7 +46,7 @@ class RepoLinkGenerator(private val episodes: List<ResultEpisode>, private var c | ||||||
|     var linkCache = Array<Set<ExtractorLink>>(size = episodes.size, init = { setOf() }) |     var linkCache = Array<Set<ExtractorLink>>(size = episodes.size, init = { setOf() }) | ||||||
|     var subsCache = Array<Set<SubtitleData>>(size = episodes.size, init = { setOf() }) |     var subsCache = Array<Set<SubtitleData>>(size = episodes.size, init = { setOf() }) | ||||||
| 
 | 
 | ||||||
|     override fun generateLinks( |     override suspend fun generateLinks( | ||||||
|         clearCache: Boolean, |         clearCache: Boolean, | ||||||
|         isCasting: Boolean, |         isCasting: Boolean, | ||||||
|         callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit, |         callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit, | ||||||
|  |  | ||||||
|  | @ -98,6 +98,14 @@ object AppUtils { | ||||||
|         return mapper.readValue(value) |         return mapper.readValue(value) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     inline fun <reified T> tryParseJson(value : String): T? { | ||||||
|  |         return try { | ||||||
|  |             parseJson(value) | ||||||
|  |         } catch (_ : Exception) { | ||||||
|  |             null | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /**| S1:E2 Hello World |     /**| S1:E2 Hello World | ||||||
|      * | Episode 2. Hello world |      * | Episode 2. Hello world | ||||||
|      * | Hello World |      * | Hello World | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue