Completed
Push — develop ( 1af38c...877f7e )
by Bastien
21s queued 10s
created

backend.tracim_backend.views.contents_api.file_controller   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 783
Duplicated Lines 27.33 %

Importance

Changes 0
Metric Value
wmc 23
eloc 589
dl 214
loc 783
rs 10
c 0
b 0
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
A FileController.preview_jpg() 0 40 1
A FileController.download_revisions_file() 32 32 1
A FileController.update_file_info() 0 37 2
A FileController.set_file_status() 0 34 2
B FileController.sized_preview_jpg_revision() 46 46 1
A FileController.preview_pdf_full_revision() 36 36 1
A FileController.get_file_revisions() 0 30 1
A FileController.download_file() 28 28 1
A FileController.sized_preview_jpg() 42 42 1
A FileController.preview_pdf() 0 35 1
A FileController.get_file_infos() 0 22 1
A FileController.preview_pdf_revision() 0 41 1
B FileController.bind() 0 124 1
B FileController.create_file() 0 55 4
A FileController.upload_file() 0 37 2
A FileController.allowed_dim_preview_jpg() 0 19 1
A FileController.preview_pdf_full() 30 30 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
# coding=utf-8
2
import typing
3
4
import transaction
5
from depot.manager import DepotManager
6
from hapic.data import HapicFile
7
from preview_generator.exception import UnavailablePreviewType
8
from pyramid.config import Configurator
9
10
from tracim_backend.app_models.contents import CONTENT_TYPES
11
from tracim_backend.app_models.contents import FILE_TYPE
12
from tracim_backend.exceptions import ContentLabelAlreadyUsedHere
13
from tracim_backend.exceptions import ContentNotFound
14
from tracim_backend.exceptions import EmptyLabelNotAllowed
15
from tracim_backend.exceptions import PageOfPreviewNotFound
16
from tracim_backend.exceptions import ParentNotFound
17
from tracim_backend.exceptions import PreviewDimNotAllowed
18
from tracim_backend.exceptions import TracimUnavailablePreviewType
19
from tracim_backend.exceptions import UnavailablePreview
20
from tracim_backend.extensions import hapic
21
from tracim_backend.lib.core.content import ContentApi
22
from tracim_backend.lib.utils.authorization import require_content_types
23
from tracim_backend.lib.utils.authorization import require_workspace_role
24
from tracim_backend.lib.utils.request import TracimRequest
25
from tracim_backend.models.context_models import ContentInContext
26
from tracim_backend.models.context_models import RevisionInContext
27
from tracim_backend.models.data import ActionDescription
28
from tracim_backend.models.data import UserRoleInWorkspace
29
from tracim_backend.models.revision_protection import new_revision
30
from tracim_backend.views.controllers import Controller
31
from tracim_backend.views.core_api.schemas import AllowedJpgPreviewDimSchema
32
from tracim_backend.views.core_api.schemas import ContentDigestSchema
33
from tracim_backend.views.core_api.schemas import ContentPreviewSizedPathSchema
34
from tracim_backend.views.core_api.schemas import FileContentModifySchema
35
from tracim_backend.views.core_api.schemas import FileContentSchema
36
from tracim_backend.views.core_api.schemas import FileCreationFormSchema
37
from tracim_backend.views.core_api.schemas import FileQuerySchema
38
from tracim_backend.views.core_api.schemas import FileRevisionSchema
39
from tracim_backend.views.core_api.schemas import NoContentSchema
40
from tracim_backend.views.core_api.schemas import PageQuerySchema
41
from tracim_backend.views.core_api.schemas import \
42
    RevisionPreviewSizedPathSchema
43
from tracim_backend.views.core_api.schemas import SetContentStatusSchema
44
from tracim_backend.views.core_api.schemas import SimpleFileSchema
45
from tracim_backend.views.core_api.schemas import \
46
    WorkspaceAndContentIdPathSchema
47
from tracim_backend.views.core_api.schemas import \
48
    WorkspaceAndContentRevisionIdPathSchema
49
from tracim_backend.views.core_api.schemas import WorkspaceIdPathSchema
50
51
try:  # Python 3.5+
52
    from http import HTTPStatus
53
except ImportError:
54
    from http import client as HTTPStatus
55
56
SWAGGER_TAG__FILE_ENDPOINTS = 'Files'
57
58
59
class FileController(Controller):
60
    """
61
    Endpoints for File Content
62
    """
63
64
    # File data
65
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
66
    @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
67
    @hapic.input_path(WorkspaceIdPathSchema())
68
    @hapic.output_body(ContentDigestSchema())
69
    @hapic.input_forms(FileCreationFormSchema())
70
    @hapic.input_files(SimpleFileSchema())
71
    def create_file(self, context, request: TracimRequest, hapic_data=None):
72
        """
73
        Create a file .This will create 2 new
74
        revision.
75
        """
76
        app_config = request.registry.settings['CFG']
77
        api = ContentApi(
78
            show_archived=True,
79
            show_deleted=True,
80
            current_user=request.current_user,
81
            session=request.dbsession,
82
            config=app_config,
83
        )
84
        _file = hapic_data.files.files
85
        parent_id = hapic_data.forms.parent_id
86
        api = ContentApi(
87
            current_user=request.current_user,
88
            session=request.dbsession,
89
            config=app_config
90
        )
91
92
        parent = None  # type: typing.Optional['Content']
93
        if parent_id:
94
            try:
95
                parent = api.get_one(content_id=parent_id, content_type=CONTENT_TYPES.Any_SLUG)  # nopep8
96
            except ContentNotFound as exc:
97
                raise ParentNotFound(
98
                    'Parent with content_id {} not found'.format(parent_id)
99
                ) from exc
100
        content = api.create(
101
            filename=_file.filename,
102
            content_type_slug=FILE_TYPE,
103
            workspace=request.current_workspace,
104
            parent=parent,
105
        )
106
        api.save(content, ActionDescription.CREATION)
107
        with new_revision(
108
                session=request.dbsession,
109
                tm=transaction.manager,
110
                content=content
111
        ):
112
            api.update_file_data(
113
                content,
114
                new_filename=_file.filename,
115
                new_mimetype=_file.type,
116
                new_content=_file.file,
117
            )
118
119
        return api.get_content_in_context(content)
120
121
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
122
    @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
123
    @require_content_types([FILE_TYPE])
124
    @hapic.input_path(WorkspaceAndContentIdPathSchema())
125
    @hapic.input_files(SimpleFileSchema())
126
    @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT)  # nopep8
127
    def upload_file(self, context, request: TracimRequest, hapic_data=None):
128
        """
129
        Upload a new version of raw file of content. This will create a new
130
        revision.
131
        """
132
        app_config = request.registry.settings['CFG']
133
        api = ContentApi(
134
            show_archived=True,
135
            show_deleted=True,
136
            current_user=request.current_user,
137
            session=request.dbsession,
138
            config=app_config,
139
        )
140
        content = api.get_one(
141
            hapic_data.path.content_id,
142
            content_type=CONTENT_TYPES.Any_SLUG
143
        )
144
        _file = hapic_data.files.files
145
        with new_revision(
146
                session=request.dbsession,
147
                tm=transaction.manager,
148
                content=content
149
        ):
150
            api.update_file_data(
151
                content,
152
                new_filename=_file.filename,
153
                new_mimetype=_file.type,
154
                new_content=_file.file,
155
            )
156
        api.save(content)
157
        return
158
159 View Code Duplication
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
160
    @require_workspace_role(UserRoleInWorkspace.READER)
161
    @require_content_types([FILE_TYPE])
162
    @hapic.input_query(FileQuerySchema())
163
    @hapic.input_path(WorkspaceAndContentIdPathSchema())
164
    @hapic.output_file([])
165
    def download_file(self, context, request: TracimRequest, hapic_data=None):
166
        """
167
        Download raw file of last revision of content.
168
        """
169
        app_config = request.registry.settings['CFG']
170
        api = ContentApi(
171
            show_archived=True,
172
            show_deleted=True,
173
            current_user=request.current_user,
174
            session=request.dbsession,
175
            config=app_config,
176
        )
177
        content = api.get_one(
178
            hapic_data.path.content_id,
179
            content_type=CONTENT_TYPES.Any_SLUG
180
        )
181
        file = DepotManager.get().get(content.depot_file)
182
        return HapicFile(
183
            file_object=file,
184
            mimetype=file.content_type,
185
            filename=content.file_name,
186
            as_attachment=hapic_data.query.force_download
187
        )
188
189 View Code Duplication
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
190
    @require_workspace_role(UserRoleInWorkspace.READER)
191
    @require_content_types([FILE_TYPE])
192
    @hapic.input_query(FileQuerySchema())
193
    @hapic.input_path(WorkspaceAndContentRevisionIdPathSchema())
194
    @hapic.output_file([])
195
    def download_revisions_file(self, context, request: TracimRequest, hapic_data=None):  # nopep8
196
        """
197
        Download raw file for specific revision of content.
198
        """
199
        app_config = request.registry.settings['CFG']
200
        api = ContentApi(
201
            show_archived=True,
202
            show_deleted=True,
203
            current_user=request.current_user,
204
            session=request.dbsession,
205
            config=app_config,
206
        )
207
        content = api.get_one(
208
            hapic_data.path.content_id,
209
            content_type=CONTENT_TYPES.Any_SLUG
210
        )
211
        revision = api.get_one_revision(
212
            revision_id=hapic_data.path.revision_id,
213
            content=content
214
        )
215
        file = DepotManager.get().get(revision.depot_file)
216
        return HapicFile(
217
            file_object=file,
218
            mimetype=file.content_type,
219
            filename=revision.file_name,
220
            as_attachment=hapic_data.query.force_download
221
        )
222
223
    # preview
224
    # pdf
225
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
226
    @require_workspace_role(UserRoleInWorkspace.READER)
227
    @require_content_types([FILE_TYPE])
228
    @hapic.handle_exception(TracimUnavailablePreviewType, HTTPStatus.BAD_REQUEST)
229
    @hapic.handle_exception(UnavailablePreview, HTTPStatus.BAD_REQUEST)
230
    @hapic.handle_exception(PageOfPreviewNotFound, HTTPStatus.BAD_REQUEST)
231
    @hapic.input_query(PageQuerySchema())
232
    @hapic.input_path(WorkspaceAndContentIdPathSchema())
233
    @hapic.output_file([])
234
    def preview_pdf(self, context, request: TracimRequest, hapic_data=None):
235
        """
236
        Obtain a specific page pdf preview of last revision of content.
237
        """
238
        app_config = request.registry.settings['CFG']
239
        api = ContentApi(
240
            show_archived=True,
241
            show_deleted=True,
242
            current_user=request.current_user,
243
            session=request.dbsession,
244
            config=app_config,
245
        )
246
        content = api.get_one(
247
            hapic_data.path.content_id,
248
            content_type=CONTENT_TYPES.Any_SLUG
249
        )
250
        pdf_preview_path = api.get_pdf_preview_path(
251
            content.content_id,
252
            content.revision_id,
253
            page_number=hapic_data.query.page
254
        )
255
        filename = "{}_page_{}.pdf".format(content.label, hapic_data.query.page)
256
        return HapicFile(
257
            file_path=pdf_preview_path,
258
            filename=filename,
259
            as_attachment=hapic_data.query.force_download
260
        )
261
262 View Code Duplication
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
263
    @require_workspace_role(UserRoleInWorkspace.READER)
264
    @require_content_types([FILE_TYPE])
265
    @hapic.handle_exception(TracimUnavailablePreviewType, HTTPStatus.BAD_REQUEST)
266
    @hapic.handle_exception(UnavailablePreview, HTTPStatus.BAD_REQUEST)
267
    @hapic.input_query(FileQuerySchema())
268
    @hapic.input_path(WorkspaceAndContentIdPathSchema())
269
    @hapic.output_file([])
270
    def preview_pdf_full(self, context, request: TracimRequest, hapic_data=None):  # nopep8
271
        """
272
        Obtain a full pdf preview (all page) of last revision of content.
273
        """
274
        app_config = request.registry.settings['CFG']
275
        api = ContentApi(
276
            show_archived=True,
277
            show_deleted=True,
278
            current_user=request.current_user,
279
            session=request.dbsession,
280
            config=app_config,
281
        )
282
        content = api.get_one(
283
            hapic_data.path.content_id,
284
            content_type=CONTENT_TYPES.Any_SLUG
285
        )
286
        pdf_preview_path = api.get_full_pdf_preview_path(content.revision_id)
287
        filename = "{label}.pdf".format(label=content.label)
288
        return HapicFile(
289
            file_path=pdf_preview_path,
290
            filename=filename,
291
            as_attachment=hapic_data.query.force_download
292
        )
293
294 View Code Duplication
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
295
    @require_workspace_role(UserRoleInWorkspace.READER)
296
    @require_content_types([FILE_TYPE])
297
    @hapic.handle_exception(TracimUnavailablePreviewType, HTTPStatus.BAD_REQUEST)
298
    @hapic.handle_exception(UnavailablePreview, HTTPStatus.BAD_REQUEST)
299
    @hapic.input_path(WorkspaceAndContentRevisionIdPathSchema())
300
    @hapic.input_query(FileQuerySchema())
301
    @hapic.output_file([])
302
    def preview_pdf_full_revision(self, context, request: TracimRequest, hapic_data=None):  # nopep8
303
        """
304
        Obtain full pdf preview of a specific revision of content.
305
        """
306
        app_config = request.registry.settings['CFG']
307
        api = ContentApi(
308
            show_archived=True,
309
            show_deleted=True,
310
            current_user=request.current_user,
311
            session=request.dbsession,
312
            config=app_config,
313
        )
314
        content = api.get_one(
315
            hapic_data.path.content_id,
316
            content_type=CONTENT_TYPES.Any_SLUG
317
        )
318
        revision = api.get_one_revision(
319
            revision_id=hapic_data.path.revision_id,
320
            content=content
321
        )
322
        pdf_preview_path = api.get_full_pdf_preview_path(
323
            revision.revision_id,
324
        )
325
        filename = "{label}.pdf".format(label=revision.label)
326
        return HapicFile(
327
            file_path=pdf_preview_path,
328
            filename=filename,
329
            as_attachment=hapic_data.query.force_download
330
        )
331
332
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
333
    @require_workspace_role(UserRoleInWorkspace.READER)
334
    @require_content_types([FILE_TYPE])
335
    @hapic.handle_exception(TracimUnavailablePreviewType, HTTPStatus.BAD_REQUEST)
336
    @hapic.handle_exception(UnavailablePreview, HTTPStatus.BAD_REQUEST)
337
    @hapic.input_path(WorkspaceAndContentRevisionIdPathSchema())
338
    @hapic.input_query(PageQuerySchema())
339
    @hapic.output_file([])
340
    def preview_pdf_revision(self, context, request: TracimRequest, hapic_data=None):  # nopep8
341
        """
342
        Obtain a specific page pdf preview of a specific revision of content.
343
        """
344
        app_config = request.registry.settings['CFG']
345
        api = ContentApi(
346
            show_archived=True,
347
            show_deleted=True,
348
            current_user=request.current_user,
349
            session=request.dbsession,
350
            config=app_config,
351
        )
352
        content = api.get_one(
353
            hapic_data.path.content_id,
354
            content_type=CONTENT_TYPES.Any_SLUG
355
        )
356
        revision = api.get_one_revision(
357
            revision_id=hapic_data.path.revision_id,
358
            content=content
359
        )
360
        pdf_preview_path = api.get_pdf_preview_path(
361
            revision.content_id,
362
            revision.revision_id,
363
            page_number=hapic_data.query.page
364
        )
365
        filename = "{label}_page_{page_number}.pdf".format(
366
            label=content.label,
367
            page_number=hapic_data.query.page
368
        )
369
        return HapicFile(
370
            file_path=pdf_preview_path,
371
            filename=filename,
372
            as_attachment=hapic_data.query.force_download
373
        )
374
375
    # jpg
376
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
377
    @require_workspace_role(UserRoleInWorkspace.READER)
378
    @require_content_types([FILE_TYPE])
379
    @hapic.handle_exception(UnavailablePreview, HTTPStatus.BAD_REQUEST)
380
    @hapic.handle_exception(PageOfPreviewNotFound, HTTPStatus.BAD_REQUEST)
381
    @hapic.input_path(WorkspaceAndContentIdPathSchema())
382
    @hapic.input_query(PageQuerySchema())
383
    @hapic.output_file([])
384
    def preview_jpg(self, context, request: TracimRequest, hapic_data=None):
385
        """
386
        Obtain normally sied jpg preview of last revision of content.
387
        """
388
        app_config = request.registry.settings['CFG']
389
        api = ContentApi(
390
            show_archived=True,
391
            show_deleted=True,
392
            current_user=request.current_user,
393
            session=request.dbsession,
394
            config=app_config,
395
        )
396
        content = api.get_one(
397
            hapic_data.path.content_id,
398
            content_type=CONTENT_TYPES.Any_SLUG
399
        )
400
        allowed_dim = api.get_jpg_preview_allowed_dim()
401
        jpg_preview_path = api.get_jpg_preview_path(
402
            content_id=content.content_id,
403
            revision_id=content.revision_id,
404
            page_number=hapic_data.query.page,
405
            width=allowed_dim.dimensions[0].width,
406
            height=allowed_dim.dimensions[0].height,
407
        )
408
        filename = "{label}_page_{page_number}.jpg".format(
409
            label=content.label,
410
            page_number=hapic_data.query.page
411
        )
412
        return HapicFile(
413
            file_path=jpg_preview_path,
414
            filename=filename,
415
            as_attachment=hapic_data.query.force_download
416
        )
417
418 View Code Duplication
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
419
    @require_workspace_role(UserRoleInWorkspace.READER)
420
    @require_content_types([FILE_TYPE])
421
    @hapic.handle_exception(UnavailablePreview, HTTPStatus.BAD_REQUEST)
422
    @hapic.handle_exception(PageOfPreviewNotFound, HTTPStatus.BAD_REQUEST)
423
    @hapic.handle_exception(PreviewDimNotAllowed, HTTPStatus.BAD_REQUEST)
424
    @hapic.input_query(PageQuerySchema())
425
    @hapic.input_path(ContentPreviewSizedPathSchema())
426
    @hapic.output_file([])
427
    def sized_preview_jpg(self, context, request: TracimRequest, hapic_data=None):  # nopep8
428
        """
429
        Obtain resized jpg preview of last revision of content.
430
        """
431
        app_config = request.registry.settings['CFG']
432
        api = ContentApi(
433
            show_archived=True,
434
            show_deleted=True,
435
            current_user=request.current_user,
436
            session=request.dbsession,
437
            config=app_config,
438
        )
439
        content = api.get_one(
440
            hapic_data.path.content_id,
441
            content_type=CONTENT_TYPES.Any_SLUG
442
        )
443
        jpg_preview_path = api.get_jpg_preview_path(
444
            content_id=content.content_id,
445
            revision_id=content.revision_id,
446
            page_number=hapic_data.query.page,
447
            height=hapic_data.path.height,
448
            width=hapic_data.path.width,
449
        )
450
        filename = "{label}_page_{page_number}_{width}x{height}.jpg".format(
451
            label=content.label,
452
            page_number=hapic_data.query.page,
453
            width=hapic_data.path.width,
454
            height=hapic_data.path.height
455
        )
456
        return HapicFile(
457
            file_path=jpg_preview_path,
458
            filename=filename,
459
            as_attachment=hapic_data.query.force_download
460
        )
461
462 View Code Duplication
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
463
    @require_workspace_role(UserRoleInWorkspace.READER)
464
    @require_content_types([FILE_TYPE])
465
    @hapic.handle_exception(UnavailablePreview, HTTPStatus.BAD_REQUEST)
466
    @hapic.handle_exception(PageOfPreviewNotFound, HTTPStatus.BAD_REQUEST)
467
    @hapic.handle_exception(PreviewDimNotAllowed, HTTPStatus.BAD_REQUEST)
468
    @hapic.input_path(RevisionPreviewSizedPathSchema())
469
    @hapic.input_query(PageQuerySchema())
