comment_controller.py 5.6KB

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