60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
"""File storage utilities for persistence, retrieval, and checksum calculation."""
|
|
|
|
import hashlib
|
|
import uuid
|
|
from datetime import UTC, datetime
|
|
from pathlib import Path
|
|
|
|
from app.core.config import get_settings
|
|
|
|
|
|
settings = get_settings()
|
|
|
|
|
|
def ensure_storage() -> None:
|
|
"""Ensures required storage directories exist at service startup."""
|
|
|
|
for relative in ["originals", "derived/previews", "tmp"]:
|
|
(settings.storage_root / relative).mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
def compute_sha256(data: bytes) -> str:
|
|
"""Computes a SHA-256 hex digest for raw file bytes."""
|
|
|
|
return hashlib.sha256(data).hexdigest()
|
|
|
|
|
|
def store_bytes(filename: str, data: bytes) -> str:
|
|
"""Stores file content under a unique path and returns its storage-relative location."""
|
|
|
|
stamp = datetime.now(UTC).strftime("%Y/%m/%d")
|
|
safe_ext = Path(filename).suffix.lower()
|
|
target_dir = settings.storage_root / "originals" / stamp
|
|
target_dir.mkdir(parents=True, exist_ok=True)
|
|
target_name = f"{uuid.uuid4()}{safe_ext}"
|
|
target_path = target_dir / target_name
|
|
target_path.write_bytes(data)
|
|
return str(target_path.relative_to(settings.storage_root))
|
|
|
|
|
|
def read_bytes(relative_path: str) -> bytes:
|
|
"""Reads and returns bytes from a storage-relative path."""
|
|
|
|
return (settings.storage_root / relative_path).read_bytes()
|
|
|
|
|
|
def absolute_path(relative_path: str) -> Path:
|
|
"""Returns the absolute filesystem path for a storage-relative location."""
|
|
|
|
return settings.storage_root / relative_path
|
|
|
|
|
|
def write_preview(document_id: str, data: bytes, suffix: str = ".jpg") -> str:
|
|
"""Writes preview bytes and returns the preview path relative to storage root."""
|
|
|
|
target_dir = settings.storage_root / "derived" / "previews"
|
|
target_dir.mkdir(parents=True, exist_ok=True)
|
|
target_path = target_dir / f"{document_id}{suffix}"
|
|
target_path.write_bytes(data)
|
|
return str(target_path.relative_to(settings.storage_root))
|