Ejemplo n.º 1
0
 def delete_content(
     self,
     context,
     request: TracimRequest,
     hapic_data=None,
 ) -> None:
     """
     Move a content to the trash. After that, the content will be invisible by default.
     This action requires the user to be a content manager.
     Note: the content is still accessible but becomes read-only.
     """
     app_config = request.registry.settings['CFG']
     path_data = hapic_data.path
     api = ContentApi(
         show_archived=True,
         show_deleted=True,
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config,
     )
     content = api.get_one(path_data.content_id,
                           content_type=content_type_list.Any_SLUG)
     with new_revision(session=request.dbsession,
                       tm=transaction.manager,
                       content=content):
         api.delete(content)
     return
Ejemplo n.º 2
0
 def delete_comment(self, context, request: TracimRequest, hapic_data=None):
     """
     Delete comment
     """
     app_config = request.registry.settings['CFG']
     api = ContentApi(
         show_archived=True,
         show_deleted=True,
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config,
     )
     wapi = WorkspaceApi(
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config,
     )
     workspace = wapi.get_one(hapic_data.path.workspace_id)
     parent = api.get_one(hapic_data.path.content_id,
                          content_type=content_type_list.Any_SLUG,
                          workspace=workspace)
     comment = api.get_one(
         hapic_data.path.comment_id,
         content_type=content_type_list.Comment.slug,
         workspace=workspace,
         parent=parent,
     )
     with new_revision(session=request.dbsession,
                       tm=transaction.manager,
                       content=comment):
         api.delete(comment)
     return
Ejemplo n.º 3
0
 def delete_content(
         self,
         context,
         request: TracimRequest,
         hapic_data=None,
 ) -> None:
     """
     Move a content to the trash. After that, the content will be invisible by default.
     This action requires the user to be a content manager.
     Note: the content is still accessible but becomes read-only.
     """
     app_config = request.registry.settings['CFG']
     path_data = hapic_data.path
     api = ContentApi(
         show_archived=True,
         show_deleted=True,
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config,
     )
     content = api.get_one(
         path_data.content_id,
         content_type=content_type_list.Any_SLUG
     )
     with new_revision(
             session=request.dbsession,
             tm=transaction.manager,
             content=content
     ):
         api.delete(content)
     return
Ejemplo n.º 4
0
 def delete_comment(self, context, request: TracimRequest, hapic_data=None):
     """
     Delete comment
     """
     app_config = request.registry.settings['CFG']
     api = ContentApi(
         show_archived=True,
         show_deleted=True,
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config,
     )
     wapi = WorkspaceApi(
         current_user=request.current_user,
         session=request.dbsession,
         config=app_config,
     )
     workspace = wapi.get_one(hapic_data.path.workspace_id)
     parent = api.get_one(
         hapic_data.path.content_id,
         content_type=content_type_list.Any_SLUG,
         workspace=workspace
     )
     comment = api.get_one(
         hapic_data.path.comment_id,
         content_type=content_type_list.Comment.slug,
         workspace=workspace,
         parent=parent,
     )
     with new_revision(
             session=request.dbsession,
             tm=transaction.manager,
             content=comment
     ):
         api.delete(comment)
     return
