diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/TmdbClient.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/TmdbClient.kt index f91d4eb..ef6f6f9 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/TmdbClient.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/TmdbClient.kt @@ -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) diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/AccountV4Api.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/AccountV4Api.kt new file mode 100644 index 0000000..e1fef5b --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/AccountV4Api.kt @@ -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> + + @GET("/account/{account_id}/movie/favorites") + suspend fun getFavoriteMovies(@Path("account_id") accountId: String, page: Int = 1): Response> + + @GET("/account/{account_id}/tv/favorites") + suspend fun getFavoriteTvShows(@Path("account_id") accountId: String, page: Int = 1): Response> + + @GET("/account/{account_id}/movie/recommendations") + suspend fun getMovieRecommendations(@Path("account_id") accountId: String, page: Int = 1): Response> + + @GET("/account/{account_id}/tv/recommendations") + suspend fun getTvShowRecommendations(@Path("account_id") accountId: String, page: Int = 1): Response> + + @GET("/account/{account_id}/movie/watchlist") + suspend fun getMovieWatchlist(@Path("account_id") accountId: String, page: Int = 1): Response> + + @GET("/account/{account_id}/tv/watchlist") + suspend fun getTvShowWatchlist(@Path("account_id") accountId: String, page: Int = 1): Response> + + @GET("/account/{account_id}/movie/rated") + suspend fun getRatedMovies(@Path("account_id") accountId: String, page: Int = 1): Response> + + @GET("account/{account_id}/tv/rated") + suspend fun getRatedTvShows(@Path("account_id") accountId: String, page: Int = 1): Response> + +} \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/AccountV4Service.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/AccountV4Service.kt new file mode 100644 index 0000000..83bebbb --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/AccountV4Service.kt @@ -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> { + return service.getLists(accountId, page) + } + + suspend fun getFavoriteMovies(accountId: String, page: Int = 1): Response> { + return service.getFavoriteMovies(accountId, page) + } + + suspend fun getFavoriteTvShows(accountId: String, page: Int = 1): Response> { + return service.getFavoriteTvShows(accountId, page) + } + + suspend fun getMovieRecommendations(accountId: String, page: Int = 1): Response> { + return service.getMovieRecommendations(accountId, page) + } + + suspend fun getTvShowRecommendations(accountId: String, page: Int = 1): Response> { + return service.getTvShowRecommendations(accountId, page) + } + + suspend fun getMovieWatchlist(accountId: String, page: Int = 1): Response> { + return service.getMovieWatchlist(accountId, page) + } + + suspend fun getTvShowWatchlist(accountId: String, page: Int = 1): Response> { + return service.getTvShowWatchlist(accountId, page) + } + + suspend fun getRatedMovies(accountId: String, page: Int = 1): Response> { + return service.getRatedMovies(accountId, page) + } + + suspend fun getRatedTvShows(accountId: String, page: Int = 1): Response> { + return service.getRatedTvShows(accountId, page) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Api.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Api.kt index 01b6064..811768f 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Api.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Api.kt @@ -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 @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 } \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Service.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Service.kt new file mode 100644 index 0000000..55f7356 --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Service.kt @@ -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 { + return service.getList(listId, apiKey, page) + } + + suspend fun createList(body: CreateListBody): Response { + return service.createList(body) + } + + suspend fun updateList(listId: Int, body: ListUpdateBody): Response { + return service.updateList(listId, body) + } + + suspend fun clearList(listId: Int): Response { + return service.clearList(listId) + } + + suspend fun deleteList(listId: Int): Response { + return service.deleteList(listId) + } + + suspend fun addItemsToList(listId: Int, body: AddToListBody): Response { + return service.addItemsToList(listId, body) + } + + suspend fun updateListItems(listId: Int, body: UpdateListItemBody): Response { + return service.updateListItems(listId, body) + } + + suspend fun deleteListItems(listId: Int, body: DeleteListItemsBody): Response { + return service.deleteListItems(listId, body) + } + + suspend fun getListItemStatus(listId: Int, mediaId: Int, mediaType: String): Response { + return service.getListItemStatus(listId, mediaId, mediaType) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItemStatusResponse.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItemStatusResponse.kt new file mode 100644 index 0000000..e997d08 --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItemStatusResponse.kt @@ -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) \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/StatusResponse.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/StatusResponse.kt index e31966e..c8b4ec8 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/StatusResponse.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/StatusResponse.kt @@ -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 diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4AccountList.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4AccountList.kt new file mode 100644 index 0000000..19ea868 --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4AccountList.kt @@ -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 +) diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4AccountResponse.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4AccountResponse.kt new file mode 100644 index 0000000..795e2d6 --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4AccountResponse.kt @@ -0,0 +1,10 @@ +package com.owenlejeune.tvtime.api.tmdb.api.v4.model + +import com.google.gson.annotations.SerializedName + +class V4AccountResponse( + @SerializedName("page") val page: Int, + @SerializedName("total_results") val totalResults: Int, + @SerializedName("total_pages") val totalPages: Int, + @SerializedName("results") val results: List +) \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4RatedMedia.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4RatedMedia.kt new file mode 100644 index 0000000..aea1baa --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4RatedMedia.kt @@ -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, + @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 + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4RatedMovie.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4RatedMovie.kt new file mode 100644 index 0000000..8898bb9 --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4RatedMovie.kt @@ -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, + 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 +) \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4RatedTv.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4RatedTv.kt new file mode 100644 index 0000000..e8e0437 --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/V4RatedTv.kt @@ -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, + originalLanguage: String, + originalName: String, + posterPath: String?, + popularity: Float, + releaseDate: String, + @SerializedName("origin_country") val originCountry: List, +): V4RatedMedia( + RatedType.SERIES, id, overview, name, voteAverage, voteCount, rating, releaseDate, + backdropPath, genreIds, originalLanguage, originalName, posterPath, popularity +) \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/di/modules/modules.kt b/app/src/main/java/com/owenlejeune/tvtime/di/modules/modules.kt index 1708a84..9011eae 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/di/modules/modules.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/di/modules/modules.kt @@ -19,6 +19,8 @@ val networkModule = module { single { TmdbClient() } single { get().createV4AuthenticationService() } + single { get().createV4AccountService() } + single { get().createV4ListService() } single { get().createAccountService() } single { get().createGuestSessionService() } single { get().createAuthenticationService() } diff --git a/app/src/main/java/com/owenlejeune/tvtime/utils/SessionManager.kt b/app/src/main/java/com/owenlejeune/tvtime/utils/SessionManager.kt index c928db4..cb4b85a 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/utils/SessionManager.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/utils/SessionManager.kt @@ -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 = emptyList() val ratedMovies: List 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() {