refactoring

This commit is contained in:
Devaev Maxim
2020-05-17 15:24:29 +03:00
parent 1251b8d705
commit 1fd33bc8ed
10 changed files with 52 additions and 20 deletions

View File

@@ -36,7 +36,7 @@ from pyghmi.ipmi.private.serversession import ServerSession as IpmiServerSession
from ...logging import get_logger
from ... import __version__
from ... import make_user_agent
from .auth import IpmiAuthManager
@@ -169,7 +169,7 @@ class IpmiServer(BaseIpmiServer): # pylint: disable=too-many-instance-attribute
headers={
"X-KVMD-User": credentials.kvmd_user,
"X-KVMD-Passwd": credentials.kvmd_passwd,
"User-Agent": f"KVMD-IPMI/{__version__}",
"User-Agent": make_user_agent("KVMD-IPMI"),
},
timeout=self.__kvmd_timeout,
) as response:

View File

@@ -38,7 +38,7 @@ from ...logging import get_logger
from ... import aiotools
from ... import gpio
from ... import __version__
from ... import make_user_agent
# =====
@@ -180,7 +180,7 @@ class Streamer: # pylint: disable=too-many-instance-attributes
try:
async with session.get(
url=f"http://{self.__host}:{self.__port}/state",
headers={"User-Agent": f"KVMD/{__version__}"},
headers={"User-Agent": make_user_agent("KVMD")},
timeout=self.__timeout,
) as response:
response.raise_for_status()

View File

@@ -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()

View File

@@ -1,114 +0,0 @@
# ========================================================================== #
# #
# KVMD - The main Pi-KVM daemon. #
# #
# Copyright (C) 2020 Maxim Devaev <mdevaev@gmail.com> #
# #
# 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)

View File

@@ -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

View File

@@ -1,86 +0,0 @@
# ========================================================================== #
# #
# KVMD - The main Pi-KVM daemon. #
# #
# Copyright (C) 2020 Maxim Devaev <mdevaev@gmail.com> #
# #
# 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)