comment_controller.py 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 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.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. current_user=request.current_user,
  38. session=request.dbsession,
  39. config=app_config,
  40. )
  41. content = api.get_one(
  42. hapic_data.path.content_id,
  43. content_type=CONTENT_TYPES.Any_SLUG
  44. )
  45. comments = content.get_comments()
  46. comments.sort(key=lambda comment: comment.created)
  47. return [api.get_content_in_context(comment)
  48. for comment in comments
  49. ]
  50. @hapic.with_api_doc(tags=[SWAGGER_TAG__COMMENT_ENDPOINTS])
  51. @hapic.handle_exception(EmptyCommentContentNotAllowed, HTTPStatus.BAD_REQUEST) # nopep8
  52. @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
  53. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  54. @hapic.input_body(SetCommentSchema())
  55. @hapic.output_body(CommentSchema())
  56. def add_comment(self, context, request: TracimRequest, hapic_data=None):
  57. """
  58. Add new comment
  59. """
  60. # login = hapic_data.body
  61. app_config = request.registry.settings['CFG']
  62. api = ContentApi(
  63. current_user=request.current_user,
  64. session=request.dbsession,
  65. config=app_config,
  66. )
  67. content = api.get_one(
  68. hapic_data.path.content_id,
  69. content_type=CONTENT_TYPES.Any_SLUG
  70. )
  71. comment = api.create_comment(
  72. content.workspace,
  73. content,
  74. hapic_data.body.raw_content,
  75. do_save=True,
  76. )
  77. return api.get_content_in_context(comment)
  78. @hapic.with_api_doc(tags=[SWAGGER_TAG__COMMENT_ENDPOINTS])
  79. @require_comment_ownership_or_role(
  80. minimal_required_role_for_anyone=UserRoleInWorkspace.WORKSPACE_MANAGER,
  81. minimal_required_role_for_owner=UserRoleInWorkspace.CONTRIBUTOR,
  82. )
  83. @hapic.input_path(CommentsPathSchema())
  84. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  85. def delete_comment(self, context, request: TracimRequest, hapic_data=None):
  86. """
  87. Delete comment
  88. """
  89. app_config = request.registry.settings['CFG']
  90. api = ContentApi(
  91. current_user=request.current_user,
  92. session=request.dbsession,
  93. config=app_config,
  94. )
  95. wapi = WorkspaceApi(
  96. current_user=request.current_user,
  97. session=request.dbsession,
  98. config=app_config,
  99. )
  100. workspace = wapi.get_one(hapic_data.path.workspace_id)
  101. parent = api.get_one(
  102. hapic_data.path.content_id,
  103. content_type=CONTENT_TYPES.Any_SLUG,
  104. workspace=workspace
  105. )
  106. comment = api.get_one(
  107. hapic_data.path.comment_id,
  108. content_type=CONTENT_TYPES.Comment.slug,
  109. workspace=workspace,
  110. parent=parent,
  111. )
  112. with new_revision(
  113. session=request.dbsession,
  114. tm=transaction.manager,
  115. content=comment
  116. ):
  117. api.delete(comment)
  118. return
  119. def bind(self, configurator: Configurator):
  120. # Get comments
  121. configurator.add_route(
  122. 'content_comments',
  123. '/workspaces/{workspace_id}/contents/{content_id}/comments',
  124. request_method='GET'
  125. )
  126. configurator.add_view(self.content_comments, route_name='content_comments')
  127. # Add comments
  128. configurator.add_route(
  129. 'add_comment',
  130. '/workspaces/{workspace_id}/contents/{content_id}/comments',
  131. request_method='POST'
  132. ) # nopep8
  133. configurator.add_view(self.add_comment, route_name='add_comment')
  134. # delete comments
  135. configurator.add_route(
  136. 'delete_comment',
  137. '/workspaces/{workspace_id}/contents/{content_id}/comments/{comment_id}', # nopep8
  138. request_method='DELETE'
  139. )
  140. configurator.add_view(self.delete_comment, route_name='delete_comment')