def display_downloaded_content(self): """Open downloaded non-html content in a separate application. Called when an unsupported content type is finished downloading. """ file_path = ( QDir.toNativeSeparators( QDir.tempPath() + "/XXXXXX_" + self.content_filename ) ) myfile = QTemporaryFile(file_path) myfile.setAutoRemove(False) if myfile.open(): myfile.write(self.reply.readAll()) myfile.close() subprocess.Popen([ (self.config.get("content_handlers") .get(str(self.content_type))), myfile.fileName() ]) # Sometimes downloading files opens an empty window. # So if the current window has no URL, close it. if(str(self.url().toString()) in ('', 'about:blank')): self.close()
def display_downloaded_content(self): """Open downloaded non-html content in a separate application. Called when an unsupported content type is finished downloading. """ debug("displaying downloaded content from {}".format(self.reply.url())) file_path = ( QDir.toNativeSeparators( QDir.tempPath() + "/XXXXXX_" + self.content_filename ) ) myfile = QTemporaryFile(file_path) myfile.setAutoRemove(False) if myfile.open(): myfile.write(self.reply.readAll()) myfile.close() subprocess.Popen([ (self.config.get("content_handlers") .get(str(self.content_type))), myfile.fileName() ]) # Sometimes downloading files opens an empty window. # So if the current window has no URL, close it. if(str(self.url().toString()) in ('', 'about:blank')): self.close()
def run(self): returned = [] # TODO: Should pop up modal if not confident in the structure results! index = None pid = None struct = None structseq = None uniID = None alignoff = 0 result = None ids = [] coordinates = None line = None i = 0 x = None data = None structs = None struct0 = None offset = 0 start = None end = None parser = None tmp = None url = None myfile = None for seq in self.seqs: if self.nodes: index = self.nodes[self.seqs.index(seq)] pid = seq.id self.PDBLogger.info("Searching with ID %s" % pid) self.logger.emit("Searching with ID %s" % pid) uniID = self.u.search(pid, columns="id, genes, organism, protein names") if uniID: self.PDBLogger.info('Results!\n\n%s' % uniID) self.logger.emit('Results collected for search: %s' % uniID) result = uniID.split("\n") for line in result[1:]: ids.append(line.split("\t")) while coordinates == None: self.PDBLogger.info('Attempting search with %s from %s' % (ids[i][1], ids[i][2])) self.logger.emit('Attempting search with %s from %s' % (ids[i][1], ids[i][2])) structurl = "https://swissmodel.expasy.org/repository/uniprot/%s.json" % ids[ i][0] self.PDBLogger.debug( 'Searching SwissModel repository: %s' % structurl) self.logger.emit('Searching SwissModel for structure') try: with urllib.request.urlopen(structurl) as url: data = json.loads(url.read().decode()) if data['result']: #print("Data found") result = data['result'] if result['structures']: #print("structures found") structs = result['structures'] structseq = result['sequence'] self.PDBLogger.info( "QUERY: \n%s" % str(seq.seq).replace("-", "")) self.PDBLogger.info("RESULT: \n%s" % structseq) if str(seq.seq).replace("-", "") == structseq: # They should match, else keep looking if structs[0]: # print("accessing first model") struct0 = structs[0] if struct0['coordinates']: coordinates = struct0[ 'coordinates'] alignoff = int( struct0['chains']['A'][0] ['uniprot']['from']) - 1 self.PDBLogger.debug( "MODEL ACQUIRED") self.logger.emit('MODEL ACQUIRED!') else: i += 1 continue else: i += 1 continue else: self.PDBLogger.debug( "Seq didn't match, trying with next model" ) i += 1 continue else: i += 1 continue elif i == len(ids): self.PDBLogger.info("Sorry, no models found") break else: i += 1 continue except HTTPError: break if coordinates: start = structseq[:7] #print(start) for x in range(len(seq)): end = x + 7 if str(seq.seq)[x:end] == start: self.PDBLogger.debug( "Sequence offset is %s residues" % x) offset = x + alignoff self.PDBLogger.info( "Alignment offset is %s residues" % offset) self.logger.emit( "Alignment offset is %s residues" % offset) parser = PDB.PDBParser() tmp = QTemporaryFile() with urllib.request.urlopen(coordinates) as url: myfile = url.read() if tmp.open(): tmp.write(myfile) struct = parser.get_structure( ids[1], tmp.fileName()) self.PDBLogger.debug("STRUCTURE PARSED") self.logger.emit("STRUCTURE PARSED") #print(struct, type(struct)) returned.append([struct, seq, index, offset]) else: self.PDBLogger.debug("Sorry, no models found!!!") else: self.PDBLogger.info("NO STRUCTURE FOUND") self.logger.emit("No structure found, sorry!") self.finished.emit(returned) del returned, index, uniID, result, ids, line, coordinates, i, x, url, start, offset, tmp, parser, seq, struct, structseq, alignoff
def save(self): """ Public slot to save the history entries to disk. """ historyFile = QFile(self.getFileName()) if not historyFile.exists(): self.__lastSavedUrl = "" saveAll = self.__lastSavedUrl == "" first = len(self.__history) - 1 if not saveAll: # find the first one to save for index in range(len(self.__history)): if self.__history[index].url == self.__lastSavedUrl: first = index - 1 break if first == len(self.__history) - 1: saveAll = True if saveAll: # use a temporary file when saving everything f = QTemporaryFile() f.setAutoRemove(False) opened = f.open() else: f = historyFile opened = f.open(QIODevice.Append) if not opened: E5MessageBox.warning( None, self.tr("Saving History"), self.tr("""<p>Unable to open history file <b>{0}</b>.<br/>""" """Reason: {1}</p>""").format( f.fileName(), f.errorString() ), ) return for index in range(first, -1, -1): data = QByteArray() stream = QDataStream(data, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_6) itm = self.__history[index] stream.writeUInt32(HISTORY_VERSION) stream.writeString(itm.url.encode("utf-8")) stream << itm.dateTime stream.writeString(itm.title.encode("utf-8")) f.write(data) f.close() if saveAll: if historyFile.exists() and not historyFile.remove(): E5MessageBox.warning( None, self.tr("Saving History"), self.tr("""<p>Error removing old history file <b>{0}</b>.""" """<br/>Reason: {1}</p>""").format( historyFile.fileName(), historyFile.errorString() ), ) if not f.copy(historyFile.fileName()): E5MessageBox.warning( None, self.tr("Saving History"), self.tr( """<p>Error moving new history file over old one """ """(<b>{0}</b>).<br/>Reason: {1}</p>""" ).format(historyFile.fileName(), f.errorString()), ) self.historySaved.emit() try: self.__lastSavedUrl = self.__history[0].url except IndexError: self.__lastSavedUrl = ""
def save(self): """ Public slot to save the history entries to disk. """ historyFile = QFile(self.getFileName()) if not historyFile.exists(): self.__lastSavedUrl = "" saveAll = self.__lastSavedUrl == "" first = len(self.__history) - 1 if not saveAll: # find the first one to save for index in range(len(self.__history)): if self.__history[index].url == self.__lastSavedUrl: first = index - 1 break if first == len(self.__history) - 1: saveAll = True if saveAll: # use a temporary file when saving everything f = QTemporaryFile() f.setAutoRemove(False) opened = f.open() else: f = historyFile opened = f.open(QIODevice.Append) if not opened: E5MessageBox.warning( None, self.tr("Saving History"), self.tr("""<p>Unable to open history file <b>{0}</b>.<br/>""" """Reason: {1}</p>""").format(f.fileName(), f.errorString())) return for index in range(first, -1, -1): data = QByteArray() stream = QDataStream(data, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_6) itm = self.__history[index] stream.writeUInt32(HISTORY_VERSION) stream.writeString(itm.url.encode("utf-8")) stream << itm.dateTime stream.writeString(itm.title.encode('utf-8')) f.write(data) f.close() if saveAll: if historyFile.exists() and not historyFile.remove(): E5MessageBox.warning( None, self.tr("Saving History"), self.tr( """<p>Error removing old history file <b>{0}</b>.""" """<br/>Reason: {1}</p>""").format( historyFile.fileName(), historyFile.errorString())) if not f.copy(historyFile.fileName()): E5MessageBox.warning( None, self.tr("Saving History"), self.tr( """<p>Error moving new history file over old one """ """(<b>{0}</b>).<br/>Reason: {1}</p>""").format( historyFile.fileName(), f.errorString())) self.historySaved.emit() try: self.__lastSavedUrl = self.__history[0].url except IndexError: self.__lastSavedUrl = ""
class TranslatorWidget(QWidget, Ui_TranslatorWidget): """ Class implementing the translator widget. """ def __init__(self, plugin, translator, parent=None): """ Constructor @param plugin reference to the plugin object (TranslatorPlugin) @param translator reference to the translator object (Translator) @param parent reference to the parent widget (QWidget) """ super(TranslatorWidget, self).__init__(parent) self.setupUi(self) self.__plugin = plugin self.__translator = translator self.__languages = TranslatorLanguagesDb(self) self.__translatorRequest = None self.__translationEngine = None self.__mediaPlayer = None self.__mediaFile = None audioAvailable = (MULTIMEDIA_AVAILABLE and bool(QMediaPlayer.hasSupport("audio/mpeg"))) self.pronounceOrigButton.setVisible(audioAvailable) self.pronounceTransButton.setVisible(audioAvailable) self.pronounceOrigButton.setIcon( self.__translator.getAppIcon("pronounce.png")) self.pronounceTransButton.setIcon( self.__translator.getAppIcon("pronounce.png")) self.swapButton.setIcon(self.__translator.getAppIcon("swap.png")) self.translateButton.setIcon( self.__translator.getAppIcon("translate.png")) self.clearButton.setIcon(UI.PixmapCache.getIcon("editDelete.png")) self.preferencesButton.setIcon(UI.PixmapCache.getIcon("configure.png")) self.translateButton.setEnabled(False) self.clearButton.setEnabled(False) self.pronounceOrigButton.setEnabled(False) self.pronounceTransButton.setEnabled(False) selectedEngine = self.__plugin.getPreferences("SelectedEngine") self.__updateEngines() engineIndex = self.engineComboBox.findData(selectedEngine) self.engineComboBox.setCurrentIndex(engineIndex) self.__engineComboBoxCurrentIndexChanged(engineIndex) self.engineComboBox.currentIndexChanged.connect( self.__engineComboBoxCurrentIndexChanged) self.__plugin.updateLanguages.connect(self.__updateLanguages) def __updateLanguages(self): """ Private slot to update the language combo boxes. """ self.__ensureTranslationEngineReady() if self.__translationEngine is not None: supportedCodes = self.__translationEngine.supportedLanguages() enabledCodes = self.__plugin.getPreferences("EnabledLanguages") # 1. save current selections origLanguage = self.origLanguageComboBox.itemData( self.origLanguageComboBox.currentIndex()) # 2. reload the original language combo box self.origLanguageComboBox.blockSignals(True) self.origLanguageComboBox.clear() for code in enabledCodes: if code in supportedCodes: language = self.__languages.getLanguage(code) if language: icon = self.__languages.getLanguageIcon(code) self.origLanguageComboBox.addItem(icon, language, code) self.origLanguageComboBox.model().sort(0) origIndex = self.origLanguageComboBox.findData(origLanguage) if origIndex == -1: origIndex = 0 self.origLanguageComboBox.blockSignals(False) self.origLanguageComboBox.setCurrentIndex(origIndex) def __updateEngines(self): """ Private slot to update the engines combo box. """ currentEngine = self.engineComboBox.itemData( self.engineComboBox.currentIndex()) self.engineComboBox.clear() for engineName in TranslatorEngines.supportedEngineNames(): icon = TranslatorEngines.getEngineIcon(engineName) self.engineComboBox.addItem( icon, TranslatorEngines.engineDisplayName(engineName), engineName) self.engineComboBox.model().sort(0) self.engineComboBox.setCurrentIndex( self.engineComboBox.findData(currentEngine)) def __originalLanguage(self): """ Private method to return the code of the selected original language. @return code of the original language (string) """ return self.origLanguageComboBox.itemData( self.origLanguageComboBox.currentIndex()) def __translationLanguage(self): """ Private method to return the code of the selected translation language. @return code of the translation language (string) """ return self.transLanguageComboBox.itemData( self.transLanguageComboBox.currentIndex()) @pyqtSlot() def on_translateButton_clicked(self): """ Private slot to translate the entered text. """ self.transEdit.clear() result, ok = self.__translate(self.origEdit.toPlainText(), self.__originalLanguage(), self.__translationLanguage()) if ok: self.transEdit.setHtml(result) else: E5MessageBox.critical(self, self.tr("Translation Error"), result) @pyqtSlot() def on_pronounceOrigButton_clicked(self): """ Private slot to pronounce the original text. """ self.__pronounce(self.origEdit.toPlainText(), self.__originalLanguage()) @pyqtSlot() def on_pronounceTransButton_clicked(self): """ Private slot to pronounce the translated text. """ self.__pronounce(self.transEdit.toPlainText(), self.__translationLanguage()) @pyqtSlot() def on_swapButton_clicked(self): """ Private slot to swap the languages. """ # save selected language codes oLanguage = self.origLanguageComboBox.itemData( self.origLanguageComboBox.currentIndex()) tLanguage = self.transLanguageComboBox.itemData( self.transLanguageComboBox.currentIndex()) oIdx = self.origLanguageComboBox.findData(tLanguage) if oIdx < 0: oIdx = 0 self.origLanguageComboBox.setCurrentIndex(oIdx) tIdx = self.transLanguageComboBox.findData(oLanguage) if tIdx < 0: tIdx = 0 self.transLanguageComboBox.setCurrentIndex(tIdx) origText = self.origEdit.toPlainText() self.origEdit.setPlainText(self.transEdit.toPlainText()) self.transEdit.setPlainText(origText) @pyqtSlot() def on_clearButton_clicked(self): """ Private slot to clear the text fields. """ self.origEdit.clear() self.transEdit.clear() @pyqtSlot() def on_origEdit_textChanged(self): """ Private slot to handle changes of the original text. """ self.__updatePronounceButtons() self.__updateClearButton() self.__updateTranslateButton() @pyqtSlot() def on_transEdit_textChanged(self): """ Private slot to handle changes of the translation text. """ self.__updatePronounceButtons() self.__updateClearButton() @pyqtSlot(int) def on_origLanguageComboBox_currentIndexChanged(self, index): """ Private slot to handle the selection of the original language. @param index current index (integer) """ self.__plugin.setPreferences("OriginalLanguage", self.origLanguageComboBox.itemData(index)) supportedTargetCodes = ( self.__translationEngine.supportedTargetLanguages( self.origLanguageComboBox.itemData(index))) if supportedTargetCodes is not None: enabledCodes = self.__plugin.getPreferences("EnabledLanguages") transLanguage = self.transLanguageComboBox.itemData( self.transLanguageComboBox.currentIndex()) self.transLanguageComboBox.clear() if len(supportedTargetCodes) > 0: for code in enabledCodes: if code in supportedTargetCodes: language = self.__languages.getLanguage(code) if language: icon = self.__languages.getLanguageIcon(code) self.transLanguageComboBox.addItem( icon, language, code) self.transLanguageComboBox.model().sort(0) index = self.transLanguageComboBox.findData(transLanguage) if index == -1: index = 0 self.transLanguageComboBox.setCurrentIndex(index) self.__updateTranslateButton() @pyqtSlot(int) def on_transLanguageComboBox_currentIndexChanged(self, index): """ Private slot to handle the selection of the translation language. @param index current index (integer) """ self.__plugin.setPreferences( "TranslationLanguage", self.transLanguageComboBox.itemData(index)) @pyqtSlot() def __availableTranslationsLoaded(self): """ Private slot to handle the availability of translations. """ origLanguage = self.__plugin.getPreferences("OriginalLanguage") transLanguage = self.__plugin.getPreferences("TranslationLanguage") self.__updateLanguages() origIndex = self.origLanguageComboBox.findData(origLanguage) self.origLanguageComboBox.setCurrentIndex(origIndex) self.on_origLanguageComboBox_currentIndexChanged(origIndex) self.transLanguageComboBox.setCurrentIndex( self.transLanguageComboBox.findData(transLanguage)) def __ensureTranslationEngineReady(self): """ Private slot to ensure, that the currently selected translation engine is ready. """ engineName = self.engineComboBox.itemData( self.engineComboBox.currentIndex()) if (self.__translationEngine is not None and self.__translationEngine.engineName() != engineName): self.__translationEngine.availableTranslationsLoaded.disconnect( self.__availableTranslationsLoaded) self.__translationEngine.deleteLater() self.__translationEngine = None if self.__translationEngine is None: self.__translationEngine = TranslatorEngines.getTranslationEngine( engineName, self.__plugin, self) if self.__translationEngine is not None: self.__translationEngine.availableTranslationsLoaded.connect( self.__availableTranslationsLoaded) @pyqtSlot(int) def __engineComboBoxCurrentIndexChanged(self, index): """ Private slot to handle the selection of a translation service. @param index current index @type int """ self.__ensureTranslationEngineReady() if self.__translationEngine is not None: self.__updateTranslateButton() self.__updatePronounceButtons() self.__plugin.setPreferences("SelectedEngine", self.engineComboBox.itemData(index)) def __updatePronounceButtons(self): """ Private slot to set the state of the pronounce buttons. """ if self.__translationEngine is not None: hasTTS = self.__translationEngine.hasTTS() else: hasTTS = False self.pronounceOrigButton.setEnabled( hasTTS and bool(self.origEdit.toPlainText())) self.pronounceTransButton.setEnabled( hasTTS and bool(self.transEdit.toPlainText())) def __updateClearButton(self): """ Private slot to set the state of the clear button. """ enable = (bool(self.origEdit.toPlainText()) or bool(self.transEdit.toPlainText())) self.clearButton.setEnabled(enable) def __updateTranslateButton(self): """ Private slot to set the state of the translate button. """ enable = bool(self.origEdit.toPlainText()) enable &= bool(self.__translationLanguage()) enable &= bool(self.__originalLanguage()) self.translateButton.setEnabled(enable) def __translate(self, text, originalLanguage, translationLanguage): """ Private method to translate the given text. @param text text to be translated (string) @param originalLanguage language code of the original (string) @param translationLanguage language code of the translation (string) @return tuple of translated text (string) and flag indicating success (boolean) """ if self.__translatorRequest is None: from .TranslatorRequest import TranslatorRequest self.__translatorRequest = TranslatorRequest(self) self.__ensureTranslationEngineReady() if self.__translationEngine is None: return "", False else: result, ok = self.__translationEngine.getTranslation( self.__translatorRequest, text, originalLanguage, translationLanguage) return result, ok def __pronounce(self, text, language): """ Private method to pronounce the given text. @param text text to be pronounced (string) @param language language code of the text (string) """ if not text or not language: return if self.__translatorRequest is None: from .TranslatorRequest import TranslatorRequest self.__translatorRequest = TranslatorRequest(self) if self.__mediaPlayer is None: self.__mediaPlayer = QMediaPlayer(self) self.__mediaPlayer.stateChanged.connect( self.__mediaPlayerStateChanged) if self.__mediaPlayer.state() == QMediaPlayer.PlayingState: return self.__ensureTranslationEngineReady() if self.__translationEngine is not None: if not self.__translationEngine.hasTTS(): E5MessageBox.critical( self, self.tr("Translation Error"), self.tr("The selected translation service does not" " support the Text-to-Speech function.")) return data, ok = self.__translationEngine.getTextToSpeechData( self.__translatorRequest, text, language) if ok: self.__mediaFile = QTemporaryFile(self) self.__mediaFile.open() self.__mediaFile.setAutoRemove(False) self.__mediaFile.write(data) self.__mediaPlayer.setMedia(QMediaContent(), self.__mediaFile) self.__mediaPlayer.play() else: E5MessageBox.critical(self, self.tr("Translation Error"), data) def __mediaPlayerStateChanged(self, state): """ Private slot handling changes of the media player state. @param state media player state (QAudio.State) """ if state == QMediaPlayer.StoppedState: self.__mediaFile.close() self.__mediaFile.remove() self.__mediaFile = None @pyqtSlot() def on_preferencesButton_clicked(self): """ Private slot to open the Translator configuration page. """ e5App().getObject("UserInterface").showPreferences("translatorPage")
class EditorWorker(QObject): file_change_sig = pyqtSignal(bool) # is_zim def __init__(self, command, old_text, is_zim, zim_folder=None, docid=None, zim_file=None, parent=None): '''Observe the write/save states of a txt file to edit notes Args: command (list): command string list to pass into Popen. old_text (str): existing note text to paste into editor. is_zim (bool): if True, try open the associated zim note file. if False, open a temp file to edit. Kwargs: zim_folder (str or None): if not None, the path to the zim note folder, used to search for zim notes. docid (int or None): if not None, id of current doc. parent (QWidget or None): parent widget. ''' super(EditorWorker, self).__init__(parent) self.is_zim = is_zim self.zim_folder = zim_folder self.docid = docid self.logger = logging.getLogger(__name__) if not self.is_zim: self._temp_file = QTemporaryFile(self) else: if zim_file is not None: # use given zim file if os.path.exists(zim_file) and os.path.islink(zim_file): self._temp_file = QFile(zim_file, self) self.logger.debug('Got given zim file %s' % zim_file) else: try: zim_file = locateZimNote(self.zim_folder, self.docid) self._temp_file = QFile(zim_file, self) self.logger.exception( 'Failed to open given zim file. Get the id one.') except: self.logger.exception('Failed to find zim file.') self._temp_file = QTemporaryFile(self) self.is_zim = False else: # no given zim file, get the one in all_notes try: zim_file = locateZimNote(self.zim_folder, self.docid) self._temp_file = QFile(zim_file, self) self.logger.debug('Got zim file %s' % zim_file) except: self.logger.exception('Failed to find zim file.') self._temp_file = QTemporaryFile(self) self.is_zim = False self._process = QProcess(self) self._text = "" self._watcher = QFileSystemWatcher(self) self._watcher.fileChanged.connect(self.onFileChange) # write existing lines if temp file if not self.is_zim and self._temp_file.open(): self._temp_file.write(old_text.encode('utf-8')) self._temp_file.close() # open() on temp file assumes QIODevice.ReadWrite as well. if self._temp_file.open(QIODevice.ReadWrite): self._file_path = self._temp_file.fileName() self._watcher.addPath(self._file_path) self.logger.debug('_file_path = %s' % self._file_path) program = command[0] arguments = command[1:] self._process.start(program, arguments + [self._temp_file.fileName()]) @pyqtSlot() def onFileChange(self): if self._temp_file.isOpen(): #self._temp_file.seek(0) #self._text = self._temp_file.readAll().data().decode() # has to use with open and read(), the above doesn't work for # some editors, like xed # For some reason, if watching the zim file, and open in gvim # it reports file not found unless I wait for a while. wtf = os.path.exists(self._temp_file.fileName()) while not wtf: wtf = os.path.exists(self._temp_file.fileName()) with open(self._temp_file.fileName()) as tmp: self._text = tmp.read() # Re-add watch file, again for xed. self._watcher.removePath(self._file_path) self._watcher.addPath(self._file_path) self.file_change_sig.emit(self.is_zim) @property def text(self): return self._text def __del__(self): self._process.kill()