diff --git a/screenless/bureau/__init__.py b/screenless/bureau/__init__.py index 5d21496..582ac86 100644 --- a/screenless/bureau/__init__.py +++ b/screenless/bureau/__init__.py @@ -1 +1 @@ -from bureau import Bureau +from .bureau import Bureau, add_command, add_api diff --git a/screenless/bureau/bureau.py b/screenless/bureau/bureau.py index fed1536..270f1b2 100644 --- a/screenless/bureau/bureau.py +++ b/screenless/bureau/bureau.py @@ -184,13 +184,13 @@ class Bureau(object): lp.close() @add_command("test") - def test(self, data): + def test(self, data=None): """ Standard test command. """ # stupid test to see if modules work print(("hi! testing. " + self.name + " bureau seems to work!")) - return b"seems to work." + return "seems to work." def run_io(self): """process hardware or timed input @@ -245,15 +245,18 @@ class Bureau(object): data = json.loads(data) ret = self.api[ref](data) else: - ret = self.commands[ref](data) + if data: + ret = self.commands[ref](data) + else: + ret = self.commands[ref]() if ret is None: ret = "" - ret = b"0" + ret - self._recv.send(ret) - except TypeError as err: - print(err) - print("invalid data for command '{}': {}".format(ref, data)) - self._recv.send_unicode("Error. Invalid or missing data.") + ret = "0" + ret + self._recv.send_string(ret) + #except TypeError as err: + # print(err) + # print("invalid data for command '{}': {}".format(ref, data)) + # self._recv.send_unicode("Error. Invalid or missing data.") except KeyError as err: print(err) print("You are calling a command as an API or vice-versa.") @@ -264,6 +267,9 @@ class Bureau(object): self._recv.send_unicode("Error! Command/API not found.") -if __name__ == "__main__": +def main(): buro = Bureau() buro.run() + +if __name__ == "__main__": + main() diff --git a/screenless/bureau/ihr.py b/screenless/bureau/ihr.py index 6daee1c..8a5d4d2 100644 --- a/screenless/bureau/ihr.py +++ b/screenless/bureau/ihr.py @@ -29,11 +29,10 @@ class InhumanResources(Bureau): desc: "Keep track of public resources provided by bureaus" } """ - d = json.loads(data) try: - name = d["name"] - prefix = d["prefix"] - desc = d["desc"] + name = data["name"] + prefix = data["prefix"] + desc = data["desc"] except KeyError as e: print("cannot add invalid bureau:", str(e)) return @@ -45,12 +44,11 @@ class InhumanResources(Bureau): @add_api("addcommand", "Register Command") def add_cmd(self, data): - d = json.loads(data) try: - prefix = d["prefix"] - cmd = d["cmd"] - cmdname = d["cmdname"] - desc = d["desc"] + prefix = data["prefix"] + cmd = data["cmd"] + cmdname = data["cmdname"] + desc = data["desc"] except KeyError as e: print("cannot add invalid command:", str(e)) return @@ -64,12 +62,11 @@ class InhumanResources(Bureau): @add_api("addapi", "Register API Method") def add_api_method(self, data): - d = json.loads(data) try: - prefix = d["prefix"] - cmd = d["api"] - cmdname = d["apiname"] - desc = d["desc"] + prefix = data["prefix"] + cmd = data["api"] + cmdname = data["apiname"] + desc = data["desc"] except KeyError as e: print("cannot add invalid command:", str(e)) return @@ -89,6 +86,10 @@ class InhumanResources(Bureau): print(self.menu) +def main(): + hr = InhumanResources() + hr.run() + if __name__ == "__main__": hr = InhumanResources() hr.run() diff --git a/screenless/bureau/kbtest.py b/screenless/bureau/kbtest.py index 21f0205..df5574d 100644 --- a/screenless/bureau/kbtest.py +++ b/screenless/bureau/kbtest.py @@ -1,13 +1,16 @@ +import os import time import zmq ctx = zmq.Context() +basepath = os.path.expanduser("~/.screenless/") + while True: msg = input("> ") send = ctx.socket(zmq.REQ) - send.connect("ipc://.screenless/" + msg[0:2] + ".ipc") + send.connect("ipc://" + basepath + msg[0:2] + ".ipc") send.send_string(msg[2:]) print("sending ", msg[2:]) ret = None diff --git a/screenless/bureau/typing.py b/screenless/bureau/typing.py index 42c5d29..eb537b2 100644 --- a/screenless/bureau/typing.py +++ b/screenless/bureau/typing.py @@ -71,6 +71,11 @@ class TypingPool(Bureau): except KeyError: print("Error invalid keycode:", data.scancode) + +def main(): + evd = TypingPool() + evd.run() + if __name__ == "__main__": evd = TypingPool() evd.run() diff --git a/screenless/mgmt.py b/screenless/mgmt.py new file mode 100644 index 0000000..cc63917 --- /dev/null +++ b/screenless/mgmt.py @@ -0,0 +1,56 @@ +""" +The Management - this module takes care of loading and running subordinate + bureaus in the office organization. Bureaus are enabled in the file + "~/.screenless/mgmt.ini": + [mgmt] + bureaus = ihr typing myburo and so on +""" +import configparser +import importlib +import multiprocessing +import os +import time + +def mgmt(): + + basepath = os.path.expanduser("~/.screenless") + if not os.path.exists(basepath): + os.mkdir(basepath) + os.chdir(basepath) + + config = configparser.ConfigParser() + procs = {} + + try: + config.read("mgmt.ini") + org_chart = config["mgmt"]["bureaus"].split() + except KeyError: + config["mgmt"] = {"bureaus": "ihr typing"} + with open("mgmt.ini", "w") as configfile: + config.write(configfile) + print("created new mgmt.ini config file. please modify this to suit.") + org_chart = config["mgmt"]["bureaus"].split() + + print("org chart:", org_chart) + + for buro in org_chart: + lib = importlib.import_module("bureau." + buro) + # run lib.main() in a separate process + proc = multiprocessing.Process(target=lib.main) + procs[buro] = proc.start() + + while True: + for buro in org_chart: + proc = procs[buro] + if not proc.is_alive(): + print("bureau", buro, "has crashed! Call the consultants!") + #TODO this should probably restart in some sensible way + else: + print("bureau", buro, "still running...") + time.sleep(1) + + + + +if __name__ == "__main__": + mgmt()