def _get_content(self, content_path_fetcher): path = content_path_fetcher() content_path = self.reduce_path(path) splited_local_path = content_path.strip('/').split('/') workspace_name = webdav_convert_file_name_to_bdd(splited_local_path[0]) wapi = WorkspaceApi( current_user=self.current_user, session=self.dbsession, config=self.app_config, ) workspace = wapi.get_one_by_label(workspace_name) parents = [] if len(splited_local_path) > 2: parent_string = splited_local_path[1:-1] parents = [webdav_convert_file_name_to_bdd(x) for x in parent_string] content_api = ContentApi( config=self.app_config, current_user=self.current_user, session=self.dbsession ) return content_api.get_one_by_filename_and_parent_labels( content_label=webdav_convert_file_name_to_bdd(basename(path)), content_parent_labels=parents, workspace=workspace, )
def _get_content(self, content_path_fetcher): path = content_path_fetcher() content_path = self.reduce_path(path) splited_local_path = content_path.strip('/').split('/') workspace_name = webdav_convert_file_name_to_bdd(splited_local_path[0]) wapi = WorkspaceApi( current_user=self.current_user, session=self.dbsession, config=self.app_config, ) workspace = wapi.get_one_by_label(workspace_name) parents = [] if len(splited_local_path) > 2: parent_string = splited_local_path[1:-1] parents = [ webdav_convert_file_name_to_bdd(x) for x in parent_string ] content_api = ContentApi(config=self.app_config, current_user=self.current_user, session=self.dbsession) return content_api.get_one_by_filename_and_parent_labels( content_label=webdav_convert_file_name_to_bdd(basename(path)), content_parent_labels=parents, workspace=workspace, )
def __init__(self, path: str, current_user: User, session: TracimSession, app_config: CFG): self.path = path self.workspace_api = WorkspaceApi(current_user=current_user, session=session, config=app_config) self.content_api = ContentApi(current_user=current_user, session=session, config=app_config) self.workspaces = [] self.contents = [] path_parts = self._path_splitter(self.path) # TODO - G.M - 2020-10-09 - Find a proper way to refactor this code to make easier to # understood. This code is a bit confusing because: # - distinction between invalid path, proper destination path (for move) and root is not so # clear. # - We do add None value into both self.contents and self.workspaces list. path_parts = self._path_splitter(self.path) if not path_parts: self.workspaces.append(None) return workspace_found = True current_part_index = 0 # Build space hierarchy while workspace_found: try: part = path_parts[current_part_index] filemanager_filename = webdav_convert_file_name_to_bdd(part) parent = self.workspaces[-1] if self.workspaces else None self.workspaces.append( self.workspace_api.get_one_by_filemanager_filename( filemanager_filename, parent=parent)) current_part_index += 1 except (IndexError, WorkspaceNotFound): workspace_found = False # Build content hierarchy if self.workspaces: for part in path_parts[current_part_index:]: try: filemanager_filename = webdav_convert_file_name_to_bdd( part) workspace = self.workspaces[-1] parent = self.contents[-1] if self.contents else None content = self.content_api.get_one_by_filename( filename=filemanager_filename, workspace=workspace, parent=parent, ) except ContentNotFound: content = None self.contents.append(content)
def moveRecursive(self, destpath): # INFO - G.M - 2018-12-11 - We only allow renaming if dirname(normpath( destpath)) == self.environ["http_authenticator.realm"]: # FIXME - G.M - 2018-12-11 - For an unknown reason current_workspace # of tracim_context is here invalid. self.tracim_context._current_workspace = self.workspace try: can_modify_workspace.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) try: workspace_api = WorkspaceApi(current_user=self.user, session=self.session, config=self.provider.app_config) workspace_api.update_workspace( workspace=self.workspace, label=webdav_convert_file_name_to_bdd( basename(normpath(destpath))), description=self.workspace.description, ) self.session.add(self.workspace) self.session.flush() workspace_api.execute_update_workspace_actions(self.workspace) transaction.commit() except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc))
def createCollection(self, label: str) -> 'FolderResource': """ Create a new folder for the current workspace. As it's not possible for the user to choose which types of content are allowed in this folder, we allow allow all of them. This method return the DAVCollection created. """ if '/.deleted/' in self.path or '/.archived/' in self.path: raise DAVError(HTTP_FORBIDDEN) folder_label = webdav_convert_file_name_to_bdd(label) try: folder = self.content_api.create( content_type_slug=content_type_list.Folder.slug, workspace=self.workspace, label=folder_label, parent=self.content ) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc self.content_api.save(folder) transaction.commit() # fixed_path folder_path = '%s/%s' % (self.path, webdav_convert_file_name_to_display(label)) # return item return FolderResource( folder_path, self.environ, content=folder, tracim_context=self.tracim_context, workspace=self.workspace, )
def createCollection(self, name: str): """ This method is called whenever the user wants to create a DAVCollection resource as a child (in our case, we create workspaces as this is the root). [For now] we don't allow to create new workspaces through webdav client. Though if we come to allow it, deleting the error's raise will make it possible. """ # TODO : remove comment here # raise DAVError(HTTP_FORBIDDEN) workspace_name = webdav_convert_file_name_to_bdd(name) new_workspace = self.workspace_api.create_workspace(workspace_name) self.workspace_api.save(new_workspace) transaction.commit() # fix path workspace_path = '%s%s%s' % ( self.path, '' if self.path == '/' else '/', webdav_convert_file_name_to_display(new_workspace.label) ) # create item return WorkspaceResource( workspace_path, self.environ, new_workspace, tracim_context=self.tracim_context )
def createCollection(self, label: str) -> "FolderResource": """ Create a new folder for the current workspace/folder. As it's not possible for the user to choose which types of content are allowed in this folder, we allow allow all of them. This method return the DAVCollection created. """ folder_label = webdav_convert_file_name_to_bdd(label) try: folder = self.content_api.create( content_type_slug=content_type_list.Folder.slug, workspace=self.workspace, label=folder_label, parent=self.content, ) self.content_api.execute_created_content_actions(folder) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) from exc self.content_api.save(folder) transaction.commit() # fixed_path folder_path = "%s/%s" % (self.path, webdav_convert_file_name_to_display(label)) # return item return FolderResource( folder_path, self.environ, content=folder, tracim_context=self.tracim_context, workspace=self.workspace, )
def createCollection(self, name: str): """ This method is called whenever the user wants to create a DAVCollection resource as a child (in our case, we create workspaces as this is the root). [For now] we don't allow to create new workspaces through webdav client. Though if we come to allow it, deleting the error's raise will make it possible. """ # TODO : remove comment here # raise DAVError(HTTP_FORBIDDEN) workspace_name = webdav_convert_file_name_to_bdd(name) try: new_workspace = self.workspace_api.create_workspace(workspace_name) except (UserNotAllowedToCreateMoreWorkspace, EmptyLabelNotAllowed) as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) self.workspace_api.save(new_workspace) self.workspace_api.execute_created_workspace_actions(new_workspace) transaction.commit() # fix path workspace_path = "%s%s%s" % ( self.path, "" if self.path == "/" else "/", webdav_convert_file_name_to_display(new_workspace.label), ) # create item return WorkspaceResource( path=workspace_path, environ=self.environ, workspace=new_workspace, tracim_context=self.tracim_context, label=new_workspace.label, )
def copyMoveSingle(self, destpath, isMove): if isMove: # INFO - G.M - 12-03-2018 - This case should not happen # As far as moveRecursive method exist, all move should not go # through this method. If such case appear, try replace this to : #### # self.move_file(destpath) # return #### raise NotImplementedError("Feature not available") destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) try: can_move_content.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) content_in_context = self.content_api.get_content_in_context( self.content) try: self.content_api.check_upload_size(content_in_context.size or 0, self.content.workspace) except ( FileSizeOverMaxLimitation, FileSizeOverWorkspaceEmptySpace, FileSizeOverOwnerEmptySpace, ) as exc: raise DAVError(HTTP_REQUEST_ENTITY_TOO_LARGE, contextinfo=str(exc)) new_filename = webdav_convert_file_name_to_bdd(basename(destpath)) regex_file_extension = re.compile("(?P<label>.*){}".format( re.escape(self.content.file_extension))) same_extension = regex_file_extension.match(new_filename) if same_extension: new_label = same_extension.group("label") new_file_extension = self.content.file_extension else: new_label, new_file_extension = os.path.splitext(new_filename) self.tracim_context.set_destpath(destpath) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound: destination_parent = None try: new_content = self.content_api.copy( item=self.content, new_label=new_label, new_file_extension=new_file_extension, new_parent=destination_parent, new_workspace=destination_workspace, ) self.content_api.execute_created_content_actions(new_content) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) from exc transaction.commit()
def move_folder(self, destpath): workspace_api = WorkspaceApi( current_user=self.user, session=self.session, config=self.provider.app_config, ) destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound as e: destination_parent = None try: with new_revision( content=self.content, tm=transaction.manager, session=self.session, ): # renaming file if needed if basename(destpath) != self.getDisplayName(): self.content_api.update_content(self.content, webdav_convert_file_name_to_bdd(basename(destpath))) self.content_api.save(self.content) # move file if needed if destination_workspace != self.content.workspace or destination_parent != self.content.parent : self.content_api.move( self.content, new_parent=destination_parent, new_workspace=destination_workspace, must_stay_in_same_workspace=False ) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc transaction.commit()
def move_folder(self, destpath): workspace_api = WorkspaceApi( current_user=self.user, session=self.session, config=self.provider.app_config, ) destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound as e: destination_parent = None try: with new_revision( content=self.content, tm=transaction.manager, session=self.session, ): if basename(destpath) != self.getDisplayName(): self.content_api.update_content( self.content, webdav_convert_file_name_to_bdd(basename(destpath))) self.content_api.save(self.content) else: if destination_workspace.workspace_id == self.content.workspace.workspace_id: self.content_api.move(self.content, destination_parent) else: self.content_api.move_recursively( self.content, destination_parent, destination_workspace) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc transaction.commit()
def copyMoveSingle(self, destpath, isMove): if isMove: # INFO - G.M - 12-03-2018 - This case should not happen # As far as moveRecursive method exist, all move should not go # through this method. If such case appear, try replace this to : #### # self.move_file(destpath) # return #### raise NotImplemented('Feature not available') destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) try: can_move_content.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) new_filename = webdav_convert_file_name_to_bdd(basename(destpath)) regex_file_extension = re.compile( '(?P<label>.*){}'.format(re.escape(self.content.file_extension))) same_extension = regex_file_extension.match(new_filename) if same_extension: new_label = same_extension.group('label') new_file_extension = self.content.file_extension else: new_label, new_file_extension = os.path.splitext(new_filename) self.tracim_context.set_destpath(destpath) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound as e: destination_parent = None workspace = self.content.workspace parent = self.content.parent try: new_content = self.content_api.copy( item=self.content, new_label=new_label, new_file_extension=new_file_extension, new_parent=destination_parent, new_workspace=destination_workspace ) self.content_api.copy_children(self.content, new_content) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc transaction.commit()
def copyMoveSingle(self, destpath, isMove): if isMove: # INFO - G.M - 12-03-2018 - This case should not happen # As far as moveRecursive method exist, all move should not go # through this method. If such case appear, try replace this to : #### # self.move_file(destpath) # return #### raise NotImplemented('Feature not available') destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) try: can_move_content.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) new_filename = webdav_convert_file_name_to_bdd(basename(destpath)) regex_file_extension = re.compile('(?P<label>.*){}'.format( re.escape(self.content.file_extension))) same_extension = regex_file_extension.match(new_filename) if same_extension: new_label = same_extension.group('label') new_file_extension = self.content.file_extension else: new_label, new_file_extension = os.path.splitext(new_filename) self.tracim_context.set_destpath(destpath) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound as e: destination_parent = None workspace = self.content.workspace parent = self.content.parent try: new_content = self.content_api.copy( item=self.content, new_label=new_label, new_file_extension=new_file_extension, new_parent=destination_parent, new_workspace=destination_workspace) self.content_api.copy_children(self.content, new_content) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc transaction.commit()
def move_folder(self, destpath: str): destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound: destination_parent = None try: with new_revision(content=self.content, tm=transaction.manager, session=self.session): # renaming file if needed if basename(destpath) != self.getDisplayName(): self.content_api.update_content( self.content, webdav_convert_file_name_to_bdd(basename(destpath))) self.content_api.save(self.content) # move file if needed if (destination_workspace != self.content.workspace or destination_parent != self.content.parent): self.content_api.move( self.content, new_parent=destination_parent, new_workspace=destination_workspace, must_stay_in_same_workspace=False, ) self.content_api.execute_update_content_actions(self.content) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) from exc transaction.commit()
def moveRecursive(self, destpath): # INFO - G.M - 2018-12-11 - We only allow renaming if dirname(normpath(destpath)) == self.environ['http_authenticator.realm']: # FIXME - G.M - 2018-12-11 - For an unknown reason current_workspace # of tracim_context is here invalid. self.tracim_context._current_workspace = self.workspace try: can_modify_workspace.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) try: self.workspace.label = webdav_convert_file_name_to_bdd(basename(normpath(destpath))) self.session.add(self.workspace) self.session.flush() transaction.commit() except TracimException as exc: raise DAVError(HTTP_FORBIDDEN)
def _get_current_workspace_label(self) -> str: return webdav_convert_file_name_to_bdd(self.path.split("/")[1])
def _get_candidate_workspace_path(self): return webdav_convert_file_name_to_bdd(self._destpath.split("/")[1])
def move_file(self, destpath: str) -> None: """ Move file mean changing the path to access to a file. This can mean simple renaming(1), moving file from a directory to one another(2) but also renaming + moving file from a directory to one another at the same time (3). (1): move /dir1/file1 -> /dir1/file2 (2): move /dir1/file1 -> /dir2/file1 (3): move /dir1/file1 -> /dir2/file2 :param destpath: destination path of webdav move :return: nothing """ workspace = self.content.workspace parent = self.content.parent destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) try: with new_revision(content=self.content, tm=transaction.manager, session=self.session): # INFO - G.M - 2018-03-09 - First, renaming file if needed if basename(destpath) != self.getDisplayName(): new_filename = webdav_convert_file_name_to_bdd( basename(destpath)) regex_file_extension = re.compile("(?P<label>.*){}".format( re.escape(self.content.file_extension))) same_extension = regex_file_extension.match(new_filename) if same_extension: new_label = same_extension.group("label") new_file_extension = self.content.file_extension else: new_label, new_file_extension = os.path.splitext( new_filename) self.content_api.update_content(self.content, new_label=new_label) self.content.file_extension = new_file_extension self.content_api.save(self.content) # INFO - G.M - 2018-03-09 - Moving file if needed destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound: destination_parent = None if destination_parent != parent or destination_workspace != workspace: # INFO - G.M - 12-03-2018 - Avoid moving the file "at the same place" # if the request does not result in a real move. self.content_api.move( item=self.content, new_parent=destination_parent, must_stay_in_same_workspace=False, new_workspace=destination_workspace, ) self.content_api.execute_update_content_actions(self.content) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) from exc transaction.commit()
def _get_current_workspace_label(self) -> str: return webdav_convert_file_name_to_bdd(self.path.split('/')[1])
def _get_candidate_workspace_path(self): return webdav_convert_file_name_to_bdd(self._destpath.split('/')[1])
def move_file(self, destpath: str) -> None: """ Move file mean changing the path to access to a file. This can mean simple renaming(1), moving file from a directory to one another(2) but also renaming + moving file from a directory to one another at the same time (3). (1): move /dir1/file1 -> /dir1/file2 (2): move /dir1/file1 -> /dir2/file1 (3): move /dir1/file1 -> /dir2/file2 :param destpath: destination path of webdav move :return: nothing """ workspace = self.content.workspace parent = self.content.parent destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) try: with new_revision( content=self.content, tm=transaction.manager, session=self.session, ): # INFO - G.M - 2018-03-09 - First, renaming file if needed if basename(destpath) != self.getDisplayName(): new_filename = webdav_convert_file_name_to_bdd(basename(destpath)) regex_file_extension = re.compile( '(?P<label>.*){}'.format( re.escape(self.content.file_extension))) same_extension = regex_file_extension.match(new_filename) if same_extension: new_label = same_extension.group('label') new_file_extension = self.content.file_extension else: new_label, new_file_extension = os.path.splitext( new_filename) self.content_api.update_content( self.content, new_label=new_label, ) self.content.file_extension = new_file_extension self.content_api.save(self.content) # INFO - G.M - 2018-03-09 - Moving file if needed destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound: destination_parent = None if destination_parent != parent or destination_workspace != workspace: # nopep8 # INFO - G.M - 12-03-2018 - Avoid moving the file "at the same place" # nopep8 # if the request does not result in a real move. self.content_api.move( item=self.content, new_parent=destination_parent, must_stay_in_same_workspace=False, new_workspace=destination_workspace ) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc transaction.commit()