fix(plex): a checkpoint sent just before the finish no longer lands on the watched row

The 10 s tick in flight when the player finishes (or a refusal rollback whose state write in fact
committed) wrote its mid-item position onto the freshly watched row and scheduled a resume push
after the scrobble, so Plex showed the item in progress again. The checkpoint is now a conditional
write that skips a row marked watched in the last 30 s and answers like a finish; a rewatch past
that is checkpointed as before. Marking an item (or a season/show) watched also supersedes resume
pushes still in flight, as the near-end finish already did.
This commit is contained in:
2026-10-28 18:56:12 +01:00
parent e96a562f14
commit 24190e4c16
4 changed files with 112 additions and 18 deletions
+4 -2
View File
@@ -348,7 +348,8 @@ def test_an_early_checkpoint_drops_a_bare_state_and_zeroes_a_marked_one(db, make
user = make_user()
lib = _lib(db)
bare, hid = _movie(db, lib, "bare"), _movie(db, lib, "hid")
st = service.checkpoint(db, user, bare.id, None, 120, NOW, dirty=True)
assert service.checkpoint(db, user, bare.id, None, 120, NOW, dirty=True)
st = queries.state(db, user, bare.id)
assert (st.position_seconds, st.synced_to_plex) == (120, False)
_state(db, user, hid, status="hidden", position_seconds=40)
service.clear_progress(db, queries.state(db, user, bare.id), NOW)
@@ -429,7 +430,8 @@ def test_a_first_write_that_lost_the_race_updates_the_winners_row(db, make_user)
user = make_user()
it = _movie(db, _lib(db), "m-race")
_state(db, user, it, position_seconds=10) # the request that won, committed
st = service.checkpoint(db, user, it.id, None, 42, NOW, dirty=True) # read "none" before it
assert service.checkpoint(db, user, it.id, None, 42, NOW, dirty=True) # read "none" before it
st = queries.state(db, user, it.id)
assert (st.position_seconds, st.synced_to_plex) == (42, False)
st = service.set_status(db, user, it.id, None, "hidden")
assert st.status == "hidden"