Sanjay / app /services /fallback_storage.py
TheDeepDas's picture
cloudinary upload
54fe70d
"""
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