Include oversized Synology photos through existing read-only XL previews

This commit is contained in:
Pigway
2026-10-05 08:18:56 +08:00
parent 763d340e4d
commit 9e14adcb1f
9 changed files with 111 additions and 6 deletions
+31 -1
View File
@@ -29,6 +29,7 @@ class PhotoSourceInput(StrictModel):
recursive: bool = True
enabled: bool = True
catalog_limit: int = Field(default=10000, ge=1, le=100000)
synology_previews: bool = False
organized_only: bool = False
folder_caption: bool = False
credential_env: str | None = Field(
@@ -44,6 +45,7 @@ class PhotoItem(StrictModel):
id: str
name: str
caption: dict[str, str] | None = None
provider_preview: bool = False
class PhotoCatalog(StrictModel):
@@ -201,6 +203,22 @@ class PhotoSources:
self.settings.additional_secrets.append(encoded)
return {"Authorization": "Basic " + encoded}
def thumbnail(self, path):
candidate = path.parent / "@eaDir" / path.name / "SYNOPHOTO_THUMB_XL.jpg"
try:
if candidate.is_symlink() or not candidate.resolve().is_relative_to(
path.parent.resolve()
):
return None
if (
candidate.is_file()
and candidate.stat().st_size <= self.settings.max_bytes
):
return candidate
except OSError:
pass
return None
def catalog(self, source_id, refresh=False):
source = self.get(source_id)
if not source.enabled:
@@ -240,13 +258,20 @@ class PhotoSources:
):
continue
try:
if path.stat().st_size > self.settings.max_bytes:
large = path.stat().st_size > self.settings.max_bytes
preview = (
large
and source.synology_previews
and self.thumbnail(path) is not None
)
if large and not preview:
continue
relative = path.relative_to(root).as_posix()
items.append(
{
"id": relative,
"name": name,
"provider_preview": preview,
"caption": caption if source.folder_caption else None,
}
)
@@ -328,6 +353,11 @@ class PhotoSources:
if source.kind == "local":
root = self.settings.photo_root.resolve()
path = root / item["id"]
if item.get("provider_preview"):
preview = self.thumbnail(path)
if preview is None:
raise FlowError(E.NOT_FOUND, "Synology preview is unavailable", 404)
path = preview
if path.is_symlink() or not path.resolve().is_relative_to(
self.local_directory(source.location)
):