Improved Simkl autosync and fixed syncing seasons (#722)

* Improved simkl autosync and fixed syncing seasons
This commit is contained in:
self-similarity 2023-10-28 22:55:49 +00:00 committed by GitHub
parent b2e0b7dec8
commit 137d833d4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 31 deletions

View File

@ -1465,6 +1465,15 @@ interface EpisodeResponse {
var nextAiring: NextAiring? var nextAiring: NextAiring?
var seasonNames: List<SeasonData>? var seasonNames: List<SeasonData>?
fun getLatestEpisodes(): Map<DubStatus, Int?> fun getLatestEpisodes(): Map<DubStatus, Int?>
/** Count all episodes in all previous seasons up until this episode to get a total count.
* Example:
* Season 1: 10 episodes.
* Season 2: 6 episodes.
*
* getTotalEpisodeIndex(episode = 3, season = 2) -> 10 + 3 = 13
* */
fun getTotalEpisodeIndex(episode: Int, season: Int): Int
} }
@JvmName("addSeasonNamesString") @JvmName("addSeasonNamesString")
@ -1544,6 +1553,12 @@ data class AnimeLoadResponse(
.takeUnless { it == Int.MIN_VALUE } .takeUnless { it == Int.MIN_VALUE }
}.toMap() }.toMap()
} }
override fun getTotalEpisodeIndex(episode: Int, season: Int): Int {
return this.episodes.maxOf { (_, episodes) ->
episodes.count { ((it.season ?: Int.MIN_VALUE) < season) && it.season != 0 }
} + episode
}
} }
/** /**
@ -1752,6 +1767,12 @@ data class TvSeriesLoadResponse(
.takeUnless { it == Int.MIN_VALUE } .takeUnless { it == Int.MIN_VALUE }
return mapOf(DubStatus.None to max) return mapOf(DubStatus.None to max)
} }
override fun getTotalEpisodeIndex(episode: Int, season: Int): Int {
return episodes.count {
(it.season ?: Int.MIN_VALUE) < season && it.season != 0
} + episode
}
} }
suspend fun MainAPI.newTvSeriesLoadResponse( suspend fun MainAPI.newTvSeriesLoadResponse(

View File

@ -376,6 +376,8 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI {
private var status: Int? = null, private var status: Int? = null,
private var addEpisodes: Pair<List<MediaObject.Season>?, List<MediaObject.Season.Episode>?>? = null, private var addEpisodes: Pair<List<MediaObject.Season>?, List<MediaObject.Season.Episode>?>? = null,
private var removeEpisodes: Pair<List<MediaObject.Season>?, List<MediaObject.Season.Episode>?>? = null, private var removeEpisodes: Pair<List<MediaObject.Season>?, List<MediaObject.Season.Episode>?>? = null,
// Required for knowing if the status should be overwritten
private var onList: Boolean = false
) { ) {
fun interceptor(interceptor: Interceptor) = apply { this.interceptor = interceptor } fun interceptor(interceptor: Interceptor) = apply { this.interceptor = interceptor }
fun apiUrl(url: String) = apply { this.url = url } fun apiUrl(url: String) = apply { this.url = url }
@ -387,6 +389,7 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI {
} }
fun status(newStatus: Int?, oldStatus: Int?) = apply { fun status(newStatus: Int?, oldStatus: Int?) = apply {
onList = oldStatus != null
// Only set status if its new // Only set status if its new
if (newStatus != oldStatus) { if (newStatus != oldStatus) {
this.status = newStatus this.status = newStatus
@ -412,6 +415,11 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI {
// Do not add episodes if there is no change // Do not add episodes if there is no change
if (newEpisodes > (oldEpisodes ?: 0)) { if (newEpisodes > (oldEpisodes ?: 0)) {
this.addEpisodes = getEpisodes(allEpisodes.take(newEpisodes)) this.addEpisodes = getEpisodes(allEpisodes.take(newEpisodes))
// Set to watching if episodes are added and there is no current status
if (!onList) {
status = SimklListStatusType.Watching.value
}
} }
if ((oldEpisodes ?: 0) > newEpisodes) { if ((oldEpisodes ?: 0) > newEpisodes) {
this.removeEpisodes = getEpisodes(allEpisodes.drop(newEpisodes)) this.removeEpisodes = getEpisodes(allEpisodes.drop(newEpisodes))
@ -431,6 +439,28 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI {
interceptor = interceptor interceptor = interceptor
).isSuccessful ).isSuccessful
} else { } else {
val statusResponse = status?.let { setStatus ->
val newStatus =
SimklListStatusType.values()
.firstOrNull { it.value == setStatus }?.originalName
?: SimklListStatusType.Watching.originalName!!
app.post(
"${this.url}/sync/add-to-list",
json = StatusRequest(
shows = listOf(
StatusMediaObject(
null,
null,
ids,
newStatus,
)
), movies = emptyList()
),
interceptor = interceptor
).isSuccessful
} ?: true
val episodeRemovalResponse = removeEpisodes?.let { (seasons, episodes) -> val episodeRemovalResponse = removeEpisodes?.let { (seasons, episodes) ->
app.post( app.post(
"${this.url}/sync/history/remove", "${this.url}/sync/history/remove",
@ -472,28 +502,6 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI {
true true
} }
val statusResponse = status?.let { setStatus ->
val newStatus =
SimklListStatusType.values()
.firstOrNull { it.value == setStatus }?.originalName
?: SimklListStatusType.Watching.originalName!!
app.post(
"${this.url}/sync/add-to-list",
json = StatusRequest(
shows = listOf(
StatusMediaObject(
null,
null,
ids,
newStatus,
)
), movies = emptyList()
),
interceptor = interceptor
).isSuccessful
} ?: true
statusResponse && episodeRemovalResponse && historyResponse statusResponse && episodeRemovalResponse && historyResponse
} }
} }
@ -1051,4 +1059,4 @@ class SimklApi(index: Int) : AccountManager(index), SyncAPI {
return true return true
} }
} }

View File

@ -1023,7 +1023,7 @@ class GeneratorPlayer : FullScreenPlayer() {
ctx.getString(R.string.episode_sync_enabled_key), true ctx.getString(R.string.episode_sync_enabled_key), true
) )
) maxEpisodeSet = meta.episode ) maxEpisodeSet = meta.episode
sync.modifyMaxEpisode(meta.episode) sync.modifyMaxEpisode(meta.totalEpisodeIndex ?: meta.episode)
} }
} }

View File

@ -47,7 +47,9 @@ data class ResultEpisode(
/** /**
* Conveys if the episode itself is marked as watched * Conveys if the episode itself is marked as watched
**/ **/
val videoWatchState: VideoWatchState val videoWatchState: VideoWatchState,
/** Sum of all previous season episode counts + episode */
val totalEpisodeIndex: Int? = null,
) )
fun ResultEpisode.getRealPosition(): Long { fun ResultEpisode.getRealPosition(): Long {
@ -82,6 +84,7 @@ fun buildResultEpisode(
isFiller: Boolean? = null, isFiller: Boolean? = null,
tvType: TvType, tvType: TvType,
parentId: Int, parentId: Int,
totalEpisodeIndex: Int? = null,
): ResultEpisode { ): ResultEpisode {
val posDur = getViewPos(id) val posDur = getViewPos(id)
val videoWatchState = getVideoWatchState(id) ?: VideoWatchState.None val videoWatchState = getVideoWatchState(id) ?: VideoWatchState.None
@ -103,7 +106,8 @@ fun buildResultEpisode(
isFiller, isFiller,
tvType, tvType,
parentId, parentId,
videoWatchState videoWatchState,
totalEpisodeIndex
) )
} }

