feat: add gallery page with image and video details, including upload and generation status

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-04-29 16:13:09 +02:00
parent d4421616e5
commit 951a653dc9
8 changed files with 477 additions and 3 deletions
+79
View File
@@ -186,6 +186,56 @@ async def list_generated_images(
]
@router.get("/images/{image_id}")
async def get_generated_image(
image_id: str,
current_user: dict = Depends(get_current_user),
) -> dict:
"""Return details for a single generated image."""
user_id = current_user.get("id") or current_user.get("sub")
conn = get_conn()
row = conn.execute(
"""SELECT id, model_id, prompt, image_data, created_at
FROM generated_images
WHERE id = ? AND user_id = ?""",
[image_id, user_id],
).fetchone()
if not row:
raise HTTPException(status_code=404, detail="Image not found")
return {
"id": str(row[0]),
"model_id": row[1],
"prompt": row[2],
"image_data": row[3],
"created_at": row[4].isoformat() if row[4] else None,
}
@router.get("/images/{image_id}")
async def get_generated_image(
image_id: str,
current_user: dict = Depends(get_current_user),
) -> dict:
"""Return details for a single generated image."""
user_id = current_user.get("id") or current_user.get("sub")
conn = get_conn()
row = conn.execute(
"""SELECT id, model_id, prompt, image_data, created_at
FROM generated_images
WHERE id = ? AND user_id = ?""",
[image_id, user_id],
).fetchone()
if not row:
raise HTTPException(status_code=404, detail="Image not found")
return {
"id": str(row[0]),
"model_id": row[1],
"prompt": row[2],
"image_data": row[3],
"created_at": row[4].isoformat() if row[4] else None,
}
@router.post("/video", response_model=VideoResponse)
async def generate_video(
body: VideoRequest,
@@ -358,3 +408,32 @@ async def list_generated_videos(
}
for r in rows
]
@router.get("/videos/{video_id}")
async def get_generated_video(
video_id: str,
current_user: dict = Depends(get_current_user),
) -> dict:
"""Return details for a single video generation job."""
user_id = current_user.get("id") or current_user.get("sub")
conn = get_conn()
row = conn.execute(
"""SELECT id, job_id, model_id, prompt, polling_url, status, video_url, created_at, updated_at
FROM generated_videos
WHERE id = ? AND user_id = ?""",
[video_id, user_id],
).fetchone()
if not row:
raise HTTPException(status_code=404, detail="Video job not found")
return {
"id": str(row[0]),
"job_id": row[1],
"model_id": row[2],
"prompt": row[3],
"polling_url": row[4],
"status": row[5],
"video_url": row[6],
"created_at": row[7].isoformat() if row[7] else None,
"updated_at": row[8].isoformat() if row[8] else None,
}
+36 -3
View File
@@ -93,6 +93,36 @@ async def list_images(
]
@router.get("/{image_id}", status_code=status.HTTP_200_OK)
async def get_image_details(
image_id: str,
current_user: dict = Depends(get_current_user),
) -> dict:
"""Return metadata for a single uploaded image."""
conn = get_conn()
row = conn.execute(
"""
SELECT id, filename, content_type, size_bytes, created_at
FROM uploaded_images
WHERE id = ? AND user_id = ?
""",
[image_id, current_user["id"]],
).fetchone()
if not row:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Image not found"
)
return {
"id": str(row[0]),
"filename": row[1],
"content_type": row[2],
"size_bytes": row[3],
"created_at": row[4].isoformat() if row[4] else None,
}
@router.get("/{image_id}/file", status_code=status.HTTP_200_OK)
async def serve_image(
image_id: str,
@@ -106,12 +136,15 @@ async def serve_image(
).fetchone()
if row is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Image not found.")
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Image not found.")
if str(row[2]) != current_user["id"]:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Access denied.")
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="Access denied.")
file_path: str = row[0]
if not os.path.isfile(file_path):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Image file missing.")
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Image file missing.")
return FileResponse(file_path, media_type=row[1])