Bladeren bron

create a file controller example without specific code

Guénaël Muller 6 jaren geleden
bovenliggende
commit
406dba61a4
1 gewijzigde bestanden met toevoegingen van 205 en 0 verwijderingen
  1. 205 0
      tracim/views/contents_api/file_controller.py

+ 205 - 0
tracim/views/contents_api/file_controller.py Bestand weergeven

@@ -0,0 +1,205 @@
1
+# coding=utf-8
2
+import typing
3
+
4
+import transaction
5
+from pyramid.config import Configurator
6
+from tracim.models.data import UserRoleInWorkspace
7
+
8
+try:  # Python 3.5+
9
+    from http import HTTPStatus
10
+except ImportError:
11
+    from http import client as HTTPStatus
12
+
13
+from tracim import TracimRequest
14
+from tracim.extensions import hapic
15
+from tracim.lib.core.content import ContentApi
16
+from tracim.views.controllers import Controller
17
+from tracim.views.core_api.schemas import FileContentSchema
18
+from tracim.views.core_api.schemas import FileRevisionSchema
19
+from tracim.views.core_api.schemas import SetContentStatusSchema
20
+from tracim.views.core_api.schemas import FileModifySchema
21
+from tracim.views.core_api.schemas import WorkspaceAndContentIdPathSchema
22
+from tracim.views.core_api.schemas import NoContentSchema
23
+from tracim.lib.utils.authorization import require_content_types
24
+from tracim.lib.utils.authorization import require_workspace_role
25
+from tracim.exceptions import WorkspaceNotFound, ContentTypeNotAllowed
26
+from tracim.exceptions import InsufficientUserRoleInWorkspace
27
+from tracim.exceptions import NotAuthenticated
28
+from tracim.exceptions import AuthenticationFailed
29
+from tracim.models.context_models import ContentInContext
30
+from tracim.models.context_models import RevisionInContext
31
+from tracim.models.contents import ContentTypeLegacy as ContentType
32
+from tracim.models.contents import file_type
33
+from tracim.models.revision_protection import new_revision
34
+
35
+FILE_ENDPOINTS_TAG = 'Files'
36
+
37
+
38
+class FileController(Controller):
39
+
40
+    @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
41
+    @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
42
+    @hapic.handle_exception(InsufficientUserRoleInWorkspace, HTTPStatus.FORBIDDEN)
43
+    @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
44
+    @hapic.handle_exception(AuthenticationFailed, HTTPStatus.FORBIDDEN)
45
+    @hapic.handle_exception(ContentTypeNotAllowed, HTTPStatus.BAD_REQUEST)
46
+    @require_workspace_role(UserRoleInWorkspace.READER)
47
+    @require_content_types([file_type])
48
+    @hapic.input_path(WorkspaceAndContentIdPathSchema())
49
+    @hapic.output_body(FileContentSchema())
50
+    def get_file(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext:  # nopep8
51
+        """
52
+        Get thread content
53
+        """
54
+        app_config = request.registry.settings['CFG']
55
+        api = ContentApi(
56
+            current_user=request.current_user,
57
+            session=request.dbsession,
58
+            config=app_config,
59
+        )
60
+        content = api.get_one(
61
+            hapic_data.path.content_id,
62
+            content_type=ContentType.Any
63
+        )
64
+        return api.get_content_in_context(content)
65
+
66
+    @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
67
+    @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
68
+    @hapic.handle_exception(InsufficientUserRoleInWorkspace, HTTPStatus.FORBIDDEN)
69
+    @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
70
+    @hapic.handle_exception(AuthenticationFailed, HTTPStatus.FORBIDDEN)
71
+    @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
72
+    @require_content_types([file_type])
73
+    @hapic.input_path(WorkspaceAndContentIdPathSchema())
74
+    @hapic.input_body(FileModifySchema())
75
+    @hapic.output_body(FileContentSchema())
76
+    def update_file(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext:  # nopep8
77
+        """
78
+        update thread
79
+        """
80
+        app_config = request.registry.settings['CFG']
81
+        api = ContentApi(
82
+            current_user=request.current_user,
83
+            session=request.dbsession,
84
+            config=app_config,
85
+        )
86
+        content = api.get_one(
87
+            hapic_data.path.content_id,
88
+            content_type=ContentType.Any
89
+        )
90
+        with new_revision(
91
+                session=request.dbsession,
92
+                tm=transaction.manager,
93
+                content=content
94
+        ):
95
+            api.update_content(
96
+                item=content,
97
+                new_label=hapic_data.body.label,
98
+                new_content=hapic_data.body.raw_content,
99
+
100
+            )
101
+            api.save(content)
102
+        return api.get_content_in_context(content)
103
+
104
+    @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
105
+    @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
106
+    @hapic.handle_exception(InsufficientUserRoleInWorkspace, HTTPStatus.FORBIDDEN)
107
+    @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
108
+    @hapic.handle_exception(AuthenticationFailed, HTTPStatus.FORBIDDEN)
109
+    @require_workspace_role(UserRoleInWorkspace.READER)
110
+    @require_content_types([file_type])
111
+    @hapic.input_path(WorkspaceAndContentIdPathSchema())
112
+    @hapic.output_body(FileRevisionSchema(many=True))
113
+    def get_file_revisions(
114
+            self,
115
+            context,
116
+            request: TracimRequest,
117
+            hapic_data=None
118
+    ) -> typing.List[RevisionInContext]:
119
+        """
120
+        get file revisions
121
+        """
122
+        app_config = request.registry.settings['CFG']
123
+        api = ContentApi(
124
+            current_user=request.current_user,
125
+            session=request.dbsession,
126
+            config=app_config,
127
+        )
128
+        content = api.get_one(
129
+            hapic_data.path.content_id,
130
+            content_type=ContentType.Any
131
+        )
132
+        revisions = content.revisions
133
+        return [
134
+            api.get_revision_in_context(revision)
135
+            for revision in revisions
136
+        ]
137
+
138
+    @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
139
+    @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
140
+    @hapic.handle_exception(InsufficientUserRoleInWorkspace, HTTPStatus.FORBIDDEN)
141
+    @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
142
+    @hapic.handle_exception(AuthenticationFailed, HTTPStatus.FORBIDDEN)
143
+    @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
144
+    @require_content_types([file_type])
145
+    @hapic.input_path(WorkspaceAndContentIdPathSchema())
146
+    @hapic.input_body(SetContentStatusSchema())
147
+    @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT)  # nopep8
148
+    def set_file_status(self, context, request: TracimRequest, hapic_data=None) -> None:  # nopep8
149
+        """
150
+        set file status
151
+        """
152
+        app_config = request.registry.settings['CFG']
153
+        api = ContentApi(
154
+            current_user=request.current_user,
155
+            session=request.dbsession,
156
+            config=app_config,
157
+        )
158
+        content = api.get_one(
159
+            hapic_data.path.content_id,
160
+            content_type=ContentType.Any
161
+        )
162
+        with new_revision(
163
+                session=request.dbsession,
164
+                tm=transaction.manager,
165
+                content=content
166
+        ):
167
+            api.set_status(
168
+                content,
169
+                hapic_data.body.status,
170
+            )
171
+            api.save(content)
172
+        return
173
+
174
+    def bind(self, configurator: Configurator) -> None:
175
+        # Get file
176
+        configurator.add_route(
177
+            'file',
178
+            '/workspaces/{workspace_id}/files/{content_id}',
179
+            request_method='GET'
180
+        )
181
+        configurator.add_view(self.get_file, route_name='file')  # nopep8
182
+
183
+        # update file
184
+        configurator.add_route(
185
+            'update_file',
186
+            '/workspaces/{workspace_id}/files/{content_id}',
187
+            request_method='PUT'
188
+        )  # nopep8
189
+        configurator.add_view(self.update_file, route_name='update_file')  # nopep8
190
+
191
+        # get file revisions
192
+        configurator.add_route(
193
+            'file_revisions',
194
+            '/workspaces/{workspace_id}/files/{content_id}/revisions',  # nopep8
195
+            request_method='GET'
196
+        )
197
+        configurator.add_view(self.get_file_revisions, route_name='file_revisions')  # nopep8
198
+
199
+        # get file revisions
200
+        configurator.add_route(
201
+            'set_file_status',
202
+            '/workspaces/{workspace_id}/files/{content_id}/status',  # nopep8
203
+            request_method='PUT'
204
+        )
205
+        configurator.add_view(self.set_file_status, route_name='set_file_status')  # nopep8