mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
add trailers (not complete)
This commit is contained in:
parent
fd7c337109
commit
e864d28b35
5 changed files with 474 additions and 8 deletions
|
@ -142,8 +142,8 @@ dependencies {
|
||||||
//implementation 'com.github.TorrentStream:TorrentStream-Android:2.7.0'
|
//implementation 'com.github.TorrentStream:TorrentStream-Android:2.7.0'
|
||||||
|
|
||||||
// Downloading
|
// Downloading
|
||||||
implementation "androidx.work:work-runtime:2.7.0"
|
implementation "androidx.work:work-runtime:2.7.1"
|
||||||
implementation "androidx.work:work-runtime-ktx:2.7.0"
|
implementation "androidx.work:work-runtime-ktx:2.7.1"
|
||||||
|
|
||||||
// Networking
|
// Networking
|
||||||
implementation "com.squareup.okhttp3:okhttp:4.9.1"
|
implementation "com.squareup.okhttp3:okhttp:4.9.1"
|
||||||
|
@ -152,6 +152,10 @@ dependencies {
|
||||||
// Util to skip the URI file fuckery 🙏
|
// Util to skip the URI file fuckery 🙏
|
||||||
implementation "com.github.tachiyomiorg:unifile:17bec43"
|
implementation "com.github.tachiyomiorg:unifile:17bec43"
|
||||||
|
|
||||||
|
// API because cba maintaining it myself
|
||||||
|
implementation "com.uwetrottmann.tmdb2:tmdb-java:2.6.0"
|
||||||
|
|
||||||
|
|
||||||
// debugImplementation because LeakCanary should only run in debug builds.
|
// debugImplementation because LeakCanary should only run in debug builds.
|
||||||
// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
|
// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
import com.lagradost.cloudstream3.animeproviders.*
|
import com.lagradost.cloudstream3.animeproviders.*
|
||||||
|
import com.lagradost.cloudstream3.metaproviders.TmdbProvider
|
||||||
import com.lagradost.cloudstream3.movieproviders.*
|
import com.lagradost.cloudstream3.movieproviders.*
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -52,6 +53,10 @@ object APIHolder {
|
||||||
SflixProvider("https://sflix.to","Sflix"),
|
SflixProvider("https://sflix.to","Sflix"),
|
||||||
SflixProvider("https://dopebox.to","Dopebox"),
|
SflixProvider("https://dopebox.to","Dopebox"),
|
||||||
|
|
||||||
|
// TmdbProvider(),
|
||||||
|
|
||||||
|
// TrailersTwoProvider(),
|
||||||
|
|
||||||
ZoroProvider()
|
ZoroProvider()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,261 @@
|
||||||
|
package com.lagradost.cloudstream3.metaproviders
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
||||||
|
import com.uwetrottmann.tmdb2.Tmdb
|
||||||
|
import com.uwetrottmann.tmdb2.entities.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
open class TmdbProvider : MainAPI() {
|
||||||
|
|
||||||
|
open val useMetaLoadResponse = false
|
||||||
|
open val apiName = "TMDB"
|
||||||
|
|
||||||
|
override val hasMainPage: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
val tmdb = Tmdb("TMDB_KEY_HERE")
|
||||||
|
|
||||||
|
private fun getImageUrl(link: String?): String? {
|
||||||
|
if (link == null) return null
|
||||||
|
return if (link.startsWith("/")) "https://image.tmdb.org/t/p/w500/$link" else link
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getUrl(id: Int?, tvShow: Boolean): String {
|
||||||
|
return if (tvShow) "https://www.themoviedb.org/tv/${id ?: -1}"
|
||||||
|
else "https://www.themoviedb.org/movie/${id ?: -1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* episode and season starting from 1
|
||||||
|
* they are null if movie
|
||||||
|
* */
|
||||||
|
data class TmdbLink(
|
||||||
|
@JsonProperty("imdbID") val imdbID: String?,
|
||||||
|
@JsonProperty("tmdbID") val tmdbID: Int?,
|
||||||
|
@JsonProperty("episode") val episode: Int?,
|
||||||
|
@JsonProperty("season") val season: Int?
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private fun BaseTvShow.toSearchResponse(): TvSeriesSearchResponse {
|
||||||
|
return TvSeriesSearchResponse(
|
||||||
|
this.name ?: this.original_name,
|
||||||
|
getUrl(id, true),
|
||||||
|
apiName,
|
||||||
|
TvType.TvSeries,
|
||||||
|
getImageUrl(this.poster_path),
|
||||||
|
this.first_air_date?.let {
|
||||||
|
Calendar.getInstance().apply {
|
||||||
|
time = it
|
||||||
|
}.get(Calendar.YEAR)
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
this.id
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun BaseMovie.toSearchResponse(): MovieSearchResponse {
|
||||||
|
return MovieSearchResponse(
|
||||||
|
this.title ?: this.original_title,
|
||||||
|
getUrl(id, false),
|
||||||
|
apiName,
|
||||||
|
TvType.TvSeries,
|
||||||
|
getImageUrl(this.poster_path),
|
||||||
|
this.release_date?.let {
|
||||||
|
Calendar.getInstance().apply {
|
||||||
|
time = it
|
||||||
|
}.get(Calendar.YEAR)
|
||||||
|
},
|
||||||
|
this.id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TvShow.toLoadResponse(): TvSeriesLoadResponse {
|
||||||
|
val episodes = this.seasons?.mapNotNull {
|
||||||
|
it.episodes?.map {
|
||||||
|
TvSeriesEpisode(
|
||||||
|
it.name,
|
||||||
|
it.season_number,
|
||||||
|
it.episode_number,
|
||||||
|
TmdbLink(
|
||||||
|
it.external_ids?.imdb_id,
|
||||||
|
it.id,
|
||||||
|
it.episode_number,
|
||||||
|
it.season_number,
|
||||||
|
).toJson(),
|
||||||
|
getImageUrl(it.still_path),
|
||||||
|
it.air_date?.toString(),
|
||||||
|
it.rating,
|
||||||
|
it.overview,
|
||||||
|
)
|
||||||
|
} ?: (1..(it.episode_count ?: 1)).map { episodeNum ->
|
||||||
|
TvSeriesEpisode(
|
||||||
|
episode = episodeNum,
|
||||||
|
data = episodeNum.toString(),
|
||||||
|
season = it.season_number
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}?.flatten() ?: listOf()
|
||||||
|
|
||||||
|
return TvSeriesLoadResponse(
|
||||||
|
this.name ?: this.original_name,
|
||||||
|
getUrl(id, true),
|
||||||
|
this@TmdbProvider.apiName,
|
||||||
|
TvType.TvSeries,
|
||||||
|
episodes,
|
||||||
|
getImageUrl(this.poster_path),
|
||||||
|
this.first_air_date?.let {
|
||||||
|
Calendar.getInstance().apply {
|
||||||
|
time = it
|
||||||
|
}.get(Calendar.YEAR)
|
||||||
|
},
|
||||||
|
this.overview,
|
||||||
|
null,//this.status
|
||||||
|
null, // possible to get
|
||||||
|
this.rating,
|
||||||
|
this.genres?.mapNotNull { it.name },
|
||||||
|
null, //this.episode_run_time.average()
|
||||||
|
null,
|
||||||
|
this.recommendations?.results?.map { it.toSearchResponse() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Movie.toLoadResponse(): MovieLoadResponse {
|
||||||
|
println("EXTERNAL IDS ${this.toJson()}")
|
||||||
|
return MovieLoadResponse(
|
||||||
|
this.title ?: this.original_title,
|
||||||
|
getUrl(id, true),
|
||||||
|
this@TmdbProvider.apiName,
|
||||||
|
TvType.Movie,
|
||||||
|
TmdbLink(
|
||||||
|
this.imdb_id,
|
||||||
|
this.id,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
).toJson(),
|
||||||
|
getImageUrl(this.poster_path),
|
||||||
|
this.release_date?.let {
|
||||||
|
Calendar.getInstance().apply {
|
||||||
|
time = it
|
||||||
|
}.get(Calendar.YEAR)
|
||||||
|
},
|
||||||
|
this.overview,
|
||||||
|
null,//this.status
|
||||||
|
this.rating,
|
||||||
|
this.genres?.mapNotNull { it.name },
|
||||||
|
null, //this.episode_run_time.average()
|
||||||
|
null,
|
||||||
|
this.recommendations?.results?.map { it.toSearchResponse() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMainPage(): HomePageResponse {
|
||||||
|
|
||||||
|
// SAME AS DISCOVER IT SEEMS
|
||||||
|
// val popularSeries = tmdb.tvService().popular(1, "en-US").execute().body()?.results?.map {
|
||||||
|
// it.toSearchResponse()
|
||||||
|
// } ?: listOf()
|
||||||
|
//
|
||||||
|
// val popularMovies =
|
||||||
|
// tmdb.moviesService().popular(1, "en-US", "840").execute().body()?.results?.map {
|
||||||
|
// it.toSearchResponse()
|
||||||
|
// } ?: listOf()
|
||||||
|
|
||||||
|
val discoverMovies = tmdb.discoverMovie().build().execute().body()?.results?.map {
|
||||||
|
it.toSearchResponse()
|
||||||
|
} ?: listOf()
|
||||||
|
|
||||||
|
val discoverSeries = tmdb.discoverTv().build().execute().body()?.results?.map {
|
||||||
|
it.toSearchResponse()
|
||||||
|
} ?: listOf()
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/ISO_3166-1
|
||||||
|
val topMovies =
|
||||||
|
tmdb.moviesService().topRated(1, "en-US", "US").execute().body()?.results?.map {
|
||||||
|
it.toSearchResponse()
|
||||||
|
} ?: listOf()
|
||||||
|
|
||||||
|
val topSeries = tmdb.tvService().topRated(1, "en-US").execute().body()?.results?.map {
|
||||||
|
it.toSearchResponse()
|
||||||
|
} ?: listOf()
|
||||||
|
|
||||||
|
return HomePageResponse(
|
||||||
|
listOf(
|
||||||
|
// HomePageList("Popular Series", popularSeries),
|
||||||
|
// HomePageList("Popular Movies", popularMovies),
|
||||||
|
HomePageList("Popular Movies", discoverMovies),
|
||||||
|
HomePageList("Popular Series", discoverSeries),
|
||||||
|
HomePageList("Top Movies", topMovies),
|
||||||
|
HomePageList("Top Series", topSeries),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun loadFromImdb(imdb: String, seasons: List<TvSeason>): LoadResponse? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun loadFromTmdb(tmdb: Int, seasons: List<TvSeason>): LoadResponse? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun loadFromImdb(imdb: String): LoadResponse? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun loadFromTmdb(tmdb: Int): LoadResponse? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Possible to add recommendations and such here.
|
||||||
|
override fun load(url: String): LoadResponse? {
|
||||||
|
// https://www.themoviedb.org/movie/7445-brothers
|
||||||
|
// https://www.themoviedb.org/tv/71914-the-wheel-of-time
|
||||||
|
|
||||||
|
val idRegex = Regex("""themoviedb\.org/(.*)/(\d+)""")
|
||||||
|
val found = idRegex.find(url)
|
||||||
|
|
||||||
|
val isTvSeries = found?.groupValues?.getOrNull(1).equals("tv", ignoreCase = true)
|
||||||
|
val id = found?.groupValues?.getOrNull(2)?.toIntOrNull() ?: return null
|
||||||
|
|
||||||
|
return if (useMetaLoadResponse) {
|
||||||
|
return if (isTvSeries) {
|
||||||
|
val body = tmdb.tvService().tv(id, "en-US").execute().body()
|
||||||
|
body?.toLoadResponse()
|
||||||
|
} else {
|
||||||
|
val body = tmdb.moviesService().summary(id, "en-US").execute().body()
|
||||||
|
body?.toLoadResponse()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loadFromTmdb(id)?.let { return it }
|
||||||
|
if (isTvSeries) {
|
||||||
|
tmdb.tvService().externalIds(id, "en-US").execute().body()?.imdb_id?.let {
|
||||||
|
val fromImdb = loadFromImdb(it)
|
||||||
|
val result = if (fromImdb == null) {
|
||||||
|
val details = tmdb.tvService().tv(id, "en-US").execute().body()
|
||||||
|
loadFromImdb(it, details?.seasons ?: listOf())
|
||||||
|
?: loadFromTmdb(id, details?.seasons ?: listOf())
|
||||||
|
} else {
|
||||||
|
fromImdb
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmdb.moviesService().externalIds(id, "en-US").execute()
|
||||||
|
.body()?.imdb_id?.let { loadFromImdb(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun search(query: String): List<SearchResponse>? {
|
||||||
|
return tmdb.searchService().multi(query, 1, "en-Us", "US", true).execute()
|
||||||
|
.body()?.results?.mapNotNull {
|
||||||
|
it.movie?.toSearchResponse() ?: it.tvShow?.toSearchResponse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
package com.lagradost.cloudstream3.movieproviders
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
|
import com.lagradost.cloudstream3.SubtitleFile
|
||||||
|
import com.lagradost.cloudstream3.mapper
|
||||||
|
import com.lagradost.cloudstream3.metaproviders.TmdbProvider
|
||||||
|
import com.lagradost.cloudstream3.network.get
|
||||||
|
import com.lagradost.cloudstream3.network.text
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
import com.lagradost.cloudstream3.utils.SubtitleHelper
|
||||||
|
|
||||||
|
class TrailersTwoProvider : TmdbProvider() {
|
||||||
|
|
||||||
|
val user = "cloudstream"
|
||||||
|
|
||||||
|
override val apiName: String
|
||||||
|
get() = "Trailers.to"
|
||||||
|
|
||||||
|
override val name: String
|
||||||
|
get() = "Trailers.to"
|
||||||
|
|
||||||
|
override val mainUrl: String
|
||||||
|
get() = "https://trailers.to"
|
||||||
|
|
||||||
|
override val useMetaLoadResponse: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override val instantLinkLoading: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun loadLinks(
|
||||||
|
data: String,
|
||||||
|
isCasting: Boolean,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
): Boolean {
|
||||||
|
val mappedData = mapper.readValue<TmdbLink>(data)
|
||||||
|
println("MAPPED $mappedData")
|
||||||
|
if (mappedData.imdbID == null) return false
|
||||||
|
|
||||||
|
val isMovie = mappedData.episode == null && mappedData.season == null
|
||||||
|
val subtitleUrl = if (isMovie) {
|
||||||
|
callback.invoke(
|
||||||
|
ExtractorLink(
|
||||||
|
this.name,
|
||||||
|
this.name,
|
||||||
|
"https://trailers.to/video/$user/imdb/${mappedData.imdbID}",
|
||||||
|
"https://trailers.to",
|
||||||
|
Qualities.Unknown.value,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"https://trailers.to/subtitles/$user/imdb/${mappedData.imdbID}"
|
||||||
|
} else {
|
||||||
|
callback.invoke(
|
||||||
|
ExtractorLink(
|
||||||
|
this.name,
|
||||||
|
this.name,
|
||||||
|
"https://trailers.to/video/$user/imdb/${mappedData.imdbID}/S${mappedData.season ?: 1}E${mappedData.episode ?: 1}",
|
||||||
|
"https://trailers.to",
|
||||||
|
Qualities.Unknown.value,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"https://trailers.to/subtitles/$user/imdb/${mappedData.imdbID}/S${mappedData.season ?: 1}E${mappedData.episode ?: 1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
val subtitles =
|
||||||
|
get(subtitleUrl).text
|
||||||
|
val subtitlesMapped = mapper.readValue<List<TrailersSubtitleFile>>(subtitles)
|
||||||
|
subtitlesMapped.forEach {
|
||||||
|
subtitleCallback.invoke(
|
||||||
|
SubtitleFile(
|
||||||
|
it.LanguageCode ?: "en",
|
||||||
|
"https://trailers.to/subtitles/${it.ContentHash ?: return@forEach}/${it.LanguageCode ?: return@forEach}.vtt" // ${it.MetaInfo?.SubFormat ?: "srt"}"
|
||||||
|
).also { println(it) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto generated
|
||||||
|
data class TrailersSubtitleFile(
|
||||||
|
@JsonProperty("SubtitleID") val SubtitleID: Int?,
|
||||||
|
@JsonProperty("ItemID") val ItemID: Int?,
|
||||||
|
@JsonProperty("ContentText") val ContentText: String?,
|
||||||
|
@JsonProperty("ContentHash") val ContentHash: String?,
|
||||||
|
@JsonProperty("LanguageCode") val LanguageCode: String?,
|
||||||
|
@JsonProperty("MetaInfo") val MetaInfo: MetaInfo?,
|
||||||
|
@JsonProperty("EntryDate") val EntryDate: String?,
|
||||||
|
@JsonProperty("ItemSubtitleAdaptations") val ItemSubtitleAdaptations: List<ItemSubtitleAdaptations>?,
|
||||||
|
@JsonProperty("ReleaseNames") val ReleaseNames: List<String>?,
|
||||||
|
@JsonProperty("SubFileNames") val SubFileNames: List<String>?,
|
||||||
|
@JsonProperty("Framerates") val Framerates: List<Int>?,
|
||||||
|
@JsonProperty("IsRelevant") val IsRelevant: Boolean?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class QueryParameters(
|
||||||
|
@JsonProperty("imdbid") val imdbid: String?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class MetaInfo(
|
||||||
|
@JsonProperty("MatchedBy") val MatchedBy: String?,
|
||||||
|
@JsonProperty("IDSubMovieFile") val IDSubMovieFile: String?,
|
||||||
|
@JsonProperty("MovieHash") val MovieHash: String?,
|
||||||
|
@JsonProperty("MovieByteSize") val MovieByteSize: String?,
|
||||||
|
@JsonProperty("MovieTimeMS") val MovieTimeMS: String?,
|
||||||
|
@JsonProperty("IDSubtitleFile") val IDSubtitleFile: String?,
|
||||||
|
@JsonProperty("SubFileName") val SubFileName: String?,
|
||||||
|
@JsonProperty("SubActualCD") val SubActualCD: String?,
|
||||||
|
@JsonProperty("SubSize") val SubSize: String?,
|
||||||
|
@JsonProperty("SubHash") val SubHash: String?,
|
||||||
|
@JsonProperty("SubLastTS") val SubLastTS: String?,
|
||||||
|
@JsonProperty("SubTSGroup") val SubTSGroup: String?,
|
||||||
|
@JsonProperty("InfoReleaseGroup") val InfoReleaseGroup: String?,
|
||||||
|
@JsonProperty("InfoFormat") val InfoFormat: String?,
|
||||||
|
@JsonProperty("InfoOther") val InfoOther: String?,
|
||||||
|
@JsonProperty("IDSubtitle") val IDSubtitle: String?,
|
||||||
|
@JsonProperty("UserID") val UserID: String?,
|
||||||
|
@JsonProperty("SubLanguageID") val SubLanguageID: String?,
|
||||||
|
@JsonProperty("SubFormat") val SubFormat: String?,
|
||||||
|
@JsonProperty("SubSumCD") val SubSumCD: String?,
|
||||||
|
@JsonProperty("SubAuthorComment") val SubAuthorComment: String?,
|
||||||
|
@JsonProperty("SubAddDate") val SubAddDate: String?,
|
||||||
|
@JsonProperty("SubBad") val SubBad: String?,
|
||||||
|
@JsonProperty("SubRating") val SubRating: String?,
|
||||||
|
@JsonProperty("SubSumVotes") val SubSumVotes: String?,
|
||||||
|
@JsonProperty("SubDownloadsCnt") val SubDownloadsCnt: String?,
|
||||||
|
@JsonProperty("MovieReleaseName") val MovieReleaseName: String?,
|
||||||
|
@JsonProperty("MovieFPS") val MovieFPS: String?,
|
||||||
|
@JsonProperty("IDMovie") val IDMovie: String?,
|
||||||
|
@JsonProperty("IDMovieImdb") val IDMovieImdb: String?,
|
||||||
|
@JsonProperty("MovieName") val MovieName: String?,
|
||||||
|
@JsonProperty("MovieNameEng") val MovieNameEng: String?,
|
||||||
|
@JsonProperty("MovieYear") val MovieYear: String?,
|
||||||
|
@JsonProperty("MovieImdbRating") val MovieImdbRating: String?,
|
||||||
|
@JsonProperty("SubFeatured") val SubFeatured: String?,
|
||||||
|
@JsonProperty("UserNickName") val UserNickName: String?,
|
||||||
|
@JsonProperty("SubTranslator") val SubTranslator: String?,
|
||||||
|
@JsonProperty("ISO639") val ISO639: String?,
|
||||||
|
@JsonProperty("LanguageName") val LanguageName: String?,
|
||||||
|
@JsonProperty("SubComments") val SubComments: String?,
|
||||||
|
@JsonProperty("SubHearingImpaired") val SubHearingImpaired: String?,
|
||||||
|
@JsonProperty("UserRank") val UserRank: String?,
|
||||||
|
@JsonProperty("SeriesSeason") val SeriesSeason: String?,
|
||||||
|
@JsonProperty("SeriesEpisode") val SeriesEpisode: String?,
|
||||||
|
@JsonProperty("MovieKind") val MovieKind: String?,
|
||||||
|
@JsonProperty("SubHD") val SubHD: String?,
|
||||||
|
@JsonProperty("SeriesIMDBParent") val SeriesIMDBParent: String?,
|
||||||
|
@JsonProperty("SubEncoding") val SubEncoding: String?,
|
||||||
|
@JsonProperty("SubAutoTranslation") val SubAutoTranslation: String?,
|
||||||
|
@JsonProperty("SubForeignPartsOnly") val SubForeignPartsOnly: String?,
|
||||||
|
@JsonProperty("SubFromTrusted") val SubFromTrusted: String?,
|
||||||
|
@JsonProperty("QueryCached") val QueryCached: Int?,
|
||||||
|
@JsonProperty("SubTSGroupHash") val SubTSGroupHash: String?,
|
||||||
|
@JsonProperty("SubDownloadLink") val SubDownloadLink: String?,
|
||||||
|
@JsonProperty("ZipDownloadLink") val ZipDownloadLink: String?,
|
||||||
|
@JsonProperty("SubtitlesLink") val SubtitlesLink: String?,
|
||||||
|
@JsonProperty("QueryNumber") val QueryNumber: String?,
|
||||||
|
@JsonProperty("QueryParameters") val QueryParameters: QueryParameters?,
|
||||||
|
@JsonProperty("Score") val Score: Double?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class ItemSubtitleAdaptations(
|
||||||
|
@JsonProperty("ContentHash") val ContentHash: String?,
|
||||||
|
@JsonProperty("OffsetMs") val OffsetMs: Int?,
|
||||||
|
@JsonProperty("Framerate") val Framerate: Int?,
|
||||||
|
@JsonProperty("Views") val Views: Int?,
|
||||||
|
@JsonProperty("EntryDate") val EntryDate: String?,
|
||||||
|
@JsonProperty("Subtitle") val Subtitle: String?
|
||||||
|
)
|
|
@ -51,7 +51,10 @@ object AppUtils {
|
||||||
intent.data = Uri.parse(url)
|
intent.data = Uri.parse(url)
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
startActivity(Intent.createChooser(intent, null).putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, components))
|
startActivity(
|
||||||
|
Intent.createChooser(intent, null)
|
||||||
|
.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, components)
|
||||||
|
)
|
||||||
else
|
else
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
@ -68,6 +71,11 @@ object AppUtils {
|
||||||
return queryPairs
|
return queryPairs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Any object as json string */
|
||||||
|
fun Any.toJson(): String {
|
||||||
|
return mapper.writeValueAsString(this)
|
||||||
|
}
|
||||||
|
|
||||||
/**| S1:E2 Hello World
|
/**| S1:E2 Hello World
|
||||||
* | Episode 2. Hello world
|
* | Episode 2. Hello world
|
||||||
* | Hello World
|
* | Hello World
|
||||||
|
@ -103,7 +111,12 @@ object AppUtils {
|
||||||
|
|
||||||
//private val viewModel: ResultViewModel by activityViewModels()
|
//private val viewModel: ResultViewModel by activityViewModels()
|
||||||
|
|
||||||
fun AppCompatActivity.loadResult(url: String, apiName: String, startAction: Int = 0, startValue: Int = 0) {
|
fun AppCompatActivity.loadResult(
|
||||||
|
url: String,
|
||||||
|
apiName: String,
|
||||||
|
startAction: Int = 0,
|
||||||
|
startValue: Int = 0
|
||||||
|
) {
|
||||||
this.runOnUiThread {
|
this.runOnUiThread {
|
||||||
// viewModelStore.clear()
|
// viewModelStore.clear()
|
||||||
this.navigate(
|
this.navigate(
|
||||||
|
@ -113,7 +126,11 @@ object AppUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Activity?.loadSearchResult(card: SearchResponse, startAction: Int = 0, startValue: Int = 0) {
|
fun Activity?.loadSearchResult(
|
||||||
|
card: SearchResponse,
|
||||||
|
startAction: Int = 0,
|
||||||
|
startValue: Int = 0
|
||||||
|
) {
|
||||||
(this as AppCompatActivity?)?.loadResult(card.url, card.apiName, startAction, startValue)
|
(this as AppCompatActivity?)?.loadResult(card.url, card.apiName, startAction, startValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +196,8 @@ object AppUtils {
|
||||||
val conManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
val conManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||||
val networkInfo = conManager.allNetworks
|
val networkInfo = conManager.allNetworks
|
||||||
return networkInfo.any {
|
return networkInfo.any {
|
||||||
conManager.getNetworkCapabilities(it)?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true
|
conManager.getNetworkCapabilities(it)
|
||||||
|
?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +234,10 @@ object AppUtils {
|
||||||
return currentAudioFocusRequest
|
return currentAudioFocusRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
fun filterProviderByPreferredMedia(apis: ArrayList<MainAPI>, currentPrefMedia: Int): List<MainAPI> {
|
fun filterProviderByPreferredMedia(
|
||||||
|
apis: ArrayList<MainAPI>,
|
||||||
|
currentPrefMedia: Int
|
||||||
|
): List<MainAPI> {
|
||||||
val allApis = apis.filter { api -> api.hasMainPage }
|
val allApis = apis.filter { api -> api.hasMainPage }
|
||||||
return if (currentPrefMedia < 1) {
|
return if (currentPrefMedia < 1) {
|
||||||
allApis
|
allApis
|
||||||
|
@ -226,7 +247,8 @@ object AppUtils {
|
||||||
val listEnumMovieTv = listOf(TvType.Movie, TvType.TvSeries, TvType.Cartoon)
|
val listEnumMovieTv = listOf(TvType.Movie, TvType.TvSeries, TvType.Cartoon)
|
||||||
val mediaTypeList = if (currentPrefMedia == 1) listEnumMovieTv else listEnumAnime
|
val mediaTypeList = if (currentPrefMedia == 1) listEnumMovieTv else listEnumAnime
|
||||||
|
|
||||||
val filteredAPI = allApis.filter { api -> api.supportedTypes.any { it in mediaTypeList } }
|
val filteredAPI =
|
||||||
|
allApis.filter { api -> api.supportedTypes.any { it in mediaTypeList } }
|
||||||
filteredAPI
|
filteredAPI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue