From 1ebc1194e62ccafb32132acc56feb7667f9ca876 Mon Sep 17 00:00:00 2001 From: Jannik Date: Sat, 16 Apr 2022 17:23:53 +0200 Subject: [PATCH] add categories support to Crunchyroll.browse() --- .../teapod/parser/crunchyroll/Crunchyroll.kt | 54 +++++++++++++++---- .../teapod/parser/crunchyroll/DataTypes.kt | 26 ++++++++- .../activity/main/viewmodel/HomeViewModel.kt | 1 - 3 files changed, 70 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt index b3fa4ee..73ef269 100644 --- a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt +++ b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt @@ -42,7 +42,6 @@ import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.put import org.mosad.teapod.preferences.EncryptedPreferences import org.mosad.teapod.preferences.Preferences -import org.mosad.teapod.util.concatenate private val json = Json { ignoreUnknownKeys = true } @@ -102,7 +101,6 @@ object Crunchyroll { var success = false// is false withContext(Dispatchers.IO) { - // TODO handle exceptions Log.i(TAG, "getting token ...") val status = try { @@ -117,7 +115,7 @@ object Crunchyroll { if (status == HttpStatusCode.Unauthorized) { Log.e(TAG, "Could not complete login: " + "${status.value} ${status.description}. " + - "Propably wrong username or password") + "Probably wrong username or password") } status @@ -255,7 +253,6 @@ object Crunchyroll { * General element/media functions: browse, search, objects, season_list */ - // TODO categories /** * Browse the media available on crunchyroll. * @@ -265,13 +262,14 @@ object Crunchyroll { * @return A **[BrowseResult]** object is returned. */ suspend fun browse( + categories: List = emptyList(), sortBy: SortBy = SortBy.ALPHABETICAL, seasonTag: String = "", start: Int = 0, n: Int = 10 ): BrowseResult { val browseEndpoint = "/content/v1/browse" - val noneOptParams = listOf( + val parameters = mutableListOf( "locale" to Preferences.preferredLocale.toLanguageTag(), "sort_by" to sortBy.str, "start" to start, @@ -279,10 +277,13 @@ object Crunchyroll { ) // if a season tag is present add it to the parameters - val parameters = if (seasonTag.isNotEmpty()) { - concatenate(noneOptParams, listOf("season_tag" to seasonTag)) - } else { - noneOptParams + if (seasonTag.isNotEmpty()) { + parameters.add("season_tag" to seasonTag) + } + + // if a season tag is present add it to the parameters + if (categories.isNotEmpty()) { + parameters.add("categories" to categories.joinToString(",") { it.str }) } val browseResult: BrowseResult = try { @@ -412,6 +413,12 @@ object Crunchyroll { } } + /** + * Get all available seasons for a series. + * + * @param seriesId The series id for which to get the seasons + * @return A **[Seasons]** object with a list of **[Season]** + */ suspend fun seasons(seriesId: String): Seasons { val seasonsEndpoint = "/cms/v2/${token.country}/M3/crunchyroll/seasons" val parameters = listOf( @@ -430,6 +437,12 @@ object Crunchyroll { } } + /** + * Get all available episodes for a season. + * + * @param seasonId The season id for which to get the episodes + * @return A **[Episodes]** object with a list of **[Episode]** + */ suspend fun episodes(seasonId: String): Episodes { val episodesEndpoint = "/cms/v2/${token.country}/M3/crunchyroll/episodes" val parameters = listOf( @@ -448,6 +461,12 @@ object Crunchyroll { } } + /** + * Get all available subtitles and streams of a episode. + * + * @param url The playback url of a episode + * @return A **[Playback]** object + */ suspend fun playback(url: String): Playback { return try { requestGet("", url = url) @@ -546,6 +565,13 @@ object Crunchyroll { requestPost(playheadsEndpoint, parameters, json) } + /** + * Get similar media for a show/movie. + * + * @param seriesId The crunchyroll series id of the media + * @param n The maximum number of results to return, default = 10 + * @return A **[SimilarToResult]** object + */ suspend fun similarTo(seriesId: String, n: Int = 10): SimilarToResult { val similarToEndpoint = "/content/v1/$accountID/similar_to" val parameters = listOf( @@ -615,6 +641,11 @@ object Crunchyroll { * Account/Profile functions */ + /** + * Get profile information for the currently logged in account. + * + * @return A **[Profile]** object + */ suspend fun profile(): Profile { val profileEndpoint = "/accounts/v1/me/profile" @@ -626,6 +657,11 @@ object Crunchyroll { } } + /** + * Post the preferred content subtitle language. + * + * @param languageTag the preferred language as language tag + */ suspend fun postPrefSubLanguage(languageTag: String) { val profileEndpoint = "/accounts/v1/me/profile" val json = buildJsonObject { diff --git a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt index 3d05973..6863e36 100644 --- a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt +++ b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt @@ -50,6 +50,25 @@ enum class SortBy(val str: String) { POPULARITY("popularity") } +@Suppress("unused") +enum class Categories(val str: String) { + ACTION("action"), + ADVENTURE("adventure"), + COMEDY("comedy"), + DRAMA("drama"), + FANTASY("fantasy"), + MUSIC("music"), + ROMANCE("romance"), + SCI_FI("sci-fi"), + SEINEN("seinen"), + SHOJO("shojo"), + SHONEN("shonen"), + SLICE_OF_LIFE("slice+of+life"), + SPORTS("sports"), + SUPERNATURAL("supernatural"), + THRILLER("thriller") +} + /** * token, index, account. This must pe present for the app to work! */ @@ -206,7 +225,12 @@ val NoneSimilarToResult = SimilarToResult(0, emptyList()) val NoneDiscSeasonList = DiscSeasonList(0, emptyList()) val NoneContinueWatchingList = ContinueWatchingList(0, emptyList()) -val NoneUpNextSeriesItem = UpNextSeriesItem(0, false, false, NoneEpisodePanel) +val NoneUpNextSeriesItem = UpNextSeriesItem( + playhead = 0, + fullyWatched = false, + neverWatched = false, + panel = NoneEpisodePanel +) /** * series data class diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/viewmodel/HomeViewModel.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/viewmodel/HomeViewModel.kt index 97b2409..9b4f376 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/main/viewmodel/HomeViewModel.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/viewmodel/HomeViewModel.kt @@ -61,7 +61,6 @@ class HomeViewModel : ViewModel() { uiState.emit(UiState.Loading) try { // run the loading in parallel to speed up the process - val upNextJob = viewModelScope.async { Crunchyroll.upNextAccount().items } val watchlistJob = viewModelScope.async { Crunchyroll.watchlist(50).items } val recentlyAddedJob = viewModelScope.async {