def test_get_all_with_filter(self): uapi = UserApi(None) groups = [GroupApi(None).get_one(Group.TIM_USER), GroupApi(None).get_one(Group.TIM_MANAGER), GroupApi(None).get_one(Group.TIM_ADMIN)] user = uapi.create_user(email='this.is@user', groups=groups, save_now=True) workspace = WorkspaceApi(user).create_workspace('test workspace', save_now=True) api = ContentApi(user) item = api.create(ContentType.Folder, workspace, None, 'thefolder', True) item2 = api.create(ContentType.File, workspace, None, 'thefile', True) uid = user.user_id wid = workspace.workspace_id transaction.commit() # Refresh instances after commit user = uapi.get_one(uid) workspace = WorkspaceApi(user).get_one(wid) api = ContentApi(user) items = api.get_all(None, ContentType.Any, workspace) eq_(2, len(items)) items2 = api.get_all(None, ContentType.File, workspace) eq_(1, len(items2)) eq_('thefile', items2[0].label) items3 = api.get_all(None, ContentType.Folder, workspace) eq_(1, len(items3)) eq_('thefolder', items3[0].label)
def test_get_all_with_parent_id(self): uapi = UserApi(None) groups = [ GroupApi(None).get_one(Group.TIM_USER), GroupApi(None).get_one(Group.TIM_MANAGER), GroupApi(None).get_one(Group.TIM_ADMIN) ] user = uapi.create_user(email='this.is@user', groups=groups, save_now=True) workspace = WorkspaceApi(user).create_workspace('test workspace', save_now=True) api = ContentApi(user) item = api.create(ContentType.Folder, workspace, None, 'parent', True) item2 = api.create(ContentType.File, workspace, item, 'file1', True) item3 = api.create(ContentType.File, workspace, None, 'file2', True) parent_id = item.content_id child_id = item2.content_id uid = user.user_id wid = workspace.workspace_id transaction.commit() # Refresh instances after commit user = uapi.get_one(uid) workspace = WorkspaceApi(user).get_one(wid) api = ContentApi(user) items = api.get_all(None, ContentType.Any, workspace) eq_(3, len(items)) items2 = api.get_all(parent_id, ContentType.File, workspace) eq_(1, len(items2)) eq_(child_id, items2[0].content_id)
def test_get_all_with_parent_id(self): uapi = UserApi(None) groups = [GroupApi(None).get_one(Group.TIM_USER), GroupApi(None).get_one(Group.TIM_MANAGER), GroupApi(None).get_one(Group.TIM_ADMIN)] user = uapi.create_user(email='this.is@user', groups=groups, save_now=True) workspace = WorkspaceApi(user).create_workspace('test workspace', save_now=True) api = ContentApi(user) item = api.create(ContentType.Folder, workspace, None, 'parent', True) item2 = api.create(ContentType.File, workspace, item, 'file1', True) item3 = api.create(ContentType.File, workspace, None, 'file2', True) parent_id = item.content_id child_id = item2.content_id uid = user.user_id wid = workspace.workspace_id transaction.commit() # Refresh instances after commit user = uapi.get_one(uid) workspace = WorkspaceApi(user).get_one(wid) api = ContentApi(user) items = api.get_all(None, ContentType.Any, workspace) eq_(3, len(items)) items2 = api.get_all(parent_id, ContentType.File, workspace) eq_(1, len(items2)) eq_(child_id, items2[0].content_id)
def test_archive(self): uapi = UserApi(None) groups = [ GroupApi(None).get_one(Group.TIM_USER), GroupApi(None).get_one(Group.TIM_MANAGER), GroupApi(None).get_one(Group.TIM_ADMIN) ] user = uapi.create_user(email='this.is@user', groups=groups, save_now=True) workspace = WorkspaceApi(user).create_workspace('test workspace', save_now=True) api = ContentApi(user) item = api.create(ContentType.Folder, workspace, None, 'not_archived', True) item2 = api.create(ContentType.Folder, workspace, None, 'to_archive', True) uid = user.user_id wid = workspace.workspace_id transaction.commit() # Refresh instances after commit user = uapi.get_one(uid) workspace = WorkspaceApi(user).get_one(wid) api = ContentApi(user) items = api.get_all(None, ContentType.Any, workspace) eq_(2, len(items)) items = api.get_all(None, ContentType.Any, workspace) with new_revision(items[0]): api.archive(items[0]) transaction.commit() # Refresh instances after commit user = uapi.get_one(uid) workspace = WorkspaceApi(user).get_one(wid) api = ContentApi(user) items = api.get_all(None, ContentType.Any, workspace) eq_(1, len(items)) transaction.commit() # Refresh instances after commit user = uapi.get_one(uid) workspace = WorkspaceApi(user).get_one(wid) api = ContentApi(user) # Test that the item is still available if "show deleted" is activated api = ContentApi(None, show_archived=True) items = api.get_all(None, ContentType.Any, workspace) eq_(2, len(items))
def test_archive(self): uapi = UserApi(None) groups = [GroupApi(None).get_one(Group.TIM_USER), GroupApi(None).get_one(Group.TIM_MANAGER), GroupApi(None).get_one(Group.TIM_ADMIN)] user = uapi.create_user(email='this.is@user', groups=groups, save_now=True) workspace = WorkspaceApi(user).create_workspace('test workspace', save_now=True) api = ContentApi(user) item = api.create(ContentType.Folder, workspace, None, 'not_archived', True) item2 = api.create(ContentType.Folder, workspace, None, 'to_archive', True) uid = user.user_id wid = workspace.workspace_id transaction.commit() # Refresh instances after commit user = uapi.get_one(uid) workspace = WorkspaceApi(user).get_one(wid) api = ContentApi(user) items = api.get_all(None, ContentType.Any, workspace) eq_(2, len(items)) items = api.get_all(None, ContentType.Any, workspace) with new_revision(items[0]): api.archive(items[0]) transaction.commit() # Refresh instances after commit user = uapi.get_one(uid) workspace = WorkspaceApi(user).get_one(wid) api = ContentApi(user) items = api.get_all(None, ContentType.Any, workspace) eq_(1, len(items)) transaction.commit() # Refresh instances after commit user = uapi.get_one(uid) workspace = WorkspaceApi(user).get_one(wid) api = ContentApi(user) # Test that the item is still available if "show deleted" is activated api = ContentApi(None, show_archived=True) items = api.get_all(None, ContentType.Any, workspace) eq_(2, len(items))
def getMemberList(self) -> [_DAVResource]: members = [] content_api = ContentApi(self.user) visible_children = content_api.get_all( self.content.content_id, ContentType.Any, self.workspace, ) for content in visible_children: content_path = '%s/%s' % ( self.path, transform_to_display(content.get_label_as_file())) try: if content.type == ContentType.Folder: members.append( Folder(content_path, self.environ, self.workspace, content)) elif content.type == ContentType.File: self._file_count += 1 members.append(File(content_path, self.environ, content)) else: self._file_count += 1 members.append( OtherFile(content_path, self.environ, content)) except Exception as exc: logger.exception( 'Unable to construct member {}'.format(content_path, ), exc_info=True, ) if self._file_count > 0 and self.provider.show_history(): members.append( HistoryFolder(path=self.path + '/' + ".history", environ=self.environ, content=self.content, workspace=self.workspace, type=HistoryType.Standard)) if self.provider.show_delete(): members.append( DeletedFolder(path=self.path + '/' + ".deleted", environ=self.environ, content=self.content, workspace=self.workspace)) if self.provider.show_archive(): members.append( ArchivedFolder(path=self.path + '/' + ".archived", environ=self.environ, content=self.content, workspace=self.workspace)) return members
def getMemberList(self) -> [_DAVResource]: members = [] content_api = ContentApi(self.user) visible_children = content_api.get_all( self.content.content_id, ContentType.Any, self.workspace, ) for content in visible_children: content_path = '%s/%s' % (self.path, transform_to_display(content.get_label_as_file())) if content.type == ContentType.Folder: members.append(Folder(content_path, self.environ, self.workspace, content)) elif content.type == ContentType.File: self._file_count += 1 members.append(File(content_path, self.environ, content)) else: self._file_count += 1 members.append(OtherFile(content_path, self.environ, content)) if self._file_count > 0 and self.provider.show_history(): members.append( HistoryFolder( path=self.path + '/' + ".history", environ=self.environ, content=self.content, workspace=self.workspace, type=HistoryType.Standard ) ) if self.provider.show_delete(): members.append( DeletedFolder( path=self.path + '/' + ".deleted", environ=self.environ, content=self.content, workspace=self.workspace ) ) if self.provider.show_archive(): members.append( ArchivedFolder( path=self.path + '/' + ".archived", environ=self.environ, content=self.content, workspace=self.workspace ) ) return members
def test_get_all_with_filter(self): uapi = UserApi(None) groups = [ GroupApi(None).get_one(Group.TIM_USER), GroupApi(None).get_one(Group.TIM_MANAGER), GroupApi(None).get_one(Group.TIM_ADMIN) ] user = uapi.create_user(email='this.is@user', groups=groups, save_now=True) workspace = WorkspaceApi(user).create_workspace('test workspace', save_now=True) api = ContentApi(user) item = api.create(ContentType.Folder, workspace, None, 'thefolder', True) item2 = api.create(ContentType.File, workspace, None, 'thefile', True) uid = user.user_id wid = workspace.workspace_id transaction.commit() # Refresh instances after commit user = uapi.get_one(uid) workspace = WorkspaceApi(user).get_one(wid) api = ContentApi(user) items = api.get_all(None, ContentType.Any, workspace) eq_(2, len(items)) items2 = api.get_all(None, ContentType.File, workspace) eq_(1, len(items2)) eq_('thefile', items2[0].label) items3 = api.get_all(None, ContentType.Folder, workspace) eq_(1, len(items3)) eq_('thefolder', items3[0].label)
def get_all_fake(self, context_workspace: Workspace, context_folder: Content) -> [Content]: """ fake methods are used in other controllers in order to simulate a client/server api. the "client" controller method will include the result into its own fake_api object which will be available in the templates :param context_workspace: the workspace which would be taken from tmpl_context if we were in the normal behavior :return: """ workspace = context_workspace content_api = ContentApi(tmpl_context.current_user) items = content_api.get_all(context_folder.content_id, self._item_type, workspace) dictified_items = Context(self._get_all_context).toDict(items) return DictLikeClass(result = dictified_items)
class HistoryFolder(Folder): """ A virtual resource which contains a sub-folder for every files (DAVNonCollection) contained in the parent folder """ def __init__(self, path, environ, workspace: data.Workspace, content: data.Content=None, type: str=HistoryType.Standard): super(HistoryFolder, self).__init__(path, environ, workspace, content) self._is_archived = type == HistoryType.Archived self._is_deleted = type == HistoryType.Deleted self.content_api = ContentApi( current_user=self.user, show_archived=self._is_archived, show_deleted=self._is_deleted ) def __repr__(self) -> str: return "<DAVCollection: HistoryFolder (%s)>" % self.content.file_name def getCreationDate(self) -> float: return mktime(datetime.now().timetuple()) def getDisplayName(self) -> str: return '.history' def getLastModified(self) -> float: return mktime(datetime.now().timetuple()) def getMember(self, content_label: str) -> _DAVResource: content = self.content_api.get_one_by_label_and_parent( content_label=content_label, content_parent=self.content ) return HistoryFileFolder( path='%s/%s' % (self.path, content.get_label_as_file()), environ=self.environ, content=content) def getMemberNames(self) -> [str]: ret = [] content_id = None if self.content is None else self.content.id for content in self.content_api.get_all(content_id, ContentType.Any, self.workspace): if (self._is_archived and content.is_archived or self._is_deleted and content.is_deleted or not (content.is_archived or self._is_archived or content.is_deleted or self._is_deleted))\ and content.type != ContentType.Folder: ret.append(content.get_label_as_file()) return ret def createEmptyResource(self, name: str): raise DAVError(HTTP_FORBIDDEN) def createCollection(self, name: str): raise DAVError(HTTP_FORBIDDEN) def delete(self): raise DAVError(HTTP_FORBIDDEN) def handleDelete(self): return True def handleCopy(self, destPath: str, depthInfinity): return True def handleMove(self, destPath: str): return True def getMemberList(self) -> [_DAVResource]: members = [] if self.content: children = self.content.children else: children = self.content_api.get_all(False, ContentType.Any, self.workspace) for content in children: if content.is_archived == self._is_archived and content.is_deleted == self._is_deleted: members.append(HistoryFileFolder( path='%s/%s' % (self.path, content.get_label_as_file()), environ=self.environ, content=content)) return members
class Workspace(DAVCollection): """ Workspace resource corresponding to tracim's workspaces. Direct children can only be folders, though files might come later on and are supported """ def __init__(self, path: str, environ: dict, workspace: data.Workspace): super(Workspace, self).__init__(path, environ) self.workspace = workspace self.content = None self.user = UserApi(None).get_one_by_email(environ['http_authenticator.username']) self.content_api = ContentApi(self.user, show_temporary=True) self._file_count = 0 def __repr__(self) -> str: return "<DAVCollection: Workspace (%d)>" % self.workspace.workspace_id def getPreferredPath(self): return self.path def getCreationDate(self) -> float: return mktime(self.workspace.created.timetuple()) def getDisplayName(self) -> str: return self.workspace.label def getLastModified(self) -> float: return mktime(self.workspace.updated.timetuple()) def getMemberNames(self) -> [str]: retlist = [] children = self.content_api.get_all( parent_id=self.content.id if self.content is not None else None, workspace=self.workspace ) for content in children: # the purpose is to display .history only if there's at least one content's type that has a history if content.type != ContentType.Folder: self._file_count += 1 retlist.append(content.get_label_as_file()) return retlist def getMember(self, content_label: str) -> _DAVResource: return self.provider.getResourceInst( '%s/%s' % (self.path, transform_to_display(content_label)), self.environ ) def createEmptyResource(self, file_name: str): """ [For now] we don't allow to create files right under workspaces. Though if we come to allow it, deleting the error's raise will make it possible. """ # TODO : remove commentary here raise DAVError(HTTP_FORBIDDEN) if '/.deleted/' in self.path or '/.archived/' in self.path: raise DAVError(HTTP_FORBIDDEN) content = None # Note: To prevent bugs, check here again if resource already exist path = os.path.join(self.path, file_name) resource = self.provider.getResourceInst(path, self.environ) if resource: content = resource.content return FakeFileStream( file_name=file_name, content_api=self.content_api, workspace=self.workspace, content=content, parent=self.content, path=self.path + '/' + file_name ) def createCollection(self, label: str) -> 'Folder': """ 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 = self.content_api.create( content_type=ContentType.Folder, workspace=self.workspace, label=label, parent=self.content ) subcontent = dict( folder=True, thread=True, file=True, page=True ) self.content_api.set_allowed_content(folder, subcontent) self.content_api.save(folder) transaction.commit() return Folder('%s/%s' % (self.path, transform_to_display(label)), self.environ, folder, self.workspace) def delete(self): """For now, it is not possible to delete a workspace through the webdav client.""" raise DAVError(HTTP_FORBIDDEN) def supportRecursiveMove(self, destpath): return True def moveRecursive(self, destpath): if dirname(normpath(destpath)) == self.environ['http_authenticator.realm']: self.workspace.label = basename(normpath(destpath)) transaction.commit() else: raise DAVError(HTTP_FORBIDDEN) def getMemberList(self) -> [_DAVResource]: members = [] children = self.content_api.get_all(False, ContentType.Any, self.workspace) for content in children: content_path = '%s/%s' % (self.path, transform_to_display(content.get_label_as_file())) if content.type == ContentType.Folder: members.append(Folder(content_path, self.environ, self.workspace, content)) elif content.type == ContentType.File: self._file_count += 1 members.append(File(content_path, self.environ, content)) else: self._file_count += 1 members.append(OtherFile(content_path, self.environ, content)) if self._file_count > 0 and self.provider.show_history(): members.append( HistoryFolder( path=self.path + '/' + ".history", environ=self.environ, content=self.content, workspace=self.workspace, type=HistoryType.Standard ) ) if self.provider.show_delete(): members.append( DeletedFolder( path=self.path + '/' + ".deleted", environ=self.environ, content=self.content, workspace=self.workspace ) ) if self.provider.show_archive(): members.append( ArchivedFolder( path=self.path + '/' + ".archived", environ=self.environ, content=self.content, workspace=self.workspace ) ) return members
class HistoryFolder(Folder): """ A virtual resource which contains a sub-folder for every files (DAVNonCollection) contained in the parent folder """ def __init__(self, path, environ, workspace: data.Workspace, content: data.Content = None, type: str = HistoryType.Standard): super(HistoryFolder, self).__init__(path, environ, workspace, content) self._is_archived = type == HistoryType.Archived self._is_deleted = type == HistoryType.Deleted self.content_api = ContentApi(current_user=self.user, show_archived=self._is_archived, show_deleted=self._is_deleted) def __repr__(self) -> str: return "<DAVCollection: HistoryFolder (%s)>" % self.content.file_name def getCreationDate(self) -> float: return mktime(datetime.now().timetuple()) def getDisplayName(self) -> str: return '.history' def getLastModified(self) -> float: return mktime(datetime.now().timetuple()) def getMember(self, content_label: str) -> _DAVResource: content = self.content_api.get_one_by_label_and_parent( content_label=content_label, content_parent=self.content) return HistoryFileFolder(path='%s/%s' % (self.path, content.get_label()), environ=self.environ, content=content) def getMemberNames(self) -> [str]: ret = [] content_id = None if self.content is None else self.content.id for content in self.content_api.get_all(content_id, ContentType.Any, self.workspace): if (self._is_archived and content.is_archived or self._is_deleted and content.is_deleted or not (content.is_archived or self._is_archived or content.is_deleted or self._is_deleted))\ and content.type != ContentType.Folder: ret.append(content.get_label()) return ret def createEmptyResource(self, name: str): raise DAVError(HTTP_FORBIDDEN) def createCollection(self, name: str): raise DAVError(HTTP_FORBIDDEN) def delete(self): raise DAVError(HTTP_FORBIDDEN) def handleDelete(self): return True def handleCopy(self, destPath: str, depthInfinity): return True def handleMove(self, destPath: str): return True def getMemberList(self) -> [_DAVResource]: members = [] if self.content: children = self.content.children else: children = self.content_api.get_all(None, ContentType.Any, self.workspace) for content in children: if content.is_archived == self._is_archived and content.is_deleted == self._is_deleted: members.append( HistoryFileFolder(path='%s/%s' % (self.path, content.get_label()), environ=self.environ, content=content)) return members
class Workspace(DAVCollection): """ Workspace resource corresponding to tracim's workspaces. Direct children can only be folders, though files might come later on and are supported """ def __init__(self, path: str, environ: dict, workspace: data.Workspace): super(Workspace, self).__init__(path, environ) self.workspace = workspace self.content = None self.user = UserApi(None).get_one_by_email( environ['http_authenticator.username']) self.content_api = ContentApi(self.user, show_temporary=True) self._file_count = 0 def __repr__(self) -> str: return "<DAVCollection: Workspace (%d)>" % self.workspace.workspace_id def getPreferredPath(self): return self.path def getCreationDate(self) -> float: return mktime(self.workspace.created.timetuple()) def getDisplayName(self) -> str: return self.workspace.label def getLastModified(self) -> float: print("hm....", self.path) return mktime(self.workspace.updated.timetuple()) def getMemberNames(self) -> [str]: retlist = [] children = self.content_api.get_all( parent_id=self.content.id if self.content is not None else None, workspace=self.workspace) for content in children: # the purpose is to display .history only if there's at least one content's type that has a history if content.type != ContentType.Folder: self._file_count += 1 retlist.append(content.get_label()) return retlist def getMember(self, content_label: str) -> _DAVResource: return self.provider.getResourceInst( '%s/%s' % (self.path, self.provider.transform_to_display(content_label)), self.environ) def createEmptyResource(self, file_name: str): """ [For now] we don't allow to create files right under workspaces. Though if we come to allow it, deleting the error's raise will make it possible. """ # TODO : remove commentary here raise DAVError(HTTP_FORBIDDEN) if '/.deleted/' in self.path or '/.archived/' in self.path: raise DAVError(HTTP_FORBIDDEN) return FakeFileStream(file_name=file_name, content_api=self.content_api, workspace=self.workspace, content=None, parent=self.content, path=self.path + '/' + file_name) def createCollection(self, label: str) -> 'Folder': """ 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 = self.content_api.create(content_type=ContentType.Folder, workspace=self.workspace, label=label, parent=self.content) subcontent = dict(folder=True, thread=True, file=True, page=True) self.content_api.set_allowed_content(folder, subcontent) self.content_api.save(folder) transaction.commit() return Folder( '%s/%s' % (self.path, self.provider.transform_to_display(label)), self.environ, folder, self.workspace) def delete(self): """For now, it is not possible to delete a workspace through the webdav client.""" raise DAVError(HTTP_FORBIDDEN) def supportRecursiveMove(self, destpath): return True def moveRecursive(self, destpath): if dirname(normpath( destpath)) == self.environ['http_authenticator.realm']: self.workspace.label = basename(normpath(destpath)) transaction.commit() else: raise DAVError(HTTP_FORBIDDEN) def getMemberList(self) -> [_DAVResource]: members = [] children = self.content_api.get_all(None, ContentType.Any, self.workspace) for content in children: content_path = '%s/%s' % (self.path, self.provider.transform_to_display( content.get_label())) if content.type == ContentType.Folder: members.append( Folder(content_path, self.environ, self.workspace, content)) elif content.type == ContentType.File: self._file_count += 1 members.append(File(content_path, self.environ, content)) else: self._file_count += 1 members.append(OtherFile(content_path, self.environ, content)) if self._file_count > 0 and self.provider.show_history(): members.append( HistoryFolder(path=self.path + '/' + ".history", environ=self.environ, content=self.content, workspace=self.workspace, type=HistoryType.Standard)) if self.provider.show_delete(): members.append( DeletedFolder(path=self.path + '/' + ".deleted", environ=self.environ, content=self.content, workspace=self.workspace)) if self.provider.show_archive(): members.append( ArchivedFolder(path=self.path + '/' + ".archived", environ=self.environ, content=self.content, workspace=self.workspace)) return members