Spaces:
Sleeping
Sleeping
| """Resolve report section photo paths under ``settings.upload_dir``.""" | |
| from __future__ import annotations | |
| from pathlib import Path | |
| from app.config import settings | |
| _PHOTO_EXTENSIONS = ("jpg", "jpeg", "png", "webp") | |
| def report_photo_relpath( | |
| tenant_id: str, | |
| report_id: str, | |
| section_code: str, | |
| photo_id: str, | |
| ext: str, | |
| ) -> str: | |
| """Relative path stored in ``ReportSectionPhoto.file_path`` (POSIX-style).""" | |
| ext_norm = ext.lower().lstrip(".") | |
| if ext_norm == "jpeg": | |
| ext_norm = "jpg" | |
| return "/".join( | |
| ( | |
| tenant_id, | |
| "report_photos", | |
| str(report_id), | |
| str(section_code), | |
| f"{photo_id}.{ext_norm}", | |
| ) | |
| ) | |
| def resolve_report_photo_path( | |
| file_path: str, | |
| *, | |
| tenant_id: str | None = None, | |
| report_id: str | None = None, | |
| section_code: str | None = None, | |
| photo_id: str | None = None, | |
| ) -> str | None: | |
| """Return an on-disk path for python-docx / FileResponse, or ``None``.""" | |
| raw = (file_path or "").strip() | |
| if not raw: | |
| return None | |
| upload_root = settings.upload_dir.resolve() | |
| candidate = Path(raw) | |
| if candidate.is_file(): | |
| return str(candidate.resolve()) | |
| # Path stored relative to upload_dir (preferred). | |
| rel = Path(raw.replace("\\", "/")) | |
| if not rel.is_absolute(): | |
| under = (upload_root / rel).resolve() | |
| if under.is_file(): | |
| return str(under) | |
| # Absolute path from another host/container — re-root under upload_dir when possible. | |
| parts = tuple(Path(raw).parts) | |
| if "report_photos" in parts: | |
| idx = parts.index("report_photos") | |
| if idx >= 1: | |
| suffix = Path(*parts[idx - 1 :]) | |
| under = (upload_root / suffix).resolve() | |
| if under.is_file(): | |
| return str(under) | |
| if tenant_id and report_id and section_code and photo_id: | |
| section_dir = upload_root / tenant_id / "report_photos" / str(report_id) / str(section_code) | |
| if section_dir.is_dir(): | |
| for ext in _PHOTO_EXTENSIONS: | |
| cand = section_dir / f"{photo_id}.{ext}" | |
| if cand.is_file(): | |
| return str(cand.resolve()) | |
| name = Path(raw).name | |
| if name: | |
| cand = section_dir / name | |
| if cand.is_file(): | |
| return str(cand.resolve()) | |
| return None | |