Skip to content

Commit

Permalink
draft Show notes: send note to Trakt
Browse files Browse the repository at this point in the history
  • Loading branch information
UweTrottmann committed Sep 12, 2024
1 parent 59ec745 commit 39fb3aa
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import com.battlelancer.seriesguide.provider.SeriesGuideContract
import com.battlelancer.seriesguide.provider.SeriesGuideDatabase
import com.battlelancer.seriesguide.provider.SgRoomDatabase
import com.battlelancer.seriesguide.sync.HexagonShowSync
import com.battlelancer.seriesguide.traktapi.TraktCredentials
import com.battlelancer.seriesguide.traktapi.TraktTools2
import com.uwetrottmann.androidutils.AndroidUtils
import com.uwetrottmann.seriesguide.backend.shows.model.SgCloudShow
import dagger.Lazy
Expand Down Expand Up @@ -452,30 +454,50 @@ class ShowTools2 @Inject constructor(
}

/**
* Uploads to Cloud and on success saves to local database.
* Uploads to Hexagon and Trakt and on success saves to local database.
* Does not sanitize the given values.
*/
suspend fun storeUserNote(showId: Long, userNote: String?): Boolean {
// Send to Cloud.
// Send to cloud
val isCloudFailed = withContext(Dispatchers.Default) {
if (!HexagonSettings.isEnabled(context)) {
return@withContext false
}
if (isNotConnected(context)) {
return@withContext true
}
val sendToHexagon = HexagonSettings.isEnabled(context)
val sendToTrakt = TraktCredentials.get(context).hasCredentials()
if (!sendToHexagon && !sendToTrakt) return@withContext false

if (isNotConnected(context)) return@withContext true

val showTmdbId =
SgRoomDatabase.getInstance(context).sgShow2Helper().getShowTmdbId(showId)
if (showTmdbId == 0) {
return@withContext true
if (showTmdbId == 0) return@withContext true

// Send to Hexagon first, Trakt may fail if user is not VIP
if (sendToHexagon) {
val show = SgCloudShow()
show.tmdbId = showTmdbId
show.note = userNote
if (!uploadShowToCloud(show)) return@withContext true
}

val show = SgCloudShow()
show.tmdbId = showTmdbId
show.note = userNote

val success = uploadShowToCloud(show)
return@withContext !success
if (sendToTrakt) {
val trakt = SgApp.getServicesComponent(context).trakt()
val response = if (userNote == null) {
TODO("Need Trakt note ID")
// TraktTools2.deleteNote(trakt, traktNoteId)
} else {
// TODO Need to save Trakt note ID
TraktTools2.saveNoteForShow(trakt, showTmdbId, userNote)
}
val success = when (response) {
is TraktTools2.TraktResponse.Success -> true
is TraktTools2.TraktResponse.Error -> false
is TraktTools2.TraktResponse.IsNotVip -> true
is TraktTools2.TraktResponse.IsUnauthorized -> {
TraktCredentials.get(context).setCredentialsInvalid()
false
}
}
if (!success) return@withContext true
}
return@withContext false
}
// Do not save to local database if sending to cloud has failed.
if (isCloudFailed) return false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2021-2024 Uwe Trottmann
// SPDX-License-Identifier: Apache-2.0
// Copyright 2021-2024 Uwe Trottmann

package com.battlelancer.seriesguide.traktapi

Expand All @@ -13,19 +13,74 @@ import com.github.michaelbull.result.Result
import com.github.michaelbull.result.andThen
import com.github.michaelbull.result.mapError
import com.github.michaelbull.result.runCatching
import com.uwetrottmann.trakt5.TraktV2
import com.uwetrottmann.trakt5.entities.AddNoteRequest
import com.uwetrottmann.trakt5.entities.BaseShow
import com.uwetrottmann.trakt5.entities.LastActivity
import com.uwetrottmann.trakt5.entities.LastActivityMore
import com.uwetrottmann.trakt5.entities.LastActivityUpdated
import com.uwetrottmann.trakt5.entities.Note
import com.uwetrottmann.trakt5.entities.Ratings
import com.uwetrottmann.trakt5.entities.Show
import com.uwetrottmann.trakt5.entities.ShowIds
import com.uwetrottmann.trakt5.enums.Extended
import com.uwetrottmann.trakt5.enums.IdType
import com.uwetrottmann.trakt5.enums.Type
import retrofit2.Call
import retrofit2.Response
import retrofit2.awaitResponse

object TraktTools2 {

sealed class TraktResponse<T> {
data class Success<T>(val data: T) : TraktResponse<T>()
class IsNotVip<T> : TraktResponse<T>()
class IsUnauthorized<T> : TraktResponse<T>()
class Error<T> : TraktResponse<T>()
}

/**
* Adds or updates the note for the given show.
*/
suspend fun saveNoteForShow(
trakt: SgTrakt,
showTmdbId: Int,
noteText: String
): TraktResponse<Note> {
return awaitTraktCall(trakt.notes().addNote(
AddNoteRequest(
Show().apply {
ids = ShowIds.tmdb(showTmdbId)
},
noteText
)
), "update note")
}

suspend fun deleteNote(
trakt: SgTrakt,
noteId: Long
): TraktResponse<Void> {
return awaitTraktCall(trakt.notes().deleteNote(noteId), "delete note")
}

private suspend fun <T> awaitTraktCall(call: Call<T>, action: String): TraktResponse<T> {
try {
val response = call.awaitResponse()
if (response.isSuccessful) {
response.body()
?.let { return TraktResponse.Success(it) }
} else {
if (TraktV2.isNotVip(response)) return TraktResponse.IsNotVip()
if (TraktV2.isUnauthorized(response)) return TraktResponse.IsUnauthorized()
Errors.logAndReport(action, response)
}
} catch (e: Exception) {
Errors.logAndReport(action, e)
}
return TraktResponse.Error()
}

/**
* Look up a show by its TMDB ID, may return `null` if not found.
*/
Expand Down

0 comments on commit 39fb3aa

Please sign in to comment.