def __updateExistingItem(self, item, newSrcAbsPath, newDstRelPath, userLogin): logger.info("__updateExistingItem with args={}".format( (item, newSrcAbsPath, newDstRelPath, userLogin))) if newSrcAbsPath is None: assert newDstRelPath is None, \ "Both newSrcAbsPath and newDstRelPath args should be None." else: assert not hlp.is_none_or_empty(newSrcAbsPath) assert not hlp.is_none_or_empty(newDstRelPath), \ "Both newSrcAbsPath and newDstRelPath args should be not empty." persistentItem = self._session.query(db.Item).get(item.id) self.__updatePlainDataMembers(item, persistentItem) self.__updateTags(item, persistentItem, userLogin) self.__updateFields(item, persistentItem, userLogin) self.__updateDataRefAndFilesystem(item, persistentItem, newSrcAbsPath, newDstRelPath, userLogin) self._session.commit() self._session.refresh(persistentItem) self._session.expunge(persistentItem) return persistentItem
def buttonAddDataRef(self): file = QtGui.QFileDialog.getOpenFileName(self, self.tr("Select a file to link with the Item.")) if is_none_or_empty(file): return #Suggest a title for the Item, if it has not any title yet title = self.ui.lineEdit_title.text() if is_none_or_empty(title): self.ui.lineEdit_title.setText(os.path.basename(file)) data_ref = DataRef(objType=DataRef.FILE, url=file) self.item.data_ref = data_ref assert(os.path.isabs(data_ref.url)) self.ui.fileAbsPath.setText(data_ref.url) dstRelPath = None if is_internal(data_ref.url, self.repoBasePath): dstRelPath = os.path.relpath(data_ref.url, self.repoBasePath) else: dstRelPath = os.path.basename(data_ref.url) dstRelPath = os.path.join(".", dstRelPath) self.ui.fileRelPath.setText(dstRelPath)
def buttonAddDataRef(self): file = QtGui.QFileDialog.getOpenFileName( self, self.tr("Select a file to link with the Item.")) if is_none_or_empty(file): return #Suggest a title for the Item, if it has not any title yet title = self.ui.lineEdit_title.text() if is_none_or_empty(title): self.ui.lineEdit_title.setText(os.path.basename(file)) data_ref = DataRef(objType=DataRef.FILE, url=file) self.item.data_ref = data_ref assert (os.path.isabs(data_ref.url)) self.ui.fileAbsPath.setText(data_ref.url) dstRelPath = None if is_internal(data_ref.url, self.repoBasePath): dstRelPath = os.path.relpath(data_ref.url, self.repoBasePath) else: dstRelPath = os.path.basename(data_ref.url) dstRelPath = os.path.join(".", dstRelPath) self.ui.fileRelPath.setText(dstRelPath)
def hash(self): ''' Calculates and returns a hash of the Item instance state. ''' text = "" if not is_none_or_empty(self.title): text += self.title if not is_none_or_empty(self.user_login): text += self.user_login if self.date_created is not None: text += str(self.date_created) tag_names = [] for item_tag in self.item_tags: tag_names.append(item_tag.tag.name) tag_names.sort() for tag_name in tag_names: text += tag_name field_vals = [] for item_field in self.item_fields: field_vals.append(item_field.field.name + str(item_field.field_value)) field_vals.sort() for field_val in field_vals: text += field_val return hashlib.sha1(text.encode("utf-8")).hexdigest()
def __saveNewItem(self, item, srcAbsPath=None, dstRelPath=None): #We do not need any info, that can be in item.data_ref object at this point. #But if it is not None, it may break the creation of tags/fields. #Don't worry, item.data_ref will be assigned a new DataRef instance later (if required). item.data_ref = None user_login = item.user_login if hlp.is_none_or_empty(user_login): raise err.AccessError( "Argument user_login shouldn't be null or empty.") user = self._session.query(db.User).get(user_login) if user is None: raise err.AccessError( "User with login {} doesn't exist.".format(user_login)) #Making copies of tags and fields item_tags_copy = item.item_tags[:] item_fields_copy = item.item_fields[:] # Storing the item without tags and fields (for now) del item.item_tags[:] del item.item_fields[:] self._session.add(item) self._session.flush() tagNamesToAdd = map(lambda itag: itag.tag.name, item_tags_copy) operations.ItemOperations.addTags(self._session, item, tagNamesToAdd, user_login) nameValuePairsToAdd = map( lambda ifield: (ifield.field.name, ifield.field_value), item_fields_copy) operations.ItemOperations.addOrUpdateFields(self._session, item, nameValuePairsToAdd, user_login) isDataRefRequired = not hlp.is_none_or_empty(srcAbsPath) if isDataRefRequired: operations.ItemOperations.addUntrackedFile(self._session, item, self._repoBasePath, srcAbsPath, dstRelPath, user_login) self._session.commit() item_id = item.id self._session.expunge(item) return item_id
def keyPressEvent(self, event): cursor = self.textCursor() cursor.select(QtGui.QTextCursor.WordUnderCursor) word = cursor.selectedText() word = word if not is_none_or_empty(word) else "" if self.completer is not None and \ event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_Space: self.completer.filter(word) self.show_completer() super(TextEdit, self).keyPressEvent(event) #TODO When user press Ctrl+Space, completer is shown, but TextEdit cursor becomes hidden! Why? elif self.one_line and event.key() in [Qt.Key_Enter, Qt.Key_Return]: #This signal is for QLineEdit behaviour self.emit(QtCore.SIGNAL("returnPressed()")) elif event.key() in [ Qt.Key_Backspace, Qt.Key_Delete, Qt.Key_Up, Qt.Key_Down, Qt.Key_Left, Qt.Key_Right, Qt.Key_End, Qt.Key_Home, Qt.Key_Shift, Qt.Key_Alt, Qt.Key_Control ]: super(TextEdit, self).keyPressEvent(event) elif len(word) > 0: self.completer.filter(word) if self.completer.count() > 0: self.show_completer() super(TextEdit, self).keyPressEvent(event) else: super(TextEdit, self).keyPressEvent(event)
def buttonMoveFile(self): try: if self.item.data_ref is None: raise Exception(self.tr("You must add a file first.")) directory = QtGui.QFileDialog.getExistingDirectory( self, self.tr("Select destination path within repository"), self.repoBasePath) if is_none_or_empty(directory): return if not is_internal(directory, self.repoBasePath): raise MsgException( self.tr("Chosen directory is out of active repository.")) new_dst_path = os.path.relpath(directory, self.repoBasePath) if not new_dst_path.startswith("."): new_dst_path = os.path.join(".", new_dst_path) newDstRelPath = os.path.join( new_dst_path, os.path.basename(self.item.data_ref.url)) self.ui.fileRelPath.setText(newDstRelPath) except Exception as ex: show_exc_info(self, ex)
def mouseMoveEvent(self, e): #Get current word under cursor cursor = self.cursorForPosition(e.pos()) cursor.select(QtGui.QTextCursor.WordUnderCursor) word = cursor.selectedText() #print("pos={}".format(cursor.position())) if word == "ALL" and cursor.position() <= 3: self.keywordAll = True else: self.keywordAll = False # If current word has changed or cleared --- set default formatting if word != self.word or is_none_or_empty(word): cursor1 = self.textCursor() cursor1.select(QtGui.QTextCursor.Document) fmt = QtGui.QTextCharFormat() fmt.setForeground(QtGui.QBrush(QtGui.QColor(self.text_color))) cursor1.mergeCharFormat(fmt) self.word = None # If current word has changed --- highlight it if word != self.word: fmt = QtGui.QTextCharFormat() fmt.setForeground(QtGui.QBrush(QtGui.QColor(self.hl_text_color))) cursor.mergeCharFormat(fmt) self.word = word # NOTE: There is a problem when tag contains a spaces or dashes (and other special chars). # word is detected incorrectly in such a case. # TODO: Have to fix this problem return super(TagCloudTextEdit, self).mouseMoveEvent(e)
def __onButtonNewCategoryClicked(self): try: categoriesCountBefore = self.ui.comboBoxCategory.count() text, isOk = self.__dialogs.execGetTextDialog(self, self.tr("Input Dialog"), self.tr("Enter the name for new category of files."), defaultText="Category_{}".format(categoriesCountBefore)) if not isOk: return if helpers.is_none_or_empty(text): raise MsgException(self.tr("Category name should not be empty")) if self.__isCategoryExists(text): raise MsgException(self.tr("Category with given name already exists. Choose different name.")) appDescription = ExtAppDescription(text, "<path to executable> %f", [".mp3", ".ogg"]) self.__extAppMgrState.appDescriptions.append(appDescription) self.ui.comboBoxCategory.addItem(text) categoriesCountAfter = self.ui.comboBoxCategory.count() self.ui.comboBoxCategory.setCurrentIndex(categoriesCountAfter - 1) except Exception as ex: helpers.show_exc_info(self, ex)
def sendEvent(name): if not isSendStatisticsAllowed(): return instanceId = reggataInstanceId() if hlp.is_none_or_empty(instanceId): return t = Thread(target=_sendEvent, args=(instanceId, name)) t.start()
def sendIntValue(name, intValue): if not isSendStatisticsAllowed(): return instanceId = reggataInstanceId() if hlp.is_none_or_empty(instanceId): return t = Thread(target=_sendIntValue, args=(instanceId, name, intValue)) t.start()
def __writeDataRef(self): assert (self.item.data_ref is not None) srcAbsPath = self.ui.fileAbsPath.text() dstRelPath = self.ui.fileRelPath.text() srcAbsPath = os.path.normpath(srcAbsPath) dstRelPath = os.path.normpath(dstRelPath) if helpers.is_none_or_empty(srcAbsPath): raise MsgException(self.tr("srcAbsPath should not be empty.")) if helpers.is_none_or_empty(dstRelPath): raise MsgException(self.tr("dstRelPath should not be empty.")) self.item.data_ref.srcAbsPath = srcAbsPath self.item.data_ref.dstRelPath = dstRelPath
def __writeDataRef(self): assert(self.item.data_ref is not None) srcAbsPath = self.ui.fileAbsPath.text() dstRelPath = self.ui.fileRelPath.text() srcAbsPath = os.path.normpath(srcAbsPath) dstRelPath = os.path.normpath(dstRelPath) if helpers.is_none_or_empty(srcAbsPath): raise MsgException(self.tr("srcAbsPath should not be empty.")) if helpers.is_none_or_empty(dstRelPath): raise MsgException(self.tr("dstRelPath should not be empty.")) self.item.data_ref.srcAbsPath = srcAbsPath self.item.data_ref.dstRelPath = dstRelPath
def __parseAndWriteFileExtentions(self): index = self.__currentCategoryIndex() if index < 0: return userText = self.ui.lineEditFileExtensions.text().strip() assert not helpers.is_none_or_empty(userText), "This is a sign of bug in FileExtentionsListValidator.." self.__extAppMgrState.appDescriptions[index].fileExtentions = userText.split()
def is_image(self): supported = set([".bmp", ".gif", ".jpg", ".jpeg", ".png", ".pbm", ".pgm", ".ppm", ".xbm", ".xpm"]) if self.type and self.type == "FILE" and not is_none_or_empty(self.url): _root, ext = os.path.splitext(self.url.lower()) if ext in supported: return True return False
def unquote(string): ''' Removes quotes and unescapes all symbols of the string. Returns modified string. ''' if not is_none_or_empty(string) and string.startswith('"') \ and string.endswith('"') and not string.endswith(r'\"'): string = string[1:-1] return unescape(string)
def __decodeFavoriteReposFromStr(self, favoriteReposPropValue): if helpers.is_none_or_empty(favoriteReposPropValue): return [] try: repos = eval(favoriteReposPropValue) except SyntaxError: repos = [] logger.warn("Could not parse '" + favoriteReposPropValue + "' " + " Check the value of 'favorite_repos' property in your reggata.conf.") return repos
def widget_text_changed(self): if self.widget is not None: cursor = self.widget.textCursor() cursor.select(QtGui.QTextCursor.WordUnderCursor) word = cursor.selectedText() if is_none_or_empty(word): self.hide() self.filter(word) if self.count() <= 0: self.hide()
def __saveNewItem(self, item, srcAbsPath=None, dstRelPath=None): #We do not need any info, that can be in item.data_ref object at this point. #But if it is not None, it may break the creation of tags/fields. #Don't worry, item.data_ref will be assigned a new DataRef instance later (if required). item.data_ref = None user_login = item.user_login if hlp.is_none_or_empty(user_login): raise err.AccessError("Argument user_login shouldn't be null or empty.") user = self._session.query(db.User).get(user_login) if user is None: raise err.AccessError("User with login {} doesn't exist.".format(user_login)) #Making copies of tags and fields item_tags_copy = item.item_tags[:] item_fields_copy = item.item_fields[:] # Storing the item without tags and fields (for now) del item.item_tags[:] del item.item_fields[:] self._session.add(item) self._session.flush() tagNamesToAdd = map(lambda itag: itag.tag.name, item_tags_copy) operations.ItemOperations.addTags(self._session, item, tagNamesToAdd, user_login) nameValuePairsToAdd = map(lambda ifield: (ifield.field.name, ifield.field_value), item_fields_copy) operations.ItemOperations.addOrUpdateFields(self._session, item, nameValuePairsToAdd, user_login) isDataRefRequired = not hlp.is_none_or_empty(srcAbsPath) if isDataRefRequired: operations.ItemOperations.addUntrackedFile(self._session, item, self._repoBasePath, srcAbsPath, dstRelPath, user_login) self._session.commit() item_id = item.id self._session.expunge(item) return item_id
def __writeDataRefs(self): if self.mode == ItemsDialog.EDIT_MODE: for item in self.items: if (item.data_ref is None) or (item.data_ref.type != DataRef.FILE): continue item.data_ref.srcAbsPath = os.path.join(self.repoBasePath, item.data_ref.url) if is_none_or_empty(self.dstPath): item.data_ref.dstRelPath = item.data_ref.url else: item.data_ref.dstRelPath = os.path.join(self.dstPath, os.path.basename(item.data_ref.url)) elif self.mode == ItemsDialog.CREATE_MODE: # In CREATE_MODE item.data_ref.url for all items will be None at this point # We should use item.data_ref.srcAbsPath instead for item in self.items: if (item.data_ref is None) or (item.data_ref.type != DataRef.FILE): continue if self.same_dst_path: tmp = self.dstPath if not is_none_or_empty(self.dstPath) else "" item.data_ref.dstRelPath = os.path.join( tmp, os.path.basename(item.data_ref.srcAbsPath)) else: if self.dstPath: relPathToFile = os.path.relpath(item.data_ref.srcAbsPath, item.data_ref.srcAbsPathToRoot) item.data_ref.dstRelPath = os.path.join( self.dstPath, relPathToFile) else: if is_internal(item.data_ref.srcAbsPath, self.repoBasePath): item.data_ref.dstRelPath = os.path.relpath( item.data_ref.srcAbsPath, self.repoBasePath) else: item.data_ref.dstRelPath = os.path.relpath( item.data_ref.srcAbsPath, item.data_ref.srcAbsPathToRoot)
def __loginUser(self, login, password): if hlp.is_none_or_empty(login): raise err.LoginError("User login cannot be empty.") user = self._session.query(db.User).get(login) if user is None: raise err.LoginError("User {} doesn't exist.".format(login)) if user.password != password: raise err.LoginError("Password incorrect.") self._session.expunge(user) return user
def __writeFileBrowserCommand(self): currentCmd = self.__extAppMgrState.extFileMgrCommandPattern try: userText = self.ui.lineEditExtFileBrowserCmd.text().strip() if helpers.is_none_or_empty(userText): raise MsgException(self.tr("File Browser command should not be empty.")) self.__extAppMgrState.extFileMgrCommandPattern = userText except Exception as ex: helpers.show_exc_info(self, ex) self.ui.lineEditExtFileBrowserCmd.setText(currentCmd)
def is_image(self): supported = set([ ".bmp", ".gif", ".jpg", ".jpeg", ".png", ".pbm", ".pgm", ".ppm", ".xbm", ".xpm" ]) if self.type and self.type == "FILE" and not is_none_or_empty( self.url): _root, ext = os.path.splitext(self.url.lower()) if ext in supported: return True return False
def __decodeFavoriteReposFromStr(self, favoriteReposPropValue): if helpers.is_none_or_empty(favoriteReposPropValue): return [] try: repos = eval(favoriteReposPropValue) except SyntaxError: repos = [] logger.warn( "Could not parse '" + favoriteReposPropValue + "' " + " Check the value of 'favorite_repos' property in your reggata.conf." ) return repos
def addUntrackedFile(session, item, repoBasePath, srcAbsPath, dstRelPath, userLogin): assert not hlp.is_none_or_empty(srcAbsPath) assert dstRelPath is not None #NOTE: If dstRelPath is an empty string it means the root of repository srcAbsPath = os.path.normpath(srcAbsPath) if not os.path.isabs(srcAbsPath): raise ValueError( "srcAbsPath='{}' must be an absolute path.".format(srcAbsPath)) if not os.path.exists(srcAbsPath): raise ValueError( "srcAbsPath='{}' must point to an existing file.".format( srcAbsPath)) if os.path.isabs(dstRelPath): raise ValueError( "dstRelPath='{}' must be a relative to repository root path, but it is absolute." .format(dstRelPath)) dstRelPath = hlp.removeTrailingOsSeps(dstRelPath) dstRelPath = os.path.normpath(dstRelPath) dstAbsPath = os.path.abspath(os.path.join(repoBasePath, dstRelPath)) dstAbsPath = os.path.normpath(dstAbsPath) if srcAbsPath != dstAbsPath and os.path.exists(dstAbsPath): raise ValueError( "{} should not point to an existing file.".format(dstAbsPath)) dataRef = session.query(db.DataRef).filter( db.DataRef.url_raw == hlp.to_db_format(dstRelPath)).first() if dataRef is not None: raise err.DataRefAlreadyExistsError( "DataRef instance with url='{}' " "is already in database. ".format(dstRelPath)) item.data_ref = db.DataRef(objType=db.DataRef.FILE, url=dstRelPath) item.data_ref.user_login = userLogin item.data_ref.size = os.path.getsize(srcAbsPath) item.data_ref.hash = hlp.computeFileHash(srcAbsPath) item.data_ref.date_hashed = datetime.datetime.today() session.add(item.data_ref) item.data_ref_id = item.data_ref.id session.flush() #Now it's time to COPY physical file to the repository if srcAbsPath != dstAbsPath: try: head, _tail = os.path.split(dstAbsPath) os.makedirs(head) except: pass shutil.copy(srcAbsPath, dstAbsPath)
def __init__(self, path, objType=None, status=None): assert not hlp.is_none_or_empty(path) assert objType is not None or status is not None #remove trailing slashes in the path while path.endswith(os.sep): path = path[0:-1] self.path = path self.status = status self.type = objType self.tags = [] self.fields = [] self.itemIds = []
def __updateExistingItem(self, item, newSrcAbsPath, newDstRelPath, userLogin): logger.info("__updateExistingItem with args={}" .format((item, newSrcAbsPath, newDstRelPath, userLogin))) if newSrcAbsPath is None: assert newDstRelPath is None, \ "Both newSrcAbsPath and newDstRelPath args should be None." else: assert not hlp.is_none_or_empty(newSrcAbsPath) assert not hlp.is_none_or_empty(newDstRelPath), \ "Both newSrcAbsPath and newDstRelPath args should be not empty." persistentItem = self._session.query(db.Item).get(item.id) self.__updatePlainDataMembers(item, persistentItem) self.__updateTags(item, persistentItem, userLogin) self.__updateFields(item, persistentItem, userLogin) self.__updateDataRefAndFilesystem(item, persistentItem, newSrcAbsPath, newDstRelPath, userLogin) self._session.commit() self._session.refresh(persistentItem) self._session.expunge(persistentItem) return persistentItem
def write(self): ''' Writes all data from dialog GUI elements to the self.item object. ''' self.item.title = self.ui.lineEdit_title.text() #Processing Tags del self.item.item_tags[:] text = self.ui.plainTextEdit_tags.toPlainText() tags, _tmp = definition_parser.parse(text) for t in tags: tag = Tag(name=t) item_tag = Item_Tag(tag) item_tag.user_login = self.item.user_login self.item.item_tags.append(item_tag) #Processing Fields del self.item.item_fields[:] text = self.ui.plainTextEdit_fields.toPlainText() _tmp, fields = definition_parser.parse(text) for (f, v) in fields: if f in consts.RESERVED_FIELDS: raise MsgException( self.tr("Field name '{}' is reserved.").format(f)) field = Field(name=f) item_field = Item_Field(field, v) item_field.user_login = self.item.user_login self.item.item_fields.append(item_field) #Processing reserved field NOTES_FIELD notes = self.ui.plainTextEdit_notes.toPlainText() if not is_none_or_empty(notes): field = Field(name=consts.NOTES_FIELD) item_field = Item_Field(field, notes) item_field.user_login = self.item.user_login self.item.item_fields.append(item_field) #Processing reserved field RATING_FIELD rating = self.ui.spinBox_rating.value() if rating > 0: field = Field(name=consts.RATING_FIELD) item_field = Item_Field(field, rating) item_field.user_login = self.item.user_login self.item.item_fields.append(item_field) #Processing DataRef object if self.item.data_ref is not None: self.__writeDataRef()
def __writeApplicationCommand(self): index = self.__currentCategoryIndex() if index < 0: return currentAppCmd = self.__extAppMgrState.appDescriptions[index].appCommandPattern try: userText = self.ui.lineEditAppCmd.text().strip() if helpers.is_none_or_empty(userText): raise MsgException(self.tr("Application command should not be empty.")) self.__extAppMgrState.appDescriptions[index].appCommandPattern = userText except Exception as ex: helpers.show_exc_info(self, ex) self.ui.lineEditAppCmd.setText(currentAppCmd)
def write(self): ''' Writes all data from dialog GUI elements to the self.item object. ''' self.item.title = self.ui.lineEdit_title.text() #Processing Tags del self.item.item_tags[:] text = self.ui.plainTextEdit_tags.toPlainText() tags, _tmp = definition_parser.parse(text) for t in tags: tag = Tag(name=t) item_tag = Item_Tag(tag) item_tag.user_login = self.item.user_login self.item.item_tags.append(item_tag) #Processing Fields del self.item.item_fields[:] text = self.ui.plainTextEdit_fields.toPlainText() _tmp, fields = definition_parser.parse(text) for (f, v) in fields: if f in consts.RESERVED_FIELDS: raise MsgException(self.tr("Field name '{}' is reserved.").format(f)) field = Field(name=f) item_field = Item_Field(field, v) item_field.user_login = self.item.user_login self.item.item_fields.append(item_field) #Processing reserved field NOTES_FIELD notes = self.ui.plainTextEdit_notes.toPlainText() if not is_none_or_empty(notes): field = Field(name=consts.NOTES_FIELD) item_field = Item_Field(field, notes) item_field.user_login = self.item.user_login self.item.item_fields.append(item_field) #Processing reserved field RATING_FIELD rating = self.ui.spinBox_rating.value() if rating > 0: field = Field(name=consts.RATING_FIELD) item_field = Item_Field(field, rating) item_field.user_login = self.item.user_login self.item.item_fields.append(item_field) #Processing DataRef object if self.item.data_ref is not None: self.__writeDataRef()
def addUntrackedFile(session, item, repoBasePath, srcAbsPath, dstRelPath, userLogin): assert not hlp.is_none_or_empty(srcAbsPath) assert dstRelPath is not None #NOTE: If dstRelPath is an empty string it means the root of repository srcAbsPath = os.path.normpath(srcAbsPath) if not os.path.isabs(srcAbsPath): raise ValueError("srcAbsPath='{}' must be an absolute path.".format(srcAbsPath)) if not os.path.exists(srcAbsPath): raise ValueError("srcAbsPath='{}' must point to an existing file.".format(srcAbsPath)) if os.path.isabs(dstRelPath): raise ValueError("dstRelPath='{}' must be a relative to repository root path, but it is absolute." .format(dstRelPath)) dstRelPath = hlp.removeTrailingOsSeps(dstRelPath) dstRelPath = os.path.normpath(dstRelPath) dstAbsPath = os.path.abspath(os.path.join(repoBasePath, dstRelPath)) dstAbsPath = os.path.normpath(dstAbsPath) if srcAbsPath != dstAbsPath and os.path.exists(dstAbsPath): raise ValueError("{} should not point to an existing file.".format(dstAbsPath)) dataRef = session.query(db.DataRef).filter( db.DataRef.url_raw==hlp.to_db_format(dstRelPath)).first() if dataRef is not None: raise err.DataRefAlreadyExistsError("DataRef instance with url='{}' " "is already in database. ".format(dstRelPath)) item.data_ref = db.DataRef(objType=db.DataRef.FILE, url=dstRelPath) item.data_ref.user_login = userLogin item.data_ref.size = os.path.getsize(srcAbsPath) item.data_ref.hash = hlp.computeFileHash(srcAbsPath) item.data_ref.date_hashed = datetime.datetime.today() session.add(item.data_ref) item.data_ref_id = item.data_ref.id session.flush() #Now it's time to COPY physical file to the repository if srcAbsPath != dstAbsPath: try: head, _tail = os.path.split(dstAbsPath) os.makedirs(head) except: pass shutil.copy(srcAbsPath, dstAbsPath)
def execMessageBox(self, parent, text, title="Reggata", buttons=[QMessageBox.Ok], detailedText=None): ''' Shows modal QtGui.QMessageBox and returns code of the clicked button. ''' mb = QMessageBox(parent) mb.setText(text) mb.setWindowTitle(title) buttonsCode = QMessageBox.NoButton for button in buttons: buttonsCode = buttonsCode | button mb.setStandardButtons(buttonsCode) if not helpers.is_none_or_empty(detailedText): mb.setDetailedText(detailedText) return mb.exec_()
def __addStoredOrUntrackedFile(self, persistentItem, newSrcAbsPath, newDstRelPath, userLogin): assert not hlp.is_none_or_empty(newDstRelPath) # Check if a newSrcAbsPath points to an already stored file newSrcRelPath = os.path.relpath(newSrcAbsPath, self._repoBasePath) existingDataRef = self._session.query(db.DataRef).filter( db.DataRef.url_raw==hlp.to_db_format(newSrcRelPath)).first() isNewFileStored = existingDataRef is not None if isNewFileStored: # NOTE: newDstRelPath is ignored in this case... operations.ItemOperations.addStoredFile(self._session, persistentItem, self._repoBasePath, existingDataRef) else: operations.ItemOperations.addUntrackedFile(self._session, persistentItem, self._repoBasePath, newSrcAbsPath, newDstRelPath, userLogin)
def __initFavoriteReposMenu(self): assert len(self.__favoriteReposDynamicQActions) == 0 if self._model.user is None: return actionToInsertBefore = self.ui.menuFavoriteRepos.insertSeparator(self.ui.actionAdd_current_repository) login = self._model.user.login favoriteReposInfo = self._model.favoriteRepos(login) for repoBasePath, repoAlias in favoriteReposInfo: if helpers.is_none_or_empty(repoBasePath): continue action = QtGui.QAction(self) action.setText(repoAlias) action.repoBasePath = repoBasePath self._model.connectOpenFavoriteRepoAction(action) self.ui.menuFavoriteRepos.insertAction(actionToInsertBefore, action) self.__favoriteReposDynamicQActions.append(action)
def handle(self): logger.info("RenameFileActionHandler.handle invoked") try: self._tool.checkActiveRepoIsNotNone() self._tool.checkActiveUserIsNotNone() selFiles = self._tool.gui.selectedFiles() if len(selFiles) != 1: raise err.MsgException( self.tr("Please select one file or directory")) selFile = selFiles[0] newName, isOk = self._dialogs.execGetTextDialog( self._tool.gui, self.tr("Rename File"), self.tr("Enter new file name:"), os.path.basename(selFile)) if not isOk or newName == os.path.basename(selFile): return if is_none_or_empty(newName.strip()): raise err.MsgException( self.tr("Wrong input, file name cannot be empty.")) if os.path.isdir(selFile): self.__renameDir(selFile, newName) elif os.path.isfile(selFile): self.__renameFile(selFile, newName) else: raise err.MsgException( self. tr("Cannot rename '{}' because it is not a file or directory." .format(selFile))) self._emitHandlerSignal(HandlerSignals.STATUS_BAR_MESSAGE, self.tr("Done."), consts.STATUSBAR_TIMEOUT) self._emitHandlerSignal(HandlerSignals.ITEM_CHANGED) stats.sendEvent("file_browser.rename_file") except Exception as ex: show_exc_info(self._tool.gui, ex)
def __addStoredOrUntrackedFile(self, persistentItem, newSrcAbsPath, newDstRelPath, userLogin): assert not hlp.is_none_or_empty(newDstRelPath) # Check if a newSrcAbsPath points to an already stored file newSrcRelPath = os.path.relpath(newSrcAbsPath, self._repoBasePath) existingDataRef = self._session.query(db.DataRef).filter( db.DataRef.url_raw == hlp.to_db_format(newSrcRelPath)).first() isNewFileStored = existingDataRef is not None if isNewFileStored: # NOTE: newDstRelPath is ignored in this case... operations.ItemOperations.addStoredFile(self._session, persistentItem, self._repoBasePath, existingDataRef) else: operations.ItemOperations.addUntrackedFile( self._session, persistentItem, self._repoBasePath, newSrcAbsPath, newDstRelPath, userLogin)
def mouseDoubleClickEvent(self, e): if self.keywordAll: self.emit(QtCore.SIGNAL("selectedKeywordAll")) self.refresh() stats.sendEvent("tag_cloud.all_clicked") return if not is_none_or_empty(self.word): word = self.word if parsers.query_tokens.needs_quote(word): word = parsers.util.quote(word) if e.modifiers() == Qt.ControlModifier: self.not_tags.add(word) else: self.tags.add(word) self.emit(QtCore.SIGNAL("selectedTagsChanged"), self.tags, self.not_tags) self.refresh() stats.sendEvent("tag_cloud.tag_clicked") return
def __initFavoriteReposMenu(self): assert len(self.__favoriteReposDynamicQActions) == 0 if self._model.user is None: return actionToInsertBefore = self.ui.menuFavoriteRepos.insertSeparator( self.ui.actionAdd_current_repository) login = self._model.user.login favoriteReposInfo = self._model.favoriteRepos(login) for repoBasePath, repoAlias in favoriteReposInfo: if helpers.is_none_or_empty(repoBasePath): continue action = QtGui.QAction(self) action.setText(repoAlias) action.repoBasePath = repoBasePath self._model.connectOpenFavoriteRepoAction(action) self.ui.menuFavoriteRepos.insertAction(actionToInsertBefore, action) self.__favoriteReposDynamicQActions.append(action)
def addSingleItem(tool, dialogs, file=None): ''' Creates and saves in repo an Item linked with a given file (or without file). Returns id of saved Item, or raises an exception. ''' savedItemId = None item = db.Item(user_login=tool.user.login) if not hlp.is_none_or_empty(file): file = os.path.normpath(file) item.title, _ = os.path.splitext(os.path.basename(file)) item.data_ref = db.DataRef(objType=db.DataRef.FILE, url=file) if not dialogs.execItemDialog(item=item, gui=tool.gui, repo=tool.repo, dialogMode=ItemDialog.CREATE_MODE): raise err.CancelOperationError("User cancelled operation.") uow = tool.repo.createUnitOfWork() try: srcAbsPath = None dstRelPath = None if item.data_ref is not None: srcAbsPath = item.data_ref.srcAbsPath dstRelPath = item.data_ref.dstRelPath cmd = cmds.SaveNewItemCommand(item, srcAbsPath, dstRelPath) thread = BackgrThread(tool.gui, uow.executeCommand, cmd) dialogs.startThreadWithWaitDialog(thread, tool.gui, indeterminate=True) savedItemId = thread.result finally: uow.close() return savedItemId
def keyPressEvent(self, event): cursor = self.textCursor() cursor.select(QtGui.QTextCursor.WordUnderCursor) word = cursor.selectedText() word = word if not is_none_or_empty(word) else "" if self.completer is not None and event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_Space: self.completer.filter(word) self.show_completer() super(TextEdit, self).keyPressEvent(event) # TODO When user press Ctrl+Space, completer is shown, but TextEdit cursor becomes hidden! Why? elif self.one_line and event.key() in [Qt.Key_Enter, Qt.Key_Return]: # This signal is for QLineEdit behaviour self.emit(QtCore.SIGNAL("returnPressed()")) elif event.key() in [ Qt.Key_Backspace, Qt.Key_Delete, Qt.Key_Up, Qt.Key_Down, Qt.Key_Left, Qt.Key_Right, Qt.Key_End, Qt.Key_Home, Qt.Key_Shift, Qt.Key_Alt, Qt.Key_Control, ]: super(TextEdit, self).keyPressEvent(event) elif len(word) > 0: self.completer.filter(word) if self.completer.count() > 0: self.show_completer() super(TextEdit, self).keyPressEvent(event) else: super(TextEdit, self).keyPressEvent(event)
def handle(self): logger.info("RenameFileActionHandler.handle invoked") try: self._tool.checkActiveRepoIsNotNone() self._tool.checkActiveUserIsNotNone() selFiles = self._tool.gui.selectedFiles() if len(selFiles) != 1: raise err.MsgException(self.tr("Please select one file or directory")) selFile = selFiles[0] newName, isOk = self._dialogs.execGetTextDialog( self._tool.gui, self.tr("Rename File"), self.tr("Enter new file name:"), os.path.basename(selFile)) if not isOk or newName == os.path.basename(selFile): return if is_none_or_empty(newName.strip()): raise err.MsgException(self.tr("Wrong input, file name cannot be empty.")) if os.path.isdir(selFile): self.__renameDir(selFile, newName) elif os.path.isfile(selFile): self.__renameFile(selFile, newName) else: raise err.MsgException(self.tr( "Cannot rename '{}' because it is not a file or directory." .format(selFile))) self._emitHandlerSignal(HandlerSignals.STATUS_BAR_MESSAGE, self.tr("Done."), consts.STATUSBAR_TIMEOUT) self._emitHandlerSignal(HandlerSignals.ITEM_CHANGED) stats.sendEvent("file_browser.rename_file") except Exception as ex: show_exc_info(self._tool.gui, ex)
def buttonMoveFile(self): try: if self.item.data_ref is None: raise Exception(self.tr("You must add a file first.")) directory = QtGui.QFileDialog.getExistingDirectory( self, self.tr("Select destination path within repository"), self.repoBasePath) if is_none_or_empty(directory): return if not is_internal(directory, self.repoBasePath): raise MsgException(self.tr("Chosen directory is out of active repository.")) new_dst_path = os.path.relpath(directory, self.repoBasePath) if not new_dst_path.startswith("."): new_dst_path = os.path.join(".", new_dst_path) newDstRelPath = os.path.join(new_dst_path, os.path.basename(self.item.data_ref.url)) self.ui.fileRelPath.setText(newDstRelPath) except Exception as ex: show_exc_info(self, ex)
def addSingleItem(tool, dialogs, file=None): ''' Creates and saves in repo an Item linked with a given file (or without file). Returns id of saved Item, or raises an exception. ''' savedItemId = None item = db.Item(user_login=tool.user.login) if not hlp.is_none_or_empty(file): file = os.path.normpath(file) item.title, _ = os.path.splitext(os.path.basename(file)) item.data_ref = db.DataRef(objType=db.DataRef.FILE, url=file) if not dialogs.execItemDialog( item=item, gui=tool.gui, repo=tool.repo, dialogMode=ItemDialog.CREATE_MODE): raise err.CancelOperationError("User cancelled operation.") uow = tool.repo.createUnitOfWork() try: srcAbsPath = None dstRelPath = None if item.data_ref is not None: srcAbsPath = item.data_ref.srcAbsPath dstRelPath = item.data_ref.dstRelPath cmd = cmds.SaveNewItemCommand(item, srcAbsPath, dstRelPath) thread = BackgrThread(tool.gui, uow.executeCommand, cmd) dialogs.startThreadWithWaitDialog( thread, tool.gui, indeterminate=True) savedItemId = thread.result finally: uow.close() return savedItemId
def test_isNoneOrEmpty_nonEmptyStr(self): nonEmptyStr = "Reggata" self.assertFalse(helpers.is_none_or_empty(nonEmptyStr))
def test_isNoneOrEmpty_none(self): noneObj = None self.assertTrue(helpers.is_none_or_empty(noneObj))
def _set_data_ref_url(self, value): if not is_none_or_empty(self.data_ref_hash): self.data_ref_url_raw = helpers.to_db_format(value) else: self.data_ref_url_raw = value
def test_isNoneOrEmpty_empty(self): emptyStr = "" self.assertTrue(helpers.is_none_or_empty(emptyStr))
def isUserGaveTheAnswerAboutSendStatistics(): sendStatistics = UserConfig().get("send_statistics") return False if hlp.is_none_or_empty(sendStatistics) else True
def registerColumn(self, col, isVisible=True): assert not helpers.is_none_or_empty(col.id) assert not self.isColumnIdRegistered(col.id) self._allColumns.append(col) if isVisible: self._visibleColumns.append(col)
def isReggataInstanceRegistered(): instanceId = reggataInstanceId() return False if hlp.is_none_or_empty(instanceId) else True