470
    @hapic.output_file([])
471
    def sized_preview_jpg_revision(self, context, request: TracimRequest, hapic_data=None):  # nopep8
472
        """
473
        Obtain resized jpg preview of a specific revision of content.
474
        """
475
        app_config = request.registry.settings['CFG']
476
        api = ContentApi(
477
            show_archived=True,
478
            show_deleted=True,
479
            current_user=request.current_user,
480
            session=request.dbsession,
481
            config=app_config,
482
        )
483
        content = api.get_one(
484
            hapic_data.path.content_id,
485
            content_type=CONTENT_TYPES.Any_SLUG
486
        )
487
        revision = api.get_one_revision(
488
            revision_id=hapic_data.path.revision_id,
489
            content=content
490
        )
491
        jpg_preview_path = api.get_jpg_preview_path(
492
            content_id=content.content_id,
493
            revision_id=revision.revision_id,
494
            page_number=hapic_data.query.page,
495
            height=hapic_data.path.height,
496
            width=hapic_data.path.width,
497
        )
498
        filename = "{label}_page_{page_number}_{width}x{height}.jpg".format(
499
            label=revision.label,
500
            page_number=hapic_data.query.page,
501
            width=hapic_data.path.width,
502
            height=hapic_data.path.height
503
        )
504
        return HapicFile(
505
            file_path=jpg_preview_path,
506
            filename=filename,
507
            as_attachment=hapic_data.query.force_download
508
        )
509
510
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
511
    @require_workspace_role(UserRoleInWorkspace.READER)
512
    @require_content_types([FILE_TYPE])
513
    @hapic.input_path(WorkspaceAndContentIdPathSchema())
514
    @hapic.output_body(AllowedJpgPreviewDimSchema())
515
    def allowed_dim_preview_jpg(self, context, request: TracimRequest, hapic_data=None):  # nopep8
516
        """
517
        Get allowed dimensions of jpg preview. If restricted is true,
518
        only those dimensions are strictly accepted.
519
        """
520
        app_config = request.registry.settings['CFG']
521
        api = ContentApi(
522
            show_archived=True,
523
            show_deleted=True,
524
            current_user=request.current_user,
525
            session=request.dbsession,
526
            config=app_config,
527
        )
528
        return api.get_jpg_preview_allowed_dim()
529
530
    # File infos
531
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
532
    @require_workspace_role(UserRoleInWorkspace.READER)
533
    @require_content_types([FILE_TYPE])
534
    @hapic.input_path(WorkspaceAndContentIdPathSchema())
535
    @hapic.output_body(FileContentSchema())
