forked from recloudstream/cloudstream
mainApi changes
This commit is contained in:
parent
117730e9a8
commit
94561e0d5b
19 changed files with 358 additions and 325 deletions
|
@ -111,6 +111,12 @@ object APIHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
var apis: List<MainAPI> = arrayListOf()
|
var apis: List<MainAPI> = arrayListOf()
|
||||||
|
private var apiMap: Map<String, Int>? = null
|
||||||
|
|
||||||
|
private fun initMap() {
|
||||||
|
if (apiMap == null)
|
||||||
|
apiMap = apis.mapIndexed { index, api -> api.name to index }.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
fun getApiFromName(apiName: String?): MainAPI {
|
fun getApiFromName(apiName: String?): MainAPI {
|
||||||
return getApiFromNameNull(apiName) ?: apis[defProvider]
|
return getApiFromNameNull(apiName) ?: apis[defProvider]
|
||||||
|
@ -118,11 +124,9 @@ object APIHolder {
|
||||||
|
|
||||||
fun getApiFromNameNull(apiName: String?): MainAPI? {
|
fun getApiFromNameNull(apiName: String?): MainAPI? {
|
||||||
if (apiName == null) return null
|
if (apiName == null) return null
|
||||||
for (api in allProviders) {
|
initMap()
|
||||||
if (apiName == api.name)
|
|
||||||
return api
|
return apiMap?.get(apiName)?.let { apis.getOrNull(it) }
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getApiFromUrlNull(url: String?): MainAPI? {
|
fun getApiFromUrlNull(url: String?): MainAPI? {
|
||||||
|
@ -622,10 +626,65 @@ interface SearchResponse {
|
||||||
val apiName: String
|
val apiName: String
|
||||||
var type: TvType?
|
var type: TvType?
|
||||||
var posterUrl: String?
|
var posterUrl: String?
|
||||||
|
var posterHeaders: Map<String, String>?
|
||||||
var id: Int?
|
var id: Int?
|
||||||
var quality: SearchQuality?
|
var quality: SearchQuality?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun MainAPI.newMovieSearchResponse(
|
||||||
|
name: String,
|
||||||
|
url: String,
|
||||||
|
type: TvType = TvType.Movie,
|
||||||
|
fix: Boolean = true,
|
||||||
|
initializer: MovieSearchResponse.() -> Unit = { },
|
||||||
|
): MovieSearchResponse {
|
||||||
|
val builder = MovieSearchResponse(name, if (fix) fixUrl(url) else url, this.name, type)
|
||||||
|
builder.initializer()
|
||||||
|
|
||||||
|
return builder
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MainAPI.newTvSeriesSearchResponse(
|
||||||
|
name: String,
|
||||||
|
url: String,
|
||||||
|
type: TvType = TvType.TvSeries,
|
||||||
|
fix: Boolean = true,
|
||||||
|
initializer: TvSeriesSearchResponse.() -> Unit = { },
|
||||||
|
): TvSeriesSearchResponse {
|
||||||
|
val builder = TvSeriesSearchResponse(name, if (fix) fixUrl(url) else url, this.name, type)
|
||||||
|
builder.initializer()
|
||||||
|
|
||||||
|
return builder
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun MainAPI.newAnimeSearchResponse(
|
||||||
|
name: String,
|
||||||
|
url: String,
|
||||||
|
type: TvType = TvType.Anime,
|
||||||
|
fix: Boolean = true,
|
||||||
|
initializer: AnimeSearchResponse.() -> Unit = { },
|
||||||
|
): AnimeSearchResponse {
|
||||||
|
val builder = AnimeSearchResponse(name, if (fix) fixUrl(url) else url, this.name, type)
|
||||||
|
builder.initializer()
|
||||||
|
|
||||||
|
return builder
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SearchResponse.addQuality(quality: String) {
|
||||||
|
this.quality = getQualityFromString(quality)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SearchResponse.addPoster(url: String?, headers: Map<String, String>? = null) {
|
||||||
|
this.posterUrl = url
|
||||||
|
this.posterHeaders = headers
|
||||||
|
}
|
||||||
|
|
||||||
|
fun LoadResponse.addPoster(url: String?, headers: Map<String, String>? = null) {
|
||||||
|
this.posterUrl = url
|
||||||
|
this.posterHeaders = headers
|
||||||
|
}
|
||||||
|
|
||||||
enum class ActorRole {
|
enum class ActorRole {
|
||||||
Main,
|
Main,
|
||||||
Supporting,
|
Supporting,
|
||||||
|
@ -648,19 +707,62 @@ data class AnimeSearchResponse(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val url: String,
|
override val url: String,
|
||||||
override val apiName: String,
|
override val apiName: String,
|
||||||
override var type: TvType?,
|
override var type: TvType? = null,
|
||||||
|
|
||||||
override var posterUrl: String?,
|
override var posterUrl: String? = null,
|
||||||
val year: Int? = null,
|
var year: Int? = null,
|
||||||
val dubStatus: EnumSet<DubStatus>? = null,
|
var dubStatus: EnumSet<DubStatus>? = null,
|
||||||
|
|
||||||
|
var otherName: String? = null,
|
||||||
|
var episodes: MutableMap<DubStatus, Int> = mutableMapOf(),
|
||||||
|
|
||||||
val otherName: String? = null,
|
|
||||||
val dubEpisodes: Int? = null,
|
|
||||||
val subEpisodes: Int? = null,
|
|
||||||
override var id: Int? = null,
|
override var id: Int? = null,
|
||||||
override var quality: SearchQuality? = null,
|
override var quality: SearchQuality? = null,
|
||||||
|
override var posterHeaders: Map<String, String>? = null,
|
||||||
) : SearchResponse
|
) : SearchResponse
|
||||||
|
|
||||||
|
fun AnimeSearchResponse.addDubStatus(status: DubStatus, episodes: Int? = null) {
|
||||||
|
this.dubStatus = dubStatus?.also { it.add(status) } ?: EnumSet.of(status)
|
||||||
|
if (this.type?.isMovieType() != true)
|
||||||
|
if (episodes != null && episodes > 0)
|
||||||
|
this.episodes[status] = episodes
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AnimeSearchResponse.addDubStatus(isDub: Boolean, episodes: Int? = null) {
|
||||||
|
addDubStatus(if (isDub) DubStatus.Dubbed else DubStatus.Subbed, episodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AnimeSearchResponse.addDub(episodes: Int?) {
|
||||||
|
if(episodes == null || episodes <= 0) return
|
||||||
|
addDubStatus(DubStatus.Dubbed, episodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AnimeSearchResponse.addSub(episodes: Int?) {
|
||||||
|
if(episodes == null || episodes <= 0) return
|
||||||
|
addDubStatus(DubStatus.Subbed, episodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AnimeSearchResponse.addDubStatus(
|
||||||
|
dubExist: Boolean,
|
||||||
|
subExist: Boolean,
|
||||||
|
dubEpisodes: Int? = null,
|
||||||
|
subEpisodes: Int? = null
|
||||||
|
) {
|
||||||
|
if (dubExist)
|
||||||
|
addDubStatus(DubStatus.Dubbed, dubEpisodes)
|
||||||
|
|
||||||
|
if (subExist)
|
||||||
|
addDubStatus(DubStatus.Subbed, subEpisodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AnimeSearchResponse.addDubStatus(status: String, episodes: Int? = null) {
|
||||||
|
if (status.contains("(dub)", ignoreCase = true)) {
|
||||||
|
addDubStatus(DubStatus.Dubbed)
|
||||||
|
} else if (status.contains("(sub)", ignoreCase = true)) {
|
||||||
|
addDubStatus(DubStatus.Subbed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class TorrentSearchResponse(
|
data class TorrentSearchResponse(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val url: String,
|
override val url: String,
|
||||||
|
@ -670,31 +772,34 @@ data class TorrentSearchResponse(
|
||||||
override var posterUrl: String?,
|
override var posterUrl: String?,
|
||||||
override var id: Int? = null,
|
override var id: Int? = null,
|
||||||
override var quality: SearchQuality? = null,
|
override var quality: SearchQuality? = null,
|
||||||
|
override var posterHeaders: Map<String, String>? = null,
|
||||||
) : SearchResponse
|
) : SearchResponse
|
||||||
|
|
||||||
data class MovieSearchResponse(
|
data class MovieSearchResponse(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val url: String,
|
override val url: String,
|
||||||
override val apiName: String,
|
override val apiName: String,
|
||||||
override var type: TvType?,
|
override var type: TvType? = null,
|
||||||
|
|
||||||
override var posterUrl: String?,
|
override var posterUrl: String? = null,
|
||||||
val year: Int? = null,
|
val year: Int? = null,
|
||||||
override var id: Int? = null,
|
override var id: Int? = null,
|
||||||
override var quality: SearchQuality? = null,
|
override var quality: SearchQuality? = null,
|
||||||
|
override var posterHeaders: Map<String, String>? = null,
|
||||||
) : SearchResponse
|
) : SearchResponse
|
||||||
|
|
||||||
data class TvSeriesSearchResponse(
|
data class TvSeriesSearchResponse(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val url: String,
|
override val url: String,
|
||||||
override val apiName: String,
|
override val apiName: String,
|
||||||
override var type: TvType?,
|
override var type: TvType? = null,
|
||||||
|
|
||||||
override var posterUrl: String?,
|
override var posterUrl: String? = null,
|
||||||
val year: Int?,
|
val year: Int? = null,
|
||||||
val episodes: Int?,
|
val episodes: Int? = null,
|
||||||
override var id: Int? = null,
|
override var id: Int? = null,
|
||||||
override var quality: SearchQuality? = null,
|
override var quality: SearchQuality? = null,
|
||||||
|
override var posterHeaders: Map<String, String>? = null,
|
||||||
) : SearchResponse
|
) : SearchResponse
|
||||||
|
|
||||||
interface LoadResponse {
|
interface LoadResponse {
|
||||||
|
@ -713,6 +818,7 @@ interface LoadResponse {
|
||||||
var actors: List<ActorData>?
|
var actors: List<ActorData>?
|
||||||
var comingSoon: Boolean
|
var comingSoon: Boolean
|
||||||
var syncData: MutableMap<String, String>
|
var syncData: MutableMap<String, String>
|
||||||
|
var posterHeaders: Map<String, String>?
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val malIdPrefix = malApi.idPrefix
|
private val malIdPrefix = malApi.idPrefix
|
||||||
|
@ -844,6 +950,7 @@ data class TorrentLoadResponse(
|
||||||
override var actors: List<ActorData>? = null,
|
override var actors: List<ActorData>? = null,
|
||||||
override var comingSoon: Boolean = false,
|
override var comingSoon: Boolean = false,
|
||||||
override var syncData: MutableMap<String, String> = mutableMapOf(),
|
override var syncData: MutableMap<String, String> = mutableMapOf(),
|
||||||
|
override var posterHeaders: Map<String, String>? = null,
|
||||||
) : LoadResponse
|
) : LoadResponse
|
||||||
|
|
||||||
data class AnimeLoadResponse(
|
data class AnimeLoadResponse(
|
||||||
|
@ -871,6 +978,7 @@ data class AnimeLoadResponse(
|
||||||
override var actors: List<ActorData>? = null,
|
override var actors: List<ActorData>? = null,
|
||||||
override var comingSoon: Boolean = false,
|
override var comingSoon: Boolean = false,
|
||||||
override var syncData: MutableMap<String, String> = mutableMapOf(),
|
override var syncData: MutableMap<String, String> = mutableMapOf(),
|
||||||
|
override var posterHeaders: Map<String, String>? = null,
|
||||||
) : LoadResponse
|
) : LoadResponse
|
||||||
|
|
||||||
fun AnimeLoadResponse.addEpisodes(status: DubStatus, episodes: List<Episode>?) {
|
fun AnimeLoadResponse.addEpisodes(status: DubStatus, episodes: List<Episode>?) {
|
||||||
|
@ -882,7 +990,7 @@ fun MainAPI.newAnimeLoadResponse(
|
||||||
name: String,
|
name: String,
|
||||||
url: String,
|
url: String,
|
||||||
type: TvType,
|
type: TvType,
|
||||||
comingSoonIfNone: Boolean,
|
comingSoonIfNone: Boolean = true,
|
||||||
initializer: AnimeLoadResponse.() -> Unit = { },
|
initializer: AnimeLoadResponse.() -> Unit = { },
|
||||||
): AnimeLoadResponse {
|
): AnimeLoadResponse {
|
||||||
val builder = AnimeLoadResponse(name = name, url = url, apiName = this.name, type = type)
|
val builder = AnimeLoadResponse(name = name, url = url, apiName = this.name, type = type)
|
||||||
|
@ -898,15 +1006,6 @@ fun MainAPI.newAnimeLoadResponse(
|
||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MainAPI.newAnimeLoadResponse(
|
|
||||||
name: String,
|
|
||||||
url: String,
|
|
||||||
type: TvType,
|
|
||||||
initializer: AnimeLoadResponse.() -> Unit = { },
|
|
||||||
): AnimeLoadResponse {
|
|
||||||
return newAnimeLoadResponse(name, url, type, true, initializer)
|
|
||||||
}
|
|
||||||
|
|
||||||
data class MovieLoadResponse(
|
data class MovieLoadResponse(
|
||||||
override var name: String,
|
override var name: String,
|
||||||
override var url: String,
|
override var url: String,
|
||||||
|
@ -926,6 +1025,7 @@ data class MovieLoadResponse(
|
||||||
override var actors: List<ActorData>? = null,
|
override var actors: List<ActorData>? = null,
|
||||||
override var comingSoon: Boolean = false,
|
override var comingSoon: Boolean = false,
|
||||||
override var syncData: MutableMap<String, String> = mutableMapOf(),
|
override var syncData: MutableMap<String, String> = mutableMapOf(),
|
||||||
|
override var posterHeaders: Map<String, String>? = null,
|
||||||
) : LoadResponse
|
) : LoadResponse
|
||||||
|
|
||||||
fun <T> MainAPI.newMovieLoadResponse(
|
fun <T> MainAPI.newMovieLoadResponse(
|
||||||
|
@ -1046,6 +1146,7 @@ data class TvSeriesLoadResponse(
|
||||||
override var actors: List<ActorData>? = null,
|
override var actors: List<ActorData>? = null,
|
||||||
override var comingSoon: Boolean = false,
|
override var comingSoon: Boolean = false,
|
||||||
override var syncData: MutableMap<String, String> = mutableMapOf(),
|
override var syncData: MutableMap<String, String> = mutableMapOf(),
|
||||||
|
override var posterHeaders: Map<String, String>? = null,
|
||||||
) : LoadResponse
|
) : LoadResponse
|
||||||
|
|
||||||
fun MainAPI.newTvSeriesLoadResponse(
|
fun MainAPI.newTvSeriesLoadResponse(
|
||||||
|
|
|
@ -14,7 +14,6 @@ import org.mozilla.javascript.Context
|
||||||
import org.mozilla.javascript.Scriptable
|
import org.mozilla.javascript.Scriptable
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
class AllAnimeProvider : MainAPI() {
|
class AllAnimeProvider : MainAPI() {
|
||||||
|
@ -88,49 +87,48 @@ class AllAnimeProvider : MainAPI() {
|
||||||
@JsonProperty("data") val data: Data
|
@JsonProperty("data") val data: Data
|
||||||
)
|
)
|
||||||
|
|
||||||
data class RandomMain (
|
data class RandomMain(
|
||||||
@JsonProperty("data" ) var data : DataRan? = DataRan()
|
@JsonProperty("data") var data: DataRan? = DataRan()
|
||||||
)
|
)
|
||||||
|
|
||||||
data class DataRan (
|
data class DataRan(
|
||||||
@JsonProperty("queryRandomRecommendation" ) var queryRandomRecommendation : ArrayList<QueryRandomRecommendation> = arrayListOf()
|
@JsonProperty("queryRandomRecommendation") var queryRandomRecommendation: ArrayList<QueryRandomRecommendation> = arrayListOf()
|
||||||
)
|
)
|
||||||
|
|
||||||
data class QueryRandomRecommendation (
|
data class QueryRandomRecommendation(
|
||||||
@JsonProperty("_id" ) val Id : String? = null,
|
@JsonProperty("_id") val Id: String? = null,
|
||||||
@JsonProperty("name" ) val name : String? = null,
|
@JsonProperty("name") val name: String? = null,
|
||||||
@JsonProperty("englishName" ) val englishName : String? = null,
|
@JsonProperty("englishName") val englishName: String? = null,
|
||||||
@JsonProperty("nativeName" ) val nativeName : String? = null,
|
@JsonProperty("nativeName") val nativeName: String? = null,
|
||||||
@JsonProperty("thumbnail" ) val thumbnail : String? = null,
|
@JsonProperty("thumbnail") val thumbnail: String? = null,
|
||||||
@JsonProperty("airedStart" ) val airedStart : String? = null,
|
@JsonProperty("airedStart") val airedStart: String? = null,
|
||||||
@JsonProperty("availableChapters" ) val availableChapters : String? = null,
|
@JsonProperty("availableChapters") val availableChapters: String? = null,
|
||||||
@JsonProperty("availableEpisodes" ) val availableEpisodes : String? = null,
|
@JsonProperty("availableEpisodes") val availableEpisodes: String? = null,
|
||||||
@JsonProperty("__typename" ) val _typename : String? = null
|
@JsonProperty("__typename") val _typename: String? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
override suspend fun getMainPage(): HomePageResponse {
|
override suspend fun getMainPage(): HomePageResponse {
|
||||||
val items = ArrayList<HomePageList>()
|
val items = ArrayList<HomePageList>()
|
||||||
val urls = listOf(
|
val urls = listOf(
|
||||||
Pair("Top Anime",
|
Pair(
|
||||||
"$mainUrl/graphql?variables=%7B%22search%22%3A%7B%22allowAdult%22%3Afalse%2C%22sortBy%22%3A%22Top%22%7D%2C%22limit%22%3A26%2C%22page%22%3A1%2C%22translationType%22%3A%22sub%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%229343797cc3d9e3f444e2d3b7db9a84d759b816a4d84512ea72d079f85bb96e98%22%7D%7D"),
|
"Top Anime",
|
||||||
Pair("Animes",
|
"$mainUrl/graphql?variables=%7B%22search%22%3A%7B%22allowAdult%22%3Afalse%2C%22sortBy%22%3A%22Top%22%7D%2C%22limit%22%3A26%2C%22page%22%3A1%2C%22translationType%22%3A%22sub%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%229343797cc3d9e3f444e2d3b7db9a84d759b816a4d84512ea72d079f85bb96e98%22%7D%7D"
|
||||||
"$mainUrl/graphql?variables=%7B%22search%22%3A%7B%22allowAdult%22%3Afalse%7D%2C%22limit%22%3A26%2C%22page%22%3A1%2C%22translationType%22%3A%22sub%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%229343797cc3d9e3f444e2d3b7db9a84d759b816a4d84512ea72d079f85bb96e98%22%7D%7D"),
|
),
|
||||||
|
Pair(
|
||||||
|
"Animes",
|
||||||
|
"$mainUrl/graphql?variables=%7B%22search%22%3A%7B%22allowAdult%22%3Afalse%7D%2C%22limit%22%3A26%2C%22page%22%3A1%2C%22translationType%22%3A%22sub%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%229343797cc3d9e3f444e2d3b7db9a84d759b816a4d84512ea72d079f85bb96e98%22%7D%7D"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
val random = "$mainUrl/graphql?variables=%7B%22format%22%3A%22anime%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%2221ac672633498a3698e8f6a93ce6c2b3722b29a216dcca93363bf012c360cd54%22%7D%7D"
|
val random =
|
||||||
|
"$mainUrl/graphql?variables=%7B%22format%22%3A%22anime%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%2221ac672633498a3698e8f6a93ce6c2b3722b29a216dcca93363bf012c360cd54%22%7D%7D"
|
||||||
val ranlink = app.get(random).text
|
val ranlink = app.get(random).text
|
||||||
val jsonran = parseJson<RandomMain>(ranlink)
|
val jsonran = parseJson<RandomMain>(ranlink)
|
||||||
val ranhome = jsonran.data?.queryRandomRecommendation?.map {
|
val ranhome = jsonran.data?.queryRandomRecommendation?.map {
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(it.name!!,"$mainUrl/anime/${it.Id}", fix = false) {
|
||||||
it.name!!,
|
this.posterUrl = it.thumbnail
|
||||||
"$mainUrl/anime/${it.Id}",
|
this.otherName = it.nativeName
|
||||||
this.name,
|
}
|
||||||
TvType.Anime,
|
|
||||||
it.thumbnail,
|
|
||||||
null,
|
|
||||||
EnumSet.of(DubStatus.Subbed, DubStatus.Dubbed),
|
|
||||||
it.nativeName,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
items.add(HomePageList("Random", ranhome!!))
|
items.add(HomePageList("Random", ranhome!!))
|
||||||
|
@ -144,18 +142,14 @@ class AllAnimeProvider : MainAPI() {
|
||||||
!(it.availableEpisodes?.raw == 0 && it.availableEpisodes.sub == 0 && it.availableEpisodes.dub == 0)
|
!(it.availableEpisodes?.raw == 0 && it.availableEpisodes.sub == 0 && it.availableEpisodes.dub == 0)
|
||||||
}
|
}
|
||||||
results.map {
|
results.map {
|
||||||
home.add(AnimeSearchResponse(
|
home.add(
|
||||||
it.name,
|
newAnimeSearchResponse(it.name, "$mainUrl/anime/${it.Id}", fix = false) {
|
||||||
"$mainUrl/anime/${it.Id}",
|
this.posterUrl = it.thumbnail
|
||||||
this.name,
|
this.year = it.airedStart?.year
|
||||||
TvType.Anime,
|
this.otherName = it.englishName
|
||||||
it.thumbnail,
|
addDub(it.availableEpisodes?.dub)
|
||||||
it.airedStart?.year,
|
addSub(it.availableEpisodes?.sub)
|
||||||
EnumSet.of(DubStatus.Subbed, DubStatus.Dubbed),
|
})
|
||||||
it.englishName,
|
|
||||||
it.availableEpisodes?.dub,
|
|
||||||
it.availableEpisodes?.sub
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
items.add(HomePageList(HomeName, home))
|
items.add(HomePageList(HomeName, home))
|
||||||
}
|
}
|
||||||
|
@ -180,18 +174,13 @@ class AllAnimeProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return results.map {
|
return results.map {
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(it.name, "$mainUrl/anime/${it.Id}", fix = false) {
|
||||||
it.name,
|
this.posterUrl = it.thumbnail
|
||||||
"$mainUrl/anime/${it.Id}",
|
this.year = it.airedStart?.year
|
||||||
this.name,
|
this.otherName = it.englishName
|
||||||
TvType.Anime,
|
addDub(it.availableEpisodes?.dub)
|
||||||
it.thumbnail,
|
addSub(it.availableEpisodes?.sub)
|
||||||
it.airedStart?.year,
|
}
|
||||||
EnumSet.of(DubStatus.Subbed, DubStatus.Dubbed),
|
|
||||||
it.englishName,
|
|
||||||
it.availableEpisodes?.dub,
|
|
||||||
it.availableEpisodes?.sub
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.JsUnpacker
|
import com.lagradost.cloudstream3.utils.JsUnpacker
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.util.*
|
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
class AnimePaheProvider : MainAPI() {
|
class AnimePaheProvider : MainAPI() {
|
||||||
|
@ -84,19 +83,14 @@ class AnimePaheProvider : MainAPI() {
|
||||||
try {
|
try {
|
||||||
val response = app.get(i.first).text
|
val response = app.get(i.first).text
|
||||||
val episodes = mapper.readValue<AnimePaheLatestReleases>(response).data.map {
|
val episodes = mapper.readValue<AnimePaheLatestReleases>(response).data.map {
|
||||||
|
newAnimeSearchResponse(
|
||||||
AnimeSearchResponse(
|
|
||||||
it.animeTitle,
|
it.animeTitle,
|
||||||
"https://pahe.win/a/${it.animeId}?slug=${it.animeTitle}",
|
"https://pahe.win/a/${it.animeId}?slug=${it.animeTitle}",
|
||||||
this.name,
|
fix = false
|
||||||
TvType.Anime,
|
) {
|
||||||
it.snapshot,
|
this.posterUrl = it.snapshot
|
||||||
null,
|
addDubStatus(DubStatus.Subbed, it.episode)
|
||||||
EnumSet.of(DubStatus.Subbed),
|
}
|
||||||
null,
|
|
||||||
null,
|
|
||||||
it.episode
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
items.add(HomePageList(i.second, episodes))
|
items.add(HomePageList(i.second, episodes))
|
||||||
|
@ -151,18 +145,14 @@ class AnimePaheProvider : MainAPI() {
|
||||||
val data = req.let { mapper.readValue<AnimePaheSearch>(it) }
|
val data = req.let { mapper.readValue<AnimePaheSearch>(it) }
|
||||||
|
|
||||||
return data.data.map {
|
return data.data.map {
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(
|
||||||
it.title,
|
it.title,
|
||||||
"https://pahe.win/a/${it.id}?slug=${it.title}",
|
"https://pahe.win/a/${it.id}?slug=${it.title}",
|
||||||
this.name,
|
fix = false
|
||||||
TvType.Anime,
|
) {
|
||||||
it.poster,
|
this.posterUrl = it.poster
|
||||||
it.year,
|
addDubStatus(DubStatus.Subbed, it.episodes)
|
||||||
EnumSet.of(DubStatus.Subbed),
|
}
|
||||||
null,
|
|
||||||
null,
|
|
||||||
it.episodes
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +179,6 @@ class AnimePaheProvider : MainAPI() {
|
||||||
@JsonProperty("data") val data: List<AnimeData>
|
@JsonProperty("data") val data: List<AnimeData>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
private suspend fun generateListOfEpisodes(link: String): ArrayList<Episode> {
|
private suspend fun generateListOfEpisodes(link: String): ArrayList<Episode> {
|
||||||
try {
|
try {
|
||||||
val attrs = link.split('/')
|
val attrs = link.split('/')
|
||||||
|
|
|
@ -9,7 +9,6 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class AnimeWorldProvider : MainAPI() {
|
class AnimeWorldProvider : MainAPI() {
|
||||||
override var mainUrl = "https://www.animeworld.tv"
|
override var mainUrl = "https://www.animeworld.tv"
|
||||||
|
@ -31,6 +30,7 @@ class AnimeWorldProvider : MainAPI() {
|
||||||
else -> TvType.Anime
|
else -> TvType.Anime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStatus(t: String?): ShowStatus? {
|
fun getStatus(t: String?): ShowStatus? {
|
||||||
return when (t?.lowercase()) {
|
return when (t?.lowercase()) {
|
||||||
"finito" -> ShowStatus.Completed
|
"finito" -> ShowStatus.Completed
|
||||||
|
@ -54,25 +54,20 @@ class AnimeWorldProvider : MainAPI() {
|
||||||
|
|
||||||
val statusElement = this.select("div.status") // .first()
|
val statusElement = this.select("div.status") // .first()
|
||||||
val dub = statusElement.select(".dub").isNotEmpty()
|
val dub = statusElement.select(".dub").isNotEmpty()
|
||||||
val dubStatus = if (dub) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed)
|
|
||||||
val episode = statusElement.select(".ep").text().split(' ').last().toIntOrNull()
|
val episode = if (showEpisode) statusElement.select(".ep").text().split(' ').last()
|
||||||
|
.toIntOrNull() else null
|
||||||
val type = when {
|
val type = when {
|
||||||
statusElement.select(".movie").isNotEmpty() -> TvType.AnimeMovie
|
statusElement.select(".movie").isNotEmpty() -> TvType.AnimeMovie
|
||||||
statusElement.select(".ova").isNotEmpty() -> TvType.OVA
|
statusElement.select(".ova").isNotEmpty() -> TvType.OVA
|
||||||
else -> TvType.Anime
|
else -> TvType.Anime
|
||||||
}
|
}
|
||||||
|
|
||||||
return AnimeSearchResponse(
|
return newAnimeSearchResponse(title, url, type) {
|
||||||
title,
|
addDubStatus(dub, episode)
|
||||||
url,
|
this.otherName = otherTitle
|
||||||
name,
|
this.posterUrl = poster
|
||||||
type,
|
}
|
||||||
poster,
|
|
||||||
dubStatus = dubStatus,
|
|
||||||
otherName = if (otherTitle != title) otherTitle else null,
|
|
||||||
dubEpisodes = if (showEpisode && type != TvType.AnimeMovie && dub) episode else null,
|
|
||||||
subEpisodes = if (showEpisode && type != TvType.AnimeMovie && !dub) episode else null
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getMainPage(): HomePageResponse {
|
override suspend fun getMainPage(): HomePageResponse {
|
||||||
|
@ -113,14 +108,17 @@ class AnimeWorldProvider : MainAPI() {
|
||||||
arr[0].split(' ')[0].toIntOrNull()
|
arr[0].split(' ')[0].toIntOrNull()
|
||||||
else
|
else
|
||||||
arr[1].split(' ')[0].toIntOrNull()?.let {
|
arr[1].split(' ')[0].toIntOrNull()?.let {
|
||||||
arr[0].removeSuffix("h").toIntOrNull()?.times(60)!!.plus(it) }
|
arr[0].removeSuffix("h").toIntOrNull()?.times(60)!!.plus(it)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val document = app.get(url).document
|
val document = app.get(url).document
|
||||||
|
|
||||||
val widget = document.select("div.widget.info")
|
val widget = document.select("div.widget.info")
|
||||||
val title = widget.select(".info .title").text().removeSuffix(" (ITA)")
|
val title = widget.select(".info .title").text().removeSuffix(" (ITA)")
|
||||||
val otherTitle = widget.select(".info .title").attr("data-jtitle").removeSuffix(" (ITA)")
|
val otherTitle = widget.select(".info .title").attr("data-jtitle").removeSuffix(" (ITA)")
|
||||||
val description = widget.select(".desc .long").first()?.text() ?: widget.select(".desc").text()
|
val description =
|
||||||
|
widget.select(".desc .long").first()?.text() ?: widget.select(".desc").text()
|
||||||
val poster = document.select(".thumb img").attr("src")
|
val poster = document.select(".thumb img").attr("src")
|
||||||
|
|
||||||
val type: TvType = getType(widget.select("dd").first()?.text())
|
val type: TvType = getType(widget.select("dd").first()?.text())
|
||||||
|
|
|
@ -2,8 +2,9 @@ package com.lagradost.cloudstream3.animeproviders
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.utils.*
|
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class AnimeflvnetProvider:MainAPI() {
|
class AnimeflvnetProvider:MainAPI() {
|
||||||
|
@ -13,6 +14,11 @@ class AnimeflvnetProvider:MainAPI() {
|
||||||
else if (t.contains("Película")) TvType.AnimeMovie
|
else if (t.contains("Película")) TvType.AnimeMovie
|
||||||
else TvType.Anime
|
else TvType.Anime
|
||||||
}
|
}
|
||||||
|
fun getDubStatus(title: String): DubStatus {
|
||||||
|
return if (title.contains("Latino") || title.contains("Castellano"))
|
||||||
|
DubStatus.Dubbed
|
||||||
|
else DubStatus.Subbed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
override var mainUrl = "https://www3.animeflv.net"
|
override var mainUrl = "https://www3.animeflv.net"
|
||||||
override var name = "Animeflv.net"
|
override var name = "Animeflv.net"
|
||||||
|
@ -43,19 +49,10 @@ class AnimeflvnetProvider:MainAPI() {
|
||||||
val url = it.selectFirst("a").attr("href").replace(epRegex,"")
|
val url = it.selectFirst("a").attr("href").replace(epRegex,"")
|
||||||
.replace("ver/","anime/")
|
.replace("ver/","anime/")
|
||||||
val epNum = it.selectFirst("span.Capi").text().replace("Episodio ","").toIntOrNull()
|
val epNum = it.selectFirst("span.Capi").text().replace("Episodio ","").toIntOrNull()
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(title, url) {
|
||||||
title,
|
this.posterUrl = fixUrl(poster)
|
||||||
fixUrl(url),
|
addDubStatus(getDubStatus(title), epNum)
|
||||||
this.name,
|
}
|
||||||
TvType.Anime,
|
|
||||||
fixUrl(poster),
|
|
||||||
null,
|
|
||||||
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
|
|
||||||
DubStatus.Dubbed
|
|
||||||
) else EnumSet.of(DubStatus.Subbed),
|
|
||||||
subEpisodes = epNum,
|
|
||||||
dubEpisodes = epNum,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
for ((url, name) in urls) {
|
for ((url, name) in urls) {
|
||||||
|
@ -64,15 +61,10 @@ class AnimeflvnetProvider:MainAPI() {
|
||||||
val home = doc.select("ul.ListAnimes li article").map {
|
val home = doc.select("ul.ListAnimes li article").map {
|
||||||
val title = it.selectFirst("h3.Title").text()
|
val title = it.selectFirst("h3.Title").text()
|
||||||
val poster = it.selectFirst("figure img").attr("src")
|
val poster = it.selectFirst("figure img").attr("src")
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(title, fixUrl(it.selectFirst("a").attr("href"))) {
|
||||||
title,
|
this.posterUrl = fixUrl(poster)
|
||||||
fixUrl(it.selectFirst("a").attr("href")),
|
addDubStatus(MonoschinosProvider.getDubStatus(title))
|
||||||
this.name,
|
}
|
||||||
TvType.Anime,
|
|
||||||
fixUrl(poster),
|
|
||||||
null,
|
|
||||||
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
items.add(HomePageList(name, home))
|
items.add(HomePageList(name, home))
|
||||||
|
|
|
@ -201,20 +201,10 @@ class GogoanimeProvider : MainAPI() {
|
||||||
items.add(HomePageList(i.second, (parseRegex.findAll(html.text).map {
|
items.add(HomePageList(i.second, (parseRegex.findAll(html.text).map {
|
||||||
val (link, epNum, title, poster) = it.destructured
|
val (link, epNum, title, poster) = it.destructured
|
||||||
val isSub = listOf(1, 3).contains(i.first.toInt())
|
val isSub = listOf(1, 3).contains(i.first.toInt())
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(title, link) {
|
||||||
title,
|
this.posterUrl = poster
|
||||||
link,
|
addDubStatus(!isSub, epNum.toIntOrNull())
|
||||||
this.name,
|
}
|
||||||
TvType.Anime,
|
|
||||||
poster,
|
|
||||||
null,
|
|
||||||
if (isSub) EnumSet.of(DubStatus.Subbed) else EnumSet.of(
|
|
||||||
DubStatus.Dubbed
|
|
||||||
),
|
|
||||||
null,
|
|
||||||
if (!isSub) epNum.toIntOrNull() else null,
|
|
||||||
if (isSub) epNum.toIntOrNull() else null,
|
|
||||||
)
|
|
||||||
}).toList()))
|
}).toList()))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|
|
@ -14,6 +14,12 @@ class MonoschinosProvider : MainAPI() {
|
||||||
else if (t.contains("Pelicula")) TvType.AnimeMovie
|
else if (t.contains("Pelicula")) TvType.AnimeMovie
|
||||||
else TvType.Anime
|
else TvType.Anime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getDubStatus(title: String): DubStatus {
|
||||||
|
return if (title.contains("Latino") || title.contains("Castellano"))
|
||||||
|
DubStatus.Dubbed
|
||||||
|
else DubStatus.Subbed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override var mainUrl = "https://monoschinos2.com"
|
override var mainUrl = "https://monoschinos2.com"
|
||||||
|
@ -50,19 +56,10 @@ class MonoschinosProvider : MainAPI() {
|
||||||
val url = it.selectFirst("a").attr("href").replace("ver/", "anime/")
|
val url = it.selectFirst("a").attr("href").replace("ver/", "anime/")
|
||||||
.replace(epRegex, "sub-espanol")
|
.replace(epRegex, "sub-espanol")
|
||||||
val epNum = it.selectFirst(".positioning h5").text().toIntOrNull()
|
val epNum = it.selectFirst(".positioning h5").text().toIntOrNull()
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(title, url) {
|
||||||
title,
|
this.posterUrl = fixUrl(poster)
|
||||||
url,
|
addDubStatus(getDubStatus(title), epNum)
|
||||||
this.name,
|
}
|
||||||
TvType.Anime,
|
|
||||||
poster,
|
|
||||||
null,
|
|
||||||
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
|
|
||||||
DubStatus.Dubbed
|
|
||||||
) else EnumSet.of(DubStatus.Subbed),
|
|
||||||
subEpisodes = epNum,
|
|
||||||
dubEpisodes = epNum,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -71,17 +68,10 @@ class MonoschinosProvider : MainAPI() {
|
||||||
val home = app.get(i.first, timeout = 120).document.select(".col-6").map {
|
val home = app.get(i.first, timeout = 120).document.select(".col-6").map {
|
||||||
val title = it.selectFirst(".seristitles").text()
|
val title = it.selectFirst(".seristitles").text()
|
||||||
val poster = it.selectFirst("img.animemainimg").attr("src")
|
val poster = it.selectFirst("img.animemainimg").attr("src")
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(title, fixUrl(it.selectFirst("a").attr("href"))) {
|
||||||
title,
|
this.posterUrl = fixUrl(poster)
|
||||||
fixUrl(it.selectFirst("a").attr("href")),
|
addDubStatus(getDubStatus(title))
|
||||||
this.name,
|
}
|
||||||
TvType.Anime,
|
|
||||||
fixUrl(poster),
|
|
||||||
null,
|
|
||||||
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
|
|
||||||
DubStatus.Dubbed
|
|
||||||
) else EnumSet.of(DubStatus.Subbed),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
items.add(HomePageList(i.second, home))
|
items.add(HomePageList(i.second, home))
|
||||||
|
|
|
@ -17,12 +17,25 @@ class NineAnimeProvider : MainAPI() {
|
||||||
override val hasDownloadSupport = true
|
override val hasDownloadSupport = true
|
||||||
override val supportedTypes = setOf(TvType.Anime)
|
override val supportedTypes = setOf(TvType.Anime)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getDubStatus(title: String): DubStatus {
|
||||||
|
return if (title.contains("(dub)", ignoreCase = true)) {
|
||||||
|
DubStatus.Dubbed
|
||||||
|
} else {
|
||||||
|
DubStatus.Subbed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getMainPage(): HomePageResponse {
|
override suspend fun getMainPage(): HomePageResponse {
|
||||||
val items = listOf(
|
val items = listOf(
|
||||||
Pair("$mainUrl/ajax/home/widget?name=trending", "Trending"),
|
Pair("$mainUrl/ajax/home/widget?name=trending", "Trending"),
|
||||||
Pair("$mainUrl/ajax/home/widget?name=updated_all", "All"),
|
Pair("$mainUrl/ajax/home/widget?name=updated_all", "All"),
|
||||||
Pair("$mainUrl/ajax/home/widget?name=updated_sub&page=1", "Recently Updated (SUB)"),
|
Pair("$mainUrl/ajax/home/widget?name=updated_sub&page=1", "Recently Updated (SUB)"),
|
||||||
Pair("$mainUrl/ajax/home/widget?name=updated_dub&page=1", "Recently Updated (DUB)"),
|
Pair(
|
||||||
|
"$mainUrl/ajax/home/widget?name=updated_dub&page=1",
|
||||||
|
"Recently Updated (DUB)(DUB)"
|
||||||
|
),
|
||||||
Pair(
|
Pair(
|
||||||
"$mainUrl/ajax/home/widget?name=updated_chinese&page=1",
|
"$mainUrl/ajax/home/widget?name=updated_chinese&page=1",
|
||||||
"Recently Updated (Chinese)"
|
"Recently Updated (Chinese)"
|
||||||
|
@ -37,17 +50,11 @@ class NineAnimeProvider : MainAPI() {
|
||||||
val title = it.selectFirst("a.name").text()
|
val title = it.selectFirst("a.name").text()
|
||||||
val link = it.selectFirst("a").attr("href")
|
val link = it.selectFirst("a").attr("href")
|
||||||
val poster = it.selectFirst("a.poster img").attr("src")
|
val poster = it.selectFirst("a.poster img").attr("src")
|
||||||
AnimeSearchResponse(
|
|
||||||
title,
|
newAnimeSearchResponse(title, link) {
|
||||||
link,
|
this.posterUrl = poster
|
||||||
this.name,
|
addDubStatus(getDubStatus(title))
|
||||||
TvType.Anime,
|
}
|
||||||
poster,
|
|
||||||
null,
|
|
||||||
if (title.contains("(DUB)") || title.contains("(Dub)")) EnumSet.of(
|
|
||||||
DubStatus.Dubbed
|
|
||||||
) else EnumSet.of(DubStatus.Subbed),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HomePageList(name, home)
|
HomePageList(name, home)
|
||||||
|
@ -206,24 +213,18 @@ class NineAnimeProvider : MainAPI() {
|
||||||
Episode(link, name)
|
Episode(link, name)
|
||||||
} ?: return null
|
} ?: return null
|
||||||
|
|
||||||
|
|
||||||
val recommendations =
|
val recommendations =
|
||||||
doc.select("div.container aside.main section div.body ul.anime-list li")?.mapNotNull { element ->
|
doc.select("div.container aside.main section div.body ul.anime-list li")
|
||||||
val recTitle = element.select("a.name").text() ?: return@mapNotNull null
|
?.mapNotNull { element ->
|
||||||
|
val recTitle = element.select("a.name")?.text() ?: return@mapNotNull null
|
||||||
val image = element.select("a.poster img")?.attr("src")
|
val image = element.select("a.poster img")?.attr("src")
|
||||||
val recUrl = fixUrl(element.select("a").attr("href"))
|
val recUrl = fixUrl(element.select("a").attr("href"))
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(recTitle, recUrl) {
|
||||||
recTitle,
|
this.posterUrl = image
|
||||||
fixUrl(recUrl),
|
addDubStatus(getDubStatus(recTitle))
|
||||||
this.name,
|
|
||||||
TvType.Anime,
|
|
||||||
image,
|
|
||||||
dubStatus =
|
|
||||||
if (recTitle.contains("(DUB)") || recTitle.contains("(Dub)")) EnumSet.of(
|
|
||||||
DubStatus.Dubbed
|
|
||||||
) else EnumSet.of(DubStatus.Subbed),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val infodoc = doc.selectFirst("div.info .meta .col1").text()
|
val infodoc = doc.selectFirst("div.info .meta .col1").text()
|
||||||
val tvType = if (infodoc.contains("Movie")) TvType.AnimeMovie else TvType.Anime
|
val tvType = if (infodoc.contains("Movie")) TvType.AnimeMovie else TvType.Anime
|
||||||
val status =
|
val status =
|
||||||
|
@ -231,13 +232,14 @@ class NineAnimeProvider : MainAPI() {
|
||||||
else if (infodoc.contains("Airing")) ShowStatus.Ongoing
|
else if (infodoc.contains("Airing")) ShowStatus.Ongoing
|
||||||
else null
|
else null
|
||||||
val tags = doc.select("div.info .meta .col1 div:contains(Genre) a").map { it.text() }
|
val tags = doc.select("div.info .meta .col1 div:contains(Genre) a").map { it.text() }
|
||||||
|
|
||||||
return newAnimeLoadResponse(title, url, tvType) {
|
return newAnimeLoadResponse(title, url, tvType) {
|
||||||
posterUrl = poster
|
this.posterUrl = poster
|
||||||
addEpisodes(DubStatus.Subbed, episodes)
|
this.plot = description
|
||||||
plot = description
|
|
||||||
this.recommendations = recommendations
|
this.recommendations = recommendations
|
||||||
showStatus = status
|
this.showStatus = status
|
||||||
this.tags = tags
|
this.tags = tags
|
||||||
|
addEpisodes(DubStatus.Subbed, episodes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +262,8 @@ class NineAnimeProvider : MainAPI() {
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val document = app.get(data).document
|
val document = app.get(data).document
|
||||||
val animeid = document.selectFirst("div.player-wrapper.watchpage").attr("data-id") ?: return false
|
val animeid =
|
||||||
|
document.selectFirst("div.player-wrapper.watchpage").attr("data-id") ?: return false
|
||||||
val animeidencoded = encode(getVrf(animeid) ?: return false)
|
val animeidencoded = encode(getVrf(animeid) ?: return false)
|
||||||
|
|
||||||
Jsoup.parse(
|
Jsoup.parse(
|
||||||
|
@ -287,7 +290,7 @@ class NineAnimeProvider : MainAPI() {
|
||||||
parseJson<Links>(epserver)
|
parseJson<Links>(epserver)
|
||||||
} else null)?.url?.let { it1 -> getLink(it1.replace("=", "")) }
|
} else null)?.url?.let { it1 -> getLink(it1.replace("=", "")) }
|
||||||
?.replace("/embed/", "/e/")
|
?.replace("/embed/", "/e/")
|
||||||
} catch (e : Exception) {
|
} catch (e: Exception) {
|
||||||
logError(e)
|
logError(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ import okhttp3.Interceptor
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
private const val OPTIONS = "OPTIONS"
|
private const val OPTIONS = "OPTIONS"
|
||||||
|
|
||||||
|
@ -52,29 +51,30 @@ class ZoroProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val epRegex = Regex("Ep (\\d+)/")
|
||||||
private fun Element.toSearchResult(): SearchResponse? {
|
private fun Element.toSearchResult(): SearchResponse? {
|
||||||
val href = fixUrl(this.select("a").attr("href"))
|
val href = fixUrl(this.select("a").attr("href"))
|
||||||
val title = this.select("h3.film-name").text()
|
val title = this.select("h3.film-name").text()
|
||||||
/*val episodes = this.select("div.fd-infor > span.fdi-item")?.get(1)?.text()?.let { eps ->
|
val dubSub = this.select(".film-poster > .tick.ltr").text()
|
||||||
|
//val episodes = this.selectFirst(".film-poster > .tick-eps")?.text()?.toIntOrNull()
|
||||||
|
|
||||||
|
val dubExist = dubSub.contains("dub", ignoreCase = true)
|
||||||
|
val subExist = dubSub.contains("sub", ignoreCase = true)
|
||||||
|
val episodes = this.selectFirst(".film-poster > .tick.rtl > .tick-eps")?.text()?.let { eps ->
|
||||||
|
//println("REGEX:::: $eps")
|
||||||
// current episode / max episode
|
// current episode / max episode
|
||||||
val epRegex = Regex("Ep (\\d+)/")//Regex("Ep (\\d+)/(\\d+)")
|
//Regex("Ep (\\d+)/(\\d+)")
|
||||||
epRegex.find(eps)?.groupValues?.get(1)?.toIntOrNull()
|
epRegex.find(eps)?.groupValues?.get(1)?.toIntOrNull()
|
||||||
}*/
|
}
|
||||||
if (href.contains("/news/") || title.trim().equals("News", ignoreCase = true)) return null
|
if (href.contains("/news/") || title.trim().equals("News", ignoreCase = true)) return null
|
||||||
val posterUrl = fixUrl(this.select("img").attr("data-src"))
|
val posterUrl = fixUrl(this.select("img").attr("data-src"))
|
||||||
val type = getType(this.select("div.fd-infor > span.fdi-item").text())
|
val type = getType(this.select("div.fd-infor > span.fdi-item").text())
|
||||||
|
|
||||||
return AnimeSearchResponse(
|
return newAnimeSearchResponse(title, href, type) {
|
||||||
title,
|
this.posterUrl = posterUrl
|
||||||
href,
|
addDubStatus(dubExist, subExist, episodes, episodes)
|
||||||
this@ZoroProvider.name,
|
}
|
||||||
type,
|
|
||||||
posterUrl,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override suspend fun getMainPage(): HomePageResponse {
|
override suspend fun getMainPage(): HomePageResponse {
|
||||||
val html = app.get("$mainUrl/home").text
|
val html = app.get("$mainUrl/home").text
|
||||||
|
@ -152,30 +152,14 @@ class ZoroProvider : MainAPI() {
|
||||||
val dubExist = dubsub?.contains("DUB") ?: false
|
val dubExist = dubsub?.contains("DUB") ?: false
|
||||||
val subExist = dubsub?.contains("SUB") ?: false || dubsub?.contains("RAW") ?: false
|
val subExist = dubsub?.contains("SUB") ?: false || dubsub?.contains("RAW") ?: false
|
||||||
|
|
||||||
val set = if (dubExist && subExist) {
|
|
||||||
EnumSet.of(DubStatus.Dubbed, DubStatus.Subbed)
|
|
||||||
} else if (dubExist) {
|
|
||||||
EnumSet.of(DubStatus.Dubbed)
|
|
||||||
} else {
|
|
||||||
EnumSet.of(DubStatus.Subbed)
|
|
||||||
}
|
|
||||||
|
|
||||||
val tvType =
|
val tvType =
|
||||||
getType(it.selectFirst(".film-detail > .fd-infor > .fdi-item")?.text().toString())
|
getType(it.selectFirst(".film-detail > .fd-infor > .fdi-item")?.text().toString())
|
||||||
val href = fixUrl(it.selectFirst(".film-name a").attr("href"))
|
val href = fixUrl(it.selectFirst(".film-name a").attr("href"))
|
||||||
|
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(title, href, tvType) {
|
||||||
title,
|
this.posterUrl = poster
|
||||||
href,
|
addDubStatus(dubExist, subExist, episodes, episodes)
|
||||||
name,
|
}
|
||||||
tvType,
|
|
||||||
poster,
|
|
||||||
null,
|
|
||||||
set,
|
|
||||||
null,
|
|
||||||
if (dubExist) episodes else null,
|
|
||||||
if (subExist) episodes else null,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,8 +171,8 @@ class ZoroProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ZoroSyncData(
|
data class ZoroSyncData(
|
||||||
@JsonProperty("mal_id") val malId : String?,
|
@JsonProperty("mal_id") val malId: String?,
|
||||||
@JsonProperty("anilist_id") val aniListId : String?,
|
@JsonProperty("anilist_id") val aniListId: String?,
|
||||||
)
|
)
|
||||||
|
|
||||||
override suspend fun load(url: String): LoadResponse {
|
override suspend fun load(url: String): LoadResponse {
|
||||||
|
|
|
@ -14,6 +14,11 @@ class DoramasYTProvider : MainAPI() {
|
||||||
else if (t.contains("Pelicula")) TvType.Movie
|
else if (t.contains("Pelicula")) TvType.Movie
|
||||||
else TvType.TvSeries
|
else TvType.TvSeries
|
||||||
}
|
}
|
||||||
|
fun getDubStatus(title: String): DubStatus {
|
||||||
|
return if (title.contains("Latino") || title.contains("Castellano"))
|
||||||
|
DubStatus.Dubbed
|
||||||
|
else DubStatus.Subbed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override var mainUrl = "https://doramasyt.com"
|
override var mainUrl = "https://doramasyt.com"
|
||||||
|
@ -53,39 +58,22 @@ class DoramasYTProvider : MainAPI() {
|
||||||
val url = it.selectFirst("a").attr("href").replace("ver/", "dorama/")
|
val url = it.selectFirst("a").attr("href").replace("ver/", "dorama/")
|
||||||
.replace(epRegex, "sub-espanol")
|
.replace(epRegex, "sub-espanol")
|
||||||
val epNum = it.selectFirst("h3").text().toIntOrNull()
|
val epNum = it.selectFirst("h3").text().toIntOrNull()
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(title,url) {
|
||||||
title,
|
this.posterUrl = fixUrl(poster)
|
||||||
url,
|
addDubStatus(getDubStatus(title), epNum)
|
||||||
this.name,
|
}
|
||||||
TvType.Anime,
|
|
||||||
poster,
|
|
||||||
null,
|
|
||||||
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
|
|
||||||
DubStatus.Dubbed
|
|
||||||
) else EnumSet.of(DubStatus.Subbed),
|
|
||||||
subEpisodes = epNum,
|
|
||||||
dubEpisodes = epNum,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
for (i in urls) {
|
for (i in urls) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
val home = app.get(i.first, timeout = 120).document.select(".col-6").map {
|
val home = app.get(i.first, timeout = 120).document.select(".col-6").map {
|
||||||
val title = it.selectFirst(".animedtls p").text()
|
val title = it.selectFirst(".animedtls p").text()
|
||||||
val poster = it.selectFirst(".anithumb img").attr("src")
|
val poster = it.selectFirst(".anithumb img").attr("src")
|
||||||
AnimeSearchResponse(
|
newAnimeSearchResponse(title, fixUrl(it.selectFirst("a").attr("href"))) {
|
||||||
title,
|
this.posterUrl = fixUrl(poster)
|
||||||
it.selectFirst("a").attr("href"),
|
addDubStatus(getDubStatus(title))
|
||||||
this.name,
|
}
|
||||||
TvType.Anime,
|
|
||||||
poster,
|
|
||||||
null,
|
|
||||||
if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(
|
|
||||||
DubStatus.Dubbed
|
|
||||||
) else EnumSet.of(DubStatus.Subbed),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
items.add(HomePageList(i.second, home))
|
items.add(HomePageList(i.second, home))
|
||||||
|
|
|
@ -85,7 +85,7 @@ open class VidstreamProviderTemplate : MainAPI() {
|
||||||
|
|
||||||
val description = soup.selectFirst(".post-entry")?.text()?.trim()
|
val description = soup.selectFirst(".post-entry")?.text()?.trim()
|
||||||
var poster: String? = null
|
var poster: String? = null
|
||||||
var year : Int? = null
|
var year: Int? = null
|
||||||
|
|
||||||
val episodes =
|
val episodes =
|
||||||
soup.select(".listing.items.lists > .video-block").withIndex().map { (_, li) ->
|
soup.select(".listing.items.lists > .video-block").withIndex().map { (_, li) ->
|
||||||
|
@ -105,7 +105,7 @@ open class VidstreamProviderTemplate : MainAPI() {
|
||||||
|
|
||||||
val epNum = Regex("""Episode (\d+)""").find(epTitle)?.destructured?.component1()
|
val epNum = Regex("""Episode (\d+)""").find(epTitle)?.destructured?.component1()
|
||||||
?.toIntOrNull()
|
?.toIntOrNull()
|
||||||
if(year == null) {
|
if (year == null) {
|
||||||
year = epDate?.split("-")?.get(0)?.toIntOrNull()
|
year = epDate?.split("-")?.get(0)?.toIntOrNull()
|
||||||
}
|
}
|
||||||
newEpisode(li.selectFirst("a").attr("href")) {
|
newEpisode(li.selectFirst("a").attr("href")) {
|
||||||
|
@ -173,25 +173,13 @@ open class VidstreamProviderTemplate : MainAPI() {
|
||||||
val isSeries = (name.contains("Season") || name.contains("Episode"))
|
val isSeries = (name.contains("Season") || name.contains("Episode"))
|
||||||
|
|
||||||
if (isSeries) {
|
if (isSeries) {
|
||||||
TvSeriesSearchResponse(
|
newTvSeriesSearchResponse(name, link) {
|
||||||
name,
|
posterUrl = image
|
||||||
link,
|
}
|
||||||
this.name,
|
|
||||||
TvType.TvSeries,
|
|
||||||
image,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
MovieSearchResponse(
|
newMovieSearchResponse(name, link) {
|
||||||
name,
|
posterUrl = image
|
||||||
link,
|
}
|
||||||
this.name,
|
|
||||||
TvType.Movie,
|
|
||||||
image,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -770,7 +770,7 @@ class HomeFragment : Fragment() {
|
||||||
|
|
||||||
home_main_text?.text =
|
home_main_text?.text =
|
||||||
random.name + if (random is AnimeSearchResponse && !random.dubStatus.isNullOrEmpty()) {
|
random.name + if (random is AnimeSearchResponse && !random.dubStatus.isNullOrEmpty()) {
|
||||||
random.dubStatus.joinToString(
|
random.dubStatus?.joinToString(
|
||||||
prefix = " • ",
|
prefix = " • ",
|
||||||
separator = " | "
|
separator = " | "
|
||||||
) { it.name }
|
) { it.name }
|
||||||
|
|
|
@ -710,7 +710,8 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
|
||||||
CastButtonFactory.setUpMediaRouteButton(act, media_route_button)
|
CastButtonFactory.setUpMediaRouteButton(act, media_route_button)
|
||||||
val castContext = CastContext.getSharedInstance(act.applicationContext)
|
val castContext = CastContext.getSharedInstance(act.applicationContext)
|
||||||
|
|
||||||
media_route_button?.isGone = castContext.castState == CastState.NO_DEVICES_AVAILABLE
|
media_route_button?.isGone =
|
||||||
|
castContext.castState == CastState.NO_DEVICES_AVAILABLE
|
||||||
|
|
||||||
castContext.addCastStateListener { state ->
|
castContext.addCastStateListener { state ->
|
||||||
media_route_button?.isGone = state == CastState.NO_DEVICES_AVAILABLE
|
media_route_button?.isGone = state == CastState.NO_DEVICES_AVAILABLE
|
||||||
|
@ -1299,7 +1300,6 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
|
||||||
}
|
}
|
||||||
|
|
||||||
observe(syncModel.syncIds) {
|
observe(syncModel.syncIds) {
|
||||||
println("VALUES::: $it")
|
|
||||||
syncdata = it
|
syncdata = it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1657,8 +1657,8 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
|
||||||
|
|
||||||
val posterImageLink = d.posterUrl
|
val posterImageLink = d.posterUrl
|
||||||
if (!posterImageLink.isNullOrEmpty()) {
|
if (!posterImageLink.isNullOrEmpty()) {
|
||||||
result_poster?.setImage(posterImageLink)
|
result_poster?.setImage(posterImageLink, d.posterHeaders)
|
||||||
result_poster_blur?.setImageBlur(posterImageLink, 10, 3)
|
result_poster_blur?.setImageBlur(posterImageLink, 10, 3, d.posterHeaders)
|
||||||
//Full screen view of Poster image
|
//Full screen view of Poster image
|
||||||
if (context?.isTrueTvSettings() == false) // Poster not clickable on tv
|
if (context?.isTrueTvSettings() == false) // Poster not clickable on tv
|
||||||
result_poster_holder?.setOnClickListener {
|
result_poster_holder?.setOnClickListener {
|
||||||
|
|
|
@ -52,7 +52,8 @@ class SearchFragment : Fragment() {
|
||||||
fun List<SearchResponse>.filterSearchResponse(): List<SearchResponse> {
|
fun List<SearchResponse>.filterSearchResponse(): List<SearchResponse> {
|
||||||
return this.filter { response ->
|
return this.filter { response ->
|
||||||
if (response is AnimeSearchResponse) {
|
if (response is AnimeSearchResponse) {
|
||||||
(response.dubStatus.isNullOrEmpty()) || (response.dubStatus.any {
|
val status = response.dubStatus
|
||||||
|
(status.isNullOrEmpty()) || (status.any {
|
||||||
APIRepository.dubStatusActive.contains(it)
|
APIRepository.dubStatusActive.contains(it)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -225,11 +226,13 @@ class SearchFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}.sortedBy { it.name.lowercase() }
|
}.sortedBy { it.name.lowercase() }
|
||||||
|
|
||||||
val names = currentValidApis.map { if(isMultiLang) "${
|
val names = currentValidApis.map {
|
||||||
|
if (isMultiLang) "${
|
||||||
SubtitleHelper.getFlagFromIso(
|
SubtitleHelper.getFlagFromIso(
|
||||||
it.lang
|
it.lang
|
||||||
)?.plus(" ") ?: ""
|
)?.plus(" ") ?: ""
|
||||||
}${it.name}" else it.name }
|
}${it.name}" else it.name
|
||||||
|
}
|
||||||
for ((index, api) in currentValidApis.map { it.name }.withIndex()) {
|
for ((index, api) in currentValidApis.map { it.name }.withIndex()) {
|
||||||
listView?.setItemChecked(index, currentSelectedApis.contains(api))
|
listView?.setItemChecked(index, currentSelectedApis.contains(api))
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ object SearchResultBuilder {
|
||||||
textIsDub?.isVisible = false
|
textIsDub?.isVisible = false
|
||||||
textIsSub?.isVisible = false
|
textIsSub?.isVisible = false
|
||||||
|
|
||||||
when(card.quality) {
|
when (card.quality) {
|
||||||
SearchQuality.BlueRay -> R.string.quality_blueray
|
SearchQuality.BlueRay -> R.string.quality_blueray
|
||||||
SearchQuality.Cam -> R.string.quality_cam
|
SearchQuality.Cam -> R.string.quality_cam
|
||||||
SearchQuality.CamRip -> R.string.quality_cam_rip
|
SearchQuality.CamRip -> R.string.quality_cam_rip
|
||||||
|
@ -75,7 +75,7 @@ object SearchResultBuilder {
|
||||||
cardText?.text = card.name
|
cardText?.text = card.name
|
||||||
|
|
||||||
cardView.isVisible = true
|
cardView.isVisible = true
|
||||||
if (!cardView.setImage(card.posterUrl)) {
|
if (!cardView.setImage(card.posterUrl, card.posterHeaders)) {
|
||||||
cardView.setImageResource(R.drawable.default_cover)
|
cardView.setImageResource(R.drawable.default_cover)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,20 +182,24 @@ object SearchResultBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is AnimeSearchResponse -> {
|
is AnimeSearchResponse -> {
|
||||||
if (card.dubStatus != null && card.dubStatus.size > 0) {
|
val dubStatus = card.dubStatus
|
||||||
if (card.dubStatus.contains(DubStatus.Dubbed)) {
|
if (!dubStatus.isNullOrEmpty()) {
|
||||||
|
if (dubStatus.contains(DubStatus.Dubbed)) {
|
||||||
textIsDub?.visibility = View.VISIBLE
|
textIsDub?.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
if (card.dubStatus.contains(DubStatus.Subbed)) {
|
if (dubStatus.contains(DubStatus.Subbed)) {
|
||||||
textIsSub?.visibility = View.VISIBLE
|
textIsSub?.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val dubEpisodes = card.episodes[DubStatus.Dubbed]
|
||||||
|
val subEpisodes = card.episodes[DubStatus.Subbed]
|
||||||
|
|
||||||
textIsDub?.apply {
|
textIsDub?.apply {
|
||||||
val dubText = context.getString(R.string.app_dubbed_text)
|
val dubText = context.getString(R.string.app_dubbed_text)
|
||||||
text = if (card.dubEpisodes != null && card.dubEpisodes > 0) {
|
text = if (dubEpisodes != null && dubEpisodes > 0) {
|
||||||
context.getString(R.string.app_dub_sub_episode_text_format)
|
context.getString(R.string.app_dub_sub_episode_text_format)
|
||||||
.format(dubText, card.dubEpisodes)
|
.format(dubText, dubEpisodes)
|
||||||
} else {
|
} else {
|
||||||
dubText
|
dubText
|
||||||
}
|
}
|
||||||
|
@ -203,9 +207,9 @@ object SearchResultBuilder {
|
||||||
|
|
||||||
textIsSub?.apply {
|
textIsSub?.apply {
|
||||||
val subText = context.getString(R.string.app_subbed_text)
|
val subText = context.getString(R.string.app_subbed_text)
|
||||||
text = if (card.subEpisodes != null && card.subEpisodes > 0) {
|
text = if (subEpisodes != null && subEpisodes > 0) {
|
||||||
context.getString(R.string.app_dub_sub_episode_text_format)
|
context.getString(R.string.app_dub_sub_episode_text_format)
|
||||||
.format(subText, card.subEpisodes)
|
.format(subText, subEpisodes)
|
||||||
} else {
|
} else {
|
||||||
subText
|
subText
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@ class SyncSearchViewModel {
|
||||||
override var type: TvType?,
|
override var type: TvType?,
|
||||||
override var posterUrl: String?,
|
override var posterUrl: String?,
|
||||||
override var id: Int?,
|
override var id: Int?,
|
||||||
override var quality: SearchQuality? = null
|
override var quality: SearchQuality? = null,
|
||||||
|
override var posterHeaders: Map<String, String>? = null,
|
||||||
) : SearchResponse
|
) : SearchResponse
|
||||||
|
|
||||||
private fun SyncAPI.SyncSearchResult.toSearchResponse(): SyncSearchResultSearchResponse {
|
private fun SyncAPI.SyncSearchResult.toSearchResponse(): SyncSearchResultSearchResponse {
|
||||||
|
|
|
@ -43,7 +43,8 @@ object DataStoreHelper {
|
||||||
@JsonProperty("type") override var type: TvType? = null,
|
@JsonProperty("type") override var type: TvType? = null,
|
||||||
@JsonProperty("posterUrl") override var posterUrl: String?,
|
@JsonProperty("posterUrl") override var posterUrl: String?,
|
||||||
@JsonProperty("year") val year: Int?,
|
@JsonProperty("year") val year: Int?,
|
||||||
@JsonProperty("quality") override var quality: SearchQuality? = null
|
@JsonProperty("quality") override var quality: SearchQuality? = null,
|
||||||
|
@JsonProperty("posterHeaders") override var posterHeaders: Map<String, String>? = null,
|
||||||
) : SearchResponse
|
) : SearchResponse
|
||||||
|
|
||||||
data class ResumeWatchingResult(
|
data class ResumeWatchingResult(
|
||||||
|
@ -60,7 +61,8 @@ object DataStoreHelper {
|
||||||
@JsonProperty("episode") val episode: Int?,
|
@JsonProperty("episode") val episode: Int?,
|
||||||
@JsonProperty("season") val season: Int?,
|
@JsonProperty("season") val season: Int?,
|
||||||
@JsonProperty("isFromDownload") val isFromDownload: Boolean,
|
@JsonProperty("isFromDownload") val isFromDownload: Boolean,
|
||||||
@JsonProperty("quality") override var quality: SearchQuality? = null
|
@JsonProperty("quality") override var quality: SearchQuality? = null,
|
||||||
|
@JsonProperty("posterHeaders") override var posterHeaders: Map<String, String>? = null,
|
||||||
) : SearchResponse
|
) : SearchResponse
|
||||||
|
|
||||||
var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION
|
var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION
|
||||||
|
|
|
@ -148,11 +148,11 @@ object UIHelper {
|
||||||
return color
|
return color
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ImageView?.setImage(url: String?): Boolean {
|
fun ImageView?.setImage(url: String?, headers: Map<String, String>? = null): Boolean {
|
||||||
if (this == null || url.isNullOrBlank()) return false
|
if (this == null || url.isNullOrBlank()) return false
|
||||||
return try {
|
return try {
|
||||||
GlideApp.with(this.context)
|
GlideApp.with(this.context)
|
||||||
.load(GlideUrl(url)).transition(
|
.load(GlideUrl(url) { headers ?: emptyMap() }).transition(
|
||||||
DrawableTransitionOptions.withCrossFade()
|
DrawableTransitionOptions.withCrossFade()
|
||||||
)
|
)
|
||||||
.into(this)
|
.into(this)
|
||||||
|
@ -163,11 +163,17 @@ object UIHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ImageView?.setImageBlur(url: String?, radius: Int, sample: Int = 3) {
|
fun ImageView?.setImageBlur(
|
||||||
|
url: String?,
|
||||||
|
radius: Int,
|
||||||
|
sample: Int = 3,
|
||||||
|
headers: Map<String, String>? = null
|
||||||
|
) {
|
||||||
if (this == null || url.isNullOrBlank()) return
|
if (this == null || url.isNullOrBlank()) return
|
||||||
try {
|
try {
|
||||||
GlideApp.with(this.context)
|
GlideApp.with(this.context)
|
||||||
.load(GlideUrl(url)).apply(bitmapTransform(BlurTransformation(radius, sample)))
|
.load(GlideUrl(url) { headers ?: emptyMap() })
|
||||||
|
.apply(bitmapTransform(BlurTransformation(radius, sample)))
|
||||||
.transition(
|
.transition(
|
||||||
DrawableTransitionOptions.withCrossFade()
|
DrawableTransitionOptions.withCrossFade()
|
||||||
)
|
)
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
android:contentDescription="@string/search_poster_img_des" />
|
android:contentDescription="@string/search_poster_img_des" />
|
||||||
|
<TextView
|
||||||
|
tools:text="@string/quality_hd"
|
||||||
|
android:id="@+id/text_quality"
|
||||||
|
style="@style/SearchBox"
|
||||||
|
android:background="@drawable/type_bg_color"/>
|
||||||
<!--
|
<!--
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
|
Loading…
Reference in a new issue