feat(playlists): YouTube playlist read-sync (backend)
Mirror each user's own YouTube playlists into local source='youtube' playlists, one-way (YT -> local). New client methods iter_my_playlists / iter_my_playlist_video_ids (OAuth, so private playlists work); sync/playlists.py reconciles the mirror (matching YT order) and ingests any playlist videos not in the shared catalog yet (with stub channels). POST /api/playlists/sync-youtube for manual sync (read-scope gated, per-user quota) plus a scheduler job (playlist_sync_minutes, default 6h) that syncs all read-scope users. YouTube's Watch Later / History are not API-accessible and are never synced.
This commit is contained in:
parent
cbf5037374
commit
240b6fb611
5 changed files with 228 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ from app.config import settings
|
|||
from app.db import SessionLocal
|
||||
from app.state import is_sync_paused
|
||||
from app.sync.autotag import run_autotag_all
|
||||
from app.sync.playlists import sync_all_playlists
|
||||
from app.sync.runner import (
|
||||
run_deep_backfill,
|
||||
run_enrich,
|
||||
|
|
@ -79,6 +80,12 @@ def _subscriptions_job() -> None:
|
|||
_job("subscriptions", work)
|
||||
|
||||
|
||||
def _playlist_sync_job() -> None:
|
||||
# Mirror each read-scope user's YouTube playlists; per-user quota attribution is
|
||||
# handled inside sync_all_playlists.
|
||||
_job("playlist_sync", sync_all_playlists)
|
||||
|
||||
|
||||
def start_scheduler() -> None:
|
||||
global _scheduler
|
||||
if not settings.scheduler_enabled or _scheduler is not None:
|
||||
|
|
@ -114,6 +121,12 @@ def start_scheduler() -> None:
|
|||
minutes=settings.subscriptions_resync_minutes,
|
||||
id="subscriptions",
|
||||
)
|
||||
scheduler.add_job(
|
||||
_playlist_sync_job,
|
||||
"interval",
|
||||
minutes=settings.playlist_sync_minutes,
|
||||
id="playlist_sync",
|
||||
)
|
||||
scheduler.start()
|
||||
_scheduler = scheduler
|
||||
logger.info("scheduler started")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue