|
|
@ -3,6 +3,7 @@ import configparser
|
|
|
|
import functools
|
|
|
|
import functools
|
|
|
|
import inspect
|
|
|
|
import inspect
|
|
|
|
import json
|
|
|
|
import json
|
|
|
|
|
|
|
|
import logging
|
|
|
|
import os.path
|
|
|
|
import os.path
|
|
|
|
import subprocess
|
|
|
|
import subprocess
|
|
|
|
import tempfile
|
|
|
|
import tempfile
|
|
|
@ -85,6 +86,12 @@ class Bureau(object):
|
|
|
|
os.mkdir(basepath)
|
|
|
|
os.mkdir(basepath)
|
|
|
|
os.chdir(basepath)
|
|
|
|
os.chdir(basepath)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# setup log file
|
|
|
|
|
|
|
|
# TODO: make log level globally and bureau-specific via config
|
|
|
|
|
|
|
|
logfile = os.path.join(basepath, self.prefix + ".log")
|
|
|
|
|
|
|
|
logging.basicConfig(filename=logfile, level=logging.DEBUG)
|
|
|
|
|
|
|
|
self.log = logging.getLogger(self.prefix)
|
|
|
|
|
|
|
|
|
|
|
|
self.config = configparser.ConfigParser()
|
|
|
|
self.config = configparser.ConfigParser()
|
|
|
|
self.load_config()
|
|
|
|
self.load_config()
|
|
|
|
|
|
|
|
|
|
|
@ -101,9 +108,9 @@ class Bureau(object):
|
|
|
|
self.context = zmq.Context()
|
|
|
|
self.context = zmq.Context()
|
|
|
|
self._recv = self.context.socket(zmq.REP)
|
|
|
|
self._recv = self.context.socket(zmq.REP)
|
|
|
|
self._recv.bind("ipc://" + self.prefix + ".ipc")
|
|
|
|
self._recv.bind("ipc://" + self.prefix + ".ipc")
|
|
|
|
print(("bureau " + self.name + " waiting for messages"))
|
|
|
|
self.log.debug("bureau " + self.name + " waiting for messages")
|
|
|
|
print("commands: ")
|
|
|
|
self.log.debug("commands: ")
|
|
|
|
print(self.commands)
|
|
|
|
self.log.debug(self.commands)
|
|
|
|
|
|
|
|
|
|
|
|
def load_config(self):
|
|
|
|
def load_config(self):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
@ -152,7 +159,8 @@ class Bureau(object):
|
|
|
|
# TODO: this may need some better error handling
|
|
|
|
# TODO: this may need some better error handling
|
|
|
|
return resp
|
|
|
|
return resp
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
print("message sent... timed out after 10 seconds.")
|
|
|
|
self.log.warning("message" + message +
|
|
|
|
|
|
|
|
" sent... timed out after 10 seconds.")
|
|
|
|
return None
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
def _publish_methods(self):
|
|
|
|
def _publish_methods(self):
|
|
|
@ -201,9 +209,9 @@ class Bureau(object):
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.send("IR", "addapi", api_detail)
|
|
|
|
self.send("IR", "addapi", api_detail)
|
|
|
|
|
|
|
|
|
|
|
|
print("registered:")
|
|
|
|
self.log.debug("registered:")
|
|
|
|
print(self.commands)
|
|
|
|
self.log.debug(self.commands)
|
|
|
|
print(self.api)
|
|
|
|
self.log.debug(self.api)
|
|
|
|
|
|
|
|
|
|
|
|
def print_full(self, template, **kwargs):
|
|
|
|
def print_full(self, template, **kwargs):
|
|
|
|
"""print a full page (A4) document """
|
|
|
|
"""print a full page (A4) document """
|
|
|
@ -215,7 +223,7 @@ class Bureau(object):
|
|
|
|
htmlfile = os.fdopen(htmlfile, "w")
|
|
|
|
htmlfile = os.fdopen(htmlfile, "w")
|
|
|
|
# run template with kwargs
|
|
|
|
# run template with kwargs
|
|
|
|
templfile = os.path.join(self.mdir, template)
|
|
|
|
templfile = os.path.join(self.mdir, template)
|
|
|
|
print("using template: ", templfile)
|
|
|
|
self.log.debug("printing with template: ", templfile)
|
|
|
|
templ = Template(filename=templfile)
|
|
|
|
templ = Template(filename=templfile)
|
|
|
|
htmlfile.write(templ.render_unicode(**kwargs))
|
|
|
|
htmlfile.write(templ.render_unicode(**kwargs))
|
|
|
|
htmlfile.close()
|
|
|
|
htmlfile.close()
|
|
|
@ -232,7 +240,7 @@ class Bureau(object):
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: make paper size a config variable
|
|
|
|
# TODO: make paper size a config variable
|
|
|
|
pdfpath = tempfile.mkstemp(".pdf")[1]
|
|
|
|
pdfpath = tempfile.mkstemp(".pdf")[1]
|
|
|
|
print("rendering with: ", self.html2pdf + htmlpath + " " + pdfpath)
|
|
|
|
self.log.debug("rendering with: ", self.html2pdf + htmlpath + " " + pdfpath)
|
|
|
|
subprocess.call(self.html2pdf + htmlpath + " " + pdfpath +
|
|
|
|
subprocess.call(self.html2pdf + htmlpath + " " + pdfpath +
|
|
|
|
" A4 1920px", shell=True)
|
|
|
|
" A4 1920px", shell=True)
|
|
|
|
subprocess.call("lpr " + pdfpath, shell=True)
|
|
|
|
subprocess.call("lpr " + pdfpath, shell=True)
|
|
|
@ -306,22 +314,22 @@ class Bureau(object):
|
|
|
|
time.sleep(0.05) # don't waste CPU
|
|
|
|
time.sleep(0.05) # don't waste CPU
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
print("got message:", msg)
|
|
|
|
self.log.debug("got message:", msg)
|
|
|
|
dot = msg.find(".")
|
|
|
|
dot = msg.find(".")
|
|
|
|
ref = msg[:dot]
|
|
|
|
ref = msg[:dot]
|
|
|
|
if (dot < len(msg) - 1) and (dot > 0):
|
|
|
|
if (dot < len(msg) - 1) and (dot > 0):
|
|
|
|
print("msg length:", len(msg))
|
|
|
|
self.log.debug("msg length:", len(msg))
|
|
|
|
print("dot at", dot)
|
|
|
|
self.log.debug("dot at", dot)
|
|
|
|
# TODO: maybe trim off the trailing "." for convenience
|
|
|
|
# TODO: maybe trim off the trailing "." for convenience
|
|
|
|
data = msg[dot + 1:]
|
|
|
|
data = msg[dot + 1:]
|
|
|
|
# data = str(data) # force to be a string
|
|
|
|
# data = str(data) # force to be a string
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
data = None
|
|
|
|
data = None
|
|
|
|
print("data: " + str(data))
|
|
|
|
self.log.debug("data: " + str(data))
|
|
|
|
except IndexError as err:
|
|
|
|
except IndexError as err:
|
|
|
|
print("invalid message: ", err)
|
|
|
|
self.log.warning("invalid message: ", err)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
print(("got method: " + ref))
|
|
|
|
self.log.debug(("got method: " + ref))
|
|
|
|
|
|
|
|
|
|
|
|
if (ref in self.commands) or (ref in self.api):
|
|
|
|
if (ref in self.commands) or (ref in self.api):
|
|
|
|
# catch TypeErrors for case of bogus params
|
|
|
|
# catch TypeErrors for case of bogus params
|
|
|
@ -346,12 +354,12 @@ class Bureau(object):
|
|
|
|
# print("invalid data for command '{}': {}".format(ref, data))
|
|
|
|
# print("invalid data for command '{}': {}".format(ref, data))
|
|
|
|
# self._recv.send_unicode("Error. Invalid or missing data.")
|
|
|
|
# self._recv.send_unicode("Error. Invalid or missing data.")
|
|
|
|
except KeyError as err:
|
|
|
|
except KeyError as err:
|
|
|
|
print(err)
|
|
|
|
self.log.warning(err)
|
|
|
|
print("You are calling a command as an API or vice-versa.")
|
|
|
|
self.log.warning("You are calling a command as an API or vice-versa.")
|
|
|
|
self._recv.send_unicode(
|
|
|
|
self._recv.send_unicode(
|
|
|
|
"Error. Command called as API or API as command.")
|
|
|
|
"Error. Command called as API or API as command.")
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
print("error! Command/API %s not found", ref)
|
|
|
|
self.log.warning("error! Command/API %s not found", ref)
|
|
|
|
self._recv.send_unicode("Error! Command/API not found.")
|
|
|
|
self._recv.send_unicode("Error! Command/API not found.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|