comment_controller.py 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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
  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. @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. current_user=request.current_user,
  66. session=request.dbsession,
  67. config=app_config,
  68. )
  69. content = api.get_one(
  70. hapic_data.path.content_id,
  71. content_type=ContentType.Any
  72. )
  73. comment = api.create_comment(
  74. content.workspace,
  75. content,
  76. hapic_data.body.raw_content,
  77. do_save=True,
  78. )
  79. return api.get_content_in_context(comment)
  80. @hapic.with_api_doc(tags=[COMMENT_ENDPOINTS_TAG])
  81. @require_comment_ownership_or_role(
  82. minimal_required_role_for_anyone=UserRoleInWorkspace.WORKSPACE_MANAGER,
  83. minimal_required_role_for_owner=UserRoleInWorkspace.CONTRIBUTOR,
  84. )
  85. @hapic.input_path(CommentsPathSchema())
  86. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  87. def delete_comment(self, context, request: TracimRequest, hapic_data=None):
  88. """
  89. Delete comment
  90. """
  91. app_config = request.registry.settings['CFG']
  92. api = ContentApi(
  93. current_user=request.current_user,
  94. session=request.dbsession,
  95. config=app_config,
  96. )
  97. wapi = WorkspaceApi(
  98. current_user=request.current_user,
  99. session=request.dbsession,
  100. config=app_config,
  101. )
  102. workspace = wapi.get_one(hapic_data.path.workspace_id)
  103. parent = api.get_one(
  104. hapic_data.path.content_id,
  105. content_type=ContentType.Any,
  106. workspace=workspace
  107. )
  108. comment = api.get_one(
  109. hapic_data.path.comment_id,
  110. content_type=ContentType.Comment,
  111. workspace=workspace,
  112. parent=parent,
  113. )
  114. with new_revision(
  115. session=request.dbsession,
  116. tm=transaction.manager,
  117. content=comment
  118. ):
  119. api.delete(comment)
  120. return
  121. def bind(self, configurator: Configurator):
  122. # Get comments
  123. configurator.add_route(
  124. 'content_comments',
  125. '/workspaces/{workspace_id}/contents/{content_id}/comments',
  126. request_method='GET'
  127. )
  128. configurator.add_view(self.content_comments, route_name='content_comments')
  129. # Add comments
  130. configurator.add_route(
  131. 'add_comment',
  132. '/workspaces/{workspace_id}/contents/{content_id}/comments',
  133. request_method='POST'
  134. ) # nopep8
  135. configurator.add_view(self.add_comment, route_name='add_comment')
  136. # delete comments
  137. configurator.add_route(
  138. 'delete_comment',
  139. '/workspaces/{workspace_id}/contents/{content_id}/comments/{comment_id}', # nopep8
  140. request_method='DELETE'
  141. )
  142. configurator.add_view(self.delete_comment, route_name='delete_comment')