File size: 1,627 Bytes
1bd0aa4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
"""
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