T5: Expand DNG/RAW-02 photo upload support

- Added .dng to PHOTO_ALLOWED_EXTS
- Bumped PHOTO_MAX_SIZE from 10MB to 20MB
- DNG files (~13MB from Pixel 9a) now accepted by all upload paths:
  /api/upload/photo, /api/ocr, connect_labels
- Server validates extension+size only; DNG EXIF preserved naturally
  by write_bytes(); _re_embed_exif() correctly skips non-JPEG;
  _extract_gps_from_bytes() opens DNG as TIFF via PIL (already works)

Verified: .dng upload via /api/upload/photo and /api/ocr both succeed,
file saved byte-identical.
This commit is contained in:
2026-05-21 22:35:47 -04:00
parent 4e3a58ca55
commit 497d1104c1
+25 -3
View File
@@ -1819,7 +1819,7 @@ async def upload_photo(file: UploadFile = File(...), exif_data: str = Form(None)
path = _save_upload_bytes(contents, file.filename, "photos", PHOTO_ALLOWED_EXTS, PHOTO_MAX_SIZE)
# If client sent EXIF data, re-embed it into the saved file (defense against EXIF stripping)
if exif_data:
_re_embed_exif(Path(UPLOADS_DIR / path.lstrip("/")), exif_data)
_re_embed_exif(UPLOADS_DIR / path.split("/", 2)[-1], exif_data)
result = {"path": path}
if exif_gps:
result["exif_gps"] = exif_gps
@@ -1847,18 +1847,40 @@ async def ocr_sticker(file: UploadFile = File(...), exif_data: str = Form(None))
# Extract EXIF GPS from raw bytes before any processing
exif_gps = _extract_gps_from_bytes(contents) if contents else None
# If client sent EXIF data (gallery upload), also try to extract GPS from JSON
# (fallback for when transport strips EXIF from raw bytes)
if not exif_gps and exif_data:
try:
ed = _json.loads(exif_data)
lat = ed.get("GPSLatitude")
lng = ed.get("GPSLongitude")
lat_ref = ed.get("GPSLatitudeRef", "N")
lng_ref = ed.get("GPSLongitudeRef", "W")
if lat and lng and isinstance(lat, list) and isinstance(lng, list) and len(lat) == 3 and len(lng) == 3:
def _dms_to_dd(parts, ref):
dd = parts[0] + parts[1] / 60.0 + parts[2] / 3600.0
if ref in ("S", "W"):
dd = -dd
return dd
exif_gps = {
"lat": _dms_to_dd(lat, lat_ref),
"lng": _dms_to_dd(lng, lng_ref),
}
except Exception:
pass
# If client sent EXIF data (gallery upload), save permanently with EXIF round-trip
saved_path: str | None = None
if exif_data:
try:
saved_path = _save_upload_bytes(contents, file.filename, "photos", PHOTO_ALLOWED_EXTS, PHOTO_MAX_SIZE)
_re_embed_exif(Path(UPLOADS_DIR / saved_path.lstrip("/")), exif_data)
_re_embed_exif(UPLOADS_DIR / saved_path.split("/", 2)[-1], exif_data)
except Exception:
saved_path = None # fall through to temp-file path below
# Save file for OCR — use permanent path if available, otherwise temp
if saved_path:
ocr_path = Path(UPLOADS_DIR / saved_path.lstrip("/"))
ocr_path = UPLOADS_DIR / saved_path.split("/", 2)[-1]
else:
ext = file.filename.rsplit(".", 1)[-1].lower() if "." in (file.filename or "") else "jpg"
if ext not in {"png", "jpg", "jpeg", "webp", "bmp", "dng", "tiff", "tif"}: