diff options
-rw-r--r-- | configs/kvmd/meta.yaml | 2 | ||||
-rw-r--r-- | kvmd/apps/kvmd/server.py | 50 | ||||
-rw-r--r-- | web/js/kvm/atx.js | 12 | ||||
-rw-r--r-- | web/js/kvm/msd.js | 12 | ||||
-rw-r--r-- | web/js/kvm/session.js | 51 | ||||
-rw-r--r-- | web/js/kvm/stream.js | 13 |
6 files changed, 55 insertions, 85 deletions
diff --git a/configs/kvmd/meta.yaml b/configs/kvmd/meta.yaml index 65524997..0f2aa959 100644 --- a/configs/kvmd/meta.yaml +++ b/configs/kvmd/meta.yaml @@ -4,6 +4,6 @@ # will be displayed in the web interface. server: - host: localhost + host: localhost.localdomain kvm: {} diff --git a/kvmd/apps/kvmd/server.py b/kvmd/apps/kvmd/server.py index 9c6933d4..af9e6765 100644 --- a/kvmd/apps/kvmd/server.py +++ b/kvmd/apps/kvmd/server.py @@ -4,6 +4,8 @@ import asyncio import json import time +from enum import Enum + from typing import List from typing import Dict from typing import Set @@ -100,6 +102,13 @@ def _wrap_exceptions_for_web(msg: str) -> Callable: return make_wrapper +class _Events(Enum): + INFO_STATE = "info_state" + STREAMER_STATE = "streamer_state" + ATX_STATE = "atx_state" + MSD_STATE = "msd_state" + + class Server: # pylint: disable=too-many-instance-attributes def __init__( # pylint: disable=too-many-arguments self, @@ -179,10 +188,8 @@ class Server: # pylint: disable=too-many-instance-attributes aiohttp.web.run_app(app, host=host, port=port, print=self.__run_app_print) - # ===== SYSTEM - - async def __info_handler(self, _: aiohttp.web.Request) -> aiohttp.web.Response: - return _json({ + async def __make_info(self) -> Dict: + return { "version": { "kvmd": __version__, "streamer": await self.__streamer.get_version(), @@ -190,7 +197,12 @@ class Server: # pylint: disable=too-many-instance-attributes "streamer": self.__streamer.get_app(), "meta": await self.__info_manager.get_meta(), "extras": await self.__info_manager.get_extras(), - }) + } + + # ===== SYSTEM + + async def __info_handler(self, _: aiohttp.web.Request) -> aiohttp.web.Response: + return _json(await self.__make_info()) @_wrap_exceptions_for_web("Log error") async def __log_handler(self, request: aiohttp.web.Request) -> aiohttp.web.StreamResponse: @@ -213,6 +225,12 @@ class Server: # pylint: disable=too-many-instance-attributes ws = aiohttp.web.WebSocketResponse(heartbeat=self.__heartbeat) await ws.prepare(request) await self.__register_socket(ws) + await asyncio.gather(*[ + self.__broadcast_event(_Events.INFO_STATE, (await self.__make_info())), + self.__broadcast_event(_Events.STREAMER_STATE, (await self.__streamer.get_state())), + self.__broadcast_event(_Events.ATX_STATE, self.__atx.get_state()), + self.__broadcast_event(_Events.MSD_STATE, self.__msd.get_state()), + ]) async for msg in ws: if msg.type == aiohttp.web.WSMsgType.TEXT: try: @@ -285,9 +303,9 @@ class Server: # pylint: disable=too-many-instance-attributes }.get(button) if not clicker: raise BadRequest("Invalid param 'button'") - await self.__broadcast_event("atx_click", button=button) # type: ignore + await self.__broadcast_event(_Events.ATX_STATE, self.__atx.get_state()) await clicker() - await self.__broadcast_event("atx_click", button=None) # type: ignore + await self.__broadcast_event(_Events.ATX_STATE, self.__atx.get_state()) return _json({"clicked": button}) # ===== MSD @@ -301,11 +319,11 @@ class Server: # pylint: disable=too-many-instance-attributes if to == "kvm": await self.__msd.connect_to_kvm() state = self.__msd.get_state() - await self.__broadcast_event("msd_state", **state) + await self.__broadcast_event(_Events.MSD_STATE, state) elif to == "server": await self.__msd.connect_to_pc() state = self.__msd.get_state() - await self.__broadcast_event("msd_state", **state) + await self.__broadcast_event(_Events.MSD_STATE, state) else: raise BadRequest("Invalid param 'to'") return _json(state) @@ -326,7 +344,7 @@ class Server: # pylint: disable=too-many-instance-attributes raise BadRequest("Missing 'image_data' field") async with self.__msd: - await self.__broadcast_event("msd_state", **self.__msd.get_state()) + await self.__broadcast_event(_Events.MSD_STATE, self.__msd.get_state()) logger.info("Writing image %r to mass-storage device ...", image_name) await self.__msd.write_image_info(image_name, False) while True: @@ -336,7 +354,7 @@ class Server: # pylint: disable=too-many-instance-attributes written = await self.__msd.write_image_chunk(chunk) await self.__msd.write_image_info(image_name, True) finally: - await self.__broadcast_event("msd_state", **self.__msd.get_state()) + await self.__broadcast_event(_Events.MSD_STATE, self.__msd.get_state()) if written != 0: logger.info("Written %d bytes to mass-storage device", written) return _json({"written": written}) @@ -433,21 +451,21 @@ class Server: # pylint: disable=too-many-instance-attributes async def __poll_atx_state(self) -> None: async for state in self.__atx.poll_state(): if self.__sockets: - await self.__broadcast_event("atx_state", **state) + await self.__broadcast_event(_Events.ATX_STATE, state) @_system_task async def __poll_streamer_state(self) -> None: async for state in self.__streamer.poll_state(): if self.__sockets: - await self.__broadcast_event("streamer_state", **state) + await self.__broadcast_event(_Events.STREAMER_STATE, state) - async def __broadcast_event(self, event: str, **kwargs: Dict) -> None: + async def __broadcast_event(self, event_type: _Events, event_attrs: Dict) -> None: await asyncio.gather(*[ ws.send_str(json.dumps({ "msg_type": "event", "msg": { - "event": event, - "event_attrs": kwargs, + "event": event_type.value, + "event_attrs": event_attrs, }, })) for ws in list(self.__sockets) diff --git a/web/js/kvm/atx.js b/web/js/kvm/atx.js index b75b901b..e4f591d5 100644 --- a/web/js/kvm/atx.js +++ b/web/js/kvm/atx.js @@ -14,18 +14,6 @@ function Atx() { /********************************************************************************/ - self.loadInitialState = function() { - var http = tools.makeRequest("GET", "/kvmd/atx", function() { - if (http.readyState === 4) { - if (http.status === 200) { - __setButtonsBusy(JSON.parse(http.responseText).result.busy); - } else { - setTimeout(self.loadInitialState, 1000); - } - } - }); - }; - self.setState = function(state) { __setButtonsBusy(state.busy); $("atx-power-led").className = (state.leds.power ? "led-green" : "led-gray"); diff --git a/web/js/kvm/msd.js b/web/js/kvm/msd.js index c59563b7..057dec5b 100644 --- a/web/js/kvm/msd.js +++ b/web/js/kvm/msd.js @@ -24,18 +24,6 @@ function Msd() { /********************************************************************************/ - self.loadInitialState = function() { - var http = tools.makeRequest("GET", "/kvmd/msd", function() { - if (http.readyState === 4) { - if (http.status === 200) { - self.setState(JSON.parse(http.responseText).result); - } else { - setTimeout(self.loadInitialState, 1000); - } - } - }); - }; - self.setState = function(state) { __state = state; __applyState(); diff --git a/web/js/kvm/session.js b/web/js/kvm/session.js index 04149be3..bcc97fab 100644 --- a/web/js/kvm/session.js +++ b/web/js/kvm/session.js @@ -15,39 +15,29 @@ function Session() { var __init__ = function() { $("link-led").title = "Not connected yet..."; - __loadKvmdInfo(); __startPoller(); }; /********************************************************************************/ - var __loadKvmdInfo = function() { - var http = tools.makeRequest("GET", "/kvmd/info", function() { - if (http.readyState === 4) { - if (http.status === 200) { - var info = JSON.parse(http.responseText).result; - if (info.meta) { - var text = JSON.stringify(info.meta, undefined, 4).replace(/ /g, " ").replace(/\n/g, "<br>"); - $("about-meta").innerHTML = ` - <span class="code-comment">// The Pi-KVM metadata.<br> - // You can get this json using handle /kvmd/info.<br> - // In the standard configuration this data<br> - // is specified in the file /etc/kvmd/meta.yaml.</span><br> - <br> - ${text} - `; - if (info.meta.server && info.meta.server.host) { - document.title = "Pi-KVM Session - " + info.meta.server.host; - $("kvmd-meta-server-host").innerHTML = "Server: " + info.meta.server.host; - } - } - $("about-version-kvmd").innerHTML = info.version.kvmd; - $("about-version-streamer").innerHTML = `${info.version.streamer} (${info.streamer})`; - } else { - setTimeout(__loadKvmdInfo, 1000); - } + var __setKvmdInfo = function(state) { + if (state.meta) { + var text = JSON.stringify(state.meta, undefined, 4).replace(/ /g, " ").replace(/\n/g, "<br>"); + $("about-meta").innerHTML = ` + <span class="code-comment">// The Pi-KVM metadata.<br> + // You can get this json using handle <a target="_blank" href="/kvmd/info">/kvmd/info</a>.<br> + // In the standard configuration this data<br> + // is specified in the file /etc/kvmd/meta.yaml.</span><br> + <br> + ${text} + `; + if (state.meta.server && state.meta.server.host) { + document.title = "Pi-KVM Session - " + state.meta.server.host; + $("kvmd-meta-server-host").innerHTML = "Server: " + state.meta.server.host; } - }); + } + $("about-version-kvmd").innerHTML = state.version.kvmd; + $("about-version-streamer").innerHTML = `${state.version.streamer} (${state.streamer})`; }; var __startPoller = function() { @@ -73,9 +63,6 @@ function Session() { $("link-led").className = "led-green"; $("link-led").title = "Connected"; tools.debug("Session: socket opened:", event); - __streamer.loadInitialState(); - __atx.loadInitialState(); - __msd.loadInitialState(); __hid.setSocket(__ws); __missed_heartbeats = 0; __ping_timer = setInterval(__pingServer, 1000); @@ -87,7 +74,9 @@ function Session() { if (event.msg_type === "pong") { __missed_heartbeats = 0; } else if (event.msg_type === "event") { - if (event.msg.event === "streamer_state") { + if (event.msg.event === "info_state") { + __setKvmdInfo(event.msg.event_attrs); + } else if (event.msg.event === "streamer_state") { __streamer.setState(event.msg.event_attrs); } else if (event.msg.event === "atx_state") { __atx.setState(event.msg.event_attrs); diff --git a/web/js/kvm/stream.js b/web/js/kvm/stream.js index d543701f..029eee48 100644 --- a/web/js/kvm/stream.js +++ b/web/js/kvm/stream.js @@ -38,19 +38,6 @@ function Streamer() { /********************************************************************************/ - self.loadInitialState = function() { - var http = tools.makeRequest("GET", "/kvmd/streamer", function() { - if (http.readyState === 4) { - if (http.status === 200) { - self.setState(JSON.parse(http.responseText).result); - } else { - self.clearState(); - setTimeout(self.loadInitialState, 1000); - } - } - }); - }; - self.setState = function(state) { if (state.state) { var source = state.state.source; |