server-side paste-as-keys

This commit is contained in:
Devaev Maxim
2020-05-22 21:07:54 +03:00
parent 0fa0680bd7
commit 43afd9acb3
13 changed files with 196 additions and 112 deletions

View File

@@ -20,6 +20,8 @@
# ========================================================================== #
import asyncio
from typing import Dict
from aiohttp.web import Request
@@ -29,12 +31,15 @@ from aiohttp.web import WebSocketResponse
from ....plugins.hid import BaseHid
from ....validators.basic import valid_bool
from ....validators.basic import valid_number
from ....validators.kvm import valid_hid_key
from ....validators.kvm import valid_hid_mouse_move
from ....validators.kvm import valid_hid_mouse_button
from ....validators.kvm import valid_hid_mouse_wheel
from .... import keyprint
from ..http import exposed_http
from ..http import exposed_ws
from ..http import make_json_response
@@ -45,6 +50,8 @@ class HidApi:
def __init__(self, hid: BaseHid) -> None:
self.__hid = hid
self.__key_lock = asyncio.Lock()
# =====
@exposed_http("GET", "/hid")
@@ -56,16 +63,28 @@ class HidApi:
await self.__hid.reset()
return make_json_response()
@exposed_http("POST", "/hid/print")
async def __print_handler(self, request: Request) -> Response:
text = await request.text()
limit = int(valid_number(request.query.get("limit", "1024"), min=0, type=int))
if limit > 0:
text = text[:limit]
async with self.__key_lock:
for (key, state) in keyprint.text_to_keys(text):
self.__hid.send_key_event(key, state)
return make_json_response()
# =====
@exposed_ws("key")
async def __ws_key_handler(self, _: WebSocketResponse, event: Dict) -> None:
try:
key = valid_hid_key(event["key"])
state = valid_bool(event["state"])
except Exception:
return
await self.__hid.send_key_event(key, state)
async with self.__key_lock:
try:
key = valid_hid_key(event["key"])
state = valid_bool(event["state"])
except Exception:
return
self.__hid.send_key_event(key, state)
@exposed_ws("mouse_button")
async def __ws_mouse_button_handler(self, _: WebSocketResponse, event: Dict) -> None:
@@ -74,7 +93,7 @@ class HidApi:
state = valid_bool(event["state"])
except Exception:
return
await self.__hid.send_mouse_button_event(button, state)
self.__hid.send_mouse_button_event(button, state)
@exposed_ws("mouse_move")
async def __ws_mouse_move_handler(self, _: WebSocketResponse, event: Dict) -> None:
@@ -83,7 +102,7 @@ class HidApi:
to_y = valid_hid_mouse_move(event["to"]["y"])
except Exception:
return
await self.__hid.send_mouse_move_event(to_x, to_y)
self.__hid.send_mouse_move_event(to_x, to_y)
@exposed_ws("mouse_wheel")
async def __ws_mouse_wheel_handler(self, _: WebSocketResponse, event: Dict) -> None:
@@ -92,4 +111,4 @@ class HidApi:
delta_y = valid_hid_mouse_wheel(event["delta"]["y"])
except Exception:
return
await self.__hid.send_mouse_wheel_event(delta_x, delta_y)
self.__hid.send_mouse_wheel_event(delta_x, delta_y)

View File

@@ -391,7 +391,7 @@ class KvmdServer(HttpServer): # pylint: disable=too-many-arguments,too-many-ins
async def __remove_socket(self, ws: aiohttp.web.WebSocketResponse) -> None:
async with self.__sockets_lock:
await self.__hid.clear_events()
self.__hid.clear_events()
try:
self.__sockets.remove(ws)
remote: Optional[str] = (ws._req.remote if ws._req is not None else None) # pylint: disable=protected-access

View File

@@ -278,7 +278,14 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
self.__mouse_move = move
async def _on_cut_event(self, text: str) -> None:
pass # print("CutEvent", text) # TODO
assert self.__authorized.done()
(user, passwd) = self.__authorized.result()
logger = get_logger(0)
logger.info("[main] Client %s: Printing %d characters ...", self._remote, len(text))
try:
await self.__kvmd.hid.print(user, passwd, text, 0)
except Exception:
logger.exception("[main] Client %s: Can't print characters", self._remote)
async def _on_set_encodings(self) -> None:
assert self.__authorized.done()