some more v4 api stuff

This commit is contained in:
Owen LeJeune
2022-06-21 15:20:58 -04:00
parent 007db6324e
commit d997b7bf46
14 changed files with 282 additions and 6 deletions

View File

@@ -5,7 +5,9 @@ import com.owenlejeune.tvtime.BuildConfig
import com.owenlejeune.tvtime.api.Client
import com.owenlejeune.tvtime.api.QueryParam
import com.owenlejeune.tvtime.api.tmdb.api.v3.*
import com.owenlejeune.tvtime.api.tmdb.api.v4.AccountV4Api
import com.owenlejeune.tvtime.api.tmdb.api.v4.AuthenticationV4Api
import com.owenlejeune.tvtime.api.tmdb.api.v4.ListV4Api
import com.owenlejeune.tvtime.extensions.addQueryParams
import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.utils.SessionManager
@@ -59,10 +61,18 @@ class TmdbClient: KoinComponent {
return client.create(AccountApi::class.java)
}
fun createV4AccountService(): AccountV4Api {
return clientV4.create(AccountV4Api::class.java)
}
fun createSearchService(): SearchApi {
return client.create(SearchApi::class.java)
}
fun createV4ListService(): ListV4Api {
return clientV4.create(ListV4Api::class.java)
}
private inner class TmdbInterceptor: Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val apiParam = QueryParam("api_key", BuildConfig.TMDB_ApiKey)

View File

