from typing import List, Optional from uuid import UUID from django.http import HttpRequest from ninja import Router, File, Form from ninja.files import UploadedFile from django.shortcuts import get_object_or_404 from games.models import Game from .models import Submission, SubmissionFile, ImageCrop, OCRStatus from .schemas import SubmissionOut, ImageCropIn, ImageCropOut router = Router() @router.post("/submission/create", response=SubmissionOut) def create_submission( request: HttpRequest, game_path: str, files: List[UploadedFile] = File(...), notes: Optional[str] = Form(None), ): game = get_object_or_404(Game, path=game_path, enabled=True) submission = Submission.objects.create( game=game, user=request.user if request.user.is_authenticated else None, notes=notes or None, ) for file in files: SubmissionFile.objects.create( submission=submission, file=file, original_filename=file.name, content_type=file.content_type or "application/octet-stream", ) return submission @router.get("/submission/by/user", response=list[SubmissionOut]) def list_user_submissions(request: HttpRequest, game_path: str): game = get_object_or_404(Game, path=game_path) if not request.user.is_authenticated: return 403, {"detail": "Authentication required"} submissions = Submission.objects.filter(game=game, user=request.user).order_by( "-created_at" ) return submissions @router.get("/submission/by/game", response=list[SubmissionOut]) def list_submissions_by_game(request: HttpRequest, game_path: str): game = get_object_or_404(Game, path=game_path) if not request.user.is_staff: return 403, {"detail": "Admin access required"} return Submission.objects.filter(game=game) @router.get("/submission/{submission_id}", response=SubmissionOut) def get_submission(request: HttpRequest, submission_id: UUID): submission = get_object_or_404(Submission, id=submission_id) if submission.user != request.user and not request.user.is_staff: return 403, {"detail": "Not authorized"} return submission @router.post("/crops/s/{submission_file_id}", response=ImageCropOut) def create_image_crop( request: HttpRequest, submission_file_id: UUID, data: ImageCropIn, ): if not request.user.is_staff: return 403, {"detail": "Admin access required"} submission_file = get_object_or_404(SubmissionFile, id=submission_file_id) crop = ImageCrop.objects.create( submission_file=submission_file, x1=data.x1, y1=data.y1, x2=data.x2, y2=data.y2, label=data.label or "", ocr_status=OCRStatus.TO_PROCESS, ) return crop @router.delete("/crops/{crop_id}", response=dict) def delete_image_crop(request: HttpRequest, crop_id: UUID): if not request.user.is_staff: return 403, {"detail": "Admin access required"} crop = get_object_or_404(ImageCrop, id=crop_id) crop.delete() return {"status": "deleted"}