feat(submissions): auto-replace player in scopes, cancel sync + info about the sync
This commit is contained in:
@@ -12,6 +12,7 @@ from accounts.models import CustomUser
|
||||
from games.models import EventGame
|
||||
|
||||
from ..models import Scope
|
||||
from ..signals import broadcast_scope_updates
|
||||
from .aandt_client import AuthenticatedClient
|
||||
from .aandt_client.api.default import (
|
||||
aandt_api_infos,
|
||||
@@ -120,6 +121,9 @@ def sync_event_game_scopes(event_game: EventGame, /) -> ScopeSyncResult:
|
||||
Scopes whose match is no longer returned by the API (deleted, or from a
|
||||
previous AAndT run reusing the same token) are deactivated.
|
||||
|
||||
Users of scopes that opened/closed or got their players changed are
|
||||
notified over the submissions websocket (see `broadcast_scope_updates`).
|
||||
|
||||
Args:
|
||||
event_game: The EventGame to sync; must have `apibot_token` set.
|
||||
|
||||
@@ -173,10 +177,11 @@ def sync_event_game_scopes(event_game: EventGame, /) -> ScopeSyncResult:
|
||||
result = ScopeSyncResult(status=status.value if status is not None else None)
|
||||
now = timezone.now()
|
||||
synced_match_ids: set[int] = set()
|
||||
changes: dict[Scope, set[int]] = {}
|
||||
|
||||
for match in matches:
|
||||
match_id = _unwrap(match.id)
|
||||
created, warnings = _sync_match(
|
||||
created, warnings, change = _sync_match(
|
||||
event_game, client, match, userids_by_member_id, now
|
||||
)
|
||||
if created is None:
|
||||
@@ -185,14 +190,22 @@ def sync_event_game_scopes(event_game: EventGame, /) -> ScopeSyncResult:
|
||||
result.created += created
|
||||
result.updated += not created
|
||||
result.warnings.extend(warnings)
|
||||
if change is not None:
|
||||
changes[change[0]] = change[1]
|
||||
|
||||
(
|
||||
gone = list(
|
||||
Scope.objects.filter(
|
||||
event_game=event_game, is_active=True, external_id__isnull=False
|
||||
)
|
||||
.exclude(external_id__in=synced_match_ids)
|
||||
.update(is_active=False)
|
||||
.prefetch_related("assigned_users")
|
||||
)
|
||||
Scope.objects.filter(id__in=[scope.id for scope in gone]).update(is_active=False)
|
||||
for scope in gone:
|
||||
scope.is_active = False
|
||||
changes[scope] = {user.id for user in scope.assigned_users.all()}
|
||||
|
||||
broadcast_scope_updates(changes)
|
||||
|
||||
return result
|
||||
|
||||
@@ -203,10 +216,17 @@ def _sync_match(
|
||||
match: Match,
|
||||
userids_by_member_id: dict[int, set[int]],
|
||||
now: datetime,
|
||||
) -> tuple[bool | None, list[str]]:
|
||||
) -> tuple[bool | None, list[str], tuple[Scope, set[int]] | None]:
|
||||
"""Upsert the Scope of one match.
|
||||
|
||||
Returns:
|
||||
Whether the Scope was created (None when the match has no id), the
|
||||
warnings, and when it opened/closed or its players changed, the Scope
|
||||
with every user id that was or now is assigned to it.
|
||||
"""
|
||||
match_id = _unwrap(match.id)
|
||||
if match_id is None:
|
||||
return None, []
|
||||
return None, [], None
|
||||
|
||||
warnings: list[str] = []
|
||||
|
||||
@@ -218,6 +238,12 @@ def _sync_match(
|
||||
|
||||
users = list(CustomUser.objects.filter(cas_user_id__in=userids))
|
||||
|
||||
previous = Scope.objects.filter(event_game=event_game, external_id=match_id).first()
|
||||
was_active = previous.is_active if previous else False
|
||||
previous_user_ids = (
|
||||
set(previous.assigned_users.values_list("id", flat=True)) if previous else set()
|
||||
)
|
||||
|
||||
scope, created = Scope.objects.update_or_create(
|
||||
event_game=event_game,
|
||||
external_id=match_id,
|
||||
@@ -241,7 +267,12 @@ def _sync_match(
|
||||
if scope.is_active:
|
||||
warnings.extend(_push_submission_link(client, match_id, scope))
|
||||
|
||||
return created, warnings
|
||||
user_ids = {user.id for user in users}
|
||||
change = None
|
||||
if scope.is_active != was_active or user_ids != previous_user_ids:
|
||||
change = (scope, user_ids | previous_user_ids)
|
||||
|
||||
return created, warnings, change
|
||||
|
||||
|
||||
def _push_submission_link(
|
||||
|
||||
Reference in New Issue
Block a user