Files
triviathang/backend/services/image_service.py
2025-12-22 14:47:25 -05:00

79 lines
2.3 KiB
Python

import os
import uuid
from werkzeug.utils import secure_filename
from PIL import Image
def allowed_file(filename, allowed_extensions):
"""Check if file has allowed extension"""
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in allowed_extensions
def save_image(file, upload_folder, allowed_extensions):
"""
Save uploaded image file with validation
Args:
file: FileStorage object from Flask request
upload_folder: Directory to save images
allowed_extensions: Set of allowed file extensions
Returns:
str: Relative path to saved image, or None if validation fails
Raises:
ValueError: If file validation fails
"""
if not file or file.filename == '':
raise ValueError("No file provided")
if not allowed_file(file.filename, allowed_extensions):
raise ValueError(f"File type not allowed. Allowed types: {', '.join(allowed_extensions)}")
# Verify it's actually an image
try:
img = Image.open(file.stream)
img.verify()
file.stream.seek(0) # Reset stream after verification
except Exception as e:
raise ValueError(f"Invalid image file: {str(e)}")
# Generate unique filename
original_filename = secure_filename(file.filename)
extension = original_filename.rsplit('.', 1)[1].lower()
unique_filename = f"{uuid.uuid4()}.{extension}"
# Ensure upload folder exists
os.makedirs(upload_folder, exist_ok=True)
# Save file
filepath = os.path.join(upload_folder, unique_filename)
file.save(filepath)
# Return relative path (for storing in database)
return f"/static/images/{unique_filename}"
def delete_image(image_path, base_folder):
"""
Delete an image file
Args:
image_path: Relative path to image (e.g., /static/images/abc123.jpg)
base_folder: Base folder for the application
"""
if not image_path:
return
# Remove leading slash and construct full path
relative_path = image_path.lstrip('/')
full_path = os.path.join(base_folder, relative_path)
try:
if os.path.exists(full_path):
os.remove(full_path)
except Exception as e:
# Log error but don't fail the operation
print(f"Error deleting image {full_path}: {str(e)}")