mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
removed theflix
This commit is contained in:
parent
ac2760bacf
commit
87560d66bd
4 changed files with 353 additions and 195 deletions
|
@ -9,6 +9,10 @@ import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
|
|
||||||
|
|
||||||
class TheFlixToProvider : MainAPI() {
|
class TheFlixToProvider : MainAPI() {
|
||||||
|
companion object {
|
||||||
|
var latestCookies: Map<String, String> = emptyMap()
|
||||||
|
}
|
||||||
|
|
||||||
override var name = "TheFlix.to"
|
override var name = "TheFlix.to"
|
||||||
override var mainUrl = "https://theflix.to"
|
override var mainUrl = "https://theflix.to"
|
||||||
override val instantLinkLoading = false
|
override val instantLinkLoading = false
|
||||||
|
@ -99,16 +103,34 @@ class TheFlixToProvider : MainAPI() {
|
||||||
val json = parseJson<HomeJson>(scriptText)
|
val json = parseJson<HomeJson>(scriptText)
|
||||||
val homePageProps = json.props.pageProps
|
val homePageProps = json.props.pageProps
|
||||||
listOf(
|
listOf(
|
||||||
Triple(homePageProps.moviesListNewArrivals.docs, homePageProps.moviesListNewArrivals.type, "New Movie arrivals"),
|
Triple(
|
||||||
Triple(homePageProps.moviesListTrending.docs, homePageProps.moviesListTrending.type, "Trending Movies"),
|
homePageProps.moviesListNewArrivals.docs,
|
||||||
Triple(homePageProps.tvsListTrending.docs, homePageProps.tvsListTrending.type, "Trending TV Series"),
|
homePageProps.moviesListNewArrivals.type,
|
||||||
Triple(homePageProps.tvsListNewEpisodes.docs, homePageProps.tvsListNewEpisodes.type, "New Episodes")
|
"New Movie arrivals"
|
||||||
|
),
|
||||||
|
Triple(
|
||||||
|
homePageProps.moviesListTrending.docs,
|
||||||
|
homePageProps.moviesListTrending.type,
|
||||||
|
"Trending Movies"
|
||||||
|
),
|
||||||
|
Triple(
|
||||||
|
homePageProps.tvsListTrending.docs,
|
||||||
|
homePageProps.tvsListTrending.type,
|
||||||
|
"Trending TV Series"
|
||||||
|
),
|
||||||
|
Triple(
|
||||||
|
homePageProps.tvsListNewEpisodes.docs,
|
||||||
|
homePageProps.tvsListNewEpisodes.type,
|
||||||
|
"New Episodes"
|
||||||
|
)
|
||||||
).map { (docs, type, homename) ->
|
).map { (docs, type, homename) ->
|
||||||
val home = docs.map { info ->
|
val home = docs.map { info ->
|
||||||
val title = info.name
|
val title = info.name
|
||||||
val poster = info.posterUrl
|
val poster = info.posterUrl
|
||||||
val typeinfo = if (type?.contains("TV") == true) TvType.TvSeries else TvType.Movie
|
val typeinfo =
|
||||||
val link = if (typeinfo == TvType.Movie) "$mainUrl/movie/${info.id}-${cleanTitle(title)}"
|
if (type?.contains("TV") == true) TvType.TvSeries else TvType.Movie
|
||||||
|
val link =
|
||||||
|
if (typeinfo == TvType.Movie) "$mainUrl/movie/${info.id}-${cleanTitle(title)}"
|
||||||
else "$mainUrl/tv-show/${info.id}-${cleanTitle(title)}/season-1/episode-1"
|
else "$mainUrl/tv-show/${info.id}-${cleanTitle(title)}/season-1/episode-1"
|
||||||
TvSeriesSearchResponse(
|
TvSeriesSearchResponse(
|
||||||
title,
|
title,
|
||||||
|
@ -168,8 +190,11 @@ class TheFlixToProvider : MainAPI() {
|
||||||
docs.map { info ->
|
docs.map { info ->
|
||||||
val title = info.name
|
val title = info.name
|
||||||
val poster = info.posterUrl
|
val poster = info.posterUrl
|
||||||
val typeinfo = if (type?.contains("TV") == true) TvType.TvSeries else TvType.Movie
|
val typeinfo =
|
||||||
val link = if (typeinfo == TvType.Movie) "$mainUrl/movie/${info.id}-${cleanTitle(title)}"
|
if (type?.contains("TV") == true) TvType.TvSeries else TvType.Movie
|
||||||
|
val link = if (typeinfo == TvType.Movie) "$mainUrl/movie/${info.id}-${
|
||||||
|
cleanTitle(title)
|
||||||
|
}"
|
||||||
else "$mainUrl/tv-show/${info.id}-${cleanTitle(title)}/season-1/episode-1"
|
else "$mainUrl/tv-show/${info.id}-${cleanTitle(title)}/season-1/episode-1"
|
||||||
if (typeinfo == TvType.Movie) {
|
if (typeinfo == TvType.Movie) {
|
||||||
search.add(
|
search.add(
|
||||||
|
@ -205,7 +230,47 @@ class TheFlixToProvider : MainAPI() {
|
||||||
|
|
||||||
data class LoadMain(
|
data class LoadMain(
|
||||||
@JsonProperty("props") val props: LoadProps = LoadProps(),
|
@JsonProperty("props") val props: LoadProps = LoadProps(),
|
||||||
|
@JsonProperty("page") var page: String? = null,
|
||||||
|
//@JsonProperty("query") val query: Query? = Query(),
|
||||||
|
@JsonProperty("buildId") val buildId: String? = null,
|
||||||
|
@JsonProperty("runtimeConfig") val runtimeConfig: RuntimeConfig? = RuntimeConfig(),
|
||||||
|
@JsonProperty("isFallback") val isFallback: Boolean? = null,
|
||||||
|
@JsonProperty("customServer") val customServer: Boolean? = null,
|
||||||
|
@JsonProperty("appGip") val appGip: Boolean? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class RuntimeConfig(
|
||||||
|
@JsonProperty("AddThisService") val AddThisService: AddThisService? = AddThisService(),
|
||||||
|
//@JsonProperty("Application") val Application: Application? = Application(),
|
||||||
|
//@JsonProperty("Content") val Content: Content? = Content(),
|
||||||
|
//@JsonProperty("GtmService") val GtmService: GtmService? = GtmService(),
|
||||||
|
//@JsonProperty("IptvChannels") val IptvChannels: IptvChannels? = IptvChannels(),
|
||||||
|
//@JsonProperty("Notifications") val Notifications: Notifications? = Notifications(),
|
||||||
|
//@JsonProperty("Payments") val Payments: Payments? = Payments(),
|
||||||
|
//@JsonProperty("Redux") val Redux: Redux? = Redux(),
|
||||||
|
//@JsonProperty("Search") val Search: Search? = Search(),
|
||||||
|
@JsonProperty("Services") val Services: Services? = Services(),
|
||||||
|
//@JsonProperty("Sitemap") val Sitemap: Sitemap? = Sitemap(),
|
||||||
|
//@JsonProperty("Support") val Support: Support? = Support(),
|
||||||
|
@JsonProperty("Videos") val Videos: Videos? = Videos()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
data class Server(
|
||||||
|
@JsonProperty("Url") var Url: String? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Services(
|
||||||
|
|
||||||
|
@JsonProperty("Server") val Server: Server? = Server(),
|
||||||
|
@JsonProperty("TmdbServer") val TmdbServer: Server? = Server()
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
data class AddThisService(
|
||||||
|
@JsonProperty("PublicId") val PublicId: String? = null
|
||||||
|
)
|
||||||
|
|
||||||
data class LoadProps(
|
data class LoadProps(
|
||||||
@JsonProperty("pageProps") val pageProps: LoadPageProps = LoadPageProps(),
|
@JsonProperty("pageProps") val pageProps: LoadPageProps = LoadPageProps(),
|
||||||
)
|
)
|
||||||
|
@ -220,7 +285,6 @@ class TheFlixToProvider : MainAPI() {
|
||||||
data class Genres(
|
data class Genres(
|
||||||
@JsonProperty("name") val name: String,
|
@JsonProperty("name") val name: String,
|
||||||
@JsonProperty("id") val id: Int? = null
|
@JsonProperty("id") val id: Int? = null
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Seasons(
|
data class Seasons(
|
||||||
|
@ -330,11 +394,54 @@ class TheFlixToProvider : MainAPI() {
|
||||||
.replace("'", "-")).lowercase()
|
.replace("'", "-")).lowercase()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun getLoadMan(url: String): LoadMain {
|
||||||
|
val og = app.get(url, cookies = latestCookies)
|
||||||
|
val soup = og.document
|
||||||
|
val script = soup.selectFirst("script[type=application/json]").data()
|
||||||
|
return parseJson(script)
|
||||||
|
}
|
||||||
|
|
||||||
|
// I legit cant figure this out
|
||||||
|
private suspend fun getLoadMainRetry(url: String): LoadMain {
|
||||||
|
val first = getLoadMan(url)
|
||||||
|
val notFound = "/404"
|
||||||
|
if (first.page == notFound) {
|
||||||
|
first.runtimeConfig?.Services?.TmdbServer?.Url?.let { authUrl ->
|
||||||
|
val optionsUrl = "$authUrl/authorization/session/continue?contentUsageType=Viewing"
|
||||||
|
val options = app.options(
|
||||||
|
optionsUrl,
|
||||||
|
headers = mapOf(
|
||||||
|
"User-Agent" to USER_AGENT,
|
||||||
|
"Access-Control-Request-Method" to "POST",
|
||||||
|
"Access-Control-Request-Headers" to "content-type",
|
||||||
|
"Origin" to url,
|
||||||
|
"Referer" to mainUrl,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
//{"affiliateCode":"","pathname":"/movie/696806-the-adam-project"}
|
||||||
|
val data = mapOf("affiliateCode" to "", "pathname" to url.removePrefix(mainUrl))
|
||||||
|
val resp = app.post(optionsUrl, headers = mapOf(
|
||||||
|
"User-Agent" to USER_AGENT,
|
||||||
|
"Content-Type" to "application/json;charset=UTF-8",
|
||||||
|
"Accept" to "application/json, text/plain, */*",
|
||||||
|
"Origin" to url,
|
||||||
|
"Referer" to mainUrl,
|
||||||
|
), data = data)
|
||||||
|
|
||||||
|
latestCookies = resp.cookies
|
||||||
|
val newData = getLoadMan(url)
|
||||||
|
if (newData.page == notFound) {
|
||||||
|
throw ErrorLoadingException("404 Not found")
|
||||||
|
}
|
||||||
|
return newData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return first
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun load(url: String): LoadResponse? {
|
override suspend fun load(url: String): LoadResponse? {
|
||||||
val soup = app.get(url).document
|
|
||||||
val scripttext = soup.selectFirst("script[type=application/json]").data()
|
|
||||||
val tvtype = if (url.contains("movie")) TvType.Movie else TvType.TvSeries
|
val tvtype = if (url.contains("movie")) TvType.Movie else TvType.TvSeries
|
||||||
val json = parseJson<LoadMain>(scripttext)
|
val json = getLoadMainRetry(url)
|
||||||
val episodes = ArrayList<TvSeriesEpisode>()
|
val episodes = ArrayList<TvSeriesEpisode>()
|
||||||
val isMovie = tvtype == TvType.Movie
|
val isMovie = tvtype == TvType.Movie
|
||||||
val pageMain = json.props.pageProps
|
val pageMain = json.props.pageProps
|
||||||
|
@ -343,7 +450,7 @@ class TheFlixToProvider : MainAPI() {
|
||||||
|
|
||||||
val available = metadata?.available
|
val available = metadata?.available
|
||||||
|
|
||||||
val comingsoon = !available!!
|
val comingsoon = available!!
|
||||||
|
|
||||||
val movieId = metadata.id
|
val movieId = metadata.id
|
||||||
|
|
||||||
|
@ -443,9 +550,7 @@ class TheFlixToProvider : MainAPI() {
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val doc = app.get(data).document
|
val json = getLoadMainRetry(data)
|
||||||
val script = doc.selectFirst("script[type=application/json]").data()
|
|
||||||
val json = parseJson<LoadMain>(script)
|
|
||||||
val extractedLink = json.props.pageProps.videoUrl
|
val extractedLink = json.props.pageProps.videoUrl
|
||||||
val qualityReg = Regex("(\\d+p)")
|
val qualityReg = Regex("(\\d+p)")
|
||||||
if (extractedLink != null) {
|
if (extractedLink != null) {
|
||||||
|
@ -458,7 +563,8 @@ class TheFlixToProvider : MainAPI() {
|
||||||
"",
|
"",
|
||||||
getQualityFromName(quality),
|
getQualityFromName(quality),
|
||||||
false
|
false
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,6 +226,24 @@ fun putRequestCreator(
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun optionsRequestCreator(
|
||||||
|
url: String,
|
||||||
|
headers: Map<String, String>,
|
||||||
|
referer: String?,
|
||||||
|
params: Map<String, String?>,
|
||||||
|
cookies: Map<String, String>,
|
||||||
|
data: Map<String, String?>,
|
||||||
|
cacheTime: Int,
|
||||||
|
cacheUnit: TimeUnit
|
||||||
|
): Request {
|
||||||
|
return Request.Builder()
|
||||||
|
.url(addParamsToUrl(url, params))
|
||||||
|
.cacheControl(getCache(cacheTime, cacheUnit))
|
||||||
|
.headers(getHeaders(headers, referer, cookies))
|
||||||
|
.method("OPTIONS", getData(data))
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/a/59322754
|
// https://stackoverflow.com/a/59322754
|
||||||
// Issues with Akwam otherwise
|
// Issues with Akwam otherwise
|
||||||
fun OkHttpClient.Builder.ignoreAllSSLErrors(): OkHttpClient.Builder {
|
fun OkHttpClient.Builder.ignoreAllSSLErrors(): OkHttpClient.Builder {
|
||||||
|
@ -370,6 +388,40 @@ open class Requests {
|
||||||
return AppResponse(response)
|
return AppResponse(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun options(
|
||||||
|
url: String,
|
||||||
|
headers: Map<String, String> = mapOf(),
|
||||||
|
referer: String? = null,
|
||||||
|
params: Map<String, String> = mapOf(),
|
||||||
|
cookies: Map<String, String> = mapOf(),
|
||||||
|
data: Map<String, String?> = DEFAULT_DATA,
|
||||||
|
allowRedirects: Boolean = true,
|
||||||
|
cacheTime: Int = DEFAULT_TIME,
|
||||||
|
cacheUnit: TimeUnit = DEFAULT_TIME_UNIT,
|
||||||
|
timeout: Long = 0L
|
||||||
|
): AppResponse {
|
||||||
|
Log.i("OPTIONS", url)
|
||||||
|
val client = baseClient
|
||||||
|
.newBuilder()
|
||||||
|
.followRedirects(allowRedirects)
|
||||||
|
.followSslRedirects(allowRedirects)
|
||||||
|
.callTimeout(timeout, TimeUnit.SECONDS)
|
||||||
|
.build()
|
||||||
|
val request =
|
||||||
|
optionsRequestCreator(
|
||||||
|
url,
|
||||||
|
headers,
|
||||||
|
referer,
|
||||||
|
params,
|
||||||
|
cookies,
|
||||||
|
data,
|
||||||
|
cacheTime,
|
||||||
|
cacheUnit
|
||||||
|
)
|
||||||
|
val response = client.newCall(request).await()
|
||||||
|
return AppResponse(response)
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun put(
|
suspend fun put(
|
||||||
url: String,
|
url: String,
|
||||||
headers: Map<String, String> = mapOf(),
|
headers: Map<String, String> = mapOf(),
|
||||||
|
|
|
@ -237,7 +237,7 @@
|
||||||
"TheFlixToProvider": {
|
"TheFlixToProvider": {
|
||||||
"name": "TheFlix.to",
|
"name": "TheFlix.to",
|
||||||
"url": "https://theflix.to",
|
"url": "https://theflix.to",
|
||||||
"status": 1
|
"status": 0
|
||||||
},
|
},
|
||||||
"TwoEmbedProvider": {
|
"TwoEmbedProvider": {
|
||||||
"name": "2Embed",
|
"name": "2Embed",
|
||||||
|
|
|
@ -237,7 +237,7 @@
|
||||||
"TheFlixToProvider": {
|
"TheFlixToProvider": {
|
||||||
"name": "TheFlix.to",
|
"name": "TheFlix.to",
|
||||||
"url": "https://theflix.to",
|
"url": "https://theflix.to",
|
||||||
"status": 1
|
"status": 0
|
||||||
},
|
},
|
||||||
"TwoEmbedProvider": {
|
"TwoEmbedProvider": {
|
||||||
"name": "2Embed",
|
"name": "2Embed",
|
||||||
|
|
Loading…
Reference in a new issue