fix(signalr): fix SignalRMeta cannot be read

This commit is contained in:
MingxuanGame
2025-08-03 11:01:25 +00:00
parent c9fc07b29e
commit b7bc87b8b6
3 changed files with 20 additions and 16 deletions

View File

@@ -1,7 +1,7 @@
from __future__ import annotations from __future__ import annotations
from enum import IntEnum from enum import IntEnum
from typing import ClassVar, Literal from typing import Annotated, ClassVar, Literal
from app.models.signalr import SignalRMeta, SignalRUnionMessage, UserState from app.models.signalr import SignalRMeta, SignalRUnionMessage, UserState
@@ -100,12 +100,12 @@ UserActivity = (
class UserPresence(BaseModel): class UserPresence(BaseModel):
activity: UserActivity | None = Field( activity: Annotated[
default=None, metadata=SignalRMeta(use_upper_case=True) UserActivity | None, Field(default=None), SignalRMeta(use_upper_case=True)
) ]
status: OnlineStatus | None = Field( status: Annotated[
default=None, metadata=SignalRMeta(use_upper_case=True) OnlineStatus | None, Field(default=None), SignalRMeta(use_upper_case=True)
) ]
@property @property
def pushable(self) -> bool: def pushable(self) -> bool:

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
import datetime import datetime
from enum import IntEnum from enum import IntEnum
from typing import Any from typing import Annotated, Any
from app.models.beatmap import BeatmapRankStatus from app.models.beatmap import BeatmapRankStatus
from app.models.mods import APIMod from app.models.mods import APIMod
@@ -89,9 +89,9 @@ class LegacyReplayFrame(BaseModel):
mouse_y: float | None = None mouse_y: float | None = None
button_state: int button_state: int
header: FrameHeader | None = Field( header: Annotated[
default=None, metadata=[SignalRMeta(member_ignore=True)] FrameHeader | None, Field(default=None), SignalRMeta(member_ignore=True)
) ]
class FrameDataBundle(BaseModel): class FrameDataBundle(BaseModel):

View File

@@ -126,15 +126,19 @@ class MsgpackProtocol:
def process_object(v: Any, typ: type[BaseModel]) -> Any: def process_object(v: Any, typ: type[BaseModel]) -> Any:
if isinstance(v, list): if isinstance(v, list):
d = {} d = {}
for i, f in enumerate(typ.model_fields.items()): i = 0
field, info = f for field, info in typ.model_fields.items():
if info.exclude: metadata = next(
(m for m in info.metadata if isinstance(m, SignalRMeta)), None
)
if metadata and metadata.member_ignore:
continue continue
anno = info.annotation anno = info.annotation
if anno is None: if anno is None:
d[camel_to_snake(field)] = v[i] d[camel_to_snake(field)] = v[i]
continue else:
d[field] = MsgpackProtocol.validate_object(v[i], anno) d[field] = MsgpackProtocol.validate_object(v[i], anno)
i += 1
return d return d
return v return v