from dataclasses import asdict, dataclass @dataclass class DeviceProfile: brand: str model: str os_version: str device_type: str physical: bool device_id: str fingerprint: str app_version: str app_build: str language: str @classmethod def builtin(cls) -> "DeviceProfile": return cls( brand="Redmi", model="23113RKC6C", os_version="12", device_type="phone", physical=True, device_id="rd_c9f0fa17a39f96aa", fingerprint="0a4e4b212cbb0a2434cf804c8e30ab58", app_version="1.1.81", app_build="139", language="en-US", ) @classmethod def merge(cls, raw: dict | None) -> "DeviceProfile": profile = cls.builtin() values = asdict(profile) for key, value in (raw or {}).items(): if key not in values or value is None: continue if isinstance(value, str): value = value.strip() if not value: continue if key == "physical" and isinstance(value, str): value = value.lower() in ("1", "true", "yes") values[key] = value values["physical"] = bool(values["physical"]) return cls(**values) def as_dict(self) -> dict: return asdict(self) def headers(self) -> dict[str, str]: physical = "true" if self.physical else "false" return { "Content-Type": "application/json", "Accept": "application/json", "User-Agent": ( f"RaptDrama/{self.app_version} " f"(Android {self.os_version}; {self.model}; {self.brand})" ), "x-device-fingerprint": self.fingerprint, "x-os-version": str(self.os_version), "x-device-physical": physical, "x-device-model": self.model, "Accept-Encoding": "gzip", "accept-language": self.language, "accept-language-custom": self.language, "http_accept_language_custom": self.language.lower(), "x-os-name": "Android", "x-device-brand": self.brand, "x-device-id": self.device_id, "x-app-build": str(self.app_build), "x-device-type": self.device_type, "x-app-version": self.app_version, }