View File

@ -2215,6 +2215,10 @@ class ResultViewModel2 : ViewModel() {
val id = val id =
mainId + episode + idIndex * 1_000_000 + (i.season?.times(10_000) mainId + episode + idIndex * 1_000_000 + (i.season?.times(10_000)
?: 0) ?: 0)
val totalIndex =
i.season?.let { season -> loadResponse.getTotalEpisodeIndex(episode, season) }
if (!existingEpisodes.contains(id)) { if (!existingEpisodes.contains(id)) {
existingEpisodes.add(id) existingEpisodes.add(id)
val seasonData = loadResponse.seasonNames.getSeason(i.season) val seasonData = loadResponse.seasonNames.getSeason(i.season)
@ -2234,7 +2238,8 @@ class ResultViewModel2 : ViewModel() {
i.description, i.description,
fillers.getOrDefault(episode, false), fillers.getOrDefault(episode, false),
loadResponse.type, loadResponse.type,
mainId mainId,
totalIndex
) )
val season = eps.seasonIndex ?: 0 val season = eps.seasonIndex ?: 0
@ -2263,6 +2268,9 @@ class ResultViewModel2 : ViewModel() {
val seasonData = val seasonData =
loadResponse.seasonNames.getSeason(episode.season) loadResponse.seasonNames.getSeason(episode.season)
val totalIndex =
episode.season?.let { season -> loadResponse.getTotalEpisodeIndex(episodeIndex, season) }
val ep = val ep =
buildResultEpisode( buildResultEpisode(
loadResponse.name, loadResponse.name,
@ -2279,7 +2287,8 @@ class ResultViewModel2 : ViewModel() {
episode.description, episode.description,
null, null,
loadResponse.type, loadResponse.type,
mainId mainId,
totalIndex
) )
val season = ep.seasonIndex ?: 0 val season = ep.seasonIndex ?: 0
@ -2310,7 +2319,8 @@ class ResultViewModel2 : ViewModel() {
null, null,
null, null,
loadResponse.type, loadResponse.type,
mainId mainId,
null
) )
) )
} }
@ -2332,7 +2342,8 @@ class ResultViewModel2 : ViewModel() {
null, null,
null, null,
loadResponse.type, loadResponse.type,
mainId mainId,
null
) )
) )
} }
@ -2354,7 +2365,8 @@ class ResultViewModel2 : ViewModel() {
null, null,
null, null,
loadResponse.type, loadResponse.type,
mainId mainId,
null
) )
) )
} }