def start_autostarts(): global autostart_processlist, logger autostarts = {} sl = clixxIOProjectAutostarts() for sp in sl.keys(): p = QProcess() p.setWorkingDirectory(sl[sp]["directory"]) program = sl[sp]["command"] arguments = sl[sp]["arguments"].split(' ') logger.debug("Starting %s in %s with arguments %s" % (program,sl[sp]["directory"],arguments)) # Start the process running autostart_processlist.append(p) autostart_processlist[len(autostart_processlist)-1].start(program, arguments) for p in range(0,len(autostart_processlist)-1): logger.debug("PID=%d" % autostart_processlist[p].pid())
def asn2dataModel(*files): ''' Call asn1DataModel, including the Makefile.python and return the imported module "name_of_dataview_asn.py" From this module it is possible to create native Asn1scc instances of ASN.1 data types, and to access to DV.py, which contains constants such as the _PRESENT fields for choice selectors ''' assert len(files) > 0 # 1) Create a temporary directory for the output tempdir = tempfile.mkdtemp() sys.path.insert(0, tempdir) # Use a unique name for the asn1 concatenated module concat_prefix = str(uuid.uuid4()).replace('-', '_') concat_path = os.path.join(tempdir, concat_prefix) # 2) Concat all input files to the output directory cat_bin = spawn.find_executable('cat') args = list(files) cat = QProcess() LOG.debug(os.getcwd()) LOG.debug(cat_bin + ' ' + ' '.join(args)) cat.start(cat_bin, args) merged = waitfor_qprocess(cat, 'Merge dataviews') with open(concat_path + '.asn', 'wt') as merged_file: merged_file.write(merged) # 3) Run asn2dataModel asn2dm_bin = spawn.find_executable('asn2dataModel') args = ['-toPython', '-o', tempdir, concat_path + '.asn'] asn2dm = QProcess() LOG.debug(os.getcwd()) LOG.debug(asn2dm_bin + ' ' + ' '.join(args)) asn2dm.start(asn2dm_bin, args) waitfor_qprocess(asn2dm, 'DMT tool "asn2dataModel"') # 4) call make -f Makefile.python to build the .so make_bin = spawn.find_executable('make') args = ['-f', 'Makefile.python'] make = QProcess() make.setWorkingDirectory(tempdir) LOG.debug(os.getcwd()) LOG.debug(make_bin + ' ' + ' '.join(args)) make.start(make_bin, args) waitfor_qprocess(make, 'make -f Makefile.python') if concat_prefix in ASN2DM.viewkeys(): # Re-import module if it was already loaded asn1mod = ASN2DM[concat_prefix] reload(asn1mod) reload(asn1mod.DV) import Stubs reload(Stubs) else: asn1mod = importlib.import_module(concat_prefix + '_asn') # force reload of modules in case of multiple calls reload(asn1mod.DV) import Stubs reload(Stubs) ASN2DM[concat_prefix] = asn1mod sys.path.pop(0) return asn1mod
class CfdConsoleProcess: """ Class to run a console process asynchronously, printing output and errors to the FreeCAD console and allowing clean termination in Linux and Windows """ def __init__(self, finishedHook=None, stdoutHook=None, stderrHook=None): self.process = QProcess() self.finishedHook = finishedHook self.stdoutHook = stdoutHook self.stderrHook = stderrHook self.process.finished.connect(self.finished) self.process.readyReadStandardOutput.connect(self.readStdout) self.process.readyReadStandardError.connect(self.readStderr) self.print_next_error_lines = 0 self.print_next_error_file = False def __del__(self): self.terminate() def start(self, cmd, env_vars=None, working_dir=None): """ Start process and return immediately """ self.print_next_error_lines = 0 self.print_next_error_file = False env = QtCore.QProcessEnvironment.systemEnvironment() if env_vars: for key in env_vars: env.insert(key, env_vars[key]) self.process.setProcessEnvironment(env) if working_dir: self.process.setWorkingDirectory(working_dir) if platform.system() == "Windows": # Run through a wrapper process to allow clean termination cmd = [ os.path.join(FreeCAD.getHomePath(), "bin", "python.exe"), '-u', # Prevent python from buffering stdout os.path.join(os.path.dirname(__file__), "WindowsRunWrapper.py") ] + cmd print("Raw command: ", cmd) self.process.start(cmd[0], cmd[1:]) def terminate(self): if platform.system() == "Windows": # terminate() doesn't operate and kill() doesn't allow cleanup and leaves mpi processes running # Instead, instruct wrapper program to kill child process and itself cleanly with ctrl-break signal self.process.write(b"terminate\n") self.process.waitForBytesWritten() # 'flush' else: self.process.terminate() self.process.waitForFinished() def finished(self, exit_code): if self.finishedHook: self.finishedHook(exit_code) def readStdout(self): # Ensure only complete lines are passed on text = "" while self.process.canReadLine(): byteArr = self.process.readLine() text += QTextStream(byteArr).readAll() if text: print(text, end='') # Avoid displaying on FreeCAD status bar if self.stdoutHook: self.stdoutHook(text) # Must be at the end as it can cause re-entrance if FreeCAD.GuiUp: FreeCAD.Gui.updateGui() def readStderr(self): # Ensure only complete lines are passed on # Print any error output to console self.process.setReadChannel(QProcess.StandardError) text = "" while self.process.canReadLine(): byteArr = self.process.readLine() text += QTextStream(byteArr).readAll() if text: if self.stderrHook: self.stderrHook(text) FreeCAD.Console.PrintError(text) # Must be at the end as it can cause re-entrance if FreeCAD.GuiUp: FreeCAD.Gui.updateGui() self.process.setReadChannel(QProcess.StandardOutput) def state(self): return self.process.state() def waitForStarted(self): return self.process.waitForStarted() def waitForFinished(self): # For some reason waitForFinished doesn't always return - so we resort to a failsafe timeout: while True: ret = self.process.waitForFinished(1000) if self.process.error() != self.process.Timedout: self.readStdout() self.readStderr() return ret if self.process.state() == self.process.NotRunning: self.readStdout() self.readStderr() return True def exitCode(self): return self.process.exitCode() def processErrorOutput(self, err): """ Process standard error text output from OpenFOAM :param err: Standard error output, single or multiple lines :return: A message to be printed on console, or None """ ret = "" errlines = err.split('\n') for errline in errlines: if len(errline) > 0: # Ignore blanks if self.print_next_error_lines > 0: ret += errline + "\n" self.print_next_error_lines -= 1 if self.print_next_error_file and "file:" in errline: ret += errline + "\n" self.print_next_error_file = False words = errline.split(' ', 1) # Split off first field for parallel FATAL = "--> FOAM FATAL ERROR" FATALIO = "--> FOAM FATAL IO ERROR" if errline.startswith(FATAL) or (len(words) > 1 and words[1].startswith(FATAL)): self.print_next_error_lines = 1 ret += "OpenFOAM fatal error:\n" elif errline.startswith(FATALIO) or ( len(words) > 1 and words[1].startswith(FATALIO)): self.print_next_error_lines = 1 self.print_next_error_file = True ret += "OpenFOAM IO error:\n" if len(ret) > 0: return ret else: return None