Spaces:
Sleeping
Sleeping
| from fastapi import APIRouter, Depends, HTTPException, status | |
| from sqlalchemy.orm import Session | |
| from app.core.database import get_db | |
| from app.models.tryon import TryOnTask | |
| from app.models.wardrobe import WardrobeItem | |
| from app.schemas.tryon import TryOnTaskCreate, TryOnTaskResponse | |
| from app.api.deps import get_current_user | |
| from app.models.user import User | |
| from app.workers.tasks import run_tryon | |
| import uuid | |
| router = APIRouter() | |
| def trigger_try_on( | |
| task_in: TryOnTaskCreate, | |
| db: Session = Depends(get_db), | |
| current_user: User = Depends(get_current_user) | |
| ): | |
| # 1. Determine selected garment IDs and validate ownership | |
| garment_ids = [] | |
| if task_in.garment_item_ids: | |
| garment_ids = task_in.garment_item_ids | |
| elif task_in.garment_item_id: | |
| garment_ids = [task_in.garment_item_id] | |
| if not garment_ids: | |
| raise HTTPException( | |
| status_code=status.HTTP_400_BAD_REQUEST, | |
| detail="Vui lòng chọn ít nhất một trang phục để thử đồ." | |
| ) | |
| for gid in garment_ids: | |
| item = db.query(WardrobeItem).filter( | |
| WardrobeItem.id == gid, | |
| WardrobeItem.user_id == current_user.id | |
| ).first() | |
| if not item: | |
| raise HTTPException( | |
| status_code=status.HTTP_404_NOT_FOUND, | |
| detail=f"Không tìm thấy vật phẩm quần áo phù hợp (ID: {gid})." | |
| ) | |
| person_image_url = None | |
| from app.models.body import BodyProfile | |
| if task_in.person_image_base64: | |
| try: | |
| import base64 | |
| header = "base64," | |
| b64_str = task_in.person_image_base64 | |
| if header in b64_str: | |
| b64_str = b64_str.split(header)[1] | |
| img_data = base64.b64decode(b64_str) | |
| from app.services.storage import storage_service | |
| filename = f"{uuid.uuid4()}.jpg" | |
| r2_path = f"users/{current_user.id}/body/{filename}" | |
| person_image_url = storage_service.upload_file(img_data, r2_path, "image/jpeg") | |
| # Save/Update persistently to user's BodyProfile | |
| profile = db.query(BodyProfile).filter(BodyProfile.user_id == current_user.id).first() | |
| if profile: | |
| profile.body_image_url = person_image_url | |
| else: | |
| profile = BodyProfile( | |
| user_id=current_user.id, | |
| gender="male", | |
| height_cm=170.0, | |
| weight_kg=60.0, | |
| body_image_url=person_image_url | |
| ) | |
| db.add(profile) | |
| db.commit() | |
| except Exception as e: | |
| import logging | |
| logging.error(f"Failed to upload try-on person image: {e}") | |
| else: | |
| # Load from saved profile | |
| profile = db.query(BodyProfile).filter(BodyProfile.user_id == current_user.id).first() | |
| if profile and profile.body_image_url: | |
| person_image_url = profile.body_image_url | |
| else: | |
| person_image_url = None | |
| task = TryOnTask( | |
| user_id=current_user.id, | |
| garment_item_id=garment_ids[0] if garment_ids else None, | |
| garment_item_ids=garment_ids, | |
| person_image_url=person_image_url, | |
| status="PENDING" | |
| ) | |
| db.add(task) | |
| db.commit() | |
| db.refresh(task) | |
| # Kích hoạt Celery Task tạo ảnh thử đồ qua image-gen API (bất đồng bộ) | |
| run_tryon.delay(str(task.id)) | |
| return task | |
| def list_try_on_tasks( | |
| limit: int = 50, | |
| db: Session = Depends(get_db), | |
| current_user: User = Depends(get_current_user) | |
| ): | |
| """Lịch sử các lần thử đồ của người dùng (mới nhất trước).""" | |
| tasks = ( | |
| db.query(TryOnTask) | |
| .filter(TryOnTask.user_id == current_user.id) | |
| .order_by(TryOnTask.created_at.desc()) | |
| .limit(limit) | |
| .all() | |
| ) | |
| return tasks | |
| def get_try_on_task( | |
| task_id: uuid.UUID, | |
| db: Session = Depends(get_db), | |
| current_user: User = Depends(get_current_user) | |
| ): | |
| task = db.query(TryOnTask).filter( | |
| TryOnTask.id == task_id, | |
| TryOnTask.user_id == current_user.id | |
| ).first() | |
| if not task: | |
| raise HTTPException( | |
| status_code=status.HTTP_404_NOT_FOUND, | |
| detail="Không tìm thấy tác vụ thử đồ." | |
| ) | |
| return task | |