Refactor image processing and add image file serving functionality

- Updated image directory handling to prioritize mounted volume for persistence.
- Enhanced logging for directory write tests and fallback mechanisms.
- Introduced a new endpoint to serve image files directly from local paths.
- Added error handling for file serving, including checks for file existence and readability.
- Updated the frontend to include a new ContentView component and corresponding route.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-12 01:24:44 +00:00
parent 18505de848
commit 645c6f3f9e
8 changed files with 594 additions and 20 deletions

View File

@@ -536,9 +536,10 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None
from django.conf import settings
from pathlib import Path
# Create /data/app/images directory if it doesn't exist
# Try absolute path first, fallback to project-relative if needed
images_dir = '/data/app/images'
# Create images directory if it doesn't exist
# Use /data/app/igny8/images (mounted volume) for persistence
# Fallback to /data/app/images if mounted path not available
images_dir = '/data/app/igny8/images' # Use mounted volume path
write_test_passed = False
try:
@@ -549,16 +550,13 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None
f.write('test')
os.remove(test_file)
write_test_passed = True
logger.info(f"[process_image_generation_queue] Image {image_id} - Directory writable: {images_dir}")
logger.info(f"[process_image_generation_queue] Image {image_id} - Directory writable (mounted volume): {images_dir}")
except Exception as write_test_error:
logger.warning(f"[process_image_generation_queue] Image {image_id} - Directory not writable: {images_dir}, error: {write_test_error}")
# Fallback to project-relative path
from django.conf import settings
base_dir = Path(settings.BASE_DIR) if hasattr(settings, 'BASE_DIR') else Path(__file__).resolve().parent.parent.parent
images_dir = str(base_dir / 'data' / 'app' / 'images')
logger.warning(f"[process_image_generation_queue] Image {image_id} - Mounted directory not writable: {images_dir}, error: {write_test_error}")
# Fallback to /data/app/images
images_dir = '/data/app/images'
try:
os.makedirs(images_dir, exist_ok=True)
# Test fallback directory write access
test_file = os.path.join(images_dir, '.write_test')
with open(test_file, 'w') as f:
f.write('test')
@@ -566,8 +564,22 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None
write_test_passed = True
logger.info(f"[process_image_generation_queue] Image {image_id} - Using fallback directory (writable): {images_dir}")
except Exception as fallback_error:
logger.error(f"[process_image_generation_queue] Image {image_id} - Fallback directory also not writable: {images_dir}, error: {fallback_error}")
raise Exception(f"Neither /data/app/images nor {images_dir} is writable. Last error: {fallback_error}")
logger.warning(f"[process_image_generation_queue] Image {image_id} - Fallback directory also not writable: {images_dir}, error: {fallback_error}")
# Final fallback to project-relative path
from django.conf import settings
base_dir = Path(settings.BASE_DIR) if hasattr(settings, 'BASE_DIR') else Path(__file__).resolve().parent.parent.parent
images_dir = str(base_dir / 'data' / 'app' / 'images')
try:
os.makedirs(images_dir, exist_ok=True)
test_file = os.path.join(images_dir, '.write_test')
with open(test_file, 'w') as f:
f.write('test')
os.remove(test_file)
write_test_passed = True
logger.info(f"[process_image_generation_queue] Image {image_id} - Using project-relative directory (writable): {images_dir}")
except Exception as final_error:
logger.error(f"[process_image_generation_queue] Image {image_id} - All directories not writable. Last error: {final_error}")
raise Exception(f"None of the image directories are writable. Last error: {final_error}")
if not write_test_passed:
raise Exception(f"Failed to find writable directory for saving images")
@@ -620,15 +632,29 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None
logger.info(f"[process_image_generation_queue] Image {image_id} - URL length {len(image_url)} chars (was limited to 200, now supports 500)")
try:
# Save file path if available, otherwise save URL
# Save file path and URL appropriately
if saved_file_path:
# Store relative path or full path in image_url field
image.image_url = saved_file_path
# Store local file path in image_path field
image.image_path = saved_file_path
# Also keep the original URL in image_url field for reference
if image_url:
image.image_url = image_url
logger.info(f"[process_image_generation_queue] Image {image_id} - Saved local path: {saved_file_path}")
else:
# Only URL available, save to image_url
image.image_url = image_url
logger.info(f"[process_image_generation_queue] Image {image_id} - Saved URL only: {image_url[:100] if image_url else 'None'}...")
image.status = 'generated'
logger.info(f"[process_image_generation_queue] Image {image_id} - Attempting to save to database")
image.save(update_fields=['image_url', 'status'])
# Determine which fields to update
update_fields = ['status']
if saved_file_path:
update_fields.append('image_path')
if image_url:
update_fields.append('image_url')
logger.info(f"[process_image_generation_queue] Image {image_id} - Attempting to save to database (fields: {update_fields})")
image.save(update_fields=update_fields)
logger.info(f"[process_image_generation_queue] Image {image_id} - Successfully saved to database")
except Exception as save_error:
error_str = str(save_error)
@@ -659,7 +685,8 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None
'results': results + [{
'image_id': image_id,
'status': 'completed',
'image_url': saved_file_path or image_url,
'image_url': image_url, # Original URL from API
'image_path': saved_file_path, # Local file path if saved
'revised_prompt': result.get('revised_prompt')
}]
}
@@ -668,7 +695,8 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None
results.append({
'image_id': image_id,
'status': 'completed',
'image_url': saved_file_path or image_url,
'image_url': image_url, # Original URL from API
'image_path': saved_file_path, # Local file path if saved
'revised_prompt': result.get('revised_prompt')
})
completed += 1