@@ -0,0 +1,42 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.FavoriteMovie
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.FavoriteTvSeries
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4AccountList
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4AccountResponse
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4RatedMovie
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4RatedTv
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Path
interface AccountV4Api {
@GET("/account/{account_id}/lists")
suspend fun getLists(@Path("account_id") accountId: String, page: Int = 1): Response<V4AccountResponse<V4AccountList>>
@GET("/account/{account_id}/movie/favorites")
suspend fun getFavoriteMovies(@Path("account_id") accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteMovie>>
@GET("/account/{account_id}/tv/favorites")
suspend fun getFavoriteTvShows(@Path("account_id") accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteTvSeries>>
@GET("/account/{account_id}/movie/recommendations")
suspend fun getMovieRecommendations(@Path("account_id") accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteMovie>>
@GET("/account/{account_id}/tv/recommendations")
suspend fun getTvShowRecommendations(@Path("account_id") accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteTvSeries>>
@GET("/account/{account_id}/movie/watchlist")
suspend fun getMovieWatchlist(@Path("account_id") accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteMovie>>
@GET("/account/{account_id}/tv/watchlist")
suspend fun getTvShowWatchlist(@Path("account_id") accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteTvSeries>>
@GET("/account/{account_id}/movie/rated")
suspend fun getRatedMovies(@Path("account_id") accountId: String, page: Int = 1): Response<V4AccountResponse<V4RatedMovie>>
@GET("account/{account_id}/tv/rated")
suspend fun getRatedTvShows(@Path("account_id") accountId: String, page: Int = 1): Response<V4AccountResponse<V4RatedTv>>
}

View File

@@ -0,0 +1,52 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4
import com.owenlejeune.tvtime.api.tmdb.TmdbClient
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.FavoriteMovie
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.FavoriteTvSeries
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4AccountList
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4AccountResponse
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4RatedMovie
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4RatedTv
import retrofit2.Response
class AccountV4Service {
private val service by lazy { TmdbClient().createV4AccountService() }
suspend fun getLists(accountId: String, page: Int = 1): Response<V4AccountResponse<V4AccountList>> {
return service.getLists(accountId, page)
}
suspend fun getFavoriteMovies(accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteMovie>> {
return service.getFavoriteMovies(accountId, page)
}
suspend fun getFavoriteTvShows(accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteTvSeries>> {
return service.getFavoriteTvShows(accountId, page)
}
suspend fun getMovieRecommendations(accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteMovie>> {
return service.getMovieRecommendations(accountId, page)
}
suspend fun getTvShowRecommendations(accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteTvSeries>> {
return service.getTvShowRecommendations(accountId, page)
}
suspend fun getMovieWatchlist(accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteMovie>> {
return service.getMovieWatchlist(accountId, page)
}
suspend fun getTvShowWatchlist(accountId: String, page: Int = 1): Response<V4AccountResponse<FavoriteTvSeries>> {
return service.getTvShowWatchlist(accountId, page)
}
suspend fun getRatedMovies(accountId: String, page: Int = 1): Response<V4AccountResponse<V4RatedMovie>> {
return service.getRatedMovies(accountId, page)
}
suspend fun getRatedTvShows(accountId: String, page: Int = 1): Response<V4AccountResponse<V4RatedTv>> {
return service.getRatedTvShows(accountId, page)
}
}

View File

@@ -7,7 +7,7 @@ import retrofit2.http.*
interface ListV4Api {
@GET("list/{id}")
suspend fun getLists(
suspend fun getList(
@Path("id") listId: Int,
@Query("api_key") apiKey: String,
@Query("page") page: Int = 1
@@ -35,6 +35,6 @@ interface ListV4Api {
suspend fun deleteListItems(@Path("id") listId: Int, body: DeleteListItemsBody): Response<AddToListResponse>
@GET("list/{id}/item_status")
suspend fun getListItemStatus(@Path("id") listId: Int, @Query("media_id") mediaId: Int, @Query("media_type") mediaType: String)
suspend fun getListItemStatus(@Path("id") listId: Int, @Query("media_id") mediaId: Int, @Query("media_type") mediaType: String): Response<ListItemStatusResponse>
}

View File

@@ -0,0 +1,46 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4
import com.owenlejeune.tvtime.api.tmdb.TmdbClient
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.*
import retrofit2.Response
class ListV4Service {
private val service by lazy { TmdbClient().createV4ListService() }
suspend fun getLists(listId: Int, apiKey: String, page: Int = 1): Response<MediaList> {
return service.getList(listId, apiKey, page)
}
suspend fun createList(body: CreateListBody): Response<CreateListResponse> {
return service.createList(body)
}
suspend fun updateList(listId: Int, body: ListUpdateBody): Response<StatusResponse> {
return service.updateList(listId, body)
}
suspend fun clearList(listId: Int): Response<ClearListResponse> {
return service.clearList(listId)
}
suspend fun deleteList(listId: Int): Response<StatusResponse> {
return service.deleteList(listId)
}
suspend fun addItemsToList(listId: Int, body: AddToListBody): Response<AddToListResponse> {
return service.addItemsToList(listId, body)
}
suspend fun updateListItems(listId: Int, body: UpdateListItemBody): Response<AddToListResponse> {
return service.updateListItems(listId, body)
}
suspend fun deleteListItems(listId: Int, body: DeleteListItemsBody): Response<AddToListResponse> {
return service.deleteListItems(listId, body)
}
suspend fun getListItemStatus(listId: Int, mediaId: Int, mediaType: String): Response<ListItemStatusResponse> {
return service.getListItemStatus(listId, mediaId, mediaType)
}
}

View File

@@ -0,0 +1,13 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
import com.owenlejeune.tvtime.ui.screens.MediaViewType
class ListItemStatusResponse(
statusMessage: String,
isSuccess: Boolean,
statusCode: Int,
@SerializedName("media_type") val mediaType: MediaViewType,
@SerializedName("id") val id: Int,
@SerializedName("media_id") val mediaId: Int
): StatusResponse(statusMessage, isSuccess, statusCode)

View File

@@ -2,7 +2,7 @@ package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
class StatusResponse(
open class StatusResponse(
@SerializedName("status_message") val statusMessage: String,
@SerializedName("success") val isSuccess: Boolean,
@SerializedName("status_code") val statusCode: Int

View File

@@ -0,0 +1,23 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
class V4AccountList(
@SerializedName("iso_639_1") val languageCode: String,
@SerializedName("id") val id: Int,
@SerializedName("featured") val featured: Int,
@SerializedName("description") val description: String,
@SerializedName("revenue") val revenue: String,
@SerializedName("public") val public: Int,
@SerializedName("name") val name: String,
@SerializedName("updated_at") val updatedAt: String,
@SerializedName("created_at") val createdAt: String,
// @SerializedName("sort_by")
@SerializedName("backdrop_path") val backdropPath: String,
@SerializedName("runtime") val runtime: Int,
@SerializedName("average_rating") val averageRating: Float,
@SerializedName("iso_3166_1") val countryCode: String,
@SerializedName("adult") val adult: Int,
@SerializedName("number_of_items") val numberOfItems: Int,
@SerializedName("poster_path") val posterPath: String
)

View File

@@ -0,0 +1,10 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
class V4AccountResponse<T>(
@SerializedName("page") val page: Int,
@SerializedName("total_results") val totalResults: Int,
@SerializedName("total_pages") val totalPages: Int,
@SerializedName("results") val results: List<T>
)

View File

@@ -0,0 +1,31 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
abstract class V4RatedMedia(
var type: RatedType,
@SerializedName("id") val id: Int,
@SerializedName("overview") val overview: String,
@SerializedName("name", alternate = ["title"]) val name: String,
@SerializedName("vote_average") val voteAverage: Float,
@SerializedName("vote_count") val voteCount: Int,
@SerializedName("rating") val rating: AccountRating,
@SerializedName("release_date", alternate = ["first_air_date", "air_date"]) val releaseDate: String,
@SerializedName("backdrop_path") val backdropPath: String?,
@SerializedName("genre_ids") val genreIds: List<Int>,
@SerializedName("original_language") val originalLanguage: String,
@SerializedName("original_name", alternate = ["original_title"]) val originalName: String,
@SerializedName("poster_path") val posterPath: String?,
@SerializedName("popularity") val popularity: Float
) {
enum class RatedType {
MOVIE,
SERIES,
// EPISODE
}
inner class AccountRating(
@SerializedName("value") val rating: Int,
@SerializedName("created_at") val createdAt: String
)
}

View File

@@ -0,0 +1,24 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
class V4RatedMovie(
id: Int,
overview: String,
name: String,
voteAverage: Float,
voteCount: Int,
rating: AccountRating,
backdropPath: String?,
genreIds: List<Int>,
originalLanguage: String,
originalName: String,
posterPath: String?,
popularity: Float,
releaseDate: String,
@SerializedName("adult") val isAdult: Boolean,
@SerializedName("video") val video: Boolean
): V4RatedMedia(
RatedType.MOVIE, id, overview, name, voteAverage, voteCount, rating, releaseDate,
backdropPath, genreIds, originalLanguage, originalName, posterPath, popularity
)

View File

@@ -0,0 +1,23 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
class V4RatedTv(
id: Int,
overview: String,
name: String,
voteAverage: Float,
voteCount: Int,
rating: AccountRating,
backdropPath: String?,
genreIds: List<Int>,
originalLanguage: String,
originalName: String,
posterPath: String?,
popularity: Float,
releaseDate: String,
@SerializedName("origin_country") val originCountry: List<String>,
): V4RatedMedia(
RatedType.SERIES, id, overview, name, voteAverage, voteCount, rating, releaseDate,
backdropPath, genreIds, originalLanguage, originalName, posterPath, popularity
)

View File

@@ -19,6 +19,8 @@ val networkModule = module {
single { TmdbClient() }
single { get<TmdbClient>().createV4AuthenticationService() }
single { get<TmdbClient>().createV4AccountService() }
single { get<TmdbClient>().createV4ListService() }
single { get<TmdbClient>().createAccountService() }
single { get<TmdbClient>().createGuestSessionService() }
single { get<TmdbClient>().createAuthenticationService() }

View File

@@ -149,7 +149,7 @@ object SessionManager: KoinComponent {
sessionResponse.body()?.let { sr ->
preferences.authorizedSessionId = sr.sessionId
preferences.guestSessionId = ""
_currentSession = AuthorizedSession(accessToken = ar.accessToken)
_currentSession = AuthorizedSession(accessToken = ar.accessToken, accountId = ar.accountId)
_currentSession?.initialize()
isV4SignInInProgress = false
return true
@@ -168,7 +168,7 @@ object SessionManager: KoinComponent {
return false
}
abstract class Session(val sessionId: String, val isAuthorized: Boolean, val accessToken: String = "") {
abstract class Session(val sessionId: String, val isAuthorized: Boolean, val accessToken: String = "", val accountId: String = "") {
protected open var _ratedMovies: List<RatedMovie> = emptyList()
val ratedMovies: List<RatedMovie>
get() = _ratedMovies
@@ -275,7 +275,7 @@ object SessionManager: KoinComponent {
}
private class AuthorizedSession(accessToken: String = ""): Session(preferences.authorizedSessionId, true, accessToken) {
private class AuthorizedSession(accessToken: String = "", accountId: String = ""): Session(preferences.authorizedSessionId, true, accessToken, accountId) {
private val service by lazy { AccountService() }
override suspend fun initialize() {