Ejemplo n.º 5
0
    def insert(self):
        admin = self._session.query(User) \
            .filter(User.email == '*****@*****.**') \
            .one()
        bob = self._session.query(User) \
            .filter(User.email == '*****@*****.**') \
            .one()
        john_the_reader = self._session.query(User) \
            .filter(User.email == '*****@*****.**') \
            .one()

        admin_workspace_api = WorkspaceApi(
            current_user=admin,
            session=self._session,
            config=self._config,
        )
        bob_workspace_api = WorkspaceApi(
            current_user=bob,
            session=self._session,
            config=self._config
        )
        content_api = ContentApi(
            current_user=admin,
            session=self._session,
            config=self._config
        )
        bob_content_api = ContentApi(
            current_user=bob,
            session=self._session,
            config=self._config
        )
        reader_content_api = ContentApi(
            current_user=john_the_reader,
            session=self._session,
            config=self._config
        )
        role_api = RoleApi(
            current_user=admin,
            session=self._session,
            config=self._config,
        )

        # Workspaces
        business_workspace = admin_workspace_api.create_workspace(
            'Business',
            description='All importants documents',
            save_now=True,
        )
        recipe_workspace = admin_workspace_api.create_workspace(
            'Recipes',
            description='Our best recipes',
            save_now=True,
        )
        other_workspace = bob_workspace_api.create_workspace(
            'Others',
            description='Other Workspace',
            save_now=True,
        )

        # Workspaces roles
        role_api.create_one(
            user=bob,
            workspace=recipe_workspace,
            role_level=UserRoleInWorkspace.CONTENT_MANAGER,
            with_notif=False,
        )
        role_api.create_one(
            user=john_the_reader,
            workspace=recipe_workspace,
            role_level=UserRoleInWorkspace.READER,
            with_notif=False,
        )
        # Folders

        tool_workspace = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=business_workspace,
            label='Tools',
            do_save=True,
            do_notify=False,
        )
        menu_workspace = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=business_workspace,
            label='Menus',
            do_save=True,
            do_notify=False,
        )

        dessert_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label='Desserts',
            do_save=True,
            do_notify=False,
        )
        salads_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label='Salads',
            do_save=True,
            do_notify=False,
        )
        other_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=other_workspace,
            label='Infos',
            do_save=True,
            do_notify=False,
        )

        # Pages, threads, ..
        tiramisu_page = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Tiramisu Recipes!!!',
            do_save=True,
            do_notify=False,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=tiramisu_page,
        ):
            content_api.update_content(
                item=tiramisu_page,
                new_content='<p>To cook a greet Tiramisu, you need many ingredients.</p>',  # nopep8
                new_label='Tiramisu Recipes!!!',
            )
            content_api.save(tiramisu_page)

        best_cake_thread = content_api.create(
            content_type_slug=content_type_list.Thread.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Best Cake',
            do_save=False,
            do_notify=False,
        )
        best_cake_thread.description = 'Which is the best cake?'
        self._session.add(best_cake_thread)
        apple_pie_recipe = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Apple_Pie',
            do_save=False,
            do_notify=False,
        )
        apple_pie_recipe.file_extension = '.txt'
        apple_pie_recipe.depot_file = FileIntent(
            b'Apple pie Recipe',
            'apple_Pie.txt',
            'text/plain',
        )
        self._session.add(apple_pie_recipe)
        Brownie_recipe = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Brownie Recipe',
            do_save=False,
            do_notify=False,
        )
        Brownie_recipe.file_extension = '.html'
        Brownie_recipe.depot_file = FileIntent(
            b'<p>Brownie Recipe</p>',
            'brownie_recipe.html',
            'text/html',
        )
        self._session.add(Brownie_recipe)
        fruits_desserts_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label='Fruits Desserts',
            parent=dessert_folder,
            do_save=True,
        )

        menu_page = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=business_workspace,
            parent=menu_workspace,
            label='Current Menu',
            do_save=True,
        )

        new_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label='New Fruit Salad',
            do_save=True,
        )
        old_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label='Fruit Salad',
            do_save=True,
            do_notify=False,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=old_fruit_salad,
        ):
            content_api.archive(old_fruit_salad)
        content_api.save(old_fruit_salad)

        bad_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label='Bad Fruit Salad',
            do_save=True,
            do_notify=False,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=bad_fruit_salad,
        ):
            content_api.delete(bad_fruit_salad)
        content_api.save(bad_fruit_salad)

        # File at the root for test
        new_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label='New Fruit Salad',
            do_save=True,
        )
        old_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label='Fruit Salad',
            do_save=True,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=old_fruit_salad,
        ):
            content_api.archive(old_fruit_salad)
        content_api.save(old_fruit_salad)

        bad_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label='Bad Fruit Salad',
            do_save=True,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=bad_fruit_salad,
        ):
            content_api.delete(bad_fruit_salad)
        content_api.save(bad_fruit_salad)

        content_api.create_comment(
            parent=best_cake_thread,
            content='<p>What is for you the best cake ever? </br> I personnally vote for Chocolate cupcake!</p>',  # nopep8
            do_save=True,
        )
        bob_content_api.create_comment(
            parent=best_cake_thread,
            content='<p>What about Apple Pie? There are Awesome!</p>',
            do_save=True,
        )
        reader_content_api.create_comment(
            parent=best_cake_thread,
            content='<p>You are right, but Kouign-amann are clearly better.</p>',
            do_save=True,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=best_cake_thread,
        ):
            bob_content_api.update_content(
                item=best_cake_thread,
                new_content='What is the best cake?',
                new_label='Best Cakes?',
            )
            bob_content_api.save(best_cake_thread)

        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=tiramisu_page,
        ):
            bob_content_api.update_content(
                item=tiramisu_page,
                new_content='<p>To cook a great Tiramisu, you need many ingredients.</p>',  # nopep8
                new_label='Tiramisu Recipe',
            )
            bob_content_api.save(tiramisu_page)
        self._session.flush()
