diff --git a/screenless/bureau/bureau.py b/screenless/bureau/bureau.py index aabe4ea..19d0c45 100644 --- a/screenless/bureau/bureau.py +++ b/screenless/bureau/bureau.py @@ -1,6 +1,7 @@ # bureau import configparser import functools +import inspect import json import os.path import subprocess @@ -65,6 +66,15 @@ class Bureau(object): self.commands = {} self.api = {} + modpath = os.path.dirname(__file__) + phantomjs = os.path.join(modpath, "..", "lib", "phantomjs", "bin", + "phantomjs") + renderer = os.path.join(modpath, "..", "lib", "rasterize.js") + self.phantomjs = os.path.abspath(phantomjs) + self.html2pdf = self.phantomjs + " " + os.path.abspath(renderer) + " " + mypath = inspect.getfile(self.__class__) + self.mdir = os.path.dirname(mypath) + basepath = os.path.expanduser("~/.screenless") if not os.path.exists(basepath): os.mkdir(basepath) @@ -108,22 +118,20 @@ class Bureau(object): sender = self.context.socket(zmq.REQ) sender.connect("ipc://" + recipient + ".ipc") sender.send_string(message) - # TODO: retry this a few times with a proper sleep/timeout - #time.sleep(0.5) - #try: - # ret = json.loads(sender.recv_string(flags=zmq.NOBLOCK)) - # # TODO: deal with non-json replies - #except zmq.ZMQError: - # print("message sent but got no reply...") - # ret = None events = sender.poll(timeout=10000) if events is not 0: - ret = json.loads(sender.recv_string()) + resp = sender.recv_string() + if len(resp) == 0: + return None + elif resp[0] == "0": + return json.loads(resp[1:]) + else: + # TODO: this may need some better error handling + return resp else: print("message sent... timed out after 10 seconds.") - ret = None - return ret + return None def _publish_methods(self): """ @@ -133,7 +141,13 @@ class Bureau(object): # register bureau with Inhuman Resources bureau_detail = {"name": self.name, "prefix": self.prefix, "desc": self.__doc__} - self.send("IR", "addbureau", bureau_detail) + + # slight hack to avoid messy self-reference and chicken-egg waiting + if self.prefix == "IR": + method = getattr(self, "add_bureau") + method(bureau_detail) + else: + self.send("IR", "addbureau", bureau_detail) # find and store all published methods for member in dir(self): @@ -148,14 +162,22 @@ class Bureau(object): "prefix": self.prefix, "cmd": method.command, "desc": method.__doc__} - self.send("IR", "addcommand", cmd_detail) + if self.prefix == "IR": + method = getattr(self, "add_cmd") + method(cmd_detail) + else: + self.send("IR", "addcommand", cmd_detail) elif hasattr(method, "api"): self.api[method.api] = method api_detail = {"apiname": method.name, "prefix": self.prefix, "api": method.api, "desc": method.__doc__} - self.send("IR", "addapi", api_detail) + if self.prefix == "IR": + method = getattr(self, "add_api_method") + method(api_detail) + else: + self.send("IR", "addapi", api_detail) print("registered:") print(self.commands) @@ -163,22 +185,35 @@ class Bureau(object): def print_full(self, template, **kwargs): """print a full page (A4) document """ - # TODO: look up the printer LPR name - - lpname = kwargs.get("printer", "default") - templ = Template(filename=template) - - texfile, texfilepath = tempfile.mkstemp(".tex") - texfile.write(templ.render_unicode( - **kwargs).encode('utf-8', 'replace')) - - texdir = os.path.dirname(texfilepath) - - subprocess.call("cd " + texdir + "; xelatex " + texfilepath) - - pdffile = texfilepath[0:-4] + ".pdf" - - subprocess.call("lpr -P " + lpname + " " + pdffile) + # TODO: look up the printer LPR name / allow multiple printers/non-default + + # lpname = kwargs.get("printer", "default") + + htmlfile, htmlpath = tempfile.mkstemp(".html") + htmlfile = os.fdopen(htmlfile, "w") + # run template with kwargs + templfile = os.path.join(self.mdir, template) + print("using template: ", templfile) + templ = Template(filename=templfile) + htmlfile.write(templ.render_unicode(**kwargs)) + htmlfile.close() + #.encode('utf-8', + # 'replace')) + + # texfile, texfilepath = tempfile.mkstemp(".tex") + # texfile.write(templ.render_unicode( + # **kwargs).encode('utf-8', 'replace')) + + # texdir = os.path.dirname(texfilepath) + + # subprocess.call("cd " + texdir + "; xelatex " + texfilepath) + + # TODO: make paper size a config variable + pdfpath = tempfile.mkstemp(".pdf")[1] + print("rendering with: ", self.html2pdf + htmlpath + " " + pdfpath) + subprocess.call(self.html2pdf + htmlpath + " " + pdfpath + + " A4 1920px", shell=True) + #subprocess.call("lpr " + pdfpath, shell=True) # TODO: make this asynchronous def print_small(self, text, printer="/dev/usb/lp0"):