style: apply ruff format across backend + scripts (line-length 100)
Mechanical, whole-tree `ruff format` pass — no behaviour change. Recorded in .git-blame-ignore-revs (next commit) so git blame skips it.
This commit is contained in:
@@ -13,6 +13,7 @@ exist only in Siftlode are left untouched (union, Plex-authoritative on the inte
|
||||
Phases B (Siftlode→Plex push via scrobble/timeline) and C (incremental Plex→Siftlode via the watch
|
||||
history + onDeck, last-write-wins) build on this and land in later ships.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
@@ -61,10 +62,7 @@ def _plex_watch_to_state(
|
||||
|
||||
def _rk_to_id(db: Session) -> dict[str, int]:
|
||||
"""The rating_key → PlexItem.id lookup used to resolve a Plex leaf back to its mirrored row."""
|
||||
return {
|
||||
rk: iid
|
||||
for rk, iid in db.execute(select(PlexItem.rating_key, PlexItem.id)).all()
|
||||
}
|
||||
return {rk: iid for rk, iid in db.execute(select(PlexItem.rating_key, PlexItem.id)).all()}
|
||||
|
||||
|
||||
def _scan_plex_states(
|
||||
@@ -165,9 +163,7 @@ def link_for_push(db: Session, user_id: int) -> PlexLink | None:
|
||||
"""The active owner watch-push link for this user, or None when push is off / not the owner.
|
||||
Push is gated on `initial_import_done` so we never push a half-known local state over Plex's
|
||||
authoritative one before the one-time "Plex is master" import has reconciled them."""
|
||||
link = db.execute(
|
||||
select(PlexLink).where(PlexLink.user_id == user_id)
|
||||
).scalars().first()
|
||||
link = db.execute(select(PlexLink).where(PlexLink.user_id == user_id)).scalars().first()
|
||||
if link and link.uses_admin and link.sync_enabled and link.initial_import_done:
|
||||
return link
|
||||
return None
|
||||
@@ -222,11 +218,13 @@ def push_state_to_plex(
|
||||
# Flag the row synced — but an "unwatched" via status=new deletes the row, so there may be
|
||||
# nothing to flag; that's fine (unscrobble still happened). Skip the flag if the row was
|
||||
# re-edited since we captured `expect_ts` (leave it dirty for its own push / the reconcile).
|
||||
st = db.execute(
|
||||
select(PlexState).where(
|
||||
PlexState.user_id == user_id, PlexState.item_id == item_id
|
||||
st = (
|
||||
db.execute(
|
||||
select(PlexState).where(PlexState.user_id == user_id, PlexState.item_id == item_id)
|
||||
)
|
||||
).scalars().first()
|
||||
.scalars()
|
||||
.first()
|
||||
)
|
||||
if st is not None and _row_matches(st, expect_ts):
|
||||
st.synced_to_plex = True
|
||||
db.commit()
|
||||
@@ -270,7 +268,11 @@ def push_bulk_state_to_plex(user_id: int, changes: list[tuple[int, str, str]]) -
|
||||
# One bad item mustn't abort the rest of the batch; leave its row dirty
|
||||
# (synced_to_plex=False) for a later reconcile.
|
||||
log.warning(
|
||||
"Plex bulk push failed (user %s, item %s, %s): %s", user_id, item_id, action, e
|
||||
"Plex bulk push failed (user %s, item %s, %s): %s",
|
||||
user_id,
|
||||
item_id,
|
||||
action,
|
||||
e,
|
||||
)
|
||||
continue
|
||||
synced_ids.append(item_id)
|
||||
@@ -301,13 +303,17 @@ _LWW_TOLERANCE_S = 90
|
||||
def _active_sync_links(db: Session) -> list[PlexLink]:
|
||||
"""Every link with two-way sync actually running (owner MVP = one row). Iterated uniformly so
|
||||
P5b friend links slot in later without touching this loop."""
|
||||
return db.execute(
|
||||
select(PlexLink).where(
|
||||
PlexLink.uses_admin.is_(True),
|
||||
PlexLink.sync_enabled.is_(True),
|
||||
PlexLink.initial_import_done.is_(True),
|
||||
return (
|
||||
db.execute(
|
||||
select(PlexLink).where(
|
||||
PlexLink.uses_admin.is_(True),
|
||||
PlexLink.sync_enabled.is_(True),
|
||||
PlexLink.initial_import_done.is_(True),
|
||||
)
|
||||
)
|
||||
).scalars().all()
|
||||
.scalars()
|
||||
.all()
|
||||
)
|
||||
|
||||
|
||||
def _resolve_account_id(db: Session, plex: PlexClient, link: PlexLink) -> int:
|
||||
@@ -353,11 +359,13 @@ def _pull_apply(
|
||||
"""Bring one Plex-side positive signal into Siftlode under last-write-wins. Returns
|
||||
"watched"/"in_progress" if it changed the row, else None. Never clears a row (un-watch is the
|
||||
full reconcile's job) — this only pulls in watched/resume."""
|
||||
st = db.execute(
|
||||
select(PlexState).where(
|
||||
PlexState.user_id == user_id, PlexState.item_id == item_id
|
||||
st = (
|
||||
db.execute(
|
||||
select(PlexState).where(PlexState.user_id == user_id, PlexState.item_id == item_id)
|
||||
)
|
||||
).scalars().first()
|
||||
.scalars()
|
||||
.first()
|
||||
)
|
||||
if _same_state(st, status, pos):
|
||||
if st is not None and not st.synced_to_plex:
|
||||
st.synced_to_plex = True # already matches Plex → just settle the flag, no churn
|
||||
@@ -370,7 +378,12 @@ def _pull_apply(
|
||||
st = PlexState(user_id=user_id, item_id=item_id)
|
||||
db.add(st)
|
||||
if status == "watched":
|
||||
st.status, st.position_seconds, st.watched_at, st.progress_updated_at = "watched", 0, plex_ts, plex_ts
|
||||
st.status, st.position_seconds, st.watched_at, st.progress_updated_at = (
|
||||
"watched",
|
||||
0,
|
||||
plex_ts,
|
||||
plex_ts,
|
||||
)
|
||||
else:
|
||||
st.status, st.position_seconds, st.progress_updated_at = "new", pos, plex_ts
|
||||
st.synced_to_plex = True
|
||||
@@ -390,13 +403,17 @@ def _repush_dirty(db: Session, plex: PlexClient, link: PlexLink) -> int:
|
||||
select(PlexItem.id, PlexItem.rating_key, PlexItem.duration_s)
|
||||
).all()
|
||||
}
|
||||
dirty = db.execute(
|
||||
select(PlexState).where(
|
||||
PlexState.user_id == link.user_id,
|
||||
PlexState.synced_to_plex.is_(False),
|
||||
PlexState.status != "hidden",
|
||||
dirty = (
|
||||
db.execute(
|
||||
select(PlexState).where(
|
||||
PlexState.user_id == link.user_id,
|
||||
PlexState.synced_to_plex.is_(False),
|
||||
PlexState.status != "hidden",
|
||||
)
|
||||
)
|
||||
).scalars().all()
|
||||
.scalars()
|
||||
.all()
|
||||
)
|
||||
n = 0
|
||||
for st in dirty:
|
||||
info = info_by_id.get(st.item_id)
|
||||
@@ -440,7 +457,9 @@ def run_plex_watch_sync(db: Session) -> dict:
|
||||
iid = rk_to_id.get(str(row.get("ratingKey") or ""))
|
||||
if iid is None:
|
||||
continue
|
||||
ch = _pull_apply(db, link.user_id, iid, "watched", 0, _epoch(row.get("viewedAt")))
|
||||
ch = _pull_apply(
|
||||
db, link.user_id, iid, "watched", 0, _epoch(row.get("viewedAt"))
|
||||
)
|
||||
if ch:
|
||||
total[ch] += 1
|
||||
|
||||
@@ -451,7 +470,9 @@ def run_plex_watch_sync(db: Session) -> dict:
|
||||
off = int(row.get("viewOffset") or 0) // 1000
|
||||
if off < _PROGRESS_MIN_S:
|
||||
continue
|
||||
ch = _pull_apply(db, link.user_id, iid, "new", off, _epoch(row.get("lastViewedAt")))
|
||||
ch = _pull_apply(
|
||||
db, link.user_id, iid, "new", off, _epoch(row.get("lastViewedAt"))
|
||||
)
|
||||
if ch:
|
||||
total[ch] += 1
|
||||
|
||||
@@ -495,9 +516,11 @@ def run_plex_watch_reconcile(db: Session) -> dict:
|
||||
|
||||
# Siftlode rows Plex no longer has a record for: clear the ones that were mirrored
|
||||
# (Plex un-watched them); leave hidden + dirty (dirty gets re-pushed just below).
|
||||
for st in db.execute(
|
||||
select(PlexState).where(PlexState.user_id == link.user_id)
|
||||
).scalars().all():
|
||||
for st in (
|
||||
db.execute(select(PlexState).where(PlexState.user_id == link.user_id))
|
||||
.scalars()
|
||||
.all()
|
||||
):
|
||||
if st.item_id in plex_states or st.status == "hidden":
|
||||
continue
|
||||
if st.synced_to_plex:
|
||||
|
||||
Reference in New Issue
Block a user