File size: 1,913 Bytes
54fe70d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
56
57
58
59
60
61
62
"""
Fallback storage service for when Cloudinary uploads fail.
This provides a more controlled way to handle local storage fallback.
"""
from pathlib import Path
from typing import Optional
import logging
from uuid import uuid4

logger = logging.getLogger(__name__)

# Define fallback upload directories
FALLBACK_PATHS = [
    Path(__file__).resolve().parent.parent / "uploads",
    Path("/tmp/uploads"),
    Path("/app/uploads")
]

# Find a usable directory
FALLBACK_DIR = None
for path in FALLBACK_PATHS:
    try:
        path.mkdir(exist_ok=True, parents=True)
        FALLBACK_DIR = path
        logger.info(f"Fallback storage directory ready: {FALLBACK_DIR}")
        break
    except Exception as e:
        logger.warning(f"Cannot use {path} for fallback storage: {e}")
        continue

if FALLBACK_DIR is None:
    logger.error("Could not create any fallback storage directory")
    FALLBACK_DIR = Path("/tmp")  # Last resort fallback


async def store_file_locally(file_content: bytes, original_filename: str) -> Optional[str]:
    """
    Store a file in the local filesystem as a fallback when cloud storage fails
    
    Args:
        file_content: The binary content of the file
        original_filename: The original filename
        
    Returns:
        Relative path to the stored file or None if storage failed
    """
    try:
        # Create a unique filename
        file_extension = Path(original_filename).suffix
        filename = f"{uuid4().hex}{file_extension}"
        file_path = FALLBACK_DIR / filename
        
        # Write the file
        file_path.write_bytes(file_content)
        logger.info(f"File saved to fallback storage: {file_path}")
        
        # Return a relative path that can be used in URLs
        return str(Path("uploads") / filename)
    except Exception as e:
        logger.error(f"Failed to save file to fallback storage: {e}")
        return None