mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
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,7 +147,12 @@ 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(
|
||||||
|
title,
|
||||||
|
url,
|
||||||
|
type,
|
||||||
|
data.filter { it != "about:blank" }.toJson()
|
||||||
|
) {
|
||||||
posterUrl = backgroundPoster
|
posterUrl = backgroundPoster
|
||||||
this.year = year?.toIntOrNull()
|
this.year = year?.toIntOrNull()
|
||||||
this.plot = descipt
|
this.plot = descipt
|
||||||
|
@ -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…
Reference in a new issue