file_controller.py 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. # coding=utf-8
  2. import typing
  3. import transaction
  4. from pyramid.config import Configurator
  5. from tracim.exceptions import EmptyLabelNotAllowed
  6. from tracim.models.data import UserRoleInWorkspace
  7. try: # Python 3.5+
  8. from http import HTTPStatus
  9. except ImportError:
  10. from http import client as HTTPStatus
  11. from tracim import TracimRequest
  12. from tracim.extensions import hapic
  13. from tracim.lib.core.content import ContentApi
  14. from tracim.views.controllers import Controller
  15. from tracim.views.core_api.schemas import FileContentSchema
  16. from tracim.views.core_api.schemas import FileRevisionSchema
  17. from tracim.views.core_api.schemas import SetContentStatusSchema
  18. from tracim.views.core_api.schemas import FileContentModifySchema
  19. from tracim.views.core_api.schemas import WorkspaceAndContentIdPathSchema
  20. from tracim.views.core_api.schemas import NoContentSchema
  21. from tracim.lib.utils.authorization import require_content_types
  22. from tracim.lib.utils.authorization import require_workspace_role
  23. from tracim.models.context_models import ContentInContext
  24. from tracim.models.context_models import RevisionInContext
  25. from tracim.models.contents import ContentTypeLegacy as ContentType
  26. from tracim.models.contents import file_type
  27. from tracim.models.revision_protection import new_revision
  28. FILE_ENDPOINTS_TAG = 'Files'
  29. class FileController(Controller):
  30. # # File data
  31. # @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
  32. # @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
  33. # @require_content_types([file_type])
  34. # @hapic.input_path(WorkspaceAndContentIdPathSchema())
  35. # #@hapic.input_files()
  36. # @hapic.output_file([])
  37. # def upload_file(self, context, request: TracimRequest, hapic_data=None):
  38. # # TODO - G.M - 2018-07-05 - Do this endpoint
  39. # app_config = request.registry.settings['CFG']
  40. # api = ContentApi(
  41. # current_user=request.current_user,
  42. # session=request.dbsession,
  43. # config=app_config,
  44. # )
  45. # content = api.get_one(
  46. # hapic_data.path.content_id,
  47. # content_type=ContentType.Any
  48. # )
  49. # file = request.POST['files']
  50. # api.update_file_data(
  51. # content,
  52. # new_filename=file.filename,
  53. # new_mimetype=file.type,
  54. # new_content=file.file,
  55. # )
  56. # return content.depot_file
  57. #
  58. # @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
  59. # @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
  60. # @require_content_types([file_type])
  61. # @hapic.input_path(WorkspaceAndContentIdPathSchema())
  62. # @hapic.output_file([])
  63. # def download_file(self, context, request: TracimRequest, hapic_data=None):
  64. # # TODO - G.M - 2018-07-05 - Do this endpoint
  65. # app_config = request.registry.settings['CFG']
  66. # api = ContentApi(
  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=ContentType.Any
  74. # )
  75. # return content.depot_file
  76. # Previews
  77. # def get_file_preview(self):
  78. # # TODO - G.M - 2018-07-05 - Do this endpoint
  79. # pass
  80. # File infos
  81. @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
  82. @require_workspace_role(UserRoleInWorkspace.READER)
  83. @require_content_types([file_type])
  84. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  85. @hapic.output_body(FileContentSchema())
  86. def get_file_infos(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext: # nopep8
  87. """
  88. Get thread content
  89. """
  90. app_config = request.registry.settings['CFG']
  91. api = ContentApi(
  92. current_user=request.current_user,
  93. session=request.dbsession,
  94. config=app_config,
  95. )
  96. content = api.get_one(
  97. hapic_data.path.content_id,
  98. content_type=ContentType.Any
  99. )
  100. return api.get_content_in_context(content)
  101. @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
  102. @hapic.handle_exception(EmptyLabelNotAllowed, HTTPStatus.BAD_REQUEST)
  103. @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
  104. @require_content_types([file_type])
  105. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  106. @hapic.input_body(FileContentModifySchema())
  107. @hapic.output_body(FileContentSchema())
  108. def update_file_info(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext: # nopep8
  109. """
  110. update thread
  111. """
  112. app_config = request.registry.settings['CFG']
  113. api = ContentApi(
  114. current_user=request.current_user,
  115. session=request.dbsession,
  116. config=app_config,
  117. )
  118. content = api.get_one(
  119. hapic_data.path.content_id,
  120. content_type=ContentType.Any
  121. )
  122. with new_revision(
  123. session=request.dbsession,
  124. tm=transaction.manager,
  125. content=content
  126. ):
  127. api.update_content(
  128. item=content,
  129. new_label=hapic_data.body.label,
  130. new_content=hapic_data.body.raw_content,
  131. )
  132. api.save(content)
  133. return api.get_content_in_context(content)
  134. @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
  135. @require_workspace_role(UserRoleInWorkspace.READER)
  136. @require_content_types([file_type])
  137. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  138. @hapic.output_body(FileRevisionSchema(many=True))
  139. def get_file_revisions(
  140. self,
  141. context,
  142. request: TracimRequest,
  143. hapic_data=None
  144. ) -> typing.List[RevisionInContext]:
  145. """
  146. get file revisions
  147. """
  148. app_config = request.registry.settings['CFG']
  149. api = ContentApi(
  150. current_user=request.current_user,
  151. session=request.dbsession,
  152. config=app_config,
  153. )
  154. content = api.get_one(
  155. hapic_data.path.content_id,
  156. content_type=ContentType.Any
  157. )
  158. revisions = content.revisions
  159. return [
  160. api.get_revision_in_context(revision)
  161. for revision in revisions
  162. ]
  163. @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
  164. @hapic.handle_exception(EmptyLabelNotAllowed, HTTPStatus.BAD_REQUEST)
  165. @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
  166. @require_content_types([file_type])
  167. @hapic.input_path(WorkspaceAndContentIdPathSchema())
  168. @hapic.input_body(SetContentStatusSchema())
  169. @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
  170. def set_file_status(self, context, request: TracimRequest, hapic_data=None) -> None: # nopep8
  171. """
  172. set file status
  173. """
  174. app_config = request.registry.settings['CFG']
  175. api = ContentApi(
  176. current_user=request.current_user,
  177. session=request.dbsession,
  178. config=app_config,
  179. )
  180. content = api.get_one(
  181. hapic_data.path.content_id,
  182. content_type=ContentType.Any
  183. )
  184. with new_revision(
  185. session=request.dbsession,
  186. tm=transaction.manager,
  187. content=content
  188. ):
  189. api.set_status(
  190. content,
  191. hapic_data.body.status,
  192. )
  193. api.save(content)
  194. return
  195. def bind(self, configurator: Configurator) -> None:
  196. # Get file info
  197. configurator.add_route(
  198. 'file_info',
  199. '/workspaces/{workspace_id}/files/{content_id}',
  200. request_method='GET'
  201. )
  202. configurator.add_view(self.get_file_infos, route_name='file_info') # nopep8
  203. # update file
  204. configurator.add_route(
  205. 'update_file_info',
  206. '/workspaces/{workspace_id}/files/{content_id}',
  207. request_method='PUT'
  208. ) # nopep8
  209. configurator.add_view(self.update_file_info, route_name='update_file_info') # nopep8
  210. # # upload new file data
  211. # configurator.add_route(
  212. # 'upload_file',
  213. # '/workspaces/{workspace_id}/files/{content_id}/file_data', # nopep8
  214. # request_method='PUT'
  215. # )
  216. # configurator.add_view(self.upload_file, route_name='upload_file') # nopep8
  217. #
  218. # # download file data
  219. # configurator.add_route(
  220. # 'download_file',
  221. # '/workspaces/{workspace_id}/files/{content_id}/file_data', # nopep8
  222. # request_method='GET'
  223. # )
  224. # configurator.add_view(self.download_file, route_name='download_file') # nopep8
  225. # get file revisions
  226. configurator.add_route(
  227. 'file_revisions',
  228. '/workspaces/{workspace_id}/files/{content_id}/revisions', # nopep8
  229. request_method='GET'
  230. )
  231. configurator.add_view(self.get_file_revisions, route_name='file_revisions') # nopep8
  232. # get file revisions
  233. configurator.add_route(
  234. 'set_file_status',
  235. '/workspaces/{workspace_id}/files/{content_id}/status', # nopep8
  236. request_method='PUT'
  237. )
  238. configurator.add_view(self.set_file_status, route_name='set_file_status') # nopep8