mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
NewApi
This commit is contained in:
parent
13c0d91bc9
commit
b0e0c836a0
1 changed files with 187 additions and 348 deletions
|
@ -1,5 +1,6 @@
|
||||||
package com.lagradost.cloudstream3.metaproviders
|
package com.lagradost.cloudstream3.metaproviders
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.fasterxml.jackson.annotation.JsonAlias
|
import com.fasterxml.jackson.annotation.JsonAlias
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
@ -20,135 +21,117 @@ open class TraktProvider : MainAPI() {
|
||||||
TvType.TvSeries,
|
TvType.TvSeries,
|
||||||
TvType.Anime,
|
TvType.Anime,
|
||||||
)
|
)
|
||||||
// Override this to control random Posters on every extension reload
|
|
||||||
open val randomPosters = false
|
|
||||||
private val traktClientId = "d9f434f48b55683a279ffe88ddc68351cc04c9dc9372bd95af5de780b794e770"
|
|
||||||
private val tmdbApiKey = "e6333b32409e02a4a6eba6fb7ff866bb"
|
|
||||||
private val traktApiUrl = "https://api.trakt.tv"
|
|
||||||
private val tmdbApiUrl = "https://api.themoviedb.org/3"
|
|
||||||
|
|
||||||
// You can override mainPage in extension to pass the needed APIs.
|
private val traktClientId = base64Decode("N2YzODYwYWQzNGI4ZTZmOTdmN2I5MTA0ZWQzMzEwOGI0MmQ3MTdlMTM0MmM2NGMxMTg5NGE1MjUyYTQ3NjE3Zg==")
|
||||||
|
private val traktApiUrl = base64Decode("aHR0cHM6Ly9hcGl6LnRyYWt0LnR2")
|
||||||
|
|
||||||
override val mainPage = mainPageOf(
|
override val mainPage = mainPageOf(
|
||||||
"$traktApiUrl/movies/trending" to "Trending Movies", //Most watched movies right now
|
"$traktApiUrl/movies/trending" to "Trending Movies", //Most watched movies right now
|
||||||
"$traktApiUrl/movies/popular" to "Popular Movies", //The most popular movies for all time
|
"$traktApiUrl/movies/popular" to "Popular Movies", //The most popular movies for all time
|
||||||
"$traktApiUrl/shows/trending" to "Trending Shows", //Most watched Shows right now
|
"$traktApiUrl/shows/trending" to "Trending Shows", //Most watched Shows right now
|
||||||
"$traktApiUrl/shows/popular" to "Popular Shows", //The most popular Shows for all time
|
"$traktApiUrl/shows/popular" to "Popular Shows", //The most popular Shows for all time
|
||||||
)
|
)
|
||||||
|
|
||||||
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
|
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
|
||||||
|
|
||||||
val apiResponse = getApi("${request.data}?page=$page")
|
val apiResponse = getApi("${request.data}?extended=cloud9,full&page=$page")
|
||||||
|
|
||||||
val results = parseJson<List<Results>>(apiResponse).map { element ->
|
val results = parseJson<List<MediaDetails>>(apiResponse).map { element ->
|
||||||
element.toSearchResponse()
|
element.toSearchResponse()
|
||||||
}
|
}
|
||||||
return newHomePageResponse(request.name, results)
|
return newHomePageResponse(request.name, results)
|
||||||
}
|
}
|
||||||
private suspend fun Results.toSearchResponse(): SearchResponse {
|
|
||||||
|
|
||||||
val ids = this.ids ?: this.media?.ids
|
private fun MediaDetails.toSearchResponse(): SearchResponse {
|
||||||
|
|
||||||
val tmdbId = ids?.tmdb.toString()
|
val media = this.media ?: this
|
||||||
val tvdbId = ids?.tvdb
|
val mediaType = if (media.ids?.tvdb == null) TvType.Movie else TvType.TvSeries
|
||||||
|
val poster = media.images?.poster?.firstOrNull()
|
||||||
val mediaType = if (tvdbId == null) TvType.Movie else TvType.TvSeries
|
|
||||||
|
|
||||||
if (mediaType == TvType.Movie) {
|
if (mediaType == TvType.Movie) {
|
||||||
val images = getImages(tmdbId, true)
|
|
||||||
val posterUrl = getPosterUrl(images, randomPosters)
|
|
||||||
|
|
||||||
return newMovieSearchResponse(
|
return newMovieSearchResponse(
|
||||||
name = this.media?.title ?: this.title!!,
|
name = media.title!!,
|
||||||
url = Data(
|
url = Data(
|
||||||
title = this.media?.title ?: this.title!!,
|
type = mediaType,
|
||||||
movieBool = true,
|
mediaDetails = media,
|
||||||
ids = ids,
|
|
||||||
images = images,
|
|
||||||
type = mediaType
|
|
||||||
).toJson(),
|
).toJson(),
|
||||||
type = TvType.Movie,
|
type = TvType.Movie,
|
||||||
) {
|
) {
|
||||||
this.posterUrl = posterUrl
|
posterUrl = fixPath(poster)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val images = getImages(tmdbId, false)
|
|
||||||
val posterUrl = getPosterUrl(images, randomPosters)
|
|
||||||
|
|
||||||
return newTvSeriesSearchResponse(
|
return newTvSeriesSearchResponse(
|
||||||
name = this.media?.title ?: this.title!!,
|
name = media.title!!,
|
||||||
url = Data(
|
url = Data(
|
||||||
title = this.media?.title ?: this.title!!,
|
type = mediaType,
|
||||||
movieBool = false,
|
mediaDetails = media,
|
||||||
ids = ids,
|
|
||||||
images = images,
|
|
||||||
type = mediaType
|
|
||||||
).toJson(),
|
).toJson(),
|
||||||
type = TvType.TvSeries,
|
type = TvType.TvSeries,
|
||||||
) {
|
) {
|
||||||
this.posterUrl = posterUrl
|
this.posterUrl = fixPath(poster)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override suspend fun search(query: String): List<SearchResponse>? {
|
|
||||||
val apiResponse = getApi("$traktApiUrl/search/movie,show?query=$query")
|
|
||||||
|
|
||||||
val results = parseJson<List<Results>>(apiResponse).map { element ->
|
override suspend fun search(query: String): List<SearchResponse>? {
|
||||||
|
val apiResponse = getApi("$traktApiUrl/search/movie,show?extended=cloud9,full&limit=20&page=1&query=$query")
|
||||||
|
|
||||||
|
val results = parseJson<List<MediaDetails>>(apiResponse).map { element ->
|
||||||
element.toSearchResponse()
|
element.toSearchResponse()
|
||||||
}
|
}
|
||||||
|
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
override suspend fun load(url: String): LoadResponse {
|
override suspend fun load(url: String): LoadResponse {
|
||||||
|
|
||||||
val data = parseJson<Data>(url)
|
val data = parseJson<Data>(url)
|
||||||
|
val mediaDetails = data.mediaDetails
|
||||||
|
val moviesOrShows = if (data.type == TvType.Movie) "movies" else "shows"
|
||||||
|
|
||||||
val posterUrl = getOrigPosterUrl(data.images, randomPosters)
|
val posterUrl = mediaDetails?.images?.poster?.firstOrNull()
|
||||||
val backDropUrl = getBackdropUrl(data.images)
|
val backDropUrl = mediaDetails?.images?.fanart?.firstOrNull()
|
||||||
|
|
||||||
val moviesOrShows = if (data.movieBool) "movies" else "shows"
|
val resActor = getApi("$traktApiUrl/$moviesOrShows/${mediaDetails?.ids?.trakt}/people?extended=cloud9,full")
|
||||||
val res = getApi("$traktApiUrl/$moviesOrShows/${data.ids?.trakt}?extended=full")
|
|
||||||
|
|
||||||
val mediaDetails = parseJson<MediaDetails>(res)
|
val actors = parseJson<People>(resActor).cast?.map {
|
||||||
|
|
||||||
val peopleDetails = getProfileImages(data.ids?.tmdb.toString(), data.movieBool)
|
|
||||||
|
|
||||||
val actors = peopleDetails.cast?.filter { it.knownForDepartment == "Acting" }?.map {
|
|
||||||
ActorData(
|
ActorData(
|
||||||
Actor(
|
Actor(
|
||||||
name = it.name,
|
name = it.person?.name!!,
|
||||||
image = getImageUrl(it.profilePath)
|
image = fixPath(it.person.images?.headshot?.firstOrNull())
|
||||||
),
|
),
|
||||||
roleString = it.character
|
roleString = it.character
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val resRelated = getApi("$traktApiUrl/$moviesOrShows/${data.ids?.trakt}/related")
|
val resRelated = getApi("$traktApiUrl/$moviesOrShows/${mediaDetails?.ids?.trakt}/related?extended=cloud9,full&limit=20")
|
||||||
|
|
||||||
val relatedMedia = parseJson<List<Results>>(resRelated).map { it.toSearchResponse() }
|
val relatedMedia = parseJson<List<MediaDetails>>(resRelated).map { it.toSearchResponse() }
|
||||||
|
|
||||||
val isCartoon = mediaDetails.genres?.contains("animation") == true || mediaDetails.genres?.contains("anime") == true
|
val isCartoon = (mediaDetails?.genres?.contains("animation") == true || mediaDetails?.genres?.contains("anime") == true)
|
||||||
val isAnime = isCartoon && (mediaDetails.language == "zh" || mediaDetails.language == "ja")
|
val isAnime = isCartoon && (mediaDetails?.language == "zh" || mediaDetails?.language == "ja")
|
||||||
val isAsian = !isAnime && (mediaDetails.language == "zh" || mediaDetails.language == "ko")
|
val isAsian = !isAnime && (mediaDetails?.language == "zh" || mediaDetails?.language == "ko")
|
||||||
val isBollywood = mediaDetails.country == "in"
|
val isBollywood = mediaDetails?.country == "in"
|
||||||
|
|
||||||
if (data.type == TvType.Movie) {
|
if (data.type == TvType.Movie) {
|
||||||
|
|
||||||
val linkData = LinkData(
|
val linkData = LinkData(
|
||||||
id = mediaDetails.ids?.tmdb,
|
id = mediaDetails?.ids?.tmdb,
|
||||||
imdbId = mediaDetails.ids?.imdb.toString(),
|
imdbId = mediaDetails?.ids?.imdb.toString(),
|
||||||
tvdbId = mediaDetails.ids?.tvdb,
|
tvdbId = mediaDetails?.ids?.tvdb,
|
||||||
type = data.type.toString(),
|
type = data.type.toString(),
|
||||||
title = mediaDetails.title,
|
title = mediaDetails?.title,
|
||||||
year = mediaDetails.year,
|
year = mediaDetails?.year,
|
||||||
orgTitle = mediaDetails.title,
|
orgTitle = mediaDetails?.title,
|
||||||
isAnime = isAnime,
|
isAnime = isAnime,
|
||||||
//jpTitle = later if needed as it requires another network request,
|
//jpTitle = later if needed as it requires another network request,
|
||||||
airedDate = mediaDetails.released
|
airedDate = mediaDetails?.released
|
||||||
?: mediaDetails.firstAired,
|
?: mediaDetails?.firstAired,
|
||||||
isAsian = isAsian,
|
isAsian = isAsian,
|
||||||
isBollywood = isBollywood,
|
isBollywood = isBollywood,
|
||||||
).toJson()
|
).toJson()
|
||||||
|
|
||||||
return newMovieLoadResponse(
|
return newMovieLoadResponse(
|
||||||
name = mediaDetails.title,
|
name = mediaDetails?.title!!,
|
||||||
url = data.toJson(),
|
url = data.toJson(),
|
||||||
dataUrl = linkData.toJson(),
|
dataUrl = linkData.toJson(),
|
||||||
type = if (isAnime) TvType.AnimeMovie else TvType.Movie,
|
type = if (isAnime) TvType.AnimeMovie else TvType.Movie,
|
||||||
|
@ -156,7 +139,7 @@ open class TraktProvider : MainAPI() {
|
||||||
this.name = mediaDetails.title
|
this.name = mediaDetails.title
|
||||||
this.apiName = "Trakt"
|
this.apiName = "Trakt"
|
||||||
this.type = if (isAnime) TvType.AnimeMovie else TvType.Movie
|
this.type = if (isAnime) TvType.AnimeMovie else TvType.Movie
|
||||||
this.posterUrl = posterUrl
|
this.posterUrl = getOriginalWidthImageUrl(posterUrl)
|
||||||
this.year = mediaDetails.year
|
this.year = mediaDetails.year
|
||||||
this.plot = mediaDetails.overview
|
this.plot = mediaDetails.overview
|
||||||
this.rating = mediaDetails.rating?.times(1000)?.roundToInt()
|
this.rating = mediaDetails.rating?.times(1000)?.roundToInt()
|
||||||
|
@ -167,41 +150,44 @@ open class TraktProvider : MainAPI() {
|
||||||
this.actors = actors
|
this.actors = actors
|
||||||
this.comingSoon = isUpcoming(mediaDetails.released)
|
this.comingSoon = isUpcoming(mediaDetails.released)
|
||||||
//posterHeaders
|
//posterHeaders
|
||||||
this.backgroundPosterUrl = backDropUrl
|
this.backgroundPosterUrl = getOriginalWidthImageUrl(backDropUrl)
|
||||||
this.contentRating = mediaDetails.certification
|
this.contentRating = mediaDetails.certification
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
val resSeasons = getApi("$traktApiUrl/shows/${data.ids?.trakt.toString()}/seasons?extended=episodes")
|
val resSeasons = getApi("$traktApiUrl/shows/${mediaDetails?.ids?.trakt.toString()}/seasons?extended=cloud9,full,episodes")
|
||||||
val episodes = mutableListOf<Episode>()
|
val episodes = mutableListOf<Episode>()
|
||||||
|
|
||||||
val seasons = parseJson<List<Seasons>>(resSeasons)
|
val seasons = parseJson<List<Seasons>>(resSeasons)
|
||||||
|
val seasonsNames = mutableListOf<SeasonData>()
|
||||||
|
|
||||||
seasons.forEach { season ->
|
seasons.forEach { season ->
|
||||||
parseJson<TmdbSeason>(
|
|
||||||
|
|
||||||
// Using tmdb here because trakt requires a network request for every episode to get its details which make the ext so slow
|
seasonsNames.add(
|
||||||
|
SeasonData(
|
||||||
|
season.number!!,
|
||||||
|
season.title
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
getApi("$tmdbApiUrl/tv/${data.ids?.tmdb.toString()}/season/${season.number}?api_key=$tmdbApiKey")
|
season.episodes?.map { episode ->
|
||||||
).episodes?.map { episode ->
|
|
||||||
|
|
||||||
val linkData = LinkData(
|
val linkData = LinkData(
|
||||||
id = mediaDetails.ids?.tmdb,
|
id = mediaDetails?.ids?.tmdb,
|
||||||
imdbId = mediaDetails.ids?.imdb.toString(),
|
imdbId = mediaDetails?.ids?.imdb.toString(),
|
||||||
tvdbId = mediaDetails.ids?.tvdb,
|
tvdbId = mediaDetails?.ids?.tvdb,
|
||||||
type = data.type.toString(),
|
type = data.type.toString(),
|
||||||
season = episode.seasonNumber,
|
season = episode.season,
|
||||||
episode = episode.episodeNumber,
|
episode = episode.number,
|
||||||
title = mediaDetails.title,
|
title = mediaDetails?.title,
|
||||||
year = mediaDetails.year,
|
year = mediaDetails?.year,
|
||||||
orgTitle = mediaDetails.title,
|
orgTitle = mediaDetails?.title,
|
||||||
isAnime = isAnime,
|
isAnime = isAnime,
|
||||||
airedYear = mediaDetails.year,
|
airedYear = mediaDetails?.year,
|
||||||
lastSeason = seasons.size,
|
lastSeason = seasons.size,
|
||||||
epsTitle = episode.name,
|
epsTitle = episode.title,
|
||||||
//jpTitle = later if needed as it requires another network request,
|
//jpTitle = later if needed as it requires another network request,
|
||||||
date = episode.airDate,
|
date = episode.firstAired,
|
||||||
airedDate = episode.airDate,
|
airedDate = episode.firstAired,
|
||||||
isAsian = isAsian,
|
isAsian = isAsian,
|
||||||
isBollywood = isBollywood,
|
isBollywood = isBollywood,
|
||||||
isCartoon = isCartoon
|
isCartoon = isCartoon
|
||||||
|
@ -210,21 +196,21 @@ open class TraktProvider : MainAPI() {
|
||||||
episodes.add(
|
episodes.add(
|
||||||
Episode(
|
Episode(
|
||||||
data = linkData.toJson(),
|
data = linkData.toJson(),
|
||||||
name = episode.name + if (isUpcoming(episode.airDate)) " • [UPCOMING]" else "",
|
name = episode.title,
|
||||||
season = episode.seasonNumber,
|
season = episode.season,
|
||||||
episode = episode.episodeNumber,
|
episode = episode.number,
|
||||||
posterUrl = getImageUrl(episode.stillPath),
|
posterUrl = fixPath(episode.images?.screenshot?.firstOrNull()),
|
||||||
rating = episode.voteAverage?.times(10)?.roundToInt(),
|
rating = episode.rating?.times(10)?.roundToInt(),
|
||||||
description = episode.overview,
|
description = episode.overview,
|
||||||
).apply {
|
).apply {
|
||||||
this.addDate(episode.airDate)
|
this.addDate(episode.firstAired)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newTvSeriesLoadResponse(
|
return newTvSeriesLoadResponse(
|
||||||
name = mediaDetails.title,
|
name = mediaDetails?.title!!,
|
||||||
url = data.toJson(),
|
url = data.toJson(),
|
||||||
type = if (isAnime) TvType.Anime else TvType.TvSeries,
|
type = if (isAnime) TvType.Anime else TvType.TvSeries,
|
||||||
episodes = episodes
|
episodes = episodes
|
||||||
|
@ -233,7 +219,7 @@ open class TraktProvider : MainAPI() {
|
||||||
this.apiName = "Trakt"
|
this.apiName = "Trakt"
|
||||||
this.type = if (isAnime) TvType.Anime else TvType.TvSeries
|
this.type = if (isAnime) TvType.Anime else TvType.TvSeries
|
||||||
this.episodes = episodes
|
this.episodes = episodes
|
||||||
this.posterUrl = posterUrl
|
this.posterUrl = getOriginalWidthImageUrl(posterUrl)
|
||||||
this.year = mediaDetails.year
|
this.year = mediaDetails.year
|
||||||
this.plot = mediaDetails.overview
|
this.plot = mediaDetails.overview
|
||||||
this.showStatus = getStatus(mediaDetails.status)
|
this.showStatus = getStatus(mediaDetails.status)
|
||||||
|
@ -243,13 +229,15 @@ open class TraktProvider : MainAPI() {
|
||||||
addTrailer(mediaDetails.trailer)
|
addTrailer(mediaDetails.trailer)
|
||||||
this.recommendations = relatedMedia
|
this.recommendations = relatedMedia
|
||||||
this.actors = actors
|
this.actors = actors
|
||||||
//comingSoon
|
this.comingSoon = isUpcoming(mediaDetails.released)
|
||||||
//posterHeaders
|
//posterHeaders
|
||||||
this.backgroundPosterUrl = backDropUrl
|
this.seasonNames = seasonsNames
|
||||||
|
this.backgroundPosterUrl = getOriginalWidthImageUrl(backDropUrl)
|
||||||
this.contentRating = mediaDetails.certification
|
this.contentRating = mediaDetails.certification
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getApi(url: String) : String {
|
private suspend fun getApi(url: String) : String {
|
||||||
return app.get(
|
return app.get(
|
||||||
url = url,
|
url = url,
|
||||||
|
@ -261,85 +249,11 @@ open class TraktProvider : MainAPI() {
|
||||||
).toString()
|
).toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPosterUrl(images: Images, random: Boolean) : String? {
|
|
||||||
|
|
||||||
val imagePath = when {
|
|
||||||
random -> {
|
|
||||||
images.posters?.filter { it.iso6391 == "en" }?.randomOrNull() ?: images.posters?.randomOrNull()
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
images.posters?.firstOrNull { it.iso6391 == "en" } ?: images.posters?.firstOrNull()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?: return null
|
|
||||||
return "https://image.tmdb.org/t/p/w500${imagePath.filePath}"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getOrigPosterUrl(images: Images, random: Boolean) : String? {
|
|
||||||
|
|
||||||
val imagePath = when {
|
|
||||||
random -> {
|
|
||||||
images.posters?.filter { it.iso6391 == null }?.randomOrNull() ?: images.posters?.randomOrNull()
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
images.posters?.firstOrNull { it.iso6391 == null } ?: images.posters?.firstOrNull()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?: return null
|
|
||||||
return "https://image.tmdb.org/t/p/original${imagePath.filePath}"
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getBackdropUrl(images: Images) : String? {
|
|
||||||
val imagePath = images.backdrops?.filter { it.iso6391 == null }?.randomOrNull() ?: images.backdrops?.randomOrNull()
|
|
||||||
?: return null
|
|
||||||
return "https://image.tmdb.org/t/p/original${imagePath.filePath}"
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getImageUrl(path: String?) : String? {
|
|
||||||
if (path == null) return null
|
|
||||||
return "https://image.tmdb.org/t/p/w500${path}"
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun getProfileImages(castTmdbId: String, movie: Boolean) : Images {
|
|
||||||
val imageApiUrl = if (movie) {
|
|
||||||
"$tmdbApiUrl/movie/$castTmdbId/credits?api_key=$tmdbApiKey"
|
|
||||||
} else {
|
|
||||||
"$tmdbApiUrl/tv/$castTmdbId/credits?api_key=$tmdbApiKey"
|
|
||||||
}
|
|
||||||
|
|
||||||
val req = app.get(
|
|
||||||
url = imageApiUrl,
|
|
||||||
headers = mapOf(
|
|
||||||
"accept" to "application/json",
|
|
||||||
)
|
|
||||||
).toString()
|
|
||||||
return parseJson<Images>(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun getImages(tmdbId: String, movie: Boolean = true) : Images {
|
|
||||||
|
|
||||||
val imageApiUrl = if (movie) {
|
|
||||||
"$tmdbApiUrl/movie/${tmdbId}/images?api_key=${tmdbApiKey}"
|
|
||||||
} else {
|
|
||||||
"$tmdbApiUrl/tv/${tmdbId}/images?api_key=${tmdbApiKey}"
|
|
||||||
}
|
|
||||||
|
|
||||||
val req = app.get(
|
|
||||||
url = imageApiUrl,
|
|
||||||
headers = mapOf(
|
|
||||||
"accept" to "application/json",
|
|
||||||
)
|
|
||||||
).toString()
|
|
||||||
|
|
||||||
return parseJson<Images>(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isUpcoming(dateString: String?): Boolean {
|
private fun isUpcoming(dateString: String?): Boolean {
|
||||||
return try {
|
return try {
|
||||||
val format = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
val format = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||||
val dateTime = dateString?.let { format.parse(it)?.time } ?: return false
|
val dateTime = dateString?.let { format.parse(it)?.time } ?: return false
|
||||||
System.currentTimeMillis() < dateTime
|
APIHolder.unixTimeMS < dateTime
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
logError(t)
|
logError(t)
|
||||||
false
|
false
|
||||||
|
@ -354,209 +268,134 @@ open class TraktProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun fixPath(url: String?): String? {
|
||||||
|
url ?: return null
|
||||||
|
return "https://$url"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getWidthImageUrl(path: String?, width: String) : String? {
|
||||||
|
if (path == null) return null
|
||||||
|
if (!path.contains("image.tmdb.org")) return fixPath(path)
|
||||||
|
val fileName = Uri.parse(path).lastPathSegment ?: return null
|
||||||
|
return "https://image.tmdb.org/t/p/${width}/${fileName}"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getOriginalWidthImageUrl(path: String?) : String? {
|
||||||
|
if (path == null) return null
|
||||||
|
if (!path.contains("image.tmdb.org")) return fixPath(path)
|
||||||
|
return getWidthImageUrl(path, "original")
|
||||||
|
}
|
||||||
|
|
||||||
data class Data(
|
data class Data(
|
||||||
val title: String,
|
val type: TvType? = null,
|
||||||
val movieBool: Boolean,
|
val mediaDetails: MediaDetails? = null,
|
||||||
val type: TvType,
|
|
||||||
val ids: Ids? = null,
|
|
||||||
val images: Images,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class Results(
|
|
||||||
val watchers: Long? = null,
|
|
||||||
val revenue: Long? = null,
|
|
||||||
val title: String? = null,
|
|
||||||
val year: Int? = null,
|
|
||||||
@JsonProperty("movie")
|
|
||||||
@JsonAlias("show")
|
|
||||||
val media: Media? = null,
|
|
||||||
val ids: Ids? = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class Media(
|
|
||||||
val title: String,
|
|
||||||
val year: Int,
|
|
||||||
val ids: Ids,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class MediaDetails(
|
data class MediaDetails(
|
||||||
val title: String,
|
@JsonProperty("title") val title: String? = null,
|
||||||
val year: Int? = null,
|
@JsonProperty("year") val year: Int? = null,
|
||||||
val ids: Ids? = null,
|
@JsonProperty("ids") val ids: Ids? = null,
|
||||||
val tagline: String? = null,
|
@JsonProperty("tagline") val tagline: String? = null,
|
||||||
val overview: String? = null,
|
@JsonProperty("overview") val overview: String? = null,
|
||||||
val released: String? = null,
|
@JsonProperty("released") val released: String? = null,
|
||||||
val runtime: Int? = null,
|
@JsonProperty("runtime") val runtime: Int? = null,
|
||||||
val country: String? = null,
|
@JsonProperty("country") val country: String? = null,
|
||||||
@JsonProperty("updated_at")
|
@JsonProperty("updatedAt") val updatedAt: String? = null,
|
||||||
val updatedAt: String? = null,
|
@JsonProperty("trailer") val trailer: String? = null,
|
||||||
val trailer: String? = null,
|
@JsonProperty("homepage") val homepage: String? = null,
|
||||||
val homepage: String? = null,
|
@JsonProperty("status") val status: String? = null,
|
||||||
val status: String? = null,
|
@JsonProperty("rating") val rating: Double? = null,
|
||||||
val rating: Double? = null,
|
@JsonProperty("votes") val votes: Long? = null,
|
||||||
val votes: Long? = null,
|
@JsonProperty("comment_count") val commentCount: Long? = null,
|
||||||
@JsonProperty("comment_count")
|
@JsonProperty("language") val language: String? = null,
|
||||||
val commentCount: Long? = null,
|
@JsonProperty("languages") val languages: List<String>? = null,
|
||||||
val language: String? = null,
|
@JsonProperty("available_translations") val availableTranslations: List<String>? = null,
|
||||||
val languages: List<String>? = null,
|
@JsonProperty("genres") val genres: List<String>? = null,
|
||||||
@JsonProperty("available_translations")
|
@JsonProperty("certification") val certification: String? = null,
|
||||||
val availableTranslations: List<String>? = null,
|
@JsonProperty("aired_episodes") val airedEpisodes: Int? = null,
|
||||||
val genres: List<String>? = null,
|
@JsonProperty("first_aired") val firstAired: String? = null,
|
||||||
val certification: String? = null,
|
@JsonProperty("airs") val airs: Airs? = null,
|
||||||
@JsonProperty("aired_episodes")
|
@JsonProperty("network") val network: String? = null,
|
||||||
val airedEpisodes: Int? = null,
|
@JsonProperty("images") val images: Images? = null,
|
||||||
@JsonProperty("first_aired")
|
@JsonProperty("movie") @JsonAlias("show") val media: MediaDetails? = null
|
||||||
val firstAired: String? = null,
|
|
||||||
val airs: Airs? = null,
|
|
||||||
val network: String? = null,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Airs(
|
data class Airs(
|
||||||
val day: String? = null,
|
@JsonProperty("day") val day: String? = null,
|
||||||
val time: String? = null,
|
@JsonProperty("time") val time: String? = null,
|
||||||
val timezone: String? = null,
|
@JsonProperty("timezone") val timezone: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Ids(
|
data class Ids(
|
||||||
val trakt: Int? = null,
|
@JsonProperty("trakt") val trakt: Int? = null,
|
||||||
val slug: String? = null,
|
@JsonProperty("slug") val slug: String? = null,
|
||||||
val tvdb: Int? = null,
|
@JsonProperty("tvdb") val tvdb: Int? = null,
|
||||||
val imdb: String? = null,
|
@JsonProperty("imdb") val imdb: String? = null,
|
||||||
val tmdb: Int? = null,
|
@JsonProperty("tmdb") val tmdb: Int? = null,
|
||||||
val tvrage: String? = null,
|
@JsonProperty("tvrage") val tvrage: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Images(
|
data class Images(
|
||||||
val backdrops: List<Backdrop>? = null,
|
@JsonProperty("fanart") val fanart: List<String>? = null,
|
||||||
val id: Long? = null,
|
@JsonProperty("poster") val poster: List<String>? = null,
|
||||||
val logos: List<Logo>? = null,
|
@JsonProperty("logo") val logo: List<String>? = null,
|
||||||
val posters: List<Poster>? = null,
|
@JsonProperty("clearart") val clearart: List<String>? = null,
|
||||||
val cast: List<Cast>? = null,
|
@JsonProperty("banner") val banner: List<String>? = null,
|
||||||
|
@JsonProperty("thumb") val thumb: List<String>? = null,
|
||||||
|
@JsonProperty("screenshot") val screenshot: List<String>? = null,
|
||||||
|
@JsonProperty("headshot") val headshot: List<String>? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Backdrop(
|
data class People(
|
||||||
@JsonProperty("aspect_ratio")
|
@JsonProperty("cast") val cast: List<Cast>? = null,
|
||||||
val aspectRatio: Double? = null,
|
|
||||||
val height: Long? = null,
|
|
||||||
@JsonProperty("iso_639_1")
|
|
||||||
val iso6391: String? = null,
|
|
||||||
@JsonProperty("file_path")
|
|
||||||
val filePath: String? = null,
|
|
||||||
@JsonProperty("vote_average")
|
|
||||||
val voteAverage: Double? = null,
|
|
||||||
@JsonProperty("vote_count")
|
|
||||||
val voteCount: Long? = null,
|
|
||||||
val width: Long? = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class Logo(
|
|
||||||
@JsonProperty("aspect_ratio")
|
|
||||||
val aspectRatio: Double? = null,
|
|
||||||
val height: Long? = null,
|
|
||||||
@JsonProperty("iso_639_1")
|
|
||||||
val iso6391: String? = null,
|
|
||||||
@JsonProperty("file_path")
|
|
||||||
val filePath: String? = null,
|
|
||||||
@JsonProperty("vote_average")
|
|
||||||
val voteAverage: Double? = null,
|
|
||||||
@JsonProperty("vote_count")
|
|
||||||
val voteCount: Long? = null,
|
|
||||||
val width: Long? = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class Poster(
|
|
||||||
@JsonProperty("aspect_ratio")
|
|
||||||
val aspectRatio: Double? = null,
|
|
||||||
val height: Long? = null,
|
|
||||||
@JsonProperty("iso_639_1")
|
|
||||||
val iso6391: String? = null,
|
|
||||||
@JsonProperty("file_path")
|
|
||||||
val filePath: String? = null,
|
|
||||||
@JsonProperty("vote_average")
|
|
||||||
val voteAverage: Double? = null,
|
|
||||||
@JsonProperty("vote_count")
|
|
||||||
val voteCount: Long? = null,
|
|
||||||
val width: Long? = null,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Cast(
|
data class Cast(
|
||||||
val adult: Boolean? = null,
|
@JsonProperty("character") val character: String? = null,
|
||||||
val gender: Long? = null,
|
@JsonProperty("characters") val characters: List<String>? = null,
|
||||||
val id: Long? = null,
|
@JsonProperty("episode_count") val episodeCount: Long? = null,
|
||||||
@JsonProperty("known_for_department")
|
@JsonProperty("person") val person: Person? = null,
|
||||||
val knownForDepartment: String? = null,
|
@JsonProperty("images") val images: Images? = null,
|
||||||
val name: String,
|
)
|
||||||
@JsonProperty("original_name")
|
|
||||||
val originalName: String? = null,
|
data class Person(
|
||||||
val popularity: Double? = null,
|
@JsonProperty("name") val name: String? = null,
|
||||||
@JsonProperty("profile_path")
|
@JsonProperty("ids") val ids: Ids? = null,
|
||||||
val profilePath: String? = null,
|
@JsonProperty("images") val images: Images? = null,
|
||||||
@JsonProperty("cast_id")
|
|
||||||
val castId: Long? = null,
|
|
||||||
val character: String? = null,
|
|
||||||
@JsonProperty("credit_id")
|
|
||||||
val creditId: String? = null,
|
|
||||||
val order: Long? = null,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Seasons(
|
data class Seasons(
|
||||||
val number: Int? = null,
|
@JsonProperty("aired_episodes") val airedEpisodes: Int? = null,
|
||||||
val ids: Ids? = null,
|
@JsonProperty("episode_count") val episodeCount: Int? = null,
|
||||||
@JsonProperty("episodes")
|
@JsonProperty("episodes") val episodes: List<TraktEpisode>? = null,
|
||||||
val episodes: List<TraktEpisode>? = null,
|
@JsonProperty("first_aired") val firstAired: String? = null,
|
||||||
|
@JsonProperty("ids") val ids: Ids? = null,
|
||||||
|
@JsonProperty("images") val images: Images? = null,
|
||||||
|
@JsonProperty("network") val network: String? = null,
|
||||||
|
@JsonProperty("number") val number: Int? = null,
|
||||||
|
@JsonProperty("overview") val overview: String? = null,
|
||||||
|
@JsonProperty("rating") val rating: Double? = null,
|
||||||
|
@JsonProperty("title") val title: String? = null,
|
||||||
|
@JsonProperty("updated_at") val updatedAt: String? = null,
|
||||||
|
@JsonProperty("votes") val votes: Int? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class TraktEpisode(
|
data class TraktEpisode(
|
||||||
val season: Int? = null,
|
@JsonProperty("available_translations") val availableTranslations: List<String>? = null,
|
||||||
val number: Int? = null,
|
@JsonProperty("comment_count") val commentCount: Int? = null,
|
||||||
val title: String? = null,
|
@JsonProperty("episode_type") val episodeType: String? = null,
|
||||||
val ids: Ids? = null,
|
@JsonProperty("first_aired") val firstAired: String? = null,
|
||||||
)
|
@JsonProperty("ids") val ids: Ids? = null,
|
||||||
|
@JsonProperty("images") val images: Images? = null,
|
||||||
data class TmdbSeason(
|
@JsonProperty("number") val number: Int? = null,
|
||||||
@JsonProperty("_id")
|
@JsonProperty("number_abs") val numberAbs: Int? = null,
|
||||||
val id: String? = null,
|
@JsonProperty("overview") val overview: String? = null,
|
||||||
@JsonProperty("air_date")
|
@JsonProperty("rating") val rating: Double? = null,
|
||||||
val airDate: String? = null,
|
@JsonProperty("runtime") val runtime: Int? = null,
|
||||||
val episodes: List<TmdbEpisode>? = null,
|
@JsonProperty("season") val season: Int? = null,
|
||||||
val name: String? = null,
|
@JsonProperty("title") val title: String? = null,
|
||||||
val overview: String? = null,
|
@JsonProperty("updated_at") val updatedAt: String? = null,
|
||||||
@JsonProperty("id")
|
@JsonProperty("votes") val votes: Int? = null,
|
||||||
val id2: Int? = null,
|
|
||||||
@JsonProperty("poster_path")
|
|
||||||
val posterPath: String? = null,
|
|
||||||
@JsonProperty("season_number")
|
|
||||||
val seasonNumber: Int? = null,
|
|
||||||
@JsonProperty("vote_average")
|
|
||||||
val voteAverage: Double? = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class TmdbEpisode(
|
|
||||||
@JsonProperty("air_date")
|
|
||||||
val airDate: String? = null,
|
|
||||||
@JsonProperty("episode_number")
|
|
||||||
val episodeNumber: Int? = null,
|
|
||||||
@JsonProperty("episode_type")
|
|
||||||
val episodeType: String? = null,
|
|
||||||
val id: Int? = null,
|
|
||||||
val name: String? = null,
|
|
||||||
val overview: String? = null,
|
|
||||||
@JsonProperty("production_code")
|
|
||||||
val productionCode: String? = null,
|
|
||||||
val runtime: Int? = null,
|
|
||||||
@JsonProperty("season_number")
|
|
||||||
val seasonNumber: Int? = null,
|
|
||||||
@JsonProperty("show_id")
|
|
||||||
val showId: Int? = null,
|
|
||||||
@JsonProperty("still_path")
|
|
||||||
val stillPath: String? = null,
|
|
||||||
@JsonProperty("vote_average")
|
|
||||||
val voteAverage: Double? = null,
|
|
||||||
@JsonProperty("vote_count")
|
|
||||||
val voteCount: Int? = null,
|
|
||||||
//val crew: List<Crew>,
|
|
||||||
//@JsonProperty("guest_stars")
|
|
||||||
//val guestStars: List<GuestStar>,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class LinkData(
|
data class LinkData(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue