diff options
| author | 2019-10-11 15:12:26 +0100 | |
|---|---|---|
| committer | 2019-10-11 15:12:26 +0100 | |
| commit | de389b34b817d0bcc8940730f45a2c50407df1cf (patch) | |
| tree | 0cc9047c7af43a438c6b2758dc6259172d1915ff /src/Control.py | |
| parent | first draft of infrastructure for unix domain control socket (diff) | |
| signature | ||
add first real cli functionality: showing log
Diffstat (limited to 'src/Control.py')
| -rw-r--r-- | src/Control.py | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/src/Control.py b/src/Control.py index 2fe742cc..19c2faaa 100644 --- a/src/Control.py +++ b/src/Control.py @@ -1,11 +1,13 @@ import json, os, socket, typing -from src import EventManager, PollSource +from src import IRCBot, Logging, PollSource class ControlClient(object): def __init__(self, sock: socket.socket): self._socket = sock self._read_buffer = b"" self._write_buffer = b"" + self.version = None + self.log_level = None def fileno(self) -> int: return self._socket.fileno() @@ -13,19 +15,14 @@ class ControlClient(object): def read_lines(self) -> typing.List[str]: data = self._socket.recv(2048) if not data: - return [] + return None lines = (self._read_buffer+data).split(b"\n") lines = [line.strip(b"\r") for line in lines] self._read_buffer = lines.pop(-1) return [line.decode("utf8") for line in lines] def write_line(self, line: str): - self._write_buffer += ("%s\n" % line).encode("utf8") - def _send(self): - sent = self._socket.send(self._write_buffer) - self._write_buffer = self._write_buffer[sent:] - def writeable(self) -> bool: - return bool(self._write_buffer) + self._socket.send(("%s\n" % line).encode("utf8")) def disconnect(self): try: @@ -39,11 +36,19 @@ class ControlClient(object): class Control(PollSource.PollSource): - def __init__(self, events: EventManager.Events, database_location): + def __init__(self, bot: IRCBot.Bot, database_location: str): + self._bot = bot + self._bot.log.hook(self._on_log) + self._socket_location = "%s.sock" % database_location self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self._clients = {} + def _on_log(self, levelno: int, line: str): + for client in self._clients.values(): + if not client.log_level == None and client.log_level <= levelno: + self._send_action(client, "log", line) + def bind(self): if os.path.exists(self._socket_location): os.remove(self._socket_location) @@ -52,8 +57,6 @@ class Control(PollSource.PollSource): def get_readables(self) -> typing.List[int]: return [self._socket.fileno()]+list(self._clients.keys()) - def get_writables(self) -> typing.List[int]: - return [f for f, c in self._clients.items() if c.writeable()] def is_readable(self, fileno: int): if fileno == self._socket.fileno(): @@ -62,20 +65,40 @@ class Control(PollSource.PollSource): elif fileno in self._clients: client = self._clients[fileno] lines = client.read_lines() - if not lines: + if lines == None: client.disconnect() del self._clients[fileno] else: for line in lines: response = self._parse_line(client, line) - client.write_line(response) - def is_writeable(self, fileno: int): - self._clients[fileno]._send() def _parse_line(self, client: ControlClient, line: str): - version, _, id = line.partition(" ") - id, _, data_str = id.partition(" ") - if version == "0.1": -# data = json.loads(data_str) - response = {"action": "ack"} - return "0.1 %s %s" % (id, json.dumps(response)) + id, _, command = line.partition(" ") + command, _, data = command.partition(" ") + if not id or not command: + client.disconnect() + return + + command = command.lower() + response_action = "ack" + response_data = None + + if command == "version": + client.version = int(data) + elif command == "log": + client.log_level = Logging.LEVELS[data.lower()] + + elif command == "command": + result = self._bot._events.on("control.command").on( + data["command"]).call_for_result(command=data["command"], + args=data["args"]) + if not result == None: + response_action = "result" + response_data = result + + self._send_action(client, response_action, response_data, id) + + def _send_action(self, client: ControlClient, action: str, data: str, + id: int=None): + client.write_line( + json.dumps({"action": action, "data": data, "id": id})) |
