feat(phase 4): vision fetches NC previews; stop writing /data/thumbs
Last consumer of the on-disk thumbnail pipeline was the vision
worker reading /data/thumbs/{id}/medium.webp. Now it asks Nextcloud
for a 640px preview (the same edge size the old thumb used) and
decodes the bytes in-memory — no disk dependency.
- nextcloud_dav.get_preview_bytes: sync sibling of get_preview_async,
for the celery vision worker (which is sync).
- vision._load_thumb: tries NC preview first; transitional disk
fallback stays for rows still indexed during the rollout.
- thumbs.WORKER_THUMB_SIZES = set() — generate_thumbnails still runs
the decode + pHash side-effect (perceptual dedup is mule-only and
needs original-resolution pixels) but no longer writes thumbnail
files.
The HTTP thumbnail endpoint's disk fallback path stays in place
unchanged: for NC-404 cases (e.g. iPhone JPEGs mis-extensioned as
.DNG), inline Pillow regeneration still writes a tiny per-photo
file so subsequent requests are fast. That path is rare and the
files are small.
Disk impact: /data/thumbs currently has ~22k medium.webp totaling
~1 GB. They'll stop being read after the worker-vision container
restarts, but no automatic delete — purge with the same find
pattern used for small/large reclaim when ready:
find /data/thumbs -name "medium.webp" -delete
This commit is contained in:
@@ -344,6 +344,35 @@ def fetch_fileid(user: User, abs_path: str) -> Optional[int]:
|
||||
return int(m.group(1)) if m else None
|
||||
|
||||
|
||||
def get_preview_bytes(
|
||||
user: User, fileid: int, x: int, y: int
|
||||
) -> Optional[bytes]:
|
||||
"""Sync sibling of `get_preview_async` for callers in non-async
|
||||
contexts (e.g. the vision celery worker, which is sync).
|
||||
|
||||
Returns the preview body on success, None on 404 / non-success /
|
||||
missing credentials. Caller is expected to feed the bytes into
|
||||
PIL or similar.
|
||||
"""
|
||||
try:
|
||||
nc_user, app_pw = _credentials_for(user)
|
||||
except NextcloudCredentialsMissing:
|
||||
return None
|
||||
url = f"{_base_url()}/index.php/core/preview"
|
||||
params = {
|
||||
"fileId": str(fileid),
|
||||
"x": str(x),
|
||||
"y": str(y),
|
||||
"a": "true",
|
||||
"forceIcon": "false",
|
||||
}
|
||||
with _client((nc_user, app_pw)) as c:
|
||||
resp = c.get(url, params=params)
|
||||
if resp.status_code == 404 or not resp.is_success:
|
||||
return None
|
||||
return resp.content
|
||||
|
||||
|
||||
async def fetch_memories_info_async(
|
||||
user: User, fileid: int
|
||||
) -> Optional[dict]:
|
||||
|
||||
Reference in New Issue
Block a user