feat(thumbs): proxy Nextcloud previews instead of duplicating the cache
mule-image was generating and storing three WebP sizes per photo in /data/thumbs while Nextcloud already keeps its own previews for the same source files. Frontend thumbnail requests now proxy NC's /index.php/core/preview keyed by the photo's Nextcloud fileid, authenticated with the owner's encrypted app password. - new column photos.nextcloud_fileid (alembic 0018) plus an index - get_preview_async + fetch_fileid helpers in nextcloud_dav.py - thumb route proxies NC primary, falls back to /data/thumbs (legacy rows / NC unreachable) so a single-file revert restores the old path - extract_metadata caches the fileid on first run for new photos - generate_thumbnails now writes only medium since the vision worker still loads it from disk; small + large drop out of the worker path - backend/scripts/backfill_nextcloud_fileid.py for one-shot population of existing rows: docker exec mulita-backend python -m scripts.backfill_nextcloud_fileid X-Mule-Thumb-Source response header marks each request 'nextcloud' or 'disk' for observability while the rollout settles.
This commit is contained in:
38
backend/alembic/versions/0018_photos_nextcloud_fileid.py
Normal file
38
backend/alembic/versions/0018_photos_nextcloud_fileid.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""Add photos.nextcloud_fileid for NC preview proxying
|
||||
|
||||
Revision ID: 0018_photos_nextcloud_fileid
|
||||
Revises: 0017_photos_list_index
|
||||
Create Date: 2026-05-11
|
||||
|
||||
The thumbnail endpoint will proxy Nextcloud's /index.php/core/preview
|
||||
instead of generating and serving its own WebP cache under /data/thumbs.
|
||||
That requires storing each photo's Nextcloud numeric fileid alongside
|
||||
the row. NULL is allowed because legacy / non-NC photos still exist
|
||||
and the handler keeps the on-disk fallback for them.
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision: str = "0018_photos_nextcloud_fileid"
|
||||
down_revision: Union[str, None] = "0017_photos_list_index"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column(
|
||||
"photos",
|
||||
sa.Column("nextcloud_fileid", sa.Integer(), nullable=True),
|
||||
)
|
||||
op.create_index(
|
||||
"ix_photos_nextcloud_fileid",
|
||||
"photos",
|
||||
["nextcloud_fileid"],
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index("ix_photos_nextcloud_fileid", table_name="photos")
|
||||
op.drop_column("photos", "nextcloud_fileid")
|
||||
Reference in New Issue
Block a user