class ProcessHostapd(QObject): statusAP_connected = pyqtSignal(object) def __init__(self,cmd): QObject.__init__(self) self.cmd = cmd def getNameThread(self): return '[New Thread {} ({})]'.format(self.procHostapd.pid(),self.objectName()) @pyqtSlot() def read_OutputCommand(self): self.data = str(self.procHostapd.readAllStandardOutput()) if 'AP-STA-DISCONNECTED' in self.data.rstrip() or 'inactivity (timer DEAUTH/REMOVE)' in self.data.rstrip(): self.statusAP_connected.emit(self.data.split()[2]) def start(self): self.makeLogger() self.procHostapd = QProcess(self) self.procHostapd.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procHostapd, SIGNAL('readyReadStandardOutput()'), self, SLOT('read_OutputCommand()')); self.procHostapd.start(self.cmd.keys()[0],self.cmd[self.cmd.keys()[0]]) print '[New Thread {} ({})]'.format(self.procHostapd.pid(),self.objectName()) def makeLogger(self): setup_logger('hostapd', './Logs/AccessPoint/requestAP.log') self.log_hostapd = logging.getLogger('hostapd') def stop(self): print 'Thread::[{}] successfully stopped.'.format(self.objectName()) if hasattr(self,'procHostapd'): self.procHostapd.terminate() self.procHostapd.waitForFinished() self.procHostapd.kill()
class ProcessThread(QObject): _ProcssOutput = pyqtSignal(object) def __init__(self,cmd,): QObject.__init__(self) self.cmd = cmd def getNameThread(self): return '[New Thread {} ({})]'.format(self.procThread.pid(),self.objectName()) @pyqtSlot() def readProcessOutput(self): self.data = str(self.procThread.readAllStandardOutput()) self._ProcssOutput.emit(self.data) def start(self): self.procThread = QProcess(self) self.procThread.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procThread, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()')) self.procThread.start(self.cmd.keys()[0],self.cmd[self.cmd.keys()[0]]) print '[New Thread {} ({})]'.format(self.procThread.pid(),self.objectName()) def stop(self): print 'Thread::[{}] successfully stopped.'.format(self.objectName()) if hasattr(self,'procThread'): self.procThread.terminate() self.procThread.waitForFinished() self.procThread.kill()
def process_file(self): """ Converts PDF pages to tif files, Uses ghostscript from the command line """ process = QProcess() process.start(' '.join([ self.gscriptpath + '\gswin32c.exe"', #gs exe '-q', '-dNOPAUSE', '-dBATCH', # resolution/dpi '-r{0}x{0}'.format(self.res), # container type, see gs docs '-sDEVICE={0}'.format(self.mode), '-sPAPERSIZE=a4', # page size '-sOutputFile=%s %s' % (str(self.ofname), str(self.ifname))])) # don't spawn cmd window process.waitForFinished(-1)
class ThreadDNSspoofNF(QObject): DnsReq = pyqtSignal(object) def __init__(self,domains,interface,redirect,APmode=True,parent=None): super(ThreadDNSspoofNF, self).__init__(parent) self.domains = domains self.interface = interface self.redirect = redirect self.APmode = APmode self.desc = 'DNS spoof Module::NetFilter' @pyqtSlot() def readProcessOutput(self): self.data = str(self.procThreadDNS.readAllStandardOutput()) self.DnsReq.emit(self.data) def start(self): self.setIptables(self.APmode,option='A') self.procThreadDNS = QProcess(self) self.procThreadDNS.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procThreadDNS, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()')) self.procThreadDNS.start('python',['core/packets/dnsspoofNF.py','-r',self.redirect, '-d',','.join(self.domains)]) def setIptables(self,APMode=True, option=str()): if APMode: system('iptables -{} INPUT -i {} -p udp --dport 53 -s {} -j ACCEPT'.format(option,self.interface,self.redirect)) system('iptables -{} INPUT -i {} -p udp --dport 53 -j DROP'.format(option,self.interface)) system('iptables -t nat -{} PREROUTING -p udp --dport 53 -j NFQUEUE'.format(option)) def stop(self): self.setIptables(self.APmode,option='D') if hasattr(self,'procThreadDNS'): self.procThreadDNS.terminate() self.procThreadDNS.waitForFinished() self.procThreadDNS.kill()
def translate(path): files = [] tsfiles = [] for name in os.listdir(path): if name.endswith((".py", ".pyw")): files.append(os.path.join(path, name)) elif name.endswith(".ts"): tsfiles.append(os.path.join(path, name)) if not tsfiles: return verbose = "-verbose" if Verbose else "" silent = "-silent" if not Verbose else "" process = QProcess() for ts in tsfiles: qm = ts[:-3] + ".qm" command1 = PYLUPDATE4 args1 = [verbose] + files + ["-ts", ts] command2 = LRELEASE args2 = [silent, ts, "-qm", qm] if Debug: print("updated", ts) print("generated", qm) else: process.start(command1, args1) if not process.waitForFinished(2 * 60 * 1000): print("failed", command1, " ".join(args1)) process.start(command2, args2) if not process.waitForFinished(2 * 60 * 1000): print("failed", command2, " ".join(args2))
def translate(path): files = [] tsfiles = [] for name in os.listdir(path): if name.endswith((".py", ".pyw")): files.append(os.path.join(path, name)) elif name.endswith(".ts"): tsfiles.append(os.path.join(path, name)) if not tsfiles: return verbose = "-verbose" if Verbose else "" silent = "-silent" if not Verbose else "" process = QProcess() for ts in tsfiles: qm = ts[:-3] + ".qm" command1 = PYLUPDATE4 args1 = [verbose] + files + ["-ts", ts] command2 = LRELEASE args2 = [silent, ts, "-qm", qm] if Debug: print("updated", ts) print("generated", qm) else: process.start(command1, args1) if not process.waitForFinished(2 * 60 * 1000): print("failed", command1, " ".join(args1)) process.start(command2, args2) if not process.waitForFinished(2 * 60 * 1000): print("failed", command2, " ".join(args2))
class ThreadDNSspoofNF(QObject): DnsReq = pyqtSignal(object) def __init__(self,domains,interface,redirect,APmode=True,parent=None): super(ThreadDNSspoofNF, self).__init__(parent) self.domains = domains self.interface = interface self.redirect = redirect self.APmode = APmode self.desc = 'DNS spoof Module::NetFilter' @pyqtSlot() def readProcessOutput(self): self.data = str(self.procThreadDNS.readAllStandardOutput()) self.DnsReq.emit(self.data) def start(self): self.setIptables(self.APmode,option='A') self.procThreadDNS = QProcess(self) self.procThreadDNS.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procThreadDNS, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()')) self.procThreadDNS.start('python',['Core/packets/dnsspoofNF.py','-r',self.redirect, '-d',','.join(self.domains)]) def setIptables(self,APMode=True, option=str()): if APMode: system('iptables -{} INPUT -i {} -p udp --dport 53 -s {} -j ACCEPT'.format(option,self.interface,self.redirect)) system('iptables -{} INPUT -i {} -p udp --dport 53 -j DROP'.format(option,self.interface)) system('iptables -t nat -{} PREROUTING -p udp --dport 53 -j NFQUEUE'.format(option)) def stop(self): self.setIptables(self.APmode,option='D') if hasattr(self,'procThreadDNS'): self.procThreadDNS.terminate() self.procThreadDNS.waitForFinished() self.procThreadDNS.kill()
class ThreadLogger(QObject): def __init__(self, logger_path=str): QObject.__init__(self) self.logger_path = logger_path @pyqtSlot() def readProcessOutput(self): try: self.emit( SIGNAL('Activated( QString )'), str(self.procLogger.readAllStandardOutput()).rstrip().split( ' : ')[1]) except Exception: pass def start(self): self.procLogger = QProcess(self) self.procLogger.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procLogger, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()')) self.procLogger.start('tail', ['-f', self.logger_path]) def stop(self): if hasattr(self, 'procLogger'): self.procLogger.terminate() self.procLogger.waitForFinished() self.procLogger.kill()
class ProcessThread(QObject): _ProcssOutput = pyqtSignal(object) def __init__( self, cmd, ): QObject.__init__(self) self.cmd = cmd def getNameThread(self): return '[New Thread {} ({})]'.format(self.procThread.pid(), self.objectName()) @pyqtSlot() def readProcessOutput(self): self.data = str(self.procThread.readAllStandardOutput()) self._ProcssOutput.emit(self.data) def start(self): self.procThread = QProcess(self) self.procThread.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procThread, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()')) self.procThread.start(self.cmd.keys()[0], self.cmd[self.cmd.keys()[0]]) print '[New Thread {} ({})]'.format(self.procThread.pid(), self.objectName()) def stop(self): print 'Thread::[{}] successfully stopped.'.format(self.objectName()) if hasattr(self, 'procThread'): self.procThread.terminate() self.procThread.waitForFinished() self.procThread.kill()
class QProcessTransport(Transport): '''A Transport communicating with a child process. Start the process using .start(). Sent data is written to the process' stdin. Data is received from the process's stdout and processed on the Qt mainloop thread. ''' shorthand='qprocess' @classmethod def fromstring(cls, expression): '''qprocess:(<commandline>)''' _, _, expr = expression.partition(':') cmdline, _, _ = paren_partition(expr) return cls(cmdline, sendername=expression) def __init__(self, cmdline, sendername='qprocess'): self.cmdline = cmdline self.sendername = sendername self.leftover = b'' self.process = QProcess() self.process.readyRead.connect(self.on_ready_read) self.process.finished.connect(self.on_finished) def start(self): L().debug('starting: %r'%self.cmdline) self.process.start(self.cmdline) def stop(self, kill=False): if kill: self.process.kill() else: self.process.terminate() self.process.waitForFinished() def send(self, data, receivers=None): if receivers is not None and self.sendername not in receivers: return L().debug('message to child processs: %s'%data) self.process.write(data.decode('utf8')) def on_ready_read(self): data = self.process.readAllStandardOutput().data() errors = self.process.readAllStandardError().data().decode('utf8') if errors: L().error('Error from child process:\n%s' % errors) pdata = data.decode('utf8') if len(pdata) > 100: pdata = pdata[:100] + '...' #if pdata.startswith('{'): L().debug('message from child process: %s'%pdata) self.leftover = self.received( sender=self.sendername, data=self.leftover + data ) def on_finished(self): L().info('Child process exited.')
class ProcessThread(QObject): def __init__(self,cmd,): QObject.__init__(self) self.cmd = cmd def getNameThread(self): return 'Starting Thread:' + self.objectName() @pyqtSlot() def readProcessOutput(self): self.data = str(self.procThread.readAllStandardOutput()) def start(self): print 'Starting Thread:' + self.objectName() self.procThread = QProcess(self) self.procThread.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procThread, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()')) self.procThread.start(self.cmd.keys()[0],self.cmd[self.cmd.keys()[0]]) def stop(self): print 'Stop thread:' + self.objectName() if hasattr(self,'procThread'): self.procThread.terminate() self.procThread.waitForFinished() self.procThread.kill()
class WorkThread(QThread): def __init__(self): QThread.__init__(self) self.process = QProcess() self.cmd = None self.process.readyReadStandardOutput.connect(self.readOutput) self.process.readyReadStandardError.connect(self.readErrors) self.process.finished.connect(self.fini) def fini(self,no): self.emit(SIGNAL("fini"),no,self.cmd) def setCmd(self,val): self.cmd = val def kill_process(self): self.process.kill() def close_process(self): self.process.close() def run(self): if(self.process.isOpen()): self.process.close() #print "open" #self.process.kill() self.process.start(self.cmd) else: #print "strgin" self.process.start(self.cmd) self.exec_() self.process.waitForFinished() self.process.kill() #self.procDone.emit(True) def run2(self): if(self.process.isOpen()): self.process.close() #print "open" #self.process.kill() self.process.start(self.cmd) else: #print "strgin" self.process.start(self.cmd) self.exec_() #self.process.kill() def readOutput(self): self.emit(SIGNAL("update"),str(self.process.readAllStandardOutput())) def readErrors(self): self.emit(SIGNAL("update"),str(self.process.readAllStandardError())) def __del__(self): self.wait()
class ProcessHostapd(QObject): statusAP_connected = pyqtSignal(object) statusAPError = pyqtSignal(object) def __init__(self, cmd, session): QObject.__init__(self) self.cmd = cmd self.session = session self.errorAPDriver = ('AP-DISABLED', 'Failed to initialize interface', 'nl80211 driver initialization failed.', 'errors found in configuration file') def getNameThread(self): return '[New Thread {} ({})]'.format(self.procHostapd.pid(), self.objectName()) @pyqtSlot() def read_OutputCommand(self): self.data = str(self.procHostapd.readAllStandardOutput()) if 'AP-STA-DISCONNECTED' in self.data.rstrip( ) or 'inactivity (timer DEAUTH/REMOVE)' in self.data.rstrip(): self.statusAP_connected.emit(self.data.split()[2]) self.log_hostapd.info(self.data) for error in self.errorAPDriver: if self.data.find(error) != -1: return self.statusAPError.emit(self.data) def start(self): self.makeLogger() self.procHostapd = QProcess(self) self.procHostapd.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procHostapd, SIGNAL('readyReadStandardOutput()'), self, SLOT('read_OutputCommand()')) self.procHostapd.start(self.cmd.keys()[0], self.cmd[self.cmd.keys()[0]]) print '[New Thread {} ({})]'.format(self.procHostapd.pid(), self.objectName()) def makeLogger(self): setup_logger('hostapd', C.LOG_HOSTAPD, self.session) self.log_hostapd = logging.getLogger('hostapd') def stop(self): print 'Thread::[{}] successfully stopped.'.format(self.objectName()) if hasattr(self, 'procHostapd'): QObject.disconnect(self.procHostapd, SIGNAL('readyReadStandardOutput()'), self, SLOT('read_OutputCommand()')) self.procHostapd.terminate() self.procHostapd.waitForFinished() self.procHostapd.kill()
def run_command(cmd, args): process = QProcess() process.start(cmd, args) if not process.waitForFinished(): return "" output = process.readAllStandardOutput() return fromByteArray(output).strip()
def setOptions(self, colormode_index, quality_index, papertype_index, papersize_index, custom_size=[]): color_mode = self.color_modes[colormode_index] quality = self.quality_modes[quality_index] paper_type = self.paper_types[papertype_index] paper_size = self.paper_sizes[papersize_index] if paper_size == 'Custom.WIDTHxHEIGHT': paper_size = 'Custom.%ix%imm' % (custom_size[0], custom_size[1]) lpoptions_args = [ '-p', self.printer, '-o', 'ColorModel=' + color_mode, '-o', 'cupsPrintQuality=' + quality, '-o', "MediaType=" + paper_type, '-o', 'PageSize=' + paper_size ] print('lpoptions', ' '.join(lpoptions_args)) process = QProcess() process.start('lpoptions', lpoptions_args) if not process.waitForFinished(): print("Error : Could not execute lpoptions") return False return True
def __pack_cpk(self, csv, cpk): self.progress.setValue(0) self.progress.setMaximum(1000) self.progress.setLabelText("Building %s" % cpk) process = QProcess() process.start("tools/cpkmakec", [csv, cpk, "-align=2048", "-mode=FILENAME"]) percent = 0 while not process.waitForFinished(100): output = QString(process.readAll()) output = output.split("\n", QString.SkipEmptyParts) for line in output: line = common.qt_to_unicode(line) match = OUTPUT_RE.search(line) if match == None: continue percent = float(match.group(1)) * 1000 self.progress.setValue(percent) percent += 1
def build(path): for name in os.listdir(path): source = os.path.join(path, name) target = None if source.endswith(".ui"): target = os.path.join(path, "ui_" + name.replace(".ui", ".py")) command = PYUIC4 elif source.endswith(".qrc"): target = os.path.join(path, "qrc_" + name.replace(".qrc", ".py")) command = PYRCC4 process = QProcess() if target is not None: if not os.access(target, os.F_OK) or ( os.stat(source)[stat.ST_MTIME] > os.stat(target)[stat.ST_MTIME]): args = ["-o", target, source] if Debug: print("# {0} -o {1} {2}".format(command, target, source)) else: process.start(command, args) if not process.waitForFinished(2 * 60 * 1000): print("failed", command, " ".join(args)) else: print(source, "->", target) elif Verbose: print(source, "is up-to-date")
def build(path): for name in os.listdir(path): source = os.path.join(path, name) target = None if source.endswith(".ui"): target = os.path.join(path, "ui_" + name.replace(".ui", ".py")) command = PYUIC4 elif source.endswith(".qrc"): target = os.path.join(path, "qrc_" + name.replace(".qrc", ".py")) command = PYRCC4 process = QProcess() if target is not None: if not os.access(target, os.F_OK) or (os.stat(source)[stat.ST_MTIME] > os.stat(target)[stat.ST_MTIME]): args = ["-o", target, source] if Debug: print("# {0} -o {1} {2}".format(command, target, source)) else: process.start(command, args) if not process.waitForFinished(2 * 60 * 1000): print("failed", command, " ".join(args)) else: print(source, "->", target) elif Verbose: print(source, "is up-to-date")
def __pack_cpk(self, csv, cpk): self.progress.setValue(0) self.progress.setMaximum(100000) self.progress.setLabelText("Building %s" % cpk) process = QProcess() process.start("tools/cpkmakec", [csv, cpk, "-align=2048", "-mode=FILENAME"]) percent = 0 while not process.waitForFinished(100): output = QString(process.readAll()) output = output.split("\n", QString.SkipEmptyParts) for line in output: line = common.qt_to_unicode(line) match = OUTPUT_RE.search(line) if match == None: continue percent = float(match.group(1)) * 1000 self.progress.setValue(percent) percent += 1
class XTerm(QX11EmbedContainer): def __init__(self, parent, xterm_cmd="xterm"): QX11EmbedContainer.__init__(self, parent) self.xterm_cmd = xterm_cmd self.process = QProcess(self) self.connect(self.process, SIGNAL("finished(int, QProcess::ExitStatus)"), self.on_term_close) atexit.register(self.kill) self.show_term() def kill(self): self.process.kill() self.process.waitForFinished() def sizeHint(self): size = QSize(400, 300) return size.expandedTo(QApplication.globalStrut()) def show_term(self): args = [ "-into", str(self.winId()), "-bg", "#000000", # self.palette().color(QPalette.Background).name(), "-fg", "#f0f0f0", # self.palette().color(QPalette.Foreground).name(), # border "-b", "0", "-w", "0", # blink cursor "-bc", '-e', 'tmux', 'new', '-s', 'my_session' ] self.process.start(self.xterm_cmd, args) if self.process.error() == QProcess.FailedToStart: print("xterm not installed") def on_term_close(self, exit_code, exit_status): print("close", exit_code, exit_status) self.close()
class ProcessHostapd(QObject): statusAP_connected = pyqtSignal(object) statusAPError = pyqtSignal(object) def __init__(self,cmd,session): QObject.__init__(self) self.cmd = cmd self.session = session self.errorAPDriver = ('AP-DISABLED', 'Failed to initialize interface', 'nl80211 driver initialization failed.', 'errors found in configuration file') def getNameThread(self): return '[New Thread {} ({})]'.format(self.procHostapd.pid(),self.objectName()) @pyqtSlot() def read_OutputCommand(self): self.data = str(self.procHostapd.readAllStandardOutput()) if 'AP-STA-DISCONNECTED' in self.data.rstrip() or 'inactivity (timer DEAUTH/REMOVE)' in self.data.rstrip(): self.statusAP_connected.emit(self.data.split()[2]) self.log_hostapd.info(self.data) for error in self.errorAPDriver: if self.data.find(error) != -1: return self.statusAPError.emit(self.data) def start(self): self.makeLogger() self.procHostapd = QProcess(self) self.procHostapd.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procHostapd, SIGNAL('readyReadStandardOutput()'), self, SLOT('read_OutputCommand()')); self.procHostapd.start(self.cmd.keys()[0],self.cmd[self.cmd.keys()[0]]) print '[New Thread {} ({})]'.format(self.procHostapd.pid(),self.objectName()) def makeLogger(self): setup_logger('hostapd', './logs/AccessPoint/hostapd.log',self.session) self.log_hostapd = logging.getLogger('hostapd') def stop(self): print 'Thread::[{}] successfully stopped.'.format(self.objectName()) if hasattr(self,'procHostapd'): QObject.disconnect(self.procHostapd, SIGNAL('readyReadStandardOutput()'), self, SLOT('read_OutputCommand()')) self.procHostapd.terminate() self.procHostapd.waitForFinished() self.procHostapd.kill()
def __runPackagingCommand(self, command_line): self.ui.pbCreatePackage.setEnabled(False) try: logger.info("going to run command: {0}".format(command_line)) proc = QProcess() proc.startDetached(command_line) proc.waitForFinished(-1) # note: you are looking here, probably because the PKG command failed, but it wasn't caught - I've noticed that # the waitForFinished() will always return False (the command runs too quick on analysis for example?), and exitStatus() # isn't reliable when a failure occurs anyway. Useless.... if proc.exitStatus() != QProcess.NormalExit: QMessageBox.critical(self, "Packaging Error", "The packaging process failed to finish properly") return False return True finally: self.ui.pbCreatePackage.setEnabled(True)
class PROCESS(QObject): queue_finished = pyqtSignal(int) prog_finished = pyqtSignal(tuple) stoped = pyqtSignal(int, int) # 1: start, 0: finished, 2: error | queue state = pyqtSignal(int, str) def __init__(self, parent=None): QObject.__init__(self, parent) self.process = QProcess() self.process.setProcessChannelMode(QProcess.MergedChannels) self.process.finished.connect(self.emit_finished) self.process.stateChanged.connect(self.emit_state) self.process_type = 0 # 0 process, 1 runnable self.threadpool = QThreadPool() self.worker = Worker() self.worker.signals.state.connect(self.emit_state) self.queue = None def emit_state(self, state): self.state.emit(state, self.prog_name) def emit_finished(self, exitcode, exitstatus): self.prog_finished.emit((self.prog_name, exitcode, exitstatus)) def set_queue(self, queue): self.queue = queue def start_process(self): try: obj = self.queue.get(False) self.prog_name = obj.keys()[0] if callable(obj.values()[0][0]): self.process_type = 1 funct = obj.values()[0][0] args = obj.values()[0][1] self.worker.insert_function(funct, args, self.prog_name) self.threadpool.start(self.worker) else: self.process_type = 0 self.process.start(obj.values()[0][0], obj.values()[0][1]) except Queue.Empty: self.queue_finished.emit(self.queue.name) def force_finished(self): # for process (programs) self.stoped.emit(1, self.queue.name) if self.process_type == 0: self.process.terminate() if not self.process.waitForFinished(1000): self.process.kill() else: if self.threadpool.activeThreadCount(): self.threadpool.clear() self.threadpool.waitForDone() with self.queue.mutex: self.queue.queue.clear() self.stoped.emit(0, self.queue.name)
class InoProcess(QtCore.QThread): def __init__(self,project,command): QtCore.QThread.__init__(self,project.parent()) self.project=project self.command=command def run(self): self.project.newMessage.emit() self.project.addMessage.emit("# running: "+self.command+"\n") start_time=time.time() self.proc = QProcess(None) self.proc.readyReadStandardError.connect(self.stdErrReady) self.proc.readyReadStandardOutput.connect(self.stdOutReady) self.proc.setWorkingDirectory(self.project.path) commands = self.command.split(' ') args=QStringList() for cmd in commands[1:]: args.append(cmd) self.proc.start(QString(commands[0]), args, mode=QIODevice.ReadOnly) self.proc.waitForFinished() end_time=time.time() if (self.proc.exitCode()==0): self.project.statusChanged.emit("SUCCESS") self.project.addMessage.emit("# \""+self.command+"\" finished in "+str(end_time-start_time)+"sec\n") else: self.project.statusChanged.emit("FAILED") self.project.addErrorMessage.emit("# \""+self.command+"\" finished in "+str(end_time-start_time)+ "sec with status:"+str(self.proc.exitCode())+"\n") def stop(self): if self.proc!=None and self.proc.state()!=QProcess.NotRunning: self.project.addErrorMessage.emit("# Received stop process command\n") self.proc.kill() def stdErrReady(self): #Reading possible errors errors=unicode(self.proc.readAllStandardError().data(),errors='ignore') if (errors!=None and len(errors)>0): self.project.addErrorMessage.emit(QString(errors)) def stdOutReady(self): msg=unicode(self.proc.readAllStandardOutput().data(),errors='ignore') if (msg!=None and len(msg)>0): self.project.addMessage.emit(QString(msg))
def __runPackagingCommand(self, command_line): self.ui.pbCreatePackage.setEnabled(False) try: logger.info("going to run command: {0}".format(command_line)) proc = QProcess() proc.startDetached(command_line) proc.waitForFinished(-1) # note: you are looking here, probably because the PKG command failed, but it wasn't caught - I've noticed that # the waitForFinished() will always return False (the command runs too quick on analysis for example?), and exitStatus() # isn't reliable when a failure occurs anyway. Useless.... if proc.exitStatus() != QProcess.NormalExit: QMessageBox.critical( self, "Packaging Error", "The packaging process failed to finish properly") return False return True finally: self.ui.pbCreatePackage.setEnabled(True)
def getProcList(): retProcs = [] if HAIKU or LINUX or MACOS: process = QProcess() process.start("ps", ["-u", str(os.getuid())]) process.waitForFinished() processDump = process.readAllStandardOutput().split("\n") for i in range(len(processDump)): if (i == 0): continue dumpTest = str(processDump[i], encoding="utf-8").rsplit(":", 1)[-1].split(" ") if len(dumpTest) > 1 and dumpTest[1]: retProcs.append(dumpTest[1]) else: print("getProcList() - Not supported in this system") return retProcs
class ProcessHostapd(QObject): statusAP_connected = pyqtSignal(object) def __init__(self, cmd, session): QObject.__init__(self) self.cmd = cmd self.session = session def getNameThread(self): return '[New Thread {} ({})]'.format(self.procHostapd.pid(), self.objectName()) @pyqtSlot() def read_OutputCommand(self): self.data = str(self.procHostapd.readAllStandardOutput()) if 'AP-STA-DISCONNECTED' in self.data.rstrip( ) or 'inactivity (timer DEAUTH/REMOVE)' in self.data.rstrip(): self.statusAP_connected.emit(self.data.split()[2]) self.log_hostapd.info(self.data) def start(self): self.makeLogger() self.procHostapd = QProcess(self) self.procHostapd.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procHostapd, SIGNAL('readyReadStandardOutput()'), self, SLOT('read_OutputCommand()')) self.procHostapd.start(self.cmd.keys()[0], self.cmd[self.cmd.keys()[0]]) print '[New Thread {} ({})]'.format(self.procHostapd.pid(), self.objectName()) def makeLogger(self): setup_logger('hostapd', './Logs/AccessPoint/hostapd.log', self.session) self.log_hostapd = logging.getLogger('hostapd') def stop(self): print 'Thread::[{}] successfully stopped.'.format(self.objectName()) if hasattr(self, 'procHostapd'): self.procHostapd.terminate() self.procHostapd.waitForFinished() self.procHostapd.kill()
def getProcList(): retProcs = [] if HAIKU or LINUX or MACOS: process = QProcess() process.start("ps", ["-u", str(os.getuid())]) process.waitForFinished() processDump = process.readAllStandardOutput().split("\n") for i in range(len(processDump)): if (i == 0): continue dumpTest = str(processDump[i], encoding="utf-8").rsplit(":", 1)[-1].split(" ") if len(dumpTest) > 1 and dumpTest[1]: retProcs.append(dumpTest[1]) else: print("getProcList() - Not supported in this system") return retProcs
def stopAllAudioProcesses(): tryCloseJackDBus() if not (HAIKU or LINUX or MACOS): print("stopAllAudioProcesses() - Not supported in this system") return process = QProcess() # Tell pulse2jack script to create files, prevents pulseaudio respawn process.start("cadence-pulse2jack", "--dummy") process.waitForFinished() procsTerm = [ "a2j", "a2jmidid", "artsd", "jackd", "jackdmp", "knotify4", "lash", "ladishd", "ladiappd", "ladiconfd", "jmcore" ] procsKill = ["jackdbus", "pulseaudio"] tries = 20 process.start("killall", procsTerm) process.waitForFinished() waitProcsEnd(procsTerm, tries) process.start("killall", ["-KILL"] + procsKill) process.waitForFinished() waitProcsEnd(procsKill, tries)
def __launch_example(self): '''Called when the user presses the 'Print' button. Launches ther configured example with the arguments presented by the UI. ''' example = self.examplesComboBox.itemData( self.examplesComboBox.currentIndex() ).toPyObject() try: cmd = 'python {0} {1}'.format( QUrl(example.script_file).toLocalFile(), self.inputWidget.currentWidget().args() ) print(cmd) proc = QProcess() proc.start(cmd) proc.waitForFinished() except UnicodeDecodeError as _unknown: QMessageBox.information(self, 'Font Problem', 'There was a problem decoding some of the font ' 'information. Print has been cancelled.')
def generateDEM(layer, crs, extent, width, height, demfilename): # generate dem file # gdalwarp options options = [] options.append("--config GDAL_FILENAME_IS_UTF8 NO") options.append("-r bilinear") # calculate extent. note: pixel is area in the output geotiff, but pixel should be handled as point xres = extent.width() / width yres = extent.height() / height ext = (extent.xMinimum() - xres / 2, extent.yMinimum() - yres / 2, extent.xMaximum() + xres / 2, extent.yMaximum() + yres / 2) options.append("-te %f %f %f %f" % ext) options.append("-ts %d %d" % (width + 1, height + 1)) # target crs authid = crs.authid() if authid.startswith("EPSG:"): options.append("-t_srs %s" % authid) else: options.append('-t_srs "%s"' % crs.toProj4()) options.append('"' + layer.source() + '"') options.append('"' + demfilename + '"') # run gdalwarp command cmd = "gdalwarp " + u" ".join(options) if debug_mode: qDebug(cmd.encode("UTF-8")) process = QProcess() process.start(cmd) process.waitForFinished() if not os.path.exists(demfilename): hint = "" if os.system("gdalwarp --help-general"): hint = "gdalwarp is not installed." return "Failed to generate a dem file using gdalwarp. " + hint return 0
class ThreadLogger(QObject): def __init__(self,logger_path=str): QObject.__init__(self) self.logger_path = logger_path @pyqtSlot() def readProcessOutput(self): try: self.emit(SIGNAL('Activated( QString )'), str(self.procLogger.readAllStandardOutput()).rstrip().split(' : ')[1]) except Exception: pass def start(self): self.procLogger = QProcess(self) self.procLogger.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self.procLogger, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()')) self.procLogger.start('tail',['-f',self.logger_path]) def stop(self): if hasattr(self,'procLogger'): self.procLogger.terminate() self.procLogger.waitForFinished() self.procLogger.kill()
def generateDEM(layer, crs, extent, width, height, demfilename): # generate dem file # gdalwarp options options = [] options.append("--config GDAL_FILENAME_IS_UTF8 NO") options.append("-r bilinear") # calculate extent. note: pixel is area in the output geotiff, but pixel should be handled as point xres = extent.width() / width yres = extent.height() / height ext = (extent.xMinimum() - xres / 2, extent.yMinimum() - yres / 2, extent.xMaximum() + xres / 2, extent.yMaximum() + yres / 2) options.append("-te %f %f %f %f" % ext) options.append("-ts %d %d" % (width + 1, height + 1)) # target crs authid = crs.authid() if authid.startswith("EPSG:"): options.append("-t_srs %s" % authid) else: options.append('-t_srs "%s"' % crs.toProj4()) options.append('"' + layer.source() + '"') options.append('"' + demfilename + '"') # run gdalwarp command cmd = "gdalwarp " + u" ".join(options) if debug_mode: qDebug(cmd.encode("UTF-8")) process = QProcess() process.start(cmd) process.waitForFinished() if not os.path.exists(demfilename): hint = "" if os.system("gdalwarp --help-general"): hint = "gdalwarp is not installed." return "Failed to generate a dem file using gdalwarp. " + hint return 0
def runProcess(self, args): self.logDb( u"BEFEHL: '%s'" % ( u"' '".join(args) ) ) currout = "" currerr = "" p = QProcess() p.start( args[0], args[1:] ) i=0 while not p.waitForFinished(500): i += 1 self.alive.setText( self.alive.text()[:-1] + ("-\|/")[i%4] ) app.processEvents() currout = self.processOutput( currout, p.readAllStandardOutput() ) currerr = self.processOutput( currerr, p.readAllStandardError() ) if p.state()<>QProcess.Running: if self.canceled: self.log( u"Prozeß abgebrochen." ) break if self.canceled: self.log( u"Prozeß wird abgebrochen." ) p.kill() currout = self.processOutput( currout, p.readAllStandardOutput() ) if currout and currout!="": self.log( "E %s" % currout ) currerr = self.processOutput( currerr, p.readAllStandardError() ) if currerr and currerr!="": self.log( "E %s" % currerr ) ok = False if p.exitStatus()==QProcess.NormalExit: if p.exitCode()==0: ok = True else: self.log( u"Fehler bei Prozeß: %d" % p.exitCode() ) else: self.log( u"Prozeß abgebrochen: %d" % p.exitCode() ) self.logDb( "EXITCODE: %d" % p.exitCode() ) p.close() return ok
def runProcess(self, args): self.logDb(u"BEFEHL: '%s'" % (u"' '".join(args))) currout = "" currerr = "" p = QProcess() p.start(args[0], args[1:]) i = 0 while not p.waitForFinished(500): i += 1 self.alive.setText(self.alive.text()[:-1] + ("-\|/")[i % 4]) app.processEvents() currout = self.processOutput(currout, p.readAllStandardOutput()) currerr = self.processOutput(currerr, p.readAllStandardError()) if p.state() <> QProcess.Running: if self.canceled: self.log(u"Prozeß abgebrochen.") break if self.canceled: self.log(u"Prozeß wird abgebrochen.") p.kill() currout = self.processOutput(currout, p.readAllStandardOutput()) if currout and currout != "": self.log("E %s" % currout) currerr = self.processOutput(currerr, p.readAllStandardError()) if currerr and currerr != "": self.log("E %s" % currerr) ok = False if p.exitStatus() == QProcess.NormalExit: if p.exitCode() == 0: ok = True else: self.log(u"Fehler bei Prozeß: %d" % p.exitCode()) else: self.log(u"Prozeß abgebrochen: %d" % p.exitCode()) self.logDb("EXITCODE: %d" % p.exitCode()) p.close() return ok
def get_devices(): devices = [] process = QProcess() process.start('scanimage', ['-f', '%d=>%v=>%m%n']) if not process.waitForFinished(): return devices data = bytes(process.readAllStandardOutput()).decode("utf-8").strip() if data=="": return devices lines = data.split("\n") for line in lines: dev, vendor, model = line.strip().split('=>') if not " " in dev: devices.append({'device':dev, 'vendor':vendor, 'model':model}) return devices
class ExtGuesser(object): _TAVI = "AVI" _MMP4 = "video/mp4" _MFLV = "video/x-flv" _TFLV = "Macromedia Flash Video" def __init__(self, path, filepgm='file'): self._path = path self._proc = QProcess() self._file_pgm = filepgm if not exists(self._path): raise InvalidPathError(path) def _guessExtension(self, text, mime): if text.find(self._TAVI) >= 0: return 'avi' elif mime.find(self._MMP4) >= 0: return 'mp4' elif ((mime.find(self._MFLV) >= 0) and (text.find(self._TFLV) >= 0)): return 'flv' else: return 'unk' def get(self): self._proc.start(self._file_pgm, ["-b", self._path]) ret0 = self._proc.waitForFinished() textual = str(self._proc.readAllStandardOutput()) self._proc.start(self._file_pgm, ["-bi", self._path]) ret1 = self._proc.waitForFinished() mime = str(self._proc.readAllStandardOutput()) if ret0 and ret1: return self._guessExtension(textual, mime) else: raise ExternalProgramError()
class WallpaperChanger(object): def __init__(self): self.settings = Settings() self.process = QProcess() def apply_wallpaper(self, filepath): system_platform = platform.system() if system_platform == 'Windows': return self._windows(filepath) elif system_platform == 'Linux': # Read desktop environment from settings. env = self.settings.linux_desktop print 'Setting wallpaper using environment "{0:s}"'.format(env) if env == 'feh': return self._feh(filepath) elif env == 'unity': return self._unity(filepath) elif env == 'xfce4': return self._xfce4(filepath) elif env == 'mate': return self._mate(filepath) def _windows(self, filepath): import ctypes SPI_SETDESKWALLPAPER = 20 # According to http://support.microsoft.com/default.aspx?scid=97142 ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, filepath, 1) def _feh(self, filepath): error = self.process.execute('feh --bg-scale {0:s}'.format(filepath)) return not bool(error) def _unity(self, filepath): error = self.process.execute('gsettings set org.gnome.desktop.background picture-uri {0:s}'.format(filepath)) return not bool(error) def _mate(self, filepath): error = self.process.execute('gsettings set org.mate.background picture-filename {0:s}'.format(filepath)) return not bool(error) def _xfce4(self, filepath): self.process.start('xfconf-query -c xfce4-desktop -l') self.process.waitForFinished() properties = re.findall(r'(/backdrop/screen.*(?:last-image|image-path))', unicode(self.process.readAllStandardOutput())) error = False for item in properties: self.process.start('xfconf-query --channel xfce4-desktop --property {0:s} --set {1:s}'.format(item, '/')) self.process.waitForFinished() self.process.start( 'xfconf-query --channel xfce4-desktop --property {0:s} --set {1:s}'.format(item, filepath)) self.process.waitForFinished() if self.process.exitCode(): error = True return not error
def setOptions(self, colormode_index, quality_index, papertype_index, papersize_index, custom_size=[]): color_mode = self.color_modes[colormode_index] quality = self.quality_modes[quality_index] paper_type = self.paper_types[papertype_index] paper_size = self.paper_sizes[papersize_index] lpoptions_args = [ '-p', self.printer, '-o', 'BRMonoColor=' + color_mode, '-o', 'BRResolution=' + quality, '-o', "BRMediaType=" + paper_type, '-o', 'PageSize=' + paper_size ] print('lpoptions', ' '.join(lpoptions_args)) process = QProcess() process.start('lpoptions', lpoptions_args) if not process.waitForFinished(): print("Error : Could not execute lpoptions") return False return True
def stopAllAudioProcesses(): if not (HAIKU or LINUX or MACOS): print("stopAllAudioProcesses() - Not supported in this system") return process = QProcess() # Tell pulse2jack script to create files, prevents pulseaudio respawn process.start("cadence-pulse2jack", "--dummy") process.waitForFinished() procsTerm = ["a2j", "a2jmidid", "artsd", "jackd", "jackdmp", "knotify4", "lash", "ladishd", "ladiappd", "ladiconfd", "jmcore"] procsKill = ["jackdbus", "pulseaudio"] tries = 20 process.start("killall", procsTerm) process.waitForFinished() for x in range(tries): procsList = getProcList() for term in range(len(procsTerm)): if term in procsList: break else: sleep(0.1) else: break process.start("killall", ["-KILL"] + procsKill) process.waitForFinished() for x in range(tries): procsList = getProcList() for kill in range(len(procsKill)): if kill in procsList: break else: sleep(0.1) else: break
def stopAllAudioProcesses(): if not (HAIKU or LINUX or MACOS): print("stopAllAudioProcesses() - Not supported in this system") return process = QProcess() # Tell pulse2jack script to create files, prevents pulseaudio respawn process.start("cadence-pulse2jack", "--dummy") process.waitForFinished() procsTerm = ["a2j", "a2jmidid", "artsd", "jackd", "jackdmp", "knotify4", "lash", "ladishd", "ladiappd", "ladiconfd", "jmcore"] procsKill = ["jackdbus", "pulseaudio"] tries = 20 process.start("killall", procsTerm) process.waitForFinished() process.start("killall", ["-KILL"] + procsKill) process.waitForFinished() waitProcsEnd(procsTerm, tries) waitProcsEnd(procsKill, tries)
def browseModels(self): dir_to_show = './model/'+ self.txtModelName.text() process = QProcess(self) process.startDetached("open", [dir_to_show]) if process.waitForFinished(): process.close()
class TerreImageProcess(): def __init__(self): self.process = QProcess() self.process.error[QProcess.ProcessError].connect( self.error_management) self.env = QProcessEnvironment().systemEnvironment() self.set_otb_process_env_default() self.command = "" def run_process(self, command): logger.info(u"Running {}".format(command)) self.process.setProcessEnvironment(self.env) # logger.debug("..............{}".format(self.process.processEnvironment().value("OTB_APPLICATION_PATH"))) # logger.debug("..............{}".format(self.process.processEnvironment().value("PATH"))) # logger.debug("Environ : PATH {}".format(os.environ["PATH"])) # logger.debug("Environ : OTB_APPLICATION_PATH {}".format(os.environ.get("OTB_APPLICATION_PATH", "Empty"))) self.command = command self.process.start(command) if self.process.waitForStarted(): self.process.waitForFinished(-1) exit_code = self.process.exitCode() if exit_code != 0: self.error_management(exit_code) result = self.process.readAllStandardOutput() # logger.debug(" {} {}".format(type(result), result)) error = self.process.readAllStandardError().data() # logger.debug(repr(error)) if not error in ["\n", ""]: logger.error("error : %s" % (error)) output = result.data() logger.info(output) return result else: code_d_erreur = self.process.error() self.error_management(code_d_erreur) return None def error_management(self, errorCode): dic_err = { 0: "QProcess::FailedToStart", 1: "QProcess::Crashed", 2: "QProcess::TimedOut", 3: "QProcess::WriteError", 4: "QProcess::ReadError", 5: "QProcess::UnknownError", 127: "Other, The application may not have been found" } try: type_qt_error = dic_err[errorCode] logger.error(u"Error {} {}".format(errorCode, type_qt_error)) except KeyError: type_qt_error = "" error = self.process.readAllStandardError().data() logger.error(error) logger.error(self.process.readAllStandardOutput()) try: raise terre_image_exceptions.TerreImageRunProcessError( u"Error running : {}\n {}{}".format(self.command, type_qt_error, error)) except UnicodeError: raise terre_image_exceptions.TerreImageRunProcessError( u"Error running : {}\n {}".format(self.command, type_qt_error)) def set_env_var(self, varname, varval, append=False, pre=False): if append == True: if pre == False: # insert value at the end of the variable self.env.insert(varname, self.env.value(varname) + os.pathsep + varval) else: # insert value in head self.env.insert(varname, varval + os.pathsep + self.env.value(varname)) else: # replace value if existing self.env.insert(varname, varval) # logger.debug("env {} {}".format(varname, self.env.value(varname))) def set_otb_process_env(self): dirname = os.path.dirname(os.path.abspath(__file__)) self.set_env_var("OTB_APPLICATION_PATH", os.path.join(dirname, "win32", "plugin"), pre=True) self.set_env_var("PATH", os.path.join(dirname, "win32", "bin"), append=False, pre=True) def set_otb_process_env_custom(self, otb_app_path="", path=""): """ Add the given values to OTB_APPLICATION_PATH and PATH environement variables Args: otb_app_path: path: Returns: """ self.set_env_var("OTB_APPLICATION_PATH", otb_app_path, pre=True) self.set_env_var("PATH", path, append=False, pre=True) def set_otb_process_env_default(self): """ Add the values from the config file to OTB_APPLICATION_PATH and PATH environement variables Args: otb_app_path: path: Returns: """ self.set_env_var("OTB_APPLICATION_PATH", terre_image_configuration.OTB_APPLICATION_PATH, pre=True) self.set_env_var("PATH", terre_image_configuration.PATH, append=True, pre=True) if terre_image_configuration.LD_LIBRARY_PATH: self.set_env_var("LD_LIBRARY_PATH", terre_image_configuration.LD_LIBRARY_PATH, append=True, pre=True)
def __createProgramEntry(self, description, exe, versionCommand = "", versionStartsWith = "", versionPosition = 0, version = "", versionCleanup = None, versionRe = None): """ Private method to generate a program entry. @param description descriptive text (string or QString) @param exe name of the executable program (string) @param versionCommand command line switch to get the version info (string) if this is empty, the given version will be shown. @param versionStartsWith start of line identifying version info (string) @param versionPosition index of part containing the version info (integer) @keyparam version version string to show (string) @keyparam versionCleanup tuple of two integers giving string positions start and stop for the version string (tuple of integers) @keyparam versionRe regexp to determine the line identifying version info (string). Takes precedence over versionStartsWith. @return version string of detected or given version (string) """ itm = QTreeWidgetItem(self.programsList, QStringList(description)) font = itm.font(0) font.setBold(True) itm.setFont(0, font) if not exe: itm.setText(1, self.trUtf8("(not configured)")) else: if os.path.isabs(exe): if not Utilities.isExecutable(exe): exe = "" else: exe = Utilities.getExecutablePath(exe) if exe: if versionCommand and \ (versionStartsWith != "" or \ (versionRe is not None and versionRe != "")) and \ versionPosition: proc = QProcess() proc.setProcessChannelMode(QProcess.MergedChannels) proc.start(exe, QStringList(versionCommand)) finished = proc.waitForFinished(10000) if finished: output = \ unicode(proc.readAllStandardOutput(), str(Preferences.getSystem("IOEncoding")), 'replace') if versionRe is None: versionRe = "^%s" % re.escape(versionStartsWith) versionRe = re.compile(versionRe, re.UNICODE) for line in output.splitlines(): if versionRe.search(line): try: version = line.split()[versionPosition] if versionCleanup: version = \ version[versionCleanup[0]:versionCleanup[1]] break except IndexError: version = self.trUtf8("(unknown)") else: version = self.trUtf8("(not executable)") itm2 = QTreeWidgetItem(itm, QStringList() << exe << version) itm.setExpanded(True) else: itm.setText(1, self.trUtf8("(not found)")) QApplication.processEvents() self.programsList.header().resizeSections(QHeaderView.ResizeToContents) self.programsList.header().setStretchLastSection(True) return version
class PylintWidget(QWidget): """ Pylint widget """ DATAPATH = get_conf_path('.pylint.results') VERSION = '1.0.2' def __init__(self, parent, max_entries=100): QWidget.__init__(self, parent) self.output = None self.error_output = None self.max_entries = max_entries self.data = [self.VERSION] if osp.isfile(self.DATAPATH): try: data = cPickle.load(file(self.DATAPATH)) if data[0] == self.VERSION: self.data = data except EOFError: pass self.filecombo = PythonModulesComboBox(self) if self.data: self.remove_obsolete_items() self.filecombo.addItems(self.get_filenames()) self.start_button = create_toolbutton(self, get_icon('run.png'), translate('Pylint', "Analyze"), tip=translate( 'Pylint', "Run analysis"), triggered=self.start) self.stop_button = create_toolbutton(self, get_icon('terminate.png'), translate('Pylint', "Stop"), tip=translate( 'Pylint', "Stop current analysis")) self.connect(self.filecombo, SIGNAL('valid(bool)'), self.start_button.setEnabled) self.connect(self.filecombo, SIGNAL('valid(bool)'), self.show_data) browse_button = create_toolbutton(self, get_icon('fileopen.png'), tip=translate( 'Pylint', 'Select Python script'), triggered=self.select_file) self.ratelabel = QLabel() self.datelabel = QLabel() self.log_button = create_toolbutton(self, get_icon('log.png'), translate('Pylint', "Output"), tip=translate( 'Pylint', "Complete Pylint output"), triggered=self.show_log) self.treewidget = ResultsTree(self) hlayout1 = QHBoxLayout() hlayout1.addWidget(self.filecombo) hlayout1.addWidget(browse_button) hlayout1.addWidget(self.start_button) hlayout1.addWidget(self.stop_button) hlayout2 = QHBoxLayout() hlayout2.addWidget(self.ratelabel) hlayout2.addStretch() hlayout2.addWidget(self.datelabel) hlayout2.addStretch() hlayout2.addWidget(self.log_button) layout = QVBoxLayout() layout.addLayout(hlayout1) layout.addLayout(hlayout2) layout.addWidget(self.treewidget) self.setLayout(layout) self.process = None self.set_running_state(False) if not is_pylint_installed(): for widget in (self.treewidget, self.filecombo, self.start_button, self.stop_button): widget.setDisabled(True) text = translate('Pylint', 'Please install <b>pylint</b>:') url = 'http://www.logilab.fr' text += ' <a href=%s>%s</a>' % (url, url) self.ratelabel.setText(text) else: self.show_data() def analyze(self, filename): if not is_pylint_installed(): return filename = unicode(filename) # filename is a QString instance self.kill_if_running() index, _data = self.get_data(filename) if index is None: self.filecombo.addItem(filename) self.filecombo.setCurrentIndex(self.filecombo.count() - 1) else: self.filecombo.setCurrentIndex(index) self.filecombo.selected() if self.filecombo.is_valid(): self.start() def select_file(self): self.emit(SIGNAL('redirect_stdio(bool)'), False) filename = QFileDialog.getOpenFileName( self, translate('Pylint', "Select Python script"), os.getcwdu(), translate('Pylint', "Python scripts") + " (*.py ; *.pyw)") self.emit(SIGNAL('redirect_stdio(bool)'), False) if filename: self.analyze(filename) def remove_obsolete_items(self): """Removing obsolete items""" self.data = [self.VERSION] + \ [(filename, data) for filename, data in self.data[1:] if is_module_or_package(filename)] def get_filenames(self): return [filename for filename, _data in self.data[1:]] def get_data(self, filename): filename = osp.abspath(filename) for index, (fname, data) in enumerate(self.data[1:]): if fname == filename: return index, data else: return None, None def set_data(self, filename, data): filename = osp.abspath(filename) index, _data = self.get_data(filename) if index is not None: self.data.pop(index) self.data.append((filename, data)) self.save() def set_max_entries(self, max_entries): self.max_entries = max_entries self.save() def save(self): while len(self.data) > self.max_entries + 1: self.data.pop(1) cPickle.dump(self.data, file(self.DATAPATH, 'w')) def show_log(self): if self.output: TextEditor(self.output, title=translate('Pylint', "Pylint output"), readonly=True, size=(700, 500)).exec_() def start(self): filename = unicode(self.filecombo.currentText()) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.SeparateChannels) self.process.setWorkingDirectory(osp.dirname(filename)) self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.read_output) self.connect(self.process, SIGNAL("readyReadStandardError()"), lambda: self.read_output(error=True)) self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"), self.finished) self.connect(self.stop_button, SIGNAL("clicked()"), self.process.kill) self.output = '' self.error_output = '' p_args = [osp.basename(filename)] self.process.start(PYLINT_PATH, p_args) running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical( self, translate('Pylint', "Error"), translate('Pylint', "Process failed to start")) def set_running_state(self, state=True): self.start_button.setEnabled(not state) self.stop_button.setEnabled(state) def read_output(self, error=False): if error: self.process.setReadChannel(QProcess.StandardError) else: self.process.setReadChannel(QProcess.StandardOutput) bytes = QByteArray() while self.process.bytesAvailable(): if error: bytes += self.process.readAllStandardError() else: bytes += self.process.readAllStandardOutput() text = unicode(QString.fromLocal8Bit(bytes.data())) if error: self.error_output += text else: self.output += text def finished(self): self.set_running_state(False) if not self.output: return # Convention, Refactor, Warning, Error results = {'C:': [], 'R:': [], 'W:': [], 'E:': []} txt_module = '************* Module ' module = '' # Should not be needed - just in case something goes wrong for line in self.output.splitlines(): if line.startswith(txt_module): # New module module = line[len(txt_module):] continue for prefix in results: if line.startswith(prefix): break else: continue i1 = line.find(':') if i1 == -1: continue i2 = line.find(':', i1 + 1) if i2 == -1: continue line_nb = line[i1 + 1:i2].strip() if not line_nb: continue line_nb = int(line_nb) message = line[i2 + 1:] item = (module, line_nb, message) results[line[:i1 + 1]].append(item) # Rate rate = None txt_rate = 'Your code has been rated at ' i_rate = self.output.find(txt_rate) if i_rate > 0: i_rate_end = self.output.find('/10', i_rate) if i_rate_end > 0: rate = self.output[i_rate + len(txt_rate):i_rate_end] # Previous run previous = '' if rate is not None: txt_prun = 'previous run: ' i_prun = self.output.find(txt_prun, i_rate_end) if i_prun > 0: i_prun_end = self.output.find('/10', i_prun) previous = self.output[i_prun + len(txt_prun):i_prun_end] filename = unicode(self.filecombo.currentText()) self.set_data(filename, (time.localtime(), rate, previous, results)) self.output = self.error_output + self.output self.show_data(justanalyzed=True) def kill_if_running(self): if self.process is not None: if self.process.state() == QProcess.Running: self.process.kill() self.process.waitForFinished() def show_data(self, justanalyzed=False): if not justanalyzed: self.output = None self.log_button.setEnabled(self.output is not None \ and len(self.output) > 0) self.kill_if_running() filename = unicode(self.filecombo.currentText()) if not filename: return _index, data = self.get_data(filename) if data is None: text = translate('Pylint', 'Source code has not been rated yet.') self.treewidget.clear() date_text = '' else: datetime, rate, previous_rate, results = data if rate is None: text = translate( 'Pylint', 'Analysis did not succeed ' '(see output for more details).') self.treewidget.clear() date_text = '' else: text_style = "<span style=\'color: #444444\'><b>%s </b></span>" rate_style = "<span style=\'color: %s\'><b>%s</b></span>" prevrate_style = "<span style=\'color: #666666\'>%s</span>" color = "#FF0000" if float(rate) > 5.: color = "#22AA22" elif float(rate) > 3.: color = "#EE5500" text = translate('Pylint', 'Global evaluation:') text = (text_style % text) + (rate_style % (color, ('%s/10' % rate))) if previous_rate: text_prun = translate('Pylint', 'previous run:') text_prun = ' (%s %s/10)' % (text_prun, previous_rate) text += prevrate_style % text_prun self.treewidget.set_results(filename, results) date_text = text_style % time.strftime("%d %b %Y %H:%M", datetime) self.ratelabel.setText(text) self.datelabel.setText(date_text)
class Kitty(QObject): """manage kitty process (terminals)""" exe_name = 'kitty' DELAY = 150 def __init__(self, ip, port, protocol, name, log_path, window_title, log_name, parent=None): QObject.__init__(self, parent) self.ip = ip self.port = port self.protocol = protocol self.log_path = log_path self.log_name = log_name self.id = str(os.getpid()) + name self.window_title = window_title self.terminal = QProcess() self.terminal.finished.connect(self.close) self.terminal.stateChanged.connect(self.state) self.send_process = QProcess() self.send_process.finished.connect(self.end_send) def open(self): """ kitty -telnet -P 9696 hostname """ if self.terminal.state() == QProcess.Running: return file_name = utils.set_log_name(self.log_name, self.log_path, ext='.txt') args = [ '-{}'.format(self.protocol), self.ip, '-P', self.port, '-log', os.path.join(self.log_path, file_name), '-title', self.window_title, '-classname', self.id ] while self.terminal.state() == QProcess.NotRunning: self.terminal.start(os.path.join(dep_dir, Kitty.exe_name), args) self.terminal.waitForStarted() QThread.msleep(Kitty.DELAY) def send(self, text): if self.send_process.state() == QProcess.Running: self.send_process.close() self.show_terminal() args = ['-classname', self.id, '-sendcmd', text] self.send_process.start(os.path.join(dep_dir, Kitty.exe_name), args) self.send_process.waitForStarted() self.send_process.waitForFinished() QThread.msleep(Kitty.DELAY) def show_terminal(self): if self.terminal.state() == QProcess.NotRunning: return autowin.show_window(autowin.get_qprocess_pid(self.terminal.pid())) QThread.msleep(Kitty.DELAY) @staticmethod def show_main(): autowin.show_window(os.getpid()) def end_send(self): pass def close(self): self.terminal.close() def state(self, st): print(st)
class EjecutarWidget(QWidget): def __init__(self): super(EjecutarWidget, self).__init__() layoutV = QVBoxLayout(self) layoutV.setContentsMargins(0, 0, 0, 0) layoutV.setSpacing(0) self.output = output_compiler.SalidaCompilador(self) layoutV.addWidget(self.output) self.setLayout(layoutV) # Flag self._compilation_failed = False # Procesos self.build_process = QProcess(self) if not sys.platform.startswith('linux'): self._envgcc = QProcessEnvironment.systemEnvironment() self._envgcc.insert("PATH", ENV_GCC) self.build_process.setProcessEnvironment(self._envgcc) self.execution_process = QProcess(self) # Conexiones self.build_process.readyReadStandardError.connect( self.output.stderr_output) self.build_process.finished[int, QProcess.ExitStatus].connect( self._compilation_finished) self.build_process.error[QProcess.ProcessError].connect( self._compilation_error) self.execution_process.finished[int, QProcess.ExitStatus].connect( self._execution_finished) def _execution_finished(self, code, status): if status == QProcess.CrashExit: text = output_compiler.Item( self.tr("La ejecución se ha interrumpido")) text.setForeground(Qt.red) self.output.addItem(text) else: text = output_compiler.Item(self.tr("Ejecución Exitosa!")) text.setForeground(QColor("#7FE22A")) self.output.addItem(text) def run_compilation(self, sources): """ Se corre el comando gcc para la compilación """ # Ejecutable filename, files = sources if not files: # No es un proyecto files = [filename] path = QDir.fromNativeSeparators(filename) self.exe = os.path.splitext(os.path.basename(path))[0] # Generar el ejecutable en el directorio del código fuente exe_path = os.path.dirname(path) self.build_process.setWorkingDirectory(exe_path) # Se limpia el QListWidget self.output.clear() flags = settings.COMPILER_FLAGS.split() params = ['-o', self.exe] + flags gcc = 'gcc' if not sys.platform.startswith("linux"): gcc = os.path.join(self._environment, 'gcc') item = output_compiler.Item( self.tr(">>> Compilando: {0} ( en directorio {1} )").format( path.split('/')[-1], exe_path)) self.output.addItem(item) self.output.addItem( output_compiler.Item( self.tr(">>> Comando: {0}").format(gcc + ' ' + ' '.join(params) + ' ' + ' '.join(files)))) # Se inicia el proceso self.build_process.start(gcc, params + files) self.build_process.waitForFinished() def _compilation_finished(self, code, status): """ Cuando la compilación termina @codigoError toma dos valores: 0 = La compilación ha terminado de forma correcta 1 = La compilación ha fallado """ if status == QProcess.NormalExit and code == 0: self._compilation_failed = False item_ok = output_compiler.Item( self.tr("¡LA COMPILACIÓN HA SIDO EXITOSA!")) self.output.addItem(item_ok) item_ok.setForeground(QColor("#7FE22A")) else: self._compilation_failed = True item_error = output_compiler.Item( self.tr("¡LA COMPILACIÓN HA FALLADO!")) item_error.setForeground(QColor("#E20000")) self.output.addItem(item_error) syntax_ok = True if code == 0 else False self.emit(SIGNAL("updateSyntaxCheck(bool)"), syntax_ok) code_status = output_compiler.Item( self.tr("Proceso terminado con código: {0}").format(code), italic=True) self.output.addItem(code_status) count = self.output.count() self.output.setCurrentRow(count - 1, QItemSelectionModel.NoUpdate) def _compilation_error(self, error): """ Éste método se ejecuta cuando el inicio del proceso de compilación falla. Una de las causas puede ser la ausencia del compilador. """ text = output_compiler.Item( self.tr("Se ha producido un error. Compilador no encontrado.")) text.setForeground(Qt.red) self.output.addItem(text) def run_program(self, sources): """ Ejecuta el binario generado por el compilador """ path = os.path.dirname(sources[0]) self.execution_process.setWorkingDirectory(path) # Path ejecutable path_exe = os.path.join(path, self.exe) if not settings.IS_LINUX: path_exe += '.exe' # Si no existe se termina el proceso if not self._check_file_exists(path_exe): text = output_compiler.Item( self.tr("El archivo no existe: {0}").format(path_exe)) text.setForeground(Qt.red) self.output.addItem(text) return # Texto en la salida text = output_compiler.Item( self.tr("Ejecutando... {0}").format(path_exe)) self.output.addItem(text) if settings.IS_LINUX: # Run ! terminal = settings.get_setting('terminal') arguments = [ os.path.join(paths.PATH, "tools", "run_script.sh %s" % path_exe) ] self.execution_process.start(terminal, ['-e'] + arguments) else: pauser = os.path.join(paths.PATH, "tools", "pauser", "system_pause.exe") process = [pauser] + ["\"%s\"" % path_exe] Popen(process, creationflags=CREATE_NEW_CONSOLE) def _check_file_exists(self, exe): """ Comprueba si el ejecutable existe """ exists = True if not os.path.exists(exe): exists = False return exists @property def _environment(self): """ Devuelve la variable de entorno gcc """ return self._envgcc.value("PATH", "") def build_and_run(self, archivo): self.run_compilation(archivo) if not self._compilation_failed: self.run_program(archivo) def clean(self, exe): """ Elimina el binario generado por la compilación """ if exe is None: return binary = exe.split('.')[0] if not settings.IS_LINUX: binary += '.exe' os.remove(binary) def kill_process(self): """ Termina el proceso """ self.execution_process.kill()
if doRunNow: if firstStart: firstStart = False print("cadence-aloop-daemon started, using %s and %i channels" % ("zita-a2j/j2a" if useZita else "alsa_in/out", channels)) run_alsa_bridge() doRunNow = False elif isKernelGood and reactivateCounter >= 0: if reactivateCounter == 5: reactivateCounter = -1 doRunNow = True else: reactivateCounter += 1 sleep(1) # Close JACK client jacklib.deactivate(client) jacklib.client_close(client) if os.path.exists(checkFile): os.remove(checkFile) if procIn.state() != QProcess.NotRunning: procIn.terminate() procIn.waitForFinished(1000) if procOut.state() != QProcess.NotRunning: procOut.terminate() procOut.waitForFinished(1000)
class TestRunner(): def __init__(self, testfile): self.testfile = testfile self.data = "" self.passed_tests = [] self.failed_tests = [] def writeStdout(self): data = self.process.readAllStandardOutput().data().decode("utf-8").replace(r'\n', '\n') if "debug" in sys.argv: sys.stdout.write(data) else: for line in data.split('\n'): if line[:4] == "PASS" or line[:5] == "FAIL!" or line[:5] == "XFAIL": sys.stdout.write(".") sys.stdout.flush() self.data += data def writeStderr(self): data = self.process.readAllStandardError().data().decode("utf-8").replace(r'\n', '\n') if "debug" in sys.argv: sys.stdout.write(data) self.data += data def doTestrun(self): data = self.fetchOutputForJob() last_failed = False for line in data.split('\n'): success = re.match(r"PASS\s*:\s*(.*)", line) if success: function = success.groups()[0] self.passed_tests.append(function) last_failed = False if last_failed: getLocation = re.match(r"\s*Loc:\s*\[(.*)\((\d*)\)]", line) if getLocation: filename = ".../" + '/'.join(getLocation.groups()[0].split('/')[-2:]) lineno = getLocation.groups()[1] self.failed_tests[-1].filename = filename self.failed_tests[-1].lineno = lineno last_failed = False fail = re.match(r"FAIL!\s*:\s*(.*)\((.*)\)\s+(.*)", line) if fail: function = fail.groups()[0] args = fail.groups()[1] function = function + "(" + args + ")" reason = fail.groups()[2] self.failed_tests.append(FailedTest(function, reason)) last_failed = True xfail = re.match(r"XFAIL\s*:\s*(.*)\((.*)\)\s+(.*)", line) if xfail: function = xfail.groups()[0] args = xfail.groups()[1] function = function + "(" + args + ")" reason = xfail.groups()[2] self.failed_tests.append(FailedTest(function, reason)) self.failed_tests[-1].failExpected = True last_failed = True fatal_fail = re.match(r"(QFATAL|ASSERT)\s*", line) if fatal_fail: print(self.data) print(red("Fatal error occured, aborting")) return passed, failed = len(self.passed_tests), len(self.failed_tests) try: percent = round((float(passed) / (failed+passed)) * 100) except ZeroDivisionError: percent = 0 percent = green(percent) if percent == 100 else yellow(percent) if percent > 80 else red(percent) total = white(passed+failed) passed, failed = green(passed), red(failed) print("\n Done. Summary: %s tests reported total, %s passed, %s failed (%s%% passed)." % (total, passed, failed, percent)) print(" Detailed information:\n") print(white(" ==="), green("Passed tests:"), white("===")) namespaceFunctionArgs = r"(.*)::(.*)\((.*)\)" if len(self.passed_tests): for test in self.passed_tests: test = re.match(namespaceFunctionArgs, test) test = test.groups() test = "[%s] " % test[0] + green(test[1]) + "(" + white(test[2]) + ")" print(indent(green("✔ ") + test)) if len(self.failed_tests): print("\n" + white(" ==="), red("Failed tests:"), white("===")) for test in self.failed_tests: namespace, function, args = re.match(namespaceFunctionArgs, test.name).groups() filename = test.filename.split('/')[-1] path = '/'.join(test.filename.split('/')[:-1]) + "/" print(indent((yellow("✘ ") if test.failExpected else red("✘ ")) + white(filename) + ":" + blue(test.lineno) + " "*(5-len(str(lineno))) + red(function) + "(" + yellow(args) + ")")) if 'noreason' not in sys.argv: print(indent("Reason of failure:" + blue(" ❮") + white(test.reason) + blue("❯ ") + ( "(Failure expected)" if test.failExpected else "" ), 2)) #print "[in %s]" % namespace def fetchOutputForJob(self): self.process = QProcess() self.process.readyReadStandardOutput.connect(self.writeStdout) self.process.readyReadStandardError.connect(self.writeStderr) print(" Please wait, running tests", end=' ') sys.stdout.flush() self.process.start(self.testfile, ["-maxwarnings", "0"]) self.process.waitForFinished(-1) return str(self.data)
class EjecutarWidget(QWidget): _script = '%s -e "bash -c ./%s;echo;echo;echo;echo -n Presione \<Enter\> '\ 'para salir.;read I"' def __init__(self): super(EjecutarWidget, self).__init__() self.compilado = False self.tiempo = 0.0 layoutV = QVBoxLayout(self) layoutV.setContentsMargins(0, 0, 0, 0) layoutV.setSpacing(0) self.output = salida.SalidaCompilador(self) layoutV.addWidget(self.output) self.setLayout(layoutV) # Procesos self.proceso_compilacion = QProcess(self) self.proceso_ejecucion = QProcess(self) # Conexión self.output.ir_a_linea.connect(self._emitir_ir_a_linea) self.proceso_compilacion.readyReadStandardError.connect( self.output.parsear_salida_stderr) self.proceso_compilacion.finished[int, QProcess.ExitStatus].connect( self.ejecucion_terminada) self.proceso_compilacion.error[QProcess.ProcessError].connect( self._error_compilacion) self.proceso_ejecucion.error[QProcess.ProcessError].connect( self._ejecucion_terminada) def _emitir_ir_a_linea(self, linea): self.emit(SIGNAL("ir_a_linea(int)"), linea) def _ejecucion_terminada(self, codigo_error): """ Éste método es ejecutado cuando la ejecución es frenada por el usuario o algún otro error. """ self.output.clear() if codigo_error == 1: error1 = salida.Item(self.tr("El proceso ha sido frenado")) error1.setForeground(Qt.blue) self.output.addItem(error1) else: error = salida.Item(self.tr("Ha ocurrido un error en la ejecución. " "Código de error: %s" % codigo_error)) error.setForeground(Qt.red) self.output.addItem(error) def correr_compilacion(self, nombre_archivo=''): """ Se corre el comando gcc para la compilación """ # Ejecutable directorio = QDir.fromNativeSeparators(nombre_archivo) self.ejecutable = directorio.split('/')[-1].split('.')[0] # Generar el ejecutable en el directorio del código fuente directorio_ejecutable = os.path.dirname(directorio) self.proceso_compilacion.setWorkingDirectory(directorio_ejecutable) self.output.clear() item = salida.Item(self.tr( "Compilando archivo: %s ( %s )" % (directorio.split('/')[-1], nombre_archivo))) self.output.addItem(item) gcc = GCC parametros_gcc = ['-Wall', '-o'] self.proceso_compilacion.start(gcc, parametros_gcc + [self.ejecutable] + [nombre_archivo]) self.proceso_compilacion.waitForFinished() def ejecucion_terminada(self, codigoError, exitStatus): """ Cuando la compilación termina @codigoError toma dos valores: 0 = La compilación ha terminado de forma correcta 1 = La compilación ha fallado """ if exitStatus == QProcess.NormalExit and codigoError == 0: item_ok = salida.Item(self.tr("¡COMPILACIÓN EXITOSA!")) item_ok.setForeground(QColor("#0046cc")) self.output.addItem(item_ok) else: item_error = salida.Item(self.tr("¡LA COMPILACIÓN HA FALLADO!")) item_error.setForeground(Qt.red) self.output.addItem(item_error) count = self.output.count() self.output.setCurrentRow(count - 1, QItemSelectionModel.NoUpdate) def _error_compilacion(self, error): """ Éste método se ejecuta cuando el inicio del proceso de compilación falla. Una de las causas puede ser la ausencia del compilador. """ texto = salida.Item(self.tr("Ha ocurrido un error: quizás el compilador" " no está instalado.")) texto.setForeground(Qt.red) self.output.addItem(texto) def correr_programa(self, archivo): """ Ejecuta el binario generado por el compilador """ #FIXME: Agregar terminal por defecto direc = os.path.dirname(archivo) self.proceso_ejecucion.setWorkingDirectory(direc) if configuracion.LINUX: proceso = 'xterm -T "%s" -e /usr/bin/cb_console_runner "%s"' \ % (self.ejecutable, os.path.join(direc, self.ejecutable)) # Run ! self.proceso_ejecucion.start(proceso) else: #FIXME: Usar QProcess Popen([os.path.join(direc, self.ejecutable)], creationflags=CREATE_NEW_CONSOLE) def compilar_ejecutar(self, archivo): self.correr_compilacion(archivo) self.correr_programa(archivo) def limpiar(self, archivo): """ Elimina el binario generado por la compilación """ if archivo is None: return binario = archivo.split('.')[0] if configuracion.WINDOWS: binario = binario + '.exe' os.remove(binario) def terminar_proceso(self): """ Termina el proceso """ self.proceso_ejecucion.kill()
class RenderW(QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.ui = ui_render.Ui_RenderW() self.ui.setupUi(self) self.fFreewheel = False self.fLastTime = -1 self.fMaxTime = 180 self.fTimer = QTimer(self) self.fProcess = QProcess(self) # ------------------------------------------------------------- # Get JACK client and base information global gJackClient if gJackClient: self.fJackClient = gJackClient else: self.fJackClient = jacklib.client_open("Render-Dialog", jacklib.JackNoStartServer, None) self.fBufferSize = int(jacklib.get_buffer_size(self.fJackClient)) self.fSampleRate = int(jacklib.get_sample_rate(self.fJackClient)) for i in range(self.ui.cb_buffer_size.count()): if int(self.ui.cb_buffer_size.itemText(i)) == self.fBufferSize: self.ui.cb_buffer_size.setCurrentIndex(i) break else: self.ui.cb_buffer_size.addItem(str(self.fBufferSize)) self.ui.cb_buffer_size.setCurrentIndex( self.ui.cb_buffer_size.count() - 1) # ------------------------------------------------------------- # Set-up GUI stuff # Get List of formats self.fProcess.start(gJackCapturePath, ["-pf"]) self.fProcess.waitForFinished() formats = str(self.fProcess.readAllStandardOutput(), encoding="utf-8").split(" ") formatsList = [] for i in range(len(formats) - 1): iFormat = formats[i].strip() if iFormat: formatsList.append(iFormat) formatsList.sort() # Put all formats in combo-box, select 'wav' option for i in range(len(formatsList)): self.ui.cb_format.addItem(formatsList[i]) if formatsList[i] == "wav": self.ui.cb_format.setCurrentIndex(i) self.ui.cb_depth.setCurrentIndex(4) #Float self.ui.rb_stereo.setChecked(True) self.ui.te_end.setTime(QTime(0, 3, 0)) self.ui.progressBar.setFormat("") self.ui.progressBar.setMinimum(0) self.ui.progressBar.setMaximum(1) self.ui.progressBar.setValue(0) self.ui.b_render.setIcon(getIcon("media-record")) self.ui.b_stop.setIcon(getIcon("media-playback-stop")) self.ui.b_close.setIcon(getIcon("window-close")) self.ui.b_open.setIcon(getIcon("document-open")) self.ui.b_stop.setVisible(False) self.ui.le_folder.setText(HOME) # ------------------------------------------------------------- # Set-up connections self.connect(self.ui.b_render, SIGNAL("clicked()"), SLOT("slot_renderStart()")) self.connect(self.ui.b_stop, SIGNAL("clicked()"), SLOT("slot_renderStop()")) self.connect(self.ui.b_open, SIGNAL("clicked()"), SLOT("slot_getAndSetPath()")) self.connect(self.ui.b_now_start, SIGNAL("clicked()"), SLOT("slot_setStartNow()")) self.connect(self.ui.b_now_end, SIGNAL("clicked()"), SLOT("slot_setEndNow()")) self.connect(self.ui.te_start, SIGNAL("timeChanged(const QTime)"), SLOT("slot_updateStartTime(const QTime)")) self.connect(self.ui.te_end, SIGNAL("timeChanged(const QTime)"), SLOT("slot_updateEndTime(const QTime)")) self.connect(self.ui.group_time, SIGNAL("clicked(bool)"), SLOT("slot_transportChecked(bool)")) self.connect(self.fTimer, SIGNAL("timeout()"), SLOT("slot_updateProgressbar()")) # ------------------------------------------------------------- self.loadSettings() @pyqtSlot() def slot_renderStart(self): if not os.path.exists(self.ui.le_folder.text()): QMessageBox.warning( self, self.tr("Warning"), self. tr("The selected directory does not exist. Please choose a valid one." )) return timeStart = self.ui.te_start.time() timeEnd = self.ui.te_end.time() minTime = (timeStart.hour() * 3600) + (timeStart.minute() * 60) + (timeStart.second()) maxTime = (timeEnd.hour() * 3600) + (timeEnd.minute() * 60) + (timeEnd.second()) newBufferSize = int(self.ui.cb_buffer_size.currentText()) useTransport = self.ui.group_time.isChecked() self.fFreewheel = bool(self.ui.cb_render_mode.currentIndex() == 1) self.fLastTime = -1 self.fMaxTime = maxTime if self.fFreewheel: self.fTimer.setInterval(100) else: self.fTimer.setInterval(500) self.ui.group_render.setEnabled(False) self.ui.group_time.setEnabled(False) self.ui.group_encoding.setEnabled(False) self.ui.b_render.setVisible(False) self.ui.b_stop.setVisible(True) self.ui.b_close.setEnabled(False) if useTransport: self.ui.progressBar.setFormat("%p%") self.ui.progressBar.setMinimum(minTime) self.ui.progressBar.setMaximum(maxTime) self.ui.progressBar.setValue(minTime) else: self.ui.progressBar.setFormat("") self.ui.progressBar.setMinimum(0) self.ui.progressBar.setMaximum(0) self.ui.progressBar.setValue(0) self.ui.progressBar.update() arguments = [] # Filename prefix arguments.append("-fp") arguments.append(self.ui.le_prefix.text()) # Format arguments.append("-f") arguments.append(self.ui.cb_format.currentText()) # Bit depth arguments.append("-b") arguments.append(self.ui.cb_depth.currentText()) # Channels arguments.append("-c") if self.ui.rb_mono.isChecked(): arguments.append("1") elif self.ui.rb_stereo.isChecked(): arguments.append("2") else: arguments.append(str(self.ui.sb_channels.value())) # Controlled only by freewheel if self.fFreewheel: arguments.append("-jf") # Controlled by transport elif useTransport: arguments.append("-jt") # Silent mode arguments.append("-dc") arguments.append("-s") # Change current directory os.chdir(self.ui.le_folder.text()) if newBufferSize != int(jacklib.get_buffer_size(self.fJackClient)): print("NOTICE: buffer size changed before render") jacklib.set_buffer_size(self.fJackClient, newBufferSize) if useTransport: if jacklib.transport_query( self.fJackClient, None ) > jacklib.JackTransportStopped: # rolling or starting jacklib.transport_stop(self.fJackClient) jacklib.transport_locate(self.fJackClient, minTime * self.fSampleRate) self.fProcess.start(gJackCapturePath, arguments) self.fProcess.waitForStarted() if self.fFreewheel: print("NOTICE: rendering in freewheel mode") sleep(1) jacklib.set_freewheel(self.fJackClient, 1) if useTransport: self.fTimer.start() jacklib.transport_start(self.fJackClient) @pyqtSlot() def slot_renderStop(self): useTransport = self.ui.group_time.isChecked() if useTransport: jacklib.transport_stop(self.fJackClient) if self.fFreewheel: jacklib.set_freewheel(self.fJackClient, 0) sleep(1) self.fProcess.close() if useTransport: self.fTimer.stop() self.ui.group_render.setEnabled(True) self.ui.group_time.setEnabled(True) self.ui.group_encoding.setEnabled(True) self.ui.b_render.setVisible(True) self.ui.b_stop.setVisible(False) self.ui.b_close.setEnabled(True) self.ui.progressBar.setFormat("") self.ui.progressBar.setMinimum(0) self.ui.progressBar.setMaximum(1) self.ui.progressBar.setValue(0) self.ui.progressBar.update() # Restore buffer size newBufferSize = int(jacklib.get_buffer_size(self.fJackClient)) if newBufferSize != self.fBufferSize: jacklib.set_buffer_size(self.fJackClient, newBufferSize) @pyqtSlot() def slot_getAndSetPath(self): getAndSetPath(self, self.ui.le_folder.text(), self.ui.le_folder) @pyqtSlot() def slot_setStartNow(self): time = int( jacklib.get_current_transport_frame(self.fJackClient) / self.fSampleRate) secs = time % 60 mins = int(time / 60) % 60 hrs = int(time / 3600) % 60 self.ui.te_start.setTime(QTime(hrs, mins, secs)) @pyqtSlot() def slot_setEndNow(self): time = int( jacklib.get_current_transport_frame(self.fJackClient) / self.fSampleRate) secs = time % 60 mins = int(time / 60) % 60 hrs = int(time / 3600) % 60 self.ui.te_end.setTime(QTime(hrs, mins, secs)) @pyqtSlot(QTime) def slot_updateStartTime(self, time): if time >= self.ui.te_end.time(): self.ui.te_end.setTime(time) renderEnabled = False else: renderEnabled = True if self.ui.group_time.isChecked(): self.ui.b_render.setEnabled(renderEnabled) @pyqtSlot(QTime) def slot_updateEndTime(self, time): if time <= self.ui.te_start.time(): self.ui.te_start.setTime(time) renderEnabled = False else: renderEnabled = True if self.ui.group_time.isChecked(): self.ui.b_render.setEnabled(renderEnabled) @pyqtSlot(bool) def slot_transportChecked(self, yesNo): if yesNo: renderEnabled = bool( self.ui.te_end.time() > self.ui.te_start.time()) else: renderEnabled = True self.ui.b_render.setEnabled(renderEnabled) @pyqtSlot() def slot_updateProgressbar(self): time = int(jacklib.get_current_transport_frame( self.fJackClient)) / self.fSampleRate self.ui.progressBar.setValue(time) if time > self.fMaxTime or (self.fLastTime > time and not self.fFreewheel): self.slot_renderStop() self.fLastTime = time def saveSettings(self): settings = QSettings("Cadence", "Cadence-Render") if self.ui.rb_mono.isChecked(): channels = 1 elif self.ui.rb_stereo.isChecked(): channels = 2 else: channels = self.ui.sb_channels.value() settings.setValue("Geometry", self.saveGeometry()) settings.setValue("OutputFolder", self.ui.le_folder.text()) settings.setValue("FilenamePrefix", self.ui.le_prefix.text()) settings.setValue("EncodingFormat", self.ui.cb_format.currentText()) settings.setValue("EncodingDepth", self.ui.cb_depth.currentText()) settings.setValue("EncodingChannels", channels) settings.setValue("UseTransport", self.ui.group_time.isChecked()) settings.setValue("StartTime", self.ui.te_start.time()) settings.setValue("EndTime", self.ui.te_end.time()) def loadSettings(self): settings = QSettings("Cadence", "Cadence-Render") self.restoreGeometry(settings.value("Geometry", "")) outputFolder = settings.value("OutputFolder", HOME) if os.path.exists(outputFolder): self.ui.le_folder.setText(outputFolder) self.ui.le_prefix.setText( settings.value("FilenamePrefix", "jack_capture_")) encFormat = settings.value("EncodingFormat", "Wav", type=str) for i in range(self.ui.cb_format.count()): if self.ui.cb_format.itemText(i) == encFormat: self.ui.cb_format.setCurrentIndex(i) break encDepth = settings.value("EncodingDepth", "Float", type=str) for i in range(self.ui.cb_depth.count()): if self.ui.cb_depth.itemText(i) == encDepth: self.ui.cb_depth.setCurrentIndex(i) break encChannels = settings.value("EncodingChannels", 2, type=int) if encChannels == 1: self.ui.rb_mono.setChecked(True) elif encChannels == 2: self.ui.rb_stereo.setChecked(True) else: self.ui.rb_outro.setChecked(True) self.ui.sb_channels.setValue(encChannels) self.ui.group_time.setChecked( settings.value("UseTransport", False, type=bool)) self.ui.te_start.setTime( settings.value("StartTime", self.ui.te_start.time(), type=QTime)) self.ui.te_end.setTime( settings.value("EndTime", self.ui.te_end.time(), type=QTime)) def closeEvent(self, event): self.saveSettings() if self.fJackClient: jacklib.client_close(self.fJackClient) QDialog.closeEvent(self, event) def done(self, r): QDialog.done(self, r) self.close()
class HostWindow(QMainWindow): # signals SIGTERM = pyqtSignal() SIGUSR1 = pyqtSignal() # -------------------------------------------------------------------------------------------------------- def __init__(self): QMainWindow.__init__(self) self.ui = Ui_HostWindow() self.ui.setupUi(self) # ---------------------------------------------------------------------------------------------------- # Internal stuff # Current mod-ui title #self.fCurrentBundle = "" self.fCurrentTitle = "" # Next bundle to load (done by startup arguments) self.fNextBundle = "" # first attempt of auto-start backend doesn't show an error self.fFirstBackendInit = True # need to call session reconnect after connecting the 1st time self.fNeedsSessionReconnect = False # Qt idle timer self.fIdleTimerId = 0 # Qt web frame, used for evaluating javascript self.fWebFrame = None # to be filled with key-value pairs of current settings self.fSavedSettings = {} # List of pedalboards self.fPedalboards = get_all_pedalboards() # List of current-pedalboard presets self.fPresetMenuList = [] # Process that runs the backend self.fProccessBackend = QProcess(self) self.fProccessBackend.setProcessChannelMode(QProcess.MergedChannels) self.fProccessBackend.setReadChannel(QProcess.StandardOutput) self.fStoppingBackend = False # Thread for managing the webserver self.fWebServerThread = WebServerThread(self) # ---------------------------------------------------------------------------------------------------- # Set up GUI self.ui.webview = QWebView(self.ui.swp_webview) self.ui.webview.setMinimumWidth(980) self.ui.swp_webview.layout().addWidget(self.ui.webview) self.ui.webpage = HostWebPage(self) self.ui.webpage.setViewportSize(QSize(980, 600)) self.ui.webview.setPage(self.ui.webpage) self.ui.webinspector = QWebInspector(None) self.ui.webinspector.resize(800, 600) self.ui.webinspector.setPage(self.ui.webpage) self.ui.webinspector.setVisible(False) self.ui.act_file_connect.setEnabled(False) self.ui.act_file_connect.setVisible(False) self.ui.act_file_disconnect.setEnabled(False) self.ui.act_file_disconnect.setVisible(False) self.ui.label_app.setText("MOD Application v%s" % config["version"]) # disable file menu self.ui.act_file_refresh.setEnabled(False) self.ui.act_file_inspect.setEnabled(False) # disable pedalboard menu self.ui.act_pedalboard_new.setEnabled(False) self.ui.act_pedalboard_open.setEnabled(False) self.ui.act_pedalboard_save.setEnabled(False) self.ui.act_pedalboard_save_as.setEnabled(False) self.ui.act_pedalboard_share.setEnabled(False) self.ui.menu_Pedalboard.setEnabled(False) # disable presets menu self.ui.act_presets_new.setEnabled(False) self.ui.act_presets_save.setEnabled(False) self.ui.act_presets_save_as.setEnabled(False) self.ui.menu_Presets.setEnabled(False) # initial stopped state self.slot_backendFinished(-1, -1) # Qt needs this so it properly creates & resizes the webview self.ui.stackedwidget.setCurrentIndex(1) self.ui.stackedwidget.setCurrentIndex(0) # FIXME #self.ui.act_backend_stop.setVisible(False) #self.ui.act_backend_restart.setVisible(False) # ---------------------------------------------------------------------------------------------------- # Set up GUI (special stuff for Mac OS) if MACOS: self.ui.act_file_quit.setMenuRole(QAction.QuitRole) self.ui.act_settings_configure.setMenuRole(QAction.PreferencesRole) self.ui.act_help_about.setMenuRole(QAction.AboutRole) #self.ui.menu_Settings.setTitle("Panels") #self.ui.menu_Help.hide() # ---------------------------------------------------------------------------------------------------- # Load Settings self.loadSettings(True) # ---------------------------------------------------------------------------------------------------- # Connect actions to functions self.SIGUSR1.connect(self.slot_handleSIGUSR1) self.SIGTERM.connect(self.slot_handleSIGTERM) self.fProccessBackend.error.connect(self.slot_backendError) self.fProccessBackend.started.connect(self.slot_backendStarted) self.fProccessBackend.finished.connect(self.slot_backendFinished) self.fProccessBackend.readyRead.connect(self.slot_backendRead) self.fWebServerThread.running.connect(self.slot_webServerRunning) self.fWebServerThread.finished.connect(self.slot_webServerFinished) self.ui.act_file_refresh.triggered.connect(self.slot_fileRefresh) self.ui.act_file_inspect.triggered.connect(self.slot_fileInspect) self.ui.act_settings_configure.triggered.connect(self.slot_configure) self.ui.act_help_about.triggered.connect(self.slot_about) self.ui.act_help_project.triggered.connect(self.slot_showProject) self.ui.act_help_website.triggered.connect(self.slot_showWebsite) self.ui.b_start.clicked.connect(self.slot_backendStart) self.ui.b_configure.clicked.connect(self.slot_configure) self.ui.b_about.clicked.connect(self.slot_about) # force our custom refresh webReloadAction = self.ui.webpage.action(QWebPage.Reload) webReloadAction.triggered.disconnect() webReloadAction.triggered.connect(self.slot_fileRefresh) # ---------------------------------------------------------------------------------------------------- # Final setup self.setProperWindowTitle() SESSION.setupApp(self._pedal_changed_callback) if not "--no-autostart" in sys.argv: QTimer.singleShot(0, self.slot_backendStart) QTimer.singleShot(1, self.fixWebViewSize) def __del__(self): self.stopAndWaitForWebServer() self.stopAndWaitForBackend() def _pedal_changed_callback(self, ok, bundlepath, title): #self.fCurrentBundle = bundlepath self.fCurrentTitle = title or "" #self.updatePresetsMenu() self.setProperWindowTitle() # -------------------------------------------------------------------------------------------------------- # Files (menu actions) @pyqtSlot() def slot_fileRefresh(self): if self.fWebFrame is None: return self.ui.label_progress.setText(self.tr("Refreshing UI...")) self.ui.stackedwidget.setCurrentIndex(0) QTimer.singleShot(0, self.ui.webview.reload) @pyqtSlot() def slot_fileInspect(self): self.ui.webinspector.show() # -------------------------------------------------------------------------------------------------------- # Settings (menu actions) @pyqtSlot() def slot_configure(self): dialog = SettingsWindow(self, True) if not dialog.exec_(): return self.loadSettings(False) # -------------------------------------------------------------------------------------------------------- # About (menu actions) @pyqtSlot() def slot_about(self): QMessageBox.about( self, self.tr("About"), self.tr(""" <b>MOD Desktop Application</b><br/> <br/> A software to have the complete MOD environment running in your desktop.<br/> (C) 2015-2016 - The MOD Team<br/> <br/> Publications, products, content or services referenced herein or on the website are the exclusive trademarks or servicemarks of MOD.<br/> Other product and company names mentioned in the site may be the trademarks of their respective owners.<br/> <br/> All software is available under the <a href="https://www.gnu.org/licenses/gpl-2.0.html">GPL license</a>.<br/> """)) @pyqtSlot() def slot_showProject(self): QDesktopServices.openUrl(QUrl("https://github.com/moddevices/mod-app")) @pyqtSlot() def slot_showWebsite(self): QDesktopServices.openUrl(QUrl("http://moddevices.com/")) # -------------------------------------------------------------------------------------------------------- # Backend (menu actions) @pyqtSlot() def slot_backendInformation(self): table = """ <table><tr> <td> MOD-UI port: <td></td> %s </td> </tr></table> """ % (config["port"], ) QMessageBox.information(self, self.tr("information"), table) @pyqtSlot() def slot_backendStart(self): if self.fProccessBackend.state() != QProcess.NotRunning: print("slot_backendStart ignored") return print("slot_backendStart in progress...") hostPath = self.fSavedSettings[MOD_KEY_HOST_PATH] if hostPath.endswith("ingen"): hostPath = MOD_DEFAULT_HOST_PATH hostArgs = ["-p", "5555", "-f", "5556"] if self.fSavedSettings[MOD_KEY_HOST_VERBOSE]: hostArgs.append("-v") else: hostArgs.append("-n") self.fProccessBackend.start(hostPath, hostArgs) @pyqtSlot() def slot_backendStop(self): #if self.fPluginCount > 0: #if not forced: #ask = QMessageBox.question(self, self.tr("Warning"), self.tr("There are still some plugins loaded, you need to remove them to stop the engine.\n" #"Do you want to do this now?"), #QMessageBox.Yes | QMessageBox.No, QMessageBox.No) #if ask != QMessageBox.Yes: #return #self.removeAllPlugins() #self.host.set_engine_about_to_close() #self.host.remove_all_plugins() # testing red color for server stopped self.ui.webview.blockSignals(True) self.ui.webview.setHtml("<html><body bgcolor='green'></body></html>") self.ui.webview.blockSignals(False) self.stopAndWaitForWebServer() self.stopAndWaitForBackend() @pyqtSlot() def slot_backendRestart(self): self.slot_backendStop() self.slot_backendStart() # -------------------------------------------------------------------------------------------------------- @pyqtSlot() def slot_backendStarted(self): self.ui.act_backend_start.setEnabled(False) self.ui.act_backend_stop.setEnabled(True) self.ui.act_backend_restart.setEnabled(True) self.ui.w_buttons.setEnabled(False) self.ui.label_progress.setText(self.tr("Loading backend...")) @pyqtSlot(int, QProcess.ExitStatus) def slot_backendFinished(self, exitCode, exitStatus): self.fFirstBackendInit = False self.fStoppingBackend = False self.ui.act_backend_start.setEnabled(True) self.ui.act_backend_stop.setEnabled(False) self.ui.act_backend_restart.setEnabled(False) self.ui.w_buttons.setEnabled(True) self.ui.label_progress.setText("") self.ui.stackedwidget.setCurrentIndex(0) # stop webserver self.stopAndWaitForWebServer() @pyqtSlot(QProcess.ProcessError) def slot_backendError(self, error): firstBackendInit = self.fFirstBackendInit self.fFirstBackendInit = False # stop webserver self.stopAndWaitForWebServer() # crashed while stopping, ignore if error == QProcess.Crashed and self.fStoppingBackend: return errorStr = self.tr("Could not start host backend.\n" ) + self.getProcessErrorAsString(error) qWarning(errorStr) # don't show error if this is the first time starting the host or using live-iso if firstBackendInit: return # show the error message QMessageBox.critical(self, self.tr("Error"), errorStr) @pyqtSlot() def slot_backendRead(self): #if self.fProccessBackend.state() != QProcess.Running: #return for line in str( self.fProccessBackend.readAllStandardOutput().trimmed(), encoding="utf-8", errors="ignore").strip().split("\n"): line = line.replace("\x1b[0m", "").replace("\x1b[0;31m", "").replace("\x1b[0;33m", "").strip() if not line: continue if self.fSavedSettings[MOD_KEY_HOST_VERBOSE]: print("BACKEND:", line) if line == "mod-host ready!" or line == "mod-host is running.": QTimer.singleShot(0, self.slot_backendStartPhase2) #elif "Listening on socket " in line: #QTimer.singleShot(1000, self.slot_ingenStarted) ##elif "Activated Jack client " in line: ##QTimer.singleShot(1000, self.fWebServerThread.start) #elif "Failed to create UNIX socket" in line or "Could not activate Jack client" in line: ## need to wait for ingen to create sockets so it can delete them on termination #QTimer.singleShot(1000, self.slot_ingenStartError) @pyqtSlot() def slot_backendStartPhase2(self): if self.fProccessBackend.state() == QProcess.NotRunning: return if not self.fNeedsSessionReconnect: # we'll need it for next time self.fNeedsSessionReconnect = True else: # we need it now SESSION.reconnectApp() self.fWebServerThread.start() @pyqtSlot() def slot_backendStartError(self): self.stopAndWaitForBackend() self.slot_backendError(-2) # -------------------------------------------------------------------------------------------------------- # Web Server @pyqtSlot() def slot_webServerRunning(self): self.ui.webview.loadStarted.connect(self.slot_webviewLoadStarted) self.ui.webview.loadProgress.connect(self.slot_webviewLoadProgress) self.ui.webview.loadFinished.connect(self.slot_webviewLoadFinished) print("webserver running with URL:", config["addr"]) self.ui.webview.load(QUrl(config["addr"])) @pyqtSlot() def slot_webServerFinished(self): try: self.ui.webview.loadStarted.disconnect( self.slot_webviewLoadStarted) self.ui.webview.loadProgress.disconnect( self.slot_webviewLoadProgress) self.ui.webview.loadFinished.disconnect( self.slot_webviewLoadFinished) except: pass print("webserver finished") # testing red color for server finished self.ui.webview.blockSignals(True) self.ui.webview.setHtml("<html><body bgcolor='red'></body></html>") self.ui.webview.blockSignals(False) # -------------------------------------------------------------------------------------------------------- # Web View @pyqtSlot() def slot_webviewLoadStarted(self): self.ui.label_progress.setText(self.tr("Loading UI...")) print("load started") @pyqtSlot(int) def slot_webviewLoadProgress(self, progress): self.ui.label_progress.setText(self.tr("Loading UI... %i%%" % progress)) @pyqtSlot(bool) def slot_webviewLoadFinished(self, ok): self.ui.webview.loadStarted.disconnect(self.slot_webviewLoadStarted) self.ui.webview.loadProgress.disconnect(self.slot_webviewLoadProgress) self.ui.webview.loadFinished.disconnect(self.slot_webviewLoadFinished) if ok: # message self.ui.label_progress.setText(self.tr("Loading UI... finished!")) # enable file menu self.ui.act_file_refresh.setEnabled(True) self.ui.act_file_inspect.setEnabled(True) # for js evaulation self.fWebFrame = self.ui.webpage.currentFrame() # postpone app stuff QTimer.singleShot(100, self.slot_webviewPostFinished) else: # message self.ui.label_progress.setText(self.tr("Loading UI... failed!")) # disable file menu self.ui.act_file_refresh.setEnabled(False) self.ui.act_file_inspect.setEnabled(False) # disable pedalboard menu self.ui.act_pedalboard_new.setEnabled(False) self.ui.act_pedalboard_open.setEnabled(False) self.ui.act_pedalboard_save.setEnabled(False) self.ui.act_pedalboard_save_as.setEnabled(False) self.ui.act_pedalboard_share.setEnabled(False) self.ui.menu_Pedalboard.setEnabled(False) # stop js evaulation self.fWebFrame = None # stop backend&server self.stopAndWaitForWebServer() self.stopAndWaitForBackend() print("load finished") @pyqtSlot() def slot_webviewPostFinished(self): if self.fNextBundle: bundle = self.fNextBundle self.fNextBundle = "" self.fWebFrame.evaluateJavaScript( "desktop.loadPedalboard(\"%s\")" % bundle) QTimer.singleShot(0, self.slot_webviewPostFinished2) @pyqtSlot() def slot_webviewPostFinished2(self): self.ui.stackedwidget.setCurrentIndex(1) # -------------------------------------------------------------------------------------------------------- # Settings def saveSettings(self): settings = QSettings() settings.setValue("Geometry", self.saveGeometry()) def loadSettings(self, firstTime): qsettings = QSettings() websettings = self.ui.webview.settings() self.fSavedSettings = { # Main MOD_KEY_MAIN_PROJECT_FOLDER: qsettings.value(MOD_KEY_MAIN_PROJECT_FOLDER, MOD_DEFAULT_MAIN_PROJECT_FOLDER, type=str), MOD_KEY_MAIN_REFRESH_INTERVAL: qsettings.value(MOD_KEY_MAIN_REFRESH_INTERVAL, MOD_DEFAULT_MAIN_REFRESH_INTERVAL, type=int), # Host MOD_KEY_HOST_VERBOSE: qsettings.value(MOD_KEY_HOST_VERBOSE, MOD_DEFAULT_HOST_VERBOSE, type=bool), MOD_KEY_HOST_PATH: qsettings.value(MOD_KEY_HOST_PATH, MOD_DEFAULT_HOST_PATH, type=str), # WebView MOD_KEY_WEBVIEW_INSPECTOR: qsettings.value(MOD_KEY_WEBVIEW_INSPECTOR, MOD_DEFAULT_WEBVIEW_INSPECTOR, type=bool), MOD_KEY_WEBVIEW_VERBOSE: qsettings.value(MOD_KEY_WEBVIEW_VERBOSE, MOD_DEFAULT_WEBVIEW_VERBOSE, type=bool), MOD_KEY_WEBVIEW_SHOW_INSPECTOR: qsettings.value(MOD_KEY_WEBVIEW_SHOW_INSPECTOR, MOD_DEFAULT_WEBVIEW_SHOW_INSPECTOR, type=bool) } inspectorEnabled = self.fSavedSettings[MOD_KEY_WEBVIEW_INSPECTOR] websettings.setAttribute(QWebSettings.DeveloperExtrasEnabled, inspectorEnabled) if firstTime: if qsettings.contains("Geometry"): self.restoreGeometry(qsettings.value("Geometry", "")) else: self.setWindowState(self.windowState() | Qt.WindowMaximized) if inspectorEnabled and self.fSavedSettings[ MOD_KEY_WEBVIEW_SHOW_INSPECTOR]: QTimer.singleShot(1000, self.ui.webinspector.show) self.ui.act_file_inspect.setVisible(inspectorEnabled) if self.fIdleTimerId != 0: self.killTimer(self.fIdleTimerId) self.fIdleTimerId = self.startTimer( self.fSavedSettings[MOD_KEY_MAIN_REFRESH_INTERVAL]) # -------------------------------------------------------------------------------------------------------- # Misc @pyqtSlot() def slot_handleSIGUSR1(self): print("Got SIGUSR1 -> Saving project now") self.slot_pedalboardSave() @pyqtSlot() def slot_handleSIGTERM(self): print("Got SIGTERM -> Closing now") self.close() # -------------------------------------------------------------------------------------------------------- # Qt events def closeEvent(self, event): if self.fIdleTimerId != 0: self.killTimer(self.fIdleTimerId) self.fIdleTimerId = 0 self.saveSettings() self.slot_backendStop() QMainWindow.closeEvent(self, event) # Needed in case the web inspector is still alive #self.ui.webinspector.close() QApplication.instance().quit() def timerEvent(self, event): if event.timerId() == self.fIdleTimerId: pass QMainWindow.timerEvent(self, event) def resizeEvent(self, event): QMainWindow.resizeEvent(self, event) self.fixWebViewSize() # -------------------------------------------------------------------------------------------------------- # Internal stuff def getProcessErrorAsString(self, error): if error == -2: return self.tr("Ingen failed to create UNIX socket.") if error == QProcess.FailedToStart: return self.tr("Process failed to start.") if error == QProcess.Crashed: return self.tr("Process crashed.") if error == QProcess.Timedout: return self.tr("Process timed out.") if error == QProcess.WriteError: return self.tr("Process write error.") return self.tr("Unkown error.") def fixWebViewSize(self): if self.ui.stackedwidget.currentIndex() == 1: return size = self.ui.swp_intro.size() self.ui.swp_webview.resize(size) self.ui.webview.resize(size) self.ui.webpage.setViewportSize(size) def stopAndWaitForBackend(self): SESSION.host.close_jack() if self.fProccessBackend.state() == QProcess.NotRunning: return self.fStoppingBackend = True self.fProccessBackend.terminate() if not self.fProccessBackend.waitForFinished(2000): qWarning("Backend failed top stop cleanly, forced kill") self.fProccessBackend.kill() def stopAndWaitForWebServer(self): if not self.fWebServerThread.isRunning(): return if not self.fWebServerThread.stopWait(): qWarning( "WebServer Thread failed top stop cleanly, forced terminate") self.fWebServerThread.terminate() def setProperWindowTitle(self): title = "MOD Application" if self.fCurrentTitle: title += " - %s" % self.fCurrentTitle self.setWindowTitle(title)
class FrD_NukeBatchRender(QtGui.QMainWindow, form_class): def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.setupUi(self) self.setWindowTitle('FrD Nuke Batch Render' + PROGRAM_VERSION) self.output_LW.setEnabled(0) # ============================ STYLE ======================= # # Progress Bar Style PB_STYLE = """ QProgressBar { border: 2px solid grey; border-radius: 5px; text-align: center; } QProgressBar::chunk { background-color: #d7801a; width: 3px; margin: 1.5px; } """ # self.PB.setStyleSheet(PB_STYLE) # QMenuBar Style MB_STYLE = """ QMenuBar::item { background: transparent; } QMenuBar::item:selected { background: background-color: rgb(49,49,49); border: 1px solid #000; } QMenuBar::item:pressed { background: #444; border: 1px solid #000; background-color: QLinearGradient( x1:0, y1:0, x2:0, y2:1, stop:1 #212121, stop:0.4 #343434/*, stop:0.2 #343434, stop:0.1 #ffaa00*/ ); margin-bottom:-1px; padding-bottom:1px; } """ self.menuFiles.setStyleSheet(MB_STYLE) # ============================ STYLE ======================= # # Enable Drah and Drop self.Queue_TW.setAcceptDrops(True) # Set up handlers for the TableWidget self.Queue_TW.dragEnterEvent = self.twDragEnterEvent self.Queue_TW.dragMoveEvent = self.twDragMoveEvent self.Queue_TW.dropEvent = self.twDropEvent # Size of Table Columns self.Queue_TW.setColumnWidth(0, 250) self.Queue_TW.setColumnWidth(1, 300) self.Queue_TW.setColumnWidth(2, 100) self.Queue_TW.setColumnWidth(3, 100) self.Queue_TW.setColumnWidth(4, 310) self.Queue_TW.setColumnWidth(5, 110) # operation ALL self.Clear_BN.clicked.connect(self.ClearQueue) self.Update_BN.clicked.connect(self.UpdateQueue) # Render self.Render_BN.clicked.connect(self.NBR_render) # ============ Drag and Drop Event) ============ # def twDragEnterEvent(self, event): if event.mimeData().hasUrls: event.accept() else: event.ignore() def twDragMoveEvent(self, event): if event.mimeData().hasUrls: event.setDropAction(QtCore.Qt.CopyAction) event.accept() else: event.ignore() def twDropEvent(self, event): if event.mimeData().hasUrls: event.setDropAction(QtCore.Qt.CopyAction) event.accept() links = [] for url in event.mimeData().urls(): links.append(str(url.toLocalFile())) # print links self.nukeProjDropped(links) else: event.ignore() # ============ Drag and Drop Ends ============ # # ============ Clear and Update All ============ # def NBR_askMsg(self, title, text): qmsgBox = QtGui.QMessageBox() qmsgBox.setStyleSheet('QMessageBox {background-color: #333; font-size: 12pt; font-family: Trebuchet MS}\nQLabel{color:white;}') # 585858 return QtGui.QMessageBox.question(qmsgBox, title, text, QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel) # | QtGui.QMessageBox.No def ClearQueue(self): global folderQueue if self.Queue_TW.rowCount() > 0: if (self.NBR_askMsg('Clear Render Queue', 'Are you sure you want to clear the whole Render Queue?') == QtGui.QMessageBox.Yes): self.Queue_TW.setRowCount(0) folderQueue = [] QtGui.QApplication.processEvents() def UpdateQueue(self): global folderQueue for project in xrange(len(folderQueue)): pass # ========== Clear and Update All Ends ========== # def nukeProjDropped(self, arg): global folderQueue appendedList = [] for url in sorted(arg): if os.path.exists(url) and os.path.isfile(url) and url.lower().endswith('.nk'): if url in folderQueue: pass else: appendedList.append(url) folderQueue.append(url) # Add table row rowPosition = self.Queue_TW.rowCount() self.Queue_TW.insertRow(rowPosition) # get All Write Node from .nk # QProcess for nuke self.nukeProcess = QProcess(self) self.nukeProcess.setProcessChannelMode(QProcess.MergedChannels) args = self.createCmdArg(str(url)) self.nukeProcess.start(NUKE_EXE, args) # For debug: read output lines self.nukeProcess.readyRead.connect(self.NBR_debug) self.nukeProcess.waitForFinished() self.nukeProcess.close() # Add row and info to table self.NBR_createCheckBoxItemTableWidget(rowPosition, 0, os.path.splitext(os.path.basename(url))[0]) # Get the write nodes from text files (D:/Temp/nukeBatch) layout = QtGui.QVBoxLayout() layout.setAlignment(QtCore.Qt.AlignLeft) with open("D:\\Temp\\nukeBatch\\" + os.path.basename(url) + ".txt", "r") as ins: bframe = False bCount = 0 for line in ins: if 'FrameRange:' in line: bframe = True continue if (bframe is False): item = QtGui.QCheckBox(str(line).strip()) item.setChecked(True) item.setFont(QtGui.QFont('meiryo', 9)) layout.addWidget(item) elif (bframe is True): self.NBR_createEditTextItemTableWidget(rowPosition, 2 + bCount, int(str(line).strip())) bCount += 1 cellWidget = QtGui.QWidget() cellWidget.setLayout(layout) self.Queue_TW.setCellWidget(rowPosition, 1, cellWidget) self.Queue_TW.resizeRowsToContents() self.Queue_TW.scrollToBottom() QtGui.QApplication.processEvents() def createCmdArg(self, nk): # nk = url return ["-ti", CHECKING_NK, nk] def createCmdArg2(self, nk, start, end, wnode=[]): return ["-ti", RENDER_NK, nk, wnode, start, end] def NBR_debug(self): while (self.nukeProcess.canReadLine()): print (str(self.nukeProcess.readLine())) def NBR_createCheckBoxItemTableWidget(self, row, col, text, color='#4c4c4c'): layout = QtGui.QVBoxLayout() layout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) item = QtGui.QCheckBox(text) item.setChecked(True) item.setFont(QtGui.QFont('meiryo', 9)) layout.addWidget(item) cellWidget = QtGui.QWidget() cellWidget.setStyleSheet('color:white; background-color:' + color) cellWidget.setLayout(layout) self.Queue_TW.setCellWidget(row, col, cellWidget) # self.Queue_TW.setItem(row, 0, QtGui.QTableWidgetItem(str(text))) def NBR_createEditTextItemTableWidget(self, row, col, text, color='#4c4c4c'): layout = QtGui.QVBoxLayout() layout.setAlignment(QtCore.Qt.AlignCenter) item = QtGui.QSpinBox() item.setMaximum(9999) item.setValue(text) item.setFont(QtGui.QFont('meiryo', 9)) layout.addWidget(item) cellWidget = QtGui.QWidget() cellWidget.setStyleSheet('color:white; background-color:' + color) cellWidget.setLayout(layout) self.Queue_TW.setCellWidget(row, col, cellWidget) def NBR_getCellData(self, row, col, key): cellDict = {} target = self.Queue_TW.cellWidget(row, col) if target: lay = target.layout() if lay: for k in xrange(lay.count()): w = lay.itemAt(k).widget() if isinstance(w, QtGui.QCheckBox): cellDict[key] = w.checkState() # 0 false, > 0 true elif isinstance(w, QtGui.QSpinBox): cellDict[key] = w.value() return cellDict def NBR_getCellNodeData(self, row, col): target = self.Queue_TW.cellWidget(row, col) cellUserInputList = [] if target: lay = target.layout() if lay: for k in xrange(lay.count()): w = lay.itemAt(k).widget() if isinstance(w, QtGui.QCheckBox): cellUserInputList.append([str(w.text()), w.checkState()]) else: cellUserInputList.append(-1) return cellUserInputList def NBR_render(self): global folderQueue for nk in xrange(len(folderQueue)): renderNode = [] # proj = os.path.splitext(os.path.basename(folderQueue[nk]))[0] projDict = self.NBR_getCellData(nk, 0, 'Project') if int(projDict['Project']) > 0: nodeArr = self.NBR_getCellNodeData(nk, 1) startDict = self.NBR_getCellData(nk, 2, 'Start') endDict = self.NBR_getCellData(nk, 3, 'End') # Write nodes loop for node in xrange(len(nodeArr)): if nodeArr[node][1] > 0: # get each node check state (0/2), selected write node (render) renderNode.append(nodeArr[node][0].split(":")[0]) # Debug print str(renderNode) # print nodeArr self.nukeProcess = QProcess(self) # QProcess for nuke print nodeArr[node][0].split(":")[0] # get each node from array self.nukeProcess.setProcessChannelMode(QProcess.MergedChannels) args = self.createCmdArg2(str(folderQueue[nk]), renderNode, startDict['Start'], endDict['End']) self.nukeProcess.start(NUKE_EXE, str(args)) self.nukeProcess.readyRead.connect(self.NBR_debug) self.nukeProcess.waitForFinished() self.nukeProcess.close()
class Dlg(QDialog, Ui_Dialog): def __init__(self, parent=None): super(Dlg, self).__init__(parent) self.setupUi(self) self.dockWidget.hide() self.fileLineEdit.setDisabled(True) self.fileButton.setDisabled(True) self.closeButton.clicked.connect(self.close) self.buildButton.clicked.connect(self.build) self.fileButton.clicked.connect(self.getFile) self.fileRadioButton.toggled.connect(self.fileLineEdit.setEnabled) self.fileRadioButton.toggled.connect(self.fileButton.setEnabled) self.logButton.toggled.connect(self.dockWidget.setVisible) for button in (self.sourceButton, self.outputButton): button.clicked.connect(self.getDirectory) self.sourceDirectory = None self.outputDirectory = None self.process = QProcess() self.process.readyReadStandardOutput.connect(self.readOutput) self.process.readyReadStandardError.connect(self.readErrors) #restore settings settings = QSettings() size = settings.value('Dialog/Size', QVariant(QSize(600, 500))).toSize() self.resize(size) pos = settings.value('Dialog/Position', QVariant(QPoint(0, 0))).toPoint() self.move(pos) for widget, setting in ((self.sourceLineEdit, 'Data/SourceDirectory'), (self.outputLineEdit, 'Data/OutputDirectory')): widget.setText(settings.value(setting).toString()) def closeEvent(self, event): """Save settings and exit""" settings = QSettings() for value, setting in ((self.size(), 'Dialog/Size'), (self.pos(), 'Dialog/Position'), (self.sourceDirectory, 'Data/SourceDirectory'), (self.outputDirectory, 'Data/OutputDirectory')): settings.setValue(setting, QVariant(value)) def getDirectory(self): """Opens the platform dialog to select directory""" sender = self.sender() if sender is self.sourceButton: receiver = self.sourceLineEdit elif sender is self.outputButton: receiver = self.outputLineEdit fname = QFileDialog.getExistingDirectory(self, 'Select Directory') if fname: receiver.setText(fname) def getFile(self): """Opens the platform file open dialog to select a file""" if not self.sourceDirectory: source_dir = self.sourceLineEdit.text() else: source_dir = self.sourceDirectory fname = QFileDialog.getOpenFileName(self, 'Select File', source_dir) if fname: self.fileLineEdit.setText(fname) def build(self): """Main function calling sphinx-build to generate the project""" self.statusLabel.clear() self.buildButton.setDisabled(True) self.sourceDirectory = str(self.sourceLineEdit.text().trimmed()) self.outputDirectory = str(self.outputLineEdit.text().trimmed()) if not len(self.sourceDirectory): self.logBrowser.append('Source directory cannot be empty') if not len(self.outputDirectory): self.logBrowser.append('Output directory cannot be empty') if not(len(self.sourceDirectory) or len(self.outputDirectory)): self.buildButton.setDisabled(False) return self.logBrowser.clear() self.logBrowser.append(self.formatInfoMsg('Building. Please wait...')) fname = None if self.fileRadioButton.isChecked(): fname = str(self.fileLineEdit.text().trimmed()) args = ['-b', 'html', self.sourceDirectory, self.outputDirectory] if fname: args.append(fname) self.statusLabel.setText(self.formatInfoMsg('Running sphinx-build...')) QApplication.processEvents() self.process.start(SPHINX_BUILD, args) if (not self.process.waitForFinished(-1)): msg = self.formatErrorMsg('Build Failed!') self.logBrowser.append(msg) self.statusLabel.setText(msg) self.buildButton.setEnabled(True) return QApplication.processEvents() self.buildButton.setEnabled(True) self.statusLabel.setText(self.formatInfoMsg('Finished')) def readOutput(self): """Read and append sphinx-build output to the logBrowser""" msg = str(QString(self.process.readAllStandardOutput())) self.logBrowser.append(msg) def readErrors(self): """Read and append sphinx-build errors to the logBrowser""" msg = str(QString(self.process.readAllStandardError())) self.logBrowser.append(self.formatErrorMsg(msg)) def formatErrorMsg(self, msg): """Format error messages in red color""" return self.formatMsg(msg, 'red') def formatInfoMsg(self, msg): """Format informative messages in blue color""" return self.formatMsg(msg, 'blue') def formatMsg(self, msg, color): """Format message with the given color""" msg = '<font color="%s">%s</font>' % (color, msg) return msg
def newProject(path): initProcess=QProcess(None) initProcess.setWorkingDirectory(path) initProcess.start("ino",['init']) initProcess.waitForFinished() return initProcess.exitCode()==0
def to_BTX(filename, out_file=None): if out_file == None: out_file = os.path.splitext(filename)[0] + ".btx" global extension try: os.makedirs(TEMP_DIR) except: pass # Convert to indexed. if ( len(QImage(filename).colorTable()) > 256 or len(QImage(filename).colorTable()) == 0 ) and not args.SHTXFF and not args.SHTXFf and not ".SHTXFF" in filename and not ".SHTXFf" in filename and not ".shtxff" in filename: process = QProcess() if args.SHTX or ".SHTX." in out_file or ".shtx." in filename: options = [ "--force", "--speed", "1", "16", "--output", TEMP_FILE, filename ] else: options = [ "--force", "--speed", "1", "256", "--output", TEMP_FILE, filename ] process.start(QUANT_PATH, options) process.waitForFinished(-1) # If it didn't output anything, the image is already indexed. if not os.path.isfile(TEMP_FILE): temp_file = filename else: temp_file = TEMP_FILE img = QImage(temp_file) #if not img.format() == QImage.Format_Indexed8: #print "Failed to convert", filename #print "Couldn't convert image to indexed." #print #return False if args.SHTXFs or ".SHTXFs." in filename: data = to_SHTXFs(img) extension = "SHTXFs" elif args.SHTXFf or ".SHTXFf." in out_file: data = to_SHTXFf(img) extension = "SHTXFf" elif args.SHTXFF or ".SHTXFF." in out_file or ".shtxff." in filename: data = to_SHTXFF(img) extension = "SHTXFF" elif args.SHTX or ".SHTX." in out_file or ".shtx." in filename: data = to_SHTX(img) extension = "SHTX" else: data = to_SHTXFS(img) extension = "SHTXFS" if os.path.isfile(TEMP_FILE): os.remove(TEMP_FILE) if data: with open(out_file, "wb") as f: f.write(data) return True return False
class Window(mainwindow, ui_mainwindow): def __init__(self): QMainWindow.__init__(self) self.setWindowIcon(QIcon(":/scanner.png")) QIcon.setThemeName("Adwaita") self.setupUi(self) close_icon = QApplication.style().standardIcon(QStyle.SP_DialogCloseButton) self.closeBtn.setIcon(close_icon) # connect signals self.comboDevice.currentIndexChanged.connect(self.onDeviceChange) self.comboColor.currentIndexChanged.connect(self.onColorModeChange) self.scanBtn.clicked.connect(self.startScanning) self.closeBtn.clicked.connect(self.close) self.process = QProcess(self) QTimer.singleShot(100, self.updateDeviceList) def updateDeviceList(self): self.devices_info = get_devices() if len(self.devices_info)>0: self.comboDevice.clear() models = [ dev['model'] for dev in self.devices_info] self.comboDevice.addItems(models) self.selectDevice(0) def selectDevice(self, index): self.scanner = get_backend_from_scanner_device(self.devices_info[index]) self.comboColor.clear() self.comboResolution.clear() self.comboArea.clear() self.comboColor.addItems(self.scanner.supportedColorModes()) self.comboResolution.addItems(self.scanner.supportedResolutions()) self.comboArea.addItems(self.scanner.supportedScanAreas()) # Init values self.comboColor.setCurrentIndex(self.scanner.default_color_index) self.comboResolution.setCurrentIndex(self.scanner.default_resolution_index) self.comboArea.setCurrentIndex(self.scanner.default_scan_area_index) self.labelExt.setText(self.scanner.extension) self.filenameEdit.setText(self.newFileName()) def onDeviceChange(self, index): self.selectDevice(index) def onColorModeChange(self, index): """ Change file format on colormode change """ self.scanner.setSelectedColor(index) self.labelExt.setText(self.scanner.extension) self.filenameEdit.setText(self.newFileName()) def startScanning(self): if self.comboDevice.count()==0: return self.scanner.setSelectedColor(self.comboColor.currentIndex()) self.scanner.setSelectedResolution(self.comboResolution.currentIndex()) self.scanner.setSelectedScanArea(self.comboArea.currentIndex()) ext = self.scanner.extension args = self.scanner.getArgs() self.statusbar.showMessage("Scan Started") wait(20) self.process.start('scanimage', args) if not self.process.waitForFinished(-1) or self.process.exitCode(): self.statusbar.showMessage("Scanning Failed !") return data = self.process.readAllStandardOutput() filename = self.filenameEdit.text() + ext # to get more accurate scanned area when A4 at 300 dpi if (self.scanner.crop_needed): image = QImage.fromData(data) image = image.copy(self.scanner.crop_rect) image.save(filename) else: img_file = QFile(filename, self) img_file.open(QIODevice.WriteOnly) img_file.write(data) img_file.close() data.clear() self.statusbar.showMessage("Scan Completed Successfully") self.filenameEdit.setText(self.newFileName()) def newFileName(self): ext = self.scanner.extension index = 1 while True: filename = "Scan%3i" % index filename = filename.replace(" ", "0") if os.path.exists(filename + ext): index +=1 else: break return filename
def getParamVideo(cheminVideoEntre, parameter, hashInfo = None): """Renvoie un ou plusieurs paramètres de la vidéo sous forme de flottant. La variable «cheminVideoEntre» est le chemin de la vidéo de type unicode. La variable «parameter» est un tuple de paramètres à renvoyer. La dernière variable renvoyée est un tuple des lignes de log 23/07/2009 : hashInfo contiendra la hashmap des infos demandées """ #cheminVideoEntre = cheminVideoEntre.encode("UTF8") if hashInfo == None: hashInfo = {} # Condition pour détection windows if os.name == 'nt': commande = u'mplayer.exe -vo null -ao null -identify -frames 0 '+ u"\"" + unicode(cheminVideoEntre) + u"\"" # Condition pour détection Linux ou MacOSX elif os.name in ['posix', 'mac']: commande = u'mplayer ' + u"\""+ unicode(cheminVideoEntre) + u"\" -vo null -ao null -frames 0 -identify '$@' 2>/dev/null" #recupDonneesVideo = os.popen(commande.encode(coding)).readlines() processus = QProcess() processus.start(commande) if (not processus.waitForStarted()): raise (u"Erreur de récupération des informations") if ( not processus.waitForFinished()): raise (u"Erreur de récupération des informations") recupDonneesVideo = QString(processus.readAllStandardOutput()) lstValeurs = [] log = [] #for ligne in recupDonneesVideo: for ligne in recupDonneesVideo.split("\n"): try: # On veut que les caractères non ASCII s'affichent # correctement pour les noms de fichiers log.append(ligne) except UnicodeDecodeError: debug("Traitement d'exception unicode au niveau de " \ "getParamVideo() probablement dûe aux " \ "méta-données de la vidéo") log.append(ligne) for param in parameter: if param in ligne: ligne = ligne.replace(param, "") ligne = ligne.replace("=", "") ligne = ligne.replace("\n", "") ############################################ # Commenté le 01/09/10 --> voir si tout # fonctionne malgré tout (commenté pour # pouvoir lire les tags vidéos correctement) #ligne = ligne.replace(" ", "") ############################################ ############################################ # Le 01/09/10 Essai de réglage de la sortie # pour les accents dans les tags vidéo # VOIR SI SYNTAXE PLUS GENERIQUE ligne = ligne.replace("é", "e") ligne = ligne.replace("è", "e") ligne = ligne.replace("ç", "c") ligne = ligne.replace("à", "a") ligne = ligne.replace("ù", "u") ligne = ligne.replace("ä", "a") ligne = ligne.replace("ü", "u") ligne = ligne.replace("ö", "o") ############################################ try : lstValeurs.append(float(ligne)) hashInfo[param] = float(ligne) except : lstValeurs.append(str(ligne)) hashInfo[param] = str(ligne) lstValeurs.append(log) #lstValeurs.append(hashInfo) return lstValeurs
class TestRunner(): def __init__(self, testfile): self.testfile = testfile self.data = "" self.passed_tests = [] self.failed_tests = [] def writeStdout(self): data = self.process.readAllStandardOutput().data().decode( "utf-8").replace(r'\n', '\n') if "debug" in sys.argv: sys.stdout.write(data) else: for line in data.split('\n'): if line[: 4] == "PASS" or line[: 5] == "FAIL!" or line[: 5] == "XFAIL": sys.stdout.write(".") sys.stdout.flush() self.data += data def writeStderr(self): data = self.process.readAllStandardError().data().decode( "utf-8").replace(r'\n', '\n') if "debug" in sys.argv: sys.stdout.write(data) self.data += data def doTestrun(self): data = self.fetchOutputForJob() last_failed = False for line in data.split('\n'): success = re.match(r"PASS\s*:\s*(.*)", line) if success: function = success.groups()[0] self.passed_tests.append(function) last_failed = False if last_failed: getLocation = re.match(r"\s*Loc:\s*\[(.*)\((\d*)\)]", line) if getLocation: filename = ".../" + '/'.join( getLocation.groups()[0].split('/')[-2:]) lineno = getLocation.groups()[1] self.failed_tests[-1].filename = filename self.failed_tests[-1].lineno = lineno last_failed = False fail = re.match(r"FAIL!\s*:\s*(.*)\((.*)\)\s+(.*)", line) if fail: function = fail.groups()[0] args = fail.groups()[1] function = function + "(" + args + ")" reason = fail.groups()[2] self.failed_tests.append(FailedTest(function, reason)) last_failed = True xfail = re.match(r"XFAIL\s*:\s*(.*)\((.*)\)\s+(.*)", line) if xfail: function = xfail.groups()[0] args = xfail.groups()[1] function = function + "(" + args + ")" reason = xfail.groups()[2] self.failed_tests.append(FailedTest(function, reason)) self.failed_tests[-1].failExpected = True last_failed = True fatal_fail = re.match(r"(QFATAL|ASSERT)\s*", line) if fatal_fail: print(self.data) print(red("Fatal error occured, aborting")) return passed, failed = len(self.passed_tests), len(self.failed_tests) try: percent = round((float(passed) / (failed + passed)) * 100) except ZeroDivisionError: percent = 0 percent = green(percent) if percent == 100 else yellow( percent) if percent > 80 else red(percent) total = white(passed + failed) passed, failed = green(passed), red(failed) print( "\n Done. Summary: %s tests reported total, %s passed, %s failed (%s%% passed)." % (total, passed, failed, percent)) print(" Detailed information:\n") print(white(" ==="), green("Passed tests:"), white("===")) namespaceFunctionArgs = r"(.*)::(.*)\((.*)\)" if len(self.passed_tests): for test in self.passed_tests: test = re.match(namespaceFunctionArgs, test) test = test.groups() test = "[%s] " % test[0] + green(test[1]) + "(" + white( test[2]) + ")" print(indent(green("✔ ") + test)) if len(self.failed_tests): print("\n" + white(" ==="), red("Failed tests:"), white("===")) for test in self.failed_tests: namespace, function, args = re.match(namespaceFunctionArgs, test.name).groups() filename = test.filename.split('/')[-1] path = '/'.join(test.filename.split('/')[:-1]) + "/" print( indent((yellow("✘ ") if test.failExpected else red("✘ ")) + white(filename) + ":" + blue(test.lineno) + " " * (5 - len(str(lineno))) + red(function) + "(" + yellow(args) + ")")) if 'noreason' not in sys.argv: print( indent( "Reason of failure:" + blue(" ❮") + white(test.reason) + blue("❯ ") + ("(Failure expected)" if test.failExpected else ""), 2)) #print "[in %s]" % namespace def fetchOutputForJob(self): self.process = QProcess() self.process.readyReadStandardOutput.connect(self.writeStdout) self.process.readyReadStandardError.connect(self.writeStderr) print(" Please wait, running tests", end=' ') sys.stdout.flush() self.process.start(self.testfile, ["-maxwarnings", "0"]) self.process.waitForFinished(-1) return str(self.data)
class HostWindow(QMainWindow): # signals SIGTERM = pyqtSignal() SIGUSR1 = pyqtSignal() # -------------------------------------------------------------------------------------------------------- def __init__(self): QMainWindow.__init__(self) self.ui = Ui_HostWindow() self.ui.setupUi(self) # ---------------------------------------------------------------------------------------------------- # Internal stuff # Current mod-ui title #self.fCurrentBundle = "" self.fCurrentTitle = "" # Next bundle to load (done by startup arguments) self.fNextBundle = "" # first attempt of auto-start backend doesn't show an error self.fFirstBackendInit = True # need to call session reconnect after connecting the 1st time self.fNeedsSessionReconnect = False # Qt idle timer self.fIdleTimerId = 0 # Qt web frame, used for evaluating javascript self.fWebFrame = None # to be filled with key-value pairs of current settings self.fSavedSettings = {} # List of pedalboards self.fPedalboards = get_all_pedalboards() # List of current-pedalboard presets self.fPresetMenuList = [] # Process that runs the backend self.fProccessBackend = QProcess(self) self.fProccessBackend.setProcessChannelMode(QProcess.MergedChannels) self.fProccessBackend.setReadChannel(QProcess.StandardOutput) self.fStoppingBackend = False # Thread for managing the webserver self.fWebServerThread = WebServerThread(self) # ---------------------------------------------------------------------------------------------------- # Set up GUI self.ui.webview = QWebView(self.ui.swp_webview) self.ui.webview.setMinimumWidth(980) self.ui.swp_webview.layout().addWidget(self.ui.webview) self.ui.webpage = HostWebPage(self) self.ui.webpage.setViewportSize(QSize(980, 600)) self.ui.webview.setPage(self.ui.webpage) self.ui.webinspector = QWebInspector(None) self.ui.webinspector.resize(800, 600) self.ui.webinspector.setPage(self.ui.webpage) self.ui.webinspector.setVisible(False) self.ui.act_file_connect.setEnabled(False) self.ui.act_file_connect.setVisible(False) self.ui.act_file_disconnect.setEnabled(False) self.ui.act_file_disconnect.setVisible(False) self.ui.label_app.setText("MOD Application v%s" % config["version"]) # disable file menu self.ui.act_file_refresh.setEnabled(False) self.ui.act_file_inspect.setEnabled(False) # disable pedalboard menu self.ui.act_pedalboard_new.setEnabled(False) self.ui.act_pedalboard_open.setEnabled(False) self.ui.act_pedalboard_save.setEnabled(False) self.ui.act_pedalboard_save_as.setEnabled(False) self.ui.act_pedalboard_share.setEnabled(False) self.ui.menu_Pedalboard.setEnabled(False) # disable presets menu self.ui.act_presets_new.setEnabled(False) self.ui.act_presets_save.setEnabled(False) self.ui.act_presets_save_as.setEnabled(False) self.ui.menu_Presets.setEnabled(False) # initial stopped state self.slot_backendFinished(-1, -1) # Qt needs this so it properly creates & resizes the webview self.ui.stackedwidget.setCurrentIndex(1) self.ui.stackedwidget.setCurrentIndex(0) # FIXME #self.ui.act_backend_stop.setVisible(False) #self.ui.act_backend_restart.setVisible(False) # ---------------------------------------------------------------------------------------------------- # Set up GUI (special stuff for Mac OS) if MACOS: self.ui.act_file_quit.setMenuRole(QAction.QuitRole) self.ui.act_settings_configure.setMenuRole(QAction.PreferencesRole) self.ui.act_help_about.setMenuRole(QAction.AboutRole) #self.ui.menu_Settings.setTitle("Panels") #self.ui.menu_Help.hide() # ---------------------------------------------------------------------------------------------------- # Set up GUI (special stuff for Live-MOD ISO) if USING_LIVE_ISO: self.ui.menubar.hide() self.ui.b_start.hide() self.ui.b_configure.hide() self.ui.b_about.hide() # ---------------------------------------------------------------------------------------------------- # Load Settings self.loadSettings(True) # ---------------------------------------------------------------------------------------------------- # Connect actions to functions self.SIGUSR1.connect(self.slot_handleSIGUSR1) self.SIGTERM.connect(self.slot_handleSIGTERM) self.fProccessBackend.error.connect(self.slot_backendError) self.fProccessBackend.started.connect(self.slot_backendStarted) self.fProccessBackend.finished.connect(self.slot_backendFinished) self.fProccessBackend.readyRead.connect(self.slot_backendRead) self.fWebServerThread.running.connect(self.slot_webServerRunning) self.fWebServerThread.finished.connect(self.slot_webServerFinished) self.ui.menu_Pedalboard.aboutToShow.connect(self.slot_pedalboardCheckOnline) self.ui.act_file_refresh.triggered.connect(self.slot_fileRefresh) self.ui.act_file_inspect.triggered.connect(self.slot_fileInspect) self.ui.act_backend_information.triggered.connect(self.slot_backendInformation) self.ui.act_backend_start.triggered.connect(self.slot_backendStart) self.ui.act_backend_stop.triggered.connect(self.slot_backendStop) self.ui.act_backend_restart.triggered.connect(self.slot_backendRestart) self.ui.act_pedalboard_new.triggered.connect(self.slot_pedalboardNew) self.ui.act_pedalboard_open.triggered.connect(self.slot_pedalboardOpen) self.ui.act_pedalboard_save.triggered.connect(self.slot_pedalboardSave) self.ui.act_pedalboard_save_as.triggered.connect(self.slot_pedalboardSaveAs) self.ui.act_pedalboard_share.triggered.connect(self.slot_pedalboardShare) self.ui.act_settings_configure.triggered.connect(self.slot_configure) self.ui.act_help_about.triggered.connect(self.slot_about) self.ui.act_help_project.triggered.connect(self.slot_showProject) self.ui.act_help_website.triggered.connect(self.slot_showWebsite) self.ui.b_start.clicked.connect(self.slot_backendStart) self.ui.b_configure.clicked.connect(self.slot_configure) self.ui.b_about.clicked.connect(self.slot_about) # force our custom refresh webReloadAction = self.ui.webpage.action(QWebPage.Reload) webReloadAction.triggered.disconnect() webReloadAction.triggered.connect(self.slot_fileRefresh) # ---------------------------------------------------------------------------------------------------- # Final setup self.setProperWindowTitle() SESSION.setupApp(self._pedal_changed_callback) if not "--no-autostart" in sys.argv: QTimer.singleShot(0, self.slot_backendStart) QTimer.singleShot(1, self.fixWebViewSize) def __del__(self): self.stopAndWaitForWebServer() self.stopAndWaitForBackend() def _pedal_changed_callback(self, ok, bundlepath, title): #self.fCurrentBundle = bundlepath self.fCurrentTitle = title or "" #self.updatePresetsMenu() self.setProperWindowTitle() # -------------------------------------------------------------------------------------------------------- # Files (menu actions) @pyqtSlot() def slot_fileRefresh(self): if self.fWebFrame is None: return self.ui.label_progress.setText(self.tr("Refreshing UI...")) self.ui.stackedwidget.setCurrentIndex(0) QTimer.singleShot(0, self.slot_fileRefreshPost) @pyqtSlot() def slot_fileRefreshPost(self): self.ui.webview.loadStarted.connect(self.slot_webviewLoadStarted) self.ui.webview.loadProgress.connect(self.slot_webviewLoadProgress) self.ui.webview.loadFinished.connect(self.slot_webviewLoadFinished) self.ui.webview.reload() @pyqtSlot() def slot_fileInspect(self): self.ui.webinspector.show() # -------------------------------------------------------------------------------------------------------- # Pedalboard (menu actions) @pyqtSlot() def slot_pedalboardCheckOnline(self): if self.fWebFrame is None: return isOnline = self.fWebFrame.evaluateJavaScript("$('#mod-cloud').hasClass('logged')") if isOnline is None: return print("isOnline is None") self.ui.act_pedalboard_share.setEnabled(isOnline) @pyqtSlot() def slot_pedalboardNew(self): if self.fWebFrame is None: return self.fWebFrame.evaluateJavaScript("desktop.reset()") # -------------------------------------------------------------------------------------------------------- @pyqtSlot() def slot_pedalboardOpen(self): if len(self.fPedalboards) == 0: return QMessageBox.information(self, self.tr("information"), "No pedalboards found") dialog = OpenPedalboardWindow(self, self.fPedalboards) if not dialog.exec_(): return pedalboard = dialog.getSelectedURI() if not pedalboard: return QMessageBox.information(self, self.tr("information"), "Invalid pedalboard selected") try: bundle = get_bundle_dirname(pedalboard) except: return if self.fWebFrame is None: return self.fWebFrame.evaluateJavaScript("desktop.loadPedalboard(\"%s\")" % bundle) def openPedalboardLater(self, filename): try: self.fNextBundle = QFileInfo(filename).absoluteFilePath() self.fCurrentTitle = get_pedalboard_info(self.fNextBundle)['name'] except: self.fNextBundle = "" self.fCurrentTitle = "" # -------------------------------------------------------------------------------------------------------- @pyqtSlot() def slot_pedalboardSave(self, saveAs=False): if self.fWebFrame is None: return self.fWebFrame.evaluateJavaScript("desktop.saveCurrentPedalboard(%s)" % ("true" if saveAs else "false")) @pyqtSlot() def slot_pedalboardSaveAs(self): self.slot_pedalboardSave(True) # -------------------------------------------------------------------------------------------------------- @pyqtSlot() def slot_pedalboardShare(self): if self.fWebFrame is None: return self.fWebFrame.evaluateJavaScript("desktop.shareCurrentPedalboard()") # -------------------------------------------------------------------------------------------------------- # Presets (menu actions) @pyqtSlot() def slot_presetClicked(self): print(self.sender().data()) # -------------------------------------------------------------------------------------------------------- # Settings (menu actions) @pyqtSlot() def slot_configure(self): dialog = SettingsWindow(self, True) if not dialog.exec_(): return self.loadSettings(False) # -------------------------------------------------------------------------------------------------------- # About (menu actions) @pyqtSlot() def slot_about(self): QMessageBox.about(self, self.tr("About"), self.tr(""" <b>MOD Desktop Application</b><br/> <br/> A software to have the complete MOD environment running in your desktop.<br/> (C) 2015-2016 - The MOD Team<br/> <br/> Publications, products, content or services referenced herein or on the website are the exclusive trademarks or servicemarks of MOD.<br/> Other product and company names mentioned in the site may be the trademarks of their respective owners.<br/> <br/> All software is available under the <a href="https://www.gnu.org/licenses/gpl-2.0.html">GPL license</a>.<br/> """)) @pyqtSlot() def slot_showProject(self): QDesktopServices.openUrl(QUrl("https://github.com/moddevices/mod-app")) @pyqtSlot() def slot_showWebsite(self): QDesktopServices.openUrl(QUrl("http://moddevices.com/")) # -------------------------------------------------------------------------------------------------------- # Backend (menu actions) @pyqtSlot() def slot_backendInformation(self): table = """ <table><tr> <td> MOD-UI port: <td></td> %s </td> </tr><tr> <td> Backend address: <td></td> %s </td> </tr></table> """ % (config["port"], "unix:///tmp/mod-app-%s.sock" % config["port"]) QMessageBox.information(self, self.tr("information"), table) @pyqtSlot() def slot_backendStart(self): if self.fProccessBackend.state() != QProcess.NotRunning: print("slot_backendStart ignored") return print("slot_backendStart in progress...") if USING_LIVE_ISO: os.system("jack_wait -w") os.system("jack_load mod-monitor") hostPath = "jack_load" hostArgs = ["-w", "-a", "mod-host"] else: hostPath = self.fSavedSettings[MOD_KEY_HOST_PATH] if hostPath.endswith("ingen"): hostPath = MOD_DEFAULT_HOST_PATH hostArgs = ["-n"] self.fProccessBackend.start(hostPath, hostArgs) @pyqtSlot() def slot_backendStop(self, forced = False): #if self.fPluginCount > 0: #if not forced: #ask = QMessageBox.question(self, self.tr("Warning"), self.tr("There are still some plugins loaded, you need to remove them to stop the engine.\n" #"Do you want to do this now?"), #QMessageBox.Yes | QMessageBox.No, QMessageBox.No) #if ask != QMessageBox.Yes: #return #self.removeAllPlugins() #self.host.set_engine_about_to_close() #self.host.remove_all_plugins() # testing red color for server stopped self.ui.webview.blockSignals(True) self.ui.webview.setHtml("<html><body bgcolor='green'></body></html>") self.ui.webview.blockSignals(False) self.stopAndWaitForWebServer() self.stopAndWaitForBackend() @pyqtSlot() def slot_backendRestart(self): #self.ui.stackedwidget.setCurrentIndex(0) self.slot_backendStop() #QApplication.instance().processEvents() self.slot_backendStart() # -------------------------------------------------------------------------------------------------------- @pyqtSlot() def slot_backendStarted(self): self.ui.act_backend_start.setEnabled(False) self.ui.act_backend_stop.setEnabled(True) self.ui.act_backend_restart.setEnabled(True) self.ui.w_buttons.setEnabled(False) self.ui.label_progress.setText(self.tr("Loading backend...")) @pyqtSlot(int, QProcess.ExitStatus) def slot_backendFinished(self, exitCode, exitStatus): self.fFirstBackendInit = False self.fStoppingBackend = False self.ui.act_backend_start.setEnabled(True) self.ui.act_backend_stop.setEnabled(False) self.ui.act_backend_restart.setEnabled(False) self.ui.w_buttons.setEnabled(True) self.ui.label_progress.setText("") self.ui.stackedwidget.setCurrentIndex(0) # stop webserver self.stopAndWaitForWebServer() @pyqtSlot(QProcess.ProcessError) def slot_backendError(self, error): firstBackendInit = self.fFirstBackendInit self.fFirstBackendInit = False # stop webserver self.stopAndWaitForWebServer() # crashed while stopping, ignore if error == QProcess.Crashed and self.fStoppingBackend: return errorStr = self.tr("Could not start host backend.\n") + self.getProcessErrorAsString(error) qWarning(errorStr) # don't show error if this is the first time starting the host or using live-iso if firstBackendInit or USING_LIVE_ISO: return # show the error message QMessageBox.critical(self, self.tr("Error"), errorStr) @pyqtSlot() def slot_backendRead(self): #if self.fProccessBackend.state() != QProcess.Running: #return for line in str(self.fProccessBackend.readAllStandardOutput().trimmed(), encoding="utf-8", errors="ignore").strip().split("\n"): line = line.replace("\x1b[0m","").replace("\x1b[0;31m","").replace("\x1b[0;33m","").strip() if not line: continue if self.fSavedSettings[MOD_KEY_HOST_VERBOSE]: print("BACKEND:", line) if line == "mod-host ready!" or line == "mod-host is running.": QTimer.singleShot(0, self.slot_backendStartPhase2) #elif "Listening on socket " in line: #QTimer.singleShot(1000, self.slot_ingenStarted) ##elif "Activated Jack client " in line: ##QTimer.singleShot(1000, self.fWebServerThread.start) #elif "Failed to create UNIX socket" in line or "Could not activate Jack client" in line: ## need to wait for ingen to create sockets so it can delete them on termination #QTimer.singleShot(1000, self.slot_ingenStartError) @pyqtSlot() def slot_backendStartPhase2(self): if self.fProccessBackend.state() == QProcess.NotRunning: return if not self.fNeedsSessionReconnect: # we'll need it for next time self.fNeedsSessionReconnect = True else: # we need it now SESSION.reconnectApp() self.fWebServerThread.start() @pyqtSlot() def slot_backendStartError(self): self.stopAndWaitForBackend() self.slot_backendError(-2) # -------------------------------------------------------------------------------------------------------- # Web Server @pyqtSlot() def slot_webServerRunning(self): try: self.ui.webview.loadStarted.connect(self.slot_webviewLoadStarted) self.ui.webview.loadProgress.connect(self.slot_webviewLoadProgress) self.ui.webview.loadFinished.connect(self.slot_webviewLoadFinished) except: pass print("webserver running") self.ui.webview.load(QUrl(config["addr"])) @pyqtSlot() def slot_webServerFinished(self): try: self.ui.webview.loadStarted.connect(self.slot_webviewLoadStarted) self.ui.webview.loadProgress.connect(self.slot_webviewLoadProgress) self.ui.webview.loadFinished.connect(self.slot_webviewLoadFinished) except: pass print("webserver finished") # testing red color for server finished self.ui.webview.blockSignals(True) self.ui.webview.setHtml("<html><body bgcolor='red'></body></html>") self.ui.webview.blockSignals(False) # -------------------------------------------------------------------------------------------------------- # Web View @pyqtSlot() def slot_webviewLoadStarted(self): self.ui.label_progress.setText(self.tr("Loading UI...")) print("load started") @pyqtSlot(int) def slot_webviewLoadProgress(self, progress): self.ui.label_progress.setText(self.tr("Loading UI... %i%%" % progress)) @pyqtSlot(bool) def slot_webviewLoadFinished(self, ok): self.ui.webview.loadStarted.disconnect(self.slot_webviewLoadStarted) self.ui.webview.loadProgress.disconnect(self.slot_webviewLoadProgress) self.ui.webview.loadFinished.disconnect(self.slot_webviewLoadFinished) if ok: # message self.ui.label_progress.setText(self.tr("Loading UI... finished!")) # enable file menu self.ui.act_file_refresh.setEnabled(True) self.ui.act_file_inspect.setEnabled(True) # for js evaulation self.fWebFrame = self.ui.webpage.currentFrame() # postpone app stuff QTimer.singleShot(100, self.slot_webviewPostFinished) else: # message self.ui.label_progress.setText(self.tr("Loading UI... failed!")) # disable file menu self.ui.act_file_refresh.setEnabled(False) self.ui.act_file_inspect.setEnabled(False) # disable pedalboard menu self.ui.act_pedalboard_new.setEnabled(False) self.ui.act_pedalboard_open.setEnabled(False) self.ui.act_pedalboard_save.setEnabled(False) self.ui.act_pedalboard_save_as.setEnabled(False) self.ui.act_pedalboard_share.setEnabled(False) self.ui.menu_Pedalboard.setEnabled(False) # stop js evaulation self.fWebFrame = None # stop backend&server self.stopAndWaitForWebServer() self.stopAndWaitForBackend() print("load finished") @pyqtSlot() def slot_webviewPostFinished(self): if self.fNextBundle: bundle = self.fNextBundle self.fNextBundle = "" self.fWebFrame.evaluateJavaScript("desktop.loadPedalboard(\"%s\")" % bundle) QTimer.singleShot(0, self.slot_webviewPostFinished2) @pyqtSlot() def slot_webviewPostFinished2(self): self.ui.stackedwidget.setCurrentIndex(1) # -------------------------------------------------------------------------------------------------------- # Settings def saveSettings(self): settings = QSettings() settings.setValue("Geometry", self.saveGeometry()) def loadSettings(self, firstTime): qsettings = QSettings() websettings = self.ui.webview.settings() self.fSavedSettings = { # Main MOD_KEY_MAIN_PROJECT_FOLDER: qsettings.value(MOD_KEY_MAIN_PROJECT_FOLDER, MOD_DEFAULT_MAIN_PROJECT_FOLDER, type=str), MOD_KEY_MAIN_REFRESH_INTERVAL: qsettings.value(MOD_KEY_MAIN_REFRESH_INTERVAL, MOD_DEFAULT_MAIN_REFRESH_INTERVAL, type=int), # Host MOD_KEY_HOST_VERBOSE: qsettings.value(MOD_KEY_HOST_VERBOSE, MOD_DEFAULT_HOST_VERBOSE, type=bool), MOD_KEY_HOST_PATH: qsettings.value(MOD_KEY_HOST_PATH, MOD_DEFAULT_HOST_PATH, type=str), # WebView MOD_KEY_WEBVIEW_INSPECTOR: qsettings.value(MOD_KEY_WEBVIEW_INSPECTOR, MOD_DEFAULT_WEBVIEW_INSPECTOR, type=bool), MOD_KEY_WEBVIEW_VERBOSE: qsettings.value(MOD_KEY_WEBVIEW_VERBOSE, MOD_DEFAULT_WEBVIEW_VERBOSE, type=bool), MOD_KEY_WEBVIEW_SHOW_INSPECTOR: qsettings.value(MOD_KEY_WEBVIEW_SHOW_INSPECTOR, MOD_DEFAULT_WEBVIEW_SHOW_INSPECTOR, type=bool) } inspectorEnabled = self.fSavedSettings[MOD_KEY_WEBVIEW_INSPECTOR] and not USING_LIVE_ISO websettings.setAttribute(QWebSettings.DeveloperExtrasEnabled, inspectorEnabled) if firstTime: if qsettings.contains("Geometry"): self.restoreGeometry(qsettings.value("Geometry", "")) else: self.setWindowState(self.windowState() | Qt.WindowMaximized) if inspectorEnabled and self.fSavedSettings[MOD_KEY_WEBVIEW_SHOW_INSPECTOR]: QTimer.singleShot(1000, self.ui.webinspector.show) self.ui.act_file_inspect.setVisible(inspectorEnabled) if self.fIdleTimerId != 0: self.killTimer(self.fIdleTimerId) self.fIdleTimerId = self.startTimer(self.fSavedSettings[MOD_KEY_MAIN_REFRESH_INTERVAL]) # -------------------------------------------------------------------------------------------------------- # Misc @pyqtSlot() def slot_handleSIGUSR1(self): print("Got SIGUSR1 -> Saving project now") self.slot_pedalboardSave() @pyqtSlot() def slot_handleSIGTERM(self): print("Got SIGTERM -> Closing now") self.close() # -------------------------------------------------------------------------------------------------------- # Qt events def closeEvent(self, event): if self.fIdleTimerId != 0: self.killTimer(self.fIdleTimerId) self.fIdleTimerId = 0 self.saveSettings() self.slot_backendStop(True) QMainWindow.closeEvent(self, event) # Needed in case the web inspector is still alive #self.ui.webinspector.close() QApplication.instance().quit() def timerEvent(self, event): if event.timerId() == self.fIdleTimerId: pass QMainWindow.timerEvent(self, event) def resizeEvent(self, event): QMainWindow.resizeEvent(self, event) self.fixWebViewSize() # -------------------------------------------------------------------------------------------------------- # Internal stuff def getProcessErrorAsString(self, error): if error == -2: return self.tr("Ingen failed to create UNIX socket.") if error == QProcess.FailedToStart: return self.tr("Process failed to start.") if error == QProcess.Crashed: return self.tr("Process crashed.") if error == QProcess.Timedout: return self.tr("Process timed out.") if error == QProcess.WriteError: return self.tr("Process write error.") return self.tr("Unkown error.") def fixWebViewSize(self): if self.ui.stackedwidget.currentIndex() == 1: return size = self.ui.swp_intro.size() self.ui.swp_webview.resize(size) self.ui.webview.resize(size) self.ui.webpage.setViewportSize(size) def stopAndWaitForBackend(self): if self.fProccessBackend.state() == QProcess.NotRunning: return self.fStoppingBackend = True self.fProccessBackend.terminate() if not self.fProccessBackend.waitForFinished(2000): qWarning("Backend failed top stop cleanly, forced kill") self.fProccessBackend.kill() def stopAndWaitForWebServer(self): if not self.fWebServerThread.isRunning(): return if not self.fWebServerThread.stopWait(): qWarning("WebServer Thread failed top stop cleanly, forced terminate") self.fWebServerThread.terminate() def setProperWindowTitle(self): title = "MOD Application" if self.fCurrentTitle: title += " - %s" % self.fCurrentTitle self.setWindowTitle(title)