diff options
author | Devaev Maxim <[email protected]> | 2020-05-17 15:24:29 +0300 |
---|---|---|
committer | Devaev Maxim <[email protected]> | 2020-05-17 16:09:58 +0300 |
commit | 1fd33bc8ed29c3aaeb6c9971e5879c04113246a3 (patch) | |
tree | db022c9c291fdd2495ddd02aa89b532ce4d011cc /kvmd/apps/vnc | |
parent | 1251b8d705c5a48a78290b2d25cd4de048245035 (diff) |
refactoring
Diffstat (limited to 'kvmd/apps/vnc')
-rw-r--r-- | kvmd/apps/vnc/__init__.py | 12 | ||||
-rw-r--r-- | kvmd/apps/vnc/kvmd.py | 114 | ||||
-rw-r--r-- | kvmd/apps/vnc/server.py | 12 | ||||
-rw-r--r-- | kvmd/apps/vnc/streamer.py | 86 |
4 files changed, 15 insertions, 209 deletions
diff --git a/kvmd/apps/vnc/__init__.py b/kvmd/apps/vnc/__init__.py index 8bd9be63..9bcc9d27 100644 --- a/kvmd/apps/vnc/__init__.py +++ b/kvmd/apps/vnc/__init__.py @@ -23,10 +23,13 @@ from typing import List from typing import Optional +from ...clients.kvmd import KvmdClient +from ...clients.streamer import StreamerClient + +from ... import make_user_agent + from .. import init -from .kvmd import KvmdClient -from .streamer import StreamerClient from .vncauth import VncAuthManager from .server import VncServer from .keysym import build_symmap @@ -53,6 +56,9 @@ def main(argv: Optional[List[str]]=None) -> None: symmap=build_symmap(config.keymap), kvmd=KvmdClient(**config.kvmd._unpack()), - streamer=StreamerClient(**config.streamer._unpack()), + streamer=StreamerClient( + user_agent=make_user_agent("KVMD-VNC"), + **config.streamer._unpack(), + ), vnc_auth_manager=VncAuthManager(**config.auth.vncauth._unpack()), ).run() diff --git a/kvmd/apps/vnc/kvmd.py b/kvmd/apps/vnc/kvmd.py deleted file mode 100644 index ebea5554..00000000 --- a/kvmd/apps/vnc/kvmd.py +++ /dev/null @@ -1,114 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2020 Maxim Devaev <[email protected]> # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <https://www.gnu.org/licenses/>. # -# # -# ========================================================================== # - - -import contextlib - -from typing import Dict -from typing import AsyncGenerator - -import aiohttp - -from ... import __version__ - - -# ===== -class KvmdError(Exception): - def __init__(self, err: Exception): - super().__init__(f"{type(err).__name__} {err}") - - -# ===== -class KvmdClient: - def __init__( - self, - host: str, - port: int, - unix_path: str, - timeout: float, - ) -> None: - - assert port or unix_path - self.__host = host - self.__port = port - self.__unix_path = unix_path - self.__timeout = timeout - - # ===== - - async def authorize(self, user: str, passwd: str) -> bool: - try: - async with self.__make_session(user, passwd) as session: - async with session.get( - url=f"http://{self.__host}:{self.__port}/auth/check", - timeout=self.__timeout, - ) as response: - response.raise_for_status() - if response.status == 200: - return True - raise RuntimeError(f"Invalid OK response: {response.status} {await response.text()}") - except aiohttp.ClientResponseError as err: - if err.status in [401, 403]: - return False - raise KvmdError(err) - except aiohttp.ClientError as err: - raise KvmdError(err) - - @contextlib.asynccontextmanager - async def ws(self, user: str, passwd: str) -> AsyncGenerator[aiohttp.ClientWebSocketResponse, None]: - try: - async with self.__make_session(user, passwd) as session: - async with session.ws_connect( - url=f"http://{self.__host}:{self.__port}/ws", - timeout=self.__timeout, - ) as ws: - yield ws - except aiohttp.ClientError as err: - raise KvmdError(err) - - async def set_streamer_params(self, user: str, passwd: str, quality: int, desired_fps: int) -> None: - try: - async with self.__make_session(user, passwd) as session: - async with session.post( - url=f"http://{self.__host}:{self.__port}/streamer/set_params", - timeout=self.__timeout, - params={ - "quality": quality, - "desired_fps": desired_fps, - }, - ) as response: - response.raise_for_status() - except aiohttp.ClientError as err: - raise KvmdError(err) - - # ===== - - def __make_session(self, user: str, passwd: str) -> aiohttp.ClientSession: - kwargs: Dict = { - "headers": { - "X-KVMD-User": user, - "X-KVMD-Passwd": passwd, - "User-Agent": f"KVMD-VNC/{__version__}", - }, - } - if self.__unix_path: - kwargs["connector"] = aiohttp.UnixConnector(path=self.__unix_path) - return aiohttp.ClientSession(**kwargs) diff --git a/kvmd/apps/vnc/server.py b/kvmd/apps/vnc/server.py index baec8d36..b860b261 100644 --- a/kvmd/apps/vnc/server.py +++ b/kvmd/apps/vnc/server.py @@ -34,6 +34,12 @@ import aiohttp from ...logging import get_logger +from ...clients.kvmd import KvmdError +from ...clients.kvmd import KvmdClient + +from ...clients.streamer import StreamerError +from ...clients.streamer import StreamerClient + from ... import aiotools from .rfb import RfbClient @@ -44,12 +50,6 @@ from .rfb.errors import RfbError from .vncauth import VncAuthKvmdCredentials from .vncauth import VncAuthManager -from .kvmd import KvmdError -from .kvmd import KvmdClient - -from .streamer import StreamerError -from .streamer import StreamerClient - from .render import make_text_jpeg diff --git a/kvmd/apps/vnc/streamer.py b/kvmd/apps/vnc/streamer.py deleted file mode 100644 index 094f5081..00000000 --- a/kvmd/apps/vnc/streamer.py +++ /dev/null @@ -1,86 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2020 Maxim Devaev <[email protected]> # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see <https://www.gnu.org/licenses/>. # -# # -# ========================================================================== # - - -from typing import Tuple -from typing import Dict -from typing import AsyncGenerator - -import aiohttp - -from ... import __version__ - - -# ===== -class StreamerError(Exception): - def __init__(self, err: Exception): - super().__init__(f"{type(err).__name__} {err}") - - -# ===== -class StreamerClient: - def __init__( - self, - host: str, - port: int, - unix_path: str, - timeout: float, - ) -> None: - - assert port or unix_path - self.__host = host - self.__port = port - self.__unix_path = unix_path - self.__timeout = timeout - - async def read(self) -> AsyncGenerator[Tuple[bool, int, int, bytes], None]: - try: - async with self.__make_session() as session: - async with session.get( - url=f"http://{self.__host}:{self.__port}/stream", - params={"extra_headers": "1"}, - headers={"User-Agent": f"KVMD-VNC/{__version__}"}, - ) as response: - response.raise_for_status() - reader = aiohttp.MultipartReader.from_response(response) - while True: - frame = await reader.next() # pylint: disable=not-callable - if not isinstance(frame, aiohttp.BodyPartReader): - raise RuntimeError("Expected body part") - yield ( - (frame.headers["X-UStreamer-Online"] == "true"), - int(frame.headers["X-UStreamer-Width"]), - int(frame.headers["X-UStreamer-Height"]), - bytes(await frame.read()), - ) - except Exception as err: # Тут бывают и ассерты, и KeyError, и прочая херня из-за корявых исключений в MultipartReader - raise StreamerError(err) - - def __make_session(self) -> aiohttp.ClientSession: - kwargs: Dict = { - "timeout": aiohttp.ClientTimeout( - connect=self.__timeout, - sock_read=self.__timeout, - ), - } - if self.__unix_path: - kwargs["connector"] = aiohttp.UnixConnector(path=self.__unix_path) - return aiohttp.ClientSession(**kwargs) |