Ejemplo n.º 6
0
class FileResource(DAVNonCollection):
    """
    FileResource resource corresponding to tracim's files
    """
    def __init__(self, path: str, environ: dict, content: Content,
                 tracim_context: "WebdavTracimContext") -> None:
        super(FileResource, self).__init__(path, environ)
        self.tracim_context = tracim_context
        self.content = content
        self.user = tracim_context.current_user
        self.session = tracim_context.dbsession
        self.content_api = ContentApi(
            current_user=self.user,
            config=tracim_context.app_config,
            session=self.session,
            namespaces_filter=[self.content.content_namespace],
        )

        # this is the property that windows client except to check if the file is read-write or read-only,
        # but i wasn't able to set this property so you'll have to look into it >.>
        # self.setPropertyValue('Win32FileAttributes', '00000021')

    def __repr__(self) -> str:
        return "<DAVNonCollection: FileResource (%d)>" % self.content.cached_revision_id

    @webdav_check_right(is_reader)
    def getContentLength(self) -> int:
        return self.content.depot_file.file.content_length

    @webdav_check_right(is_reader)
    def getContentType(self) -> str:
        return self.content.file_mimetype

    @webdav_check_right(is_reader)
    def getCreationDate(self) -> float:
        return mktime(self.content.created.timetuple())

    @webdav_check_right(is_reader)
    def getDisplayName(self) -> str:
        return webdav_convert_file_name_to_display(self.content.file_name)

    @webdav_check_right(is_reader)
    def getDisplayInfo(self):
        return {"type": self.content.type.capitalize()}

    def getLastModified(self) -> float:
        return mktime(self.content.updated.timetuple())

    @webdav_check_right(is_reader)
    def getContent(self) -> typing.BinaryIO:
        return self.content.depot_file.file

    @webdav_check_right(is_contributor)
    def beginWrite(self, contentType: str = None) -> FakeFileStream:
        try:
            self.content_api.check_upload_size(
                int(self.environ["CONTENT_LENGTH"]), self.content.workspace)
        except (
                FileSizeOverMaxLimitation,
                FileSizeOverWorkspaceEmptySpace,
                FileSizeOverOwnerEmptySpace,
        ) as exc:
            raise DAVError(HTTP_REQUEST_ENTITY_TOO_LARGE, contextinfo=str(exc))
        return FakeFileStream(
            content=self.content,
            content_api=self.content_api,
            file_name=self.content.file_name,
            workspace=self.content.workspace,
            path=self.path,
            session=self.session,
        )

    def moveRecursive(self, destpath):
        """As we support recursive move, copymovesingle won't be called, though with copy it'll be called
            but i have to check if the client ever call that function..."""
        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))

        invalid_path = False
        invalid_path = dirname(
            destpath) == self.environ["http_authenticator.realm"]

        if not invalid_path:
            self.move_file(destpath)

        if invalid_path:
            raise DAVError(HTTP_FORBIDDEN)

    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 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 supportRecursiveMove(self, destpath):
        return True

    @webdav_check_right(is_content_manager)
    def delete(self):
        try:
            with new_revision(session=self.session,
                              tm=transaction.manager,
                              content=self.content):
                self.content_api.delete(self.content)
                self.content_api.execute_update_content_actions(self.content)
                self.content_api.save(self.content)
        except TracimException as exc:
            raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) from exc
        transaction.commit()
Ejemplo n.º 7
0
class FolderResource(DAVCollection):
    """
    FolderResource resource corresponding to tracim's folders.
    Direct children can only be content (folder, html-document, file, etc...)
    By default when creating new folders, we allow them to contain all types of content
    """
    def __init__(
        self,
        path: str,
        environ: dict,
        workspace: Workspace,
        content: Content,
        tracim_context: "WebdavTracimContext",
    ):
        DAVCollection.__init__(self, path, environ)
        self.content_container = ContentOnlyContainer(
            path,
            environ,
            provider=self.provider,
            content=content,
            label=workspace.filemanager_filename,
            workspace=workspace,
            tracim_context=tracim_context,
        )
        self.tracim_context = tracim_context
        self.content_api = ContentApi(
            current_user=tracim_context.current_user,
            session=tracim_context.dbsession,
            config=tracim_context.app_config,
            show_temporary=True,
            namespaces_filter=[ContentNamespaces.CONTENT],
        )
        self.content = content
        self.session = tracim_context.dbsession

    def __repr__(self) -> str:
        return "<DAVCollection: Folder (%s)>" % self.content.label

    @webdav_check_right(is_reader)
    def getCreationDate(self) -> float:
        return mktime(self.content.created.timetuple())

    @webdav_check_right(is_reader)
    def getDisplayName(self) -> str:
        return webdav_convert_file_name_to_display(self.content.file_name)

    @webdav_check_right(is_reader)
    def getDisplayInfo(self):
        return {"type": self.content.type.capitalize()}

    def getLastModified(self) -> float:
        return mktime(self.content.updated.timetuple())

    @webdav_check_right(is_content_manager)
    def delete(self):
        try:
            with new_revision(session=self.session,
                              tm=transaction.manager,
                              content=self.content):
                self.content_api.delete(self.content)
                self.content_api.execute_update_content_actions(self.content)
                self.content_api.save(self.content)
        except TracimException as exc:
            raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) from exc
        transaction.commit()

    def supportRecursiveMove(self, destpath: str):
        return True

    def moveRecursive(self, destpath: str):
        """
        As we support recursive move, copymovesingle won't be called, though with copy it'll be called
        but i have to check if the client ever call that function...
        """
        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))

        # we check if the path is good (not at the root path /)
        # and we move the content
        invalid_path = dirname(
            destpath) == self.environ["http_authenticator.realm"]

        if not invalid_path:
            self.move_folder(destpath)

        if invalid_path:
            raise DAVError(HTTP_FORBIDDEN)

    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()

    @webdav_check_right(is_contributor)
    def createEmptyResource(self, file_name: str):
        return self.content_container.createEmptyResource(file_name=file_name)

    @webdav_check_right(is_content_manager)
    def createCollection(self, label: str) -> "FolderResource":
        return self.content_container.createCollection(label=label)

    def getMemberNames(self) -> [str]:
        return self.content_container.getMemberNames()

    def getMember(self, label: str) -> _DAVResource:
        return self.content_container.getMember(label=label)

    def getMemberList(self) -> [_DAVResource]:
        return self.content_container.getMemberList()
