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 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 _execute(self, uow): session = uow.session repoBasePath = uow._repo_base_path if not hlp.is_internal(self._srcFileAbsPath, repoBasePath): raise err.WrongValueError( "File '{}' is outside of the repository".format( self._srcFileAbsPath)) if not hlp.is_internal(self._dstFileAbsPath, repoBasePath): raise err.WrongValueError( "File '{}' is outside of the repository".format( self._dstFileAbsPath)) if not os.path.exists(self._srcFileAbsPath): raise err.NotExistError("File '{}' doesn't exist".format( self._srcFileAbsPath)) if os.path.exists(self._dstFileAbsPath): raise err.FileAlreadyExistsError( "Cannot move file: destination file '{}' already exists.". format(self._dstFileAbsPath)) dstFileRelPath = os.path.relpath(self._dstFileAbsPath, repoBasePath) dstDataRef = session.query(db.DataRef).filter( db.DataRef.url_raw == hlp.to_db_format(dstFileRelPath)).first() if dstDataRef is not None: raise err.DataRefAlreadyExistsError( "Cannot move file: there is a hanging DataRef object, that references to file '{}'" .format(dstFileRelPath)) srcFileRelPath = os.path.relpath(self._srcFileAbsPath, repoBasePath) srcDataRef = session.query(db.DataRef).filter( db.DataRef.url_raw == hlp.to_db_format(srcFileRelPath)).first() if srcDataRef is not None: srcDataRef.url = os.path.relpath(self._dstFileAbsPath, repoBasePath) if not os.path.exists(os.path.dirname(self._dstFileAbsPath)): os.makedirs(os.path.dirname(self._dstFileAbsPath), exist_ok=True) shutil.move(self._srcFileAbsPath, self._dstFileAbsPath) session.commit()
def handle(self): logger.info("MoveFilesActionHandler.handle invoked") try: self._tool.checkActiveRepoIsNotNone() self._tool.checkActiveUserIsNotNone() selFilesAndDirs = self._tool.gui.selectedFiles() selFilesAndDirs = MoveFilesActionHandler.__filterSelectedFilesDirs( selFilesAndDirs) selFileAbsPaths = self.__getListOfAllAffectedFiles(selFilesAndDirs) if len(selFileAbsPaths) == 0: return dstDir = self._dialogs.getExistingDirectory( self._tool.gui, self.tr("Select destination directory")) if not dstDir: return if not hlp.is_internal(dstDir, self._tool.repo.base_path): raise err.WrongValueError( self. tr("Selected directory should be within the current repo")) dstFileAbsPaths = [] currDir = self._tool.currDir for absFile in selFileAbsPaths: relFile = os.path.relpath(absFile, currDir) dstAbsFile = os.path.join(dstDir, relFile) dstFileAbsPaths.append((absFile, dstAbsFile)) thread = MoveFilesThread(self._tool.gui, self._tool.repo, dstFileAbsPaths, selFilesAndDirs) self._dialogs.startThreadWithWaitDialog(thread, self._tool.gui, indeterminate=False) if thread.errors > 0: self._dialogs.execMessageBox( self._tool.gui, text="There were {} errors.".format(thread.errors), detailedText=thread.detailed_message) self._emitHandlerSignal(HandlerSignals.STATUS_BAR_MESSAGE, self.tr("Done."), consts.STATUSBAR_TIMEOUT) self._emitHandlerSignal(HandlerSignals.ITEM_CHANGED) stats.sendEvent("file_browser.move_files") except Exception as ex: show_exc_info(self._tool.gui, ex)
def _execute(self, uow): session = uow.session repoBasePath = uow._repo_base_path if not hlp.is_internal(self._srcFileAbsPath, repoBasePath): raise err.WrongValueError("File '{}' is outside of the repository".format(self._srcFileAbsPath)) if not hlp.is_internal(self._dstFileAbsPath, repoBasePath): raise err.WrongValueError("File '{}' is outside of the repository".format(self._dstFileAbsPath)) if not os.path.exists(self._srcFileAbsPath): raise err.NotExistError("File '{}' doesn't exist".format(self._srcFileAbsPath)) if os.path.exists(self._dstFileAbsPath): raise err.FileAlreadyExistsError( "Cannot move file: destination file '{}' already exists." .format(self._dstFileAbsPath)) dstFileRelPath = os.path.relpath(self._dstFileAbsPath, repoBasePath) dstDataRef = session.query(db.DataRef).filter( db.DataRef.url_raw==hlp.to_db_format(dstFileRelPath)).first() if dstDataRef is not None: raise err.DataRefAlreadyExistsError( "Cannot move file: there is a hanging DataRef object, that references to file '{}'" .format(dstFileRelPath)) srcFileRelPath = os.path.relpath(self._srcFileAbsPath, repoBasePath) srcDataRef = session.query(db.DataRef).filter( db.DataRef.url_raw==hlp.to_db_format(srcFileRelPath)).first() if srcDataRef is not None: srcDataRef.url = os.path.relpath(self._dstFileAbsPath, repoBasePath) if not os.path.exists(os.path.dirname(self._dstFileAbsPath)): os.makedirs(os.path.dirname(self._dstFileAbsPath), exist_ok=True) shutil.move(self._srcFileAbsPath, self._dstFileAbsPath) session.commit()
def changeDir(self, directory): if directory == ".": directory = self._currDir if directory == "..": directory, _ = os.path.split(self._currDir) if not os.path.exists(directory): raise NotExistError(directory + " not exists on the file system.") if not helpers.is_internal(directory, self.repoBasePath()): raise ValueError(directory + " is outside the repository.") if os.path.isfile(directory): raise ValueError(directory + " is not a directory but a file.") assert os.path.isabs(directory) self.__setCurrDir(directory)
def changeDir(self, directory): if directory == ".": directory = self._currDir if directory == "..": directory, _ = os.path.split(self._currDir) if not os.path.exists(directory): raise NotExistError(directory + " not exists on the file system.") if not helpers.is_internal(directory, self.repoBasePath()): raise ValueError(directory + " is outside the repository.") if os.path.isfile(directory): raise ValueError(directory + " is not a directory but a file.") assert os.path.isabs(directory) self.__setCurrDir(directory)
def selectLocationDirRelPath(self): try: if self.mode == ItemsDialog.EDIT_MODE and not self.groupHasFiles: raise MsgException(self.tr( "Selected group of items doesn't reference any physical files on filesysem.")) selDir = QtGui.QFileDialog.getExistingDirectory(self, self.tr("Select destination path within repository"), self.repoBasePath) if not selDir: return if not is_internal(selDir, self.repoBasePath): raise MsgException(self.tr("Chosen directory is out of opened repository.")) self.dstPath = os.path.relpath(selDir, self.repoBasePath) self.ui.locationDirRelPath.setText(self.dstPath) except Exception as ex: show_exc_info(self, ex)
def handle(self): logger.info("MoveFilesActionHandler.handle invoked") try: self._tool.checkActiveRepoIsNotNone() self._tool.checkActiveUserIsNotNone() selFilesAndDirs = self._tool.gui.selectedFiles() selFilesAndDirs = MoveFilesActionHandler.__filterSelectedFilesDirs(selFilesAndDirs) selFileAbsPaths = self.__getListOfAllAffectedFiles(selFilesAndDirs) if len(selFileAbsPaths) == 0: return dstDir = self._dialogs.getExistingDirectory(self._tool.gui, self.tr("Select destination directory")) if not dstDir: return if not hlp.is_internal(dstDir, self._tool.repo.base_path): raise err.WrongValueError(self.tr("Selected directory should be within the current repo")) dstFileAbsPaths = [] currDir = self._tool.currDir for absFile in selFileAbsPaths: relFile = os.path.relpath(absFile, currDir) dstAbsFile = os.path.join(dstDir, relFile) dstFileAbsPaths.append((absFile, dstAbsFile)) thread = MoveFilesThread(self._tool.gui, self._tool.repo, dstFileAbsPaths, selFilesAndDirs) self._dialogs.startThreadWithWaitDialog(thread, self._tool.gui, indeterminate=False) if thread.errors > 0: self._dialogs.execMessageBox(self._tool.gui, text="There were {} errors.".format(thread.errors), detailedText=thread.detailed_message) self._emitHandlerSignal(HandlerSignals.STATUS_BAR_MESSAGE, self.tr("Done."), consts.STATUSBAR_TIMEOUT) self._emitHandlerSignal(HandlerSignals.ITEM_CHANGED) stats.sendEvent("file_browser.move_files") except Exception as ex: show_exc_info(self._tool.gui, ex)
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 _execute(self, uow): session = uow.session repoBasePath = uow._repo_base_path if not hlp.is_internal(self._fileAbsPath, repoBasePath): raise err.WrongValueError("File '{}' is outside of the repository".format(self._fileAbsPath)) if not os.path.exists(self._fileAbsPath): raise err.NotExistError("File '{}' doesn't exist".format(self._fileAbsPath)) fileRelPath = os.path.relpath(self._fileAbsPath, repoBasePath) dataRef = session.query(db.DataRef).filter( db.DataRef.url_raw==hlp.to_db_format(fileRelPath)).first() if dataRef is not None: for item in dataRef.items: session.delete(item) session.delete(dataRef) os.remove(self._fileAbsPath) session.commit()
def _execute(self, uow): session = uow.session repoBasePath = uow._repo_base_path if not hlp.is_internal(self._fileAbsPath, repoBasePath): raise err.WrongValueError( "File '{}' is outside of the repository".format( self._fileAbsPath)) if not os.path.exists(self._fileAbsPath): raise err.NotExistError("File '{}' doesn't exist".format( self._fileAbsPath)) fileRelPath = os.path.relpath(self._fileAbsPath, repoBasePath) dataRef = session.query(db.DataRef).filter( db.DataRef.url_raw == hlp.to_db_format(fileRelPath)).first() if dataRef is not None: for item in dataRef.items: session.delete(item) session.delete(dataRef) os.remove(self._fileAbsPath) session.commit()
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 read(self): ''' Function updates all dialog GUI elements according to self.item object data. ''' self.ui.lineEdit_id.setText(str(self.item.id)) self.ui.lineEdit_user_login.setText(self.item.user_login) self.ui.lineEdit_title.setText(self.item.title) # TODO: data_ref.url should be always a relative path. data_ref.srcAbsPath should be used... if self.item.data_ref: #Make an absolute path to the DataRef file fileAbsPath = self.item.data_ref.url if not os.path.isabs(fileAbsPath): fileAbsPath = os.path.join(self.repoBasePath, fileAbsPath) self.ui.fileAbsPath.setText(fileAbsPath) if not os.path.exists(fileAbsPath): self.ui.srcAbsPathErrorLabel.setText( '<html><font color="red">' + self.tr("Error: File not found")) locationDirRelPath = None if self.mode == ItemDialog.EDIT_MODE or self.mode == ItemDialog.VIEW_MODE: locationDirRelPath = os.path.join(".", self.item.data_ref.url) elif self.mode == ItemDialog.CREATE_MODE: # TODO: use data_ref.srcAbsPath if helpers.is_internal(fileAbsPath, self.repoBasePath): locationDirRelPath = os.path.relpath( fileAbsPath, self.repoBasePath) else: locationDirRelPath = os.path.basename( self.item.data_ref.url) locationDirRelPath = os.path.join(".", locationDirRelPath) self.ui.fileRelPath.setText(locationDirRelPath) #Displaying item's list of field-values s = "" for itf in self.item.item_fields: #Processing reserved fields if itf.field.name in consts.RESERVED_FIELDS: if itf.field.name == consts.NOTES_FIELD: self.ui.plainTextEdit_notes.setPlainText(itf.field_value) elif itf.field.name == consts.RATING_FIELD: try: rating = int(itf.field_value) except: rating = 0 self.ui.spinBox_rating.setValue(rating) else: raise MsgException( self.tr("Unknown reserved field name '{}'").format( itf.field.name)) #Processing all other fields else: name = quote(itf.field.name) if definition_tokens.needs_quote(itf.field.name) \ else itf.field.name value = quote(itf.field_value) if definition_tokens.needs_quote(itf.field_value) \ else itf.field_value s = s + name + ": " + value + os.linesep self.ui.plainTextEdit_fields.setPlainText(s) #Displaying item's list of tags s = "" for itg in self.item.item_tags: tag_name = itg.tag.name s = s + (quote(tag_name) if definition_tokens.needs_quote(tag_name) else tag_name) + " " self.ui.plainTextEdit_tags.setPlainText(s)
def read(self): ''' Function updates all dialog GUI elements according to self.item object data. ''' self.ui.lineEdit_id.setText(str(self.item.id)) self.ui.lineEdit_user_login.setText(self.item.user_login) self.ui.lineEdit_title.setText(self.item.title) # TODO: data_ref.url should be always a relative path. data_ref.srcAbsPath should be used... if self.item.data_ref: #Make an absolute path to the DataRef file fileAbsPath = self.item.data_ref.url if not os.path.isabs(fileAbsPath): fileAbsPath = os.path.join(self.repoBasePath, fileAbsPath) self.ui.fileAbsPath.setText(fileAbsPath) if not os.path.exists(fileAbsPath): self.ui.srcAbsPathErrorLabel.setText('<html><font color="red">' + self.tr("Error: File not found")) locationDirRelPath = None if self.mode == ItemDialog.EDIT_MODE or self.mode == ItemDialog.VIEW_MODE: locationDirRelPath = os.path.join(".", self.item.data_ref.url) elif self.mode == ItemDialog.CREATE_MODE: # TODO: use data_ref.srcAbsPath if helpers.is_internal(fileAbsPath, self.repoBasePath): locationDirRelPath = os.path.relpath(fileAbsPath, self.repoBasePath) else: locationDirRelPath = os.path.basename(self.item.data_ref.url) locationDirRelPath = os.path.join(".", locationDirRelPath) self.ui.fileRelPath.setText(locationDirRelPath) #Displaying item's list of field-values s = "" for itf in self.item.item_fields: #Processing reserved fields if itf.field.name in consts.RESERVED_FIELDS: if itf.field.name == consts.NOTES_FIELD: self.ui.plainTextEdit_notes.setPlainText(itf.field_value) elif itf.field.name == consts.RATING_FIELD: try: rating = int(itf.field_value) except: rating = 0 self.ui.spinBox_rating.setValue(rating) else: raise MsgException( self.tr("Unknown reserved field name '{}'").format(itf.field.name)) #Processing all other fields else: name = quote(itf.field.name) if definition_tokens.needs_quote(itf.field.name) \ else itf.field.name value = quote(itf.field_value) if definition_tokens.needs_quote(itf.field_value) \ else itf.field_value s = s + name + ": " + value + os.linesep self.ui.plainTextEdit_fields.setPlainText(s) #Displaying item's list of tags s = "" for itg in self.item.item_tags: tag_name = itg.tag.name s = s + (quote(tag_name) if definition_tokens.needs_quote(tag_name) else tag_name) + " " self.ui.plainTextEdit_tags.setPlainText(s)