def test_replaceFileOfItemWithAnotherInnerStoredFile(self): # File of new DataRef will be from the same repo, and it will be # a stored file (linked with some other item) item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertIsNotNone(item) self.assertIsNotNone(item.data_ref) self.assertEqual(hlp.to_db_format(item.data_ref.url), context.itemWithTagsAndFields.relFilePath) self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, item.data_ref.url))) # Link file with the item relUrl = context.itemWithFile.relFilePath absUrl = os.path.abspath(os.path.join(self.repo.base_path, relUrl)) self.assertTrue(os.path.exists(absUrl)) self.updateExistingItem(item, absUrl, relUrl, item.user_login) item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertEqual(item.title, context.itemWithTagsAndFields.title) self.assertIsNotNone(item.data_ref) self.assertEqual(item.data_ref.url, relUrl) self.assertTrue(os.path.exists(absUrl)) #Two different items now share same DataRef otherItem = self.getExistingItem(context.itemWithFile.id) self.assertIsNotNone(otherItem.data_ref) self.assertEquals(item.data_ref.id, otherItem.data_ref.id) # Old physical file should not be deleted self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, context.itemWithTagsAndFields.relFilePath))) #Old DataRef should not be deleted after this operation dataRef = self.getDataRef(context.itemWithTagsAndFields.relFilePath) self.assertIsNone(dataRef)
def test_moveFileOfItemToAnotherLocationWithinRepoAndRename(self): item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertEqual(item.title, context.itemWithTagsAndFields.title) self.assertIsNotNone(item.data_ref) self.assertTrue( os.path.exists(os.path.join(self.repo.base_path, item.data_ref.url))) # Move linked file to another location within the repository # NOTE: File will be not only moved, but also renamed newSrcAbsPath = os.path.join(self.repo.base_path, item.data_ref.url) path = ["new", "location", "for", "file", "could_have_lied_lyrics.txt"] newDstRelPath = os.path.join(*path) self.updateExistingItem(item, newSrcAbsPath, newDstRelPath, item.user_login) item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertEqual(item.title, context.itemWithTagsAndFields.title) self.assertIsNotNone(item.data_ref) self.assertEqual(hlp.to_db_format(item.data_ref.url), "new/location/for/file/could_have_lied_lyrics.txt") self.assertFalse( os.path.isdir(os.path.join(self.repo.base_path, *path))) self.assertTrue( os.path.exists(os.path.join(self.repo.base_path, *path)))
def test_replaceFileOfItemWithAnotherInnerFile(self): # File of new DataRef will be from the same repo. # But the new file is not a stored file (it has no corresponding DataRef object) item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertIsNotNone(item) self.assertIsNotNone(item.data_ref) self.assertEqual(hlp.to_db_format(item.data_ref.url), context.itemWithTagsAndFields.relFilePath) self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, item.data_ref.url))) # Link file with the item relUrl = os.path.join("this", "is", "untracked", "file.txt") absUrl = os.path.abspath(os.path.join(self.repo.base_path, relUrl)) self.assertTrue(os.path.exists(absUrl)) self.updateExistingItem(item, absUrl, relUrl, item.user_login) item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertEqual(item.title, context.itemWithTagsAndFields.title) self.assertIsNotNone(item.data_ref) self.assertEqual(item.data_ref.url, relUrl) self.assertTrue(os.path.exists(absUrl)) # Old physical file should not be deleted self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, context.itemWithTagsAndFields.relFilePath))) #Old DataRef should be deleted after this operation dataRef = self.getDataRef(context.itemWithTagsAndFields.relFilePath) self.assertIsNone(dataRef)
def test_replaceFileOfItemWithAnotherInnerFile(self): # File of new DataRef will be from the same repo. # But the new file is not a stored file (it has no corresponding DataRef object) item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertIsNotNone(item) self.assertIsNotNone(item.data_ref) self.assertEqual(hlp.to_db_format(item.data_ref.url), context.itemWithTagsAndFields.relFilePath) self.assertTrue( os.path.exists(os.path.join(self.repo.base_path, item.data_ref.url))) # Link file with the item relUrl = os.path.join("this", "is", "untracked", "file.txt") absUrl = os.path.abspath(os.path.join(self.repo.base_path, relUrl)) self.assertTrue(os.path.exists(absUrl)) self.updateExistingItem(item, absUrl, relUrl, item.user_login) item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertEqual(item.title, context.itemWithTagsAndFields.title) self.assertIsNotNone(item.data_ref) self.assertEqual(item.data_ref.url, relUrl) self.assertTrue(os.path.exists(absUrl)) # Old physical file should not be deleted self.assertTrue( os.path.exists( os.path.join(self.repo.base_path, context.itemWithTagsAndFields.relFilePath))) #Old DataRef should be deleted after this operation dataRef = self.getDataRef(context.itemWithTagsAndFields.relFilePath) self.assertIsNone(dataRef)
def test_saveNewItemWithACopyOfAStoredFileInRepo(self): ''' User wants to add a copy of a stored file from the repo into the same repo but to the another location. The copy of the original file will be attached to the new Item object. ''' item = db.Item("user", "Item's title") self.srcAbsPath = os.path.abspath(os.path.join( self.repo.base_path, "lyrics", "led_zeppelin", "stairway_to_heaven.txt")) self.dstRelPath = os.path.join("dir1", "dir2", "dir3", "copy_of_stairway_to_heaven.txt") try: uow = self.repo.createUnitOfWork() cmd = cmds.SaveNewItemCommand(item, self.srcAbsPath, self.dstRelPath) self.savedItemId = uow.executeCommand(cmd) finally: uow.close() try: uow = self.repo.createUnitOfWork() savedItem = uow.executeCommand(cmds.GetExpungedItemCommand(self.savedItemId)) self.assertEqual(savedItem.title, item.title) self.assertIsNotNone(savedItem.data_ref) self.assertEqual(savedItem.data_ref.url_raw, hlp.to_db_format(self.dstRelPath)) self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, savedItem.data_ref.url))) self.assertTrue(os.path.exists(self.srcAbsPath)) finally: uow.close()
def test_saveNewItemWithFileInsideRepo(self): ''' There is an untracked file inside the repo tree. User wants to add such file into the repo to make it a stored file. File is not copied, because it is alredy in the repo tree. It's essential that srcAbsPath and dstRelPath point to the same file. ''' item = db.Item("user", "Item's title") self.srcAbsPath = os.path.abspath(os.path.join( self.repo.base_path, "this", "is", "untracked", "file.txt")) self.dstRelPath = os.path.join("this", "is", "untracked", "file.txt") try: uow = self.repo.createUnitOfWork() cmd = cmds.SaveNewItemCommand(item, self.srcAbsPath, self.dstRelPath) self.savedItemId = uow.executeCommand(cmd) finally: uow.close() try: uow = self.repo.createUnitOfWork() savedItem = uow.executeCommand(cmds.GetExpungedItemCommand(self.savedItemId)) self.assertEqual(savedItem.title, item.title) self.assertIsNotNone(savedItem.data_ref) self.assertEqual(savedItem.data_ref.url_raw, hlp.to_db_format(self.dstRelPath)) self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, savedItem.data_ref.url))) finally: uow.close()
def test_saveNewItemWithFileOutsideRepo(self): ''' User wants to add an external file into the repo. File is copied to the repo. ''' item = db.Item("user", "Item's title") self.srcAbsPath = os.path.abspath(os.path.join(self.repo.base_path, "..", "tmp", "file.txt")) self.dstRelPath = os.path.join("dir1", "dir2", "dir3", "newFile.txt") try: uow = self.repo.createUnitOfWork() cmd = cmds.SaveNewItemCommand(item, self.srcAbsPath, self.dstRelPath) self.savedItemId = uow.executeCommand(cmd) finally: uow.close() try: uow = self.repo.createUnitOfWork() savedItem = uow.executeCommand(cmds.GetExpungedItemCommand(self.savedItemId)) self.assertEqual(savedItem.title, item.title) self.assertIsNotNone(savedItem.data_ref) self.assertEqual(savedItem.data_ref.url_raw, hlp.to_db_format(self.dstRelPath)) self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, savedItem.data_ref.url))) self.assertTrue(os.path.exists(self.srcAbsPath)) finally: uow.close()
def test_addRecursivelyDirFromOutsideOfRepo(self): user = User(login="******", password="") srcDirAbsPath = os.path.abspath(os.path.join(self.repo.base_path, "..", "tmp")) dstRelPaths = [] for root, _dirs, files in os.walk(srcDirAbsPath): for file in files: dstRelPath = os.path.relpath(os.path.join(root, file), os.path.join(srcDirAbsPath, "..")) dstRelPaths.append(dstRelPath) tool = TestsToolModel(self.repo, user) dialogs = TestsDialogsFacade(selectedFiles=[srcDirAbsPath]) handler = AddItemsActionHandler(tool, dialogs) handler.handle() self.assertEqual(len(handler.lastSavedItemIds), len(dstRelPaths)) for i, savedItemId in enumerate(handler.lastSavedItemIds): try: uow = self.repo.createUnitOfWork() savedItem = uow.executeCommand(GetExpungedItemCommand(savedItemId)) self.assertIsNotNone(savedItem, "Item should exist") self.assertIsNotNone(savedItem.data_ref, "Item should have a DataRef object") self.assertEqual(savedItem.data_ref.url_raw, to_db_format(dstRelPaths[i]), "Item's file not found in repo") self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, savedItem.data_ref.url)), "Item's file should exist") finally: uow.close()
def test_saveNewItemWithFileOutsideRepo(self): ''' User wants to add an external file into the repo. File is copied to the repo. ''' item = db.Item("user", "Item's title") self.srcAbsPath = os.path.abspath( os.path.join(self.repo.base_path, "..", "tmp", "file.txt")) self.dstRelPath = os.path.join("dir1", "dir2", "dir3", "newFile.txt") try: uow = self.repo.createUnitOfWork() cmd = cmds.SaveNewItemCommand(item, self.srcAbsPath, self.dstRelPath) self.savedItemId = uow.executeCommand(cmd) finally: uow.close() try: uow = self.repo.createUnitOfWork() savedItem = uow.executeCommand( cmds.GetExpungedItemCommand(self.savedItemId)) self.assertEqual(savedItem.title, item.title) self.assertIsNotNone(savedItem.data_ref) self.assertEqual(savedItem.data_ref.url_raw, hlp.to_db_format(self.dstRelPath)) self.assertTrue( os.path.exists( os.path.join(self.repo.base_path, savedItem.data_ref.url))) self.assertTrue(os.path.exists(self.srcAbsPath)) finally: uow.close()
def _execute(self, uow): session = uow.session repoBasePath = uow._repo_base_path dirRelPath = os.path.relpath(self._dirAbsPath, repoBasePath) head, oldDirName = os.path.split(dirRelPath) if self._newDirName == oldDirName: return newDirRelPath = os.path.join(head, self._newDirName) if os.path.exists(os.path.join(repoBasePath, newDirRelPath)): raise err.FileAlreadyExistsError( "Directory '{}' already exists, please choose a different name." .format(self._newDirName)) affectedDataRefs = session.query(db.DataRef).filter( db.DataRef.url_raw.like(to_db_format(dirRelPath) + "/%")) for dataRef in affectedDataRefs: oldAbsFilePath = os.path.join(repoBasePath, dataRef.url) suffix = os.path.relpath(oldAbsFilePath, self._dirAbsPath) dataRef.url = os.path.join(newDirRelPath, suffix) shutil.move(self._dirAbsPath, os.path.join(self._dirAbsPath, "..", self._newDirName)) session.commit()
def test_saveNewItemWithACopyOfAStoredFileInRepo(self): ''' User wants to add a copy of a stored file from the repo into the same repo but to the another location. The copy of the original file will be attached to the new Item object. ''' item = db.Item("user", "Item's title") self.srcAbsPath = os.path.abspath( os.path.join(self.repo.base_path, "lyrics", "led_zeppelin", "stairway_to_heaven.txt")) self.dstRelPath = os.path.join("dir1", "dir2", "dir3", "copy_of_stairway_to_heaven.txt") try: uow = self.repo.createUnitOfWork() cmd = cmds.SaveNewItemCommand(item, self.srcAbsPath, self.dstRelPath) self.savedItemId = uow.executeCommand(cmd) finally: uow.close() try: uow = self.repo.createUnitOfWork() savedItem = uow.executeCommand( cmds.GetExpungedItemCommand(self.savedItemId)) self.assertEqual(savedItem.title, item.title) self.assertIsNotNone(savedItem.data_ref) self.assertEqual(savedItem.data_ref.url_raw, hlp.to_db_format(self.dstRelPath)) self.assertTrue( os.path.exists( os.path.join(self.repo.base_path, savedItem.data_ref.url))) self.assertTrue(os.path.exists(self.srcAbsPath)) finally: uow.close()
def test_addFileFromOutsideOfRepo(self): user = User(login="******", password="") srcAbsPath = os.path.abspath( os.path.join(self.repo.base_path, "..", "tmp", "file.txt")) dstRelPath = "file.txt" self.assertFalse( os.path.exists(os.path.join(self.repo.base_path, dstRelPath)), "Target file should not be already in the repo root") tool = TestsToolModel(self.repo, user) dialogs = TestsDialogsFacade(selectedFiles=[srcAbsPath]) handler = AddItemsActionHandler(tool, dialogs) handler.handle() self.assertEqual(len(handler.lastSavedItemIds), 1) try: uow = self.repo.createUnitOfWork() savedItem = uow.executeCommand( GetExpungedItemCommand(handler.lastSavedItemIds[0])) self.assertIsNotNone(savedItem, "Item should exist") self.assertIsNotNone(savedItem.data_ref, "Item should have a DataRef object") self.assertEqual( savedItem.data_ref.url_raw, to_db_format(dstRelPath), "Item's file should be located in the root of repo") self.assertTrue( os.path.exists( os.path.join(self.repo.base_path, savedItem.data_ref.url)), "Item's file should exist") finally: uow.close()
def test_saveNewItemWithFileInsideRepo(self): ''' There is an untracked file inside the repo tree. User wants to add such file into the repo to make it a stored file. File is not copied, because it is alredy in the repo tree. It's essential that srcAbsPath and dstRelPath point to the same file. ''' item = db.Item("user", "Item's title") self.srcAbsPath = os.path.abspath( os.path.join(self.repo.base_path, "this", "is", "untracked", "file.txt")) self.dstRelPath = os.path.join("this", "is", "untracked", "file.txt") try: uow = self.repo.createUnitOfWork() cmd = cmds.SaveNewItemCommand(item, self.srcAbsPath, self.dstRelPath) self.savedItemId = uow.executeCommand(cmd) finally: uow.close() try: uow = self.repo.createUnitOfWork() savedItem = uow.executeCommand( cmds.GetExpungedItemCommand(self.savedItemId)) self.assertEqual(savedItem.title, item.title) self.assertIsNotNone(savedItem.data_ref) self.assertEqual(savedItem.data_ref.url_raw, hlp.to_db_format(self.dstRelPath)) self.assertTrue( os.path.exists( os.path.join(self.repo.base_path, savedItem.data_ref.url))) finally: uow.close()
def test_addFileToItemWithoutFileWithDestinationInsideRepo(self): # Referenced file for new DataRef will be from the outside of the repo # We will specify the destination path in the repo - where to put the file item = self.getExistingItem(context.itemWithoutFile.id) self.assertEqual(item.title, context.itemWithoutFile.title) self.assertIsNone(item.data_ref) self.assertFalse( os.path.exists( os.path.join(self.repo.base_path, "dir1", "dir2", "file.txt"))) # Link file with the item newSrcAbsPath = os.path.abspath( os.path.join(self.repo.base_path, "..", "tmp", "file.txt")) newDstRelPath = os.path.join("dir1", "dir2", "copied_file.txt") self.updateExistingItem(item, newSrcAbsPath, newDstRelPath, item.user_login) item = self.getExistingItem(context.itemWithoutFile.id) self.assertEqual(item.title, context.itemWithoutFile.title) self.assertIsNotNone(item.data_ref) self.assertEqual(hlp.to_db_format(item.data_ref.url), "dir1/dir2/copied_file.txt") self.assertTrue( os.path.exists( os.path.join(self.repo.base_path, "dir1", "dir2", "copied_file.txt"))) self.assertFalse( os.path.isdir( os.path.join(self.repo.base_path, "dir1", "dir2", "copied_file.txt")))
def test_addFileFromOutsideOfRepo(self): user = User(login="******", password="") srcAbsPath = os.path.abspath(os.path.join(self.repo.base_path, "..", "tmp", "file.txt")) dstRelPath = "file.txt" self.assertFalse(os.path.exists(os.path.join(self.repo.base_path, dstRelPath)), "Target file should not be already in the repo root") tool = TestsToolModel(self.repo, user) dialogs = TestsDialogsFacade(selectedFiles=[srcAbsPath]) handler = AddItemsActionHandler(tool, dialogs) handler.handle() self.assertEqual(len(handler.lastSavedItemIds), 1) try: uow = self.repo.createUnitOfWork() savedItem = uow.executeCommand(GetExpungedItemCommand(handler.lastSavedItemIds[0])) self.assertIsNotNone(savedItem, "Item should exist") self.assertIsNotNone(savedItem.data_ref, "Item should have a DataRef object") self.assertEqual(savedItem.data_ref.url_raw, to_db_format(dstRelPath), "Item's file should be located in the root of repo") self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, savedItem.data_ref.url)), "Item's file should exist") finally: uow.close()
def getDataRefsFromDir(self, dirRelPath): dataRefs = [] try: uow = self.repo.createUnitOfWork() dataRefs = uow._session.query(DataRef).filter( DataRef.url_raw.like(helpers.to_db_format(dirRelPath) + "/%")).all() finally: uow.close() return dataRefs
def _execute(self, uow): items = [] try: items = uow._session.query(db.Item) \ .join(db.Item.data_ref) \ .filter(db.DataRef.url_raw.like(hlp.to_db_format(self._dirRelPath) + "/%")) \ .all() finally: uow.close() return [item.id for item in items]
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 getDataRef(self, url): # In the case when this DataRef is a file, url should be a relative path try: uow = self.repo.createUnitOfWork() dataRef = uow._session.query(DataRef) \ .filter(DataRef.url_raw==helpers.to_db_format(url)).first() # NOTE: dataRef could be None finally: uow.close() return dataRef
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 _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 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 test_moveFileOfItemToAnotherLocationWithinRepo(self): item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertEqual(item.title, context.itemWithTagsAndFields.title) self.assertIsNotNone(item.data_ref) self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, item.data_ref.url))) # Move linked file to another location within the repository newSrcAbsPath = os.path.join(self.repo.base_path, item.data_ref.url) path = ["new", "location", "for", "file", "I Could Have Lied.txt"] newDstRelPath = os.path.join(*path) self.updateExistingItem(item, newSrcAbsPath, newDstRelPath, item.user_login) item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertEqual(item.title, context.itemWithTagsAndFields.title) self.assertIsNotNone(item.data_ref) self.assertEqual(hlp.to_db_format(item.data_ref.url), "new/location/for/file/I Could Have Lied.txt") self.assertFalse(os.path.isdir(os.path.join(self.repo.base_path, *path))) self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, *path)))
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 test_addFileToItemWithoutFileWithDestinationInsideRepo(self): # Referenced file for new DataRef will be from the outside of the repo # We will specify the destination path in the repo - where to put the file item = self.getExistingItem(context.itemWithoutFile.id) self.assertEqual(item.title, context.itemWithoutFile.title) self.assertIsNone(item.data_ref) self.assertFalse(os.path.exists(os.path.join(self.repo.base_path, "dir1", "dir2", "file.txt"))) # Link file with the item newSrcAbsPath = os.path.abspath(os.path.join(self.repo.base_path, "..", "tmp", "file.txt")) newDstRelPath = os.path.join("dir1", "dir2", "copied_file.txt") self.updateExistingItem(item, newSrcAbsPath, newDstRelPath, item.user_login) item = self.getExistingItem(context.itemWithoutFile.id) self.assertEqual(item.title, context.itemWithoutFile.title) self.assertIsNotNone(item.data_ref) self.assertEqual(hlp.to_db_format(item.data_ref.url), "dir1/dir2/copied_file.txt") self.assertTrue(os.path.exists(os.path.join(self.repo.base_path, "dir1", "dir2", "copied_file.txt"))) self.assertFalse(os.path.isdir(os.path.join(self.repo.base_path, "dir1", "dir2", "copied_file.txt")))
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 __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 __getFileInfo(self, path): try: data_ref = self._session.query(db.DataRef)\ .filter(db.DataRef.url_raw==hlp.to_db_format(path))\ .options(joinedload_all("items"))\ .options(joinedload_all("items.item_tags.tag"))\ .options(joinedload_all("items.item_fields.field"))\ .one() self._session.expunge(data_ref) finfo = FileInfo(data_ref.url, objType=FileInfo.FILE, status=FileInfo.STORED) for item in data_ref.items: finfo.itemIds.append(item.id) for item_tag in item.item_tags: finfo.tags.append(item_tag.tag.name) for item_field in item.item_fields: finfo.fields.append((item_field.field.name, item_field.field_value)) return finfo except NoResultFound: return FileInfo(self.__relPath, status=FileInfo.UNTRACKED)
def test_replaceFileOfItemWithAnotherInnerStoredFile(self): # File of new DataRef will be from the same repo, and it will be # a stored file (linked with some other item) item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertIsNotNone(item) self.assertIsNotNone(item.data_ref) self.assertEqual(hlp.to_db_format(item.data_ref.url), context.itemWithTagsAndFields.relFilePath) self.assertTrue( os.path.exists(os.path.join(self.repo.base_path, item.data_ref.url))) # Link file with the item relUrl = context.itemWithFile.relFilePath absUrl = os.path.abspath(os.path.join(self.repo.base_path, relUrl)) self.assertTrue(os.path.exists(absUrl)) self.updateExistingItem(item, absUrl, relUrl, item.user_login) item = self.getExistingItem(context.itemWithTagsAndFields.id) self.assertEqual(item.title, context.itemWithTagsAndFields.title) self.assertIsNotNone(item.data_ref) self.assertEqual(item.data_ref.url, relUrl) self.assertTrue(os.path.exists(absUrl)) #Two different items now share same DataRef otherItem = self.getExistingItem(context.itemWithFile.id) self.assertIsNotNone(otherItem.data_ref) self.assertEquals(item.data_ref.id, otherItem.data_ref.id) # Old physical file should not be deleted self.assertTrue( os.path.exists( os.path.join(self.repo.base_path, context.itemWithTagsAndFields.relFilePath))) #Old DataRef should not be deleted after this operation dataRef = self.getDataRef(context.itemWithTagsAndFields.relFilePath) self.assertIsNone(dataRef)
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 test_addRecursivelyDirFromOutsideOfRepo(self): user = User(login="******", password="") srcDirAbsPath = os.path.abspath( os.path.join(self.repo.base_path, "..", "tmp")) dstRelPaths = [] for root, _dirs, files in os.walk(srcDirAbsPath): for file in files: dstRelPath = os.path.relpath(os.path.join(root, file), os.path.join(srcDirAbsPath, "..")) dstRelPaths.append(dstRelPath) tool = TestsToolModel(self.repo, user) dialogs = TestsDialogsFacade(selectedFiles=[srcDirAbsPath]) handler = AddItemsActionHandler(tool, dialogs) handler.handle() self.assertEqual(len(handler.lastSavedItemIds), len(dstRelPaths)) for i, savedItemId in enumerate(handler.lastSavedItemIds): try: uow = self.repo.createUnitOfWork() savedItem = uow.executeCommand( GetExpungedItemCommand(savedItemId)) self.assertIsNotNone(savedItem, "Item should exist") self.assertIsNotNone(savedItem.data_ref, "Item should have a DataRef object") self.assertEqual(savedItem.data_ref.url_raw, to_db_format(dstRelPaths[i]), "Item's file not found in repo") self.assertTrue( os.path.exists( os.path.join(self.repo.base_path, savedItem.data_ref.url)), "Item's file should exist") finally: uow.close()
def __getFileInfo(self, path): try: data_ref = self._session.query(db.DataRef)\ .filter(db.DataRef.url_raw==hlp.to_db_format(path))\ .options(joinedload_all("items"))\ .options(joinedload_all("items.item_tags.tag"))\ .options(joinedload_all("items.item_fields.field"))\ .one() self._session.expunge(data_ref) finfo = FileInfo(data_ref.url, objType=FileInfo.FILE, status=FileInfo.STORED) for item in data_ref.items: finfo.itemIds.append(item.id) for item_tag in item.item_tags: finfo.tags.append(item_tag.tag.name) for item_field in item.item_fields: finfo.fields.append( (item_field.field.name, item_field.field_value)) return finfo except NoResultFound: return FileInfo(self.__relPath, status=FileInfo.UNTRACKED)
def _set_url(self, value): if self.type == DataRef.FILE and value is not None: value = helpers.to_db_format(value) self.url_raw = value
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