diff options
Diffstat (limited to 'kvmd/apps/vnc')
-rw-r--r-- | kvmd/apps/vnc/rfb/__init__.py | 7 | ||||
-rw-r--r-- | kvmd/apps/vnc/rfb/encodings.py | 50 |
2 files changed, 35 insertions, 22 deletions
diff --git a/kvmd/apps/vnc/rfb/__init__.py b/kvmd/apps/vnc/rfb/__init__.py index e7adfbce..0aa13114 100644 --- a/kvmd/apps/vnc/rfb/__init__.py +++ b/kvmd/apps/vnc/rfb/__init__.py @@ -22,7 +22,6 @@ import asyncio import ssl -import dataclasses from typing import Tuple from typing import List @@ -423,9 +422,9 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute raise RfbError(f"Too many encodings: {encodings_count}") self._encodings = RfbClientEncodings(frozenset(await self._read_struct("encodings list", "l" * encodings_count))) - logger.info("[main] %s: Client features (SetEncodings): ...", self._remote) - for (key, value) in dataclasses.asdict(self._encodings).items(): - logger.info("[main] %s: ... %s=%s", self._remote, key, value) + logger.info("[main] %s: Client features (SetEncodings):", self._remote) + for item in self._encodings.get_summary(): + logger.info("[main] %s: ... %s", self._remote, item) self.__check_tight_jpeg() if self._encodings.has_ext_keys: # Preferred method diff --git a/kvmd/apps/vnc/rfb/encodings.py b/kvmd/apps/vnc/rfb/encodings.py index 5a8e1ad9..5ec47635 100644 --- a/kvmd/apps/vnc/rfb/encodings.py +++ b/kvmd/apps/vnc/rfb/encodings.py @@ -22,7 +22,9 @@ import dataclasses +from typing import List from typing import FrozenSet +from typing import Union from typing import Any @@ -42,36 +44,48 @@ class RfbEncodings: H264 = 50 # Open H.264 Encoding +def _feature(default: Any, variants: Union[int, FrozenSet[int]]) -> dataclasses.Field: + return dataclasses.field(default=default, metadata={ + "variants": (frozenset([variants]) if isinstance(variants, int) else variants), + }) + + @dataclasses.dataclass(frozen=True) class RfbClientEncodings: # pylint: disable=too-many-instance-attributes encodings: FrozenSet[int] - has_resize: bool = dataclasses.field(default=False) - has_rename: bool = dataclasses.field(default=False) - has_leds_state: bool = dataclasses.field(default=False) - has_ext_keys: bool = dataclasses.field(default=False) - - has_tight: bool = dataclasses.field(default=False) - tight_jpeg_quality: int = dataclasses.field(default=0) + has_resize: bool = _feature(False, RfbEncodings.RESIZE) + has_rename: bool = _feature(False, RfbEncodings.RENAME) + has_leds_state: bool = _feature(False, RfbEncodings.LEDS_STATE) + has_ext_keys: bool = _feature(False, RfbEncodings.EXT_KEYS) - has_h264: bool = dataclasses.field(default=False) + has_tight: bool = _feature(False, RfbEncodings.TIGHT) + tight_jpeg_quality: int = _feature(0, frozenset(RfbEncodings.TIGHT_JPEG_QUALITIES)) - def __post_init__(self) -> None: - self.__set("has_resize", (RfbEncodings.RESIZE in self.encodings)) - self.__set("has_rename", (RfbEncodings.RENAME in self.encodings)) - self.__set("has_leds_state", (RfbEncodings.LEDS_STATE in self.encodings)) - self.__set("has_ext_keys", (RfbEncodings.EXT_KEYS in self.encodings)) + has_h264: bool = _feature(False, RfbEncodings.H264) - self.__set("has_tight", (RfbEncodings.TIGHT in self.encodings)) - self.__set("tight_jpeg_quality", self.__get_tight_jpeg_quality()) + def get_summary(self) -> List[str]: + summary: List[str] = [f"encodings -- {sorted(self.encodings)}"] + for field in dataclasses.fields(self): + if field.name != "encodings": + found = ", ".join(map(str, sorted(map(int, self.__get_found(field))))) + summary.append(f"{field.name} [{found}] -- {getattr(self, field.name)}") + return summary - self.__set("has_h264", (RfbEncodings.H264 in self.encodings)) + def __post_init__(self) -> None: + for field in dataclasses.fields(self): + if field.name != "encodings": + self.__set_value(field.name, bool(self.__get_found(field))) + self.__set_value("tight_jpeg_quality", self.__get_tight_jpeg_quality()) - def __set(self, key: str, value: Any) -> None: + def __set_value(self, key: str, value: Any) -> None: object.__setattr__(self, key, value) + def __get_found(self, field: dataclasses.Field) -> None: + return self.encodings.intersection(field.metadata["variants"]) + def __get_tight_jpeg_quality(self) -> int: - if RfbEncodings.TIGHT in self.encodings: + if self.has_tight: qualities = self.encodings.intersection(RfbEncodings.TIGHT_JPEG_QUALITIES) if qualities: return RfbEncodings.TIGHT_JPEG_QUALITIES[max(qualities)] |