"""per-download display metadata + auto channel URL Revision ID: 0049_download_display_meta Revises: 0048_plex_playlists Create Date: 2026-07-07 Lets a user override a download's channel and attach extra reference links (beyond the source), and captures yt-dlp's canonical channel/uploader URL so an auto-filled channel becomes clickable. - media_assets.uploader_url: the channel page URL yt-dlp recorded (nullable; filled by the worker on extraction — older rows just stay plain text). - download_jobs.display_uploader / display_uploader_url: per-user channel-name + channel-link overrides (like display_name — display metadata only, never touches the on-disk file). - download_jobs.extra_links: optional list of extra reference URLs shown on the card + watch page. """ from typing import Sequence, Union import sqlalchemy as sa from alembic import op revision: str = "0049_download_display_meta" down_revision: Union[str, None] = "0048_plex_playlists" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.add_column("media_assets", sa.Column("uploader_url", sa.Text(), nullable=True)) op.add_column("download_jobs", sa.Column("display_uploader", sa.String(length=255), nullable=True)) op.add_column("download_jobs", sa.Column("display_uploader_url", sa.Text(), nullable=True)) op.add_column("download_jobs", sa.Column("extra_links", sa.JSON(), nullable=True)) def downgrade() -> None: op.drop_column("download_jobs", "extra_links") op.drop_column("download_jobs", "display_uploader_url") op.drop_column("download_jobs", "display_uploader") op.drop_column("media_assets", "uploader_url")