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 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(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 run(cmd, args=[]): """Executes the command `cmd` with optional arguments `args`, provided it is available on the system. Parameters: - `cmd`: The program command. - `args`: a list of arguments to pass to `cmd` (default is []). """ if not dryrun: proc = QProcess() proc.start(cmd, args) while proc.waitForReadyRead(): if verbose: print '>>>' print 'ReadyRead:\n{0}'.format(proc.readAll()) print '<<<' if verbose: stderr = proc.readAllStandardError() if stderr != '': print '>>>' print 'Errors:\n{0}'.format(stderr) print '<<<' stdout = proc.readAllStandardOutput() if stdout != '': print '>>>' print 'Output:{0}\n'.format(proc.readAllStandardOutput()) print '<<<'
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)
def generate_frames(cls, input_file_path, output_dir, finish_callbak, frame_extension = "png"): file_name = input_file_path[input_file_path.rindex("/"):].replace(" ", "_") frames_output_path = output_dir+'/'+file_name if os.path.exists(frames_output_path): print "La cartella dei frame esiste gia, non avvio ffmpeg" finish_callbak(True, frames_output_path) else: #Create the folder os.makedirs(frames_output_path) #Execute FFMPEG def _check_callback_status(code, code2): print "Processo FFMpeg finito, chiamo la callback" finish_callbak(code==0, frames_output_path) process = QProcess(QApplication.instance()) process.finished.connect(_check_callback_status) #process.start("/usr/local/bin/ffmpeg", ['-i', input_file_path,'-t', '5', frames_output_path+'/Frame_%07d.'+frame_extension]) #process.start("/usr/local/bin/ffmpeg", ['-i', input_file_path, '-r', '30', '-t', '3', '-s', '213x120', '-ss', '00:01:30', frames_output_path+'/Frame_%07d.'+frame_extension]) process.start("/usr/local/bin/ffmpeg", ['-i', input_file_path, '-r', '15', '-t', '5', '-ss', '00:00:50', frames_output_path+'/Frame_%07d.'+frame_extension])
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 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()
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 cim2modelica(self): command = "java" args = ["-jar", "./lib/cim2modelica.jar", self.txtEQ.text(), self.txtTP.text(), self.txtSV.text(), self.txtDY.text(), self.txtModelName.text(), str(self.cbxCimSchema.currentText())] process = QProcess(self) process.finished.connect(self.onFinished) process.start(command, args)
class Common(base.Common): def systemSettingsButton(self): self.procSettings = QProcess() self.procSettings.start("systemsettings") def getLanguage(self): lang = KGlobal.locale().language() return lang
class Common(base.Common): def getLanguage(self): locale_app = QLocale() locale_os = QLocale.system() info = [] var = QLocale.languageToString(locale_app.language()) return var def systemSettingsButton(self): self.procSettings = QProcess() self.procSettings.start("gnome-control-center")
class Widget(QtGui.QWidget, Screen): title = i18n("More") desc = i18n("Congratulations!") def __init__(self, *args): QtGui.QWidget.__init__(self,None) self.ui = Ui_goodbyeWidget() self.ui.setupUi(self) var=Desktop.common.getLanguage() if var == "Turkish" or var == "tr": self.helpPageUrl = "http://www.pardus.org.tr/destek" else: self.helpPageUrl = "http://www.pardus.org.tr/eng/support" self.smoltUrl = "http://smolt.pardus.org.tr:8090" def on_buttonSystemSettings_clicked(self): Desktop.common.systemSettingsButton() def on_buttonHelpPages_clicked(self): self.procSettings = QProcess() if ctx.Pds.session == ctx.pds.Gnome3: command = "chromium-browser " + self.helpPageUrl else: command = "firefox " + self.helpPageUrl self.procSettings.start(command) def on_buttonSystemSettings_2_clicked(self): self.procSettings = QProcess() if ctx.Pds.session == ctx.pds.Gnome3: command = "chromium-browser " + self.helpPageUrl else: command = "firefox " + self.smoltUrl self.procSettings.start(command) def setSmolt(self): # Smolt Settings if self.smoltSettings["profileSend"]: self.procSettings = QProcess() command = "smoltSendProfile" arguments = ["-a", "--submitOnly"] self.procSettings.startDetached(command, arguments) # if not self.smoltSettings["profileSend"]: # self.ui.smoltGroupBox.hide() # self.ui.label.hide() def shown(self): self.smoltSettings = smoltWidget.Widget.screenSettings self.setSmolt() def execute(self): return True
class Common(base.Common): def getLanguage(self): locale_app = QLocale() locale_os = QLocale.system() info = [] var = QLocale.languageToString(locale_app.language()) return var def on_buttonSystemSettings_clicked(self): self.procSettings = QProcess() # TODO: fix program self.procSettings.start("program name")
class IsoBuilder(): def __init__(self, parent = None): self.parent = parent self.process = None def __parse_output(self): if not self.process: return output = QString(self.process.readAll()) output = output.split("\n", QString.SkipEmptyParts) for line in output: line = common.qt_to_unicode(line) match = OUTPUT_RE.match(line) if match == None: continue percent = float(match.group(1)) self.progress.setValue(percent) def build_iso(self, directory, iso_file): if self.process: return directory = os.path.abspath(directory) iso_file = os.path.abspath(iso_file) self.progress = QProgressDialog("Building ISO...", QtCore.QString(), 0, 0, self.parent) self.progress.setWindowTitle("Building ISO") self.progress.setWindowModality(Qt.Qt.WindowModal) self.progress.setAutoClose(False) self.progress.setMinimumDuration(1000) self.progress.show() self.progress.setValue(0) self.progress.setMaximum(100) self.process = QProcess() self.process.finished.connect(self.__build_finished) self.process.setReadChannel(QProcess.StandardError) self.process.readyRead.connect(self.__parse_output) self.process.start("tools/mkisofs", ["-sort", "data/file_order.txt", "-iso-level", "4", "-xa", "-A", "PSP GAME", "-V", "DANGANRONPA", "-sysid", "PSP GAME", "-volset", "DANGANRONPA", "-p", "SPIKE", "-publisher", "SPIKE", "-o", iso_file, directory]) def __build_finished(self, code, status): self.progress.close() self.process = None
class Rabisk(QtGui.QMainWindow): text="peganingas" pic=None def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.layers = [] self.canvasWidth = 640 # size of image, not entire widget self.canvasHeight = 480 self.ui.label.setGeometry(QtCore.QRect(0, 0, 66, 17)) print self.ui.centralwidget.width #self.ui.label.geometry.Width=self.ui.geometry.Width #self.ui.label.height=self.ui.height self.setWindowState(Qt.WindowFullScreen) print self.ui.centralwidget.width() self.ui.label.setGeometry(QtCore.QRect(0, 0, self.ui.centralwidget.width(), self.ui.centralwidget.height())) self.pic=QPixmap(self.ui.centralwidget.width(), self.ui.centralwidget.height()) self.camera=QProcess(self) self.camera.readyReadStandardOutput.connect(self.handle_stdout) self.camera.start('python sense.py') self.show() def paintEvent(self, event): print "drawing" qp=QtGui.QPainter() qp.begin(self) qp.setPen(QtGui.QColor(1,10,0)) qp.drawText(10,10, self.text) qp.end() def handle_stdout(self): byteArray=self.camera.readAllStandardOutput() data=re.sub(r'''\n+$''', "", byteArray.data()) print data self.text=data #self.ui.label.setText("whatever"+data); qp=QtGui.QPainter(self.pic) qp.setPen(QtGui.QColor(1,10,0)) qp.drawText(100,10, self.text) self.ui.label.setPixmap(self.pic) def keyPressEvent(self, e): k=e.key() print e.key()
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
class RunWidget(QPlainTextEdit): def __init__(self): QWidget.__init__(self) self.setReadOnly(True) styles.set_style(self, 'editor') self.setPlainText('For the moment NINJA only show output when the Program ends.') self.overlay = Overlay(self) self.overlay.hide() self.proc = QProcess(self) #self.proc.setProcessChannelMode(QProcess.ForwardedChannels) self.connect(self.proc, SIGNAL("readyReadStandardOutput()"), self.refresh_output) self.connect(self.proc, SIGNAL("readyReadStandardError()"), self.refresh_error) self.connect(self.proc, SIGNAL("finished(int, QProcess::ExitStatus)"), self._finish_process) def start_process(self, fileName, pythonPath=False): self.setPlainText('Running: ' + fileName + '\n'\ + 'For the moment NINJA only show output when the Program ends.' + '\n\n') self.moveCursor(QTextCursor.Down) self.moveCursor(QTextCursor.Down) self.moveCursor(QTextCursor.Down) #runner.run_code_from_file(fileName) if not pythonPath: pythonPath = resources.python_path self.proc.start(pythonPath, [fileName]) self.overlay.show() def kill_process(self): self.proc.kill() def refresh_output(self): text = str(self.proc.readAllStandardOutput().data()) self.textCursor().insertText(text) def refresh_error(self): text = str(self.proc.readAllStandardError().data()) self.textCursor().insertText(text) def _finish_process(self): self.overlay.killTimer(self.overlay.timer) self.overlay.hide() def resizeEvent(self, event): self.overlay.resize(event.size()) event.accept()
def run_installer(self, package_name): self.package_name = package_name if os.name == 'posix': home = os.environ['HOME'] elif os.name == 'nt': home = os.environ['HOMEPATH'] ## pip_rel_path = os.path.join(os.sep,'.qgis2', 'python', 'plugins','pipinstaller','pip-1.5.4') ## pip_path = ('%s%s') % (home,pip_rel_path) ## try: ## import pip ## except: ## try: ## subprocess.call('C:\\PROGRA~2\\QGISDU~1\\Osgeo4W.bat python ez_setup.py install') ## except Exception, e: ## print str(e) ## try: ## subprocess.call('C:\\PROGRA~2\\QGISDU~1\\Osgeo4W.bat python setup.py install') ## except Exception, e: ## print str(e) package_to_install = "reportlab" cmd = 'C:\\PROGRA~2\\QGISDU~1\\Osgeo4W.bat pip install sqlalchemy' qprocess = QProcess() p = qprocess.start(cmd) return p
class ReplicationSync(SyncProvider): def __init__(self, name, cmd): super(SyncProvider, self).__init__() self.name = name self.cmd = cmd self.process = QProcess() self.process.finished.connect(self.complete) self.process.started.connect(self.syncStarted) self.process.readyReadStandardError.connect(self.error) self.process.readyReadStandardOutput.connect(self.readOutput) self._output = "" self.haserror = False def startSync(self): self._output = "" self.process.start(self.cmd, []) @property def output(self): return self._output @output.setter def output(self, value): self._output = value def error(self): self.haserror = True def complete(self, error, status): self.output += str(self.process.readAll()) html = """<h3> {0} sync report </h3> <pre>{1}</pre>""".format(self.name, self.output) if error > 0 or self.haserror: html = """<h3> {0} Error </h3> <pre>{1}</pre>""".format(self.name, self.output) self.syncError.emit(html) else: self.syncComplete.emit(html) def readOutput(self): self.output += str(self.process.readAll()) html = """<h3> {0} progress report </h3> <pre>{1}</pre>""".format(self.name, self.output) self.syncMessage.emit(html)
def generate_video(cls, input_frames_folder, file_name, frames_pattern= "Frame_%07d.png", finish_callbak = None, bitrate=1800, fps = 30): input_frames_pattern = "%s/%s" % (input_frames_folder, frames_pattern) video_name = str_insert(file_name, "_%f" % time.time(), file_name.rfind(".")) video_output_path = "/tmp/%s" %video_name #Execute FFMPEG def _check_callback_status(code, code2): print "Processo FFMpeg finito, chiamo la callback" if finish_callbak: finish_callbak(code==0, video_output_path) process = QProcess(QApplication.instance()) process.finished.connect(_check_callback_status) process.start("/usr/local/bin/ffmpeg", ['-r', str(fps), '-b', str(bitrate), '-i', input_frames_pattern, video_output_path])
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()
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 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))
class BatchFileSync(SyncProvider): def __init__(self, name, **kwargs): super(BatchFileSync, self).__init__(name) self.cmd = kwargs['cmd'] self.process = QProcess() variables = kwargs.get("variables", {}) env = QProcessEnvironment.systemEnvironment() for varname, value in variables.iteritems(): env.insert(varname, value) self.process.setProcessEnvironment(env) self.process.setWorkingDirectory(os.path.dirname(os.path.realpath(self.cmd))) self.process.finished.connect(self.complete) self.process.started.connect(self.syncStarted) self.process.readyReadStandardError.connect(self.error) self.process.readyReadStandardOutput.connect(self.readOutput) self._output = "" self.haserror = False def start(self): self._output = "" self.process.start(self.cmd, []) @property def output(self): return self._output @output.setter def output(self, value): self._output = value def error(self): self.haserror = True def complete(self, error, status): if error > 0: stderr = self.process.readAllStandardError().data() self.syncError.emit(stderr) else: self.syncComplete.emit() self.syncFinished.emit() def readOutput(self): output = str(self.process.readAll()) self.syncMessage.emit(output)
class ConsoleWidget(QPlainTextEdit): def __init__(self): QPlainTextEdit.__init__(self, u'>>> ') self.setUndoRedoEnabled(False) self.apply_editor_style() self.setToolTip(self.tr("Show/Hide (F4)")) self.moveCursor(QTextCursor.EndOfLine) self._patIsWord = re.compile('\w+') self.prompt = u'>>> ' self._console = console.Console() self._history = [] self._braces = None self.imports = ['import __builtin__'] self.patFrom = re.compile('^(\\s)*from ((\\w)+(\\.)*(\\w)*)+ import') self.patImport = re.compile('^(\\s)*import (\\w)+') self.patObject = re.compile('[^a-zA-Z0-9_\\.]') self.completer = completer_widget.CompleterWidget(self) self.okPrefix = QRegExp('[.)}:,\]]') #Create Context Menu self._create_context_menu() self._highlighter = highlighter.Highlighter(self.document(), 'python', resources.CUSTOM_SCHEME) self.connect(self, SIGNAL("cursorPositionChanged()"), self.highlight_current_line) self.highlight_current_line() self._proc = QProcess(self) self.connect(self._proc, SIGNAL("readyReadStandardOutput()"), self._python_path_detected) self.connect(self._proc, SIGNAL("error(QProcess::ProcessError)"), self.process_error) self._add_system_path_for_frozen() def _add_system_path_for_frozen(self): try: self._proc.start(settings.PYTHON_PATH, [resources.GET_SYSTEM_PATH]) except Exception, reason: logger.error('Could not get system path, error: %r' % reason)
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 checkSoxEncoding(QObject) : """checkSoxEncoding est une class pour vérifier les possibilités de Sox pour l'encodage du format mp2/mp3. Si ce n'est pas le cas, retourne 0 -> adaptation de l'interface pour supprimer ces possibilités""" def __init__(self, listeformat, parent=None) : super(checkSoxEncoding, self).__init__(parent) #self.hide() self.listeFormat = listeformat self.parent = parent self.index = 0 self.checkListeFormat = [] def run(self) : self.soxP = QProcess(self.parent) self.connect(self.soxP, SIGNAL('finished(int)'), self.finProcess) self.write = 0 commande = u"sox -n -t %s \"%s\" trim 00:00:00.000 00:00:01.000" % (self.listeFormat[self.index], os.path.expanduser("~")+os.sep+u"checkSoxEssai."+self.listeFormat[self.index]) ### Debug print commande self.soxP.setProcessChannelMode(QProcess.MergedChannels) self.soxP.start(commande) def finProcess(self,statut) : # Test si la commande a été exécutée correctement print "statut de sortie : %d" % (statut) if not statut : # Si OK -> Ajout de l'extension dans la liste des formats supportés par Sox en encodage self.checkListeFormat.append((self.listeFormat[self.index],True)) os.remove(os.path.expanduser("~")+os.sep+u"checkSoxEssai."+self.listeFormat[self.index]) else : # Sinon, déclaré le format comme non utilisable et donc pas présent dans la liste des formats supportés self.checkListeFormat.append((self.listeFormat[self.index],False)) # Incrémentation du compteur pour explorer tous les formats à tester self.index += 1 ### Debug print "index = %d" % (self.index) print "longueur liste = %d" % (len(self.listeFormat)) # Si l'index est égal au nombre de format à tester, la class émet le signal de fin de vérification + liste des formats avec info sur le support if self.index == len(self.listeFormat) : ### Debug : print self.checkListeFormat self.emit(SIGNAL("checkSox"), self.checkListeFormat) else : self.run()
class BatchFileSync(SyncProvider): def __init__(self, name, cmd): super(BatchFileSync, self).__init__(name) self.cmd = cmd self.process = QProcess() self.process.setWorkingDirectory(os.path.dirname(os.path.realpath(self.cmd))) self.process.finished.connect(self.complete) self.process.started.connect(self.syncStarted) self.process.readyReadStandardError.connect(self.error) self.process.readyReadStandardOutput.connect(self.readOutput) self._output = "" self.haserror = False def start(self): self._output = "" self.process.start(self.cmd, []) @property def output(self): return self._output @output.setter def output(self, value): self._output = value def error(self): self.haserror = True def complete(self, error, status): if error > 0: stderr = self.process.readAllStandardError().data() self.syncError.emit(stderr) else: self.syncComplete.emit() self.syncFinished.emit() def readOutput(self): output = str(self.process.readAll()) self.syncMessage.emit(output)
class Widget(QtGui.QWidget, Screen): title = i18n("Security") desc = i18n("Keep your system secure") screenSettings = {} screenSettings["hasChanged"] = False def __init__(self, *args): QtGui.QWidget.__init__(self, None) self.ui = Ui_securityWidget() self.ui.setupUi(self) # set up self.config self.config = Daemon() # set initial states self.ui.enableFire.setChecked(self.config.isEnabled("ufw")) self.ui.enableFire.setEnabled(self.config.isInstalled("ufw")) self.ui.enableClam.setEnabled(False) if self.config.isInstalled("clamd"): if os.system("grep -q ^Example /etc/clamav/clamd.conf" ) == 256: # 256 is 'no match'. if os.system( "grep -q ^Example /etc/clamav/freshclam.conf") == 256: self.ui.enableClam.setEnabled(True) self.ui.enableClam.setChecked(self.config.isEnabled("clamd")) else: self.ui.enableClam.setChecked(False) def applySettings(self): if self.ui.enableFire.isChecked(): self.__class__.screenSettings["enableFire"] = True if not self.config.isEnabled("ufw"): self.__class__.screenSettings["hasChanged"] = True else: self.__class__.screenSettings["enableFire"] = False if self.config.isEnabled("ufw"): self.__class__.screenSettings["hasChanged"] = True if self.ui.enableClam.isChecked(): self.__class__.screenSettings["enableClam"] = True if not self.config.isEnabled("clamd"): self.__class__.screenSettings["hasChanged"] = True else: self.__class__.screenSettings["enableClam"] = False if self.config.isEnabled("clamd"): self.__class__.screenSettings["hasChanged"] = True def on_buttonClam_clicked(self): self.procSettings = QProcess() command = "xdg-open http://www.chakraos.org/wiki/index.php?title=Anti-Malware#ClamAV" self.procSettings.start(command) def on_buttonTomoyo_clicked(self): self.procSettings = QProcess() command = "xdg-open http://www.chakraos.org/wiki/index.php?title=Using_tomoyo-tools_for_system_security" self.procSettings.start(command) def on_buttonKwallet_clicked(self): self.procSettings = QProcess() command = "xdg-open http://www.chakraos.org/wiki/index.php?title=KDE_Wallet_Manager" self.procSettings.start(command) def on_buttonRootkit_clicked(self): self.procSettings = QProcess() command = "xdg-open http://www.chakraos.org/wiki/index.php?title=Anti-Malware#chkrootkit_and_rkhunter" self.procSettings.start(command) def on_buttonTiger_clicked(self): self.procSettings = QProcess() command = "xdg-open http://www.nongnu.org/tiger/" self.procSettings.start(command) def shown(self): pass def execute(self): self.applySettings() return True
class GdalToolsBaseDialog(QDialog, Ui_Dialog): def __init__(self, parent, iface, pluginBase, pluginName, pluginCommand): QDialog.__init__(self, parent) self.setAttribute(Qt.WA_DeleteOnClose) self.iface = iface self.process = QProcess(self) Utils.setProcessEnvironment(self.process) self.connect(self.process, SIGNAL("error(QProcess::ProcessError)"), self.processError) self.connect(self.process, SIGNAL("finished(int, QProcess::ExitStatus)"), self.processFinished) self.setupUi(self) self.arguments = [] self.editCmdBtn.setIcon(QIcon(":/icons/edit.png")) self.connect(self.editCmdBtn, SIGNAL("toggled(bool)"), self.editCommand) self.resetCmdBtn.setIcon(QIcon(":/icons/reset.png")) self.connect(self.resetCmdBtn, SIGNAL("clicked()"), self.resetCommand) self.editCommand(False) self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject) self.connect(self.buttonBox, SIGNAL("accepted()"), self.accept) self.connect(self.buttonBox, SIGNAL("helpRequested()"), self.help) self.buttonBox.button(QDialogButtonBox.Ok).setDefault(True) self.plugin = pluginBase self.connect(self.plugin, SIGNAL("valuesChanged(PyQt_PyObject)"), self.refreshArgs) self.pluginLayout.addWidget(self.plugin) self.plugin.setFocus() self.setWindowTitle(pluginName) self.setPluginCommand(pluginCommand) def setPluginCommand(self, cmd): # on Windows replace the .py with .bat extension if platform.system() == "Windows" and cmd[-3:] == ".py": self.command = cmd[:-3] + ".bat" else: self.command = cmd if cmd[-3:] == ".py": self.helpFileName = cmd[:-3] + ".html" else: self.helpFileName = cmd + ".html" def editCommand(self, enabled): if not self.commandIsEnabled(): return self.editCmdBtn.setChecked(enabled) self.resetCmdBtn.setEnabled(enabled) self.textEditCommand.setReadOnly(not enabled) self.controlsWidget.setEnabled(not enabled) self.emit(SIGNAL("refreshArgs()")) def resetCommand(self): if not self.commandIsEditable(): return self.emit(SIGNAL("refreshArgs()")) def commandIsEditable(self): return self.commandIsEnabled() and self.editCmdBtn.isChecked() def setCommandViewerEnabled(self, enable): if not enable: self.editCommand(False) self.commandWidget.setEnabled(enable) def commandIsEnabled(self): return self.commandWidget.isEnabled() def reject(self): if self.process.state() != QProcess.NotRunning: ret = QMessageBox.warning( self, self.tr("Warning"), self. tr("The command is still running. \nDo you want terminate it anyway?" ), QMessageBox.Yes | QMessageBox.No) if ret == QMessageBox.No: return self.disconnect(self.process, SIGNAL("error(QProcess::ProcessError)"), self.processError) self.disconnect(self.process, SIGNAL("finished(int, QProcess::ExitStatus)"), self.processFinished) self.emit(SIGNAL("closeClicked()")) def accept(self): self.emit(SIGNAL("okClicked()")) def help(self): self.emit(SIGNAL("helpClicked()")) def processError(self, error): self.emit(SIGNAL("processError(QProcess::ProcessError)"), error) def processFinished(self, exitCode, status): self.emit(SIGNAL("processFinished(int, QProcess::ExitStatus)"), exitCode, status) # show the online tool documentation in the default browser def onHelp(self): helpPath = Utils.getHelpPath() if helpPath == '': url = QUrl("http://www.gdal.org/" + self.helpFileName) else: url = QUrl.fromLocalFile(helpPath + '/' + self.helpFileName) QDesktopServices.openUrl(url) # called when a value in the plugin widget interface changed def refreshArgs(self, args): self.arguments = [unicode(a) for a in args] if not self.commandIsEnabled(): self.textEditCommand.setPlainText(self.command) else: self.textEditCommand.setPlainText( self.command + " " + Utils.escapeAndJoin(self.arguments)) # enables the OK button def enableRun(self, enable=True): self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) # start the command execution def onRun(self): self.enableRun(False) self.setCursor(Qt.WaitCursor) if not self.commandIsEditable(): #print(self.command+' '+unicode(self.arguments)) self.process.start(self.command, self.arguments, QIODevice.ReadOnly) else: self.process.start(self.textEditCommand.toPlainText(), QIODevice.ReadOnly) # stop the command execution def stop(self): self.enableRun(True) self.setCursor(Qt.ArrowCursor) self.process.kill() # called on closing the dialog, stop the process if it's running def onClosing(self): self.stop() QDialog.reject(self) # called if an error occurs when the command has not already finished, shows the occurred error message def onError(self, error): if error == QProcess.FailedToStart: msg = QCoreApplication.translate( "GdalTools", "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program." ) elif error == QProcess.Crashed: msg = QCoreApplication.translate( "GdalTools", "The process crashed some time after starting successfully.") else: msg = QCoreApplication.translate("GdalTools", "An unknown error occurred.") QErrorMessage(self).showMessage(msg) QApplication.processEvents() # give the user chance to see the message self.stop() # called when the command finished its execution, shows an error message if there's one # and, if required, load the output file in canvas def onFinished(self, exitCode, status): if status == QProcess.CrashExit: self.stop() return if self.command.find("gdalinfo") != -1 and exitCode == 0: self.emit(SIGNAL("finished(bool)"), self.loadCheckBox.isChecked()) self.stop() return # show the error message if there's one, otherwise show the process output message msg = unicode(self.process.readAllStandardError()) if msg == '': outMessages = unicode( self.process.readAllStandardOutput()).splitlines() # make sure to not show the help for m in outMessages: m = string.strip(m) if m == '': continue # TODO fix this #if m.contains( QRegExp( "^(?:[Uu]sage:\\s)?" + QRegExp.escape(self.command) + "\\s" ) ): # if msg.isEmpty(): # msg = self.tr ( "Invalid parameters." ) # break #if m.contains( QRegExp( "0(?:\\.+[1-9]0{1,2})+" ) ): # continue if msg: msg += "\n" msg += m QErrorMessage(self).showMessage(msg.replace("\n", "<br>")) if exitCode == 0: self.emit(SIGNAL("finished(bool)"), self.loadCheckBox.isChecked()) self.stop()
class MyMainWindow(QMainWindow): ' Main Window ' def __init__(self, parent=None): ' Initialize QWidget inside MyMainWindow ' super(MyMainWindow, self).__init__(parent) self.statusBar().showMessage(__doc__.title()) self.setWindowTitle(__doc__) self.setMinimumSize(600, 800) self.setMaximumSize(2048, 1024) self.resize(1024, 800) self.setWindowIcon(QIcon.fromTheme("face-monkey")) if not A11Y: self.setStyleSheet('''QWidget{color:#fff;font-family:Oxygen} QWidget:item:hover, QWidget:item:selected { background-color: cyan; color: #000 } QWidget:disabled { color: #404040; background-color: #323232 } QWidget:focus { border: 1px solid cyan } QPushButton { background-color: gray; padding: 3px; border: 1px solid gray; border-radius: 9px; margin: 0;font-size: 12px; padding-left: 5px; padding-right: 5px } QLineEdit, QTextEdit { background-color: #4a4a4a; border: 1px solid gray; border-radius: 0; font-size: 12px; } QPushButton:pressed { background-color: #323232 } QComboBox { background-color: #4a4a4a; padding-left: 9px; border: 1px solid gray; border-radius: 5px; } QComboBox:pressed { background-color: gray } QComboBox QAbstractItemView, QMenu { border: 1px solid #4a4a4a; background:grey; selection-background-color: cyan; selection-color: #000; } QSlider { padding: 3px; font-size: 8px; padding-left: 2px; padding-right: 2px; border: 5px solid #1e1e1e } QSlider::sub-page:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.27, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(50, 0, 0, 200)); border: 4px solid #1e1e1e; border-radius: 5px } QSlider::add-page:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.27, stop:0 rgba(0, 255, 0, 255), stop:1 rgba(0, 99, 0, 255)); border: 4px solid #1e1e1e; border-radius: 5px; } QSlider::handle:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.273, stop:0 rgba(0, 0, 0, 255), stop:1 gray); height: 5px; border: 1px dotted #fff; text-align: center; border-top-left-radius: 2px; border-bottom-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius 2px; margin-left: 2px; margin-right: 2px; } QSlider::handle:vertical:hover { border: 1px solid cyan } QSlider::sub-page:vertical:disabled { background: #bbb; border-color: #999; } QSlider::add-page:vertical:disabled { background: #eee; border-color: #999; } QSlider::handle:vertical:disabled { background: #eee; border: 1px solid #aaa; border-radius: 4px; } QToolBar, QStatusBar, QDockWidget::title{background-color:#323232;} QToolBar::handle, QToolBar::handle:vertical, QToolBar::handle:horizontal { border: 1px solid gray; border-radius: 9px; width: 19px; height: 19px; margin: 0.5px } QGroupBox { border: 1px solid gray; border-radius: 9px; padding-top: 9px; } QStatusBar, QToolBar::separator:horizontal, QToolBar::separator:vertical {color:gray} QScrollBar:vertical{ background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #212121,stop: 1.0 #323232); width: 10px; } QScrollBar:horizontal{ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #212121,stop: 1.0 #323232); height: 10px; } QScrollBar::handle:vertical{ padding: 2px; min-height: 50px; background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #585858,stop: 1.0 #404040); border-radius: 5px; border: 1px solid #191919; } QScrollBar::handle:horizontal{ padding: 2px; min-width: 50px; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #585858,stop: 1.0 #404040); border-radius: 5px; border: 1px solid #191919; } QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { background: none; border: none; } QDockWidget::close-button, QDockWidget::float-button { border: 1px solid gray; border-radius: 3px; background: darkgray; }''') self.process = QProcess() self.process.readyReadStandardOutput.connect(self.read_output) self.process.readyReadStandardError.connect(self.read_errors) self.process.finished.connect(self._process_finished) self.process.error.connect(self._process_finished) self.group0, self.group1 = QGroupBox("Options"), QGroupBox("Paths") self.group2 = QGroupBox("Nodes") self.group3 = QGroupBox("Python Code") self.group4, self.group5 = QGroupBox("Logs"), QGroupBox("Backend") g0grid, g1vlay = QGridLayout(self.group0), QVBoxLayout(self.group1) g5vlay = QVBoxLayout(self.group5) self.treeview_nodes, self.textedit_source = QTextEdit(), QTextEdit() self.dock1, self.dock2 = QDockWidget(), QDockWidget() self.output, self.dock3 = QTextEdit(), QDockWidget() self.treeview_nodes.setAutoFormatting(QTextEdit.AutoAll) self.treeview_nodes.setWordWrapMode(QTextOption.NoWrap) self.dock1.setWidget(self.treeview_nodes) self.dock2.setWidget(self.textedit_source) self.dock3.setWidget(self.output) self.dock1.setWindowTitle("Tree") self.dock2.setWindowTitle("Sources") self.dock3.setWindowTitle("STDOutput") featur = QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable self.dock1.setFeatures(featur) self.dock2.setFeatures(featur) self.dock3.setFeatures(featur) QVBoxLayout(self.group2).addWidget(self.dock1) QVBoxLayout(self.group3).addWidget(self.dock2) QVBoxLayout(self.group4).addWidget(self.dock3) self.slider1, self.slider2 = QSlider(), QSlider() g0grid.addWidget(self.slider1, 0, 0) g0grid.addWidget(QLabel('Use Debug'), 0, 1) self.slider2.setValue(1) g0grid.addWidget(self.slider2, 1, 0) g0grid.addWidget(QLabel('Use verbose'), 1, 1) self.slider3, self.slider4 = QSlider(), QSlider() self.slider3.setValue(1) g0grid.addWidget(self.slider3, 2, 0) g0grid.addWidget(QLabel('Show compiling progress'), 2, 1) self.slider4.setValue(1) g0grid.addWidget(self.slider4, 3, 0) g0grid.addWidget(QLabel('Show Scons building debug'), 3, 1) self.slider5, self.slider6 = QSlider(), QSlider() g0grid.addWidget(self.slider5, 4, 0) g0grid.addWidget(QLabel('Keep debug unstriped binary'), 4, 1) g0grid.addWidget(self.slider6, 5, 0) g0grid.addWidget(QLabel('Traced execution outputs'), 5, 1) self.slider7, self.slider8 = QSlider(), QSlider() self.slider7.setValue(1) g0grid.addWidget(self.slider7, 6, 0) g0grid.addWidget(QLabel('Remove the build folder'), 6, 1) g0grid.addWidget(self.slider8, 7, 0) g0grid.addWidget(QLabel('No Python Optimizations'), 7, 1) self.slider9, self.slider10 = QSlider(), QSlider() g0grid.addWidget(self.slider9, 8, 0) g0grid.addWidget(QLabel('No Statements line numbers'), 8, 1) g0grid.addWidget(self.slider10, 9, 0) g0grid.addWidget(QLabel('Execute the output binary'), 9, 1) self.slider11, self.slider12 = QSlider(), QSlider() g0grid.addWidget(self.slider11, 10, 0) g0grid.addWidget(QLabel('Warning detected implicit exceptions'), 10, 1) g0grid.addWidget(self.slider12, 11, 0) g0grid.addWidget(QLabel('Keep the PYTHONPATH, do not Reset it'), 11, 1) self.slider13 = QSlider() g0grid.addWidget(self.slider13, 12, 0) g0grid.addWidget(QLabel('Enhance compile, CPython incompatible'), 12, 1) self.slider1a, self.slider2a = QSlider(), QSlider() g0grid.addWidget(self.slider1a, 0, 2) g0grid.addWidget(QLabel('Descendent Recursive Compile'), 0, 3) self.slider2a.setValue(1) g0grid.addWidget(self.slider2a, 1, 2) g0grid.addWidget(QLabel('Force non recursive compile'), 1, 3) self.slider3a, self.slider4a = QSlider(), QSlider() g0grid.addWidget(self.slider3a, 2, 2) g0grid.addWidget(QLabel('STD Lib Recursive Compile'), 2, 3) g0grid.addWidget(self.slider4a, 3, 2) g0grid.addWidget(QLabel('Enforce the use of Clang'), 3, 3) self.slider5a, self.slider6a = QSlider(), QSlider() self.slider5a.setValue(1) g0grid.addWidget(self.slider5a, 4, 2) g0grid.addWidget(QLabel('Use G++ link time optimizations'), 4, 3) g0grid.addWidget(self.slider6a, 5, 2) g0grid.addWidget(QLabel('Disable the console window'), 5, 3) self.slider7a, self.slider8a = QSlider(), QSlider() g0grid.addWidget(self.slider7a, 6, 2) g0grid.addWidget(QLabel('Force compile for MS Windows'), 6, 3) g0grid.addWidget(self.slider8a, 7, 2) g0grid.addWidget(QLabel('Use Python Debug versions'), 7, 3) self.slider9a, self.slider10a = QSlider(), QSlider() self.slider9a.setValue(1) g0grid.addWidget(self.slider9a, 8, 2) g0grid.addWidget(QLabel('Create standalone executable'), 8, 3) g0grid.addWidget(self.slider10a, 9, 2) g0grid.addWidget(QLabel('Enable Standalone mode build'), 9, 3) self.slider11a, self.slider12a = QSlider(), QSlider() g0grid.addWidget(self.slider11a, 10, 2) g0grid.addWidget(QLabel('Make module executable instead of app'), 10, 3) g0grid.addWidget(self.slider12a, 11, 2) g0grid.addWidget(QLabel('No froze module of stdlib as bytecode'), 11, 3) self.slider13a = QSlider() g0grid.addWidget(self.slider13a, 12, 2) g0grid.addWidget(QLabel('Force use of MinGW on MS Windows'), 12, 3) for each_widget in (self.slider1, self.slider2, self.slider3, self.slider4, self.slider5, self.slider6, self.slider7, self.slider8, self.slider9, self.slider10, self.slider11, self.slider12, self.slider13, self.slider1a, self.slider2a, self.slider3a, self.slider4a, self.slider5a, self.slider6a, self.slider7a, self.slider8a, self.slider9a, self.slider10a, self.slider11a, self.slider12a, self.slider13a): each_widget.setRange(0, 1) each_widget.setCursor(QCursor(Qt.OpenHandCursor)) each_widget.setTickInterval(1) each_widget.TickPosition(QSlider.TicksBothSides) self.combo1 = QComboBox() self.combo1.addItems(('2.7', '2.6', '3.2', '3.3')) g5vlay.addWidget(QLabel('Python Version')) g5vlay.addWidget(self.combo1) self.combo2 = QComboBox() self.combo2.addItems(('Default', 'Low', 'High')) g5vlay.addWidget(QLabel('CPU priority')) g5vlay.addWidget(self.combo2) self.combo3 = QComboBox() self.combo3.addItems(('1', '2', '3', '4', '5', '6', '7', '8', '9')) g5vlay.addWidget(QLabel('MultiProcessing Workers')) g5vlay.addWidget(self.combo3) self.outdir = QLineEdit() self.outdir.setStyleSheet("QLineEdit{margin-left:25px}") self.clearButton = QToolButton(self.outdir) self.clearButton.setIcon(QIcon.fromTheme("edit-clear")) self.clearButton.setIconSize(QSize(25, 25)) self.clearButton.setStyleSheet("QToolButton{border:none}") self.clearButton.hide() self.clearButton.clicked.connect(self.outdir.clear) self.outdir.textChanged.connect( lambda: self.clearButton.setVisible(True)) self.clearButton.clicked.connect( lambda: self.clearButton.setVisible(False)) self.outdir.setPlaceholderText('Output Directory') if path.isfile('.nuitka-output-dir.txt'): self.outdir.setText(open('.nuitka-output-dir.txt', 'r').read()) else: self.outdir.setText(path.expanduser("~")) self.completer, self.dirs = QCompleter(self), QDirModel(self) self.dirs.setFilter(QDir.Dirs | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.completer.popup().setStyleSheet( """border:1px solid #4a4a4a;background:grey; selection-background-color:cyan;selection-color:#000""") self.completer.popup().setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOff) self.outdir.setCompleter(self.completer) self.btn1 = QPushButton(QIcon.fromTheme("document-open"), 'Open' if IS_WIN else '') self.btn1.clicked.connect( lambda: open('.nuitka-output-dir.txt', 'w').write( str( QFileDialog.getExistingDirectory( None, 'Open Output Directory', path.expanduser("~"))))) self.btn1.released.connect(lambda: self.outdir.setText( open('.nuitka-output-dir.txt', 'r').read())) g1vlay.addWidget(QLabel('Output Directory')) g1vlay.addWidget(self.outdir) g1vlay.addWidget(self.btn1) self.target = QLineEdit() self.target.setStyleSheet("QLineEdit{margin-left:25px}") self.clearButton2 = QToolButton(self.target) self.clearButton2.setIcon(QIcon.fromTheme("edit-clear")) self.clearButton2.setIconSize(QSize(25, 25)) self.clearButton2.setStyleSheet("QToolButton{border:none}") self.clearButton2.hide() self.clearButton2.clicked.connect(self.target.clear) self.target.textChanged.connect( lambda: self.clearButton2.setVisible(True)) self.clearButton2.clicked.connect( lambda: self.clearButton2.setVisible(False)) self.target.setPlaceholderText('Target Python App to Binary Compile') self.target.setCompleter(self.completer) self.btn2 = QPushButton(QIcon.fromTheme("document-open"), 'Open' if IS_WIN else '') self.btn2.clicked.connect(lambda: self.target.setText( str( QFileDialog.getOpenFileName( None, "Open", path.expanduser("~"), ';;'.join([ '{}(*.{})'.format(e.upper(), e) for e in ('py', 'pyw', '*') ]))))) g1vlay.addWidget(QLabel('Input File')) g1vlay.addWidget(self.target) g1vlay.addWidget(self.btn2) self.icon, self.icon_label = QLineEdit(), QLabel('Icon File') self.icon.setStyleSheet("QLineEdit{margin-left:25px}") self.clearButton3 = QToolButton(self.icon) self.clearButton3.setIcon(QIcon.fromTheme("edit-clear")) self.clearButton3.setIconSize(QSize(25, 25)) self.clearButton3.setStyleSheet("QToolButton{border:none}") self.clearButton3.hide() self.clearButton3.clicked.connect(self.icon.clear) self.icon.textChanged.connect( lambda: self.clearButton3.setVisible(True)) self.clearButton3.clicked.connect( lambda: self.clearButton3.setVisible(False)) self.icon.setPlaceholderText('Path to Icon file for your App') self.icon.setCompleter(self.completer) self.btn3 = QPushButton(QIcon.fromTheme("document-open"), 'Open' if IS_WIN else '') self.btn3.clicked.connect(lambda: self.icon.setText( str( QFileDialog.getOpenFileName( None, "Open", path.expanduser("~"), ';;'.join([ '{}(*.{})'.format(e.upper(), e) for e in ('ico', 'png', 'bmp', 'svg', '*') ]))))) g1vlay.addWidget(self.icon_label) g1vlay.addWidget(self.icon) g1vlay.addWidget(self.btn3) # Menu Bar inicialization and detail definitions menu_salir = QAction(QIcon.fromTheme("application-exit"), 'Quit', self) menu_salir.setStatusTip('Quit') menu_salir.triggered.connect(exit) menu_minimize = QAction(QIcon.fromTheme("go-down"), 'Minimize', self) menu_minimize.setStatusTip('Minimize') menu_minimize.triggered.connect(lambda: self.showMinimized()) menu_qt = QAction(QIcon.fromTheme("help-about"), 'About Qt', self) menu_qt.setStatusTip('About Qt...') menu_qt.triggered.connect(lambda: QMessageBox.aboutQt(self)) menu_dev = QAction(QIcon.fromTheme("applications-development"), 'Developer Manual PDF', self) menu_dev.setStatusTip('Open Nuitka Developer Manual PDF...') menu_dev.triggered.connect(lambda: call( OPEN + '/usr/share/doc/nuitka/Developer_Manual.pdf.gz', shell=True) ) menu_usr = QAction(QIcon.fromTheme("help-contents"), 'User Docs', self) menu_usr.setStatusTip('Open Nuitka End User Manual PDF...') menu_usr.triggered.connect(lambda: call( OPEN + '/usr/share/doc/nuitka/README.pdf.gz', shell=True)) menu_odoc = QAction(QIcon.fromTheme("help-browser"), 'OnLine Doc', self) menu_odoc.setStatusTip('Open Nuitka on line Documentation pages...') menu_odoc.triggered.connect( lambda: open_new_tab('http://nuitka.net/doc/user-manual.html')) menu_man = QAction(QIcon.fromTheme("utilities-terminal"), 'Man', self) menu_man.setStatusTip('Open Nuitka technical command line Man Pages..') menu_man.triggered.connect( lambda: call('xterm -e "man nuitka"', shell=True)) menu_tra = QAction(QIcon.fromTheme("applications-development"), 'View Nuitka-GUI Source Code', self) menu_tra.setStatusTip('View, study, edit Nuitka-GUI Libre Source Code') menu_tra.triggered.connect(lambda: call(OPEN + __file__, shell=True)) menu_foo = QAction(QIcon.fromTheme("folder"), 'Open Output Dir', self) menu_foo.setStatusTip('Open the actual Output Directory location...') menu_foo.triggered.connect( lambda: call(OPEN + str(self.outdir.text()), shell=True)) menu_pic = QAction(QIcon.fromTheme("camera-photo"), 'Screenshot', self) menu_pic.setStatusTip('Take a Screenshot for Documentation purposes..') menu_pic.triggered.connect( lambda: QPixmap.grabWindow(QApplication.desktop().winId()).save( QFileDialog.getSaveFileName(None, "Save", path.expanduser("~"), 'PNG(*.png)', 'png'))) menu_don = QAction(QIcon.fromTheme("emblem-favorite"), 'Help Nuitka', self) menu_don.setStatusTip('Help the Nuitka Open Source Libre Free Project') menu_don.triggered.connect( lambda: open_new_tab('http://nuitka.net/pages/donations.html')) # movable draggable toolbar self.toolbar = QToolBar(self) self.toolbar.setIconSize(QSize(16, 16)) self.toolbar.toggleViewAction().setText("Show/Hide Toolbar") l_spacer, r_spacer = QWidget(self), QWidget(self) l_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) r_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.toolbar.addWidget(l_spacer) self.toolbar.addSeparator() self.toolbar.addActions((menu_salir, menu_minimize, menu_qt, menu_odoc, menu_foo, menu_pic, menu_don)) if not IS_WIN: self.toolbar.addActions((menu_man, menu_dev, menu_tra, menu_usr)) self.toolbar.addSeparator() self.toolbar.addWidget(r_spacer) self.addToolBar(Qt.BottomToolBarArea, self.toolbar) # Bottom Buttons Bar self.buttonBox = QDialogButtonBox(self) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Close) self.buttonBox.rejected.connect(exit) self.buttonBox.accepted.connect(self.run) self.guimode = QComboBox() self.guimode.addItems(('Full UX / UI', 'Simple UX / UI')) self.guimode.setStyleSheet( """QComboBox{background:transparent;border:0; margin-left:25px;color:gray;text-decoration:underline}""") self.guimode.currentIndexChanged.connect(self.set_guimode) container = QWidget() container_layout = QGridLayout(container) # Y, X container_layout.addWidget(self.guimode, 0, 1) container_layout.addWidget(self.group2, 1, 0) container_layout.addWidget(self.group3, 2, 0) container_layout.addWidget(self.group0, 1, 1) container_layout.addWidget(self.group1, 2, 1) container_layout.addWidget(self.group4, 1, 2) container_layout.addWidget(self.group5, 2, 2) container_layout.addWidget(self.buttonBox, 3, 1) self.setCentralWidget(container) # Paleta de colores para pintar transparente if not A11Y: palette = self.palette() palette.setBrush(QPalette.Base, Qt.transparent) self.setPalette(palette) self.setAttribute(Qt.WA_OpaquePaintEvent, False) def get_fake_tree(self, target): """Return the fake tree.""" try: fake_tree = check_output(NUITKA + ' --dump-xml ' + target, shell=True) except: fake_tree = "ERROR: Failed to get Tree Dump." finally: return fake_tree.strip() def run(self): ' run the actual backend process ' self.treeview_nodes.clear() self.textedit_source.clear() self.output.clear() self.statusBar().showMessage('WAIT!, Working...') target = str(self.target.text()).strip() self.treeview_nodes.setText(self.get_fake_tree(target)) self.textedit_source.setText(open(target, "r").read().strip()) conditional_1 = sys.platform.startswith('linux') conditional_2 = self.combo3.currentIndex() != 2 command_to_run_nuitka = " ".join( ('chrt -i 0' if conditional_1 and conditional_2 else '', NUITKA, '--debug' if self.slider1.value() else '', '--verbose' if self.slider2.value() else '', '--show-progress' if self.slider3.value() else '', '--show-scons --show-modules' if self.slider4.value() else '', '--unstriped' if self.slider5.value() else '', '--trace-execution' if self.slider6.value() else '', '--remove-output' if self.slider7.value() else '', '--no-optimization' if self.slider8.value() else '', '--code-gen-no-statement-lines' if self.slider9.value() else '', '--execute' if self.slider10.value() else '', '--recurse-all' if self.slider1a.value() else '', '--recurse-none' if self.slider2a.value() else '', '--recurse-stdlib' if self.slider3a.value() else '', '--clang' if self.slider4a.value() else '', '--lto' if self.slider5a.value() else '', '--windows-disable-console' if self.slider6a.value() else '', '--windows-target' if self.slider7a.value() else '', '--python-debug' if self.slider8a.value() else '', '--exe' if self.slider9a.value() else '', '--standalone' if self.slider10a.value() else '', '--module' if self.slider11a.value() else '', '--nofreeze-stdlib' if self.slider12a.value() else '', '--mingw' if self.slider13a.value() else '', '--warn-implicit-exceptions' if self.slider11.value() else '', '--execute-with-pythonpath' if self.slider12.value() else '', '--enhanced' if self.slider13.value() else '', '--icon="{}"'.format(self.icon.text()) if self.icon.text() else '', '--python-version={}'.format( self.combo1.currentText()), '--jobs={}'.format( self.combo3.currentText()), '--output-dir="{}"'.format( self.outdir.text()), "{}".format(target))) if DEBUG: print(command_to_run_nuitka) self.process.start(command_to_run_nuitka) if not self.process.waitForStarted() and not IS_WIN: return # ERROR ! self.statusBar().showMessage(__doc__.title()) def _process_finished(self): """finished sucessfully""" self.output.setFocus() self.output.selectAll() def read_output(self): """Read and append output to the log""" self.output.append(str(self.process.readAllStandardOutput())) def read_errors(self): """Read and append errors to the log""" self.output.append(str(self.process.readAllStandardError())) def paintEvent(self, event): """Paint semi-transparent background,animated pattern,background text""" if not A11Y: p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) p.setRenderHint(QPainter.TextAntialiasing) p.setRenderHint(QPainter.HighQualityAntialiasing) p.fillRect(event.rect(), Qt.transparent) # animated random dots background pattern for i in range(4096): x = randint(25, self.size().width() - 25) y = randint(25, self.size().height() - 25) # p.setPen(QPen(QColor(randint(9, 255), 255, 255), 1)) p.drawPoint(x, y) p.setPen(QPen(Qt.white, 1)) p.rotate(40) p.setFont(QFont('Ubuntu', 250)) p.drawText(200, 99, "Nuitka") p.rotate(-40) p.setPen(Qt.NoPen) p.setBrush(QColor(0, 0, 0)) p.setOpacity(0.8) p.drawRoundedRect(self.rect(), 9, 9) p.end() def set_guimode(self): """Switch between simple and full UX""" for widget in (self.group2, self.group3, self.group4, self.group5, self.icon, self.icon_label, self.btn3, self.toolbar, self.statusBar()): widget.hide() if self.guimode.currentIndex() else widget.show()
class RunWidget(QWidget): """Widget that show the execution output in the MiscContainer.""" def __init__(self): QWidget.__init__(self) vbox = QVBoxLayout(self) vbox.setSpacing(0) vbox.setContentsMargins(0, 0, 0, 0) self.output = OutputWidget(self) hbox = QHBoxLayout() self.input = QLineEdit() self.lblInput = QLabel(self.tr("Input:")) vbox.addWidget(self.output) hbox.addWidget(self.lblInput) hbox.addWidget(self.input) vbox.addLayout(hbox) #process self.currentProcess = None self.__preScriptExecuted = False self._proc = QProcess(self) self._preExecScriptProc = QProcess(self) self._postExecScriptProc = QProcess(self) self.connect(self._proc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._proc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) self.connect(self._proc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.finish_execution) self.connect(self._proc, SIGNAL("error(QProcess::ProcessError)"), self.process_error) self.connect(self.input, SIGNAL("returnPressed()"), self.insert_input) self.connect(self._preExecScriptProc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.__main_execution) self.connect(self._preExecScriptProc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._preExecScriptProc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) self.connect(self._postExecScriptProc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.__post_execution_message) self.connect(self._postExecScriptProc, SIGNAL("readyReadStandardOutput()"), self.output._refresh_output) self.connect(self._postExecScriptProc, SIGNAL("readyReadStandardError()"), self.output._refresh_error) def process_error(self, error): """Listen to the error signals from the running process.""" self.lblInput.hide() self.input.hide() self._proc.kill() format = QTextCharFormat() format.setAnchor(True) format.setForeground(Qt.red) if error == 0: self.output.textCursor().insertText(self.tr('Failed to start'), format) else: self.output.textCursor().insertText( self.tr('Error during execution, QProcess error: %d' % error), format) def finish_execution(self, exitCode, exitStatus): """Print a message and hide the input line when the execution ends.""" self.lblInput.hide() self.input.hide() format = QTextCharFormat() format.setAnchor(True) self.output.textCursor().insertText('\n\n') if exitStatus == QProcess.NormalExit: format.setForeground(Qt.green) self.output.textCursor().insertText( self.tr("Execution Successful!"), format) else: format.setForeground(Qt.red) self.output.textCursor().insertText( self.tr("Execution Interrupted"), format) self.output.textCursor().insertText('\n\n') self.__post_execution() def insert_input(self): """Take the user input and send it to the process.""" text = self.input.text() + '\n' self._proc.writeData(text) self.input.setText("") def start_process(self, fileName, pythonPath=False, programParams='', preExec='', postExec=''): """Prepare the output widget and start the process.""" self.lblInput.show() self.input.show() self.fileName = fileName self.pythonPath = pythonPath self.programParams = programParams self.preExec = preExec self.postExec = postExec self.__pre_execution() def __main_execution(self): """Execute the project.""" self.output.setCurrentCharFormat(self.output.plain_format) message = '' if self.__preScriptExecuted: self.__preScriptExecuted = False message = self.tr( "Pre Execution Script Successfully executed.\n\n") self.output.setPlainText(message + 'Running: %s (%s)\n\n' % (self.fileName, unicode(time.ctime()))) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) #runner.run_code_from_file(fileName) if not self.pythonPath: self.pythonPath = settings.PYTHON_PATH #change the working directory to the fileName dir file_directory = file_manager.get_folder(self.fileName) self._proc.setWorkingDirectory(file_directory) #force python to unbuffer stdin and stdout options = ['-u'] + settings.EXECUTION_OPTIONS.split() self.currentProcess = self._proc self._proc.start(self.pythonPath, options + [self.fileName] + \ [p.strip() for p in self.programParams.split(',') if p]) def __pre_execution(self): """Execute a script before executing the project.""" filePreExec = QFile(self.preExec) if filePreExec.exists() and \ bool(QFile.ExeUser & filePreExec.permissions()): ext = file_manager.get_file_extension(self.preExec) if not self.pythonPath: self.pythonPath = settings.PYTHON_PATH self.currentProcess = self._preExecScriptProc self.__preScriptExecuted = True if ext == 'py': self._preExecScriptProc.start(self.pythonPath, [self.preExec]) else: self._preExecScriptProc.start(self.preExec) else: self.__main_execution() def __post_execution(self): """Execute a script after executing the project.""" filePostExec = QFile(self.postExec) if filePostExec.exists() and \ bool(QFile.ExeUser & filePostExec.permissions()): ext = file_manager.get_file_extension(self.postExec) if not self.pythonPath: self.pythonPath = settings.PYTHON_PATH self.currentProcess = self._postExecScriptProc if ext == 'py': self._postExecScriptProc.start(self.pythonPath, [self.postExec]) else: self._postExecScriptProc.start(self.postExec) def __post_execution_message(self): """Print post execution message.""" self.output.textCursor().insertText('\n\n') format = QTextCharFormat() format.setAnchor(True) format.setForeground(Qt.green) self.output.textCursor().insertText( self.tr("Post Execution Script Successfully executed."), format) def kill_process(self): """Kill the running process.""" self._proc.kill()
class Goodbye(base.Goodbye): def showUrl(self, Url): self.procSettings = QProcess() command = "kfmclient openURL " + Url self.procSettings.start(command)
class ScriptRunner(QObject): def __init__(self, caller, parent=None, env=None, addEnv=None): QObject.__init__(self, parent) self._proc = None self._caller = caller self._decode = None if env is None: env = os.environ.copy() self._env = env if addEnv: self._env.update(addEnv) def stop(self, kill=False): if self._proc is None: return if kill: self._proc.kill() else: self._proc.terminate() def run(self, scriptFile, args=None, env=None, wd=None): if self._proc: return self._proc = QProcess(self) if wd: self._proc.setWorkingDirectory(wd) if not env is None: self._env.update(env) envList = dict2qlst(self._env) if args is None: args = [] script = quote(scriptFile) if not os.path.exists(script): script = find_script(script) if not script or not os.path.exists(script): raise PublishException("Script '%s' cannot be found" % script) self._caller.handleScriptOutput("%s %s" % (scriptFile, ' '.join(args))) self._proc.setEnvironment(envList) self._proc.setProcessChannelMode(QProcess.MergedChannels) QObject.connect(self._proc, QtCore.SIGNAL("readyReadStandardOutput()"), self.readScriptOutput) QObject.connect(self._proc, QtCore.SIGNAL("finished(int, " \ "QProcess::ExitStatus)"), self.scriptFinished) self._proc.start(script, args, QIODevice.ReadOnly) def scriptFinished(self, exitCode, exitStatus): if self._caller: self.readScriptOutput() self._caller.scriptFinished(exitCode, exitStatus == QProcess.Crashed) self._proc = None def readScriptOutput(self): if self._proc is None: return qba = self._proc.readAllStandardOutput() if self._caller and qba.length(): if not self._decode: lang, deflocale = locale.getdefaultlocale() self._decode = codecs.getdecoder(deflocale) data, datalen = self._decode(qba.data()) self._caller.handleScriptOutput(data)
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, row if len(folderQueue) > 0: row = self.Queue_TW.rowCount() else: row = 0 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: folderQueue.append(url) appendedList.append(url) # Create table row rowPosition = self.Queue_TW.rowCount() self.Queue_TW.insertRow(rowPosition) # Add project name to row self.NBR_createCheckBoxItemTableWidget( rowPosition, 0, os.path.splitext(os.path.basename(url))[0]) self.Queue_TW.resizeRowsToContents() self.Queue_TW.scrollToBottom() QtGui.QApplication.processEvents() # add write nodes and start end frame info to each row self.NBR_updateNodeInfo() # =========================== QProcess for getting and updating write nodes and Frame range information ============= # def NBR_updateNodeInfo(self): global appendedList # get All Write Node from .nk # QProcess for nuke if (len(appendedList)) > 0: self.nukeProcess = QProcess(self) self.nukeProcess.setProcessChannelMode(QProcess.MergedChannels) args = self.createCmdArg(str(appendedList[0])) self.nukeProcess.start(NUKE_EXE, args) # For debug: read output lines self.nukeProcess.readyRead.connect(self.NBR_debug) self.nukeProcess.finished.connect(self.NBR_updateNodeInfoDone) # self.nukeProcess.close() def NBR_updateNodeInfoDone(self): global row # Get the write nodes from text files (D:/Temp/nukeBatch) layout = QtGui.QVBoxLayout() layout.setAlignment(QtCore.Qt.AlignLeft) with open( r'D:/Temp/nukeBatch/' + os.path.basename(appendedList[0]) + ".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( row, 2 + bCount, int(str(line).strip())) bCount += 1 cellWidget = QtGui.QWidget() cellWidget.setLayout(layout) self.Queue_TW.setCellWidget(row, 1, cellWidget) self.Queue_TW.resizeRowsToContents() self.Queue_TW.scrollToBottom() QtGui.QApplication.processEvents() appendedList.pop(0) row += 1 self.NBR_updateNodeInfo() # ======================== QProcess for getting and updating write nodes and Frame range information END ============= # 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 ExternalSystemShell(ExternalShellBase): """External Shell widget: execute Python script in a separate process""" SHELL_CLASS = TerminalWidget def __init__(self, parent=None, wdir=None, path=[], light_background=True, menu_actions=None, show_buttons_inside=True, show_elapsed_time=True): ExternalShellBase.__init__(self, parent=parent, fname=None, wdir=wdir, history_filename='.history', light_background=light_background, menu_actions=menu_actions, show_buttons_inside=show_buttons_inside, show_elapsed_time=show_elapsed_time) # Additional python path list self.path = path # For compatibility with the other shells that can live in the external # console self.is_ipykernel = False self.connection_file = None def get_icon(self): return get_icon('cmdprompt.png') def create_process(self): self.shell.clear() self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.MergedChannels) # PYTHONPATH (in case we use Python in this terminal, e.g. py2exe) env = [unicode(_path) for _path in self.process.systemEnvironment()] add_pathlist_to_PYTHONPATH(env, self.path) self.process.setEnvironment(env) # Working directory if self.wdir is not None: self.process.setWorkingDirectory(self.wdir) # Shell arguments if os.name == 'nt': p_args = ['/Q'] else: p_args = ['-i'] if self.arguments: p_args.extend(shell_split(self.arguments)) self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.write_output) self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"), self.finished) self.connect(self.kill_button, SIGNAL("clicked()"), self.process.kill) if os.name == 'nt': self.process.start('cmd.exe', p_args) else: # Using bash: self.process.start('bash', p_args) self.send_to_process("""PS1="\u@\h:\w> "\n""") running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, _("Error"), _("Process failed to start")) else: self.shell.setFocus() self.emit(SIGNAL('started()')) return self.process #=============================================================================== # Input/Output #=============================================================================== def transcode(self, bytes): if os.name == 'nt': return encoding.transcode(str(bytes.data()), 'cp850') else: return ExternalShellBase.transcode(self, bytes) def send_to_process(self, text): if not isinstance(text, basestring): text = unicode(text) if text[:-1] in ["clear", "cls", "CLS"]: self.shell.clear() self.send_to_process(os.linesep) return if not text.endswith('\n'): text += '\n' if os.name == 'nt': self.process.write(text.encode('cp850')) else: self.process.write(locale_codec.fromUnicode(text)) self.process.waitForBytesWritten(-1) def keyboard_interrupt(self): # This does not work on Windows: # (unfortunately there is no easy way to send a Ctrl+C to cmd.exe) self.send_ctrl_to_process('c')
class GimConverter: def __init__(self, parent=None): self.parent = parent self.process = QProcess() self.temp_dir = tempfile.mkdtemp(prefix="sdse-") def __del__(self): import shutil shutil.rmtree(self.temp_dir) def quantize_png(self, png_file, quant_type=QuantizeType.auto): if quant_type == QuantizeType.none: return png_file basename = os.path.basename(png_file) temp_png = os.path.join(self.temp_dir, basename) shutil.copy(png_file, temp_png) options = ["--force", "--ext", ".png", "--speed", "1"] if quant_type == QuantizeType.auto: options.extend(["--quality", "100"]) elif quant_type == QuantizeType.index4: options.append("16") elif quant_type == QuantizeType.index8: options.append("256") options.append(temp_png) self.process.start("tools/pngquant", options) self.process.waitForFinished(-1) return temp_png def png_to_gim(self, png_file, gim_file=None, quant_type=QuantizeType.auto): # So there's no confusion. png_file = os.path.abspath(png_file) if gim_file == None: gim_file = os.path.splitext(png_file)[0] + ".gim" png_file = self.quantize_png(png_file, quant_type) data = ConstBitStream(filename=png_file) data.bytepos = 0x18 options = ["-jar", "tools/gimexport.jar", png_file, gim_file, "3"] depth = data.read("int:8") color_type = data.read("int:8") if color_type == 3: # Indexed options.append("true") else: options.append("false") self.process.start("java", options) self.process.waitForFinished(-1) def gim_to_png(self, gim_file, png_file=None, quant_type=QuantizeType.none): # So there's no confusion. gim_file = os.path.abspath(gim_file) if png_file: png_file = os.path.abspath(png_file) # Convert our GIM. self.process.start("tools/gim2png", ["-9", gim_file]) self.process.waitForFinished(-1) # Now get the output location. output = QString(self.process.readAllStandardOutput()) output = output.split("\n", QString.SkipEmptyParts) saved_file = None for line in output: line = common.qt_to_unicode(line) match = OUTPUT_RE.match(line) if match == None: continue saved_file = match.group(1) break # Make sure we actually generated a file. if not saved_file: _LOGGER.error("Failed to convert %s" % gim_file) return quant = self.quantize_png(saved_file, quant_type) if not quant == saved_file and not quant == png_file: os.remove(saved_file) # And move it to the requested location, if one exists. if png_file: shutil.move(quant, png_file) else: shutil.move(quant, saved_file)
class ExternalSystemShell(ExternalShellBase): """External Shell widget: execute Python script in a separate process""" SHELL_CLASS = TerminalWidget def __init__(self, parent=None, wdir=None): ExternalShellBase.__init__(self, parent, wdir, history_filename='.history_ec') def get_icon(self): return get_icon('cmdprompt.png') def create_process(self): self.shell.clear() self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.MergedChannels) # Working directory if self.wdir is not None: self.process.setWorkingDirectory(self.wdir) # Shell arguments if os.name == 'nt': p_args = ['/Q'] else: p_args = ['-i'] if self.arguments: p_args.extend( self.arguments.split(' ') ) self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.write_output) self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"), self.finished) self.connect(self.kill_button, SIGNAL("clicked()"), self.process.kill) if os.name == 'nt': self.process.start('cmd.exe', p_args) else: # Using bash: self.process.start('bash', p_args) self.send_to_process("""PS1="\u@\h:\w> "\n""") running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, self.tr("Error"), self.tr("Process failed to start")) else: self.shell.setFocus() self.emit(SIGNAL('started()')) return self.process #=============================================================================== # Input/Output #=============================================================================== def transcode(self, bytes): if os.name == 'nt': return encoding.transcode(str(bytes.data()), 'cp850') else: return ExternalShellBase.transcode(self, bytes) def send_to_process(self, qstr): if not isinstance(qstr, QString): qstr = QString(qstr) if qstr[:-1] in ["clear", "cls", "CLS"]: self.shell.clear() self.send_to_process(QString(os.linesep)) return if not qstr.endsWith('\n'): qstr.append('\n') if os.name == 'nt': self.process.write(unicode(qstr).encode('cp850')) else: self.process.write(qstr.toLocal8Bit()) self.process.waitForBytesWritten(-1) def keyboard_interrupt(self): # This does not work on Windows: # (unfortunately there is no easy way to send a Ctrl+C to cmd.exe) self.send_ctrl_to_process('c') # # The following code will soon be removed: # # (last attempt to send a Ctrl+C on Windows) # if os.name == 'nt': # pid = int(self.process.pid()) # import ctypes, win32api, win32con # class _PROCESS_INFORMATION(ctypes.Structure): # _fields_ = [("hProcess", ctypes.c_int), # ("hThread", ctypes.c_int), # ("dwProcessID", ctypes.c_int), # ("dwThreadID", ctypes.c_int)] # x = ctypes.cast( ctypes.c_void_p(pid), # ctypes.POINTER(_PROCESS_INFORMATION) ) # win32api.GenerateConsoleCtrlEvent(win32con.CTRL_C_EVENT, # x.dwProcessID) # else: # self.send_ctrl_to_process('c')
class PyLint(Plugin, QObject): """ PyLint Plugin """ capabilities = ['toolbarHook'] __version__ = '0.5' thread = None def do_toolbarHook(self, widget): """ Hook to install the pylint toolbar button""" widget.addAction('PyLint', self.do_pylint) @pyqtSlot() def do_pylint(self): """ Launch the lint process and create the result window """ print 'do_pylint' self.pylint_pross = QProcess() self.pylint_pross.setProcessChannelMode(QProcess.MergedChannels) self.pylint_pross.setWorkingDirectory( \ os.path.dirname(str(self.parent.editor.filename))) self.pylint_pross.setReadChannel(QProcess.StandardOutput) self.connect(self.pylint_pross, \ SIGNAL('finished(int)'), \ self.finished) self.connect(self.pylint_pross, \ SIGNAL('readyReadStandardOutput()'), \ self.handle_stdout) self.connect(self.pylint_pross, \ SIGNAL('readyReadStandardError()'), \ self.handle_stderr) if (self.pylint_pross.start("pylint", \ [self.parent.editor.filename,])): print 'Cannot start process' self.win = ResultWin() self.win.setWindowTitle("PyLint Results :" \ + os.path.basename(str(self.parent.editor.filename))) self.win.show() if isMAEMO: self.win.setAttribute(Qt.WA_Maemo5ShowProgressIndicator, True) self.win.connect(self.win.list_view, \ SIGNAL('doubleClicked(const QModelIndex&)'), \ self.goto_line) self.pylint_pross.waitForStarted() def finished(self, _): """ Call back called when lint end """ if isMAEMO: self.win.setAttribute(Qt.WA_Maemo5ShowProgressIndicator, False) def handle_stdout(self): """ Private slot to handle the readyReadStdout signal of the pylint process. """ result_list = [] #regex = QRegExp('(\w)\S*:\S*(\d*):.*: (.*)') regex = QRegExp('(\w)\s*:\s*(\d*):(.*)') regex_score = \ QRegExp('.*at.(\d.\d*)/10.*') while self.pylint_pross and self.pylint_pross.canReadLine(): result = unicode(self.pylint_pross.readLine()) if result != None: pos = 0 while True: pos = regex.indexIn(result, pos) if pos < 0: if regex_score.indexIn(result, 0) >= 0: self.win.setWindowTitle( \ "PyLint Results :" \ + str(regex_score.cap(1)) \ + ':' + os.path.basename(str(self.parent.editor.filename))) break result_list.append( (regex.cap(1), regex.cap(2), regex.cap(3))) #print 'Append : ',(regex.cap(1), regex.cap(2), regex.cap(3)) pos = pos + regex.matchedLength() if len(result_list) > 0: self.win.append_results(result_list) def goto_line(self, index): """ Callback called when a lint result is double clicked """ line = int(self.win.list_model.items[index.row()][1]) self.parent.do_gotoLine(line) def handle_stderr(self): """ Private slot to handle the readyReadStderr signal of the pylint process. Currently not managed """ print 'error stderr'
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 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 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 occurred, 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 ExternalPythonShell(ExternalShellBase): """External Shell widget: execute Python script in a separate process""" SHELL_CLASS = ExtPyQsciShell def __init__(self, parent=None, fname=None, wdir=None, commands=[], interact=False, debug=False, path=[]): ExternalShellBase.__init__(self, parent, wdir, history_filename='.history_ec.py') self.shell.set_externalshell(self) self.toggle_globals_explorer(False) self.interact_check.setChecked(interact) self.debug_check.setChecked(debug) self.monitor_socket = None self.interpreter = fname is None self.fname = startup.__file__ if fname is None else fname if self.interpreter: self.interact_check.hide() self.debug_check.hide() self.terminate_button.hide() self.commands = ["import sys", "sys.path.insert(0, '')"] + commands # Additional python path list self.path = path def get_toolbar_buttons(self): ExternalShellBase.get_toolbar_buttons(self) self.globalsexplorer_button = create_toolbutton( self, get_icon('dictedit.png'), self.tr("Variables"), tip=self.tr("Show/hide global variables explorer"), toggled=self.toggle_globals_explorer) self.terminate_button = create_toolbutton( self, get_icon('terminate.png'), self.tr("Terminate"), tip=self.tr("Attempts to terminate the process.\n" "The process may not exit as a result of clicking " "this button\n(it is given the chance to prompt " "the user for any unsaved files, etc).")) self.interact_check = QCheckBox(self.tr("Interact"), self) self.debug_check = QCheckBox(self.tr("Debug"), self) return [ self.interact_check, self.debug_check, self.globalsexplorer_button, self.run_button, self.terminate_button, self.kill_button ] def get_shell_widget(self): # Globals explorer self.globalsexplorer = GlobalsExplorer(self) self.connect(self.globalsexplorer, SIGNAL('collapse()'), lambda: self.toggle_globals_explorer(False)) # Shell splitter self.splitter = splitter = QSplitter(Qt.Vertical, self) self.connect(self.splitter, SIGNAL('splitterMoved(int, int)'), self.splitter_moved) splitter.addWidget(self.shell) splitter.setCollapsible(0, False) splitter.addWidget(self.globalsexplorer) splitter.setStretchFactor(0, 2) splitter.setStretchFactor(1, 1) return splitter def get_icon(self): return get_icon('python.png') def set_buttons_runnning_state(self, state): ExternalShellBase.set_buttons_runnning_state(self, state) self.interact_check.setEnabled(not state) self.debug_check.setEnabled(not state) self.terminate_button.setEnabled(state) if not state: self.toggle_globals_explorer(False) self.globalsexplorer_button.setEnabled(state) def create_process(self): self.shell.clear() self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.MergedChannels) self.connect(self.shell, SIGNAL("wait_for_ready_read()"), lambda: self.process.waitForReadyRead(250)) # Working directory if self.wdir is not None: self.process.setWorkingDirectory(self.wdir) #-------------------------Python specific------------------------------- # Python arguments p_args = ['-u'] if self.interact_check.isChecked(): p_args.append('-i') if self.debug_check.isChecked(): p_args.extend(['-m', 'pdb']) p_args.append(self.fname) env = self.process.systemEnvironment() # Monitor env.append('SHELL_ID=%s' % id(self)) from spyderlib.widgets.externalshell.monitor import start_server server, port = start_server() self.notification_thread = server.register(str(id(self)), self) self.connect(self.notification_thread, SIGNAL('refresh()'), self.globalsexplorer.refresh_table) env.append('SPYDER_PORT=%d' % port) # Python init commands (interpreter only) if self.commands and self.interpreter: env.append('PYTHONINITCOMMANDS=%s' % ';'.join(self.commands)) self.process.setEnvironment(env) pathlist = [] # Fix encoding with custom "sitecustomize.py" scpath = osp.dirname(osp.abspath(__file__)) pathlist.append(scpath) # Adding Spyder path pathlist += self.path # Adding path list to PYTHONPATH environment variable pypath = "PYTHONPATH" pathstr = os.pathsep.join(pathlist) if os.environ.get(pypath) is not None: env.replaceInStrings(pypath + '=', pypath + '=' + pathstr + os.pathsep, Qt.CaseSensitive) else: env.append(pypath + '=' + pathstr) self.process.setEnvironment(env) #-------------------------Python specific------------------------------- if self.arguments: p_args.extend(self.arguments.split(' ')) self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.write_output) self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"), self.finished) self.connect(self.terminate_button, SIGNAL("clicked()"), self.process.terminate) self.connect(self.kill_button, SIGNAL("clicked()"), self.process.kill) #-------------------------Python specific------------------------------- self.process.start(sys.executable, p_args) #-------------------------Python specific------------------------------- running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, self.tr("Error"), self.tr("Process failed to start")) else: self.shell.setFocus() self.emit(SIGNAL('started()')) return self.process #=============================================================================== # Input/Output #=============================================================================== def _write_error(self, text, findstr): pos = text.find(findstr) if pos != -1: self.shell.write(text[:pos]) if text.endswith(">>> "): self.shell.write_error(text[pos:-5]) self.shell.write(text[-5:], flush=True) else: self.shell.write_error(text[pos:]) return True return False def write_output(self): text = self.get_stdout() if not self._write_error(text, 'Traceback (most recent call last):') \ and not self._write_error(text, 'File "<stdin>", line 1'): self.shell.write(text) QApplication.processEvents() def send_to_process(self, qstr): if not isinstance(qstr, QString): qstr = QString(qstr) if not qstr.endsWith('\n'): qstr.append('\n') self.process.write(qstr.toLocal8Bit()) self.process.waitForBytesWritten(-1) def keyboard_interrupt(self): communicate(self.monitor_socket, "thread.interrupt_main()") #=============================================================================== # Globals explorer #=============================================================================== def toggle_globals_explorer(self, state): self.splitter.setSizes([1, 1 if state else 0]) self.globalsexplorer_button.setChecked(state) if state: self.globalsexplorer.refresh_table() def splitter_moved(self, pos, index): self.globalsexplorer_button.setChecked(self.splitter.sizes()[1])
class PluginProcessBase(QObject): proc_list = [] def __init__(self, wdir): QObject.__init__(self) PluginProcess.proc_list.append(self) self.is_rebuild = False self.is_query_fl = False self.sig = QuerySignal() self.proc = QProcess() self.proc.finished.connect(self._finished_cb) self.proc.error.connect(self._error_cb) self.proc.setWorkingDirectory(wdir) self.wdir = wdir def _cleanup(self): PluginProcess.proc_list.remove(self) if self.err_str != '': s = '<b>' + self.p_cmd + '</b><p>' + '<p>'.join( self.err_str.splitlines()) QMessageBox.warning(None, "Seascope", s, QMessageBox.Ok) if self.res != '': s = '<b>' + self.p_cmd + '</b><p>Summary<p>' + self.res QMessageBox.information(None, "Seascope", s, QMessageBox.Ok) def _error_cb(self, err): err_dict = { QProcess.FailedToStart: 'FailedToStart', QProcess.Crashed: 'Crashed', QProcess.Timedout: 'The last waitFor...() function timed out', QProcess.WriteError: 'An error occurred when attempting to write to the process', QProcess.ReadError: 'An error occurred when attempting to read from the process', QProcess.UnknownError: 'An unknown error occurred', } self.err_str = '<b>' + self.p_cmd + '</b><p>' + err_dict[err] self._cleanup() def _finished_cb(self, ret): res = str(self.proc.readAllStandardOutput()) self.err_str = str(self.proc.readAllStandardError()) #print 'output', res #print 'cmd:', self.p_cmd if self.is_rebuild: self.res = res self.sig.sig_rebuild.emit() elif self.is_query_fl: self.res = '' res = self.parse_query_fl(res) self.sig.sig_query_fl.emit(res) else: self.res = '' self.sig.sig_result_dbg.emit(self.p_cmd, res, self.err_str) try: res = self.parse_result(res, self.sig) except Exception as e: print e res = [[ '', '', '', 'error while parsing output of: ' + self.p_cmd ]] if res != None: self.sig.emit_result(res) self._cleanup() def run_query_process(self, pargs, sym, rquery=None): self.sig.sym = sym self.sig.rquery = rquery self.p_cmd = ' '.join(pargs) if os.getenv('SEASCOPE_DEBUG'): print self.p_cmd self.proc.start(pargs[0], pargs[1:]) if self.proc.waitForStarted() == False: return None self.proc.closeWriteChannel() return [self.sig.sig_result, self.sig.sig_result_dbg] def run_rebuild_process(self, pargs): self.is_rebuild = True self.p_cmd = ' '.join(pargs) self.proc.start(pargs[0], pargs[1:]) if self.proc.waitForStarted() == False: return None #print 'cmd:', pargs self.sig.sig_rebuild.connect(CtagsCache.flush) return self.sig.sig_rebuild def run_query_fl(self, pargs): self.is_query_fl = True self.p_cmd = ' '.join(pargs) self.proc.start(pargs[0], pargs[1:]) if self.proc.waitForStarted() == False: return None return self.sig.sig_query_fl def parse_query_fl(self, text): fl = [] for f in re.split('\r?\n', text.strip()): if f == '': continue fl.append(os.path.join(self.wdir, f)) return fl
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.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></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...") 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 = ["-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 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): 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] 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() 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 CFDSTUDYGUI_QProcessDialog(QDialog, Ui_CFDSTUDYGUI_QProcessDialog): """ Advanced dialog. """ def __init__(self, parent, title, cmd_list, obj_directory="", start_directory=""): """ Constructor """ QDialog.__init__(self, parent) Ui_CFDSTUDYGUI_QProcessDialog.__init__(self) self.setupUi(self) self.setWindowTitle(title) self.pushButton.setEnabled(False) if start_directory != None and start_directory != "": os.chdir(start_directory) self.objBr = None if obj_directory != None and obj_directory != "": self.objBr = obj_directory self.proc = QProcess() #env = QProcessEnvironment().systemEnvironment() #self.proc.setProcessEnvironment(env) self.connect(self.proc, SIGNAL('readyReadStandardOutput()'), self.__readFromStdout) self.connect(self.proc, SIGNAL('readyReadStandardError()'), self.__readFromStderr) self.procErrorFlag = False self.cmd_list = cmd_list self.cmd = self.cmd_list.pop(0) cursor = QCursor(Qt.BusyCursor) QApplication.setOverrideCursor(cursor) self.__process() def __process(self): if self.proc.exitStatus() == QProcess.NormalExit and not self.procErrorFlag: self.proc.start(self.cmd) if self.cmd_list: self.cmd = self.cmd_list.pop(0) self.connect(self.proc, SIGNAL('finished(int, QProcess::ExitStatus)'), self.__process) else: self.connect(self.proc, SIGNAL('finished(int, QProcess::ExitStatus)'), self.__finished) def __readFromStdout(self): """ Private slot to handle the readyReadStandardOutput signal of the process. """ if self.proc is None: return self.proc.setReadChannel(QProcess.StandardOutput) while self.proc and self.proc.canReadLine(): ba = self.proc.readLine() if ba.isNull(): return str = QString() s = QString(str.fromUtf8(ba.data()))[:-1] self.logText.append(s) def __readFromStderr(self): """ Private slot to handle the readyReadStandardError signal of the process. """ if self.proc is None: return self.proc.setReadChannel(QProcess.StandardError) while self.proc and self.proc.canReadLine(): ba = self.proc.readLine() if ba.isNull(): return str = QString() s = QString(str.fromUtf8(ba.data()))[:-1] self.logText.append(s.prepend('<font color="red">').append('</font>')) self.procErrorFlag = True def __finished(self): if self.objBr: CFDSTUDYGUI_DataModel.UpdateSubTree(self.objBr) QApplication.restoreOverrideCursor() self.pushButton.setEnabled(True) def event(self, e): if e.type() == 9999: return QDialog.event(self, QCloseEvent()) if e.type() == 9998: return QDialog.event(self, QCloseEvent()) if e.type() == QEvent.Close: e.ignore() return True return QDialog.event(self, e)
class ExternalPythonShell(ExternalShellBase): """External Shell widget: execute Python script in a separate process""" SHELL_CLASS = ExtPythonShellWidget def __init__(self, parent=None, fname=None, wdir=None, interact=False, debug=False, path=[], python_args='', ipykernel=False, arguments='', stand_alone=None, umd_enabled=True, umd_namelist=[], umd_verbose=True, pythonstartup=None, pythonexecutable=None, monitor_enabled=True, mpl_patch_enabled=True, mpl_backend=None, ets_backend='qt4', qt_api=None, pyqt_api=0, install_qt_inputhook=True, ignore_sip_setapi_errors=False, merge_output_channels=False, colorize_sys_stderr=False, autorefresh_timeout=3000, autorefresh_state=True, light_background=True, menu_actions=None, show_buttons_inside=True, show_elapsed_time=True): assert qt_api in (None, 'pyqt', 'pyside') self.namespacebrowser = None # namespace browser widget! self.dialog_manager = DialogManager() self.stand_alone = stand_alone # stand alone settings (None: plugin) self.pythonstartup = pythonstartup self.pythonexecutable = pythonexecutable self.monitor_enabled = monitor_enabled self.mpl_patch_enabled = mpl_patch_enabled self.mpl_backend = mpl_backend self.ets_backend = ets_backend self.qt_api = qt_api self.pyqt_api = pyqt_api self.install_qt_inputhook = install_qt_inputhook self.ignore_sip_setapi_errors = ignore_sip_setapi_errors self.merge_output_channels = merge_output_channels self.colorize_sys_stderr = colorize_sys_stderr self.umd_enabled = umd_enabled self.umd_namelist = umd_namelist self.umd_verbose = umd_verbose self.autorefresh_timeout = autorefresh_timeout self.autorefresh_state = autorefresh_state self.namespacebrowser_button = None self.cwd_button = None self.env_button = None self.syspath_button = None self.terminate_button = None self.notification_thread = None ExternalShellBase.__init__(self, parent=parent, fname=fname, wdir=wdir, history_filename='.history.py', light_background=light_background, menu_actions=menu_actions, show_buttons_inside=show_buttons_inside, show_elapsed_time=show_elapsed_time) if self.pythonexecutable is None: self.pythonexecutable = get_python_executable() self.python_args = None if python_args: assert isinstance(python_args, basestring) self.python_args = python_args assert isinstance(arguments, basestring) self.arguments = arguments self.connection_file = None self.is_ipykernel = ipykernel if self.is_ipykernel: interact = False # Running our custom startup script for IPython kernels: # (see spyderlib/widgets/externalshell/start_ipython_kernel.py) self.fname = get_module_source_path('SMlib.widgets.externalshell', 'start_ipython_kernel.py') self.shell.set_externalshell(self) self.toggle_globals_explorer(False) self.interact_action.setChecked(interact) self.debug_action.setChecked(debug) self.introspection_socket = None self.is_interpreter = fname is None if self.is_interpreter: self.terminate_button.hide() # Additional python path list self.path = path self.shell.path = path def set_introspection_socket(self, introspection_socket): self.introspection_socket = introspection_socket if self.namespacebrowser is not None: settings = self.namespacebrowser.get_view_settings() communicate(introspection_socket, 'set_remote_view_settings()', settings=[settings]) def set_autorefresh_timeout(self, interval): if self.introspection_socket is not None: try: communicate(self.introspection_socket, "set_monitor_timeout(%d)" % interval) except socket.error: pass def closeEvent(self, event): self.quit_monitor() ExternalShellBase.closeEvent(self, event) def get_toolbar_buttons(self): ExternalShellBase.get_toolbar_buttons(self) if self.namespacebrowser_button is None \ and self.stand_alone is not None: self.namespacebrowser_button = create_toolbutton( self, text=_("Variables"), icon=get_icon('dictedit.png'), tip=_("Show/hide global variables explorer"), toggled=self.toggle_globals_explorer, text_beside_icon=True) if self.terminate_button is None: self.terminate_button = create_toolbutton( self, text=_("Terminate"), icon=get_icon('terminate.png'), tip=_("""Attempts to terminate the process. The process may not exit as a result of clicking this button (it is given the chance to prompt the user for any unsaved files, etc).""")) buttons = [] if self.namespacebrowser_button is not None: buttons.append(self.namespacebrowser_button) buttons += [ self.run_button, self.options_button, self.terminate_button, self.kill_button ] return buttons def get_options_menu(self): ExternalShellBase.get_options_menu(self) self.interact_action = create_action(self, _("Interact")) self.interact_action.setCheckable(True) self.debug_action = create_action(self, _("Debug")) self.debug_action.setCheckable(True) self.args_action = create_action(self, _("Arguments..."), triggered=self.get_arguments) run_settings_menu = QMenu(_("Run settings"), self) add_actions( run_settings_menu, (self.interact_action, self.debug_action, self.args_action)) self.cwd_button = create_action( self, _("Working directory"), icon=get_std_icon('DirOpenIcon'), tip=_("Set current working directory"), triggered=self.set_current_working_directory) self.env_button = create_action(self, _("Environment variables"), icon=get_icon('environ.png'), triggered=self.show_env) self.syspath_button = create_action(self, _("Show sys.path contents"), icon=get_icon('syspath.png'), triggered=self.show_syspath) actions = [ run_settings_menu, self.show_time_action, None, self.cwd_button, self.env_button, self.syspath_button ] if self.menu_actions is not None: actions += [None] + self.menu_actions return actions def is_interpreter(self): """Return True if shellwidget is a Python interpreter""" return self.is_interpreter def get_shell_widget(self): if self.stand_alone is None: return self.shell else: self.namespacebrowser = NamespaceBrowser(self) settings = self.stand_alone self.namespacebrowser.set_shellwidget(self) self.namespacebrowser.setup(**settings) self.connect(self.namespacebrowser, SIGNAL('collapse()'), lambda: self.toggle_globals_explorer(False)) # Shell splitter self.splitter = splitter = QSplitter(Qt.Vertical, self) self.connect(self.splitter, SIGNAL('splitterMoved(int, int)'), self.splitter_moved) splitter.addWidget(self.shell) splitter.setCollapsible(0, False) splitter.addWidget(self.namespacebrowser) splitter.setStretchFactor(0, 1) splitter.setStretchFactor(1, 0) splitter.setHandleWidth(5) splitter.setSizes([2, 1]) return splitter def get_icon(self): return get_icon('python.png') def set_buttons_runnning_state(self, state): ExternalShellBase.set_buttons_runnning_state(self, state) self.interact_action.setEnabled(not state and not self.is_interpreter) self.debug_action.setEnabled(not state and not self.is_interpreter) self.args_action.setEnabled(not state and not self.is_interpreter) if state: if self.arguments: argstr = _("Arguments: %s") % self.arguments else: argstr = _("No argument") else: argstr = _("Arguments...") self.args_action.setText(argstr) self.terminate_button.setVisible(not self.is_interpreter and state) if not state: self.toggle_globals_explorer(False) for btn in (self.cwd_button, self.env_button, self.syspath_button): btn.setEnabled(state and self.monitor_enabled) if self.namespacebrowser_button is not None: self.namespacebrowser_button.setEnabled(state) def set_namespacebrowser(self, namespacebrowser): """ Set namespace browser *widget* Note: this method is not used in stand alone mode """ self.namespacebrowser = namespacebrowser self.configure_namespacebrowser() def configure_namespacebrowser(self): """Connect the namespace browser to the notification thread""" if self.notification_thread is not None: self.connect(self.notification_thread, SIGNAL('refresh_namespace_browser()'), self.namespacebrowser.refresh_table) signal = self.notification_thread.sig_process_remote_view signal.connect(self.namespacebrowser.process_remote_view) def create_process(self): self.shell.clear() self.process = QProcess(self) if self.merge_output_channels: self.process.setProcessChannelMode(QProcess.MergedChannels) else: self.process.setProcessChannelMode(QProcess.SeparateChannels) self.connect(self.shell, SIGNAL("wait_for_ready_read()"), lambda: self.process.waitForReadyRead(250)) # Working directory if self.wdir is not None: self.process.setWorkingDirectory(self.wdir) #-------------------------Python specific------------------------------- # Python arguments p_args = ['-u'] if DEBUG >= 3: p_args += ['-v'] p_args += get_python_args(self.fname, self.python_args, self.interact_action.isChecked(), self.debug_action.isChecked(), self.arguments) env = [unicode(_path) for _path in self.process.systemEnvironment()] if self.pythonstartup: env.append('PYTHONSTARTUP=%s' % self.pythonstartup) # Monitor if self.monitor_enabled: env.append('SPYDER_SHELL_ID=%s' % id(self)) env.append('SPYDER_AR_TIMEOUT=%d' % self.autorefresh_timeout) env.append('SPYDER_AR_STATE=%r' % self.autorefresh_state) from SMlib.widgets.externalshell import introspection introspection_server = introspection.start_introspection_server() introspection_server.register(self) notification_server = introspection.start_notification_server() self.notification_thread = notification_server.register(self) self.connect( self.notification_thread, SIGNAL('pdb(QString,int)'), lambda fname, lineno: self.emit( SIGNAL('pdb(QString,int)'), fname, lineno)) self.connect( self.notification_thread, SIGNAL('new_ipython_kernel(QString)'), lambda args: self.emit( SIGNAL('create_ipython_client(QString)'), args)) self.connect( self.notification_thread, SIGNAL('open_file(QString,int)'), lambda fname, lineno: self.emit( SIGNAL('open_file(QString,int)'), fname, lineno)) if self.namespacebrowser is not None: self.configure_namespacebrowser() env.append('SPYDER_I_PORT=%d' % introspection_server.port) env.append('SPYDER_N_PORT=%d' % notification_server.port) # External modules options env.append('ETS_TOOLKIT=%s' % self.ets_backend) env.append('MATPLOTLIB_PATCH=%r' % self.mpl_patch_enabled) if self.mpl_backend: env.append('MATPLOTLIB_BACKEND=%s' % self.mpl_backend) if self.qt_api: env.append('QT_API=%s' % self.qt_api) env.append('INSTALL_QT_INPUTHOOK=%s' % self.install_qt_inputhook) env.append('COLORIZE_SYS_STDERR=%s' % self.colorize_sys_stderr) # # Socket-based alternative (see input hook in sitecustomize.py): # if self.install_qt_inputhook: # from PyQt4.QtNetwork import QLocalServer # self.local_server = QLocalServer() # self.local_server.listen(str(id(self))) if self.pyqt_api: env.append('PYQT_API=%d' % self.pyqt_api) env.append('IGNORE_SIP_SETAPI_ERRORS=%s' % self.ignore_sip_setapi_errors) # User Module Deleter if self.is_interpreter: env.append('UMD_ENABLED=%r' % self.umd_enabled) env.append('UMD_NAMELIST=%s' % ','.join(self.umd_namelist)) env.append('UMD_VERBOSE=%r' % self.umd_verbose) # IPython kernel env.append('IPYTHON_KERNEL=%r' % self.is_ipykernel) pathlist = [] # Fix encoding with custom "sitecustomize.py" scpath = osp.dirname(osp.abspath(__file__)) pathlist.append(scpath) # Adding Spyder path pathlist += self.path # Adding path list to PYTHONPATH environment variable add_pathlist_to_PYTHONPATH(env, pathlist) #-------------------------Python specific------------------------------- self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.write_output) self.connect(self.process, SIGNAL("readyReadStandardError()"), self.write_error) self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"), self.finished) self.connect(self, SIGNAL('finished()'), self.dialog_manager.close_all) self.connect(self.terminate_button, SIGNAL("clicked()"), self.process.terminate) self.connect(self.kill_button, SIGNAL("clicked()"), self.process.kill) #-------------------------Python specific------------------------------- # Fixes for our Mac app: # 1. PYTHONPATH and PYTHONHOME are set while bootstrapping the app, # but their values are messing sys.path for external interpreters # (e.g. EPD) so we need to remove them from the environment. # 2. Add this file's dir to PYTHONPATH. This will make every external # interpreter to use our sitecustomize script. # 3. Remove PYTHONOPTIMIZE from env so that we can have assert # statements working with our interpreters (See Issue 1281) if sys.platform == 'darwin' and 'Spyder.app' in __file__: env.append('SPYDER_INTERPRETER=%s' % self.pythonexecutable) if 'Spyder.app' not in self.pythonexecutable: env = [p for p in env if not (p.startswith('PYTHONPATH') or \ p.startswith('PYTHONHOME'))] # 1. env.append('PYTHONPATH=%s' % osp.dirname(__file__)) # 2. env = [p for p in env if not p.startswith('PYTHONOPTIMIZE')] # 3. self.process.setEnvironment(env) self.process.start(self.pythonexecutable, p_args) #-------------------------Python specific------------------------------- running = self.process.waitForStarted(3000) self.set_running_state(running) if not running: QMessageBox.critical( self, _("Error"), _("A Python or IPython Console failed to start!")) else: self.shell.setFocus() self.emit(SIGNAL('started()')) return self.process def finished(self, exit_code, exit_status): """Reimplement ExternalShellBase method""" ExternalShellBase.finished(self, exit_code, exit_status) self.introspection_socket = None #=============================================================================== # Input/Output #=============================================================================== def write_error(self): if os.name == 'nt': #---This is apparently necessary only on Windows (not sure though): # emptying standard output buffer before writing error output self.process.setReadChannel(QProcess.StandardOutput) if self.process.waitForReadyRead(1): self.write_output() self.shell.write_error(self.get_stderr()) QApplication.processEvents() def send_to_process(self, text): if not self.is_running(): return if not isinstance(text, basestring): text = unicode(text) if self.install_qt_inputhook and self.introspection_socket is not None: communicate(self.introspection_socket, "toggle_inputhook_flag(True)") # # Socket-based alternative (see input hook in sitecustomize.py): # while self.local_server.hasPendingConnections(): # self.local_server.nextPendingConnection().write('go!') if text.startswith(('%', '!')): text = 'evalsc(r"%s")\n' % text if not text.endswith('\n'): text += '\n' self.process.write(locale_codec.fromUnicode(text)) self.process.waitForBytesWritten(-1) # Eventually write prompt faster (when hitting Enter continuously) # -- necessary/working on Windows only: if os.name == 'nt': self.write_error() def keyboard_interrupt(self): if self.introspection_socket is not None: communicate(self.introspection_socket, "thread.interrupt_main()") def quit_monitor(self): if self.introspection_socket is not None: try: write_packet(self.introspection_socket, "thread.exit()") except socket.error: pass #=============================================================================== # Globals explorer #=============================================================================== def toggle_globals_explorer(self, state): if self.stand_alone is not None: self.splitter.setSizes([1, 1 if state else 0]) self.namespacebrowser_button.setChecked(state) if state and self.namespacebrowser is not None: self.namespacebrowser.refresh_table() def splitter_moved(self, pos, index): self.namespacebrowser_button.setChecked(self.splitter.sizes()[1]) #=============================================================================== # Misc. #=============================================================================== def set_current_working_directory(self): """Set current working directory""" cwd = self.shell.get_cwd() self.emit(SIGNAL('redirect_stdio(bool)'), False) directory = getexistingdirectory(self, _("Select directory"), cwd) if directory: self.shell.set_cwd(directory) self.emit(SIGNAL('redirect_stdio(bool)'), True) def show_env(self): """Show environment variables""" get_func = self.shell.get_env set_func = self.shell.set_env self.dialog_manager.show(RemoteEnvDialog(get_func, set_func)) def show_syspath(self): """Show sys.path contents""" editor = DictEditor() editor.setup(self.shell.get_syspath(), title="sys.path", readonly=True, width=600, icon='syspath.png') self.dialog_manager.show(editor)
class BatchFileSync(SyncProvider): def __init__(self, name, project, **kwargs): super(BatchFileSync, self).__init__(name, project) self.cmd = kwargs['cmd'] if self.project: self.rootfolder = os.path.abspath(self.project.folder) else: self.rootfolder = kwargs['rootfolder'] self.project = project self.closeproject = kwargs.get("close_project", False) self.process = QProcess() self.parser = kwargs.get("parser", None) self.parsermodule = None variables = kwargs.get("variables", {}) env = QProcessEnvironment.systemEnvironment() for varname, value in variables.iteritems(): env.insert(varname, str(value)) self.process.setProcessEnvironment(env) self.process.setWorkingDirectory( os.path.dirname(os.path.realpath(self.cmd))) self.process.finished.connect(self.complete) self.process.started.connect(self.syncStarted) self.process.readyReadStandardError.connect(self.error) self.process.readyReadStandardOutput.connect(self.readOutput) self._output = "" self.haserror = False def import_parser_module(self): import imp name = self.parser module = imp.find_module(name, [self.rootfolder]) module = imp.load_module(name, *module) self.parsermodule = module print self.parsermodule def start(self): if not self.parsermodule and self.parser: self.import_parser_module() self._output = "" self.haserror = False self.process.start(self.cmd, []) @property def output(self): return self._output @output.setter def output(self, value): self._output = value def error(self): self.haserror = True def complete(self, error, status): if error > 0 or self.haserror: stderr = self.process.readAllStandardError().data() self.syncError.emit(stderr) else: self.syncComplete.emit() self.syncFinished.emit() def readOutput(self): output = str(self.process.readAll()) ok = True if self.parsermodule: ok, output = self.parsermodule.sync_output(output) if not ok: self.haserror = True self.process.kill() self.syncError.emit(output) else: self.syncMessage.emit(output)
def run_process(fused_command, read_output=False): # print "run process", fused_command # qprocess = QProcess() # set_process_env(qprocess) # code_de_retour = qprocess.execute(fused_command) # print "code de retour", code_de_retour # logger.info("command: ") # logger.info(fused_command) # logger.info("code de retour" + str(code_de_retour)) # # # if not qprocess.waitForStarted(): # # # handle a failed command here # # print "qprocess.waitForStarted()" # # return # # # # if not qprocess.waitForReadyRead(): # # # handle a timeout or error here # # print "qprocess.waitForReadyRead()" # # return # # #if not qprocess.waitForFinished(1): # # # qprocess.kill() # # # qprocess.waitForFinished(1) # # # if read_output: # # # logger.info("Erreur") # code_d_erreur = qprocess.error() # dic_err = { 0:"QProcess::FailedToStart", 1:"QProcess::Crashed", 2:"QProcess::TimedOut", 3:"QProcess::WriteError", 4:"QProcess::ReadError", 5:"QProcess::UnknownError" } # logger.info("Code de retour: " + str(code_d_erreur)) # logger.info(dic_err[code_d_erreur]) # # print "get output" # output = str(qprocess.readAllStandardOutput()) # # print "output", output # print 'end output' process = QProcess() process.start(fused_command) if process.waitForStarted(): process.waitForFinished(-1) exit_code = process.exitCode() logger.info("Code de sortie : " + str(exit_code)) if exit_code < 0: code_d_erreur = process.error().data dic_err = { 0: "QProcess::FailedToStart", 1: "QProcess::Crashed", 2: "QProcess::TimedOut", 3: "QProcess::WriteError", 4: "QProcess::ReadError", 5: "QProcess::UnknownError" } logger.info("Code erreur : " + str(code_d_erreur)) logger.info(dic_err[code_d_erreur]) result = process.readAllStandardOutput() # print type(result), result error = process.readAllStandardError().data() # print repr(error) if not error == "\n": logger.info("error : " + "\'" + str(error) + "\'") logger.info("output : " + result.data() + "fin output") return result else: code_d_erreur = process.error() dic_err = { 0: "QProcess::FailedToStart", 1: "QProcess::Crashed", 2: "QProcess::TimedOut", 3: "QProcess::WriteError", 4: "QProcess::ReadError", 5: "QProcess::UnknownError" } logger.info("Code erreur : " + str(code_d_erreur)) logger.info(dic_err[code_d_erreur]) return None
class skkn_tool: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'skkn_tool_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg = skkn_toolDialog() # Declare instance attributes self.actions = [] self.menu = self.tr(u'&SKKN tool') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'skkn_tool') self.toolbar.setObjectName(u'skkn_tool') # data self.dlg.buttonConvert.setEnabled(False) self.dlg.lineData.clear() self.dlg.buttonData.clicked.connect(self.select_data) # database and schema self.dlg.dataBase.setEnabled(False) self.dlg.comboBox_2.currentIndexChanged.connect(self.db_changed) # conversation self.dlg.progressBarData.setMinimum(0) self.dlg.progressBarData.setMaximum(100) self._active = False self.dlg.buttonConvert.clicked.connect(self.convertData) # ukoncenie konverzie self.dlg.buttonKill.clicked.connect(self.stopConvert) self.dlg.buttonKill.setEnabled(False) # about message self.dlg.buttonAbout.clicked.connect(self.showError) self.dlg.buttonClear.clicked.connect(self.clear) # nieco ako Popen, nativne pre Qt self.process = QProcess(self.dlg) self.process.readyRead.connect(self.writeData) # vytvorenie schemy self.dlg.buttonCreate.clicked.connect(self.db_createSchema) # import dat do schemy self.dlg.buttonImport.clicked.connect(self.db_importToSchema) # vymazanie schemy self.dlg.buttonDelete.clicked.connect(self.db_deleteSchema) # test self.dlg.buttonTest.setEnabled(False) self.dlg.buttonTest.clicked.connect(self.testImport) # cancel self.dlg.buttonCancel.clicked.connect(self.closelt) # noinspection PyMethodMayBeStatic def tr(self, message): # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('skkn_tool', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/skkn_tool/icons/icon.png' self.add_action(icon_path, text=self.tr(u'SKKN tool'), callback=self.run, parent=self.iface.mainWindow()) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu(self.tr(u'&SKKN tool'), action) self.iface.removeToolBarIcon(action) # remove the toolbarself.dlg.dataBase.setEnabled(False) del self.toolbar def select_data(self): self.foldername = QFileDialog.getExistingDirectory( self.dlg, "Select data folder with SPI and VGI data", "/home") # nahradenie v pripade medzery # self.foldername = re.sub('\s+', '', self.foldername) # self.foldername = os.rename(self.foldername,self.foldername) self.dlg.lineData.setText(self.foldername) self.buttonConvertName() self.dlg.buttonConvert.setEnabled(True) self.dlg.progressBarData.setValue(0) self.clear() def convertData(self): #self.dlg.textEditData.setText(self.foldername) ## spustenie pomocou call a Popen # subprocess.call([os.path.join(self.plugin_dir,'kataster-import','kt-sql'),self.foldername]) # subprocess.Popen([os.path.join(self.plugin_dir,'kataster-import','kt-sql'),self.foldername],shell = True) self.clear() self.process.start( os.path.join(self.plugin_dir, 'kataster-import', 'kt-sql'), [self.foldername]) self.dlg.buttonConvert.setText('Converting ...') self.dlg.buttonKill.setEnabled(True) #funkcia na zapisovanie do GUI okna, vola funkciu insertText def writeData(self): text = str(self.process.readAll()) for line in text.splitlines(): if len(line) == 0: continue if not line.startswith('PROGRESS'): self.insertText(line + os.linesep) else: try: self.pvalue = int(line.split(':', 1)[1].strip()) except: return self.dlg.progressBarData.setValue(self.pvalue) if self.pvalue == 100: self.dlg.buttonConvert.setText( 'Conversation successfully completed') self.dlg.buttonConvert.setEnabled(False) self.dlg.buttonKill.setEnabled(False) self.dlg.dataBase.setEnabled(True) def insertText(self, text): cursor = self.dlg.textEditData.textCursor() cursor.movePosition(cursor.End) cursor.insertText(text) self.dlg.textEditData.ensureCursorVisible() def stopConvert(self): self.process.kill() self.clear() self.insertText('Conversation interrupted!') self.buttonConvertName() self.dlg.buttonKill.setEnabled(False) self.dlg.progressBarData.setValue(0) def buttonConvertName(self): self.dlg.buttonConvert.setText('Convert all data') def db_changed(self, index): self.dlg.comboBox_3.clear() self.clear() self.dlg.comboBox_3.addItems(self.db_getSchema(index)) # naplnenie comboboxu schemami def db_getSchema(self, index): schemas = [] self.dbconn = self.dbconnections[index] self.dbconn.connect() # zabraniene zobrazeniu schem public a topology for schema in self.dbconn.database().schemas(): if schema.name in ('public', 'topology'): continue schemas.append(schema.name) return schemas # vytvorenie novej schemy kataster def db_createSchema(self): self.clear() db = self.dlg.comboBox_2.currentText() schema = self.dlg.comboBox_3.currentText() if not schema == 'kataster': s = os.path.join(self.plugin_dir, 'kataster-import', 'kt-vytvor_db') + ' | ' + 'psql' + ' ' + db call(s, shell=True) self.insertText( 'New schema and related SQL statements have been created successfully.\nTo see schema in combo box refresh database connection!\n\n' ) else: self.insertText('Schema already exists.') def db_importToSchema(self): self.clear() db = self.dlg.comboBox_2.currentText() s = self.dlg.comboBox_3.currentText() gsql = os.path.join(self.foldername, 'sql', 'graficke_udaje.sql') psql = os.path.join(self.foldername, 'sql', 'popisne_udaje.sql') glog = os.path.join(self.plugin_dir, 'kataster-import', 'info_g.log') plog = os.path.join(self.plugin_dir, 'kataster-import', 'info_p.log') self.goptions = "PGOPTIONS='-c search_path=%s,public' psql %s -f %s 2>%s" % ( s, db, gsql, glog) call(self.goptions, shell=True) #self.insertText(os.path.join(self.plugin_dir,'kataster-import') + self.goptions) self.poptions = "PGOPTIONS='-c search_path=%s,public' psql %s -f %s 2>%s" % ( s, db, psql, plog) call(self.poptions, shell=True) self.writeLog() self.dlg.buttonTest.setEnabled(True) #funkcia na výpis log do GUI pri tvorbe schemy def writeLog(self): gfilelog = os.path.join(self.plugin_dir, 'kataster-import', 'info_g.log') gtext = open(gfilelog).read() pfilelog = os.path.join(self.plugin_dir, 'kataster-import', 'info_p.log') ptext = open(pfilelog).read() self.insertText('GRAPHICAL DATA LOG:\n**********************\n') self.logText(gfilelog, gtext) self.insertText('\nATTRIBUTIVE DATA LOG:\n************************\n') self.logText(pfilelog, ptext) # vymazanie LOG pre graficke a popisne data os.remove(gfilelog) os.remove(pfilelog) # testovanie prazdneho log suboru def logText(self, file, opfile): if (os.stat(file).st_size == 0 or os.stat(file).st_size == 1): self.insertText( 'Import has been successfully finished with no message.') else: for line in opfile.splitlines(): if len(line) == 0: continue else: self.insertText(line + os.linesep) def testImport(self): self.clear() db = self.dlg.comboBox_2.currentText() s = self.dlg.comboBox_3.currentText() tsql = os.path.join(self.plugin_dir, 'kataster-import', 'katastertools', 'sql', 'test-import.sql') tlog = os.path.join(self.plugin_dir, 'kataster-import', 'info_t.log') self.toptions = "PGOPTIONS='-c search_path=%s,public' psql %s -f %s > %s 2>&1" % ( s, db, tsql, tlog) call(self.toptions, shell=True) tfilelog = os.path.join(self.plugin_dir, 'kataster-import', 'info_t.log') ttext = open(tfilelog).read() self.insertText( 'TEST LOG related to imported data:\n**********************************\n' ) if (os.stat(tfilelog).st_size == 0 or os.stat(tfilelog).st_size == 1): self.insertText('Unfortunately, there are no results.') else: for line in ttext.splitlines(): if len(line) == 0: continue else: self.insertText(line + os.linesep) # vymazanie TEST LOG os.remove(tfilelog) # vymazanie schemy def db_deleteSchema(self): # vycistenie dialógu so správami self.clear() index = self.dlg.comboBox_3.currentIndex() schema = self.dlg.comboBox_3.currentText() db = self.dbconn.database() # vlozenie chybovej hlasky v pripade problemu try: db.sqlResultModel('DROP schema {0} CASCADE'.format(schema), db) except DbError as e: self.insertText(str(e)) # vymazanie z comboboxu self.dlg.comboBox_3.removeItem(index) def showError(self): QMessageBox.about( None, "About SKKN Plugin", "This tool helps users to use Slovak land \ registry data (cadastral data) in exchange formats created by The Geodesy, Cartography and \ Cadastre Authority of Slovak republic, in QGIS. \nIt is only usefull and dedicated for processing \ in Slovak republic for people having access to Cadastre data. \nThere is no reason to use it for \ other purposes.") def clear(self): self.dlg.textEditData.clear() def closelt(self): self.dlg.close() def run(self): # add connections to combobox self.dlg.comboBox_2.clear() dbpluginclass = createDbPlugin('postgis') connection_list = [] self.dbconnections = dbpluginclass.connections() for c in self.dbconnections: connection_list.append(unicode(c.connectionName())) c.connect() self.dlg.comboBox_2.addItems(connection_list) dbpluginclass.typeName() # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass
class IPOPProcess(QtCore.QObject): #Signals ipop_started = pyqtSignal() controller_started = pyqtSignal() ipop_stopped = pyqtSignal() controller_stopped = pyqtSignal() started = pyqtSignal() stopped = pyqtSignal() stop_this_inst = pyqtSignal() is_admingvpn = False def __init__(self): super(IPOPProcess, self).__init__() self.ipop_process = QProcess() self.controller_process = QProcess() self.ipop_kill_process = QProcess() self.running = False self.makeConnections() self.heartbeat = QTimer() self.heartbeat.timeout.connect(self.beat) def startIPOP(self): self.ipop_process.setWorkingDirectory(os.environ['WORKING_DIR']) self.ipop_process.start("sudo", ['./script.sh']) self.ipop_process.readyRead.connect(self.ipop_started.emit) self.ipoplogupdater = LogUpdater('ipop.log', 60) def startGVPN(self): self.controller_process.setWorkingDirectory(os.environ['WORKING_DIR']) #self.controller_process.setStandardOutputFile(os.environ['WORKING_DIR'] + 'LOG.txt') self.controller_process.setStandardErrorFile( os.environ['WORKING_DIR'] + 'gvpn.log') if self.is_admingvpn: self.controller_process.start("./admin_gvpn.py", ['-c', 'conff.json']) else: self.controller_process.start("./gvpn_controller.py", ['-c', 'conff.json']) self.controller_process.started.connect(self.controller_started.emit) self.controller_process.started.connect(self.started.emit) self.gvpnlogupdater = LogUpdater('gvpn.log', 60) self.heartbeat.start(HEARTBEAT_CYCLE) def beat(self): try: connect.instance.setStatus(connect.jid, connect.vpnname, 'running') except: return def start(self): self.startIPOP() self.running = True def stop(self): self.stopIPOP() def stopIPOP(self): self.ipop_kill_process.start("sudo", ['pkill', 'ipop-tincan-x86']) del self.ipoplogupdater self.ipop_kill_process.finished.connect(self.ipop_stopped.emit) def stopGVPN(self): self.controller_process.kill() self.controller_stopped.emit() try: del self.gvpnlogupdater except AttributeError: pass # gives out error while restarting IPOP due to changed IP self.stopped.emit() self.running = False self.heartbeat.stop() def setAdminGVPN(self, is_admingvpn=False): self.is_admingvpn = is_admingvpn def makeConnections(self): self.connect(self, SIGNAL("ipop_started()"), self.startGVPN) self.connect(self, SIGNAL("ipop_stopped()"), self.stopGVPN) self.connect(self, SIGNAL("stop_this_inst()"), self.stop)
class Main(plugin.Plugin): " Main Class " def initialize(self, *args, **kwargs): " Init Main Class " super(Main, self).initialize(*args, **kwargs) self.process = QProcess() self.process.readyReadStandardOutput.connect(self.readOutput) self.process.readyReadStandardError.connect(self.readErrors) self.process.finished.connect(self._process_finished) self.process.error.connect(self._process_finished) # directory auto completer self.completer, self.dirs = QCompleter(self), QDirModel(self) self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.group0 = QGroupBox() self.group0.setTitle(' Source ') self.source, self.infile = QComboBox(), QLineEdit(path.expanduser("~")) self.source.addItems(['Local File', 'Remote URL']) self.source.currentIndexChanged.connect(self.on_source_changed) self.infile.setPlaceholderText(' /full/path/to/file.html ') self.infile.setCompleter(self.completer) self.open = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.open.setCursor(QCursor(Qt.PointingHandCursor)) self.open.clicked.connect(lambda: self.infile.setText( str( QFileDialog.getOpenFileName( self.dock, "Open a File to read from", path.expanduser( "~"), ';;'.join([ '{}(*.{})'.format(e.upper(), e) for e in ['html', 'webp', 'webm', 'svg', 'css', 'js', '*'] ]))))) self.inurl, self.output = QLineEdit('http://www.'), QTextEdit() self.inurl.setPlaceholderText( 'http://www.full/url/to/remote/file.html') self.inurl.hide() vboxg0 = QVBoxLayout(self.group0) for each_widget in (self.source, self.infile, self.open, self.inurl): vboxg0.addWidget(each_widget) self.group1 = QGroupBox() self.group1.setTitle(' Mobile ') self.ckcss1 = QCheckBox('Run in full screen using current resolution') self.ckcss2 = QCheckBox('Disable touch mode and use keypad mode') self.ckcss3 = QCheckBox( 'Disable touch mode but allow to use the mouse') self.ckcss4 = QCheckBox( 'Enable mouse,disable pointer & zoom emulation') self.ckcss5 = QCheckBox('Start the Mobile version of the browser') self.ckcss6 = QCheckBox('Start the Tablet version of the browser') self.ckcss7 = QCheckBox('Emulate hardware with Menu and Back keys') self.ckcss8 = QCheckBox('Start the browser in Kiosk mode') self.width, self.height = QSpinBox(), QSpinBox() self.zoom, self.ram, self.dpi = QSpinBox(), QSpinBox(), QSpinBox() self.cpulag, self.gpulag = QSpinBox(), QSpinBox() self.lang, self.agent = QComboBox(), QComboBox() self.lang.addItems(['EN', 'ES', 'PT', 'JA', 'ZH', 'DE', 'RU', 'FR']) self.agent.addItems(['Default', 'Android', 'MeeGo', 'Desktop']) self.fonts = QLineEdit() self.width.setMaximum(9999) self.width.setMinimum(100) self.width.setValue(480) self.height.setMaximum(9999) self.height.setMinimum(100) self.height.setValue(800) self.zoom.setMaximum(999) self.zoom.setMinimum(1) self.zoom.setValue(100) self.ram.setMaximum(999) self.ram.setMinimum(1) self.ram.setValue(100) self.dpi.setMaximum(200) self.dpi.setMinimum(50) self.dpi.setValue(96) self.cpulag.setMaximum(9999) self.cpulag.setMinimum(0) self.cpulag.setValue(1) self.gpulag.setMaximum(9999) self.gpulag.setMinimum(0) self.gpulag.setValue(1) vboxg1 = QVBoxLayout(self.group1) for each_widget in ( self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, QLabel('Width Pixels of the emulated device screen'), self.width, QLabel('Height Pixels of the emulated device screen'), self.height, QLabel('Zoom Percentage of emulated screen'), self.zoom, QLabel('RAM MegaBytes of the emulated device'), self.ram, QLabel('Language of the emulated device'), self.lang, QLabel('D.P.I. of the emulated device'), self.dpi, QLabel('User-Agent of the emulated device'), self.agent, QLabel('CPU Core Lag Miliseconds of emulated device'), self.cpulag, QLabel('GPU Video Lag Miliseconds of emulated device'), self.gpulag, QLabel('Extra Fonts Directory Full Path'), self.fonts): vboxg1.addWidget(each_widget) self.group2 = QGroupBox() self.group2.setTitle(' General ') self.nice, self.opera = QSpinBox(), QLineEdit(path.expanduser("~")) self.nice.setValue(20) self.nice.setMaximum(20) self.nice.setMinimum(0) self.opera.setCompleter(self.completer) if path.exists(CONFIG_FILE): with codecs.open(CONFIG_FILE, encoding='utf-8') as fp: self.opera.setText(fp.read()) self.open2 = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.open2.setCursor(QCursor(Qt.PointingHandCursor)) self.open2.clicked.connect(lambda: self.opera.setText( str( QFileDialog.getOpenFileName( self.dock, "Open Opera Mobile Emulator", path.expanduser("~"), 'Opera Mobile Emulator Executable(opera-mobile-emulator)')) )) self.help1 = QLabel('''<a href= "http://www.opera.com/developer/mobile-emulator"> <small><center>Download Opera Mobile Emulator !</a>''') self.help1.setTextInteractionFlags(Qt.LinksAccessibleByMouse) self.help1.setOpenExternalLinks(True) vboxg4 = QVBoxLayout(self.group2) for each_widget in (QLabel(' Backend CPU priority: '), self.nice, QLabel(' Opera Mobile Emulator Full Path: '), self.opera, self.open2, self.help1): vboxg4.addWidget(each_widget) self.button = QPushButton('Preview on Mobile') self.button.setCursor(QCursor(Qt.PointingHandCursor)) self.button.setMinimumSize(100, 50) self.button.clicked.connect(self.run) glow = QGraphicsDropShadowEffect(self) glow.setOffset(0) glow.setBlurRadius(99) glow.setColor(QColor(99, 255, 255)) self.button.setGraphicsEffect(glow) glow.setEnabled(True) class TransientWidget(QWidget): ' persistant widget thingy ' def __init__(self, widget_list): ' init sub class ' super(TransientWidget, self).__init__() vbox = QVBoxLayout(self) for each_widget in widget_list: vbox.addWidget(each_widget) tw = TransientWidget(( QLabel('<b>Mobile Browser Emulator'), self.group0, self.group1, self.group2, self.output, self.button, )) self.scrollable, self.dock = QScrollArea(), QDockWidget() self.scrollable.setWidgetResizable(True) self.scrollable.setWidget(tw) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.dock.setWidget(self.scrollable) ExplorerContainer().addTab(self.dock, "Mobile") QPushButton( QIcon.fromTheme("help-about"), 'About', self.dock).clicked.connect( lambda: QMessageBox.information(self.dock, __doc__, HELPMSG)) def run(self): ' run the string replacing ' self.output.clear() self.button.setEnabled(False) self.output.append(self.formatInfoMsg('INFO:{}'.format( datetime.now()))) if self.source.currentText() == 'Local File': target = 'file://' + str(self.infile.text()).strip() else: target = self.inurl.text() self.output.append(self.formatInfoMsg(' INFO: OK: Parsing Arguments')) cmd = ' '.join( ('nice --adjustment={}'.format(self.nice.value()), '"{}"'.format( self.opera.text()), '-fullscreen' if self.ckcss1.isChecked() is True else '', '-notouch' if self.ckcss2.isChecked() is True else '', '-notouchwithtouchevents' if self.ckcss3.isChecked() is True else '', '-usemouse' if self.ckcss4.isChecked() is True else '', '-mobileui' if self.ckcss5.isChecked() is True else '', '-tabletui' if self.ckcss6.isChecked() is True else '', '-hasmenuandback' if self.ckcss7.isChecked() is True else '', '-k' if self.ckcss8.isChecked() is True else '', '-displaysize {}x{}'.format( self.width.value(), self.height.value()), '-displayzoom {}'.format( self.zoom.value()), '-mem {}M'.format(self.ram.value()), '-lang {}'.format(self.lang.currentText()), '-ppi {}'.format( self.dpi.value()), '-extra-fonts {}'.format(self.fonts.text()) if str(self.fonts.text()).strip() is not '' else '', '-user-agent-string {}'.format( self.agent.currentText()), '-delaycorethread {}'.format( self.cpulag.value()), '-delayuithread {}'.format( self.gpulag.value()), '-url "{}"'.format(target))) self.output.append(self.formatInfoMsg( 'INFO:OK:Command:{}'.format(cmd))) self.process.start(cmd) if not self.process.waitForStarted(): self.output.append(self.formatErrorMsg(' ERROR: FAIL: Meh. ')) self.output.append( self.formatErrorMsg( 'ERROR: FAIL: Failed with Arguments: {} '.format(cmd))) self.button.setEnabled(True) return self.output.setFocus() self.output.selectAll() self.button.setEnabled(True) def on_source_changed(self): ' do something when the desired source has changed ' if self.source.currentText() == 'Local File': self.open.show() self.infile.show() self.inurl.hide() else: self.inurl.show() self.open.hide() self.infile.hide() def _process_finished(self): """ finished sucessfully """ self.output.append(self.formatInfoMsg('INFO:{}'.format( datetime.now()))) self.output.selectAll() self.output.setFocus() def readOutput(self): """Read and append output to the logBrowser""" self.output.append(str(self.process.readAllStandardOutput()).strip()) def readErrors(self): """Read and append errors to the logBrowser""" self.output.append( self.formatErrorMsg(str(self.process.readAllStandardError()))) 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, 'green') def formatMsg(self, msg, color): """Format message with the given color""" return '<font color="{}">{}</font>'.format(color, msg) def finish(self): ' save when finish ' with codecs.open(CONFIG_FILE, "w", encoding='utf-8') as fp: fp.write(self.opera.text())
class MainWindow(QMainWindow, ramyCaracteristicas.Ui_MainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self)#linea para jalar todos componente de la interfaz # crear la grafica y sus propiedades self.crear_grafica()# funcion self.grafica_datos_x = [] self.grafica_datos_y = [] self.contador_x = 0 self.inicializar_timer()#funcion self.pushButton.clicked.connect(self.funcionActualizar) self.proceso_comando = QProcess(self) def funcionActualizar(self): print ('funActualizarSO') self.proceso_comando.start('pkexec', ['dnf update', '-y']) def crear_grafica(self): self.pluma = pg.mkPen(width=2, color='y') self.graphicsView.plotItem.showGrid(True, True, 0.5) self.graphicsView.setXRange(0, 59) self.graphicsView.setYRange(0, 100) self.label.setText("RAM") memoria = psutil.virtual_memory() self.label_5.setText(str(memoria.total / (1024 * 1024 * 1024))+" GiB") self.label_2.setText("Disco:") disco = psutil.disk_usage('/').total self.label_8.setText(str(disco / (1024 * 1024 * 1024))+" GiB") self.label_3.setText("CPU:") self.label_6.setText(str(psutil.cpu_count())) self.label_4.setText("SWAP:") swap = psutil.swap_memory().total self.label_7.setText(str(swap/(1024 * 1024 * 1024))+" GiB") def inicializar_timer(self): tiempo = QTimer(self) tiempo.timeout.connect(self.actualizar_grafica)#cuanto termina tiempo, llamo actualizar_grafica tiempo.start(1000) def actualizar_grafica(self): if len(self.grafica_datos_y) == 60: self.grafica_datos_y.pop(0) self.grafica_datos_y.extend([psutil.virtual_memory().percent]) if len(self.grafica_datos_x) == 60: pass else: self.grafica_datos_x.extend([self.contador_x]) self.contador_x += 1 self.graphicsView.plot(self.grafica_datos_x, self.grafica_datos_y[::-1], pen=self.pluma, clear=True)
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()
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)
class RunWidget(QWidget): """Widget that show the execution output in the Tool Dock.""" def __init__(self): super(RunWidget, self).__init__() vbox = QVBoxLayout(self) vbox.setSpacing(0) vbox.setContentsMargins(0, 0, 0, 0) self.output = OutputWidget(self) hbox = QHBoxLayout() self.input = QLineEdit() self.lblInput = QLabel(self.tr("Input:")) vbox.addWidget(self.output) hbox.addWidget(self.lblInput) hbox.addWidget(self.input) vbox.addLayout(hbox) self.set_font(settings.FONT) #process self.currentProcess = None self.__preScriptExecuted = False self._proc = QProcess(self) self._preExecScriptProc = QProcess(self) self._postExecScriptProc = QProcess(self) self.connect(self._proc, SIGNAL("readyReadStandardOutput()"), self.output.refresh_output) self.connect(self._proc, SIGNAL("readyReadStandardError()"), self.output.refresh_error) self.connect(self._proc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.finish_execution) self.connect(self._proc, SIGNAL("error(QProcess::ProcessError)"), self.process_error) self.connect(self.input, SIGNAL("returnPressed()"), self.insert_input) self.connect(self._preExecScriptProc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.__main_execution) self.connect(self._preExecScriptProc, SIGNAL("readyReadStandardOutput()"), self.output.refresh_output) self.connect(self._preExecScriptProc, SIGNAL("readyReadStandardError()"), self.output.refresh_error) self.connect(self._postExecScriptProc, SIGNAL("finished(int, QProcess::ExitStatus)"), self.__post_execution_message) self.connect(self._postExecScriptProc, SIGNAL("readyReadStandardOutput()"), self.output.refresh_output) self.connect(self._postExecScriptProc, SIGNAL("readyReadStandardError()"), self.output.refresh_error) def set_font(self, font): """Set the font for the output widget.""" self.output.document().setDefaultFont(font) self.output.plain_format.setFont(font) self.output.error_format.setFont(font) def process_error(self, error): """Listen to the error signals from the running process.""" self.lblInput.hide() self.input.hide() self._proc.kill() format_ = QTextCharFormat() format_.setAnchor(True) font = settings.FONT format_.setFont(font) format_.setForeground( QBrush( QColor( resources.CUSTOM_SCHEME.get( "error-underline", resources.COLOR_SCHEME["error-underline"])))) if error == 0: self.output.textCursor().insertText(self.tr('Failed to start'), format_) else: self.output.textCursor().insertText( (self.tr('Error during execution, QProcess error: %d') % error), format_) def finish_execution(self, exitCode, exitStatus): """Print a message and hide the input line when the execution ends.""" self.lblInput.hide() self.input.hide() format_ = QTextCharFormat() format_.setAnchor(True) font = settings.FONT format_.setFont(font) self.output.textCursor().insertText('\n\n') if exitStatus == QProcess.NormalExit: format_.setForeground( QBrush( QColor( resources.CUSTOM_SCHEME.get( "keyword", resources.COLOR_SCHEME["keyword"])))) self.output.textCursor().insertText( self.tr("Execution Successful!"), format_) else: format_.setForeground( QBrush( QColor( resources.CUSTOM_SCHEME.get( "error-underline", resources.COLOR_SCHEME["error-underline"])))) self.output.textCursor().insertText( self.tr("Execution Interrupted"), format_) self.output.textCursor().insertText('\n\n') self.__post_execution() def insert_input(self): """Take the user input and send it to the process.""" text = self.input.text() + '\n' self._proc.writeData(text) self.output.textCursor().insertText(text, self.output.plain_format) self.input.setText("") def start_process(self, fileName, pythonExec=False, PYTHONPATH=None, programParams='', preExec='', postExec=''): """Prepare the output widget and start the process.""" self.lblInput.show() self.input.show() self.fileName = fileName self.pythonExec = pythonExec # FIXME, this is python interpreter self.programParams = programParams self.preExec = preExec self.postExec = postExec self.PYTHONPATH = PYTHONPATH self.__pre_execution() def __main_execution(self): """Execute the project.""" self.output.setCurrentCharFormat(self.output.plain_format) message = '' if self.__preScriptExecuted: self.__preScriptExecuted = False message = self.tr( "Pre Execution Script Successfully executed.\n\n") self.output.setPlainText(message + 'Running: %s (%s)\n\n' % (self.fileName, time.ctime())) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) self.output.moveCursor(QTextCursor.Down) if not self.pythonExec: self.pythonExec = settings.PYTHON_EXEC #change the working directory to the fileName dir file_directory = file_manager.get_folder(self.fileName) self._proc.setWorkingDirectory(file_directory) #force python to unbuffer stdin and stdout options = ['-u'] + settings.EXECUTION_OPTIONS.split() self.currentProcess = self._proc env = QProcessEnvironment() system_environemnt = self._proc.systemEnvironment() for e in system_environemnt: key, value = e.split('=', 1) env.insert(key, value) if self.PYTHONPATH: envpaths = [path for path in self.PYTHONPATH.splitlines()] for path in envpaths: env.insert('PYTHONPATH', path) env.insert('PYTHONIOENCODING', 'utf-8') self._proc.setProcessEnvironment(env) self._proc.start( self.pythonExec, options + [self.fileName] + [p.strip() for p in self.programParams.split(',') if p]) def __pre_execution(self): """Execute a script before executing the project.""" filePreExec = QFile(self.preExec) if filePreExec.exists() and \ bool(QFile.ExeUser & filePreExec.permissions()): ext = file_manager.get_file_extension(self.preExec) if not self.pythonExec: self.pythonExec = settings.PYTHON_PATH self.currentProcess = self._preExecScriptProc self.__preScriptExecuted = True if ext == 'py': self._preExecScriptProc.start(self.pythonExec, [self.preExec]) else: self._preExecScriptProc.start(self.preExec) else: self.__main_execution() def __post_execution(self): """Execute a script after executing the project.""" filePostExec = QFile(self.postExec) if filePostExec.exists() and \ bool(QFile.ExeUser & filePostExec.permissions()): ext = file_manager.get_file_extension(self.postExec) if not self.pythonExec: self.pythonExec = settings.PYTHON_PATH self.currentProcess = self._postExecScriptProc if ext == 'py': self._postExecScriptProc.start(self.pythonExec, [self.postExec]) else: self._postExecScriptProc.start(self.postExec) def __post_execution_message(self): """Print post execution message.""" self.output.textCursor().insertText('\n\n') format_ = QTextCharFormat() format_.setAnchor(True) format_.setForeground(Qt.green) self.output.textCursor().insertText( self.tr("Post Execution Script Successfully executed."), format_) def kill_process(self): """Kill the running process.""" self._proc.kill()
class ConsoleWidget(QPlainTextEdit): def __init__(self): QPlainTextEdit.__init__(self, '>>> ') self.setUndoRedoEnabled(False) self.apply_editor_style() self.setToolTip(self.tr("Show/Hide (F4)")) self.moveCursor(QTextCursor.EndOfLine) self._patIsWord = re.compile('\w+') self.prompt = '>>> ' self._console = console.Console() self._history = [] self.history_index = 0 self._current_command = '' self._braces = None self.imports = ['import __builtin__'] self.patFrom = re.compile('^(\\s)*from ((\\w)+(\\.)*(\\w)*)+ import') self.patImport = re.compile('^(\\s)*import (\\w)+') self.patObject = re.compile('[^a-zA-Z0-9_\\.]') self.completer = completer_widget.CompleterWidget(self) self.okPrefix = QRegExp('[.)}:,\]]') self._pre_key_press = { Qt.Key_Enter: self._enter_pressed, Qt.Key_Return: self._enter_pressed, Qt.Key_Tab: self._tab_pressed, Qt.Key_Home: self._home_pressed, Qt.Key_PageUp: lambda x: True, Qt.Key_PageDown: lambda x: True, Qt.Key_Left: self._left_pressed, Qt.Key_Up: self._up_pressed, Qt.Key_Down: self._down_pressed, Qt.Key_Backspace: self._backspace, } #Create Context Menu self._create_context_menu() #Set Font self.set_font() #Create Highlighter parts_scanner, code_scanner, formats = \ syntax_highlighter.load_syntax(python_syntax.syntax) self.highlighter = syntax_highlighter.SyntaxHighlighter( self.document(), parts_scanner, code_scanner, formats) self.connect(self, SIGNAL("cursorPositionChanged()"), self.highlight_current_line) self.highlight_current_line() self._proc = QProcess(self) self.connect(self._proc, SIGNAL("readyReadStandardOutput()"), self._python_path_detected) self.connect(self._proc, SIGNAL("error(QProcess::ProcessError)"), self.process_error) self._add_system_path_for_frozen() def _add_system_path_for_frozen(self): try: self._proc.start(settings.PYTHON_PATH, [resources.GET_SYSTEM_PATH]) except Exception as reason: logger.warning('Could not get system path, error: %r' % reason) def _python_path_detected(self): paths = self._proc.readAllStandardOutput().data().decode('utf8') add_system_path = ('import sys; ' 'sys.path = list(set(sys.path + %s))' % paths) self._write(add_system_path) self._proc.deleteLater() def process_error(self, error): message = '' if error == 0: message = 'Failed to start' else: message = 'Error during execution, QProcess error: %d' % error logger.warning('Could not get system path, error: %r' % message) def set_font(self, family=settings.FONT_FAMILY, size=settings.FONT_SIZE): font = QFont(family, size) self.document().setDefaultFont(font) def _create_context_menu(self): self.popup_menu = self.createStandardContextMenu() self.popup_menu.clear() actionCut = self.popup_menu.addAction(self.tr("Cut")) actionCopy = self.popup_menu.addAction(self.tr("Copy")) actionPaste = self.popup_menu.addAction(self.tr("Paste")) actionClean = self.popup_menu.addAction(self.tr("Clean Console")) actionCopyHistory = self.popup_menu.addAction(self.tr("Copy History")) actionCopyConsoleContent = self.popup_menu.addAction( self.tr("Copy Console Content")) self.popup_menu.addAction(actionCut) self.popup_menu.addAction(actionCopy) self.popup_menu.addAction(actionPaste) self.popup_menu.addSeparator() self.popup_menu.addAction(actionClean) self.popup_menu.addSeparator() self.popup_menu.addAction(actionCopyHistory) self.popup_menu.addAction(actionCopyConsoleContent) self.connect(actionCut, SIGNAL("triggered()"), self._cut) self.connect(actionCopy, SIGNAL("triggered()"), self.copy) self.connect(actionPaste, SIGNAL("triggered()"), self._paste) self.connect(actionClean, SIGNAL("triggered()"), self._clean_console) self.connect(actionCopyHistory, SIGNAL("triggered()"), self._copy_history) self.connect(actionCopyConsoleContent, SIGNAL("triggered()"), self._copy_console_content) def _cut(self): event = QKeyEvent(QEvent.KeyPress, Qt.Key_X, Qt.ControlModifier, "x") self.keyPressEvent(event) def _paste(self): if self.textCursor().hasSelection(): self.moveCursor(QTextCursor.End) self.paste() def _clean_console(self): self.clear() self._add_prompt() def _copy_history(self): historyContent = '\n'.join(self._history) clipboard = QApplication.instance().clipboard() clipboard.setText(historyContent) def _copy_console_content(self): content = self.toPlainText() clipboard = QApplication.instance().clipboard() clipboard.setText(content) def setCursorPosition(self, position, mode=QTextCursor.MoveAnchor): self.moveCursor(QTextCursor.StartOfLine, mode) for i in range(len(self.prompt) + position): self.moveCursor(QTextCursor.Right, mode) def _check_event_on_selection(self, event): if event.text(): cursor = self.textCursor() begin_last_block = (self.document().lastBlock().position() + len(self.prompt)) if cursor.hasSelection() and \ ((cursor.selectionEnd() < begin_last_block) or (cursor.selectionStart() < begin_last_block)): self.moveCursor(QTextCursor.End) def _enter_pressed(self, event): self._write_command() return True def _tab_pressed(self, event): self.textCursor().insertText(' ' * settings.INDENT) return True def _home_pressed(self, event): if event.modifiers() == Qt.ShiftModifier: self.setCursorPosition(0, QTextCursor.KeepAnchor) else: self.setCursorPosition(0) return True def _left_pressed(self, event): return self._get_cursor_position() == 0 def _up_pressed(self, event): if self.history_index == len(self._history): command = self.document().lastBlock().text()[len(self.prompt):] self._current_command = command self._set_command(self._get_prev_history_entry()) return True def _down_pressed(self, event): if len(self._history) == self.history_index: command = self._current_command else: command = self._get_next_history_entry() self._set_command(command) return True def _backspace(self, event): cursor = self.textCursor() selected_text = cursor.selectedText() cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor) text = cursor.selectedText()[len(self.prompt):] if (len(text) % settings.INDENT == 0) and text.isspace(): cursor.movePosition(QTextCursor.StartOfLine) cursor.movePosition(QTextCursor.Right, QTextCursor.MoveAnchor, settings.INDENT) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, settings.INDENT) cursor.removeSelectedText() return True elif (selected_text == self.document().lastBlock().text() [len(self.prompt):]): self.textCursor().removeSelectedText() return True return self._get_cursor_position() == 0 def keyPressEvent(self, event): if self.completer.popup().isVisible(): if event.key() in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Tab): event.ignore() self.completer.popup().hide() return elif event.key in (Qt.Key_Space, Qt.Key_Escape, Qt.Key_Backtab): self.completer.popup().hide() self._check_event_on_selection(event) if self._pre_key_press.get(event.key(), lambda x: False)(event): return if event.text() in (set(BRACES.values()) - set(["'", '"'])): cursor = self.textCursor() cursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor) brace = cursor.selection().toPlainText() cursor = self.textCursor() cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor) braceClose = cursor.selection().toPlainText() if BRACES.get(brace, False) == event.text() and \ braceClose == event.text(): self.moveCursor(QTextCursor.Right) return QPlainTextEdit.keyPressEvent(self, event) if event.text() in BRACES: cursor = self.textCursor() cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor) self.textCursor().insertText(BRACES[event.text()]) self.moveCursor(QTextCursor.Left) completionPrefix = self._text_under_cursor() if event.key() == Qt.Key_Period or (event.key() == Qt.Key_Space and event.modifiers() == Qt.ControlModifier): self.completer.setCompletionPrefix(completionPrefix) self._resolve_completion_argument() if self.completer.popup().isVisible() and \ completionPrefix != self.completer.completionPrefix(): self.completer.setCompletionPrefix(completionPrefix) self.completer.popup().setCurrentIndex( self.completer.completionModel().index(0, 0)) self.completer.setCurrentRow(0) self._resolve_completion_argument() def _resolve_completion_argument(self): try: cursor = self.textCursor() cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor) var = cursor.selectedText() chars = self.patObject.findall(var) var = var[var.rfind(chars[-1]) + 1:] cr = self.cursorRect() proposals = completer.get_all_completions(var, imports=self.imports) if not proposals: if self.completer.popup().isVisible(): prefix = var[var.rfind('.') + 1:] var = var[:var.rfind('.') + 1] var = self._console.get_type(var) var += prefix else: var = self._console.get_type(var) proposals = completer.get_all_completions(var, imports=self.imports) self.completer.complete(cr, proposals) except: self.completer.popup().hide() def highlight_current_line(self): self.extraSelections = [] selection = QTextEdit.ExtraSelection() lineColor = QColor( resources.CUSTOM_SCHEME.get( 'current-line', resources.COLOR_SCHEME['current-line'])) lineColor.setAlpha(20) selection.format.setBackground(lineColor) selection.format.setProperty(QTextFormat.FullWidthSelection, True) selection.cursor = self.textCursor() selection.cursor.clearSelection() self.extraSelections.append(selection) self.setExtraSelections(self.extraSelections) if self._braces is not None: self._braces = None cursor = self.textCursor() if cursor.position() == 0: self.setExtraSelections(self.extraSelections) return cursor.movePosition(QTextCursor.PreviousCharacter, QTextCursor.KeepAnchor) text = cursor.selectedText() pos1 = cursor.position() if text in (')', ']', '}'): pos2 = self._match_braces(pos1, text, forward=False) elif text in ('(', '[', '{'): pos2 = self._match_braces(pos1, text, forward=True) else: self.setExtraSelections(self.extraSelections) return if pos2 is not None: self._braces = (pos1, pos2) selection = QTextEdit.ExtraSelection() selection.format.setForeground( QColor( resources.CUSTOM_SCHEME.get( 'brace-foreground', resources.COLOR_SCHEME.get('brace-foreground')))) selection.format.setBackground( QColor( resources.CUSTOM_SCHEME.get( 'brace-background', resources.COLOR_SCHEME.get('brace-background')))) selection.cursor = cursor self.extraSelections.append(selection) selection = QTextEdit.ExtraSelection() selection.format.setForeground( QColor( resources.CUSTOM_SCHEME.get( 'brace-foreground', resources.COLOR_SCHEME.get('brace-foreground')))) selection.format.setBackground( QColor( resources.CUSTOM_SCHEME.get( 'brace-background', resources.COLOR_SCHEME.get('brace-background')))) selection.cursor = self.textCursor() selection.cursor.setPosition(pos2) selection.cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor) self.extraSelections.append(selection) else: self._braces = (pos1, ) selection = QTextEdit.ExtraSelection() selection.format.setBackground( QColor( resources.CUSTOM_SCHEME.get( 'brace-background', resources.COLOR_SCHEME.get('brace-background')))) selection.format.setForeground( QColor( resources.CUSTOM_SCHEME.get( 'brace-foreground', resources.COLOR_SCHEME.get('brace-foreground')))) selection.cursor = cursor self.extraSelections.append(selection) self.setExtraSelections(self.extraSelections) def _text_under_cursor(self): tc = self.textCursor() tc.select(QTextCursor.WordUnderCursor) return tc.selectedText() def get_selection(self, posStart, posEnd): cursor = self.textCursor() cursor.setPosition(posStart) if posEnd == QTextCursor.End: cursor2 = self.textCursor() cursor2.movePosition(posEnd) cursor.setPosition(cursor2.position(), QTextCursor.KeepAnchor) else: cursor.setPosition(posEnd, QTextCursor.KeepAnchor) return cursor.selectedText() def _match_braces(self, position, brace, forward): """based on: http://gitorious.org/khteditor""" if forward: braceMatch = {'(': ')', '[': ']', '{': '}'} text = self.get_selection(position, QTextCursor.End) braceOpen, braceClose = 1, 1 else: braceMatch = {')': '(', ']': '[', '}': '{'} text = self.get_selection(QTextCursor.Start, position) braceOpen, braceClose = len(text) - 1, len(text) - 1 while True: if forward: posClose = text.find(braceMatch[brace], braceClose) else: posClose = text.rfind(braceMatch[brace], 0, braceClose + 1) if posClose > -1: if forward: braceClose = posClose + 1 posOpen = text.find(brace, braceOpen, posClose) else: braceClose = posClose - 1 posOpen = text.rfind(brace, posClose, braceOpen + 1) if posOpen > -1: if forward: braceOpen = posOpen + 1 else: braceOpen = posOpen - 1 else: if forward: return position + posClose else: return position - (len(text) - posClose) else: return def _add_prompt(self, incomplete=False): if incomplete: prompt = '.' * 3 + ' ' else: prompt = self.prompt self.appendPlainText(prompt) self.moveCursor(QTextCursor.End) def _get_cursor_position(self): return self.textCursor().columnNumber() - len(self.prompt) def _write_command(self): command = self.document().lastBlock().text() #remove the prompt from the QString command = command[len(self.prompt):] self._add_history(command) incomplete = self._write(command) if self.patFrom.match(command) or self.patImport.match(command): self.imports += [command] if not incomplete: output = self._read() if output is not None: if isinstance(output, str): output = output.encode('utf8') self.appendPlainText(output.decode('utf8')) self._add_prompt(incomplete) def _set_command(self, command): self.moveCursor(QTextCursor.End) cursor = self.textCursor() cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, len(self.prompt)) cursor.insertText(command) def contextMenuEvent(self, event): self.popup_menu.exec_(event.globalPos()) def _write(self, line): return self._console.push(line) def _read(self): return self._console.output def _add_history(self, command): if command and (not self._history or self._history[-1] != command): self._history.append(command) self.history_index = len(self._history) def _get_prev_history_entry(self): if self._history: self.history_index = max(0, self.history_index - 1) return self._history[self.history_index] return '' def _get_next_history_entry(self): if self._history: hist_len = len(self._history) - 1 self.history_index = min(hist_len, self.history_index + 1) index = self.history_index if self.history_index == hist_len: self.history_index += 1 return self._history[index] return '' def restyle(self): self.apply_editor_style() parts_scanner, code_scanner, formats = \ syntax_highlighter.load_syntax(python_syntax.syntax) self.highlighter = syntax_highlighter.SyntaxHighlighter( self.document(), parts_scanner, code_scanner, formats) def apply_editor_style(self): css = 'QPlainTextEdit {color: %s; background-color: %s;' \ 'selection-color: %s; selection-background-color: %s;}' \ % (resources.CUSTOM_SCHEME.get('editor-text', resources.COLOR_SCHEME['editor-text']), resources.CUSTOM_SCHEME.get('editor-background', resources.COLOR_SCHEME['editor-background']), resources.CUSTOM_SCHEME.get('editor-selection-color', resources.COLOR_SCHEME['editor-selection-color']), resources.CUSTOM_SCHEME.get('editor-selection-background', resources.COLOR_SCHEME['editor-selection-background'])) self.setStyleSheet(css) self.set_font(settings.FONT_FAMILY, settings.FONT_SIZE) def load_project_into_console(self, projectFolder): """Load the projectFolder received into the sys.path.""" self._console.push("import sys; sys.path += ['%s']" % projectFolder) def unload_project_from_console(self, projectFolder): """Unload the project from the system path.""" self._console.push("import sys; " "sys.path = [path for path in sys.path " "if path != '%s']" % projectFolder)
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)