Ejemplo n.º 8
0
    def insert(self):
        admin = self._session.query(User).filter(User.email == "*****@*****.**").one()
        bob = self._session.query(User).filter(User.email == "*****@*****.**").one()
        john_the_reader = (
            self._session.query(User).filter(User.email == "*****@*****.**").one()
        )

        admin_workspace_api = WorkspaceApi(
            current_user=admin, session=self._session, config=self._config
        )
        bob_workspace_api = WorkspaceApi(
            current_user=bob, session=self._session, config=self._config
        )
        content_api = ContentApi(current_user=admin, session=self._session, config=self._config)
        bob_content_api = ContentApi(current_user=bob, session=self._session, config=self._config)
        reader_content_api = ContentApi(
            current_user=john_the_reader, session=self._session, config=self._config
        )
        role_api = RoleApi(current_user=admin, session=self._session, config=self._config)

        # Workspaces
        business_workspace = admin_workspace_api.create_workspace(
            "Business", description="All importants documents", save_now=True
        )
        recipe_workspace = admin_workspace_api.create_workspace(
            "Recipes", description="Our best recipes", save_now=True
        )
        other_workspace = bob_workspace_api.create_workspace(
            "Others", description="Other Workspace", save_now=True
        )

        # Workspaces roles
        role_api.create_one(
            user=bob,
            workspace=recipe_workspace,
            role_level=UserRoleInWorkspace.CONTENT_MANAGER,
            with_notif=False,
        )
        role_api.create_one(
            user=john_the_reader,
            workspace=recipe_workspace,
            role_level=UserRoleInWorkspace.READER,
            with_notif=False,
        )
        # Folders

        content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=business_workspace,
            label="Tools",
            do_save=True,
            do_notify=False,
        )
        menu_workspace = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=business_workspace,
            label="Menus",
            do_save=True,
            do_notify=False,
        )

        dessert_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label="Desserts",
            do_save=True,
            do_notify=False,
        )
        content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label="Salads",
            do_save=True,
            do_notify=False,
        )
        content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=other_workspace,
            label="Infos",
            do_save=True,
            do_notify=False,
        )

        # Pages, threads, ..
        tiramisu_page = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label="Tiramisu Recipes!!!",
            do_save=True,
            do_notify=False,
        )
        with new_revision(session=self._session, tm=transaction.manager, content=tiramisu_page):
            content_api.update_content(
                item=tiramisu_page,
                new_content="<p>To cook a greet Tiramisu, you need many ingredients.</p>",
                new_label="Tiramisu Recipes!!!",
            )
            content_api.save(tiramisu_page, do_notify=False)

        best_cake_thread = content_api.create(
            content_type_slug=content_type_list.Thread.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label="Best Cake",
            do_save=False,
            do_notify=False,
        )
        best_cake_thread.description = "Which is the best cake?"
        self._session.add(best_cake_thread)
        apple_pie_recipe = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label="Apple_Pie",
            do_save=False,
            do_notify=False,
        )
        apple_pie_recipe.file_extension = ".txt"
        apple_pie_recipe.depot_file = FileIntent(b"Apple pie Recipe", "apple_Pie.txt", "text/plain")
        self._session.add(apple_pie_recipe)
        brownie_recipe = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label="Brownie Recipe",
            do_save=False,
            do_notify=False,
        )
        brownie_recipe.file_extension = ".html"
        brownie_recipe.depot_file = FileIntent(
            b"<p>Brownie Recipe</p>", "brownie_recipe.html", "text/html"
        )
        self._session.add(brownie_recipe)
        fruits_desserts_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label="Fruits Desserts",
            parent=dessert_folder,
            do_save=True,
            do_notify=False,
        )

        content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=business_workspace,
            parent=menu_workspace,
            label="Current Menu",
            do_save=True,
            do_notify=False,
        )

        content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label="New Fruit Salad",
            do_save=True,
            do_notify=False,
        )
        old_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label="Fruit Salad",
            do_save=True,
            do_notify=False,
        )
        with new_revision(session=self._session, tm=transaction.manager, content=old_fruit_salad):
            content_api.archive(old_fruit_salad)
        content_api.save(old_fruit_salad, do_notify=False)

        bad_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label="Bad Fruit Salad",
            do_save=True,
            do_notify=False,
        )
        with new_revision(session=self._session, tm=transaction.manager, content=bad_fruit_salad):
            content_api.delete(bad_fruit_salad)
        content_api.save(bad_fruit_salad, do_notify=False)

        # File at the root for test
        content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label="New Fruit Salad",
            do_save=True,
            do_notify=False,
        )
        old_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label="Fruit Salad",
            do_save=True,
            do_notify=False,
        )
        with new_revision(session=self._session, tm=transaction.manager, content=old_fruit_salad):
            content_api.archive(old_fruit_salad)
        content_api.save(old_fruit_salad, do_notify=False)

        bad_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label="Bad Fruit Salad",
            do_save=True,
            do_notify=False,
        )
        with new_revision(session=self._session, tm=transaction.manager, content=bad_fruit_salad):
            content_api.delete(bad_fruit_salad)
        content_api.save(bad_fruit_salad, do_notify=False)

        content_api.create_comment(
            parent=best_cake_thread,
            content="<p>What is for you the best cake ever? <br/> I personnally vote for Chocolate cupcake!</p>",
            do_save=True,
            do_notify=False,
        )
        bob_content_api.create_comment(
            parent=best_cake_thread,
            content="<p>What about Apple Pie? There are Awesome!</p>",
            do_save=True,
            do_notify=False,
        )
        reader_content_api.create_comment(
            parent=best_cake_thread,
            content="<p>You are right, but Kouign-amann are clearly better.</p>",
            do_save=True,
            do_notify=False,
        )
        with new_revision(session=self._session, tm=transaction.manager, content=best_cake_thread):
            bob_content_api.update_content(
                item=best_cake_thread, new_content="What is the best cake?", new_label="Best Cakes?"
            )
            bob_content_api.save(best_cake_thread, do_notify=False)

        with new_revision(session=self._session, tm=transaction.manager, content=tiramisu_page):
            bob_content_api.update_content(
                item=tiramisu_page,
                new_content="<p>To cook a great Tiramisu, you need many ingredients.</p>",
                new_label="Tiramisu Recipe",
            )
            bob_content_api.save(tiramisu_page, do_notify=False)
        self._session.flush()
