comment_controller.py 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. # coding=utf-8
  2. import transaction
  3. from pyramid.config import Configurator
  4. try: # Python 3.5+
  5. from http import HTTPStatus
  6. except ImportError:
  7. from http import client as HTTPStatus
  8. from tracim_backend.lib.utils.request import TracimRequest
  9. from tracim_backend.extensions import hapic
  10. from tracim_backend.lib.core.content import ContentApi
  11. from tracim_backend.lib.core.workspace import WorkspaceApi
  12. from tracim_backend.lib.utils.authorization import require_workspace_role
  13. from tracim_backend.lib.utils.authorization import require_comment_ownership_or_role
  14. from tracim_backend.views.controllers import Controller
  15. from tracim_backend.views.core_api.schemas import CommentSchema
  16. from tracim_backend.views.core_api.schemas import CommentsPathSchema
  17. from tracim_backend.views.core_api.schemas import SetCommentSchema
  18. from tracim_backend.views.core_api.schemas import WorkspaceAndContentIdPathSchema
  19. from tracim_backend.views.core_api.schemas import NoContentSchema
  20. from tracim_backend.exceptions import EmptyCommentContentNotAllowed
  21. from tracim_backend.app_models.contents import CONTENT_TYPES
  22. from tracim_backend.models.revision_protection import new_revision
  23. from tracim_backend.models.data import UserRoleInWorkspace
  24. SWAGGER_TAG__COMMENT_ENDPOINTS = 'Comments'
  25. class CommentController(Controller):
  26. @hapic.with_api_doc(tags=[SWAGGER_TAG__COMMENT_ENDPOINTS])
  27. @require_workspace_role(UserRoleInWorkspace.READER)
  28. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  29. @hapic.output_body(CommentSchema(many=True))
  30. def content_comments(self, context, request: TracimRequest, hapic_data=None):
  31. """
  32. Get all comments related to a content in asc order (first is the oldest)
  33. """
  34. # login = hapic_data.body
  35. app_config = request.registry.settings['CFG']
  36. api = ContentApi(
  37. show_archived=True,
  38. show_deleted=True,
  39. current_user=request.current_user,
  40. session=request.dbsession,
  41. config=app_config,
  42. )
  43. content = api.get_one(
  44. hapic_data.path.content_id,
  45. content_type=CONTENT_TYPES.Any_SLUG
  46. )
  47. comments = content.get_comments()
  48. comments.sort(key=lambda comment: comment.created)
  49. return [api.get_content_in_context(comment)
  50. for comment in comments
  51. ]
  52. @hapic.with_api_doc(tags=[SWAGGER_TAG__COMMENT_ENDPOINTS])
  53. @hapic.handle_exception(EmptyCommentContentNotAllowed, HTTPStatus.BAD_REQUEST) # nopep8
  54. @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
  55. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  56. @hapic.input_body(SetCommentSchema())
  57. @hapic.output_body(CommentSchema())
  58. def add_comment(self, context, request: TracimRequest, hapic_data=None):
  59. """
  60. Add new comment
  61. """
  62. # login = hapic_data.body
  63. app_config = request.registry.settings['CFG']
  64. api = ContentApi(
  65. show_archived=True,
  66. show_deleted=True,
  67. current_user=request.current_user,
  68. session=request.dbsession,
  69. config=app_config,
  70. )
  71. content = api.get_one(
  72. hapic_data.path.content_id,
  73. content_type=CONTENT_TYPES.Any_SLUG
  74. )
  75. comment = api.create_comment(
  76. content.workspace,
  77. content,
  78. hapic_data.body.raw_content,
  79. do_save=True,
  80. )
  81. return api.get_content_in_context(comment)
  82. @hapic.with_api_doc(tags=[SWAGGER_TAG__COMMENT_ENDPOINTS])
  83. @require_comment_ownership_or_role(
  84. minimal_required_role_for_anyone=UserRoleInWorkspace.WORKSPACE_MANAGER,
  85. minimal_required_role_for_owner=UserRoleInWorkspace.CONTRIBUTOR,
  86. )
  87. @hapic.input_path(CommentsPathSchema())
  88. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  89. def delete_comment(self, context, request: TracimRequest, hapic_data=None):
  90. """
  91. Delete comment
  92. """
  93. app_config = request.registry.settings['CFG']
  94. api = ContentApi(
  95. show_archived=True,
  96. show_deleted=True,
  97. current_user=request.current_user,
  98. session=request.dbsession,
  99. config=app_config,
  100. )
  101. wapi = WorkspaceApi(
  102. current_user=request.current_user,
  103. session=request.dbsession,
  104. config=app_config,
  105. )
  106. workspace = wapi.get_one(hapic_data.path.workspace_id)
  107. parent = api.get_one(
  108. hapic_data.path.content_id,
  109. content_type=CONTENT_TYPES.Any_SLUG,
  110. workspace=workspace
  111. )
  112. comment = api.get_one(
  113. hapic_data.path.comment_id,
  114. content_type=CONTENT_TYPES.Comment.slug,
  115. workspace=workspace,
  116. parent=parent,
  117. )
  118. with new_revision(
  119. session=request.dbsession,
  120. tm=transaction.manager,
  121. content=comment
  122. ):
  123. api.delete(comment)
  124. return
  125. def bind(self, configurator: Configurator):
  126. # Get comments
  127. configurator.add_route(
  128. 'content_comments',
  129. '/workspaces/{workspace_id}/contents/{content_id}/comments',
  130. request_method='GET'
  131. )
  132. configurator.add_view(self.content_comments, route_name='content_comments')
  133. # Add comments
  134. configurator.add_route(
  135. 'add_comment',
  136. '/workspaces/{workspace_id}/contents/{content_id}/comments',
  137. request_method='POST'
  138. ) # nopep8
  139. configurator.add_view(self.add_comment, route_name='add_comment')
  140. # delete comments
  141. configurator.add_route(
  142. 'delete_comment',
  143. '/workspaces/{workspace_id}/contents/{content_id}/comments/{comment_id}', # nopep8
  144. request_method='DELETE'
  145. )
  146. configurator.add_view(self.delete_comment, route_name='delete_comment')