from django.db.models import Q from django.shortcuts import get_object_or_404 from rest_framework import permissions from rest_framework.exceptions import ValidationError from rest_framework.response import Response from rest_framework.throttling import ScopedRateThrottle from rest_framework.views import APIView from .board_services import ( board_payload, create_board, join_board, submit_guess, ) from .engine import calculate from .models import BoardSession class CalculatorView(APIView): permission_classes = [permissions.AllowAny] throttle_classes = [ScopedRateThrottle] throttle_scope = "calculator" def post(self, request): try: payload = calculate(request.data) except ValidationError: raise except (ArithmeticError, NotImplementedError, TypeError, ValueError) as exc: raise ValidationError({"expression": "该计算暂时无法完成,请缩小表达式范围"}) from exc return Response(payload) class BoardCreateView(APIView): def post(self, request): session = create_board( request.user, request.data.get("mode", BoardSession.Mode.COLLABORATE), ) return Response(board_payload(session, request.user), status=201) class BoardJoinView(APIView): def post(self, request): session = join_board(request.user, request.data.get("code")) return Response(board_payload(session, request.user)) class BoardStateView(APIView): def get(self, request, session_id): session = get_object_or_404( BoardSession.objects.select_related("host", "guest").filter( Q(host=request.user) | Q(guest=request.user) ), id=session_id, ) return Response(board_payload(session, request.user)) class BoardGuessView(APIView): def post(self, request, session_id): session, correct = submit_guess( request.user, session_id, request.data.get("guess"), ) payload = board_payload(session, request.user) payload["correct"] = correct payload["message"] = "猜对了,得 1 分" if correct else "还不对,再观察一下画板" return Response(payload)