Fix image generation model and purge logic
- Change NanoBanana Pro model from gemini-3-pro-image-preview to gemini-2.0-flash-exp-image (previous model doesn't exist) - Purge endpoint now deletes generated images from /app_data/images/ when soft-deleted presentations are purged - Add purged_images counter to purge response Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8cbe01dfa6
commit
1280e40eb2
2 changed files with 37 additions and 4 deletions
|
|
@ -12,6 +12,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|||
from models.sql.client import ClientModel
|
||||
from models.sql.master_deck import MasterDeckModel
|
||||
from models.sql.presentation import PresentationModel
|
||||
from models.sql.slide import SlideModel
|
||||
from models.sql.user import UserModel
|
||||
from services import audit_service
|
||||
from services.access_service import get_accessible_client_ids
|
||||
|
|
@ -361,7 +362,7 @@ async def purge_deleted_storage(
|
|||
admin: UserModel = Depends(require_client_admin),
|
||||
session: AsyncSession = Depends(get_async_session),
|
||||
):
|
||||
"""Hard-delete files for soft-deleted presentations."""
|
||||
"""Hard-delete files for soft-deleted presentations (exports + generated images)."""
|
||||
if admin.role != "super_admin":
|
||||
raise HTTPException(status_code=403, detail="Super admin only")
|
||||
|
||||
|
|
@ -376,8 +377,10 @@ async def purge_deleted_storage(
|
|||
purged_files = 0
|
||||
purged_bytes = 0
|
||||
purged_presentations = 0
|
||||
purged_images = 0
|
||||
|
||||
for p in deleted_presentations:
|
||||
# Delete export files (PDF/PPTX)
|
||||
if p.file_paths:
|
||||
for path in p.file_paths:
|
||||
if path and os.path.isfile(path):
|
||||
|
|
@ -389,6 +392,30 @@ async def purge_deleted_storage(
|
|||
except OSError:
|
||||
pass
|
||||
p.file_paths = []
|
||||
|
||||
# Delete generated images from slides
|
||||
slides_stmt = select(SlideModel).where(SlideModel.presentation == p.id)
|
||||
slides_result = await session.execute(slides_stmt)
|
||||
slides = slides_result.scalars().all()
|
||||
|
||||
for slide in slides:
|
||||
if slide.content and isinstance(slide.content, dict):
|
||||
# Extract image path from content.image.__image_url__
|
||||
image_data = slide.content.get("image")
|
||||
if image_data and isinstance(image_data, dict):
|
||||
image_url = image_data.get("__image_url__")
|
||||
if image_url and image_url.startswith("/app_data/images/"):
|
||||
# Convert URL to filesystem path
|
||||
image_path = image_url.lstrip("/")
|
||||
if os.path.isfile(image_path):
|
||||
try:
|
||||
size = os.path.getsize(image_path)
|
||||
os.remove(image_path)
|
||||
purged_images += 1
|
||||
purged_bytes += size
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
purged_presentations += 1
|
||||
|
||||
await session.commit()
|
||||
|
|
@ -397,12 +424,18 @@ async def purge_deleted_storage(
|
|||
user_id=admin.id,
|
||||
action="admin_purge",
|
||||
resource_type="storage",
|
||||
details={"presentations": purged_presentations, "files": purged_files, "bytes": purged_bytes},
|
||||
details={
|
||||
"presentations": purged_presentations,
|
||||
"files": purged_files,
|
||||
"images": purged_images,
|
||||
"bytes": purged_bytes
|
||||
},
|
||||
)
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
"purged_presentations": purged_presentations,
|
||||
"purged_files": purged_files,
|
||||
"purged_images": purged_images,
|
||||
"purged_bytes": purged_bytes,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,9 +201,9 @@ class ImageGenerationService:
|
|||
async def generate_image_nanobanana_pro(
|
||||
self, prompt: str, output_directory: str
|
||||
) -> str:
|
||||
"""Generate image using NanoBanana Pro (gemini-3-pro-image-preview)."""
|
||||
"""Generate image using NanoBanana Pro (gemini-2.0-flash-exp-image)."""
|
||||
return await self._generate_image_google(
|
||||
prompt, output_directory, "gemini-3-pro-image-preview"
|
||||
prompt, output_directory, "gemini-2.0-flash-exp-image"
|
||||
)
|
||||
|
||||
async def get_image_from_pexels(self, prompt: str) -> str:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue