summaryrefslogtreecommitdiff
path: root/kvmd/apps
diff options
context:
space:
mode:
authorDevaev Maxim <[email protected]>2020-06-06 06:29:29 +0300
committerDevaev Maxim <[email protected]>2020-06-06 06:29:29 +0300
commit1d7d4100a57b5d654c1434c91e97187fe25698ef (patch)
treed4709afc3fa03ceac99f1880726ef8639845702d /kvmd/apps
parent4f3ebf0fd1100d2076a626d9ae39f414e9adf90b (diff)
common component interface
Diffstat (limited to 'kvmd/apps')
-rw-r--r--kvmd/apps/kvmd/api/atx.py2
-rw-r--r--kvmd/apps/kvmd/api/wol.py2
-rw-r--r--kvmd/apps/kvmd/server.py88
-rw-r--r--kvmd/apps/kvmd/wol.py2
4 files changed, 49 insertions, 45 deletions
diff --git a/kvmd/apps/kvmd/api/atx.py b/kvmd/apps/kvmd/api/atx.py
index f4317c3c..5f1fb154 100644
--- a/kvmd/apps/kvmd/api/atx.py
+++ b/kvmd/apps/kvmd/api/atx.py
@@ -41,7 +41,7 @@ class AtxApi:
@exposed_http("GET", "/atx")
async def __state_handler(self, _: Request) -> Response:
- return make_json_response(self.__atx.get_state())
+ return make_json_response(await self.__atx.get_state())
@exposed_http("POST", "/atx/power")
async def __power_handler(self, request: Request) -> Response:
diff --git a/kvmd/apps/kvmd/api/wol.py b/kvmd/apps/kvmd/api/wol.py
index 195cf640..b9aa74f6 100644
--- a/kvmd/apps/kvmd/api/wol.py
+++ b/kvmd/apps/kvmd/api/wol.py
@@ -38,7 +38,7 @@ class WolApi:
@exposed_http("GET", "/wol")
async def __state_handler(self, _: Request) -> Response:
- return make_json_response(self.__wol.get_state())
+ return make_json_response(await self.__wol.get_state())
@exposed_http("POST", "/wol/wakeup")
async def __wakeup_handler(self, _: Request) -> Response:
diff --git a/kvmd/apps/kvmd/server.py b/kvmd/apps/kvmd/server.py
index aa4cd83b..da431754 100644
--- a/kvmd/apps/kvmd/server.py
+++ b/kvmd/apps/kvmd/server.py
@@ -23,14 +23,14 @@
import os
import signal
import asyncio
+import dataclasses
import json
-from enum import Enum
-
from typing import List
from typing import Dict
from typing import Set
from typing import Callable
+from typing import Coroutine
from typing import AsyncGenerator
from typing import Optional
from typing import Any
@@ -86,13 +86,23 @@ from .api.streamer import StreamerApi
# =====
-class _Events(Enum):
- INFO_STATE = "info_state"
- WOL_STATE = "wol_state"
- HID_STATE = "hid_state"
- ATX_STATE = "atx_state"
- MSD_STATE = "msd_state"
- STREAMER_STATE = "streamer_state"
[email protected](frozen=True)
+class _Component:
+ name: str
+ event_type: str
+ obj: object
+ get_state: Optional[Callable[[], Coroutine[Any, Any, Dict]]] = None
+ poll_state: Optional[Callable[[], AsyncGenerator[Dict, None]]] = None
+ cleanup: Optional[Callable[[], Coroutine[Any, Any, Dict]]] = None
+
+ def __post_init__(self) -> None:
+ if isinstance(self.obj, BasePlugin):
+ object.__setattr__(self, "name", f"{self.name} ({self.obj.get_plugin_name()})")
+
+ for field in ["get_state", "poll_state", "cleanup"]:
+ object.__setattr__(self, field, getattr(self.obj, field, None))
+ if self.get_state or self.poll_state:
+ assert self.event_type, self
class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-instance-attributes
@@ -115,16 +125,21 @@ class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-ins
) -> None:
self.__auth_manager = auth_manager
- self.__info_manager = info_manager
- self.__wol = wol
-
self.__hid = hid
- self.__atx = atx
- self.__msd = msd
self.__streamer = streamer
self.__heartbeat = heartbeat
+ self.__components = [
+ _Component("Auth manager", "", auth_manager),
+ _Component("Info manager", "info_state", info_manager),
+ _Component("Wake-on-LAN", "wol_state", wol),
+ _Component("HID", "hid_state", hid),
+ _Component("ATX", "atx_state", atx),
+ _Component("MSD", "msd_state", msd),
+ _Component("Streamer", "streamer_state", streamer),
+ ]
+
self.__apis: List[object] = [
self,
AuthApi(auth_manager),
@@ -180,12 +195,9 @@ class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-ins
await self.__register_socket(ws)
try:
await asyncio.gather(*[
- self.__broadcast_event(_Events.INFO_STATE, (await self.__info_manager.get_state())),
- self.__broadcast_event(_Events.WOL_STATE, self.__wol.get_state()),
- self.__broadcast_event(_Events.HID_STATE, (await self.__hid.get_state())),
- self.__broadcast_event(_Events.ATX_STATE, self.__atx.get_state()),
- self.__broadcast_event(_Events.MSD_STATE, (await self.__msd.get_state())),
- self.__broadcast_event(_Events.STREAMER_STATE, (await self.__streamer.get_state())),
+ self.__broadcast_event(component.event_type, await component.get_state())
+ for component in self.__components
+ if component.get_state
])
async for msg in ws:
if msg.type == aiohttp.web.WSMsgType.TEXT:
@@ -224,10 +236,9 @@ class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-ins
app.on_cleanup.append(self.__on_cleanup)
self.__run_system_task(self.__stream_controller)
- self.__run_system_task(self.__poll_state, _Events.HID_STATE, self.__hid.poll_state())
- self.__run_system_task(self.__poll_state, _Events.ATX_STATE, self.__atx.poll_state())
- self.__run_system_task(self.__poll_state, _Events.MSD_STATE, self.__msd.poll_state())
- self.__run_system_task(self.__poll_state, _Events.STREAMER_STATE, self.__streamer.poll_state())
+ for component in self.__components:
+ if component.poll_state:
+ self.__run_system_task(self.__poll_state, component.event_type, component.poll_state())
for api in self.__apis:
for http_exposed in get_exposed_http(api):
@@ -282,26 +293,19 @@ class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-ins
async def __on_cleanup(self, _: aiohttp.web.Application) -> None:
logger = get_logger(0)
- for (name, obj) in [
- ("Auth manager", self.__auth_manager),
- ("Streamer", self.__streamer),
- ("MSD", self.__msd),
- ("ATX", self.__atx),
- ("HID", self.__hid),
- ]:
- if isinstance(obj, BasePlugin):
- name = f"{name} ({obj.get_plugin_name()})"
- logger.info("Cleaning up %s ...", name)
- try:
- await obj.cleanup() # type: ignore
- except Exception:
- logger.exception("Cleanup error on %s", name)
-
- async def __broadcast_event(self, event_type: _Events, event: Dict) -> None:
+ for component in self.__components:
+ if component.cleanup:
+ logger.info("Cleaning up %s ...", component.name)
+ try:
+ await component.cleanup() # type: ignore
+ except Exception:
+ logger.exception("Cleanup error on %s", component.name)
+
+ async def __broadcast_event(self, event_type: str, event: Dict) -> None:
if self.__sockets:
await asyncio.gather(*[
ws.send_str(json.dumps({
- "event_type": event_type.value,
+ "event_type": event_type,
"event": event,
}))
for ws in list(self.__sockets)
@@ -351,6 +355,6 @@ class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-ins
prev = cur
await self.__streamer_notifier.wait()
- async def __poll_state(self, event_type: _Events, poller: AsyncGenerator[Dict, None]) -> None:
+ async def __poll_state(self, event_type: str, poller: AsyncGenerator[Dict, None]) -> None:
async for state in poller:
await self.__broadcast_event(event_type, state)
diff --git a/kvmd/apps/kvmd/wol.py b/kvmd/apps/kvmd/wol.py
index f388f136..672b9ef6 100644
--- a/kvmd/apps/kvmd/wol.py
+++ b/kvmd/apps/kvmd/wol.py
@@ -50,7 +50,7 @@ class WakeOnLan:
assert len(mac) == 17, mac
self.__magic = bytes.fromhex("FF" * 6 + mac.replace(":", "") * 16)
- def get_state(self) -> Dict:
+ async def get_state(self) -> Dict:
return {
"enabled": bool(self.__magic),
"target": {