forked from recloudstream/cloudstream
added AsiaFlixProvider.kt (more sources are possible)
This commit is contained in:
parent
b68ac0bd1f
commit
9812b2ebd6
2 changed files with 186 additions and 4 deletions
|
@ -6,10 +6,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
import com.lagradost.cloudstream3.animeproviders.*
|
import com.lagradost.cloudstream3.animeproviders.*
|
||||||
import com.lagradost.cloudstream3.movieproviders.AllMoviesForYouProvider
|
import com.lagradost.cloudstream3.movieproviders.*
|
||||||
import com.lagradost.cloudstream3.movieproviders.HDMProvider
|
|
||||||
import com.lagradost.cloudstream3.movieproviders.TrailersToProvider
|
|
||||||
import com.lagradost.cloudstream3.movieproviders.VMoveeProvider
|
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -43,6 +40,7 @@ object APIHolder {
|
||||||
VMoveeProvider(),
|
VMoveeProvider(),
|
||||||
WatchCartoonOnlineProvider(),
|
WatchCartoonOnlineProvider(),
|
||||||
AllMoviesForYouProvider(),
|
AllMoviesForYouProvider(),
|
||||||
|
AsiaFlixProvider(),
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getApiFromName(apiName: String?): MainAPI {
|
fun getApiFromName(apiName: String?): MainAPI {
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
package com.lagradost.cloudstream3.movieproviders
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.fasterxml.jackson.core.JsonParser
|
||||||
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.getStatus
|
||||||
|
import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
|
import khttp.get
|
||||||
|
|
||||||
|
class AsiaFlixProvider : MainAPI() {
|
||||||
|
override val mainUrl: String
|
||||||
|
get() = "https://asiaflix.app"
|
||||||
|
override val name: String
|
||||||
|
get() = "AsiaFlix"
|
||||||
|
override val hasQuickSearch: Boolean
|
||||||
|
get() = false
|
||||||
|
override val hasMainPage: Boolean
|
||||||
|
get() = true
|
||||||
|
override val hasDownloadSupport: Boolean
|
||||||
|
get() = false
|
||||||
|
override val hasChromecastSupport: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
private val apiUrl = "https://api.asiaflix.app/api/v2"
|
||||||
|
|
||||||
|
data class DashBoardObject(
|
||||||
|
@JsonProperty("sectionName") val sectionName: String,
|
||||||
|
@JsonProperty("type") val type: String?,
|
||||||
|
@JsonProperty("data") val data: List<Data>?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Episodes(
|
||||||
|
@JsonProperty("_id") val _id: String,
|
||||||
|
@JsonProperty("epUrl") val epUrl: String?,
|
||||||
|
@JsonProperty("number") val number: Int?,
|
||||||
|
@JsonProperty("type") val type: String?,
|
||||||
|
@JsonProperty("extracted") val extracted: String?,
|
||||||
|
@JsonProperty("videoUrl") val videoUrl: String?
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
data class Data(
|
||||||
|
@JsonProperty("_id") val _id: String,
|
||||||
|
@JsonProperty("name") val name: String,
|
||||||
|
@JsonProperty("altNames") val altNames: String?,
|
||||||
|
@JsonProperty("image") val image: String?,
|
||||||
|
@JsonProperty("tvStatus") val tvStatus: String?,
|
||||||
|
@JsonProperty("genre") val genre: String?,
|
||||||
|
@JsonProperty("releaseYear") val releaseYear: Int?,
|
||||||
|
@JsonProperty("createdAt") val createdAt: Long?,
|
||||||
|
@JsonProperty("episodes") val episodes: List<Episodes>?,
|
||||||
|
@JsonProperty("views") val views: Int?
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
data class DramaPage(
|
||||||
|
@JsonProperty("_id") val _id: String,
|
||||||
|
@JsonProperty("name") val name: String,
|
||||||
|
@JsonProperty("altNames") val altNames: String?,
|
||||||
|
@JsonProperty("synopsis") val synopsis: String?,
|
||||||
|
@JsonProperty("image") val image: String?,
|
||||||
|
@JsonProperty("language") val language: String?,
|
||||||
|
@JsonProperty("dramaUrl") val dramaUrl: String?,
|
||||||
|
@JsonProperty("published") val published: Boolean?,
|
||||||
|
@JsonProperty("tvStatus") val tvStatus: String?,
|
||||||
|
@JsonProperty("firstAirDate") val firstAirDate: String?,
|
||||||
|
@JsonProperty("genre") val genre: String?,
|
||||||
|
@JsonProperty("releaseYear") val releaseYear: Int?,
|
||||||
|
@JsonProperty("createdAt") val createdAt: Long?,
|
||||||
|
@JsonProperty("modifiedAt") val modifiedAt: Long?,
|
||||||
|
@JsonProperty("episodes") val episodes: List<Episodes>,
|
||||||
|
@JsonProperty("__v") val __v: Int?,
|
||||||
|
@JsonProperty("cdnImage") val cdnImage: String?,
|
||||||
|
@JsonProperty("views") val views: Int?
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun Data.toSearchResponse(): TvSeriesSearchResponse {
|
||||||
|
return TvSeriesSearchResponse(
|
||||||
|
name,
|
||||||
|
_id,
|
||||||
|
this@AsiaFlixProvider.name,
|
||||||
|
TvType.TvSeries,
|
||||||
|
image,
|
||||||
|
releaseYear,
|
||||||
|
episodes?.size,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Episodes.toTvSeriesEpisode(): TvSeriesEpisode? {
|
||||||
|
return videoUrl?.let {
|
||||||
|
TvSeriesEpisode(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
number,
|
||||||
|
it
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DramaPage.toLoadResponse(): TvSeriesLoadResponse {
|
||||||
|
return TvSeriesLoadResponse(
|
||||||
|
name,
|
||||||
|
_id,
|
||||||
|
this@AsiaFlixProvider.name,
|
||||||
|
TvType.TvSeries,
|
||||||
|
episodes.mapNotNull { it.toTvSeriesEpisode() }.sortedBy { it.episode },
|
||||||
|
image,
|
||||||
|
releaseYear,
|
||||||
|
synopsis,
|
||||||
|
getStatus(tvStatus ?: ""),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
genre?.split(",")?.map { it.trim() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMainPage(): HomePageResponse {
|
||||||
|
val headers = mapOf("X-Requested-By" to "asiaflix-web")
|
||||||
|
val response = get("$apiUrl/dashboard", headers = headers).text
|
||||||
|
|
||||||
|
val customMapper = mapper.copy().configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
|
||||||
|
// Hack, because it can either be object or a list
|
||||||
|
val cleanedResponse = Regex(""""data":(\{.*?),\{"sectionName"""").replace(response) {
|
||||||
|
""""data":null},{"sectionName""""
|
||||||
|
}
|
||||||
|
|
||||||
|
val dashBoard = customMapper.readValue<List<DashBoardObject>?>(cleanedResponse)
|
||||||
|
|
||||||
|
val listItems = dashBoard?.mapNotNull {
|
||||||
|
it.data?.map { data ->
|
||||||
|
data.toSearchResponse()
|
||||||
|
}?.let { searchResponse ->
|
||||||
|
HomePageList(it.sectionName, searchResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return HomePageResponse(listItems ?: listOf())
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Link(
|
||||||
|
@JsonProperty("url") val url: String?,
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun loadLinks(
|
||||||
|
data: String,
|
||||||
|
isCasting: Boolean,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
): Boolean {
|
||||||
|
if (isCasting) return false
|
||||||
|
val headers = mapOf("X-Requested-By" to "asiaflix-web")
|
||||||
|
get("$apiUrl/utility/get-stream-links?url=$data", headers = headers).text.toKotlinObject<Link>().url?.let {
|
||||||
|
// val fixedUrl = "https://api.asiaflix.app/api/v2/utility/cors-proxy/playlist/${URLEncoder.encode(it, StandardCharsets.UTF_8.toString())}"
|
||||||
|
callback.invoke(
|
||||||
|
ExtractorLink(
|
||||||
|
name,
|
||||||
|
name,
|
||||||
|
it,
|
||||||
|
"https://asianload.me/",
|
||||||
|
getQualityFromName(it),
|
||||||
|
it.endsWith(".m3u8")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun search(query: String): List<SearchResponse>? {
|
||||||
|
val headers = mapOf("X-Requested-By" to "asiaflix-web")
|
||||||
|
val url = "$apiUrl/drama/search?q=$query"
|
||||||
|
val response = get(url, headers = headers).text
|
||||||
|
return mapper.readValue<List<Data>?>(response)?.map { it.toSearchResponse() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun load(url: String): LoadResponse {
|
||||||
|
val headers = mapOf("X-Requested-By" to "asiaflix-web")
|
||||||
|
val requestUrl = "$apiUrl/drama?id=${url.split("/").lastOrNull()}"
|
||||||
|
val response = get(requestUrl, headers = headers).text
|
||||||
|
val dramaPage = response.toKotlinObject<DramaPage>()
|
||||||
|
return dramaPage.toLoadResponse()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue