123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- # coding=utf-8
- import typing
-
- import transaction
- from depot.io.local import LocalStoredFile
- from depot.manager import DepotManager
- from pyramid.config import Configurator
- from pyramid.response import FileResponse, FileIter
-
- from tracim.exceptions import EmptyLabelNotAllowed
- from tracim.models.data import UserRoleInWorkspace
-
- try: # Python 3.5+
- from http import HTTPStatus
- except ImportError:
- from http import client as HTTPStatus
-
- from tracim import TracimRequest
- from tracim.extensions import hapic
- from tracim.lib.core.content import ContentApi
- from tracim.views.controllers import Controller
- from tracim.views.core_api.schemas import FileContentSchema
- from tracim.views.core_api.schemas import FileRevisionSchema
- from tracim.views.core_api.schemas import SetContentStatusSchema
- from tracim.views.core_api.schemas import FileContentModifySchema
- from tracim.views.core_api.schemas import WorkspaceAndContentIdPathSchema
- from tracim.views.core_api.schemas import NoContentSchema
- from tracim.lib.utils.authorization import require_content_types
- from tracim.lib.utils.authorization import require_workspace_role
- from tracim.models.context_models import ContentInContext
- from tracim.models.context_models import RevisionInContext
- from tracim.models.contents import ContentTypeLegacy as ContentType
- from tracim.models.contents import file_type
- from tracim.models.revision_protection import new_revision
-
- FILE_ENDPOINTS_TAG = 'Files'
-
-
- class FileController(Controller):
-
- # File data
- @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
- @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
- @require_content_types([file_type])
- @hapic.input_path(WorkspaceAndContentIdPathSchema())
- #@hapic.input_files()
- @hapic.output_file([])
- def upload_file(self, context, request: TracimRequest, hapic_data=None):
- # TODO - G.M - 2018-07-05 - Do this endpoint
- app_config = request.registry.settings['CFG']
- api = ContentApi(
- current_user=request.current_user,
- session=request.dbsession,
- config=app_config,
- )
- content = api.get_one(
- hapic_data.path.content_id,
- content_type=ContentType.Any
- )
- file = request.POST['files']
- with new_revision(
- session=request.dbsession,
- tm=transaction.manager,
- content=content
- ):
- api.update_file_data(
- content,
- new_filename=file.filename,
- new_mimetype=file.type,
- new_content=file.file,
- )
- file = DepotManager.get().get(content.depot_file)
- response = request.response
- response.content_type = file.content_type
- response.app_iter = FileIter(file)
- return response
-
- @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
- @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
- @require_content_types([file_type])
- @hapic.input_path(WorkspaceAndContentIdPathSchema())
- @hapic.output_file([])
- def download_file(self, context, request: TracimRequest, hapic_data=None):
- # TODO - G.M - 2018-07-05 - Do this endpoint
- app_config = request.registry.settings['CFG']
- api = ContentApi(
- current_user=request.current_user,
- session=request.dbsession,
- config=app_config,
- )
- content = api.get_one(
- hapic_data.path.content_id,
- content_type=ContentType.Any
- )
- file = DepotManager.get().get(content.depot_file)
- response = request.response
- response.content_type = file.content_type
- response.app_iter = FileIter(file)
- return response
-
-
- # Previews
- # def get_file_preview(self):
- # # TODO - G.M - 2018-07-05 - Do this endpoint
- # pass
-
- # File infos
- @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
- @require_workspace_role(UserRoleInWorkspace.READER)
- @require_content_types([file_type])
- @hapic.input_path(WorkspaceAndContentIdPathSchema())
- @hapic.output_body(FileContentSchema())
- def get_file_infos(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext: # nopep8
- """
- Get thread content
- """
- app_config = request.registry.settings['CFG']
- api = ContentApi(
- current_user=request.current_user,
- session=request.dbsession,
- config=app_config,
- )
- content = api.get_one(
- hapic_data.path.content_id,
- content_type=ContentType.Any
- )
- return api.get_content_in_context(content)
-
- @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
- @hapic.handle_exception(EmptyLabelNotAllowed, HTTPStatus.BAD_REQUEST)
- @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
- @require_content_types([file_type])
- @hapic.input_path(WorkspaceAndContentIdPathSchema())
- @hapic.input_body(FileContentModifySchema())
- @hapic.output_body(FileContentSchema())
- def update_file_info(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext: # nopep8
- """
- update thread
- """
- app_config = request.registry.settings['CFG']
- api = ContentApi(
- current_user=request.current_user,
- session=request.dbsession,
- config=app_config,
- )
- content = api.get_one(
- hapic_data.path.content_id,
- content_type=ContentType.Any
- )
- with new_revision(
- session=request.dbsession,
- tm=transaction.manager,
- content=content
- ):
- api.update_content(
- item=content,
- new_label=hapic_data.body.label,
- new_content=hapic_data.body.raw_content,
-
- )
- api.save(content)
- return api.get_content_in_context(content)
-
- @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
- @require_workspace_role(UserRoleInWorkspace.READER)
- @require_content_types([file_type])
- @hapic.input_path(WorkspaceAndContentIdPathSchema())
- @hapic.output_body(FileRevisionSchema(many=True))
- def get_file_revisions(
- self,
- context,
- request: TracimRequest,
- hapic_data=None
- ) -> typing.List[RevisionInContext]:
- """
- get file revisions
- """
- app_config = request.registry.settings['CFG']
- api = ContentApi(
- current_user=request.current_user,
- session=request.dbsession,
- config=app_config,
- )
- content = api.get_one(
- hapic_data.path.content_id,
- content_type=ContentType.Any
- )
- revisions = content.revisions
- return [
- api.get_revision_in_context(revision)
- for revision in revisions
- ]
-
- @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
- @hapic.handle_exception(EmptyLabelNotAllowed, HTTPStatus.BAD_REQUEST)
- @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
- @require_content_types([file_type])
- @hapic.input_path(WorkspaceAndContentIdPathSchema())
- @hapic.input_body(SetContentStatusSchema())
- @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT) # nopep8
- def set_file_status(self, context, request: TracimRequest, hapic_data=None) -> None: # nopep8
- """
- set file status
- """
- app_config = request.registry.settings['CFG']
- api = ContentApi(
- current_user=request.current_user,
- session=request.dbsession,
- config=app_config,
- )
- content = api.get_one(
- hapic_data.path.content_id,
- content_type=ContentType.Any
- )
- with new_revision(
- session=request.dbsession,
- tm=transaction.manager,
- content=content
- ):
- api.set_status(
- content,
- hapic_data.body.status,
- )
- api.save(content)
- return
-
- def bind(self, configurator: Configurator) -> None:
- # Get file info
- configurator.add_route(
- 'file_info',
- '/workspaces/{workspace_id}/files/{content_id}',
- request_method='GET'
- )
- configurator.add_view(self.get_file_infos, route_name='file_info') # nopep8
-
- # update file
- configurator.add_route(
- 'update_file_info',
- '/workspaces/{workspace_id}/files/{content_id}',
- request_method='PUT'
- ) # nopep8
- configurator.add_view(self.update_file_info, route_name='update_file_info') # nopep8
-
- # upload new file data
- configurator.add_route(
- 'upload_file',
- '/workspaces/{workspace_id}/files/{content_id}/file_data', # nopep8
- request_method='PUT'
- )
- configurator.add_view(self.upload_file, route_name='upload_file') # nopep8
-
- # download file data
- configurator.add_route(
- 'download_file',
- '/workspaces/{workspace_id}/files/{content_id}/file_data', # nopep8
- request_method='GET'
- )
- configurator.add_view(self.download_file, route_name='download_file') # nopep8
- # get file revisions
- configurator.add_route(
- 'file_revisions',
- '/workspaces/{workspace_id}/files/{content_id}/revisions', # nopep8
- request_method='GET'
- )
- configurator.add_view(self.get_file_revisions, route_name='file_revisions') # nopep8
-
- # get file revisions
- configurator.add_route(
- 'set_file_status',
- '/workspaces/{workspace_id}/files/{content_id}/status', # nopep8
- request_method='PUT'
- )
- configurator.add_view(self.set_file_status, route_name='set_file_status') # nopep8
|