comment_controller.py 5.5KB

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 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 EmptyCommentContentNotAllowed
  21. from tracim.models.contents import ContentTypeLegacy as ContentType
  22. from tracim.models.revision_protection import new_revision
  23. from tracim.models.data import UserRoleInWorkspace
  24. COMMENT_ENDPOINTS_TAG = 'Comments'
  25. class CommentController(Controller):
  26. @hapic.with_api_doc(tags=[COMMENT_ENDPOINTS_TAG])
  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=ContentType.Any
  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=[COMMENT_ENDPOINTS_TAG])
  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=ContentType.Any
  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=[COMMENT_ENDPOINTS_TAG])
  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=ContentType.Any,
  104. workspace=workspace
  105. )
  106. comment = api.get_one(
  107. hapic_data.path.comment_id,
  108. content_type=ContentType.Comment,
  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')