fix(maintenance): drop dead status=="saved" scan
Watch later became a built-in playlist, so "saved" is no longer a VideoState status — the scan matched nothing and under-counted users impacted by a video removal. The playlist loop already covers Watch later, so impact is now correct. Route the local _now through the shared utils.now_utc.
This commit is contained in:
parent
7a97fef33c
commit
8ef748c7b8
1 changed files with 7 additions and 15 deletions
|
|
@ -20,18 +20,19 @@ Quota: phase 1 costs ~(flagged / 50) units, phase 2 ~(batch / 50). Both respect
|
||||||
backfill reserve as the other jobs so interactive syncs never starve.
|
backfill reserve as the other jobs so interactive syncs never starve.
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import timedelta
|
||||||
|
|
||||||
from sqlalchemy import or_, select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app import progress, quota, sysconfig
|
from app import progress, quota, sysconfig
|
||||||
from app.config import settings
|
from app.config import settings
|
||||||
from app.models import Playlist, PlaylistItem, Video, VideoState
|
from app.models import Playlist, PlaylistItem, Video
|
||||||
from app.notifications import create_notification
|
from app.notifications import create_notification
|
||||||
from app.state import get_maintenance_batch
|
from app.state import get_maintenance_batch
|
||||||
from app.sync.runner import get_service_user
|
from app.sync.runner import get_service_user
|
||||||
from app.sync.videos import apply_video_details, parse_dt
|
from app.sync.videos import apply_video_details, parse_dt
|
||||||
|
from app.utils import now_utc as _now
|
||||||
from app.youtube.client import YouTubeClient
|
from app.youtube.client import YouTubeClient
|
||||||
|
|
||||||
log = logging.getLogger("siftlode.maintenance")
|
log = logging.getLogger("siftlode.maintenance")
|
||||||
|
|
@ -45,10 +46,6 @@ GRACE_DAYS_BY_REASON = {
|
||||||
DEFAULT_GRACE_DAYS = settings.maintenance_grace_days
|
DEFAULT_GRACE_DAYS = settings.maintenance_grace_days
|
||||||
|
|
||||||
|
|
||||||
def _now() -> datetime:
|
|
||||||
return datetime.now(timezone.utc)
|
|
||||||
|
|
||||||
|
|
||||||
def _grace_days(reason: str | None) -> int:
|
def _grace_days(reason: str | None) -> int:
|
||||||
return GRACE_DAYS_BY_REASON.get(reason or "", DEFAULT_GRACE_DAYS)
|
return GRACE_DAYS_BY_REASON.get(reason or "", DEFAULT_GRACE_DAYS)
|
||||||
|
|
||||||
|
|
@ -91,14 +88,9 @@ def _collect_user_impact(db: Session, videos: list[Video]) -> dict[int, list[dic
|
||||||
impact: dict[int, set[str]] = {}
|
impact: dict[int, set[str]] = {}
|
||||||
if not ids:
|
if not ids:
|
||||||
return {}
|
return {}
|
||||||
# Saved (VideoState.status == "saved").
|
# Anyone who had it in a playlist — which now also covers "saved": Watch later became a
|
||||||
for user_id, video_id in db.execute(
|
# built-in playlist, so "saved" is no longer a VideoState status (the old status=="saved"
|
||||||
select(VideoState.user_id, VideoState.video_id).where(
|
# scan matched nothing and under-counted impacted users).
|
||||||
VideoState.video_id.in_(ids), VideoState.status == "saved"
|
|
||||||
)
|
|
||||||
):
|
|
||||||
impact.setdefault(user_id, set()).add(video_id)
|
|
||||||
# In any of the user's playlists (covers watch-later, which is a playlist).
|
|
||||||
for user_id, video_id in db.execute(
|
for user_id, video_id in db.execute(
|
||||||
select(Playlist.user_id, PlaylistItem.video_id)
|
select(Playlist.user_id, PlaylistItem.video_id)
|
||||||
.join(PlaylistItem, PlaylistItem.playlist_id == Playlist.id)
|
.join(PlaylistItem, PlaylistItem.playlist_id == Playlist.id)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue