- people_enrich: a failed TMDB lookup or a dead headshot is skipped, not the end of the run (a dead file is marked and left for a week; three failures in a row end it); portraits wait for the Plex module switch; a no-Plex original keeps its own cache key, so the resize still replaces it; the job entry lives in the plex domain (run_people_enrich) - person-image takes only a headshot-shaped CDN url (no query variants of one file) - every synced row gets Hungarian genres, and a HU genre filter matches the word as picked too; migration 0094 fills the rows no overlay reached - a job run's audit row carries its result as data; audit_clear / demo_reset store their counts - one credit-column list for the prune and the enrichment order; _overlay_pass typed - tests: batch skip + stop, HU bio stored, dead headshots, module switch, the person-image route, the job body, genre filter + facet write + twin fallback, tagline/summary fallbacks, audit data, the reader's alphabet at every remaining collated() call site
46 lines
1.5 KiB
Python
46 lines
1.5 KiB
Python
"""Hungarian genres on every Plex row, not only on overlaid ones (E30 review)
|
|
|
|
Revision ID: 0094_plex_genres_hu_everywhere
|
|
Revises: 0093_plex_person_known_for_votes
|
|
Create Date: 2026-09-30
|
|
|
|
The HU genre facets and filter read `genres_hu`, which only the overlay pass wrote — so a library with
|
|
no HU twin, or a guid-less row, offered English genres a Hungarian filter could never match. The sync
|
|
now writes `genres_hu` for every row (plex/sync.py `_apply_facet_fields`); this fills the rows it has
|
|
not reached yet, from their own English list through the same map.
|
|
"""
|
|
|
|
import json
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
from app.plex.genres import hu_genres
|
|
|
|
revision: str = "0094_plex_genres_hu_everywhere"
|
|
down_revision: str | None = "0093_plex_person_known_for_votes"
|
|
branch_labels: str | None = None
|
|
depends_on: str | None = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
conn = op.get_bind()
|
|
for table in ("plex_items", "plex_shows"):
|
|
rows = conn.execute(
|
|
sa.text(
|
|
f"SELECT id, genres FROM {table} "
|
|
"WHERE genres_hu IS NULL AND jsonb_typeof(genres) = 'array'"
|
|
)
|
|
).fetchall()
|
|
updates = [
|
|
{"id": rid, "g": json.dumps(hu)} for rid, genres in rows if (hu := hu_genres(genres))
|
|
]
|
|
if updates:
|
|
conn.execute(
|
|
sa.text(f"UPDATE {table} SET genres_hu = CAST(:g AS jsonb) WHERE id = :id"), updates
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
pass # derived from `genres`; the sync writes the same values again
|