тест 9
This commit is contained in:
@@ -2001,6 +2001,7 @@ class VmixAgentHub:
|
||||
return None
|
||||
now = _utcnow()
|
||||
with self.database.session() as session:
|
||||
device = None
|
||||
if requested_device_id:
|
||||
requested_device_id = self.normalise_device_id(requested_device_id)
|
||||
device = session.scalar(
|
||||
@@ -2012,9 +2013,12 @@ class VmixAgentHub:
|
||||
)
|
||||
)
|
||||
)
|
||||
else:
|
||||
# Legacy/single-Agent fallback only. If several devices are enabled,
|
||||
# routing must be explicit so a browser cannot control the wrong vMix.
|
||||
|
||||
if device is None:
|
||||
# BUILD111: a browser may keep a stale localStorage device id after
|
||||
# reconnect/update. Do not silently leave the new match unassigned.
|
||||
# Automatic fallback is allowed only when routing is unambiguous:
|
||||
# exactly one live active Agent, or exactly one active Agent total.
|
||||
candidates = list(session.scalars(
|
||||
select(VmixDevice)
|
||||
.where(
|
||||
@@ -2025,7 +2029,12 @@ class VmixAgentHub:
|
||||
)
|
||||
.order_by(desc(VmixDevice.last_seen_at))
|
||||
))
|
||||
device = candidates[0] if len(candidates) == 1 else None
|
||||
live_candidates = [item for item in candidates if item.device_uuid in self._live]
|
||||
if len(live_candidates) == 1:
|
||||
device = live_candidates[0]
|
||||
elif len(candidates) == 1:
|
||||
device = candidates[0]
|
||||
|
||||
if device is None:
|
||||
return None
|
||||
|
||||
@@ -2114,6 +2123,7 @@ class VmixAgentHub:
|
||||
user: HockeyUser,
|
||||
*,
|
||||
session_token: str = "",
|
||||
wait_for_mapping: bool = True,
|
||||
) -> dict[str, Any]:
|
||||
"""Bind this browser/operator session to one enabled Agent."""
|
||||
device_id = self.normalise_device_id(device_id)
|
||||
@@ -2152,6 +2162,7 @@ class VmixAgentHub:
|
||||
tournament_external_id=tournament_id,
|
||||
device_id=device_id,
|
||||
operator_session_token=session_token,
|
||||
wait_for_mapping=bool(wait_for_mapping),
|
||||
)
|
||||
return {
|
||||
"ok": True,
|
||||
@@ -3978,6 +3989,9 @@ class RuntimeVmixSequencePayload(BaseModel):
|
||||
|
||||
class SelectSessionDevicePayload(BaseModel):
|
||||
session_token: str = Field(default="", max_length=128)
|
||||
# Runtime match switching can assign immediately and apply Mapping only
|
||||
# after the new roster has been loaded. Existing Agent UI keeps True.
|
||||
apply_mapping: bool = True
|
||||
|
||||
|
||||
class MappingTestValuePayload(BaseModel):
|
||||
@@ -4243,7 +4257,12 @@ def create_hockey_agent_router(
|
||||
payload: SelectSessionDevicePayload,
|
||||
user: HockeyUser = Depends(auth_dependency),
|
||||
) -> dict[str, Any]:
|
||||
return await hub.select_device_for_session(device_id, user, session_token=payload.session_token)
|
||||
return await hub.select_device_for_session(
|
||||
device_id,
|
||||
user,
|
||||
session_token=payload.session_token,
|
||||
wait_for_mapping=bool(payload.apply_mapping),
|
||||
)
|
||||
|
||||
@router.delete("/api/hockey/agents/devices/{device_id}/pair")
|
||||
async def unpair_device(
|
||||
|
||||
Reference in New Issue
Block a user