feat(submissions): auto-replace player in scopes, cancel sync + info about the sync

This commit is contained in:
2026-10-16 01:49:53 +02:00
parent de5ee8ae7a
commit 13c09adff3
18 changed files with 1051 additions and 137 deletions
+56 -8
View File
@@ -14,8 +14,16 @@ from .schemas import (
ScopeOut,
SyncScopesIn,
SyncScopesOut,
SyncScopesStatusOut,
SyncScopesStopOut,
)
from .tasks import (
get_scope_sync_state,
process_submission_file,
process_crop,
schedule_scope_sync,
stop_scope_sync,
)
from .tasks import process_submission_file, process_crop, schedule_scope_sync
router = Router()
@@ -73,6 +81,37 @@ def list_available_scopes(request: HttpRequest, event_path: str, game_path: str)
return list(scopes.order_by("name"))
def _syncable_event_game(request: HttpRequest, game_path: str) -> EventGame:
return get_object_or_404(
EventGame,
event=request.event,
game__path=game_path,
game__custom_path=False,
enabled=True,
)
@router.get(
f"{PREFIX}/{{game_path}}/sync-scopes",
response={200: SyncScopesStatusOut, 403: dict},
)
def sync_scopes_status(request: HttpRequest, event_path: str, game_path: str):
"""State of the AAndT scope sync loop of a (non custom path) game,
superusers only."""
if not request.user.is_superuser:
return 403, {"detail": "Superuser required"}
event_game = _syncable_event_game(request, game_path)
scopes = Scope.objects.filter(event_game=event_game)
return {
**vars(get_scope_sync_state(event_game.id)),
"has_token": bool(event_game.apibot_token),
"scope_count": scopes.count(),
"active_scope_count": scopes.filter(is_active=True).count(),
}
@router.post(
f"{PREFIX}/{{game_path}}/sync-scopes",
response={200: SyncScopesOut, 400: dict, 403: dict},
@@ -86,13 +125,7 @@ def sync_scopes(
if not request.user.is_superuser:
return 403, {"detail": "Superuser required"}
event_game = get_object_or_404(
EventGame,
event=request.event,
game__path=game_path,
game__custom_path=False,
enabled=True,
)
event_game = _syncable_event_game(request, game_path)
token = (payload.apibot_token or "").strip()
if token:
@@ -108,6 +141,21 @@ def sync_scopes(
return {"started": schedule_scope_sync(event_game.id)}
@router.delete(
f"{PREFIX}/{{game_path}}/sync-scopes",
response={200: SyncScopesStopOut, 403: dict},
)
def stop_sync_scopes(request: HttpRequest, event_path: str, game_path: str):
"""Stop the AAndT scope sync loop of a (non custom path) game, superusers
only. Cancels its scheduled job, scopes are left as they are."""
if not request.user.is_superuser:
return 403, {"detail": "Superuser required"}
event_game = _syncable_event_game(request, game_path)
return {"stopped": stop_scope_sync(event_game.id)}
@router.post(f"{PREFIX}/submission/create", response={200: SubmissionOut, 403: dict})
def create_submission(
request: HttpRequest,