aboutsummaryrefslogtreecommitdiff
path: root/src/Control.py
diff options
context:
space:
mode:
authorGravatar jesopo2019-10-11 15:12:26 +0100
committerGravatar jesopo2019-10-11 15:12:26 +0100
commitde389b34b817d0bcc8940730f45a2c50407df1cf (patch)
tree0cc9047c7af43a438c6b2758dc6259172d1915ff /src/Control.py
parentfirst 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.py65
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}))