init
This commit is contained in:
108
windows_py_client/synctv_client/models.py
Normal file
108
windows_py_client/synctv_client/models.py
Normal file
@@ -0,0 +1,108 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any
|
||||
|
||||
|
||||
@dataclass
|
||||
class PlaybackInfo:
|
||||
state: str = "idle"
|
||||
position_ms: int = 0
|
||||
server_updated_at: int = 0
|
||||
target_latency_ms: int | None = None
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: dict[str, Any] | None) -> "PlaybackInfo":
|
||||
data = data or {}
|
||||
return PlaybackInfo(
|
||||
state=data.get("state", "idle"),
|
||||
position_ms=int(data.get("positionMs", 0)),
|
||||
server_updated_at=int(data.get("serverUpdatedAt", 0)),
|
||||
target_latency_ms=data.get("targetLatencyMs"),
|
||||
)
|
||||
|
||||
def to_json(self) -> dict[str, Any]:
|
||||
payload: dict[str, Any] = {
|
||||
"state": self.state,
|
||||
"positionMs": self.position_ms,
|
||||
"serverUpdatedAt": self.server_updated_at,
|
||||
}
|
||||
if self.target_latency_ms is not None:
|
||||
payload["targetLatencyMs"] = self.target_latency_ms
|
||||
return payload
|
||||
|
||||
|
||||
@dataclass
|
||||
class SourceInfo:
|
||||
type: str = "url"
|
||||
mode: str = "direct"
|
||||
url: str = ""
|
||||
is_live: bool = False
|
||||
headers: dict[str, str] = field(default_factory=dict)
|
||||
username: str = ""
|
||||
password: str = ""
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: dict[str, Any] | None) -> "SourceInfo | None":
|
||||
if not data:
|
||||
return None
|
||||
return SourceInfo(
|
||||
type=data.get("type", "url"),
|
||||
mode=data.get("mode", "direct"),
|
||||
url=data.get("url", ""),
|
||||
is_live=bool(data.get("isLive", False)),
|
||||
headers={str(k): str(v) for k, v in (data.get("headers") or {}).items()},
|
||||
username=data.get("username") or "",
|
||||
password=data.get("password") or "",
|
||||
)
|
||||
|
||||
def to_json(self) -> dict[str, Any]:
|
||||
payload: dict[str, Any] = {
|
||||
"type": self.type,
|
||||
"mode": self.mode,
|
||||
"url": self.url,
|
||||
"isLive": self.is_live,
|
||||
}
|
||||
if self.headers:
|
||||
payload["headers"] = self.headers
|
||||
if self.username:
|
||||
payload["username"] = self.username
|
||||
if self.password:
|
||||
payload["password"] = self.password
|
||||
return payload
|
||||
|
||||
|
||||
@dataclass
|
||||
class RoomInfo:
|
||||
code: str
|
||||
owner_device_id: str = ""
|
||||
online_count: int = 0
|
||||
source: SourceInfo | None = None
|
||||
playback: PlaybackInfo = field(default_factory=PlaybackInfo)
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: dict[str, Any]) -> "RoomInfo":
|
||||
return RoomInfo(
|
||||
code=data["code"],
|
||||
owner_device_id=data.get("ownerDeviceId") or "",
|
||||
online_count=int(data.get("onlineCount", 0)),
|
||||
source=SourceInfo.from_json(data.get("source")),
|
||||
playback=PlaybackInfo.from_json(data.get("playback")),
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class RoomSnapshot:
|
||||
room: RoomInfo
|
||||
is_owner: bool
|
||||
device_id: str
|
||||
server_now: int
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: dict[str, Any]) -> "RoomSnapshot":
|
||||
return RoomSnapshot(
|
||||
room=RoomInfo.from_json(data["room"]),
|
||||
is_owner=bool(data.get("isOwner", False)),
|
||||
device_id=data.get("deviceId", ""),
|
||||
server_now=int(data.get("serverNow", 0)),
|
||||
)
|
||||
Reference in New Issue
Block a user