summaryrefslogtreecommitdiff
path: root/kvmd
diff options
context:
space:
mode:
authorMaxim Devaev <[email protected]>2022-07-19 16:00:01 +0300
committerMaxim Devaev <[email protected]>2022-07-19 16:00:01 +0300
commit54cb5e1fed2ad2e0f291adcc6738659fd15dc452 (patch)
treedd6e6fa0fda253765bd0be1bdbedbd39becdd817 /kvmd
parent01ac7522dbeb542db672f087a4a35ac463e8f0ee (diff)
verbose rfb encdings report
Diffstat (limited to 'kvmd')
-rw-r--r--kvmd/apps/vnc/rfb/__init__.py7
-rw-r--r--kvmd/apps/vnc/rfb/encodings.py50
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)]