migrate more api calls to v2
This commit is contained in:
parent
8b7fb3ac5f
commit
2e7db26d1d
|
@ -322,6 +322,8 @@ object Crunchyroll {
|
|||
* Search fo a query term.
|
||||
* Note: currently this function only supports series/tv shows.
|
||||
*
|
||||
* TODO migrate to v2
|
||||
*
|
||||
* @param query The query term as String
|
||||
* @param n The maximum number of results to return, default = 10
|
||||
* @return A **[SearchResult]** object
|
||||
|
@ -370,22 +372,6 @@ object Crunchyroll {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List all available seasons as **[SeasonListItem]**.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
suspend fun seasonList(): DiscSeasonList {
|
||||
val seasonListEndpoint = "/content/v1/season_list"
|
||||
val parameters = listOf("locale" to Preferences.preferredSubtitleLocale.toLanguageTag())
|
||||
|
||||
return try {
|
||||
requestGet(seasonListEndpoint, parameters)
|
||||
} catch (ex: Exception) {
|
||||
Log.e(TAG, "Exception in seasonList().", ex)
|
||||
NoneDiscSeasonList
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main media functions: series, season, episodes, playback
|
||||
*/
|
||||
|
@ -394,12 +380,10 @@ object Crunchyroll {
|
|||
* series id == crunchyroll id?
|
||||
*/
|
||||
suspend fun series(seriesId: String): Series {
|
||||
val seriesEndpoint = "/cms/v2/${token.country}/M3/crunchyroll/series/$seriesId"
|
||||
val seriesEndpoint = "/content/v2/cms/series/$seriesId"
|
||||
val parameters = listOf(
|
||||
"locale" to Preferences.preferredSubtitleLocale.toLanguageTag(),
|
||||
"Signature" to signature,
|
||||
"Policy" to policy,
|
||||
"Key-Pair-Id" to keyPairID
|
||||
"preferred_audio_language" to Preferences.preferredAudioLocale.toLanguageTag(),
|
||||
"locale" to Preferences.preferredSubtitleLocale.toLanguageTag()
|
||||
)
|
||||
|
||||
return try {
|
||||
|
@ -413,6 +397,8 @@ object Crunchyroll {
|
|||
/**
|
||||
* Get the next episode for a series.
|
||||
*
|
||||
* FIXME up_next returns no content if the is no next episode
|
||||
*
|
||||
* @param seriesId The series id for which to call up next
|
||||
* @return A **[UpNextSeriesItem]** with a Panel representing the up next episode
|
||||
*/
|
||||
|
@ -425,6 +411,9 @@ object Crunchyroll {
|
|||
|
||||
return try {
|
||||
requestGet(upNextSeriesEndpoint, parameters)
|
||||
} catch (ex: NoTransformationFoundException) {
|
||||
// should be 204 No Content
|
||||
NoneUpNextSeriesList
|
||||
} catch (ex: JsonConvertException) {
|
||||
Log.e(TAG, "JsonConvertException in upNextSeries() with seriesId=$seriesId", ex)
|
||||
NoneUpNextSeriesList
|
||||
|
@ -512,12 +501,16 @@ object Crunchyroll {
|
|||
* @return **[Boolean]**: ture if it was found, else false
|
||||
*/
|
||||
suspend fun isWatchlist(seriesId: String): Boolean {
|
||||
val watchlistSeriesEndpoint = "/content/v1/watchlist/$accountID/$seriesId"
|
||||
val parameters = listOf("locale" to Preferences.preferredSubtitleLocale.toLanguageTag())
|
||||
val watchlistSeriesEndpoint = "/content/v2/$accountID/watchlist"
|
||||
val parameters = listOf(
|
||||
"content_ids" to seriesId,
|
||||
"preferred_audio_language" to Preferences.preferredAudioLocale.toLanguageTag(),
|
||||
"locale" to Preferences.preferredSubtitleLocale.toLanguageTag()
|
||||
)
|
||||
|
||||
return try {
|
||||
(requestGet(watchlistSeriesEndpoint, parameters) as JsonObject)
|
||||
.containsKey(seriesId)
|
||||
(requestGet(watchlistSeriesEndpoint, parameters) as Collection2<IsWatchlistItem>)
|
||||
.total == 1
|
||||
} catch (ex: Exception) {
|
||||
Log.e(TAG, "Exception in isWatchlist() with seriesId = $seriesId", ex)
|
||||
false
|
||||
|
@ -530,8 +523,11 @@ object Crunchyroll {
|
|||
* @param seriesId The crunchyroll series id of the media to check
|
||||
*/
|
||||
suspend fun postWatchlist(seriesId: String) {
|
||||
val watchlistPostEndpoint = "/content/v1/watchlist/$accountID"
|
||||
val parameters = listOf("locale" to Preferences.preferredSubtitleLocale.toLanguageTag())
|
||||
val watchlistPostEndpoint = "/content/v2/$accountID/watchlist"
|
||||
val parameters = listOf(
|
||||
"preferred_audio_language" to Preferences.preferredAudioLocale.toLanguageTag(),
|
||||
"locale" to Preferences.preferredSubtitleLocale.toLanguageTag()
|
||||
)
|
||||
|
||||
val json = buildJsonObject {
|
||||
put("content_id", seriesId)
|
||||
|
@ -542,7 +538,6 @@ object Crunchyroll {
|
|||
} catch (ex: Exception) {
|
||||
Log.e(TAG, "Exception in postWatchlist() with seriesId = $seriesId", ex)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -551,15 +546,17 @@ object Crunchyroll {
|
|||
* @param seriesId The crunchyroll series id of the media to check
|
||||
*/
|
||||
suspend fun deleteWatchlist(seriesId: String) {
|
||||
val watchlistDeleteEndpoint = "/content/v1/watchlist/$accountID/$seriesId"
|
||||
val parameters = listOf("locale" to Preferences.preferredSubtitleLocale.toLanguageTag())
|
||||
val watchlistDeleteEndpoint = "/content/v2/$accountID/watchlist/$seriesId"
|
||||
val parameters = listOf(
|
||||
"preferred_audio_language" to Preferences.preferredAudioLocale.toLanguageTag(),
|
||||
"locale" to Preferences.preferredSubtitleLocale.toLanguageTag()
|
||||
)
|
||||
|
||||
try {
|
||||
requestDelete(watchlistDeleteEndpoint, parameters)
|
||||
} catch (ex: Exception) {
|
||||
Log.e(TAG, "Exception in deleteWatchlist() with seriesId = $seriesId", ex)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -127,7 +127,6 @@ typealias SearchResult = Collection<SearchCollection>
|
|||
typealias SearchCollection = Collection<Item>
|
||||
typealias BrowseResult = Collection<Item>
|
||||
typealias SimilarToResult = Collection<Item>
|
||||
typealias DiscSeasonList = Collection<SeasonListItem>
|
||||
typealias Watchlist = Collection2<WatchlistItem>
|
||||
typealias HistoryList = Collection2<UpNextAccountItem>
|
||||
typealias UpNextSeriesList = Collection2<UpNextSeriesItem>
|
||||
|
@ -159,21 +158,6 @@ data class Images(val poster_tall: List<List<Poster>>, val poster_wide: List<Lis
|
|||
@Serializable
|
||||
data class Poster(val height: Int, val width: Int, val source: String, val type: String)
|
||||
|
||||
/**
|
||||
* season list data classes
|
||||
*/
|
||||
@Serializable
|
||||
data class SeasonListItem(
|
||||
@SerialName("id") val id: String,
|
||||
@SerialName("localization") val localization: SeasonListLocalization
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class SeasonListLocalization(
|
||||
@SerialName("title") val title: String,
|
||||
@SerialName("description") val description: String,
|
||||
)
|
||||
|
||||
/**
|
||||
* continue_watching_item data classes
|
||||
*/
|
||||
|
@ -188,6 +172,13 @@ data class WatchlistItem(
|
|||
@SerialName("is_favorite") val isFavorite: Boolean,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class IsWatchlistItem(
|
||||
@SerialName("id") val id: String,
|
||||
@SerialName("is_favorite") val isFavorite: Boolean,
|
||||
@SerialName("date_added") val dateAdded: String
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class UpNextAccountItem(
|
||||
@SerialName("panel") val panel: EpisodePanel,
|
||||
|
@ -229,15 +220,10 @@ data class EpisodeMetadata(
|
|||
@SerialName("series_title") val seriesTitle: String,
|
||||
)
|
||||
|
||||
val NoneItem = Item("", "", "", "", "", Images(emptyList(), emptyList()))
|
||||
val NoneEpisodeMetadata = EpisodeMetadata(0, 0, "", 0, "", "", "")
|
||||
val NoneEpisodePanel = EpisodePanel("", "", "", "", "", NoneEpisodeMetadata, Thumbnail(listOf())) //, "")
|
||||
|
||||
val NoneCollection = Collection<Item>(0, emptyList())
|
||||
val NoneSearchResult = SearchResult(0, emptyList())
|
||||
val NoneBrowseResult = BrowseResult(0, emptyList())
|
||||
val NoneSimilarToResult = SimilarToResult(0, emptyList())
|
||||
val NoneDiscSeasonList = DiscSeasonList(0, emptyList())
|
||||
val NoneWatchlist = Watchlist(0, emptyList())
|
||||
val NoneHistoryList = HistoryList(0, emptyList())
|
||||
val NoneUpNextSeriesList = UpNextSeriesList(0, emptyList())
|
||||
|
@ -247,15 +233,23 @@ val NoneBenefits = Benefits(0, emptyList())
|
|||
/**
|
||||
* series data class
|
||||
*/
|
||||
|
||||
typealias Series = Collection2<SeriesItem>
|
||||
|
||||
@Serializable
|
||||
data class Series(
|
||||
data class SeriesItem(
|
||||
@SerialName("id") val id: String,
|
||||
@SerialName("title") val title: String,
|
||||
@SerialName("description") val description: String,
|
||||
@SerialName("images") val images: Images,
|
||||
@SerialName("maturity_ratings") val maturityRatings: List<String>
|
||||
@SerialName("is_simulcast") val isSimulcast: Boolean,
|
||||
@SerialName("maturity_ratings") val maturityRatings: List<String>,
|
||||
@SerialName("audio_locales") val audioLocales: List<String>
|
||||
|
||||
)
|
||||
val NoneSeries = Series("", "", "", Images(emptyList(), emptyList()), emptyList())
|
||||
|
||||
val NoneSeriesItem = SeriesItem("", "", "", Images(emptyList(), emptyList()), false, emptyList(), emptyList())
|
||||
val NoneSeries = Series(1, listOf(NoneSeriesItem))
|
||||
|
||||
/**
|
||||
* Seasons data classes
|
||||
|
@ -264,17 +258,7 @@ val NoneSeries = Series("", "", "", Images(emptyList(), emptyList()), emptyList(
|
|||
data class Seasons(
|
||||
@SerialName("total") val total: Int,
|
||||
@SerialName("data") val data: List<Season>
|
||||
) {
|
||||
fun getPreferredSeasonByLocal(local: Locale): Season {
|
||||
return data.firstOrNull { season ->
|
||||
// try to get the the first seasons which matches the preferred local
|
||||
season.slugTitle.endsWith("${local.getDisplayLanguage(Locale.ENGLISH)}-dub", true)
|
||||
} ?: data.firstOrNull { season ->
|
||||
// if there is no season with the preferred local, try to find a subbed season
|
||||
season.isSubbed
|
||||
} ?: data.first() // if no preferred language and no sub, use the first season
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Season(
|
||||
|
|
|
@ -6,7 +6,6 @@ import androidx.lifecycle.viewModelScope
|
|||
import kotlinx.coroutines.joinAll
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mosad.teapod.parser.crunchyroll.*
|
||||
import org.mosad.teapod.preferences.Preferences
|
||||
import org.mosad.teapod.util.DataTypes.MediaType
|
||||
import org.mosad.teapod.util.tmdb.*
|
||||
|
||||
|
@ -16,7 +15,7 @@ import org.mosad.teapod.util.tmdb.*
|
|||
*/
|
||||
class MediaFragmentViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
var seriesCrunchy = NoneSeries // movies are also series
|
||||
var seriesCrunchy = NoneSeriesItem // movies are also series
|
||||
internal set
|
||||
var seasonsCrunchy = NoneSeasons
|
||||
internal set
|
||||
|
@ -50,7 +49,7 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic
|
|||
suspend fun loadCrunchy(crunchyId: String) {
|
||||
// load series and seasons info in parallel
|
||||
listOf(
|
||||
viewModelScope.launch { seriesCrunchy = Crunchyroll.series(crunchyId) },
|
||||
viewModelScope.launch { seriesCrunchy = Crunchyroll.series(crunchyId).data.first() },
|
||||
viewModelScope.launch { seasonsCrunchy = Crunchyroll.seasons(crunchyId) },
|
||||
viewModelScope.launch { isWatchlist = Crunchyroll.isWatchlist(crunchyId) },
|
||||
viewModelScope.launch { upNextSeries = Crunchyroll.upNextSeries(crunchyId) },
|
||||
|
@ -58,10 +57,15 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic
|
|||
).joinAll()
|
||||
|
||||
// load the preferred season:
|
||||
// next episode > preferred language (language per season, not per stream)
|
||||
currentSeasonCrunchy = seasonsCrunchy.data.firstOrNull{ season ->
|
||||
season.id == upNextSeries.data.first().panel.episodeMetadata.seasonId
|
||||
} ?: seasonsCrunchy.getPreferredSeasonByLocal(Preferences.preferredSubtitleLocale)
|
||||
// next episode > first season
|
||||
currentSeasonCrunchy = if (upNextSeries != NoneUpNextSeriesList) {
|
||||
seasonsCrunchy.data.firstOrNull{ season ->
|
||||
season.id == upNextSeries.data.first().panel.episodeMetadata.seasonId
|
||||
} ?: seasonsCrunchy.data.first()
|
||||
} else {
|
||||
seasonsCrunchy.data.first()
|
||||
}
|
||||
|
||||
// Note: if we need to query metaDB, do it now
|
||||
|
||||
// load episodes and metaDB in parallel (tmdb needs mediaType, which is set via episodes)
|
||||
|
|
|
@ -171,10 +171,6 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
|||
playCurrentMedia(player.currentPosition)
|
||||
}
|
||||
|
||||
println(newSubtitleLocale != currentSubtitleLocale)
|
||||
println("currentSubtitleLocale: $currentSubtitleLocale")
|
||||
println("newSubtitleLocale: $newSubtitleLocale")
|
||||
|
||||
// else nothing has changed so no need do do anything
|
||||
}
|
||||
|
||||
|
@ -235,7 +231,6 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
|||
|
||||
currentStreams = Crunchyroll.streamsFromMediaGUID(currentVersion.mediaGUID)
|
||||
Log.d(classTag, currentVersion.toString())
|
||||
println("stream: $currentStreams")
|
||||
},
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
Crunchyroll.playheads(listOf(currentEpisode.id))[currentEpisode.id]?.let {
|
||||
|
|
Loading…
Reference in New Issue