def testRpc(rpc, name): try: rpc.getbestblockhash() except ConnectionRefusedError as e: log.crit("%s RPC connection refused: %s" % (name, e)) except JSONRPCException as e: log.crit("%s RPC error: %s" % (name, e))
def run(self, job): """ """ super(Vector, self).run(job) # Generate HPGL text log.info('Generating HPGL information from input file.') hpgl = pstoedit.execute(job.file) if hpgl.strip() == '': # No HPGL text generated error and quit. log.crit('No vector information found in input file from cups.') sys.exit(1) if config.debug: # Debug is enabled so dump hpgl to filesystem. hpgl_file = "%s_%s_%s.hpgl" % (os.getenv('PRINTER'), job.number, os.getpid()) out_filename = config.tmp_dir + hpgl_file out_file = open(out_filename, 'w') os.fchmod(out_file.fileno(), 0666) out_file.write(hpgl) out_file.close() # Close the job's file as its no longer needed. job.file.close() # Send data to the device. self.send(hpgl) # Successfully completed printed job. log.info("Job %s printed." % job)
def rotate(pdf_file): """ Execute the pdftk command to rotate the document returning the rotated document in a buffer. """ args = [config.pdftk, "-", "cat", "endE", "output", "-", ] log.debug("Executing pdftk process with args: %s" % args) process = subprocess.Popen(args, cwd=config.tmp_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) (stdoutdata, stderrdata) = process.communicate(pdf_file.read()) process.wait() if process.returncode != 0: log.crit("pdftk failed during execution with returncode = %s." % process.returncode) sys.exit(1) else: # Collect the outputted text. rotated_pdf = StringIO(stdoutdata) # Return the text. return rotated_pdf
def execute(in_file, resolution, width, height, raster_mode): """ Execute the ghostscript command on the given in_file generating out raster and vector information with the given resolution. Width and height should be specified in pts. Raster_mode is one of: none, mono, grey, color """ raster_tmpfile = tempfile.NamedTemporaryFile() # Convert width and height to DPI. width = (width/72) * resolution height = (height/72) * resolution args = [config.gs, "-q", "-dBATCH", "-dNOPAUSE", "-r%s" % resolution, "-g%dx%d" % (width, height), "-sDEVICE=%s" % raster_mode, "-sOutputFile=%s" % raster_tmpfile.name, "-", ] # Execute ghostscript log.debug("Opening ghostscript process with args: %s" % args) process = subprocess.Popen(args, cwd=config.tmp_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) (stdoutdata, stderrdata) = process.communicate(in_file.read()) log.debug("Waiting on ghostscript to terminate.") process.wait() # Check that ghostscript functioned correctly. if process.returncode != 0: log.crit("Ghostscript failed during execution with returncode = %s." % process.returncode) # Get raster information into a StringIO log.debug("Rewinding ghostscript raster output and storing it in StringIO") raster_tmpfile.seek(0) raster = raster_tmpfile # Gather the vector information into a StringIO log.debug("Gathering the vector output from ghostscript.") vector = StringIO() vector.write(stdoutdata) vector.seek(0) log.debug("Returning ghostscript raster and vector output.") return (raster, vector)
def send(self, data): """ Send data to the printer. This dispatches data over the network or over a serial port depending upon the device uri. """ if self.host: self.send_network(data) elif self.serial: self.send_serial(data) else: log.crit("Failed to send data to device.") log.crit("Device specified is attached via network or serial.") sys.exit(1)
def timerEvent(): while True: mutexEvents.acquire() curTime = time.time() for ev in T.events: if curTime - ev.time >= 0: log.info("Triggering timer for \"%s\" %i" % (ev.name, ev.node)) if curTime - ev.time >= 1: log.crit("Trigger is late by %i sec!" % (curTime - ev.time)) T.callback_func(2, ev.node, 0, (ev.name, )) T.events.remove(ev) mutexEvents.release() time.sleep(1)
def execute( self, handler_name, update={}, return_mode=None ): """ During program execution this will call the individual handlers. It is called from execute program for every target and dependency, and can be called by handlers themselves. For each handler, the implements resolving variable names from the function signature to runtime values XXX IProgramHandler, and processing of the returned arguments with the help of IProgramHandlerResultProc. The return is always integreated with the current XXX IProgram return_mode specifies how the handler return value is processed by the result adapter. Currently the 'first:' prefix determines that the first named keywords is to be `return`\ 'ed. XXX: It should offer various methods of filter and either generate, return or be silent. """ log.debug("SimpleCommand.execute %s %s", handler_name, update) if update: self.globaldict.update(update) handler = getattr( self, handler_name ) args, kwds = self.select_kwds(handler, self.globaldict) log.debug("SimpleCommand.execute %s, %r, %r", handler.__name__, repr(args), repr(kwds)) try: ret = handler(*args, **kwds) except Exception as e: log.crit("Exception in handler %s: %s", handler_name, e) traceback.print_exc() raise e # XXX: result_adapter = HandlerReturnAdapter( self.globaldict ) #if isinstance( result_adapter, basestring ): # result_adapter = getUtility(IResultAdapter, name=result_adapter) if return_mode: result_adapter.set_return_mode( return_mode ) g = result_adapter.start( ret ) if result_adapter.generates: return g for res in g: # XXX extracted.append(res) for reporter in self.globaldict.prog.output: reporter.append(res) if result_adapter.returns: return result_adapter.generated
def raster_mode_to_ghostscript(mode): """ Given a raster mode return the ghostscript mode. """ if mode == 'mono': return 'pngmono' if mode in ['gray', 'grey']: return 'pnggray' elif mode in ['color', 'colour']: return 'png16m' elif mode == 'none': return None else: log.crit("Invalid raster mode %s specified." % mode) sys.exit(1)
def hostname_find(args, sa=None): if not args: import socket hostnamestr = socket.gethostname() else: hostnamestr = args.pop(0) if not hostnamestr: return if not sa: log.crit("No session, cannot retrieve anything!") return try: name = sa\ .query(Name)\ .filter(Name.name == hostnamestr).one() except NoResultFound, e: name = None
def execute(in_file, xscale=config.xscale, yscale=config.yscale): """ Execute pstoedit returning the generated HPGL to the calling function. """ # Arguments to pass to pstoedit args = [config.pstoedit, "-f", config.pstoedit_format, "-dt", # Draw the text rather than assume cutter can handle text "-pta", # Precision text spacing (spaces handled gracefully) "-xscale", "%s" % xscale, "-yscale", "%s" % yscale, "-", ] # Execute pstoedit process = subprocess.Popen(args, cwd=config.tmp_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) (stdoutdata, stderrdata) = process.communicate(in_file.read()) process.wait() # Check that pstoedit functioned correctly. if process.returncode != 0: log.crit("pstoedit failed during execution with returncode = %s." % process.returncode) # Printing out stdout and stderr log.debug("Standard output for pstoedit was:") out = StringIO(stdoutdata) for line in out.readlines(): log.debug(line) out = StringIO(stderrdata) log.debug("Standard error for pstoedit was:") for line in out.readlines(): log.debug(line) sys.exit(1) else: # Collect the outputted text. text = stdoutdata # Return the text. return text
def page_size(pdf_file): """ Discover page size of a pdf document through the usage of the pdfinfo external command. Note that this functionality will not work properly with Python StringIO buffers as they do not have proper file handles so instead we utilize a named tempfile. """ # Create the tmp file. tmp_file = tempfile.NamedTemporaryFile() # Write pdf contents to tmp_file tmp_file.write(pdf_file.read()) # Rewind pdf_file and tmp_file. pdf_file.seek(0) tmp_file.seek(0) args = [config.pdfinfo, tmp_file.name, ] log.debug("Executing pdfinfo process with args: %s." % args) process = subprocess.Popen(args, cwd=config.tmp_dir, stdout=subprocess.PIPE) (stdoutdata, stderrdata) = process.communicate() process.wait() tmp_file.close() if process.returncode != 0: log.crit("pdfinfo failed during execution with returncode = %s." % process.returncode) sys.exit(1) else: width = None height = None buf = StringIO(stdoutdata) # Get the page size from the stdout data. for line in buf.readlines(): if line.startswith('Page size:'): match = re.search('^Page size: +(\d+) x (\d+) pts', line) groups = match.groups() width = int(groups[0]) height = int(groups[1]) return (width, height)
def findCompetingAnchors(cfg, rpc, myFeeRate, alreadyChecked, repeatingChecks): competingList = [] txInfos = rpc.getrawmempool(True) for txid, txInfo in txInfos.items(): if txid in alreadyChecked: continue if not "vsize" in txInfo: log.crit("incompatible BTC RPC version (getrawmempool.vsize field not found)") if not "fees" in txInfo: log.crit("incompatible BTC RPC version (getrawmempool.fees field not found)") alreadyChecked[txid] = True # check competing conditions. check it first because it's cheap feeRate = int((txInfo["fees"]["base"] * 100000000 * 1000) / Decimal(txInfo["vsize"]))/Decimal(100000000) age = time.time() - txInfo["time"] isCompetingFeeRate = feeRate * Decimal(cfg.Competing.FeeRateAdvantage) > myFeeRate isCompetingAge = age < cfg.Competing.TxTimeout if cfg.Competing.Mode == "OneOf" and (not isCompetingFeeRate or not isCompetingAge): continue # not competing if cfg.Competing.Mode == "AllOf" and (not isCompetingFeeRate and not isCompetingAge): continue # not competing # request full tx to check is it anchor tx try: tx = rpc.getrawtransaction(txid, True) except: continue # not found due to race condition if not isAnchorTx(cfg, tx): continue competingList.append(txid) # the check above took very long, so check new transactions which were received during the check (a few times). # the most time takes getrawtransaction, so each subsequent check will take much less time because only new transactions are checked if repeatingChecks != 0: competingList = competingList + findCompetingAnchors(cfg, rpc, myFeeRate, alreadyChecked, repeatingChecks - 1) return competingList
def txs_session(prog=None, sa=None, opts=None, settings=None): # default SA session dbref = opts.dbref if opts.init: log.debug("Initializing SQLAlchemy session for %s", dbref) sa = SessionMixin.get_session('default', opts.dbref, opts.init) # Host hostnamestr = current_hostname(opts.init, opts.interactive) if opts.init: hostname = hostname_find([hostnamestr], sa) assert not hostname or not isinstance(hostname, (tuple, list)), hostname if not hostname: log.note("New Name: %s", hostnamestr) hostname = Name( name=hostnamestr, date_added=datetime.now()) hostname.commit() else: log.warn("Name exists: %s", hostname) assert hostname host = host_find([hostname], sa) if not host: log.note("New Host: %s", hostnamestr) host = Host( hostname=hostname, date_added=datetime.now()) host.commit() else: log.warn("Host exists: %s", host) assert host else: host, name = sa.query(Host, Name)\ .join('hostname')\ .filter(Name.name == hostnamestr).one() if not host: log.crit("Could not get host") urlresolver = LocalPathResolver(host, sa) log.info("On %s", host) yield Keywords(sa=sa, ur=urlresolver)
def to_ps(pdf_file): """ Convert a pdf file to a postscript file. """ args = [config.pdf2ps, "-", "-", ] log.debug("Executing pdf2ps to convert pdf to ps with args: %s." % args) process = subprocess.Popen(args, cwd=config.tmp_dir, stdout=subprocess.PIPE, stdin=subprocess.PIPE) (stdoutdata, stderrdata) = process.communicate(pdf_file.read()) process.wait() if process.returncode != 0: log.crit("pdf2ps failed during execution with returncode = %s." % process.returncode) sys.exit(1) else: # Collect the outputted text. ps_file = StringIO(stdoutdata) # Return the text. return ps_file
def mustLoad(cfgPath): try: cfg = Config(toml.load(cfgPath)) checkConfig(cfg) except KeyError as e: log.crit("%s: config field not found: %s" % (cfgPath, e)) except AttributeError as e: log.crit("%s: config field not found: %s" % (cfgPath, e)) except Exception as e: log.crit("%s parsing error: %s" % (cfgPath, e)) return cfg
def add_genre(self, genre, supergenre, opts=None, sa=None): log.crit("TODO add genre %s %s", genre, supergenre)
def parse_device_uri(self, device_uri): """ Parse the device_uri options. """ log.info('Parsing device options.') match = re.search('([A-Za-z\-0-9]+)://([A-Za-z\-0-9\.:]+)/(.*?)', device_uri) if not match: log.crit("Could not parse the device settings specified by cups.") sys.exit(1) # First parameter is the backend name. self.backend = match.group(1) # Second parameter is the name of either the serial or network device # to use. self.name = match.group(2) # Setup variables for serial, host, and port. self.serial = None self.host = None self.port = None # Check to see if device is a serial port filename = config.device_dir + self.name if utils.is_serial_port(filename): self.serial = filename elif utils.is_host(self.name): self.host, self.port = utils.hostname_port(self.name) if not self.port: log.debug("Port information not provided in device name.") log.debug("Setting socket port to default %d." % config.socket_port) self.port = config.socket_port else: log.crit("Device named %s is neither serial not host." % self.name) sys.exit(1) match = re.search('([A-Za-z\-0-9]+)://([A-Za-z\-0-9.]+)/(.*)', device_uri) self.options = {} try: settings = match.group(3).split('/') for option in settings: if option: (key, value) = option.split('=') value = value.lower() # Handle values that are booleans. if value in ['1', 't', 'true']: self.options[key] = True continue elif value in ['0', 'f', 'false']: self.options[key] = False continue # Handle values that are integers. try: self.options[key] = int(value) continue except ValueError: pass # Handle values all other values. self.options[key] = value except AttributeError: pass
def anchor(cfg, checkProfit, checkCompeting, createAnchor, sendAnchor): # Open RPC connections dfi = openRpc(cfg.DFI.RPC, None) btc = openRpc(cfg.BTC.RPC, cfg.BTC.Wallet.WalletName) # Check RPC connection testRpc(dfi, "DeFi") testRpc(btc, "Bitcoin") # Get BTC feerate feeRate = getFeeRate(cfg.BTC.Wallet.FeeRate, btc) if checkCompeting: log.info("checking competing anchors in BTC mempool") competingTxs = findCompetingAnchors(cfg.DFI.Anchoring, btc, feeRate, {}, 3) if competingTxs: log.crit("competing anchors present in mempool: %s" % competingTxs) log.success("ok\n") else: log.warning("skip checking competing anchors in BTC mempool\n") log.info("requesting anchor template from DeFi RPC") template = dfi.spv_createanchortemplate(cfg.DFI.Anchoring.RewardAddress) log.info("* DeFi block : %s" % template["defiHash"]) log.info("* potential reward: %s DFI" % template["estimatedReward"]) log.success("ok\n") if checkProfit: log.info("checking minimum profit conditions") err = checkMinimumProfit(cfg.DFI.Anchoring.Profit, template) if err: log.crit("Minimum profit conditions not met: %s" % err) log.success("ok\n") else: log.warning("skip checking minimum profit conditions\n") if not createAnchor: log.warning("skip creation of anchor transaction\n") return log.info("creation of anchor transaction") try: outsLen = len(btc.decoderawtransaction(template["txHex"])["vout"]) fundedTx = btc.fundrawtransaction(template["txHex"], {"feeRate": feeRate, "changePosition": outsLen}) except Exception as e: log.crit("failed to fund transaction: %s" % e) try: signedTx = btc.signrawtransactionwithwallet(fundedTx["hex"]) if signedTx["complete"] == False: raise Exception("not all addresses are known") except Exception as e: log.crit("failed to sign transaction: %s" % e) log.success("ok\n") if not sendAnchor: log.warning("skip sending anchor transaction") return # Send anchor tx log.info("sending anchor transaction") txid = btc.sendrawtransaction(signedTx["hex"]) log.info("* BTC anchor transaction: %s" % txid) log.info("* DeFi block : %s" % template["defiHash"]) log.info("* potential reward : %s DFI" % template["estimatedReward"]) log.success("ok\n")
def run(self, job): """ Execute the process of sending a job to the laser cutter. """ super(LaserCutter, self).run(job) # First check the job file to determine if it is postscript of pdf. if job.is_pdf(): # Gather info on pdf's page size. (width, height) = pdf.page_size(job.file) log.info("Job sent to cups has width = %s and height = %s" % (width, height)) if width == self.height and height == self.width: # We have a rotated job. Rotate pdf to normal layout for laser # cutter's bed. log.info("Rotating pdf file.") job.file = pdf.rotate(job.file) if self.debug: # Debug is enabled so output rotated pdf file. out_filename = "%s_rotated.pdf" % self.debug_basename(job) self.debug_write(out_filename, job.file) # Convert pdf file to ps file. log.info("Converting pdf file to postscript.") job.file = pdf.to_ps(job.file) if self.debug: # Debug enabled so writing the generated ps file. out_filename = "%s.ps" % self.debug_basename(job) self.debug_write(out_filename, job.file) elif job.is_ps(): pass else: log.crit("Input file is neither pdf nor postscript.") sys.exit(1) # Convert postscript to eps. log.info('Converting input postscript to EPS.') eps = ps_to_eps(job.file, self.width, self.height) if self.debug: # Debug enabled so writing the generated eps file. out_file = "%s.eps" % self.debug_basename(job) self.debug_write(out_filename, eps) # run ghostscript on eps log.info('Running ghostscript on eps file.') (raster, vector) = ghostscript.execute( eps, self.resolution, self.width, self.height, ghostscript.raster_mode_to_ghostscript(self.raster_mode)) # convert image data to pcl log.info('Converting image data to PCL.') pcl = self.raster_to_pcl(raster) # convert vector data to hpgl log.info('Converting ghostscript vector data to HPGL') hpgl = self.vector_to_hpgl(vector) # send to printer log.info('Sending data to printer.') self.send(self.hpgl_pcl_to_pjl(job, hpgl, pcl)) # Successfully completed printing job. log.info("Job %s printed." % job)