Ejemplo n.º 9
0
    def insert(self):
        admin = self._session.query(models.User) \
            .filter(models.User.email == '*****@*****.**') \
            .one()
        bob = self._session.query(models.User) \
            .filter(models.User.email == '*****@*****.**') \
            .one()
        john_the_reader = self._session.query(models.User) \
            .filter(models.User.email == '*****@*****.**') \
            .one()

        admin_workspace_api = WorkspaceApi(
            current_user=admin,
            session=self._session,
            config=self._config,
        )
        bob_workspace_api = WorkspaceApi(current_user=bob,
                                         session=self._session,
                                         config=self._config)
        content_api = ContentApi(current_user=admin,
                                 session=self._session,
                                 config=self._config)
        bob_content_api = ContentApi(current_user=bob,
                                     session=self._session,
                                     config=self._config)
        reader_content_api = ContentApi(current_user=john_the_reader,
                                        session=self._session,
                                        config=self._config)
        role_api = RoleApi(
            current_user=admin,
            session=self._session,
            config=self._config,
        )

        # Workspaces
        business_workspace = admin_workspace_api.create_workspace(
            'Business',
            description='All importants documents',
            save_now=True,
        )
        recipe_workspace = admin_workspace_api.create_workspace(
            'Recipes',
            description='Our best recipes',
            save_now=True,
        )
        other_workspace = bob_workspace_api.create_workspace(
            'Others',
            description='Other Workspace',
            save_now=True,
        )

        # Workspaces roles
        role_api.create_one(
            user=bob,
            workspace=recipe_workspace,
            role_level=UserRoleInWorkspace.CONTENT_MANAGER,
            with_notif=False,
        )
        role_api.create_one(
            user=john_the_reader,
            workspace=recipe_workspace,
            role_level=UserRoleInWorkspace.READER,
            with_notif=False,
        )
        # Folders

        tool_workspace = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=business_workspace,
            label='Tools',
            do_save=True,
            do_notify=False,
        )
        menu_workspace = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=business_workspace,
            label='Menus',
            do_save=True,
            do_notify=False,
        )

        dessert_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label='Desserts',
            do_save=True,
            do_notify=False,
        )
        salads_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label='Salads',
            do_save=True,
            do_notify=False,
        )
        other_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=other_workspace,
            label='Infos',
            do_save=True,
            do_notify=False,
        )

        # Pages, threads, ..
        tiramisu_page = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Tiramisu Recipes!!!',
            do_save=True,
            do_notify=False,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=tiramisu_page,
        ):
            content_api.update_content(
                item=tiramisu_page,
                new_content=
                '<p>To cook a greet Tiramisu, you need many ingredients.</p>',  # nopep8
                new_label='Tiramisu Recipes!!!',
            )
            content_api.save(tiramisu_page)

        best_cake_thread = content_api.create(
            content_type_slug=content_type_list.Thread.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Best Cake',
            do_save=False,
            do_notify=False,
        )
        best_cake_thread.description = 'Which is the best cake?'
        self._session.add(best_cake_thread)
        apple_pie_recipe = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Apple_Pie',
            do_save=False,
            do_notify=False,
        )
        apple_pie_recipe.file_extension = '.txt'
        apple_pie_recipe.depot_file = FileIntent(
            b'Apple pie Recipe',
            'apple_Pie.txt',
            'text/plain',
        )
        self._session.add(apple_pie_recipe)
        Brownie_recipe = content_api.create(
            content_type_slug=content_type_list.File.slug,
            workspace=recipe_workspace,
            parent=dessert_folder,
            label='Brownie Recipe',
            do_save=False,
            do_notify=False,
        )
        Brownie_recipe.file_extension = '.html'
        Brownie_recipe.depot_file = FileIntent(
            b'<p>Brownie Recipe</p>',
            'brownie_recipe.html',
            'text/html',
        )
        self._session.add(Brownie_recipe)
        fruits_desserts_folder = content_api.create(
            content_type_slug=content_type_list.Folder.slug,
            workspace=recipe_workspace,
            label='Fruits Desserts',
            parent=dessert_folder,
            do_save=True,
        )

        menu_page = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=business_workspace,
            parent=menu_workspace,
            label='Current Menu',
            do_save=True,
        )

        new_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label='New Fruit Salad',
            do_save=True,
        )
        old_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label='Fruit Salad',
            do_save=True,
            do_notify=False,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=old_fruit_salad,
        ):
            content_api.archive(old_fruit_salad)
        content_api.save(old_fruit_salad)

        bad_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=recipe_workspace,
            parent=fruits_desserts_folder,
            label='Bad Fruit Salad',
            do_save=True,
            do_notify=False,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=bad_fruit_salad,
        ):
            content_api.delete(bad_fruit_salad)
        content_api.save(bad_fruit_salad)

        # File at the root for test
        new_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label='New Fruit Salad',
            do_save=True,
        )
        old_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label='Fruit Salad',
            do_save=True,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=old_fruit_salad,
        ):
            content_api.archive(old_fruit_salad)
        content_api.save(old_fruit_salad)

        bad_fruit_salad = content_api.create(
            content_type_slug=content_type_list.Page.slug,
            workspace=other_workspace,
            label='Bad Fruit Salad',
            do_save=True,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=bad_fruit_salad,
        ):
            content_api.delete(bad_fruit_salad)
        content_api.save(bad_fruit_salad)

        content_api.create_comment(
            parent=best_cake_thread,
            content=
            '<p>What is for you the best cake ever? </br> I personnally vote for Chocolate cupcake!</p>',  # nopep8
            do_save=True,
        )
        bob_content_api.create_comment(
            parent=best_cake_thread,
            content='<p>What about Apple Pie? There are Awesome!</p>',
            do_save=True,
        )
        reader_content_api.create_comment(
            parent=best_cake_thread,
            content=
            '<p>You are right, but Kouign-amann are clearly better.</p>',
            do_save=True,
        )
        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=best_cake_thread,
        ):
            bob_content_api.update_content(
                item=best_cake_thread,
                new_content='What is the best cake?',
                new_label='Best Cakes?',
            )
            bob_content_api.save(best_cake_thread)

        with new_revision(
                session=self._session,
                tm=transaction.manager,
                content=tiramisu_page,
        ):
            bob_content_api.update_content(
                item=tiramisu_page,
                new_content=
                '<p>To cook a great Tiramisu, you need many ingredients.</p>',  # nopep8
                new_label='Tiramisu Recipe',
            )
            bob_content_api.save(tiramisu_page)
        self._session.flush()