536
    def get_file_infos(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext:  # nopep8
537
        """
538
        Get thread content
539
        """
540
        app_config = request.registry.settings['CFG']
541
        api = ContentApi(
542
            show_archived=True,
543
            show_deleted=True,
544
            current_user=request.current_user,
545
            session=request.dbsession,
546
            config=app_config,
547
        )
548
        content = api.get_one(
549
            hapic_data.path.content_id,
550
            content_type=CONTENT_TYPES.Any_SLUG
551
        )
552
        return api.get_content_in_context(content)
553
554
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
555
    @hapic.handle_exception(EmptyLabelNotAllowed, HTTPStatus.BAD_REQUEST)
556
    @hapic.handle_exception(ContentLabelAlreadyUsedHere, HTTPStatus.BAD_REQUEST)
557
    @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
558
    @require_content_types([FILE_TYPE])
559
    @hapic.input_path(WorkspaceAndContentIdPathSchema())
560
    @hapic.input_body(FileContentModifySchema())
561
    @hapic.output_body(FileContentSchema())
562
    def update_file_info(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext:  # nopep8
563
        """
564
        update thread
565
        """
566
        app_config = request.registry.settings['CFG']
567
        api = ContentApi(
568
            show_archived=True,
569
            show_deleted=True,
570
            current_user=request.current_user,
571
            session=request.dbsession,
572
            config=app_config,
573
        )
574
        content = api.get_one(
575
            hapic_data.path.content_id,
576
            content_type=CONTENT_TYPES.Any_SLUG
577
        )
578
        with new_revision(
579
                session=request.dbsession,
580
                tm=transaction.manager,
581
                content=content
582
        ):
583
            api.update_content(
584
                item=content,
585
                new_label=hapic_data.body.label,
586
                new_content=hapic_data.body.raw_content,
587
588
            )
589
            api.save(content)
590
        return api.get_content_in_context(content)
591
592
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
593
    @require_workspace_role(UserRoleInWorkspace.READER)
594
    @require_content_types([FILE_TYPE])
595
    @hapic.input_path(WorkspaceAndContentIdPathSchema())
596
    @hapic.output_body(FileRevisionSchema(many=True))
597
    def get_file_revisions(
598
            self,
599
            context,
600
            request: TracimRequest,
601
            hapic_data=None
602
    ) -> typing.List[RevisionInContext]:
603
        """
604
        get file revisions
605
        """
606
        app_config = request.registry.settings['CFG']
607
        api = ContentApi(
608
            show_archived=True,
609
            show_deleted=True,
610
            current_user=request.current_user,
611
            session=request.dbsession,
612
            config=app_config,
613
        )
614
        content = api.get_one(
615
            hapic_data.path.content_id,
616
            content_type=CONTENT_TYPES.Any_SLUG
617
        )
618
        revisions = content.revisions
619
        return [
620
            api.get_revision_in_context(revision)
621
            for revision in revisions
622
        ]
623
624
    @hapic.with_api_doc(tags=[SWAGGER_TAG__FILE_ENDPOINTS])
625
    @hapic.handle_exception(EmptyLabelNotAllowed, HTTPStatus.BAD_REQUEST)
626
    @require_workspace_role(UserRoleInWorkspace.CONTRIBUTOR)
627
    @require_content_types([FILE_TYPE])
628
    @hapic.input_path(WorkspaceAndContentIdPathSchema())
629
    @hapic.input_body(SetContentStatusSchema())
630
    @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT)  # nopep8
631
    def set_file_status(self, context, request: TracimRequest, hapic_data=None) -> None:  # nopep8
632
        """
633
        set file status
634
        """
635
        app_config = request.registry.settings['CFG']
636
        api = ContentApi(
637
            show_archived=True,
638
            show_deleted=True,
639
            current_user=request.current_user,
640
            session=request.dbsession,
641
            config=app_config,
642
        )
643
        content = api.get_one(
644
            hapic_data.path.content_id,
645
            content_type=CONTENT_TYPES.Any_SLUG
646
        )
647
        with new_revision(
648
                session=request.dbsession,
649
                tm=transaction.manager,
650
                content=content
651
        ):
652
            api.set_status(
653
                content,
654
                hapic_data.body.status,
655
            )
656
            api.save(content)
657
        return
658
659
    def bind(self, configurator: Configurator) -> None:
660
        """
661
        Add route to configurator.
662
        """
663
664
        # file info #
665
        # Get file info
666
        configurator.add_route(
667
            'file_info',
668
            '/workspaces/{workspace_id}/files/{content_id}',
669
            request_method='GET'
670
        )
671
        configurator.add_view(self.get_file_infos, route_name='file_info')  # nopep8
672
        # update file
673
        configurator.add_route(
674
            'update_file_info',
675
            '/workspaces/{workspace_id}/files/{content_id}',
676
            request_method='PUT'
677
        )  # nopep8
678
        configurator.add_view(self.update_file_info, route_name='update_file_info')  # nopep8
679
680
        # raw file #
681
        # create file
682
        configurator.add_route(
683
            'create_file',
684
            '/workspaces/{workspace_id}/files',  # nopep8
685
            request_method='POST'
686
        )
687
        configurator.add_view(self.create_file, route_name='create_file')  # nopep8
688
        # upload raw file
689
        configurator.add_route(
690
            'upload_file',
691
            '/workspaces/{workspace_id}/files/{content_id}/raw',  # nopep8
692
            request_method='PUT'
693
        )
694
        configurator.add_view(self.upload_file, route_name='upload_file')  # nopep8
695
        # download raw file
696
        configurator.add_route(
697
            'download_file',
698
            '/workspaces/{workspace_id}/files/{content_id}/raw',  # nopep8
699
            request_method='GET'
700
        )
701
        configurator.add_view(self.download_file, route_name='download_file')  # nopep8
702
        # download raw file of revision
703
        configurator.add_route(
704
            'download_revision',
705
            '/workspaces/{workspace_id}/files/{content_id}/revisions/{revision_id}/raw',  # nopep8
706
            request_method='GET'
707
        )
708
        configurator.add_view(self.download_revisions_file, route_name='download_revision')  # nopep8
709
710
        # previews #
711
        # get preview pdf full
712
        configurator.add_route(
713
            'preview_pdf_full',
714
            '/workspaces/{workspace_id}/files/{content_id}/preview/pdf/full',  # nopep8
715
            request_method='GET'
716
        )
717
        configurator.add_view(self.preview_pdf_full, route_name='preview_pdf_full')  # nopep8
718
        # get preview pdf
719
        configurator.add_route(
720
            'preview_pdf',
721
            '/workspaces/{workspace_id}/files/{content_id}/preview/pdf',  # nopep8
722
            request_method='GET'
723
        )
724
        configurator.add_view(self.preview_pdf, route_name='preview_pdf')  # nopep8
725
        # get preview jpg allowed dims
726
        configurator.add_route(
727
            'allowed_dim_preview_jpg',
728
            '/workspaces/{workspace_id}/files/{content_id}/preview/jpg/allowed_dims',  # nopep8
729
            request_method='GET'
730
        )
731
        configurator.add_view(self.allowed_dim_preview_jpg, route_name='allowed_dim_preview_jpg')  # nopep8
732
        # get preview jpg
733
        configurator.add_route(
734
            'preview_jpg',
735
            '/workspaces/{workspace_id}/files/{content_id}/preview/jpg',  # nopep8
736
            request_method='GET'
737
        )
738
        configurator.add_view(self.preview_jpg, route_name='preview_jpg')  # nopep8
739
        # get preview jpg with size
740
        configurator.add_route(
741
            'sized_preview_jpg',
742
            '/workspaces/{workspace_id}/files/{content_id}/preview/jpg/{width}x{height}',  # nopep8
743
            request_method='GET'
744
        )
745
        configurator.add_view(self.sized_preview_jpg, route_name='sized_preview_jpg')  # nopep8
746
        # get jpg preview for revision
747
        configurator.add_route(
748
            'sized_preview_jpg_revision',
749
            '/workspaces/{workspace_id}/files/{content_id}/revisions/{revision_id}/preview/jpg/{width}x{height}',  # nopep8
750
            request_method='GET'
751
        )
752
        configurator.add_view(self.sized_preview_jpg_revision, route_name='sized_preview_jpg_revision')  # nopep8
753
        # get full pdf preview for revision
754
        configurator.add_route(
755
            'preview_pdf_full_revision',
756
            '/workspaces/{workspace_id}/files/{content_id}/revisions/{revision_id}/preview/pdf/full',  # nopep8
757
            request_method='GET'
758
        )
759
        configurator.add_view(self.preview_pdf_full_revision, route_name='preview_pdf_full_revision')  # nopep8
760
        # get pdf preview for revision
761
        configurator.add_route(
762
            'preview_pdf_revision',
763
            '/workspaces/{workspace_id}/files/{content_id}/revisions/{revision_id}/preview/pdf',  # nopep8
764
            request_method='GET'
765
        )
766
        configurator.add_view(self.preview_pdf_revision, route_name='preview_pdf_revision')  # nopep8
767
        # others #
768
        # get file revisions
769
        configurator.add_route(
770
            'file_revisions',
771
            '/workspaces/{workspace_id}/files/{content_id}/revisions',  # nopep8
772
            request_method='GET'
773
        )
774
        configurator.add_view(self.get_file_revisions, route_name='file_revisions')  # nopep8
775
776
        # get file status
777
        configurator.add_route(
778
            'set_file_status',
779
            '/workspaces/{workspace_id}/files/{content_id}/status',  # nopep8
780
            request_method='PUT'
781
        )
782
        configurator.add_view(self.set_file_status, route_name='set_file_status')  # nopep8
783