Files
polylan-submitter/polylan_submitter/submissions/api.py
T

107 lines
3.0 KiB
Python

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"}