""" File Utilities -- AI Reel Creator Platform ========================================= Canonical storage paths, file validation, hash computation. """ import os import shutil import hashlib from datetime import datetime from pathlib import Path from typing import Optional def canonical_storage_path(asset_type: str, source: Optional[str] = "upload", original_filename: Optional[str] = None, base_dir: str = "/data/assets") -> str: """Generate a canonical filesystem path for a stored asset. Pattern: {base_dir}/{YYYY-MM-DD}/{asset_type}/{source}/{uuid}.{ext} """ date_dir = datetime.utcnow().strftime("%Y-%m-%d") ext = Path(original_filename).suffix if original_filename else "" uid = hashlib.sha256(os.urandom(32)).hexdigest()[:16] filename = f"{uid}{ext}" full = Path(base_dir) / date_dir / asset_type / (source or "upload") / filename full.parent.mkdir(parents=True, exist_ok=True) return str(full) def compute_file_hash(path: str, algorithm: str = "sha256") -> str: h = hashlib.new(algorithm) with open(path, "rb") as f: for chunk in iter(lambda: f.read(8192), b""): h.update(chunk) return h.hexdigest() def validate_file_type(path: str, allowed_extensions: set) -> bool: ext = Path(path).suffix.lower().lstrip(".") return ext in allowed_extensions def ensure_dir(path: str) -> Path: p = Path(path) p.mkdir(parents=True, exist_ok=True) return p def safe_move(src: str, dst: str) -> str: ensure_dir(Path(dst).parent) shutil.move(src, dst) return dst