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