Ejemplo n.º 10
0
    def test_api___simple_search_ok__filter_by_deleted_archived_active(self) -> None:
        dbsession = get_tm_session(self.session_factory, transaction.manager)
        admin = dbsession.query(User).filter(User.email == "*****@*****.**").one()
        uapi = UserApi(current_user=admin, session=dbsession, config=self.app_config)
        gapi = GroupApi(current_user=admin, session=dbsession, config=self.app_config)
        groups = [gapi.get_one_with_name("trusted-users")]
        user = uapi.create_user(
            "*****@*****.**",
            password="******",
            do_save=True,
            do_notify=False,
            groups=groups,
        )
        workspace_api = WorkspaceApi(
            current_user=admin, session=dbsession, config=self.app_config, show_deleted=True
        )
        workspace = workspace_api.create_workspace("test", save_now=True)
        rapi = RoleApi(current_user=admin, session=dbsession, config=self.app_config)
        rapi.create_one(user, workspace, UserRoleInWorkspace.WORKSPACE_MANAGER, False)
        api = ContentApi(session=dbsession, current_user=user, config=self.app_config)
        api.create(
            content_type_slug="html-document",
            workspace=workspace,
            label="stringtosearch active",
            do_save=True,
        )
        api.create(
            content_type_slug="html-document",
            workspace=workspace,
            label="stringtosearch active 2",
            do_save=True,
        )
        deleted_content = api.create(
            content_type_slug="html-document",
            workspace=workspace,
            label="stringtosearch deleted",
            do_save=True,
        )
        with new_revision(session=dbsession, tm=transaction.manager, content=deleted_content):
            api.delete(deleted_content)
        api.save(deleted_content)
        archived_content = api.create(
            content_type_slug="html-document",
            workspace=workspace,
            label="stringtosearch archived",
            do_save=True,
        )
        with new_revision(session=dbsession, tm=transaction.manager, content=archived_content):
            api.archive(archived_content)
        api.save(archived_content)
        transaction.commit()

        # get all
        params = {
            "search_string": "stringtosearch",
            "show_deleted": 1,
            "show_archived": 1,
            "show_active": 1,
        }
        self.testapp.authorization = ("Basic", ("*****@*****.**", "*****@*****.**"))
        res = self.testapp.get("/api/v2/search/content".format(), status=200, params=params)
        search_result = res.json_body
        assert search_result
        assert search_result["total_hits"] == 4
        assert search_result["is_total_hits_accurate"] is False
        assert len(search_result["contents"]) == 4

        # get only active
        params = {"search_string": "stringtosearch"}
        self.testapp.authorization = ("Basic", ("*****@*****.**", "*****@*****.**"))
        res = self.testapp.get("/api/v2/search/content".format(), status=200, params=params)
        default_search_result = res.json_body
        assert default_search_result
        assert default_search_result["total_hits"] == 2
        assert default_search_result["is_total_hits_accurate"] is False
        assert len(default_search_result["contents"]) == 2
        assert default_search_result["contents"][0]["label"] == "stringtosearch active 2"
        assert default_search_result["contents"][1]["label"] == "stringtosearch active"

        params = {
            "search_string": "stringtosearch",
            "show_active": 1,
            "show_deleted": 0,
            "show_archived": 0,
        }
        self.testapp.authorization = ("Basic", ("*****@*****.**", "*****@*****.**"))
        res = self.testapp.get("/api/v2/search/content".format(), status=200, params=params)
        only_active_search_result = res.json_body
        assert only_active_search_result == default_search_result

        params = {
            "search_string": "stringtosearch",
            "show_active": 1,
            "show_deleted": 1,
            "show_archived": 0,
        }
        self.testapp.authorization = ("Basic", ("*****@*****.**", "*****@*****.**"))
        res = self.testapp.get("/api/v2/search/content".format(), status=200, params=params)
        search_result = res.json_body
        assert search_result
        assert search_result["total_hits"] == 3
        assert search_result["is_total_hits_accurate"] is False
        assert len(search_result["contents"]) == 3
        assert search_result["contents"][0]["label"].startswith("stringtosearch deleted")
        assert search_result["contents"][1]["label"] == "stringtosearch active 2"
        assert search_result["contents"][2]["label"] == "stringtosearch active"

        params = {
            "search_string": "stringtosearch",
            "show_active": 0,
            "show_deleted": 0,
            "show_archived": 1,
        }
        self.testapp.authorization = ("Basic", ("*****@*****.**", "*****@*****.**"))
        res = self.testapp.get("/api/v2/search/content".format(), status=200, params=params)
        search_result = res.json_body
        assert search_result
        assert search_result["total_hits"] == 1
        assert search_result["is_total_hits_accurate"] is False
        assert len(search_result["contents"]) == 1
        assert search_result["contents"][0]["label"].startswith("stringtosearch archived")