# coding=utf-8 import transaction from pyramid.config import Configurator try: # Python 3.5+ from http import HTTPStatus except ImportError: from http import client as HTTPStatus from tracim_backend.lib.utils.request import TracimRequest from tracim_backend.extensions import hapic from tracim_backend.lib.core.content import ContentApi from tracim_backend.lib.core.workspace import WorkspaceApi from tracim_backend.lib.utils.authorization import require_workspace_role from tracim_backend.lib.utils.authorization import require_comment_ownership_or_role from tracim_backend.views.controllers import Controller from tracim_backend.views.core_api.schemas import CommentSchema from tracim_backend.views.core_api.schemas import CommentsPathSchema from tracim_backend.views.core_api.schemas import SetCommentSchema from tracim_backend.views.core_api.schemas import WorkspaceAndContentIdPathSchema from tracim_backend.views.core_api.schemas import NoContentSchema from tracim_backend.exceptions import EmptyCommentContentNotAllowed from tracim_backend.app_models.contents import CONTENT_TYPES from tracim_backend.models.revision_protection import new_revision from tracim_backend.models.data import UserRoleInWorkspace SWAGGER_TAG__COMMENT_ENDPOINTS = 'Comments' class CommentController(Controller): @hapic.with_api_doc(tags=[SWAGGER_TAG__COMMENT_ENDPOINTS]) @require_workspace_role(UserRoleInWorkspace.READER) @hapic.input_path(WorkspaceAndContentIdPathSchema()) @hapic.output_body(CommentSchema(many=True)) def content_comments(self, context, request: TracimRequest, hapic_data=None): """ Get all comments related to a content in asc order (first is the oldest) """ # login = hapic_data.body 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, ) content = api.get_one( hapic_data.path.content_id, content_type=CONTENT_TYPES.Any_SLUG ) comments = content.get_comments() comments.sort(key=lambda comment: comment.created) return [api.get_content_in_context(comment) for comment in comments ] @hapic.with_api_doc(tags=[SWAGGER_TAG__COMMENT_ENDPOINTS]) @hapic.handle_exception(EmptyCommentContentNotAllowed, HTTPStatus.BAD_REQUEST) # nopep8 @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR) @hapic.input_path(WorkspaceAndContentIdPathSchema()) @hapic.input_body(SetCommentSchema()) @hapic.output_body(CommentSchema()) def add_comment(self, context, request: TracimRequest, hapic_data=None): """ Add new comment """ # login = hapic_data.body 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, ) content = api.get_one( hapic_data.path.content_id, content_type=CONTENT_TYPES.Any_SLUG ) comment = api.create_comment( content.workspace, content, hapic_data.body.raw_content, do_save=True, ) return api.get_content_in_context(comment) @hapic.with_api_doc(tags=[SWAGGER_TAG__COMMENT_ENDPOINTS]) @require_comment_ownership_or_role( minimal_required_role_for_anyone=UserRoleInWorkspace.WORKSPACE_MANAGER, minimal_required_role_for_owner=UserRoleInWorkspace.CONTRIBUTOR, ) @hapic.input_path(CommentsPathSchema()) @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8 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_TYPES.Any_SLUG, workspace=workspace ) comment = api.get_one( hapic_data.path.comment_id, content_type=CONTENT_TYPES.Comment.slug, workspace=workspace, parent=parent, ) with new_revision( session=request.dbsession, tm=transaction.manager, content=comment ): api.delete(comment) return def bind(self, configurator: Configurator): # Get comments configurator.add_route( 'content_comments', '/workspaces/{workspace_id}/contents/{content_id}/comments', request_method='GET' ) configurator.add_view(self.content_comments, route_name='content_comments') # Add comments configurator.add_route( 'add_comment', '/workspaces/{workspace_id}/contents/{content_id}/comments', request_method='POST' ) # nopep8 configurator.add_view(self.add_comment, route_name='add_comment') # delete comments configurator.add_route( 'delete_comment', '/workspaces/{workspace_id}/contents/{content_id}/comments/{comment_id}', # nopep8 request_method='DELETE' ) configurator.add_view(self.delete_comment, route_name='delete_comment')