def runProcess(self, args): self.logDb( u"BEFEHL: '%s'" % ( u"' '".join(args) ) ) currout = "" currerr = "" p = QProcess() p.start( args[0], args[1:] ) i=0 while not p.waitForFinished(500): i += 1 self.alive.setText( self.alive.text()[:-1] + ("-\|/")[i%4] ) app.processEvents() currout = self.processOutput( currout, p.readAllStandardOutput() ) currerr = self.processOutput( currerr, p.readAllStandardError() ) if p.state()<>QProcess.Running: if self.canceled: self.log( u"Prozeß abgebrochen." ) break if self.canceled: self.log( u"Prozeß wird abgebrochen." ) p.kill() currout = self.processOutput( currout, p.readAllStandardOutput() ) if currout and currout!="": self.log( "E %s" % currout ) currerr = self.processOutput( currerr, p.readAllStandardError() ) if currerr and currerr!="": self.log( "E %s" % currerr ) ok = False if p.exitStatus()==QProcess.NormalExit: if p.exitCode()==0: ok = True else: self.log( u"Fehler bei Prozeß: %d" % p.exitCode() ) else: self.log( u"Prozeß abgebrochen: %d" % p.exitCode() ) self.logDb( "EXITCODE: %d" % p.exitCode() ) p.close() return ok
def runProcess(self, args): self.logDb(u"BEFEHL: '%s'" % (u"' '".join(args))) currout = "" currerr = "" p = QProcess() p.start(args[0], args[1:]) i = 0 while not p.waitForFinished(500): i += 1 self.alive.setText(self.alive.text()[:-1] + ("-\|/")[i % 4]) app.processEvents() currout = self.processOutput(currout, p.readAllStandardOutput()) currerr = self.processOutput(currerr, p.readAllStandardError()) if p.state() <> QProcess.Running: if self.canceled: self.log(u"Prozeß abgebrochen.") break if self.canceled: self.log(u"Prozeß wird abgebrochen.") p.kill() currout = self.processOutput(currout, p.readAllStandardOutput()) if currout and currout != "": self.log("E %s" % currout) currerr = self.processOutput(currerr, p.readAllStandardError()) if currerr and currerr != "": self.log("E %s" % currerr) ok = False if p.exitStatus() == QProcess.NormalExit: if p.exitCode() == 0: ok = True else: self.log(u"Fehler bei Prozeß: %d" % p.exitCode()) else: self.log(u"Prozeß abgebrochen: %d" % p.exitCode()) self.logDb("EXITCODE: %d" % p.exitCode()) p.close() return ok
def 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 '<<<'
class QProcessTransport(Transport): '''A Transport communicating with a child process. Start the process using .start(). Sent data is written to the process' stdin. Data is received from the process's stdout and processed on the Qt mainloop thread. ''' shorthand='qprocess' @classmethod def fromstring(cls, expression): '''qprocess:(<commandline>)''' _, _, expr = expression.partition(':') cmdline, _, _ = paren_partition(expr) return cls(cmdline, sendername=expression) def __init__(self, cmdline, sendername='qprocess'): self.cmdline = cmdline self.sendername = sendername self.leftover = b'' self.process = QProcess() self.process.readyRead.connect(self.on_ready_read) self.process.finished.connect(self.on_finished) def start(self): L().debug('starting: %r'%self.cmdline) self.process.start(self.cmdline) def stop(self, kill=False): if kill: self.process.kill() else: self.process.terminate() self.process.waitForFinished() def send(self, data, receivers=None): if receivers is not None and self.sendername not in receivers: return L().debug('message to child processs: %s'%data) self.process.write(data.decode('utf8')) def on_ready_read(self): data = self.process.readAllStandardOutput().data() errors = self.process.readAllStandardError().data().decode('utf8') if errors: L().error('Error from child process:\n%s' % errors) pdata = data.decode('utf8') if len(pdata) > 100: pdata = pdata[:100] + '...' #if pdata.startswith('{'): L().debug('message from child process: %s'%pdata) self.leftover = self.received( sender=self.sendername, data=self.leftover + data ) def on_finished(self): L().info('Child process exited.')
class 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 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()
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()
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 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, 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 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 RdpConnection(object): _cfg = None _conn = None def __init__(self, cfg): self._cfg = cfg def connect(self, parent_window=None): if not parent_window is None: setattr(self._cfg, 'parent-window', parent_window) self._conn = QProcess() # print(self._cfg.as_list()) self._conn.start('xfreerdp', self._cfg.as_list()) self._conn.readyReadStandardOutput.connect(self._read_out) self._conn.readyReadStandardError.connect(self._read_err) def close(self): self._conn.close() self._conn.terminate() def connect_output(self, out_listener): self._out_listener = out_listener def _read_out(self): if not self._out_listener is None: self._out_listener(str(self._conn.readAllStandardOutput())) def _read_err(self): if not self._out_listener is None: self._out_listener(str(self._conn.readAllStandardError())) @property def cfg(self): return self._cfg
class AsciidocEditor(WithSingleIO, QWidget): """Asciidoc editor """ def __init__(self, params, parent=None): self.base_dir = os.path.dirname(__file__) QWidget.__init__(self, parent) self.setMinimumWidth(300) self.setMinimumHeight(300) # create widgets self._editor_widget = mixin( WithFind, WidthMqHighlighter, WithMqEditIO, WithBasicIdentationManager, WithLineHighlight, WithFixedFont, WithLineNumbers, WithViewPortMargins, WithWordCompletionMulty_, WithCompletion, QPlainTextEdit)(self) self.webview = QWebView(self) #self.webview.load(QUrl("/home/maiquel/develop/developing/main/qt/qadoc/bin/__builds/documents.html")) self.splitter = QSplitter(Qt.Horizontal) self.splitter.addWidget(self._editor_widget) self.splitter.addWidget(self.webview) self.splitter.setSizes([self.size().width(), self.size().width()]) self.splitterv = QSplitter(Qt.Vertical) self.splitterv.addWidget(self.splitter) self.log_widget = QPlainTextEdit() self.splitterv.addWidget(self.log_widget) layout = QVBoxLayout(self) layout.addWidget(self.splitterv) layout.setMargin(0) self.setLayout(layout) # proc_compile self.proc_compile = QProcess() self.proc_compile.finished.connect(self.proc_compile_finished) self.proc_compile.error.connect(self.proc_compile_error) self.proc_compile.readyReadStandardOutput.connect(self.proc_compile_readyReadStandardOutput) self.proc_compile.readyReadStandardError.connect(self.proc_compile_readyReadStandardError) WithSingleIO.__init__(self, params) def bw_add_command_list(self, command_list): command_list += [ ("generate preview asciidoc", "pp", 1.0, "self.get_current_widget().command_generate_preview('asciidoc -a toc -a data-uri -a icons -a iconsdir="+self.base_dir+"/adoc/icons/')"), ("generate preview asciidoc style_sheet no images embeded", "pp", 1.0, "self.get_current_widget().command_generate_preview('asciidoc -a toc --attribute stylesheet="+self.base_dir+"/adoc/mq_red.css -a icons -a iconsdir="+self.base_dir+"/adoc/icons/')"), ("generate preview asciidoc style_sheet", "pp", 1.2, "self.get_current_widget().command_generate_preview('asciidoc -a toc --attribute stylesheet="+self.base_dir+"/adoc/mq_red.css -a data-uri -a icons -a iconsdir="+self.base_dir+"/adoc/icons/')"), ("generate preview slidy", "pp slides", 0.8, "self.get_current_widget().command_generate_preview('asciidoc -a toc -b slidy -a data-uri -a icons')"), ("generate preview slidy2", "pp slides", 0.9, "self.get_current_widget().command_generate_preview('asciidoc -a toc -b slidy2 -a data-uri -a icons')"), ("generate preview asciidoctor", "pp", 0.7, "self.get_current_widget().command_generate_preview('asciidoctor -a toc -a data-uri -a icons')"), ("generate preview deck.js", "pp slides", 0.7, "self.get_current_widget().command_generate_preview('asciidoc -a toc -b deckjs -a data-uri -a icons')"), ("generate pdf small", "", 0., """self.get_current_widget().command_generate_document('a2x --verbose -d article --icons --dblatex-opts "-T native -P doc.pdfcreator.show=0 -P doc.collab.show=0 -P latex.output.revhistory=0 -P doc.toc.show=1 -P table.title.top" -f pdf -D /tmp/adoc/ ')"""), ("generate pdf book", "", 0., """self.get_current_widget().command_generate_document('a2x --verbose -d book --icons --dblatex-opts "-T native -P doc.pdfcreator.show=0 -P doc.collab.show=0 -P latex.output.revhistory=0 -P doc.toc.show=1 -P table.title.top" -f pdf -D /tmp/adoc/ ')"""), ] super(AsciidocEditor, self).bw_add_command_list(command_list) self._editor_widget.bw_add_command_list(command_list) command_list += [ ("focus editor", "fe", 0.5, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self._editor_widget.setFocus();"), ("focus preview", "fp", 0.5, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self.webview.setFocus();"), ("increase font webview", "if if", 0.7, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self.webview.setTextSizeMultiplier(_self.webview.textSizeMultiplier()+0.1);"), ("decrease font webview", "df df", 0.7, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self.webview.setTextSizeMultiplier(_self.webview.textSizeMultiplier()-0.1);"), ] def copy2tmp(self): if not os.path.exists(TEMP_DIR): os.mkdir(TEMP_DIR) source = os.listdir(self.base_dir) destination = TEMP_DIR for files in source: shutil.move(files,destination) def command_generate_preview(self, adoc_command): self.command_save_file() #self.compile(backend + " -b deckjs -o " + self.get_html_output() + " " + TEMP_DIR + "pr.adoc") #asciidoc --verbose -a data-uri -a icons -a toc -a max-width=55em -o __builds/index.html /home/maiquel/Documents/qadoc/adoc/index.adoc #self.compile(adoc_command + " --attribute stylesheet=/home/maiquel/inet.prj/miow/widgets/adoc/mq_red.css -a data-uri -a icons -o " + self.get_html_output() + " " + TEMP_DIR + "pr.adoc") self.compile(adoc_command + ' -o ' +self.get_html_output() + ' ./"' + self.file_name + '"') if self.webview.url() != QUrl("file://" + self.get_html_output()): self.webview.load(QUrl(self.get_html_output())) def command_generate_document(self, adoc_command): self.command_save_file() self.compile(adoc_command + " " + TEMP_DIR + "pr.adoc") if self.webview.url() != QUrl("file://" + self.get_html_output()): self.webview.load(QUrl(self.get_html_output())) def compile(self, command): self.log(command) self.proc_compile.start(command) def bw_lock_command_window(self): return self._editor_widget.completer.popup().isVisible() def focusInEvent(self, focus_event): super(AsciidocEditor, self).focusInEvent(focus_event) self._editor_widget.setFocus() def get_html_output(self): return TEMP_DIR + "pr.html" def proc_compile_finished(self, result, exit_status): self.log("compilation finished") if self.webview.url().toString() == "": self.webview.load(QUrl(self.get_html_output())) else: self.webview.reload() def proc_compile_error(self, q_process_error): self.log("compilation error") print(q_process_error) def proc_compile_readyReadStandardOutput(self): result = self.proc_compile.readAllStandardOutput(); self.log(result) def proc_compile_readyReadStandardError(self): result = str(self.proc_compile.readAllStandardError()) self.log(result) def log(self, text): self.log_widget.appendPlainText(unicode(text))
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
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 Georeferencer(QObject): # Step enum Start = 0 Crop = 1 Translate = 2 Warp = 3 Overview = 4 Stop = 5 Step = [0, 1, 2, 3, 4, 5] Label = ['Start', 'Crop', 'Translate', 'Warp', 'Overview', 'Stop'] # Georeferencer.Step, ProcessStatus status = pyqtSignal(int, int) # Georeferencer.Step, Message error = pyqtSignal(int, str) def __init__(self, parent=None): super(Georeferencer, self).__init__(parent) # Internal variables self._debug = True self._gdalDir = QDir() self._step = 0 self._status = 0 self._translate = QFileInfo() self._warp = QFileInfo() self._overview = QFileInfo() self._command = '' self._args = '' self._process = QProcess() self._gc = Transform() self._rawFile = QFileInfo() self._pointFile = QFileInfo() self._cropFile = QFileInfo() self._translateFile = QFileInfo() self._geoFile = QFileInfo() tempDir = QDir.temp() self._cropFile.setFile( tempDir.absoluteFilePath('.ark_georef_crop.png')) self._translateFile = QFileInfo( tempDir.absoluteFilePath('.ark_georef_translate.tiff')) self._gdalDir = QDir(self.gdalPath()) if self._debug: debug('GDAL Path: ' + self._gdalDir.absolutePath()) self._translate.setFile(self._gdalDir, 'gdal_translate') self._warp.setFile(self._gdalDir, 'gdalwarp') self._overview.setFile(self._gdalDir, 'gdaladdo') if (not self._translate.exists() or not self._warp.exists() or not self._overview.exists()): self._signalError( 'GDAL commands not found, please ensure GDAL Tools plugin is installed and has correct path set!' ) return self._process.started.connect(self._processStarted) self._process.finished.connect(self._processFinished) self._process.error.connect(self._processError) self._process.readyReadStandardError.connect(self._processError) def step(self): return self._step def processStatus(self): return self._status def run(self, gc, rawFile, pointFile, geoFile): self._step = Georeferencer.Start if (not gc.isValid()): self._signalError('Invalid ground control points.') return self._gc = gc if (not rawFile.exists()): self._signalError('Raw file not found.') return self._rawFile = rawFile self._pointFile = pointFile self._geoFile = geoFile if not self._geoFile.absoluteDir().exists(): self._geoFile.absoluteDir().mkpath('.') if (self._debug): debug('Raw File: \'' + self._rawFile.absoluteFilePath() + '\'') debug('GCP File: \'' + self._pointFile.absoluteFilePath() + '\'') debug('Crop File: \'' + self._cropFile.absoluteFilePath() + '\'') debug('Translate File: \'' + self._translateFile.absoluteFilePath() + '\'') debug('Geo File: \'' + self._geoFile.absoluteFilePath() + '\'') QCoreApplication.processEvents() self._runCropStep() def _runCropStep(self): if self._debug: debug('Crop') self._step = Georeferencer.Crop self._args = [] self._command = '' pixmap = QPixmap(self._rawFile.absoluteFilePath()) if pixmap.isNull(): self._signalError('Loading of raw image failed.') return pixmap = pixmap.copy(0, 0, pixmap.width(), int(pixmap.height() * 0.84)) image = pixmap.toImage() if image.isNull(): self._signalError('Cropping of raw image failed.') return if not image.save(self._cropFile.absoluteFilePath(), 'PNG', 100): self._signalError('Saving of cropped image failed.') return self._signalStatus() self._runTranslateStep() def _formatGcp(self, point): point = self._gc.point(point) return "{0:f} {1:f} {2:f} {3:f}".format(point.raw().x(), point.raw().y(), point.map().x(), point.map().y()) def _runTranslateStep(self): self._step = Georeferencer.Translate self._args = [] self._args.extend(['-of', 'GTiff']) self._args.extend(['-a_srs', self._gc.crs]) # self._args.extend(['-gcp', self._formatGcp(1)]) # self._args.extend(['-gcp', self._formatGcp(2)]) # self._args.extend(['-gcp', self._formatGcp(3)]) # self._args.extend(['-gcp', self._formatGcp(4)]) self._args.extend([ '-gcp', str(self._gc.point(1).raw().x()), str(self._gc.point(1).raw().y()), str(self._gc.point(1).map().x()), str(self._gc.point(1).map().y()) ]) self._args.extend([ '-gcp', str(self._gc.point(2).raw().x()), str(self._gc.point(2).raw().y()), str(self._gc.point(2).map().x()), str(self._gc.point(2).map().y()) ]) self._args.extend([ '-gcp', str(self._gc.point(3).raw().x()), str(self._gc.point(3).raw().y()), str(self._gc.point(3).map().x()), str(self._gc.point(3).map().y()) ]) self._args.extend([ '-gcp', str(self._gc.point(4).raw().x()), str(self._gc.point(4).raw().y()), str(self._gc.point(4).map().x()), str(self._gc.point(4).map().y()) ]) self._args.append(self._cropFile.absoluteFilePath()) self._args.append(self._translateFile.absoluteFilePath()) self._command = self._translate.absoluteFilePath() + ' ' + ' '.join( self._args) self._process.start(self._translate.absoluteFilePath(), self._args) def _runWarpStep(self): self._step = Georeferencer.Warp self._args = [] self._args.extend(['-order', '1']) self._args.extend(['-r', 'cubic']) self._args.extend(['-t_srs', self._gc.crs]) self._args.extend(['-of', 'GTiff']) self._args.extend(['-co', 'COMPRESS=JPEG']) self._args.extend(['-co', 'JPEG_QUALITY=50']) self._args.extend(['-co', 'TILED=YES']) self._args.append('-dstalpha') self._args.append('-overwrite') self._args.append('\"' + self._translateFile.absoluteFilePath() + '\"') self._args.append('\"' + self._geoFile.absoluteFilePath() + '\"') self._command = self._warp.absoluteFilePath() + ' ' + ' '.join( self._args) self._process.start(self._command) def _runOverviewStep(self): self._step = Georeferencer.Overview self._args = [] self._args.extend(['--config', 'COMPRESS_OVERVIEW JPEG']) self._args.extend(['--config', 'INTERLEAVE_OVERVIEW PIXEL']) self._args.extend(['-r', 'cubic']) self._args.append('\"' + self._geoFile.absoluteFilePath() + '\"') self._args.append('2 4 8 16') self._command = self._overview.absoluteFilePath() + ' ' + ' '.join( self._args) self._process.start(self._command) def _processStarted(self): self._status = ProcessStatus.Running self._signalStatus() if self._debug: debug(self.Label[self._step]) debug(self._command) def _processFinished(self): self._status = ProcessStatus.Success self._signalStatus() if (self._step == Georeferencer.Translate): self._runWarpStep() elif (self._step == Georeferencer.Warp): self._runOverviewStep() elif (self._step == Georeferencer.Overview): self.writeGcpFile(self._gc, self._pointFile.absoluteFilePath()) self._step = Georeferencer.Stop self._signalStatus() def _processError(self): self._status = ProcessStatus.Failure msg = str(self._process.readAllStandardError()) debug(msg) self._signalError(msg) def _signalStatus(self): self.status.emit(self._step, self._status) def _signalError(self, msg): self.error.emit(self._step, msg) @staticmethod def gdalPath(): return QSettings().value('/GdalTools/gdalPath', '/usr/bin') @staticmethod def loadGcpFile(path): inFile = QFile(path) if (not inFile.open(QIODevice.ReadOnly | QIODevice.Text)): return 'ERROR: Unable to open GCP file for reading' inStream = QTextStream(inFile) line = inStream.readLine() # Skip the header line if found if (line == 'mapX,mapY,pixelX,pixelY,enable'): line = inStream.readLine() lines = 0 gc = Transform() while (line): lines += 1 vals = line.split(',') if (len(vals) != 5): return None map = QgsPoint(float(vals[0]), float(vals[1])) raw = QPointF(float(vals[2]), float(vals[3])) enabled = bool(vals[4]) point = GroundControlPoint(raw, map, enabled) gc.setPoint(lines, point) line = inStream.readLine() inFile.close() return gc @staticmethod def writeGcpFile(gc, path): outFile = QFile(path) if (not outFile.open(QIODevice.WriteOnly | QIODevice.Text)): return 'Unable to open GCP file for writing' outStream = QTextStream(outFile) outStream << gc.asCsv() outFile.close()
class Dlg(QDialog, Ui_Dialog): def __init__(self, parent=None): super(Dlg, self).__init__(parent) self.setupUi(self) self.dockWidget.hide() self.fileLineEdit.setDisabled(True) self.fileButton.setDisabled(True) self.closeButton.clicked.connect(self.close) self.buildButton.clicked.connect(self.build) self.fileButton.clicked.connect(self.getFile) self.fileRadioButton.toggled.connect(self.fileLineEdit.setEnabled) self.fileRadioButton.toggled.connect(self.fileButton.setEnabled) self.logButton.toggled.connect(self.dockWidget.setVisible) for button in (self.sourceButton, self.outputButton): button.clicked.connect(self.getDirectory) self.sourceDirectory = None self.outputDirectory = None self.process = QProcess() self.process.readyReadStandardOutput.connect(self.readOutput) self.process.readyReadStandardError.connect(self.readErrors) #restore settings settings = QSettings() size = settings.value('Dialog/Size', QVariant(QSize(600, 500))).toSize() self.resize(size) pos = settings.value('Dialog/Position', QVariant(QPoint(0, 0))).toPoint() self.move(pos) for widget, setting in ((self.sourceLineEdit, 'Data/SourceDirectory'), (self.outputLineEdit, 'Data/OutputDirectory')): widget.setText(settings.value(setting).toString()) def closeEvent(self, event): """Save settings and exit""" settings = QSettings() for value, setting in ((self.size(), 'Dialog/Size'), (self.pos(), 'Dialog/Position'), (self.sourceDirectory, 'Data/SourceDirectory'), (self.outputDirectory, 'Data/OutputDirectory')): settings.setValue(setting, QVariant(value)) def getDirectory(self): """Opens the platform dialog to select directory""" sender = self.sender() if sender is self.sourceButton: receiver = self.sourceLineEdit elif sender is self.outputButton: receiver = self.outputLineEdit fname = QFileDialog.getExistingDirectory(self, 'Select Directory') if fname: receiver.setText(fname) def getFile(self): """Opens the platform file open dialog to select a file""" if not self.sourceDirectory: source_dir = self.sourceLineEdit.text() else: source_dir = self.sourceDirectory fname = QFileDialog.getOpenFileName(self, 'Select File', source_dir) if fname: self.fileLineEdit.setText(fname) def build(self): """Main function calling sphinx-build to generate the project""" self.statusLabel.clear() self.buildButton.setDisabled(True) self.sourceDirectory = str(self.sourceLineEdit.text().trimmed()) self.outputDirectory = str(self.outputLineEdit.text().trimmed()) if not len(self.sourceDirectory): self.logBrowser.append('Source directory cannot be empty') if not len(self.outputDirectory): self.logBrowser.append('Output directory cannot be empty') if not(len(self.sourceDirectory) or len(self.outputDirectory)): self.buildButton.setDisabled(False) return self.logBrowser.clear() self.logBrowser.append(self.formatInfoMsg('Building. Please wait...')) fname = None if self.fileRadioButton.isChecked(): fname = str(self.fileLineEdit.text().trimmed()) args = ['-b', 'html', self.sourceDirectory, self.outputDirectory] if fname: args.append(fname) self.statusLabel.setText(self.formatInfoMsg('Running sphinx-build...')) QApplication.processEvents() self.process.start(SPHINX_BUILD, args) if (not self.process.waitForFinished(-1)): msg = self.formatErrorMsg('Build Failed!') self.logBrowser.append(msg) self.statusLabel.setText(msg) self.buildButton.setEnabled(True) return QApplication.processEvents() self.buildButton.setEnabled(True) self.statusLabel.setText(self.formatInfoMsg('Finished')) def readOutput(self): """Read and append sphinx-build output to the logBrowser""" msg = str(QString(self.process.readAllStandardOutput())) self.logBrowser.append(msg) def readErrors(self): """Read and append sphinx-build errors to the logBrowser""" msg = str(QString(self.process.readAllStandardError())) self.logBrowser.append(self.formatErrorMsg(msg)) def formatErrorMsg(self, msg): """Format error messages in red color""" return self.formatMsg(msg, 'red') def formatInfoMsg(self, msg): """Format informative messages in blue color""" return self.formatMsg(msg, 'blue') def formatMsg(self, msg, color): """Format message with the given color""" msg = '<font color="%s">%s</font>' % (color, msg) return msg
class Main(plugin.Plugin): ' main class for plugin ' def initialize(self, *args, **kwargs): ' class init ' 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.Dirs | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) menu = QMenu('Clones') menu.addAction('Analyze for Code Clones here', lambda: self.make_clon()) self.locator.get_service('explorer').add_project_menu(menu, lang='all') self.group1 = QGroupBox() self.group1.setTitle(' Target ') self.outdir, self.igndir = QLineEdit(path.expanduser("~")), QLineEdit() self.outdir.setCompleter(self.completer) self.btn1 = QPushButton(QIcon.fromTheme("document-open"), ' Open ') self.btn1.clicked.connect(lambda: self.outdir.setText(str( QFileDialog.getExistingDirectory(self.dock, 'Please, Open a Target Directory...', path.expanduser("~"))))) self.btn1a = QPushButton(QIcon.fromTheme("face-smile"), 'Get from Ninja active project') self.btn1a.clicked.connect(lambda: self.outdir.setText( self.locator.get_service('explorer').get_current_project_item().path)) self.ignckb, self.ignmor = QComboBox(), QTextEdit() self.ignckb.addItems(['Single Directory', 'Multiple Directories CSV']) self.ignckb.currentIndexChanged.connect(self.on_ignore_changed) self.ignmor.hide() self.igndir.setPlaceholderText('Exclude directory') self.igndir.setCompleter(self.completer) self.btn2 = QPushButton(QIcon.fromTheme("document-open"), ' Open ') self.btn2.clicked.connect(lambda: self.igndir.setText(str( QFileDialog.getExistingDirectory(self.dock, 'Please, Open a Ignore Directory...', path.expanduser("~"))))) vboxg1 = QVBoxLayout(self.group1) for each_widget in (QLabel('<b>Target directory path: '), self.outdir, self.btn1, self.btn1a, QLabel('<b>Ignore directory path: '), self.ignckb, self.ignmor, self.igndir, self.btn2, ): vboxg1.addWidget(each_widget) self.group2 = QGroupBox() self.group2.setTitle(' Output ') self.outfle = QLineEdit(path.join(path.expanduser("~"), 'output.html')) self.outfle.setPlaceholderText('Exclude directory') self.outfle.setCompleter(self.completer) self.btn3 = QPushButton(QIcon.fromTheme("document-save"), ' Save ') self.btn3.clicked.connect(lambda: self.outfle.setText( QFileDialog.getSaveFileName(self.dock, 'Save', path.expanduser("~"), 'XML(*.xml)' if self.xmlo.isChecked() is True else 'HTML(*.html)'))) vboxg2 = QVBoxLayout(self.group2) for each_widget in (QLabel('<b>Output report file path:'), self.outfle, self.btn3): vboxg2.addWidget(each_widget) self.group3 = QGroupBox() self.group3.setTitle(' Options ') self.group3.setCheckable(True) self.group3.setGraphicsEffect(QGraphicsBlurEffect(self)) self.group3.graphicsEffect().setEnabled(False) self.group3.toggled.connect(self.toggle_options_group) self.qckb1, self.qckb2 = QCheckBox('Recursive'), QCheckBox('Time-less') self.qckb3, self.qckb4 = QCheckBox('Force Diff'), QCheckBox('Fast Mode') self.qckb5, self.tm = QCheckBox('Save a LOG file to target'), QLabel('') self.xmlo = QCheckBox('XML Output instead of HTML') self.opeo = QCheckBox('Open Clones Report when done') self.chrt = QCheckBox('LOW CPU priority for Backend Process') self.mdist, self.hdep, self.output = QSpinBox(), QSpinBox(), QTextEdit() self.ign_func = QLineEdit('test, forward, backward, Migration') self.mdist.setValue(5) self.hdep.setValue(1) self.mdist.setToolTip('''<b>Maximum amount of difference between pair of sequences in clone pair (5 default).Larger value more false positive''') self.hdep.setToolTip('''<b>Computation can be speeded up by increasing this value, but some clones can be missed (1 default)''') [a.setChecked(True) for a in (self.qckb1, self.qckb3, self.qckb5, self.chrt, self.opeo)] vboxg3 = QVBoxLayout(self.group3) for each_widget in (self.qckb1, self.qckb2, self.qckb3, self.qckb4, self.qckb5, self.chrt, self.xmlo, self.opeo, QLabel('<b>Max Distance Threshold:'), self.mdist, QLabel('<b>Max Hashing Depth:'), self.hdep, QLabel('<b>Ignore code block prefix:'), self.ign_func): vboxg3.addWidget(each_widget) self.group4, self.auto = QGroupBox(), QComboBox() self.group4.setTitle(' Automation ') self.group4.setCheckable(True) self.group4.setToolTip('<font color="red"><b>WARNING:Advanced Setting!') self.group4.toggled.connect(lambda: self.group4.hide()) self.auto.addItems(['Never run automatically', 'Run when File Saved', 'Run when File Executed', 'Run when Tab Changed', 'Run when File Opened', 'Run before File Saved']) self.auto.currentIndexChanged.connect(self.on_auto_changed) QVBoxLayout(self.group4).addWidget(self.auto) self.button = QPushButton(' Analyze for Clones ') self.button.setMinimumSize(75, 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) self.butkil = QPushButton(' Force Kill Clones ') self.butkil.clicked.connect(lambda: self.process.kill()) 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('<i>D.R.Y. principle analyzer'), self.group1, self.group2, self.group3, self.group4, QLabel('<b>Backend Logs'), self.output, self.tm, self.button, self.butkil)) 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, "Clones") QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, HELPMSG)) 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 make_clon(self): ' make clones analyze from contextual sub menu ' self.outdir.setText( self.locator.get_service('explorer').get_current_project_item().path) self.run() def run(self): ' run the actions ' self.output.clear() self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) self.tm.setText('<center><b>Last Clone: </b>' + datetime.now().isoformat().split('.')[0]) self.button.setDisabled(True) if not len(self.outdir.text()) and not len(self.outfle.text()): self.output.append(self.formatErrorMsg('ERROR: FAIL: Target empty')) self.button.setEnabled(True) return # run the subprocesses cmd = ' '.join(( 'chrt -i 0' if self.chrt.isChecked() is True else '', 'clonedigger', '' if self.qckb1.isChecked() is True else '--no-recursion', '--dont-print-time' if self.qckb2.isChecked() is True else '', '--force' if self.qckb3.isChecked() is True else '', '--fast' if self.qckb4.isChecked() is True else '', '--cpd-output' if self.xmlo.isChecked() is True else '', '' if self.xmlo.isChecked() is True else '--report-unifiers', '--distance-threshold={}'.format(self.mdist.value()), '--hashing-depth={}'.format(self.hdep.value()), '--ignore-dir="{}"'.format(self.igndir.text() if self.ignckb.currentIndex() is 0 else self.ignmor.toPlainText()), '--func-prefixes="{}"'.format(self.ign_func.text()), '--output="{}"'.format(self.outfle.text()), '--language=python', path.abspath(self.outdir.text()), )) 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:{}'.format(cmd))) self.button.setEnabled(True) return self.readOutput() self.readErrors() self.button.setEnabled(True) def _process_finished(self): """ finished sucessfully """ self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) # write a .log file on target if self.qckb5.isChecked() is True: log_file = 'ninja_clones.log' with open(path.join(str(self.outdir.text()), log_file), 'w') as log: self.output.append(self.formatInfoMsg('''INFO: OK: Writing Logs: {}'''.format(path.join(str(self.outdir.text()), log_file)))) log.write(self.output.toPlainText()) log.close() # open target output if self.opeo.isChecked() is True and self.xmlo.isChecked() is False: try: startfile(self.outfle.text()) except: Popen(["xdg-open", self.outfle.text()]) self.output.selectAll() self.output.setFocus() def toggle_options_group(self): ' toggle on off the options group ' if self.group3.isChecked() is True: [a.setChecked(True) for a in (self.qckb1, self.qckb3, self.qckb5, self.chrt, self.opeo)] self.mdist.setValue(5) self.hdep.setValue(1) self.group3.graphicsEffect().setEnabled(False) else: [a.setChecked(False) for a in (self.qckb1, self.qckb3, self.qckb5, self.chrt, self.opeo)] self.group3.graphicsEffect().setEnabled(True) def on_ignore_changed(self): 'hide or show one widget or another depending what kind of input need' if self.ignckb.currentIndex() is 0: self.igndir.show() self.btn2.show() self.ignmor.hide() else: self.igndir.hide() self.btn2.hide() self.ignmor.show() def on_auto_changed(self): ' automation connects ' if self.auto.currentIndex() is 1: self.locator.get_service('editor').fileSaved.connect(lambda: self.run()) QMessageBox.information(self.dock, __doc__, '<b>Now Actions will Run Automatically when any File is Saved !') elif self.auto.currentIndex() is 2: self.locator.get_service('editor').fileExecuted.connect(lambda: self.run()) QMessageBox.information(self.dock, __doc__, '<b>Now Actions will Run Automatically when any File is Executed !') elif self.auto.currentIndex() is 3: self.locator.get_service('editor').currentTabChanged.connect(lambda: self.run()) QMessageBox.information(self.dock, __doc__, '<b>Now Actions will Run Automatically when current Tab is Changed') elif self.auto.currentIndex() is 4: self.locator.get_service('editor').fileOpened.connect(lambda: self.run()) QMessageBox.information(self.dock, __doc__, '<b>Now Actions will Run Automatically when any File is Opened !') elif self.auto.currentIndex() is 5: self.locator.get_service('editor').beforeFileSaved.connect(lambda: self.run()) QMessageBox.information(self.dock, __doc__, '<b>Now Actions will Run Automatically before any File is Saved !') self.group4.setDisabled(True) def finish(self): ' clear when finish ' self.process.kill()
class SvnChangeListsDialog(QDialog, Ui_SvnChangeListsDialog): """ Class implementing a dialog to browse the change lists. """ def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ QDialog.__init__(self, parent) self.setupUi(self) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.process = None self.vcs = vcs self.rx_status = \ QRegExp('(.{8,9})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)\\s*') # flags (8 or 9 anything), revision, changed rev, author, path self.rx_status2 = \ QRegExp('(.{8,9})\\s+(.+)\\s*') # flags (8 or 9 anything), path self.rx_changelist = \ QRegExp('--- \\S+ .([\\w\\s]+).:\\s+') # three dashes, Changelist (translated), quote, # changelist name, quote, : @pyqtSignature("QListWidgetItem*, QListWidgetItem*") def on_changeLists_currentItemChanged(self, current, previous): """ Private slot to handle the selection of a new item. @param current current item (QListWidgetItem) @param previous previous current item (QListWidgetItem) """ self.filesList.clear() if current is not None: changelist = unicode(current.text()) if changelist in self.changeListsDict: self.filesList.addItems(sorted(self.changeListsDict[changelist])) def start(self, path): """ Public slot to populate the data. @param path directory name to show change lists for (string) """ self.changeListsDict = {} self.filesLabel.setText(self.trUtf8("Files (relative to %1):").arg(path)) self.errorGroup.hide() self.intercept = False self.path = path self.currentChangelist = "" self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) args = [] args.append('status') self.vcs.addArguments(args, self.vcs.options['global']) self.vcs.addArguments(args, self.vcs.options['status']) if '--verbose' not in self.vcs.options['global'] and \ '--verbose' not in self.vcs.options['status']: args.append('--verbose') if isinstance(path, list): self.dname, fnames = self.vcs.splitPathList(path) self.vcs.addArguments(args, fnames) else: self.dname, fname = self.vcs.splitPath(path) args.append(fname) self.process.setWorkingDirectory(self.dname) self.process.start('svn', args) procStarted = self.process.waitForStarted() if not procStarted: self.inputGroup.setEnabled(False) self.inputGroup.hide() KQMessageBox.critical(self, self.trUtf8('Process Generation Error'), self.trUtf8( 'The process %1 could not be started. ' 'Ensure, that it is in the search path.' ).arg('svn')) else: self.inputGroup.setEnabled(True) self.inputGroup.show() def __finish(self): """ Private slot called when the process finished or the user pressed the button. """ if self.process is not None and \ self.process.state() != QProcess.NotRunning: self.process.terminate() QTimer.singleShot(2000, self.process.kill) self.process.waitForFinished(3000) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.inputGroup.setEnabled(False) self.inputGroup.hide() if len(self.changeListsDict) == 0: self.changeLists.addItem(self.trUtf8("No changelists found")) self.buttonBox.button(QDialogButtonBox.Close).setFocus(Qt.OtherFocusReason) else: self.changeLists.addItems(sorted(self.changeListsDict.keys())) self.changeLists.setCurrentRow(0) self.changeLists.setFocus(Qt.OtherFocusReason) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Close): self.close() elif button == self.buttonBox.button(QDialogButtonBox.Cancel): self.__finish() def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ self.__finish() def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal. It reads the output of the process, formats it and inserts it into the contents pane. """ if self.process is not None: self.process.setReadChannel(QProcess.StandardOutput) while self.process.canReadLine(): s = unicode(self.process.readLine(), Preferences.getSystem("IOEncoding"), 'replace') if self.currentChangelist != "" and self.rx_status.exactMatch(s): file = unicode(self.rx_status.cap(5)).strip() filename = file.replace(self.path + os.sep, "") if filename not in self.changeListsDict[self.currentChangelist]: self.changeListsDict[self.currentChangelist].append(filename) elif self.currentChangelist != "" and self.rx_status2.exactMatch(s): file = unicode(self.rx_status2.cap(2)).strip() filename = file.replace(self.path + os.sep, "") if filename not in self.changeListsDict[self.currentChangelist]: self.changeListsDict[self.currentChangelist].append(filename) elif self.rx_changelist.exactMatch(s): self.currentChangelist = unicode(self.rx_changelist.cap(1)) if self.currentChangelist not in self.changeListsDict: self.changeListsDict[self.currentChangelist] = [] def __readStderr(self): """ Private slot to handle the readyReadStandardError signal. It reads the error output of the process and inserts it into the error pane. """ if self.process is not None: self.errorGroup.show() s = QString(self.process.readAllStandardError()) self.errors.insertPlainText(s) self.errors.ensureCursorVisible() def on_passwordCheckBox_toggled(self, isOn): """ Private slot to handle the password checkbox toggled. @param isOn flag indicating the status of the check box (boolean) """ if isOn: self.input.setEchoMode(QLineEdit.Password) else: self.input.setEchoMode(QLineEdit.Normal) @pyqtSignature("") def on_sendButton_clicked(self): """ Private slot to send the input to the subversion process. """ input = self.input.text() input += os.linesep if self.passwordCheckBox.isChecked(): self.errors.insertPlainText(os.linesep) self.errors.ensureCursorVisible() else: self.errors.insertPlainText(input) self.errors.ensureCursorVisible() self.process.write(input) self.passwordCheckBox.setChecked(False) self.input.clear() def on_input_returnPressed(self): """ Private slot to handle the press of the return key in the input field. """ self.intercept = True self.on_sendButton_clicked() def keyPressEvent(self, evt): """ Protected slot to handle a key press event. @param evt the key press event (QKeyEvent) """ if self.intercept: self.intercept = False evt.accept() return QDialog.keyPressEvent(self, evt)
class Main(plugin.Plugin): " Main Class " def initialize(self, *args, **kwargs): " Init Main Class " super(Main, self).initialize(*args, **kwargs) 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.desktop, self.project, menu = '', '', QMenu('Vagrant') menu.addAction('UP', lambda: self.vagrant_c('up')) menu.addAction('HALT', lambda: self.vagrant_c('halt')) menu.addAction('RELOAD', lambda: self.vagrant_c('reload')) menu.addAction('STATUS', lambda: self.vagrant_c('status')) menu.addAction('SUSPEND', lambda: self.vagrant_c('suspend')) menu.addAction('RESUME', lambda: self.vagrant_c('resume')) menu.addAction('PROVISION', lambda: self.vagrant_c('provision')) menu.addAction('PACKAGE', lambda: self.vagrant_c('package')) menu.addAction('INIT', lambda: self.vagrant_c('init')) menu.addSeparator() menu.addAction('DESTROY (!!!)', lambda: self.vagrant_c('destroy')) self.locator.get_service('explorer').add_project_menu(menu, lang='all') 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) # Proxy support, by reading http_proxy os env variable proxy_url = QUrl(environ.get('http_proxy', '')) QNetworkProxy.setApplicationProxy(QNetworkProxy(QNetworkProxy.HttpProxy if str(proxy_url.scheme()).startswith('http') else QNetworkProxy.Socks5Proxy, proxy_url.host(), proxy_url.port(), proxy_url.userName(), proxy_url.password())) \ if 'http_proxy' in environ else None self.mainwidget = QTabWidget() self.mainwidget.tabCloseRequested.connect(lambda: self.mainwidget.setTabPosition(1) if self.mainwidget.tabPosition() == 0 else self.mainwidget.setTabPosition(0)) self.mainwidget.setStyleSheet('QTabBar{font-weight:bold;}') self.mainwidget.setMovable(True) self.mainwidget.setTabsClosable(True) self.dock, self.scrollable = QDockWidget(), QScrollArea() self.scrollable.setWidgetResizable(True) self.scrollable.setWidget(self.mainwidget) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.dock.setWidget(self.scrollable) self.locator.get_service('misc').add_widget(self.dock, QIcon.fromTheme("virtualbox"), __doc__) self.tab1, self.tab2, self.tab3 = QGroupBox(), QGroupBox(), QGroupBox() self.tab4, self.tab5, self.tab6 = QGroupBox(), QGroupBox(), QGroupBox() for a, b in ((self.tab1, 'Basics'), (self.tab2, 'General Options'), (self.tab3, 'VM Package Manager'), (self.tab4, 'VM Provisioning'), (self.tab5, 'VM Desktop GUI'), (self.tab6, 'Run')): a.setTitle(b) a.setToolTip(b) self.mainwidget.addTab(a, QIcon.fromTheme("virtualbox"), b) QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, HELPMSG)) self.vmname = QLineEdit(self.get_name()) self.vmname.setPlaceholderText('type_your_VM_name_here_without_spaces') self.vmname.setToolTip('Type VM name, no spaces or special characters') self.target = QLabel('<b>Vagrant Target Folder: ' + path.join(BASE, self.vmname.text())) self.vmname.textChanged.connect(lambda: self.target.setText( '<b>Vagrant Target Folder: ' + path.join(BASE, self.vmname.text()))) self.btn1 = QPushButton(QIcon.fromTheme("face-smile-big"), 'Suggestion') self.btn1.setToolTip('Suggest me a Random VM name !') self.btn1.clicked.connect(lambda: self.vmname.setText(self.get_name())) self.vmcode, self.vmarch = QComboBox(), QComboBox() self.vmcode.addItems(['saucy', 'raring', 'quantal', 'precise']) self.vmarch.addItems(['x86_64 (amd64) 64-Bits', 'x86 (i386) 32-Bits']) vboxg1 = QVBoxLayout(self.tab1) for each_widget in (QLabel('<b>Name for VM'), self.vmname, self.btn1, QLabel('<b>Choose Ubuntu Codename for the VM:</b>'), self.vmcode, QLabel('<b>Choose Architecture for VM:'), self.vmarch, self.target): vboxg1.addWidget(each_widget) self.chrt = QCheckBox('LOW CPU priority for Backend Process') self.chttps = QComboBox() self.chttps.addItems(['https', 'http']) try: self.vinfo1 = QLabel('''<b> Vagrant Backend Version: </b> {}, <b> VirtualBox Backend Version: </b> {}. '''.format( getoutput('vagrant --version', shell=1).strip(), getoutput('vboxmanage --version', shell=1).strip())) except: self.vinfo1 = QLabel('<b>Warning: Failed to query Vagrant Backend!') self.qckb1 = QCheckBox(' Open target directory later') self.qckb1.setToolTip('Open the target directory when finished') self.qckb2 = QCheckBox(' Save a LOG file to target later') self.qckb2.setToolTip('Save a read-only .LOG file to target') self.qckb3 = QCheckBox(' NO run Headless Mode, use a Window') self.qckb3.setToolTip('Show the VM on a Window GUI instead of Headless') self.cpu, self.ram = QSpinBox(), QSpinBox() self.cpu.setRange(25, 99) self.cpu.setValue(99) self.ram.setRange(512, 4096) self.ram.setValue(1024) vboxg2 = QVBoxLayout(self.tab2) for each_widget in (self.qckb1, self.qckb2, self.qckb3, self.chrt, QLabel('<b>Max CPU Limit for VM:</b>'), self.cpu, QLabel('<b>Max RAM Limit for VM:</b>'), self.ram, QLabel('<b>Download Protocol Type:</b>'), self.chttps, self.vinfo1): vboxg2.addWidget(each_widget) self.qckb10 = QCheckBox('Run apt-get update on the created VM') self.qckb11 = QCheckBox('Run apt-get dist-upgrade on the created VM') self.qckb12 = QCheckBox('Run apt-get check on the created VM') self.qckb12 = QCheckBox('Run apt-get clean on the created VM') self.qckb13 = QCheckBox('Run apt-get autoremove on the created VM') self.qckb14 = QCheckBox('Try to Fix Broken packages if any on the VM') self.aptproxy, self.portredirect = QLineEdit(), QLineEdit('8000, 9000') self.aptproxy.setPlaceholderText(' user:password@proxyaddress:port ') vboxg3 = QVBoxLayout(self.tab3) for each_widget in (self.qckb10, self.qckb11, self.qckb12, self.qckb13, self.qckb14, QLabel('<b>Network Proxy for apt-get on the VM'), self.aptproxy, QLabel('<b>Network Port Redirects for the VM'), self.portredirect): vboxg3.addWidget(each_widget) self.aptpkg = QTextEdit('build-essential git python-pip vim mc wget') self.aptppa, self.pippkg = QLineEdit(), QTextEdit('virtualenv yolk') self.aptppa.setPlaceholderText(' ppa:ninja-ide-developers/daily ') self.requirements = QLineEdit() self.requirements.setPlaceholderText(' /full/path/to/requirements.txt ') self.requirements.setCompleter(self.completer) vboxg4 = QVBoxLayout(self.tab4) for each_widget in (QLabel('<b>Custom APT Ubuntu package'), self.aptpkg, QLabel('<b>Custom APT Ubuntu PPA:</b> '), self.aptppa, QLabel('<b>Custom PIP Python packages:</b> '), self.pippkg, QLabel('<b>Custom PIP Python requirements: '), self.requirements): vboxg4.addWidget(each_widget) self.buttonGroup = QButtonGroup() self.buttonGroup.buttonClicked[QAbstractButton].connect(self.get_de_pkg) vboxg5 = QVBoxLayout(self.tab5) for i, d in enumerate(('Ubuntu Unity', 'KDE Plasma', 'LXDE', 'XFCE')): button = QPushButton(d) button.setCheckable(True) button.setMinimumSize(75, 50) button.setToolTip(d) vboxg5.addWidget(button) self.buttonGroup.addButton(button) self.output = QTextEdit(''' We have persistent objects, they are called files. -Ken Thompson. ''') self.runbtn = QPushButton(QIcon.fromTheme("media-playback-start"), 'Start Vagrant Instrumentation Now !') self.runbtn.setMinimumSize(75, 50) self.runbtn.clicked.connect(self.build) glow = QGraphicsDropShadowEffect(self) glow.setOffset(0) glow.setBlurRadius(99) glow.setColor(QColor(99, 255, 255)) self.runbtn.setGraphicsEffect(glow) self.stopbt = QPushButton(QIcon.fromTheme("media-playback-stop"), 'Stop Vagrant') self.stopbt.clicked.connect(lambda: self.process.stop()) self.killbt = QPushButton(QIcon.fromTheme("application-exit"), 'Force Kill Vagrant') self.killbt.clicked.connect(lambda: self.process.kill()) vboxg6 = QVBoxLayout(self.tab6) for each_widget in (QLabel('<b>Multiprocess Output Logs'), self.output, self.runbtn, self.stopbt, self.killbt): vboxg6.addWidget(each_widget) [a.setChecked(True) for a in (self.qckb1, self.qckb2, self.qckb3, self.qckb10, self.qckb11, self.qckb12, self.qckb13, self.qckb14, self.chrt)] self.mainwidget.setCurrentIndex(5) def get_de_pkg(self, button): ' get package from desktop name ' if button.text() in 'Ubuntu Unity': self.desktop = 'ubuntu-desktop' elif button.text() in 'KDE Plasma': self.desktop = 'kubuntu-desktop' elif button.text() in 'LXDE': self.desktop = 'lubuntu-desktop' else: self.desktop = 'xubuntu-desktop' return self.desktop def get_name(self): ' return a random name of stars, planets and moons of solar system ' return choice((getuser(), 'sun', 'mercury', 'venus', 'earth', 'mars', 'neptun', 'ceres', 'pluto', 'haumea', 'makemake', 'eris', 'moon', 'saturn', 'europa', 'ganymede', 'callisto', 'mimas', 'enceladus', 'tethys', 'dione', 'rhea', 'titan', 'iapetus', 'miranda', 'ariel', 'umbriel', 'titania', 'oberon', 'triton', 'charon', 'orcus', 'io', 'ixion', 'varuna', 'quaoar', 'sedna', 'methone', 'jupiter', )) def readOutput(self): """Read and append output to the logBrowser""" self.output.append(str(self.process.readAllStandardOutput())) 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 build(self): """Main function calling vagrant to generate the vm""" self.output.setText('') self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) self.runbtn.setDisabled(True) base = path.join(BASE, self.vmname.text()) try: self.output.append(self.formatInfoMsg('INFO: Dir: {}'.format(base))) makedirs(base) except: self.output.append(self.formatErrorMsg('ERROR:Target Folder Exist')) self.output.append(self.formatInfoMsg('INFO: Changed {}'.format(base))) chdir(base) try: self.output.append(self.formatInfoMsg('INFO:Removing Vagrant file')) remove(path.join(base, 'Vagrantfile')) except: self.output.append(self.formatErrorMsg('ERROR:Remove Vagrant file')) self.output.append(self.formatInfoMsg(' INFO: OK: Runing Vagrant Init')) cmd1 = getoutput('chrt --verbose -i 0 vagrant init', shell=True) self.output.append(self.formatInfoMsg('INFO:OK:Completed Vagrant Init')) self.output.append(self.formatInfoMsg('INFO: Command: {}'.format(cmd1))) cfg = CONFIG.format(self.vmname.text(), self.vmname.text(), self.chttps.currentText(), self.vmcode.currentText(), self.vmcode.currentText(), 'amd64' if self.vmarch.currentIndex() is 0 else 'i386', '\n'.join(([ ' config.vm.network :forwarded_port, host: {}, guest: {}'.format( a, a) for a in str(self.portredirect.text()).split(',')])), VBOXGUI.format(self.ram.value(), self.cpu.value()) if self.qckb3.isChecked() is True else '') self.output.append(self.formatInfoMsg('INFO:OK:Config: {}'.format(cfg))) with open(path.join(base, 'Vagrantfile'), 'w') as f: f.write(cfg) self.output.append(self.formatInfoMsg('INFO: Writing Vagrantfile')) f.close() proxy = APTGET_PROXY.format(self.aptproxy.text(), self.aptproxy.text(), self.aptproxy.text(), self.aptproxy.text(), self.aptproxy.text(), self.aptproxy.text()) prv = '\n'.join(('#!/usr/bin/env bash', '# -*- coding: utf-8 -*-', linesep * 2, "PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' ; HISTSIZE=5000", '# Vagrant Bootstrap Provisioning generated by Vagrant Ninja!', linesep, proxy if len(self.aptproxy.text()) >= 5 else '', 'add-apt-repository -s -y {}'.format(str(self.aptppa.text()).strip()), 'apt-get -V -u -m -y update' if self.qckb10.isChecked() is True else '', 'apt-get -y -m dist-upgrade' if self.qckb11.isChecked() is True else '', 'apt-get -y -m autoremove' if self.qckb11.isChecked() is True else '', 'apt-get -y clean' if self.qckb11.isChecked() is True else '', 'dpkg --configure -a' if self.qckb11.isChecked() is True else '', 'apt-get -y -f install' if self.qckb11.isChecked() is True else '', 'apt-get -y check' if self.qckb11.isChecked() is True else '', 'apt-get -y --force-yes install {}'.format(self.aptpkg.toPlainText()), 'pip install --verbose {}'.format(self.pippkg.toPlainText()), 'pip install --verbose -r {}'.format(self.requirements.text()), 'apt-get -y --force-yes -m install {}'.format(self.desktop), linesep, 'git config --global user.name "{}"'.format(getuser()), 'git config --global color.branch auto', 'git config --global color.diff auto', 'git config --global color.interactive auto', 'git config --global color.status auto', 'git config --global credential.helper cache', 'git config --global user.email "{}@gmail.com"'.format(getuser()), 'git config --global push.default simple', 'ufw status ; service ufw stop ; ufw disable ; swapoff --verbose --all', 'export LANGUAGE=en_US.UTF-8', 'export LANG=en_US.UTF-8', 'export LC_ALL=en_US.UTF-8', 'locale-gen en_US.UTF-8', 'dpkg-reconfigure locales', )) self.output.append(self.formatInfoMsg('INFO:OK:Script: {}'.format(prv))) with open(path.join(base, 'bootstrap.sh'), 'w') as f: f.write(prv) self.output.append(self.formatInfoMsg('INFO: Writing bootstrap.sh')) f.close() try: chmod('bootstrap.sh', 0775) # Py2 self.output.append(self.formatInfoMsg('INFO: bootstrap.sh is 775')) except: chmod('bootstrap.sh', 0o775) # Py3 self.output.append(self.formatInfoMsg('INFO: bootstrap.sh is o775')) self.output.append(self.formatInfoMsg(''' INFO: OK: Vagrant Up needs time, depends on your Internet Connection Speed !''')) self.output.append(self.formatInfoMsg('INFO: OK: Running Vagrant Up !')) self.process.start('{}vagrant up'.format('chrt --verbose -i 0 ' if self.chrt.isChecked() is True else '')) if not self.process.waitForStarted(): self.output.append(self.formatErrorMsg('ERROR: FAIL: Vagrant Fail')) self.runbtn.setEnabled(True) return self.runbtn.setEnabled(True) chdir(path.expanduser("~")) def _process_finished(self): """finished sucessfully""" self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) if self.qckb2.isChecked() is True: LOG_FILE = path.join(BASE, self.vmname.text(), 'vagrant_ninja.log') with open(LOG_FILE, 'w') as f: self.output.append(self.formatInfoMsg('INFO: OK: Writing .LOG')) f.write(self.output.toPlainText()) f.close() if self.qckb1.isChecked() is True: self.output.append(self.formatInfoMsg('INFO:Opening Target Folder')) try: startfile(BASE) except: Popen(["xdg-open", BASE]) chdir(path.expanduser("~")) def vagrant_c(self, option): ' run the choosed menu option, kind of quick-mode ' self.output.setText('') self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) self.runbtn.setDisabled(True) chdir(path.abspath( self.locator.get_service('explorer').get_current_project_item().path)) self.process.start('chrt --verbose -i 0 vagrant {}'.format(option)) if not self.process.waitForStarted(): self.output.append(self.formatErrorMsg('ERROR: FAIL: Vagrant Fail')) self.runbtn.setEnabled(True) return self.runbtn.setEnabled(True) self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) chdir(path.expanduser("~")) def finish(self): ' clear when finish ' self.process.kill()
class Window(QWidget): def __init__(self): QWidget.__init__(self) self.rawstr = r"""(?:^.*Track .*?\d*\D*)(\d{1,})(?:\D*of.*?)(\d{1,})(?:.*?MB written.*$)""" self.compile_obj = re.compile(self.rawstr, re.MULTILINE) self.textBrowser = QTextBrowser(self) self.lineEdit = QLineEdit(self) self.startButton = QPushButton(self.tr("Start"), self) self.stopButton = QPushButton(self.tr("Stop"), self) self.stopButton.setEnabled(False) self.list1 = QStringList() self.connect(self.lineEdit, SIGNAL("returnPressed()"), self.startCommand) self.connect(self.startButton, SIGNAL("clicked()"), self.startCommand) self.connect(self.stopButton, SIGNAL("clicked()"), self.stopCommand) layout = QGridLayout(self) layout.setSpacing(8) layout.addWidget(self.textBrowser, 0, 0) layout.addWidget(self.lineEdit, 1, 0) layout.addWidget(self.startButton, 1, 1) layout.addWidget(self.stopButton, 1, 2) self.process = QProcess() self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.readOutput) self.connect(self.process, SIGNAL("readyReadStandardError()"), self.readErrors) self.connect(self.process, SIGNAL("finished(int)"), self.resetButtons) def startCommand(self): a=self.lineEdit.text().split(" ") self.process.start(a.first(), a.mid(1)) self.startButton.setEnabled(False) self.stopButton.setEnabled(True) self.textBrowser.clear() if self.process.exitCode(): self.textBrowser.setText( QString("*** Failed to run %1 ***").arg(self.lineEdit.text()) ) self.resetButtons() return def stopCommand(self): self.resetButtons() self.process.terminate() QTimer.singleShot(5000, self.process, SLOT("kill()")) def readOutput(self): a= self.process.readAllStandardOutput().data() match_obj = self.compile_obj.search(a) if match_obj: all_groups = match_obj.groups() group_1 = float(match_obj.group(1)) group_2 = float(match_obj.group(2)) g=int(group_1*100.0/group_2) if group_1: self.textBrowser.append(QString(str(g))) def readErrors(self): a= self.process.readAllStandardError().data() self.textBrowser.append("error: " + QString(a)) def resetButtons(self, i): self.startButton.setEnabled(True) self.stopButton.setEnabled(False)
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 RestEditor(WithSingleIO, QWidget): """Restructredtext editor """ def __init__(self, params, parent=None): QWidget.__init__(self, parent) self.setMinimumWidth(300) self.setMinimumHeight(300) # create widgets self._editor_widget = mixin( WithFind, WithMqEditIO, WithBasicIdentationManager, WithLineHighlight, WithFixedFont, WithLineNumbers, WithViewPortMargins, WithWordCompletionMulty_, WithCompletion, QPlainTextEdit)(self) self.webview = QWebView(self) #self.webview.load(QUrl("/home/maiquel/develop/developing/main/qt/qadoc/bin/__builds/documents.html")) self.splitter = QSplitter(Qt.Horizontal) self.splitter.addWidget(self._editor_widget) self.splitter.addWidget(self.webview) self.splitter.setSizes([self.size().width(), self.size().width()]) self.splitterv = QSplitter(Qt.Vertical) self.splitterv.addWidget(self.splitter) self.log_widget = QPlainTextEdit() self.splitterv.addWidget(self.log_widget) layout = QVBoxLayout(self) layout.addWidget(self.splitterv) layout.setMargin(0) self.setLayout(layout) # proc_compile self.proc_compile = QProcess() self.proc_compile.finished.connect(self.proc_compile_finished) self.proc_compile.error.connect(self.proc_compile_error) self.proc_compile.readyReadStandardOutput.connect(self.proc_compile_readyReadStandardOutput) self.proc_compile.readyReadStandardError.connect(self.proc_compile_readyReadStandardError) WithSingleIO.__init__(self, params) def bw_add_command_list(self, command_list): command_list += [ ("generate preview restructuretext", "pp", 1.0, "self.get_current_widget().command_generate_preview('rst2html')"), ] super(RestEditor, self).bw_add_command_list(command_list) self._editor_widget.bw_add_command_list(command_list) command_list += [ ("focus editor", "fe", 0.5, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self._editor_widget.setFocus();"), ("focus preview", "fp", 0.5, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self.webview.setFocus();"), ] def command_generate_preview(self, backend): self.command_save_file() if not os.path.exists(TEMP_DIR): os.mkdir(TEMP_DIR) temp_source_file = open(TEMP_DIR + 'pr.rst','wt') temp_source_file.write(self._editor_widget.toPlainText()) temp_source_file.close() self.compile(backend + " --stylesheet=./widgets/rst2html.style " + TEMP_DIR + "pr.rst" + " " + self.get_html_output()) if self.webview.url() != QUrl("file://" + self.get_html_output()): self.webview.load(QUrl(self.get_html_output())) def compile(self, command): self.log(command) self.proc_compile.start(command) def bw_lock_command_window(self): return self._editor_widget.completer.popup().isVisible() def focusInEvent(self, focus_event): super(RestEditor, self).focusInEvent(focus_event) self._editor_widget.setFocus() def get_html_output(self): return TEMP_DIR + "pr.html" def proc_compile_finished(self, result, exit_status): self.log("compilation finished") if self.webview.url().toString() == "": self.webview.load(QUrl(self.get_html_output())) else: self.webview.reload() def proc_compile_error(self, q_process_error): self.log("compilation error") print(q_process_error) def proc_compile_readyReadStandardOutput(self): result = self.proc_compile.readAllStandardOutput(); self.log(result) def proc_compile_readyReadStandardError(self): result = str(self.proc_compile.readAllStandardError()) self.log(result) def log(self, text): self.log_widget.appendPlainText(text)
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 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 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 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) self.editor_s = self.locator.get_service('editor') 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.infile = QLineEdit(path.expanduser("~")) 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 ['py', 'pyw', 'txt', '*']]))))) self.output = QTextEdit() vboxg0 = QVBoxLayout(self.group0) for each_widget in (self.infile, self.open, self.output): vboxg0.addWidget(each_widget) self.group1 = QGroupBox() self.group1.setTitle(' General ') self.group1.setCheckable(True) self.group1.setGraphicsEffect(QGraphicsBlurEffect(self)) self.group1.graphicsEffect().setEnabled(False) self.group1.toggled.connect(self.toggle_gral_group) self.ckgrl1 = QCheckBox('Create standalone executable') self.ckgrl2 = QCheckBox('Use Python debug') self.ckgrl3 = QCheckBox('Force compilation for MS Windows') self.ckgrl4 = QCheckBox('When compiling, disable the console window') self.ckgrl5 = QCheckBox('Use link time optimizations if available') self.ckgrl6 = QCheckBox('Force the use of clang') self.ckgrl7 = QCheckBox('Allow minor devitations from Python behaviour') self.ckgrl8 = QCheckBox('Warnings implicit exceptions at compile time') self.pyver, self.jobs = QComboBox(), QSpinBox() self.pyver.addItems(['2.7', '2.6', '3.2', '3.3']) self.jobs.setValue(1) self.jobs.setMaximum(12) self.jobs.setMinimum(1) vboxg1 = QVBoxLayout(self.group1) for each_widget in (self.ckgrl1, self.ckgrl2, self.ckgrl3, self.ckgrl4, self.ckgrl5, self.ckgrl6, self.ckgrl7, self.ckgrl8, QLabel('Python Version to Target'), self.pyver, QLabel('Multi-Processing Parallel Workers'), self.jobs): vboxg1.addWidget(each_widget) try: each_widget.setToolTip(each_widget.text()) except: pass self.group2 = QGroupBox() self.group2.setTitle(' Recursion Control ') self.ckrec0 = QCheckBox('Descend to imported modules from standard lib') self.ckrec1 = QCheckBox('Force not descend to any imported modules') self.ckrec2 = QCheckBox('Try to descend into all imported modules') vboxg2 = QVBoxLayout(self.group2) for each_widget in (self.ckrec0, self.ckrec1, self.ckrec2): vboxg2.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group3 = QGroupBox() self.group3.setTitle(' Execution after compilation ') self.ckexe0 = QCheckBox('Execute created binary (or import the module)') self.ckexe1 = QCheckBox('When executing binary dont reset PYTHONPATH') vboxg2 = QVBoxLayout(self.group3) for each_widget in (self.ckexe0, self.ckexe1): vboxg2.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group4, self.dumptree = QGroupBox(), QTextEdit() self.group4.setTitle(' Dump of internal tree ') QVBoxLayout(self.group4).addWidget(self.dumptree) self.group5 = QGroupBox() self.group5.setTitle(' Code generation ') self.chdmp1 = QCheckBox('Statements shall have their line numbers set') self.chdmp2 = QCheckBox('Disable all unnecessary Python optimization') vboxg5 = QVBoxLayout(self.group5) for each_widget in (self.chdmp1, self.chdmp2): vboxg5.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group6 = QGroupBox() self.group6.setTitle(' Output ') self.outdir = QLineEdit(path.expanduser("~")) self.outdir.setPlaceholderText(' /full/path/to/target/directory ') self.outdir.setCompleter(self.completer) self.open2 = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.open2.setCursor(QCursor(Qt.PointingHandCursor)) self.open2.clicked.connect(lambda: self.outdir.setText(str( QFileDialog.getExistingDirectory(self.dock, "Open Target Folder", path.expanduser("~"))))) self.ckcgn2 = QCheckBox('Remove build dir after compile module or exe') vboxg6 = QVBoxLayout(self.group6) for each_widget in (QLabel('Target Output Directory'), self.outdir, self.open2, self.ckcgn2): vboxg6.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group7 = QGroupBox() self.group7.setTitle(' Debug ') self.ckdbg1 = QCheckBox('Execute self checks to find errors in Nuitka') self.ckdbg2 = QCheckBox('Keep debug info in resulting file') self.ckdbg3 = QCheckBox('Traced execution output') self.ckdbg4 = QCheckBox('Allow compile edited C++ file, debug changes') self.ckdbg5 = QCheckBox('Use experimental features') vboxg7 = QVBoxLayout(self.group7) for each_widget in (self.ckdbg1, self.ckdbg2, self.ckdbg3, self.ckdbg4, self.ckdbg5): vboxg7.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group8 = QGroupBox() self.group8.setTitle(' Tracing ') self.cktrc1 = QCheckBox('Show Scons in non-quiet mode, showing command') self.cktrc2 = QCheckBox('Show Progress information and statistics') self.cktrc3 = QCheckBox('Show Verbose output details') vboxg8 = QVBoxLayout(self.group8) for each_widget in (self.cktrc1, self.cktrc2, self.cktrc3): vboxg8.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group9 = QGroupBox() self.group9.setTitle(' Extras ') self.group9.setCheckable(True) self.group9.toggled.connect(self.group9.hide) self.nice = QSpinBox() self.nice.setValue(20) self.nice.setMaximum(20) self.nice.setMinimum(0) self.ckxtr1 = QCheckBox('Open Target Directory later') self.ckxtr2 = QCheckBox('Save a LOG file to target later') self.ckxtr3 = QCheckBox('Save SH Bash script to reproduce Nuitka build') try: self.vinfo = QLabel('<center> <b> Nuitka Backend Version: </b>' + getoutput('nuitka --version',).strip()) except: self.vinfo = QLabel('<b>Warning: Failed to query Nuitka Backend!') vboxg9 = QVBoxLayout(self.group9) for each_widget in (QLabel('Backend CPU Priority'), self.nice, self.ckxtr1, self.ckxtr2, self.ckxtr3, self.vinfo): vboxg9.addWidget(each_widget) self.group10 = QGroupBox() self.group10.setTitle(' Documentation ') self.group10.setCheckable(True) self.group10.toggled.connect(self.group10.hide) vboxg10 = QVBoxLayout(self.group10) for each_widget in (QLabel('''<a href= "file:///usr/share/doc/nuitka/README.pdf.gz"> <small><center> Nuitka User Documentation Local PDF </a>'''), QLabel('''<a href= "file:///usr/share/doc/nuitka/Developer_Manual.pdf.gz"> <small><center> Nuitka Developer Documentation Local PDF </a>'''), QLabel('''<a href="http://nuitka.net/doc/user-manual.html"> <small><center> Nuitka User Documentation On Line HTML </a>'''), QLabel('''<a href="http://nuitka.net/doc/developer-manual.html"> <small><center> Nuitka Developer Documentation On Line HTML </a>''') ): vboxg10.addWidget(each_widget) each_widget.setOpenExternalLinks(True) each_widget.setTextInteractionFlags(Qt.LinksAccessibleByMouse) [a.setChecked(True) for a in (self.ckgrl1, self.ckgrl2, self.ckgrl4, self.ckgrl5, self.ckgrl6, self.ckgrl7, self.ckgrl8, self.ckrec0, self.ckrec1, self.ckrec2, self.ckexe1, self.ckcgn2, self.ckdbg1, self.ckdbg3, self.ckdbg4, self.ckdbg5, self.cktrc1, self.cktrc2, self.cktrc3, self.ckxtr1, self.ckxtr2, self.ckxtr3,)] self.button = QPushButton(QIcon.fromTheme("face-cool"), 'Compile Python') 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) 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>Python Code to Binary Executable Compiler'), self.group0, self.group6, self.group1, self.group2, self.group3, self.group4, self.group5, self.group7, self.group8, self.group9, self.group10, 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, "Nuitka") QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, HELPMSG)) def run(self): ' run the compile ' target = path.abspath(str(self.infile.text()).strip()) self.button.setDisabled(True) self.output.clear() self.output.show() self.output.setFocus() self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) self.output.append(self.formatInfoMsg(' INFO: Dumping Internal Tree')) try: self.dumptree.setPlainText( getoutput('nuitka --dump-tree {}'.format(target))) self.dumptree.setMinimumSize(100, 500) except: self.output.append(self.formatErrorMsg('ERROR:FAIL: Internal Tree')) self.output.append(self.formatInfoMsg(' INFO: OK: Parsing Arguments')) cmd = ' '.join(('nice --adjustment={} nuitka'.format(self.nice.value()), # output '--remove-output' if self.ckcgn2.isChecked() is True else '', # general '--exe' if self.ckgrl1.isChecked() is True else '', '--python-debug' if self.ckgrl2.isChecked() is True else '', '--verbose' if self.cktrc3.isChecked() is True else '', '--windows-target' if self.ckgrl3.isChecked() is True else '', '--windows-disable-console' if self.ckgrl4.isChecked() is True else '', '--lto' if self.ckgrl5.isChecked() is True else '', '--clang' if self.ckgrl6.isChecked() is True else '', '--improved' if self.ckgrl7.isChecked() is True else '', '--warn-implicit-exceptions' if self.ckgrl8.isChecked() is True else '', # recursion control '--recurse-stdlib' if self.ckrec0.isChecked() is True else '', '--recurse-none' if self.ckrec1.isChecked() is True else '', '--recurse-all' if self.ckrec2.isChecked() is True else '', # execution after compilation '--execute' if self.ckexe0.isChecked() is True else '', '--keep-pythonpath' if self.ckexe1.isChecked() is True else '', # code generation '--code-gen-no-statement-lines' if self.chdmp1.isChecked() is True else '', '--no-optimization' if self.chdmp2.isChecked() is True else '', # debug '--debug' if self.ckdbg1.isChecked() is True else '', '--unstripped' if self.ckdbg2.isChecked() is True else '', '--trace-execution' if self.ckdbg3.isChecked() is True else '', '--c++-only' if self.ckdbg4.isChecked() is True else '', '--experimental' if self.ckdbg5.isChecked() is True else '', # tracing '--show-scons' if self.cktrc1.isChecked() is True else '', '--show-progress' if self.cktrc2.isChecked() is True else '', '--verbose' if self.cktrc3.isChecked() is True else '', # non boolean parametrization '--python-version={}'.format(self.pyver.currentText()), '--jobs={}'.format(self.jobs.value()), '--output-dir="{}"'.format(self.outdir.text()), target)) self.output.append(self.formatInfoMsg(' INFO: Command: {}'.format(cmd))) self.output.append(self.formatInfoMsg(' INFO: OK: Starting to Compile')) self.process.start(cmd) if not self.process.waitForStarted(): self.output.append(self.formatErrorMsg('ERROR: FAIL: Compile Fail')) self.output.append(self.formatErrorMsg('ERROR:FAIL:{}'.format(cmd))) self.button.setEnabled(True) return # write a .sh bash script file on target if self.ckxtr3.isChecked() is True: sh_file = 'nuitka_compile_python_to_cpp.sh' with open(path.join(str(self.outdir.text()), sh_file), 'w') as _sh: self.output.append(self.formatInfoMsg('''INFO: OK: Writing Bash: {}'''.format(sh_file))) _sh.write('#!/usr/bin/env bash {}{}'.format(linesep, cmd)) _sh.close() self.output.append(self.formatInfoMsg('INFO: OK: Bash chmod: 775')) try: chmod(path.join(str(self.outdir.text()), sh_file), 0775) # Py2 except: chmod(path.join(str(self.outdir.text()), sh_file), 0o775) # Py3 def _process_finished(self): """sphinx-build finished sucessfully""" self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now()))) if self.ckxtr2.isChecked() is True: log_file = 'nuitka_ninja.log' with open(path.join(str(self.outdir.text()), log_file), 'w') as log: self.output.append(self.formatInfoMsg('''INFO: OK: Writing LOG: {}'''.format(log_file))) log.write(self.output.toPlainText()) if self.ckxtr1.isChecked() is True: try: startfile(path.abspath(str(self.outdir.text()))) except: Popen(["xdg-open", path.abspath(str(self.outdir.text()))]) self.button.setDisabled(False) self.output.show() self.output.setFocus() self.output.selectAll() def toggle_gral_group(self): ' toggle on or off the checkboxes ' if self.group1.isChecked() is True: [a.setChecked(True) for a in (self.ckgrl1, self.ckgrl2, self.ckgrl4, self.ckgrl5, self.ckgrl6, self.ckgrl7, self.ckgrl8)] self.group1.graphicsEffect().setEnabled(False) else: [a.setChecked(False) for a in (self.ckgrl1, self.ckgrl2, self.ckgrl4, self.ckgrl5, self.ckgrl6, self.ckgrl7, self.ckgrl8)] self.group1.graphicsEffect().setEnabled(True) def readOutput(self): """Read and append sphinx-build output to the logBrowser""" self.output.append(str(self.process.readAllStandardOutput())) def readErrors(self): """Read and append sphinx-build 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)
class NetWidget(QWidget): def __init__(self,parent = None): super(NetWidget,self).__init__(parent) self.setStyleSheet("font-size : 16px")#设置整体的字体大小 self.auto = False self.pro = QProcess(self) # self.tipDlg = TipDialog() # self.tipDlg.setModal(True)#引入tipdlg,并且将这个窗口设置为最前端窗口,且后面窗口无法操作 #初始化comBox控件,并且为其添加选项 self.comBox = QComboBox() self.comBox.setFixedWidth(120) self.comBox.insertItem(0, self.tr("ping")) self.comBox.insertItem(1, self.tr("ifconfig")) self.comBox.insertItem(2, self.tr("display")) #self.comBox.insertItem(3, self.tr("traceroute")) self.comBox.insertItem(4, self.tr("top")) self.connect(self.comBox, SIGNAL('activated(QString)'),self.onActivated)#设置combBox为活动的,与函数关联 """ #初始话控件设置 #lineEdit,固定长度 #runButton,显示字符串,信号量 #pingLabel,当前显示字符 #textBrower """ self.lineEdit = QLineEdit() self.lineEdit.setContextMenuPolicy(Qt.NoContextMenu) self.lineEdit.setFixedWidth(250) self.runButton = QPushButton(self.tr("Run")) self.runButton.setStyleSheet("background: rgb(7,87,198); color: white; width: 70px; height: 20px;font-size : 16px;") self.connect(self.runButton, SIGNAL("clicked()"),self.runButton_clicked) self.pingLabel = QLabel()#初始话,之后在函数操作中会改变 self.pingLabel.setText(self.tr("Tip:please input the IP address of pinging,then get the result with clicking the button")) self.textBrowser = QTextBrowser() """ #布局一上,横向布局 #将comBox,lineEdit,runButton添加到布局中 #设置前面空为20和后面空为280 """ hLayout1 = QHBoxLayout() hLayout1.addSpacing(20) hLayout1.addWidget(self.comBox) hLayout1.addWidget(self.lineEdit) hLayout1.addWidget(self.runButton) #hLayout1.addStretch() hLayout1.addSpacing(280) #布局二中,横向布局 #将pingLabel添加到布局中,并且诶设置前面的空白为20 hLayout2 = QHBoxLayout() hLayout2.addSpacing(20) hLayout2.addWidget(self.pingLabel) #布局三下 #将textBrower添加爱到布局中,并且设置前面空白为20,后面空白为60,控件的大小自适应 hLayout3 = QHBoxLayout() hLayout3.addSpacing(20) hLayout3.addWidget(self.textBrowser) hLayout3.addSpacing(60) #主题布局总,纵向布局 #将之上的三个布局添加到总布局中,并且设置布局间空间为20,最下面的空白为40 mainLayout = QVBoxLayout() mainLayout.addSpacing(20) mainLayout.addLayout(hLayout1) mainLayout.addSpacing(20) mainLayout.addLayout(hLayout2) mainLayout.addSpacing(20) mainLayout.addLayout(hLayout3) mainLayout.addSpacing(40) self.setLayout(mainLayout) self.thread = MyThread() self.connect(self.thread,SIGNAL("getoutput"),self.append) def append(self,actionType): self.textBrowser.clear() self.textBrowser.append(actionType) #cursor = QTextCursor() #self.runButton.setText(self.tr("Stop")) cursor = self.textBrowser.textCursor() cursor.movePosition(QTextCursor.Start) self.textBrowser.setTextCursor(cursor) #changeLabel = QLabel() def onActivated(self): language = StoreInfoParser.instance().getLanguage() m_pTranslator = QTranslator() exePath = "./" if language == "chinese": QmName = "zh_CN.qm" else: QmName = "en_US.qm" if(m_pTranslator.load(QmName, exePath)): QCoreApplication.instance().installTranslator(m_pTranslator) """#comBox的相应函数,随着comBox中字符串的改变,分别控制pingLabel的显示,以及lineEdit和textBrower的显示清除和可用状态 #如果comBox当前的字符串文字为ping #pingLabel的文字设置为"提示:请在文本框中输入要ping的目标地址,然后点击执行获取结果",保持当前大小 #lineEdit中内容清除,设置为不可用 #textBrower清空""" if(self.comBox.currentText() == "Ping" or self.comBox.currentText() == "ping"): self.pingLabel.setText(self.tr("Tip:please input the IP address of pinging,then get the result with clicking the button")) self.pingLabel.adjustSize() self.lineEdit.clear() self.lineEdit.setDisabled(False) self.textBrowser.clear() #如果comBox当前的字符串文字为ifconfig #类上所说 elif(self.comBox.currentText() == "ifconfig"): self.pingLabel.setText(self.tr("Tip:get the net information")) self.pingLabel.adjustSize() self.lineEdit.clear() self.lineEdit.setEnabled(False) self.textBrowser.clear() #如果comBox当前的字符串文字为display elif(self.comBox.currentText() == "display"): self.pingLabel.setText(self.tr("Tip:get the resolution information")) self.pingLabel.adjustSize() self.lineEdit.clear() self.lineEdit.setEnabled(False) self.textBrowser.clear() elif(self.comBox.currentText() == "top"): self.pingLabel.setText(self.tr("Tip:run tom command")) self.pingLabel.adjustSize() self.lineEdit.setEnabled(False) self.lineEdit.clear() self.textBrowser.clear() #按钮的响应函数 def runButton_clicked(self): language = StoreInfoParser.instance().getLanguage() m_pTranslator = QTranslator() exePath = "./" if language == "chinese": QmName = "zh_CN.qm" else: QmName = "en_US.qm" if(m_pTranslator.load(QmName, exePath)): QCoreApplication.instance().installTranslator(m_pTranslator) #self.pro = QProcess(self)#外部程序使用声明 desktop = QApplication.desktop()#获得桌面 self.textBrowser.clear()#清除 cmdstr = QString() center = QString() goal = QString() #comBox当前text为ping if (self.comBox.currentText() == "Ping" or self.comBox.currentText() == "ping"): if (self.runButton.text() == self.tr("Run")) : center = self.lineEdit.text().trimmed() if not center: InfoHintDialog(self.tr("please input the IP address")).exec_() # self.tipDlg.setTip(self.tr("请输入ping地址!!!")) # self.tipDlg.show() # self.tipDlg.move((desktop.width()-self.tipDlg.width())/2,(desktop.height()-self.tipDlg.height())/2) self.runButton.setText(self.tr("Run")) else: self.comBox.setDisabled(True) self.pro = QProcess(self) self.runButton.setText(self.tr("stop ping")) cmdstr = "ping " +center self.textBrowser.clear() self.textBrowser.append(self.tr(" ping ")+center+self.tr(" result:")) else: self.comBox.setDisabled(False) self.runButton.setText(self.tr("Run")) self.pro.close() elif(self.comBox.currentText() == "ifconfig"): self.pro = QProcess(self) self.lineEdit.clear() self.lineEdit.setEnabled(False) self.textBrowser.clear() cmdstr = "ifconfig" # #如果comBox当前为traceroute # elif(self.comBox.currentText() == "traceroute"): # goal = self.lineEdit.text() # if (self.runButton.text() == u"执行"): # if( goal.isEmpty() or goal.isNull() ): # InfoHintDialog(u'请输入tracer地址:').exec_() # # self.tipDlg.setTip(self.tr("请输入tracer地址:")) # # self.tipDlg.show() # # self.tipDlg.move((desktop.width()-self.tipDlg.width())/2,(desktop.height()-self.tipDlg.height())/2) # # # #QMessageBox.information(self,self.tr("错误"),self.tr("请输入traceroute的目标地址")) # #return # else: # self.proc = QProcess(self) # #self.textBrowser.clear() # cmdstrc = "traceroute -n "+ goal # self.proc.start(cmdstrc) # self.connect(self.proc, SIGNAL("readyReadStandardOutput()"),self.readR) # self.connect(self.proc, SIGNAL("readyReadStandardError()"),self.readErrorR) # if self.proc.waitForStarted(10) == True: # self.comBox.setDisabled(True) # self.runButton.setText(self.tr("停止执行")) # else: # self.runButton.setText(self.tr("执行")) # self.comBox.setDisabled(False) # self.proc.close() # #如果comBox当前为display elif (self.comBox.currentText() == "display"): self.pro = QProcess(self) cmdstr = "../lib/ccr_jytcapi display" self.textBrowser.clear() #如果当前命令cmdstr不为空,则 elif (self.comBox.currentText() == "top"): if self.runButton.text() == self.tr("Run") : self.thread.start() self.comBox.setDisabled(True) self.runButton.setText(self.tr("stop top")) else: self.textBrowser.clear() self.thread.auto = False #self.thread.destroyed() self.comBox.setDisabled(False) self.runButton.setText(self.tr("Run")) if (cmdstr != ""): self.pro.start(cmdstr)#开启执行命令 self.connect(self.pro, SIGNAL("readyReadStandardOutput()"),self.read)#读取执行正常输出槽函数 self.connect(self.pro, SIGNAL("readyReadStandardError()"),self.readError)#执行异常槽函数 #读取控制台输出 def read(self): res = QString.fromLocal8Bit(self.pro.readAllStandardOutput()) self.textBrowser.append(res)#添加到text框 #读取错误 def readError(self): res = QString.fromLocal8Bit(self.pro.readAllStandardError()) self.textBrowser.append(res) def readR(self): res = QString.fromLocal8Bit(self.proc.readAllStandardOutput()) #self.textBrowser.clear() self.textBrowser.append(res) def readErrorR(self): res = QString.fromLocal8Bit(self.proc.readAllStandardError()) self.textBrowser.append(res) def updateWindow(self): if self.pro.isOpen(): self.pro.close() self.thread.auto = False self.comBox.setDisabled(False) self.comBox.setCurrentIndex(0) self.runButton.setText((self.tr("Run"))) self.pingLabel.setText(self.tr("Tip:please input the IP address of pinging,then get the result with clicking the button")) self.textBrowser.clear()
class Window(QWidget): __pyqtSignals__ = ("burningProgress(int)") __pyqtSignals__ = ("burningFinished()") __pyqtSignals__ = ("burningStartingIn(int)") __pyqtSignals__ = ("burningError(int)") def __init__(self): QWidget.__init__(self) self.rawstr3 = r"""(?:^Current:\s)(.*)""" self.rawstr2 = r"""(?:^.*?)(\d)(?:\sseconds\.$)""" self.rawstr = r"""(?:^.*Track .*?\d*\D*)(\d{1,})(?:\D*of.*?)(\d{1,})(?:.*?MB written.*$)""" self.compile_obj = re.compile(self.rawstr, re.MULTILINE) self.compile_obj_2 = re.compile(self.rawstr2, re.MULTILINE) self.compile_obj_3 = re.compile(self.rawstr3, re.MULTILINE) self.process = QProcess() self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.readOutput) self.connect(self.process, SIGNAL("readyReadStandardError()"), self.readErrors) self.connect(self.process, SIGNAL("finished(int)"), self.resetButtons) self.connect(self, SIGNAL("burningProgress(int)"), self.readProgress) self.noError=True def blankCommand(self): print "blankCDRW" b=QString("cdrecord -v dev=1000,0,0 --blank=fast") a=b.split(" ") self.process.start(a.first(), a.mid(1)) if self.process.exitCode(): print "exitCode" self.resetButtons() return def startCommand(self, isofile): print "startCommand" b=QString("cdrecord -v -pad speed=8 dev=/dev/cdrom "+isofile) a=b.split(" ") self.process.start(a.first(), a.mid(1)) if self.process.exitCode(): print "exitCode" self.resetButtons() return def stopCommand(self, i): self.resetButtons(i) self.process.terminate() QTimer.singleShot(5000, self.process, SLOT("kill()")) def readOutput(self): a= self.process.readAllStandardOutput().data() match_obj = self.compile_obj.search(a) match_obj_2 = self.compile_obj_2.search(a) match_obj_3 = self.compile_obj_3.search(a) print a if match_obj: all_groups = match_obj.groups() group_1 = float(match_obj.group(1)) group_2 = float(match_obj.group(2)) g=int(group_1*100.0/group_2) if group_1: self.emit(SIGNAL("burningProgress(int)"), g) if match_obj_2: group_1 = int(match_obj_2.group(1)) print "group_1: "+str(group_1) if group_1: self.emit(SIGNAL("burningStartingIn(int)"), group_1) if match_obj_3: group_1 = match_obj_3.group(1) if group_1 == "none": print "NO MEDIA" self.stopCommand(334) if a=="Re-load disk and hit \<CR\>": print "Non writable disc" self.stopCommand() def readProgress(self, g): print g def readErrors(self): a= self.process.readAllStandardError().data() print "ERORR: "+a if a.startswith("cdrecord: Try to load media by hand"): print "ERROR: Non writable disc" self.stopCommand(333) def resetButtons(self, i): print "resetButtons" print i if i==0: if self.noError: self.emit(SIGNAL("burningFinished()")) if i==333: self.noError=False self.emit(SIGNAL("burningError(int)"), i) if i==334: self.noError=False self.emit(SIGNAL("burningError(int)"), i) if i==335: self.noError=False self.emit(SIGNAL("burningCanceled(int)"), i)
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: if output: self.syncMessage.emit(output)
def _performMonitor(self): """ Protected method implementing the monitoring action. This method populates the statusList member variable with a list of strings giving the status in the first column and the path relative to the project directory starting with the third column. The allowed status flags are: <ul> <li>"A" path was added but not yet comitted</li> <li>"M" path has local changes</li> <li>"O" path was removed</li> <li>"R" path was deleted and then re-added</li> <li>"U" path needs an update</li> <li>"Z" path contains a conflict</li> <li>" " path is back at normal</li> </ul> @return tuple of flag indicating successful operation (boolean) and a status message in case of non successful operation (QString) """ self.shouldUpdate = False process = QProcess() args = QStringList() args.append('status') if not Preferences.getVCS("MonitorLocalStatus"): args.append('--show-updates') args.append('--non-interactive') args.append('.') process.setWorkingDirectory(self.projectDir) process.start('svn', args) procStarted = process.waitForStarted() if procStarted: finished = process.waitForFinished(300000) if finished and process.exitCode() == 0: output = \ unicode(process.readAllStandardOutput(), self.__ioEncoding, 'replace') states = {} for line in output.splitlines(): if self.rx_status1.exactMatch(line): flags = str(self.rx_status1.cap(1)) path = self.rx_status1.cap(3).trimmed() elif self.rx_status2.exactMatch(line): flags = str(self.rx_status2.cap(1)) path = self.rx_status2.cap(5).trimmed() else: continue if flags[0] in "ACDMR" or \ (flags[0] == " " and flags[-1] == "*"): if flags[-1] == "*": status = "U" else: status = flags[0] if status == "C": status = "Z" # give it highest priority elif status == "D": status = "O" if status == "U": self.shouldUpdate = True name = unicode(path) states[name] = status try: if self.reportedStates[name] != status: self.statusList.append("%s %s" % (status, name)) except KeyError: self.statusList.append("%s %s" % (status, name)) for name in self.reportedStates.keys(): if name not in states: self.statusList.append(" %s" % name) self.reportedStates = states return True, \ self.trUtf8("Subversion status checked successfully (using svn)") else: process.kill() process.waitForFinished() return False, QString(process.readAllStandardError()) else: process.kill() process.waitForFinished() return False, self.trUtf8("Could not start the Subversion process.")
class Main(plugin.Plugin): " Main Class " def initialize(self, *args, **kwargs): " Init Main Class " super(Main, self).initialize(*args, **kwargs) 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.process, self.mainwidget = QProcess(), QTabWidget() 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) self.mainwidget.tabCloseRequested.connect(lambda: self.mainwidget.setTabPosition(1) if self.mainwidget.tabPosition() == 0 else self.mainwidget.setTabPosition(0)) self.mainwidget.setStyleSheet('QTabBar{font-weight:bold;}') self.mainwidget.setMovable(True) self.mainwidget.setTabsClosable(True) self.dock, self.scrollable = QDockWidget(), QScrollArea() self.scrollable.setWidgetResizable(True) self.scrollable.setWidget(self.mainwidget) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.dock.setWidget(self.scrollable) self.locator.get_service('misc').add_widget(self.dock, QIcon.fromTheme("face-sad"), __doc__) self.tab1, self.tab2, self.tab3 = QGroupBox(), QGroupBox(), QGroupBox() self.tab4, self.tab5, self.tab6 = QGroupBox(), QGroupBox(), QGroupBox() for a, b in ((self.tab1, 'Basics'), (self.tab2, 'Coverage'), (self.tab3, 'Extensions'), (self.tab5, 'Regex'), (self.tab4, 'Paths'), (self.tab6, 'Run')): a.setTitle(b) a.setToolTip(b) self.mainwidget.addTab(a, QIcon.fromTheme("face-sad"), b) QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, ''.join((__doc__, __version__, __license__, 'by', __author__)))) groupl, groupr, co = QWidget(), QWidget(), QGroupBox() self.qckb1 = QCheckBox('Open target directory later') self.qckb2 = QCheckBox('Save a LOG file to target later') self.qckb3 = QCheckBox('Verbose operation') self.qckb4 = QCheckBox('Force Stop on Error') self.qckb5 = QCheckBox('Scan Executable files for Tests') vboxgl, vboxgr = QVBoxLayout(groupl), QVBoxLayout(groupr) for a in (self.qckb1, self.qckb2, self.qckb3, self.qckb4, self.qckb5): vboxgl.addWidget(a) a.setToolTip(a.text()) self.qckb6 = QCheckBox('No Byte Compile to .PYC or Delete .PYC later') self.qckb7 = QCheckBox('Dont touch sys.path when running tests') self.qckb8 = QCheckBox('Traverse all paths of a package') self.qckb9 = QCheckBox('Dont capture STDOUT, print STDOUT on the fly') self.qckb10 = QCheckBox('Clear all Logging handlers') for a in (self.qckb6, self.qckb7, self.qckb8, self.qckb9, self.qckb10): vboxgr.addWidget(a) a.setToolTip(a.text()) vboxcon, self.framew = QHBoxLayout(co), QComboBox() [vboxcon.addWidget(a) for a in (groupl, groupr)] self.chrt = QCheckBox('LOW CPU priority for Backend Process') self.framew.addItems(['nosetests', 'PyTest', 'DocTest', 'Unittest', 'Django_Test', 'Django-Nose', 'None']) self.framew.currentIndexChanged.connect(lambda: #FIXME refactor for 3 QMessageBox.information(self.dock, __doc__, '<b>Only Nose for now')) self.framew.currentIndexChanged.connect(lambda: #FIXME refactor for 3 self.framew.setCurrentIndex(0)) vboxg1 = QVBoxLayout(self.tab1) for each_widget in (QLabel('<b>Framework'), self.framew, self.chrt, co): vboxg1.addWidget(each_widget) self.t2ck1, self.t2sp1 = QCheckBox('Activate Coverage'), QSpinBox() self.t2ck2 = QCheckBox('Erase previously collected Coverage before run') self.t2ck3 = QCheckBox('Include all tests modules in Coverage reports') self.t2ck4 = QCheckBox('Include all python files on working directory') self.t2ck5 = QCheckBox('Produce HTML Coverage reports information') self.t2ck6 = QCheckBox('Include Branch Coverage in Coverage reports') self.t2sp1.setRange(10, 90) self.t2sp1.setValue(75) vboxg2 = QVBoxLayout(self.tab2) for each_widget in (QLabel('<b>Min Percentage'), self.t2sp1, self.t2ck1, self.t2ck2, self.t2ck3, self.t2ck4, self.t2ck5, self.t2ck6): vboxg2.addWidget(each_widget) groupi, groupd, vbxg3 = QGroupBox(), QGroupBox(), QHBoxLayout(self.tab3) vboxgi, vboxgd = QVBoxLayout(groupi), QVBoxLayout(groupd) self.t3ck1 = QCheckBox('Activate DocTest to find and run doctests') self.t3ck2 = QCheckBox('Look for any doctests in tests modules too') self.t3ck3 = QCheckBox('Activate isolation (Do Not use with Coverage!)') self.t3ck4 = QCheckBox('Use Detailed Errors, evaluate failed asserts') for a in (self.t3ck1, self.t3ck2, self.t3ck3, self.t3ck4): vboxgi.addWidget(a) a.setToolTip(a.text()) self.t3ck5 = QCheckBox('Disable special handling of SkipTest exception') self.t3ck6 = QCheckBox('Run the tests that failed in the last test run') self.t3ck7 = QCheckBox('Use AllModules, Collect tests from all modules') self.t3ck8 = QCheckBox('Collect tests names only, do Not run any tests') for a in (self.t3ck5, self.t3ck6, self.t3ck7, self.t3ck8): vboxgd.addWidget(a) a.setToolTip(a.text()) [vbxg3.addWidget(a) for a in (groupi, groupd)] self.t4le1, self.t4le2 = QLineEdit(), QLineEdit(path.expanduser("~")) self.t4le1.setCompleter(self.completer) self.t4le2.setCompleter(self.completer) self.t4le1.setPlaceholderText(' /full/path/to/a/folder/ ') self.t4le2.setPlaceholderText(' /full/path/to/a/folder/ ') le1b = QPushButton(QIcon.fromTheme("folder-open"), 'Open') le1b.setMinimumSize(50, 50) le1b.clicked.connect(lambda: self.t4le1.setText( QFileDialog.getExistingDirectory(None, '', path.expanduser("~")))) le2b = QPushButton(QIcon.fromTheme("folder-open"), 'Open') le2b.clicked.connect(lambda: self.t4le2.setText( QFileDialog.getExistingDirectory(None, '', path.expanduser("~")))) vboxg4 = QVBoxLayout(self.tab4) for a in (QLabel('<b>Directory to look for Tests'), self.t4le1, le1b, QLabel('<b>Directory to generate HTML Coverage'), self.t4le2, le2b): vboxg4.addWidget(a) a.setToolTip(a.text()) self.t5le1 = QLineEdit(r'(?:^|[\b_\./-])[Tt]est') self.t5le2 = QLineEdit() self.t5le3, vboxg5 = QLineEdit(), QVBoxLayout(self.tab5) r = QPushButton('Reset') r.clicked.connect(lambda: self.t5le1.setText(r'(?:^|[\b_\./-])[Tt]est')) for a in (QLabel('<b>Matching Name Regex to be test'), self.t5le1, r, QLabel('<b>Force Include Regex Tests'), self.t5le2, QLabel('<b>Force Exclude Regex Tests'), self.t5le3): vboxg5.addWidget(a) a.setToolTip(a.text()) self.output = QTextEdit(''' Engineering is the art of making what you want from things you can get. -Dhobi''') self.runbtn = QPushButton(QIcon.fromTheme("face-sad"), 'Start Testing!') self.runbtn.setMinimumSize(75, 50) self.runbtn.clicked.connect(self.run) glow = QGraphicsDropShadowEffect(self) glow.setOffset(0) glow.setBlurRadius(99) glow.setColor(QColor(99, 255, 255)) self.runbtn.setGraphicsEffect(glow) self.kbt = QPushButton(QIcon.fromTheme("application-exit"), 'Kill') self.kbt.clicked.connect(lambda: self.process.kill()) vboxg6 = QVBoxLayout(self.tab6) for each_widget in (QLabel('Logs'), self.output, self.runbtn, self.kbt): vboxg6.addWidget(each_widget) [a.setChecked(True) for a in (self.chrt, self.qckb2, self.qckb3, self.qckb10, self.t2ck1, self.t2ck2, self.t2ck5, self.t3ck1, self.t3ck4)] self.mainwidget.setCurrentIndex(4) def readOutput(self): """Read and append output to the logBrowser""" self.output.append(str(self.process.readAllStandardOutput())) def readErrors(self): """Read and append errors to the logBrowser""" self.output.append(str(self.process.readAllStandardError())) def run(self): """Main function calling vagrant to generate the vm""" if not len(self.t4le1.text()): QMessageBox.information(self.dock, __doc__, '<b style="color:red">ERROR: Target Folder can not be Empty !') return self.output.clear() self.output.append('INFO: OK: Starting at {}'.format(datetime.now())) self.runbtn.setDisabled(True) #nose = True if self.framew.currentText() in 'nosetests' else False cmd = ' '.join(('chrt -i 0' if self.chrt.isChecked() else '', # tab 1 self.framew.currentText(), '--verbose' if self.qckb3.isChecked() else '--quiet', '--stop' if self.qckb4.isChecked() else '', '--exe' if self.qckb5.isChecked() else '--noexe', '--no-byte-compile' if self.qckb6.isChecked() else '', '--no-path-adjustment' if self.qckb7.isChecked() else '', '--traverse-namespace' if self.qckb8.isChecked() else '', '--nocapture' if self.qckb9.isChecked() else '', '--logging-clear-handlers' if self.qckb10.isChecked() else '', # tab 2 '--with-coverage' if self.t2ck1.isChecked() else '', '--cover-erase' if self.t2ck2.isChecked() else '', '--cover-tests' if self.t2ck3.isChecked() else '', '--cover-inclusive' if self.t2ck4.isChecked() else '', '--cover-html' if self.t2ck5.isChecked() else '--cover-xml', '--cover-branches' if self.t2ck6.isChecked() else '', '--cover-min-percentage={}'.format(self.t2sp1.value()), # tab 3 '--with-doctest' if self.t3ck1.isChecked() else '', '--doctest-tests' if self.t3ck2.isChecked() else '', '--with-isolation' if self.t3ck3.isChecked() else '', '--detailed-errors' if self.t3ck4.isChecked() else '', '--no-skip' if self.t3ck5.isChecked() else '', '--failed' if self.t3ck6.isChecked() else '', '--all-modules' if self.t3ck7.isChecked() else '', '--collect-only' if self.t3ck8.isChecked() else '', # tab 4 '--where="{}"'.format(self.t4le1.text()), '--cover-html-dir="{}"'.format(self.t4le2.text()) if self.t2ck5.isChecked() else '--cover-xml-file={}'.format(path.join(self.t4le2.text(), 'coverage_ninja.xml')), # tab 5 '--match="{}"'.format(self.t5le1.text().encode('utf-8')) if len(self.t5le1.text()) else '', '--include="{}"'.format(self.t5le2.text()) if len(self.t5le2.text()) else '', '--exclude="{}"'.format(self.t5le3.text()) if len(self.t5le3.text()) else '', )) self.output.append('INFO: OK: Command: {}'.format(cmd)) with open(path.join(self.t4le2.text(), 'tests_run_ninja.sh'), 'w') as f: self.output.append('INFO: OK : Writing tests_run_ninja.sh') f.write('#!/usr/bin/env bash\n# -*- coding: utf-8 -*-\n\n' + cmd) try: chmod(path.join(self.t4le2.text(), 'tests_run_ninja.sh'), 0775) except: chmod(path.join(self.t4le2.text(), 'tests_run_ninja.sh'), 0o775) self.output.append('INFO: OK: Running Tests !') self.process.start(cmd) if not self.process.waitForStarted(): self.output.append('ERROR: FAIL: Unkown Error !') self.runbtn.setEnabled(True) return self.runbtn.setEnabled(True) def _process_finished(self): """finished sucessfully""" self.output.append('INFO: OK: Finished at {}'.format(datetime.now())) if self.qckb2.isChecked() is True: with open(path.join(self.t4le2.text(), 'test_ninja.log'), 'w') as f: self.output.append('INFO: OK: Writing .LOG') f.write(self.output.toPlainText()) if self.qckb1.isChecked() is True: self.output.append('INFO:Opening Target Folder') try: startfile(self.t4le2.text()) except: Popen(["xdg-open", self.t4le2.text()]) def finish(self): ' clear when finish ' self.process.kill()
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 Main(plugin.Plugin): ' main class for plugin ' def initialize(self, *args, **kwargs): ' class init ' 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.Dirs | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) # menu menu = QMenu('VirtualEnv') menu.addAction('Make VirtualEnv here', lambda: self.make_virtualenv()) self.locator.get_service('explorer').add_project_menu(menu, lang='all') self.group1 = QGroupBox() self.group1.setTitle(' Paths ') self.outdir = QLineEdit(path.expanduser("~")) self.outdir.setPlaceholderText('Target Directory for Virtualenv files') self.outdir.setCompleter(self.completer) self.btn1 = QPushButton(QIcon.fromTheme("document-open"), ' Open ') self.btn1.clicked.connect(lambda: self.outdir.setText(str( QFileDialog.getExistingDirectory(self.dock, 'Please, Open a Target Directory for the Python VirtualEnv...', path.expanduser("~"))))) self.srcdir, self.prefx = QLineEdit(), QLineEdit() self.srcdir.setPlaceholderText( 'Extra search path to look for setuptools/distribute/pip') self.srcdir.setToolTip(''' Specify Extra search path to look for setuptools/distribute/pip. Defaults to Empty, then the setting is ignored.Defaults are OK.''') self.srcdir.setCompleter(self.completer) self.btn2 = QPushButton(QIcon.fromTheme("document-open"), ' Open ') self.btn2.setToolTip( 'Specify Extra search path to look for setuptools/distribute/pip') self.btn2.clicked.connect(lambda: self.srcdir.setText(str( QFileDialog.getExistingDirectory(self.dock, 'Please, Open a Extra search path to look for setuptools/pip...', path.expanduser("~"))))) self.prefx.setPlaceholderText('Prompt prefix for this environment') self.prefx.setToolTip(''' Specify a custom alternative prompt prefix for this environment. Defaults to Empty,this is optional,short prefix are recommended.''') self.btn3 = QPushButton(QIcon.fromTheme("face-smile-big"), 'Suggestion') self.btn3.setToolTip('Suggest me a Random CLI prompt prefix !') self.btn3.clicked.connect(lambda: self.prefx.setText(choice((getuser(), 'tesla', 'einstein', 'turing', 'ritchie', 'darwin', 'curie', 'planck', 'lovelace', 'dijsktra', 'galileo', 'schroedinger', 'perlman', 'hopper', 'newton', 'pasteur', 'maxwell', 'aristotle', 'volta', 'mendelev', 'bohr', 'crick', 'watson', 'archimedes', 'nash', 'fermi', 'dirac', 'feynman', 'kepler', 'copernicus', 'lorentz', 'faraday', 'heisenberg', )))) vboxg1 = QVBoxLayout(self.group1) for each_widget in ( QLabel(' Target directory dath: '), self.outdir, self.btn1, QLabel(' Extra search path: '), self.srcdir, self.btn2, QLabel(' CLI Prompt prefix (Optional): '), self.prefx, self.btn3): vboxg1.addWidget(each_widget) self.group2 = QGroupBox() self.group2.setTitle(' Options ') self.group2.setCheckable(True) self.group2.setGraphicsEffect(QGraphicsBlurEffect(self)) self.group2.graphicsEffect().setEnabled(False) self.group2.toggled.connect(self.toggle_options_group) self.qckb1, self.combo1 = QCheckBox(' Use Debug'), QDoubleSpinBox() self.qckb2 = QCheckBox(' Clear out the target directory') self.qckb3 = QCheckBox(' System-wide Python Packages') self.qckb4 = QCheckBox(' Unzip Setuptool or Distribute to virtualenv') self.qckb5 = QCheckBox(' Force the use of SetupTools') self.qckb6 = QCheckBox(' Never download packages') self.qckb7 = QCheckBox(' Delete .PYC files from virtualenv') self.qckb8 = QCheckBox(' Open target directory later') self.qckb9 = QCheckBox(' Save a LOG file to target later') self.qckb10 = QCheckBox(' No install PIP in the new virtualenv') self.qckb11 = QCheckBox('Save Bash script to reproduce virtenv later') self.chrt = QCheckBox('LOW CPU priority for Backend Process') self.combo1.setValue(2.7) self.combo1.setMaximum(3.4) self.combo1.setMinimum(2.4) self.combo1.setDecimals(1) self.combo1.setSingleStep(0.1) try: self.vinfo = QLabel('<small><b> Virtualenv Version: </b>' + getoutput('virtualenv --version', shell=1).strip()) except: self.vinfo = QLabel('Warning: Failed to query Virtualenv Backend!') [a.setChecked(True) for a in (self.qckb1, self.qckb4, self.qckb7, self.chrt, self.qckb8, self.qckb9, self.qckb11)] vboxg2 = QVBoxLayout(self.group2) for each_widget in (self.qckb1, self.qckb2, self.qckb3, self.qckb4, self.qckb5, self.qckb6, self.qckb7, self.qckb8, self.qckb9, self.qckb10, self.qckb11, QLabel(' Python interpreter version: '), self.combo1, QLabel(' Backend CPU priority: '), self.chrt): vboxg2.addWidget(each_widget) self.button = QPushButton(' Make Virtualenv ') self.button.setCursor(QCursor(Qt.PointingHandCursor)) self.button.setMinimumSize(75, 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) self.output = QTextEdit(''' " Let the future tell the truth, and evaluate each one according to his work and accomplishments. The present is theirs; the future, for which I really worked, is mine. " -Nikola Tesla. ''') 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((self.group1, self.group2, QLabel('Backend Logs'), self.output, self.vinfo, 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, "Virtualenv") QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, HELPMSG)) def readOutput(self): """Read and append sphinx-build output to the logBrowser""" self.output.append(str(self.process.readAllStandardOutput()).strip()) def readErrors(self): """Read and append sphinx-build 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 make_virtualenv(self): ' make virtualenv from contextual sub menu ' self.outdir.setText(self.ex_locator.get_current_project_item().path) self.run() def run(self): ' run the actions ' self.output.clear() self.output.append(self.formatInfoMsg( 'INFO: OK: Starting at {}'.format(datetime.now()))) self.button.setDisabled(True) # Parse Values arg0 = '' if self.qckb10.isChecked() is False else '--no-pip ' arg1 = '--quiet ' if self.qckb1.isChecked() is False else '--verbose ' arg2 = '' if self.qckb2.isChecked() is False else '--clear ' arg3 = '' if self.qckb3.isChecked() is False else '--system-site-packages ' arg4 = '' if self.qckb4.isChecked() is False else '--unzip-setuptools ' arg5 = '' if self.qckb5.isChecked() is False else '--setuptools ' arg6 = '' if self.qckb6.isChecked() is False else '--never-download ' # if the target is empty return if not len(str(self.outdir.text()).strip()): self.output.append(self.formatErrorMsg('ERROR: FAIL: Target empty')) self.button.setEnabled(True) return else: self.output.append(self.formatInfoMsg( 'INFO: OK: Output Directory is {}'.format(self.outdir.text()))) # prefix prf = str(self.prefx.text()).upper().strip().replace(' ', '') arg10 = '' if prf is '' else '--prompt="{}_" '.format(prf) self.output.append(self.formatInfoMsg('INFO: Prefix: {}'.format(arg10))) # extra search dir src = str(self.srcdir.text()).strip() arg11 = '' if src is '' else '--extra-search-dir="{}" '.format(src) self.output.append(self.formatInfoMsg(' INFO: Extra: {}'.format(arg11))) self.output.append(self.formatInfoMsg( ' INFO: OK: Write Logs ?: {} '.format(self.qckb9.isChecked()))) self.output.append(self.formatInfoMsg( ' INFO: OK: Open Directory ?: {} '.format(self.qckb8.isChecked()))) # run the subprocesses cmd = '{}virtualenv {}{}{}{}{}{}{}-p python{} {}{} {}'.format( 'chrt --verbose -i 0 ' if self.chrt.isChecked() is True else '', arg0, arg1, arg2, arg3, arg4, arg5, arg6, self.combo1.value(), arg11, arg10, str(self.outdir.text()).strip()) 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 # write a .sh bash script file on target if self.qckb11.isChecked() is True: sh_file = 'create_virtualenv.sh' with open(path.join(str(self.outdir.text()), sh_file), 'w') as _sh: self.output.append(self.formatInfoMsg('''INFO: OK: Writing Bash: {}'''.format(path.join(str(self.outdir.text()), sh_file)))) _sh.write('#!/usr/bin/env bash' + linesep + cmd) _sh.close() self.output.append(self.formatInfoMsg('INFO: OK: Bash chmod: 775')) try: chmod(path.join(str(self.outdir.text()), sh_file), 0775) # Py2 except: chmod(path.join(str(self.outdir.text()), sh_file), 0o775) # Py3 self.readOutput() self.readErrors() self.button.setEnabled(True) def _process_finished(self): """ finished sucessfully """ self.output.append(self.formatInfoMsg( 'INFO: OK: Finished at {}'.format(datetime.now()))) # remove all *.PYC bytecode if self.qckb7.isChecked() is True: self.output.append(self.formatInfoMsg(' INFO: OK: Removing *.PYC ')) self.output.append(self.formatInfoMsg(' INFO: This takes a moment')) [remove(path.join(root, f)) for root, f in list(itertools.chain(* [list(itertools.product([root], files)) for root, dirs, files in walk(str(self.outdir.text()).strip())])) if f.endswith(('.pyc', '.PYC')) and not f.startswith('.')] # write a .log file on target if self.qckb9.isChecked() is True: log_file = 'virtualenv_gui.log' with open(path.join(str(self.outdir.text()), log_file), 'w') as log: self.output.append(self.formatInfoMsg('''INFO: OK: Writing Logs: {}'''.format(path.join(str(self.outdir.text()), log_file)))) log.write(self.output.toPlainText()) log.close() # open target dir if self.qckb8.isChecked() is True: try: startfile(str(self.outdir.text())) except: Popen(["xdg-open", str(self.outdir.text())]) self.output.selectAll() self.output.setFocus() def toggle_options_group(self): ' toggle on off the options group ' if self.group2.isChecked() is True: [a.setChecked(True) for a in (self.qckb1, self.qckb4, self.qckb7, self.chrt, self.qckb8, self.qckb9, self.qckb11)] self.combo1.setValue(2.7) self.group2.graphicsEffect().setEnabled(False) else: [a.setChecked(False) for a in (self.qckb1, self.qckb4, self.qckb7, self.chrt, self.qckb8, self.qckb9, self.qckb11)] self.group2.graphicsEffect().setEnabled(True) def finish(self): ' clear when finish ' self.process.kill()
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 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: if output: self.syncMessage.emit(output)
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_error) self.sourceDirectory, self.outputDirectory = None, None self.group2 = QGroupBox() self.group2.setTitle(' Paths ') self.inf = QLineEdit(path.expanduser("~")) self.inf.setPlaceholderText(' /full/path/to/directory ') self.out, self.fle = QLineEdit(path.expanduser("~")), QLineEdit() self.out.setPlaceholderText(' /full/path/to/directory ') self.fle.setPlaceholderText(' /full/path/to/single/file ') 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.inf.setCompleter(self.completer) self.out.setCompleter(self.completer) self.fle.setCompleter(self.completer) self.open1 = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.open1.setCursor(QCursor(Qt.PointingHandCursor)) self.open1.clicked.connect(lambda: self.inf.setText(str( QFileDialog.getExistingDirectory(self.dock, "Open Source Directory", path.expanduser("~"))))) self.open2 = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.open2.setCursor(QCursor(Qt.PointingHandCursor)) self.open2.clicked.connect(lambda: self.out.setText(str( QFileDialog.getExistingDirectory(self.dock, "Open Target Directory", path.expanduser("~"))))) self.open3 = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.open3.setCursor(QCursor(Qt.PointingHandCursor)) self.open3.clicked.connect(lambda: self.fle.setText(str( QFileDialog.getOpenFileName(self.dock, "Open a Target File...", path.expanduser("~"), ';;'.join(['{}(*.{})'.format(e.upper(), e) for e in ['py', 'pyw', '*']]))))) vboxg2 = QVBoxLayout(self.group2) for each_widget in ( QLabel('Source Directory Project:'), self.inf, self.open1, QLabel(' Target Directory Outputs: '), self.out, self.open2, QLabel(' Source Single File (Optional):'), self.fle, self.open3, ): vboxg2.addWidget(each_widget) self.group1 = QGroupBox() self.group1.setTitle(' Options ') self.chckbx1 = QCheckBox(' Inject Twitter Bootstrap CSS3 ') self.chckbx1.toggled.connect(self.toggle_styles_group) self.chckbx2 = QCheckBox(' Warn all missing references ') self.chckbx3 = QCheckBox(' Open Docs when done building ') self.chckbx4 = QCheckBox('Save Bash script to reproduce Sphinx Builds') vboxg1 = QVBoxLayout(self.group1) for each_widget in (self.chckbx1, self.chckbx2, self.chckbx3, self.chckbx4): vboxg1.addWidget(each_widget) each_widget.setChecked(True) self.group3 = QGroupBox() self.group3.setTitle(' Styles ') self.group3.setGraphicsEffect(QGraphicsBlurEffect(self)) self.group3.graphicsEffect().setEnabled(False) self.basecss, self.fontcss = QComboBox(), QComboBox() self.basecss.addItems(['slate', 'united', 'spacelab', 'superhero', 'simplex', 'journal', 'flatly', 'cyborg', 'cosmo', 'cerulean']) self.fontcss.addItems(['Ubuntu Light', 'Oxygen', 'Roboto', 'Droid Sans', 'Open Sans', 'Pacifico', 'Rancho', 'Arvo', 'Fresca', 'Graduate']) self.backcss = QComboBox() self.backcss.addItems(['shattered', 'retina_wood', 'ricepaper', 'brickwall', 'sneaker_mesh_fabric', 'diagonales_decalees', 'noisy_grid', 'pw_pattern', 'escheresque', 'diamond_upholstery']) vboxg3 = QVBoxLayout(self.group3) for each_widget in (QLabel('<b>Twitter Bootstrap Theme'), self.basecss, QLabel('<b>Fonts Family'), self.fontcss, QLabel('<b>Background Seamless Tiled Pattern'), self.backcss): vboxg3.addWidget(each_widget) self.output = QTextEdit(''' My brain is something more than merely mortal; As time will show. - Ada Lovelace ''') self.output.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.button = QPushButton('Document My Code') self.button.setCursor(QCursor(Qt.PointingHandCursor)) self.button.setMinimumSize(75, 50) self.button.clicked.connect(self.build) glow = QGraphicsDropShadowEffect(self) glow.setOffset(0) glow.setBlurRadius(99) glow.setColor(QColor(99, 255, 255)) self.button.setGraphicsEffect(glow) 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((self.group2, self.group1, self.group3, QLabel(linesep + ' Logs: '), 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, "Sphinx") QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, HELPMSG)) def readOutput(self): """Read and append sphinx-build output to the logBrowser""" self.output.append(str(self.process.readAllStandardOutput())) def readErrors(self): """Read and append sphinx-build 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 build(self): """Main function calling sphinx-build to generate the project""" self.output.setText('') self.output.append(self.formatInfoMsg( 'INFO: OK: Starting at {}'.format(datetime.now()))) self.button.setDisabled(True) self.sourceDirectory = str(self.inf.text()).strip() self.outputDirectory = str(self.out.text()).strip() if not len(self.sourceDirectory): self.output.append(' ERROR: FAIL: Source directory cannot be empty') else: self.output.append(self.formatInfoMsg( 'INFO: OK: Source Directory is {}'.format(self.sourceDirectory))) if not len(self.outputDirectory): self.output.append(' ERROR: FAIL: Output directory cannot be empty') else: self.output.append(self.formatInfoMsg( 'INFO: OK: Output Directory is {}'.format(self.outputDirectory))) if not(len(self.sourceDirectory) or len(self.outputDirectory)): self.button.setDisabled(False) return self.output.append(self.formatInfoMsg('INFO:OK: Building. Please wait')) args = ['-n' if self.chckbx2.isChecked() is True else '', '-b', 'html', self.sourceDirectory, self.outputDirectory] if len(self.fle.text()): args.append(str(self.fle.text()).strip().replace('file:///', '/')) self.output.append(self.formatInfoMsg( 'INFO: OK: Source Single File is {}'.format(self.fle.text()))) self.output.append(self.formatInfoMsg('INFO:OK: Running sphinx-build!')) self.process.start('sphinx-build', args) if not self.process.waitForStarted(): self.output.append(self.formatErrorMsg('ERROR: FAIL: Build Failed')) self.output.append(self.formatErrorMsg( 'ERROR: FAIL: Failed with Arguments: {} '.format(args))) self.button.setEnabled(True) return # write a .sh bash script file on target if self.chckbx4.isChecked() is True: sh_file = 'build_sphinx_documentation.sh' with open(path.join(self.sourceDirectory, sh_file), 'w') as _sh: self.output.append(self.formatInfoMsg('''INFO: OK: Writing Bash: {}'''.format(path.join(self.sourceDirectory, sh_file)))) _sh.write('#!/usr/bin/env bash {}'.format(linesep) + 'sphinx-build {}'.format(' '.join(args))) _sh.close() self.output.append(self.formatInfoMsg('INFO: OK: Bash chmod: 775')) try: chmod(path.join(self.sourceDirectory, sh_file), 0775) # Py2 except: chmod(path.join(self.sourceDirectory, sh_file), 0o775) # Py3 self.button.setEnabled(True) def _process_finished(self): """sphinx-build finished sucessfully""" self.output.append(self.formatInfoMsg( 'INFO: OK: Finished at {}'.format(datetime.now()))) if self.chckbx1.isChecked() is True: with open(path.join(self.outputDirectory, '_static', 'default.css'), 'a') as f: css = CSS3.replace('CSSWEBFONT', str(self.fontcss.currentText()) ).replace('CSSBACKGR', str(self.backcss.currentText()) ).replace('CSSCUSTOM', str(self.basecss.currentText())) f.write(css) f.close() if self.chckbx3.isChecked() is True: call('xdg-open ' + path.join(self.outputDirectory, 'index.html'), shell=True) def toggle_styles_group(self): ' toggle on or off the styles checkboxes ' try: if self.chckbx1.isChecked() is True: self.group3.graphicsEffect().setEnabled(False) self.group3.setEnabled(True) else: self.group3.graphicsEffect().setEnabled(True) self.group3.setEnabled(False) except: pass
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 PylintWidget(QWidget): """ Pylint widget """ DATAPATH = get_conf_path('.pylint.results') VERSION = '1.0.2' def __init__(self, parent, max_entries=100): QWidget.__init__(self, parent) self.output = None self.error_output = None self.max_entries = max_entries self.data = [self.VERSION] if osp.isfile(self.DATAPATH): try: data = cPickle.load(file(self.DATAPATH)) if data[0] == self.VERSION: self.data = data except EOFError: pass self.filecombo = PythonModulesComboBox(self) if self.data: self.remove_obsolete_items() self.filecombo.addItems(self.get_filenames()) self.start_button = create_toolbutton(self, get_icon('run.png'), translate('Pylint', "Analyze"), tip=translate( 'Pylint', "Run analysis"), triggered=self.start) self.stop_button = create_toolbutton(self, get_icon('terminate.png'), translate('Pylint', "Stop"), tip=translate( 'Pylint', "Stop current analysis")) self.connect(self.filecombo, SIGNAL('valid(bool)'), self.start_button.setEnabled) self.connect(self.filecombo, SIGNAL('valid(bool)'), self.show_data) browse_button = create_toolbutton(self, get_icon('fileopen.png'), tip=translate( 'Pylint', 'Select Python script'), triggered=self.select_file) self.ratelabel = QLabel() self.datelabel = QLabel() self.log_button = create_toolbutton(self, get_icon('log.png'), translate('Pylint', "Output"), tip=translate( 'Pylint', "Complete Pylint output"), triggered=self.show_log) self.treewidget = ResultsTree(self) hlayout1 = QHBoxLayout() hlayout1.addWidget(self.filecombo) hlayout1.addWidget(browse_button) hlayout1.addWidget(self.start_button) hlayout1.addWidget(self.stop_button) hlayout2 = QHBoxLayout() hlayout2.addWidget(self.ratelabel) hlayout2.addStretch() hlayout2.addWidget(self.datelabel) hlayout2.addStretch() hlayout2.addWidget(self.log_button) layout = QVBoxLayout() layout.addLayout(hlayout1) layout.addLayout(hlayout2) layout.addWidget(self.treewidget) self.setLayout(layout) self.process = None self.set_running_state(False) if not is_pylint_installed(): for widget in (self.treewidget, self.filecombo, self.start_button, self.stop_button): widget.setDisabled(True) text = translate('Pylint', 'Please install <b>pylint</b>:') url = 'http://www.logilab.fr' text += ' <a href=%s>%s</a>' % (url, url) self.ratelabel.setText(text) else: self.show_data() def analyze(self, filename): if not is_pylint_installed(): return filename = unicode(filename) # filename is a QString instance self.kill_if_running() index, _data = self.get_data(filename) if index is None: self.filecombo.addItem(filename) self.filecombo.setCurrentIndex(self.filecombo.count() - 1) else: self.filecombo.setCurrentIndex(index) self.filecombo.selected() if self.filecombo.is_valid(): self.start() def select_file(self): self.emit(SIGNAL('redirect_stdio(bool)'), False) filename = QFileDialog.getOpenFileName( self, translate('Pylint', "Select Python script"), os.getcwdu(), translate('Pylint', "Python scripts") + " (*.py ; *.pyw)") self.emit(SIGNAL('redirect_stdio(bool)'), False) if filename: self.analyze(filename) def remove_obsolete_items(self): """Removing obsolete items""" self.data = [self.VERSION] + \ [(filename, data) for filename, data in self.data[1:] if is_module_or_package(filename)] def get_filenames(self): return [filename for filename, _data in self.data[1:]] def get_data(self, filename): filename = osp.abspath(filename) for index, (fname, data) in enumerate(self.data[1:]): if fname == filename: return index, data else: return None, None def set_data(self, filename, data): filename = osp.abspath(filename) index, _data = self.get_data(filename) if index is not None: self.data.pop(index) self.data.append((filename, data)) self.save() def set_max_entries(self, max_entries): self.max_entries = max_entries self.save() def save(self): while len(self.data) > self.max_entries + 1: self.data.pop(1) cPickle.dump(self.data, file(self.DATAPATH, 'w')) def show_log(self): if self.output: TextEditor(self.output, title=translate('Pylint', "Pylint output"), readonly=True, size=(700, 500)).exec_() def start(self): filename = unicode(self.filecombo.currentText()) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.SeparateChannels) self.process.setWorkingDirectory(osp.dirname(filename)) self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.read_output) self.connect(self.process, SIGNAL("readyReadStandardError()"), lambda: self.read_output(error=True)) self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"), self.finished) self.connect(self.stop_button, SIGNAL("clicked()"), self.process.kill) self.output = '' self.error_output = '' p_args = [osp.basename(filename)] self.process.start(PYLINT_PATH, p_args) running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical( self, translate('Pylint', "Error"), translate('Pylint', "Process failed to start")) def set_running_state(self, state=True): self.start_button.setEnabled(not state) self.stop_button.setEnabled(state) def read_output(self, error=False): if error: self.process.setReadChannel(QProcess.StandardError) else: self.process.setReadChannel(QProcess.StandardOutput) bytes = QByteArray() while self.process.bytesAvailable(): if error: bytes += self.process.readAllStandardError() else: bytes += self.process.readAllStandardOutput() text = unicode(QString.fromLocal8Bit(bytes.data())) if error: self.error_output += text else: self.output += text def finished(self): self.set_running_state(False) if not self.output: return # Convention, Refactor, Warning, Error results = {'C:': [], 'R:': [], 'W:': [], 'E:': []} txt_module = '************* Module ' module = '' # Should not be needed - just in case something goes wrong for line in self.output.splitlines(): if line.startswith(txt_module): # New module module = line[len(txt_module):] continue for prefix in results: if line.startswith(prefix): break else: continue i1 = line.find(':') if i1 == -1: continue i2 = line.find(':', i1 + 1) if i2 == -1: continue line_nb = line[i1 + 1:i2].strip() if not line_nb: continue line_nb = int(line_nb) message = line[i2 + 1:] item = (module, line_nb, message) results[line[:i1 + 1]].append(item) # Rate rate = None txt_rate = 'Your code has been rated at ' i_rate = self.output.find(txt_rate) if i_rate > 0: i_rate_end = self.output.find('/10', i_rate) if i_rate_end > 0: rate = self.output[i_rate + len(txt_rate):i_rate_end] # Previous run previous = '' if rate is not None: txt_prun = 'previous run: ' i_prun = self.output.find(txt_prun, i_rate_end) if i_prun > 0: i_prun_end = self.output.find('/10', i_prun) previous = self.output[i_prun + len(txt_prun):i_prun_end] filename = unicode(self.filecombo.currentText()) self.set_data(filename, (time.localtime(), rate, previous, results)) self.output = self.error_output + self.output self.show_data(justanalyzed=True) def kill_if_running(self): if self.process is not None: if self.process.state() == QProcess.Running: self.process.kill() self.process.waitForFinished() def show_data(self, justanalyzed=False): if not justanalyzed: self.output = None self.log_button.setEnabled(self.output is not None \ and len(self.output) > 0) self.kill_if_running() filename = unicode(self.filecombo.currentText()) if not filename: return _index, data = self.get_data(filename) if data is None: text = translate('Pylint', 'Source code has not been rated yet.') self.treewidget.clear() date_text = '' else: datetime, rate, previous_rate, results = data if rate is None: text = translate( 'Pylint', 'Analysis did not succeed ' '(see output for more details).') self.treewidget.clear() date_text = '' else: text_style = "<span style=\'color: #444444\'><b>%s </b></span>" rate_style = "<span style=\'color: %s\'><b>%s</b></span>" prevrate_style = "<span style=\'color: #666666\'>%s</span>" color = "#FF0000" if float(rate) > 5.: color = "#22AA22" elif float(rate) > 3.: color = "#EE5500" text = translate('Pylint', 'Global evaluation:') text = (text_style % text) + (rate_style % (color, ('%s/10' % rate))) if previous_rate: text_prun = translate('Pylint', 'previous run:') text_prun = ' (%s %s/10)' % (text_prun, previous_rate) text += prevrate_style % text_prun self.treewidget.set_results(filename, results) date_text = text_style % time.strftime("%d %b %Y %H:%M", datetime) self.ratelabel.setText(text) self.datelabel.setText(date_text)
class 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 PylintWidget(QWidget): """ Pylint widget """ DATAPATH = get_conf_path('.pylint.results') VERSION = '1.0.2' def __init__(self, parent, max_entries=100): QWidget.__init__(self, parent) self.output = None self.error_output = None self.max_entries = max_entries self.data = [self.VERSION] if osp.isfile(self.DATAPATH): try: data = cPickle.load(file(self.DATAPATH)) if data[0] == self.VERSION: self.data = data except EOFError: pass self.filecombo = PythonModulesComboBox(self) if self.data: self.remove_obsolete_items() self.filecombo.addItems(self.get_filenames()) self.start_button = create_toolbutton(self, get_icon('run.png'), translate('Pylint', "Analyze"), tip=translate('Pylint', "Run analysis"), triggered=self.start) self.stop_button = create_toolbutton(self, get_icon('terminate.png'), translate('Pylint', "Stop"), tip=translate('Pylint', "Stop current analysis")) self.connect(self.filecombo, SIGNAL('valid(bool)'), self.start_button.setEnabled) self.connect(self.filecombo, SIGNAL('valid(bool)'), self.show_data) browse_button = create_toolbutton(self, get_icon('fileopen.png'), tip=translate('Pylint', 'Select Python script'), triggered=self.select_file) self.ratelabel = QLabel() self.datelabel = QLabel() self.log_button = create_toolbutton(self, get_icon('log.png'), translate('Pylint', "Output"), tip=translate('Pylint', "Complete Pylint output"), triggered=self.show_log) self.treewidget = ResultsTree(self) hlayout1 = QHBoxLayout() hlayout1.addWidget(self.filecombo) hlayout1.addWidget(browse_button) hlayout1.addWidget(self.start_button) hlayout1.addWidget(self.stop_button) hlayout2 = QHBoxLayout() hlayout2.addWidget(self.ratelabel) hlayout2.addStretch() hlayout2.addWidget(self.datelabel) hlayout2.addStretch() hlayout2.addWidget(self.log_button) layout = QVBoxLayout() layout.addLayout(hlayout1) layout.addLayout(hlayout2) layout.addWidget(self.treewidget) self.setLayout(layout) self.process = None self.set_running_state(False) if not is_pylint_installed(): for widget in (self.treewidget, self.filecombo, self.start_button, self.stop_button): widget.setDisabled(True) text = translate('Pylint', 'Please install <b>pylint</b>:') url = 'http://www.logilab.fr' text += ' <a href=%s>%s</a>' % (url, url) self.ratelabel.setText(text) else: self.show_data() def analyze(self, filename): if not is_pylint_installed(): return filename = unicode(filename) # filename is a QString instance self.kill_if_running() index, _data = self.get_data(filename) if index is None: self.filecombo.addItem(filename) self.filecombo.setCurrentIndex(self.filecombo.count()-1) else: self.filecombo.setCurrentIndex(index) self.filecombo.selected() if self.filecombo.is_valid(): self.start() def select_file(self): self.emit(SIGNAL('redirect_stdio(bool)'), False) filename = QFileDialog.getOpenFileName(self, translate('Pylint', "Select Python script"), os.getcwdu(), translate('Pylint', "Python scripts")+" (*.py ; *.pyw)") self.emit(SIGNAL('redirect_stdio(bool)'), False) if filename: self.analyze(filename) def remove_obsolete_items(self): """Removing obsolete items""" self.data = [self.VERSION] + \ [(filename, data) for filename, data in self.data[1:] if is_module_or_package(filename)] def get_filenames(self): return [filename for filename, _data in self.data[1:]] def get_data(self, filename): filename = osp.abspath(filename) for index, (fname, data) in enumerate(self.data[1:]): if fname == filename: return index, data else: return None, None def set_data(self, filename, data): filename = osp.abspath(filename) index, _data = self.get_data(filename) if index is not None: self.data.pop(index) self.data.append( (filename, data) ) self.save() def set_max_entries(self, max_entries): self.max_entries = max_entries self.save() def save(self): while len(self.data) > self.max_entries+1: self.data.pop(1) cPickle.dump(self.data, file(self.DATAPATH, 'w')) def show_log(self): if self.output: TextEditor(self.output, title=translate('Pylint', "Pylint output"), readonly=True, size=(700, 500)).exec_() def start(self): filename = unicode(self.filecombo.currentText()) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.SeparateChannels) self.process.setWorkingDirectory(osp.dirname(filename)) self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.read_output) self.connect(self.process, SIGNAL("readyReadStandardError()"), lambda: self.read_output(error=True)) self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"), self.finished) self.connect(self.stop_button, SIGNAL("clicked()"), self.process.kill) self.output = '' self.error_output = '' p_args = [osp.basename(filename)] self.process.start(PYLINT_PATH, p_args) running = self.process.waitForStarted() self.set_running_state(running) if not running: QMessageBox.critical(self, translate('Pylint', "Error"), translate('Pylint', "Process failed to start")) def set_running_state(self, state=True): self.start_button.setEnabled(not state) self.stop_button.setEnabled(state) def read_output(self, error=False): if error: self.process.setReadChannel(QProcess.StandardError) else: self.process.setReadChannel(QProcess.StandardOutput) bytes = QByteArray() while self.process.bytesAvailable(): if error: bytes += self.process.readAllStandardError() else: bytes += self.process.readAllStandardOutput() text = unicode( QString.fromLocal8Bit(bytes.data()) ) if error: self.error_output += text else: self.output += text def finished(self): self.set_running_state(False) if not self.output: return # Convention, Refactor, Warning, Error results = {'C:': [], 'R:': [], 'W:': [], 'E:': []} txt_module = '************* Module ' module = '' # Should not be needed - just in case something goes wrong for line in self.output.splitlines(): if line.startswith(txt_module): # New module module = line[len(txt_module):] continue for prefix in results: if line.startswith(prefix): break else: continue i1 = line.find(':') if i1 == -1: continue i2 = line.find(':', i1+1) if i2 == -1: continue line_nb = line[i1+1:i2].strip() if not line_nb: continue line_nb = int(line_nb) message = line[i2+1:] item = (module, line_nb, message) results[line[:i1+1]].append(item) # Rate rate = None txt_rate = 'Your code has been rated at ' i_rate = self.output.find(txt_rate) if i_rate > 0: i_rate_end = self.output.find('/10', i_rate) if i_rate_end > 0: rate = self.output[i_rate+len(txt_rate):i_rate_end] # Previous run previous = '' if rate is not None: txt_prun = 'previous run: ' i_prun = self.output.find(txt_prun, i_rate_end) if i_prun > 0: i_prun_end = self.output.find('/10', i_prun) previous = self.output[i_prun+len(txt_prun):i_prun_end] filename = unicode(self.filecombo.currentText()) self.set_data(filename, (time.localtime(), rate, previous, results)) self.output = self.error_output + self.output self.show_data(justanalyzed=True) def kill_if_running(self): if self.process is not None: if self.process.state() == QProcess.Running: self.process.kill() self.process.waitForFinished() def show_data(self, justanalyzed=False): if not justanalyzed: self.output = None self.log_button.setEnabled(self.output is not None \ and len(self.output) > 0) self.kill_if_running() filename = unicode(self.filecombo.currentText()) if not filename: return _index, data = self.get_data(filename) if data is None: text = translate('Pylint', 'Source code has not been rated yet.') self.treewidget.clear() date_text = '' else: datetime, rate, previous_rate, results = data if rate is None: text = translate('Pylint', 'Analysis did not succeed ' '(see output for more details).') self.treewidget.clear() date_text = '' else: text_style = "<span style=\'color: #444444\'><b>%s </b></span>" rate_style = "<span style=\'color: %s\'><b>%s</b></span>" prevrate_style = "<span style=\'color: #666666\'>%s</span>" color = "#FF0000" if float(rate) > 5.: color = "#22AA22" elif float(rate) > 3.: color = "#EE5500" text = translate('Pylint', 'Global evaluation:') text = (text_style % text)+(rate_style % (color, ('%s/10' % rate))) if previous_rate: text_prun = translate('Pylint', 'previous run:') text_prun = ' (%s %s/10)' % (text_prun, previous_rate) text += prevrate_style % text_prun self.treewidget.set_results(filename, results) date_text = text_style % time.strftime("%d %b %Y %H:%M", datetime) self.ratelabel.setText(text) self.datelabel.setText(date_text)
class GDALLocationInfoMapTool(QgsMapTool): def __init__(self, canvas): QgsMapTool.__init__(self, canvas) self.canvas = canvas self.cursor = QCursor(QPixmap(":/plugins/AGSInfo/icons/cursor.png"), 1, 1) def activate(self): self.canvas.setCursor(self.cursor) def parseJSON(self, jsonLocationInfo): if jsonLocationInfo.has_key("error"): err_msg = "" err_msg += "Error code: " + str(jsonLocationInfo["error"]["code"]) + "\n" err_msg += "Error message: \n" + jsonLocationInfo["error"]["message"] + "\n" QMessageBox.warning(self.canvas, self.tr("Error"), str(err_msg) ) else: results = jsonLocationInfo["results"] if (len(results) == 0): QMessageBox.warning(self.canvas, self.tr("Warning"), self.tr("Not found any objects") ) return #locationInfoPure = "" locationInfoPure = {} #i = 1 for result in results: attrs = {} #locationInfoPure += str(i) + ".\n" #locationInfoPure += "\tlayerName: " + result["layerName"] + "\n" #locationInfoPure += "\tvalue: " + result["value"] + "\n" #locationInfoPure += "\tattributes: " + str(result["attributes"]) + "\n" #i += 1 attrs.update({"layerName": result["layerName"]}) attrs.update({"Shape": result["attributes"]["Shape"]}) attrs.update({"DESCRIPTION": result["attributes"]["DESCRIPTION"]}) locationInfoPure.update({result["attributes"]["OBJECTID"]: attrs}) #QMessageBox.information(self.canvas, # self.tr("Info"), # locationInfoPure # ) self.a = GDALLocationInfoForm(locationInfoPure) self.a.show() def parseXML(self, xmlLocationInfo): #locationInfoPure = u"" locationInfoPure = {} #i = 1 for child in xmlLocationInfo: attrs = {} #locationInfoPure += u"" + str(i) + u".\n" #locationInfoPure += u"\t" + string.join([string.join( (k, str(child.attrib[k])), ":") for k in child.attrib.keys() ],",") + u".\n" #locationInfoPure += string.join([ string.join( (k, child.attrib[k]), ":") for k in child.attrib.keys() ],"\n") + u".\n" #i += 1 for k in child.attrib.keys(): attrs.update({k: child.attrib[k]}) locationInfoPure.update({child.attrib["OBJECTID"]: attrs}) #QMessageBox.information(self.canvas, # self.tr("Info"), # locationInfoPure # ) self.a = GDALLocationInfoForm(locationInfoPure) self.a.show() def canvasReleaseEvent(self, event): #self.a = GDALLocationInfoForm({"a":{"asd1":"xcvsdfvss", "asd2":"xcvsdfvss", "asd3":"xcvsdfvss"}, "b":{"asd1":"xcvsdfvss", "asd2":"xcvsdfvss", "asd3":"xcvsdfvss"}}) #self.a.show() currentlayer = self.canvas.currentLayer() if currentlayer is None: QMessageBox.warning(self.canvas, self.tr("No active layer"), self.tr("To identify features, you must choose an active layer by clicking on its name in the legend") ) return if currentlayer.type() != QgsMapLayer.RasterLayer: QMessageBox.warning(self.canvas, self.tr("Wrong layer type"), self.tr("This tool works only for vector layers. Please select another layer in legend and try again") ) return self.canvas.setCursor(Qt.WaitCursor) point = self.canvas.getCoordinateTransform().toMapCoordinates(event.x(), event.y()) self.process = QProcess(self) GdalTools_utils.setProcessEnvironment(self.process) self.process.start("gdallocationinfo", ["-xml","-b", "1" ,"-geoloc", currentlayer.source(), str(point[0]), str(point[1])], QIODevice.ReadOnly) self.process.waitForFinished() self.canvas.setCursor(self.cursor) if(self.process.exitCode() != 0): err_msg = str(self.process.readAllStandardError()) if err_msg != '': QMessageBox.warning(self.canvas, self.tr("Error"), err_msg ) else: QMessageBox.warning(self.canvas, self.tr("Error"), str(self.process.readAllStandardOutput()) ) else: data = str(self.process.readAllStandardOutput()); root = ET.fromstring(data) alert_node = root.find('Alert') if (alert_node != None): QMessageBox.warning(self.canvas, self.tr("Warning"), alert_node.text ) return location_info_node = root.find('BandReport').find('LocationInfo') try: jsonLocationInfo = json.JSONDecoder().decode(location_info_node.text.encode("utf-8")) self.parseJSON(jsonLocationInfo) return except ValueError as err: print "json parse error" pass try: data = location_info_node.text.encode("utf-8") #data.decode("cp1251").encode("utf-8") xmlLocationInfo = ET.fromstring(data) self.parseXML(xmlLocationInfo) return except ValueError as err: print "xml parse error: ", err pass
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)