Passed
Pull Request — develop (#36)
by inkhey
02:15
created

UserCreation.__init__()   A

Complexity

Conditions 1

Size

Total Lines 19
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 19
rs 9.6
c 0
b 0
f 0
cc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
# coding=utf-8
2
import typing
3
from datetime import datetime
4
from enum import Enum
5
6
from slugify import slugify
7
from sqlalchemy.orm import Session
8
from tracim_backend.config import CFG
9
from tracim_backend.config import PreviewDim
10
from tracim_backend.extensions import app_list
11
from tracim_backend.lib.core.application import ApplicationApi
12
from tracim_backend.lib.utils.utils import get_root_frontend_url
13
from tracim_backend.lib.utils.utils import password_generator
14
from tracim_backend.lib.utils.utils import CONTENT_FRONTEND_URL_SCHEMA
15
from tracim_backend.lib.utils.utils import WORKSPACE_FRONTEND_URL_SCHEMA
16
from tracim_backend.models import User
17
from tracim_backend.models.auth import Profile
18
from tracim_backend.models.auth import Group
19
from tracim_backend.models.data import Content
20
from tracim_backend.models.data import ContentRevisionRO
21
from tracim_backend.models.data import Workspace
22
from tracim_backend.models.data import UserRoleInWorkspace
23
from tracim_backend.models.roles import WorkspaceRoles
24
from tracim_backend.app_models.workspace_menu_entries import WorkspaceMenuEntry
25
from tracim_backend.app_models.contents import CONTENT_TYPES
26
27
28
class PreviewAllowedDim(object):
29
30
    def __init__(
31
            self,
32
            restricted:bool,
33
            dimensions: typing.List[PreviewDim]
34
    ) -> None:
35
        self.restricted = restricted
36
        self.dimensions = dimensions
37
38
39
class MoveParams(object):
40
    """
41
    Json body params for move action model
42
    """
43
    def __init__(self, new_parent_id: str, new_workspace_id: str = None) -> None:  # nopep8
44
        self.new_parent_id = new_parent_id
45
        self.new_workspace_id = new_workspace_id
46
47
48
class LoginCredentials(object):
49
    """
50
    Login credentials model for login model
51
    """
52
53
    def __init__(self, email: str, password: str) -> None:
54
        self.email = email
55
        self.password = password
56
57
58
class SetEmail(object):
59
    """
60
    Just an email
61
    """
62
    def __init__(self, loggedin_user_password: str, email: str) -> None:
63
        self.loggedin_user_password = loggedin_user_password
64
        self.email = email
65
66
67
class SetPassword(object):
68
    """
69
    Just an password
70
    """
71
    def __init__(self,
72
        loggedin_user_password: str,
73
        new_password: str,
74
        new_password2: str
75
    ) -> None:
76
        self.loggedin_user_password = loggedin_user_password
77
        self.new_password = new_password
78
        self.new_password2 = new_password2
79
80
81
class UserInfos(object):
82
    """
83
    Just some user infos
84
    """
85
    def __init__(self, timezone: str, public_name: str, lang: str) -> None:
86
        self.timezone = timezone
87
        self.public_name = public_name
88
        self.lang = lang
89
90
91
class UserProfile(object):
92
    """
93
    Just some user infos
94
    """
95
    def __init__(self, profile: str) -> None:
96
        self.profile = profile
97
98
99
class UserCreation(object):
100
    """
101
    Just some user infos
102
    """
103
    def __init__(
104
            self,
105
            email: str,
106
            password: str = None,
107
            public_name: str = None,
108
            timezone: str = None,
109
            profile: str = None,
110
            lang: str = None,
111
            email_notification: bool = True,
112
    ) -> None:
113
        self.email = email
114
        # INFO - G.M - 2018-08-16 - cleartext password, default value
115
        # is auto-generated.
116
        self.password = password or password_generator()
117
        self.public_name = public_name or None
118
        self.timezone = timezone or ''
119
        self.lang = lang or None
120
        self.profile = profile or Group.TIM_USER_GROUPNAME
121
        self.email_notification = email_notification
122
123
124
class WorkspaceAndContentPath(object):
125
    """
126
    Paths params with workspace id and content_id model
127
    """
128
    def __init__(self, workspace_id: int, content_id: int) -> None:
129
        self.content_id = content_id
130
        self.workspace_id = workspace_id
131
132
133
class WorkspaceAndContentRevisionPath(object):
134
    """
135
    Paths params with workspace id and content_id model
136
    """
137
    def __init__(self, workspace_id: int, content_id: int, revision_id) -> None:
138
        self.content_id = content_id
139
        self.revision_id = revision_id
140
        self.workspace_id = workspace_id
141
142
143
class ContentPreviewSizedPath(object):
144
    """
145
    Paths params with workspace id and content_id, width, heigth
146
    """
147
    def __init__(self, workspace_id: int, content_id: int, width: int, height: int) -> None:  # nopep8
148
        self.content_id = content_id
149
        self.workspace_id = workspace_id
150
        self.width = width
151
        self.height = height
152
153
154
class RevisionPreviewSizedPath(object):
155
    """
156
    Paths params with workspace id and content_id, revision_id width, heigth
157
    """
158
    def __init__(self, workspace_id: int, content_id: int, revision_id: int, width: int, height: int) -> None:  # nopep8
159
        self.content_id = content_id
160
        self.revision_id = revision_id
161
        self.workspace_id = workspace_id
162
        self.width = width
163
        self.height = height
164
165
166
class WorkspaceAndUserPath(object):
167
    """
168
    Paths params with workspace id and user_id
169
    """
170
    def __init__(self, workspace_id: int, user_id: int):
171
        self.workspace_id = workspace_id
172
        self.user_id = user_id
173
174
175
class UserWorkspaceAndContentPath(object):
176
    """
177
    Paths params with user_id, workspace id and content_id model
178
    """
179
    def __init__(self, user_id: int, workspace_id: int, content_id: int) -> None:  # nopep8
180
        self.content_id = content_id
181
        self.workspace_id = workspace_id
182
        self.user_id = user_id
183
184
185
class CommentPath(object):
186
    """
187
    Paths params with workspace id and content_id and comment_id model
188
    """
189
    def __init__(
190
        self,
191
        workspace_id: int,
192
        content_id: int,
193
        comment_id: int
194
    ) -> None:
195
        self.content_id = content_id
196
        self.workspace_id = workspace_id
197
        self.comment_id = comment_id
198
199
200
class AutocompleteQuery(object):
201
    """
202
    Autocomplete query model
203
    """
204
    def __init__(self, acp: str):
205
        self.acp = acp
206
207
208
class PageQuery(object):
209
    """
210
    Page query model
211
    """
212
    def __init__(
213
            self,
214
            page: int = 0
215
    ):
216
        self.page = page
217
218
219
class ContentFilter(object):
220
    """
221
    Content filter model
222
    """
223
    def __init__(
224
            self,
225
            workspace_id: int = None,
226
            parent_id: int = None,
227
            show_archived: int = 0,
228
            show_deleted: int = 0,
229
            show_active: int = 1,
230
            content_type: str = None,
231
            offset: int = None,
232
            limit: int = None,
233
    ) -> None:
234
        self.parent_id = parent_id
235
        self.workspace_id = workspace_id
236
        self.show_archived = bool(show_archived)
237
        self.show_deleted = bool(show_deleted)
238
        self.show_active = bool(show_active)
239
        self.limit = limit
240
        self.offset = offset
241
        self.content_type = content_type
242
243
244
class ActiveContentFilter(object):
245
    def __init__(
246
            self,
247
            limit: int = None,
248
            before_content_id: datetime = None,
249
    ):
250
        self.limit = limit
251
        self.before_content_id = before_content_id
252
253
254
class ContentIdsQuery(object):
255
    def __init__(
256
            self,
257
            contents_ids: typing.List[int] = None,
258
    ):
259
        self.contents_ids = contents_ids
260
261
262
class RoleUpdate(object):
263
    """
264
    Update role
265
    """
266
    def __init__(
267
        self,
268
        role: str,
269
    ):
270
        self.role = role
271
272
273
class WorkspaceMemberInvitation(object):
274
    """
275
    Workspace Member Invitation
276
    """
277
    def __init__(
278
        self,
279
        user_id: int,
280
        user_email_or_public_name: str,
281
        role: str,
282
    ):
283
        self.role = role
284
        self.user_email_or_public_name = user_email_or_public_name
285
        self.user_id = user_id
286
287
288
class WorkspaceUpdate(object):
289
    """
290
    Update workspace
291
    """
292
    def __init__(
293
        self,
294
        label: str,
295
        description: str,
296
    ):
297
        self.label = label
298
        self.description = description
299
300
301
class ContentCreation(object):
302
    """
303
    Content creation model
304
    """
305
    def __init__(
306
        self,
307
        label: str,
308
        content_type: str,
309
        parent_id: typing.Optional[int] = None,
310
    ) -> None:
311
        self.label = label
312
        self.content_type = content_type
313
        self.parent_id = parent_id or None
314
315
316
class CommentCreation(object):
317
    """
318
    Comment creation model
319
    """
320
    def __init__(
321
        self,
322
        raw_content: str,
323
    ) -> None:
324
        self.raw_content = raw_content
325
326
327
class SetContentStatus(object):
328
    """
329
    Set content status
330
    """
331
    def __init__(
332
        self,
333
        status: str,
334
    ) -> None:
335
        self.status = status
336
337
338
class TextBasedContentUpdate(object):
339
    """
340
    TextBasedContent update model
341
    """
342
    def __init__(
343
        self,
344
        label: str,
345
        raw_content: str,
346
    ) -> None:
347
        self.label = label
348
        self.raw_content = raw_content
349
350
351
class FolderContentUpdate(object):
352
    """
353
    Folder Content update model
354
    """
355
    def __init__(
356
        self,
357
        label: str,
358
        raw_content: str,
359
        sub_content_types: typing.List[str],
360
    ) -> None:
361
        self.label = label
362
        self.raw_content = raw_content
363
        self.sub_content_types = sub_content_types
364
365
366
class TypeUser(Enum):
367
    """Params used to find user"""
368
    USER_ID = 'found_id'
369
    EMAIL = 'found_email'
370
    PUBLIC_NAME = 'found_public_name'
371
372
373
class UserInContext(object):
374
    """
375
    Interface to get User data and User data related to context.
376
    """
377
378
    def __init__(self, user: User, dbsession: Session, config: CFG):
379
        self.user = user
380
        self.dbsession = dbsession
381
        self.config = config
382
383
    # Default
384
385
    @property
386
    def email(self) -> str:
387
        return self.user.email
388
389
    @property
390
    def user_id(self) -> int:
391
        return self.user.user_id
392
393
    @property
394
    def public_name(self) -> str:
395
        return self.display_name
396
397
    @property
398
    def display_name(self) -> str:
399
        return self.user.display_name
400
401
    @property
402
    def created(self) -> datetime:
403
        return self.user.created
404
405
    @property
406
    def is_active(self) -> bool:
407
        return self.user.is_active
408
409
    @property
410
    def timezone(self) -> str:
411
        return self.user.timezone
412
413
    @property
414
    def lang(self) -> str:
415
        return self.user.lang
416
417
    @property
418
    def profile(self) -> Profile:
419
        return self.user.profile.name
420
421
    @property
422
    def is_deleted(self) -> bool:
423
        return self.user.is_deleted
424
425
    # Context related
426
427
    @property
428
    def calendar_url(self) -> typing.Optional[str]:
429
        # TODO - G-M - 20-04-2018 - [Calendar] Replace calendar code to get
430
        # url calendar url.
431
        #
432
        # from tracim.lib.calendar import CalendarManager
433
        # calendar_manager = CalendarManager(None)
434
        # return calendar_manager.get_workspace_calendar_url(self.workspace_id)
435
        return None
436
437
    @property
438
    def avatar_url(self) -> typing.Optional[str]:
439
        # TODO - G-M - 20-04-2018 - [Avatar] Add user avatar feature
440
        return None
441
442
443
class WorkspaceInContext(object):
444
    """
445
    Interface to get Workspace data and Workspace data related to context.
446
    """
447
448
    def __init__(self, workspace: Workspace, dbsession: Session, config: CFG):
449
        self.workspace = workspace
450
        self.dbsession = dbsession
451
        self.config = config
452
453
    @property
454
    def workspace_id(self) -> int:
455
        """
456
        numeric id of the workspace.
457
        """
458
        return self.workspace.workspace_id
459
460
    @property
461
    def id(self) -> int:
462
        """
463
        alias of workspace_id
464
        """
465
        return self.workspace_id
466
467
    @property
468
    def label(self) -> str:
469
        """
470
        get workspace label
471
        """
472
        return self.workspace.label
473
474
    @property
475
    def description(self) -> str:
476
        """
477
        get workspace description
478
        """
479
        return self.workspace.description
480
481
    @property
482
    def slug(self) -> str:
483
        """
484
        get workspace slug
485
        """
486
        return slugify(self.workspace.label)
487
488
    @property
489
    def is_deleted(self) -> bool:
490
        """
491
        Is the workspace deleted ?
492
        """
493
        return self.workspace.is_deleted
494
495
    @property
496
    def sidebar_entries(self) -> typing.List[WorkspaceMenuEntry]:
497
        """
498
        get sidebar entries, those depends on activated apps.
499
        """
500
        # TODO - G.M - 22-05-2018 - Rework on this in
501
        # order to not use hardcoded list
502
        # list should be able to change (depending on activated/disabled
503
        # apps)
504
        app_api = ApplicationApi(
505
            app_list
506
        )
507
        return app_api.get_default_workspace_menu_entry(self.workspace)
508
509
    @property
510
    def frontend_url(self):
511
        root_frontend_url = get_root_frontend_url(self.config)
512
        workspace_frontend_url = WORKSPACE_FRONTEND_URL_SCHEMA.format(
513
            workspace_id=self.workspace_id,
514
        )
515
        return root_frontend_url + workspace_frontend_url
516
517
518
class UserRoleWorkspaceInContext(object):
519
    """
520
    Interface to get UserRoleInWorkspace data and related content
521
522
    """
523
    def __init__(
524
            self,
525
            user_role: UserRoleInWorkspace,
526
            dbsession: Session,
527
            config: CFG,
528
            # Extended params
529
            newly_created: bool = None,
530
            email_sent: bool = None
531
    )-> None:
532
        self.user_role = user_role
533
        self.dbsession = dbsession
534
        self.config = config
535
        # Extended params
536
        self.newly_created = newly_created
537
        self.email_sent = email_sent
538
539
    @property
540
    def user_id(self) -> int:
541
        """
542
        User who has the role has this id
543
        :return: user id as integer
544
        """
545
        return self.user_role.user_id
546
547
    @property
548
    def workspace_id(self) -> int:
549
        """
550
        This role apply only on the workspace with this workspace_id
551
        :return: workspace id as integer
552
        """
553
        return self.user_role.workspace_id
554
555
    # TODO - G.M - 23-05-2018 - Check the API spec for this this !
556
557
    @property
558
    def role_id(self) -> int:
559
        """
560
        role as int id, each value refer to a different role.
561
        """
562
        return self.user_role.role
563
564
    @property
565
    def role(self) -> str:
566
        return self.role_slug
567
568
    @property
569
    def role_slug(self) -> str:
570
        """
571
        simple name of the role of the user.
572
        can be anything from UserRoleInWorkspace SLUG, like
573
        'not_applicable', 'reader',
574
        'contributor', 'content-manager', 'workspace-manager'
575
        :return: user workspace role as slug.
576
        """
577
        return WorkspaceRoles.get_role_from_level(self.user_role.role).slug
578
579
    @property
580
    def is_active(self) -> bool:
581
        return self.user.is_active
582
583
    @property
584
    def do_notify(self) -> bool:
585
        return self.user_role.do_notify
586
587
    @property
588
    def user(self) -> UserInContext:
589
        """
590
        User who has this role, with context data
591
        :return: UserInContext object
592
        """
593
        return UserInContext(
594
            self.user_role.user,
595
            self.dbsession,
596
            self.config
597
        )
598
599
    @property
600
    def workspace(self) -> WorkspaceInContext:
601
        """
602
        Workspace related to this role, with his context data
603
        :return: WorkspaceInContext object
604
        """
605
        return WorkspaceInContext(
606
            self.user_role.workspace,
607
            self.dbsession,
608
            self.config
609
        )
610
611
612
class ContentInContext(object):
613
    """
614
    Interface to get Content data and Content data related to context.
615
    """
616
617
    def __init__(self, content: Content, dbsession: Session, config: CFG, user: User=None):  # nopep8
618
        self.content = content
619
        self.dbsession = dbsession
620
        self.config = config
621
        self._user = user
622
623
    # Default
624
    @property
625
    def content_id(self) -> int:
626
        return self.content.content_id
627
628
    @property
629
    def parent_id(self) -> int:
630
        """
631
        Return parent_id of the content
632
        """
633
        return self.content.parent_id
634
635
    @property
636
    def workspace_id(self) -> int:
637
        return self.content.workspace_id
638
639
    @property
640
    def label(self) -> str:
641
        return self.content.label
642
643
    @property
644
    def content_type(self) -> str:
645
        content_type = CONTENT_TYPES.get_one_by_slug(self.content.type)
646
        return content_type.slug
647
648
    @property
649
    def sub_content_types(self) -> typing.List[str]:
650
        return [_type.slug for _type in self.content.get_allowed_content_types()]  # nopep8
651
652
    @property
653
    def status(self) -> str:
654
        return self.content.status
655
656
    @property
657
    def is_archived(self):
658
        return self.content.is_archived
659
660
    @property
661
    def is_deleted(self):
662
        return self.content.is_deleted
663
664
    @property
665
    def raw_content(self):
666
        return self.content.description
667
668
    @property
669
    def author(self):
670
        return UserInContext(
671
            dbsession=self.dbsession,
672
            config=self.config,
673
            user=self.content.first_revision.owner
674
        )
675
676
    @property
677
    def current_revision_id(self):
678
        return self.content.revision_id
679
680
    @property
681
    def created(self):
682
        return self.content.created
683
684
    @property
685
    def modified(self):
686
        return self.updated
687
688
    @property
689
    def updated(self):
690
        return self.content.updated
691
692
    @property
693
    def last_modifier(self):
694
        return UserInContext(
695
            dbsession=self.dbsession,
696
            config=self.config,
697
            user=self.content.last_revision.owner
698
        )
699
700
    # Context-related
701
    @property
702
    def show_in_ui(self):
703
        # TODO - G.M - 31-05-2018 - Enable Show_in_ui params
704
        # if false, then do not show content in the treeview.
705
        # This may his maybe used for specific contents or for sub-contents.
706
        # Default is True.
707
        # In first version of the API, this field is always True
708
        return True
709
710
    @property
711
    def slug(self):
712
        return slugify(self.content.label)
713
714
    @property
715
    def read_by_user(self):
716
        assert self._user
717
        return not self.content.has_new_information_for(self._user)
718
719
    @property
720
    def frontend_url(self):
721
        root_frontend_url = get_root_frontend_url(self.config)
722
        content_frontend_url = CONTENT_FRONTEND_URL_SCHEMA.format(
723
            workspace_id=self.workspace_id,
724
            content_type=self.content_type,
725
            content_id=self.content_id,
726
        )
727
        return root_frontend_url + content_frontend_url
728
729
    # file specific
730
    @property
731
    def nb_pages(self):
732
        if self.content.depot_file:
733
            from tracim_backend.lib.core.content import ContentApi
734
            content_api = ContentApi(
735
                current_user=self._user,
736
                session=self.dbsession,
737
                config=self.config
738
            )
739
            return content_api.get_preview_nb_pages(self.content.revision_id)
740
        else:
741
            return None
742
743
    @property
744
    def mimetype(self):
745
        return self.content.file_mimetype
746
747
    @property
748
    def size(self):
749
        if self.content.depot_file:
750
            from tracim_backend.lib.core.content import ContentApi
751
            content_api = ContentApi(
752
                current_user=self._user,
753
                session=self.dbsession,
754
                config=self.config
755
            )
756
            return content_api.get_file_size(self.content.revision_id)
757
        else:
758
            return None
759
760
761
class RevisionInContext(object):
762
    """
763
    Interface to get Content data and Content data related to context.
764
    """
765
766
    def __init__(self, content_revision: ContentRevisionRO, dbsession: Session, config: CFG,  user: User=None):  # nopep8
767
        assert content_revision is not None
768
        self.revision = content_revision
769
        self.dbsession = dbsession
770
        self.config = config
771
        self._user = user
772
773
    # Default
774
    @property
775
    def content_id(self) -> int:
776
        return self.revision.content_id
777
778
    @property
779
    def parent_id(self) -> int:
780
        """
781
        Return parent_id of the content
782
        """
783
        return self.revision.parent_id
784
785
    @property
786
    def workspace_id(self) -> int:
787
        return self.revision.workspace_id
788
789
    @property
790
    def label(self) -> str:
791
        return self.revision.label
792
793
    @property
794
    def revision_type(self) -> str:
795
        return self.revision.revision_type
796
797
    @property
798
    def content_type(self) -> str:
799
        return CONTENT_TYPES.get_one_by_slug(self.revision.type).slug
800
801
    @property
802
    def sub_content_types(self) -> typing.List[str]:
803
        return [_type.slug for _type
804
                in self.revision.node.get_allowed_content_types()]
805
806
    @property
807
    def status(self) -> str:
808
        return self.revision.status
809
810
    @property
811
    def is_archived(self) -> bool:
812
        return self.revision.is_archived
813
814
    @property
815
    def is_deleted(self) -> bool:
816
        return self.revision.is_deleted
817
818
    @property
819
    def raw_content(self) -> str:
820
        return self.revision.description
821
822
    @property
823
    def author(self) -> UserInContext:
824
        return UserInContext(
825
            dbsession=self.dbsession,
826
            config=self.config,
827
            user=self.revision.owner
828
        )
829
830
    @property
831
    def revision_id(self) -> int:
832
        return self.revision.revision_id
833
834
    @property
835
    def created(self) -> datetime:
836
        return self.updated
837
838
    @property
839
    def modified(self) -> datetime:
840
        return self.updated
841
842
    @property
843
    def updated(self) -> datetime:
844
        return self.revision.updated
845
846
    @property
847
    def next_revision(self) -> typing.Optional[ContentRevisionRO]:
848
        """
849
        Get next revision (later revision)
850
        :return: next_revision
851
        """
852
        next_revision = None
853
        revisions = self.revision.node.revisions
854
        # INFO - G.M - 2018-06-177 - Get revisions more recent that
855
        # current one
856
        next_revisions = [
857
            revision for revision in revisions
858
            if revision.revision_id > self.revision.revision_id
859
        ]
860
        if next_revisions:
861
            # INFO - G.M - 2018-06-177 -sort revisions by date
862
            sorted_next_revisions = sorted(
863
                next_revisions,
864
                key=lambda revision: revision.updated
865
            )
866
            # INFO - G.M - 2018-06-177 - return only next revision
867
            return sorted_next_revisions[0]
868
        else:
869
            return None
870
871
    @property
872
    def comment_ids(self) -> typing.List[int]:
873
        """
874
        Get list of ids of all current revision related comments
875
        :return: list of comments ids
876
        """
877
        comments = self.revision.node.get_comments()
878
        # INFO - G.M - 2018-06-177 - Get comments more recent than revision.
879
        revision_comments = [
880
            comment for comment in comments
881
            if comment.created > self.revision.updated
882
        ]
883
        if self.next_revision:
884
            # INFO - G.M - 2018-06-177 - if there is a revision more recent
885
            # than current remove comments from theses rev (comments older
886
            # than next_revision.)
887
            revision_comments = [
888
                comment for comment in revision_comments
889
                if comment.created < self.next_revision.updated
890
            ]
891
        sorted_revision_comments = sorted(
892
            revision_comments,
893
            key=lambda revision: revision.created
894
        )
895
        comment_ids = []
896
        for comment in sorted_revision_comments:
897
            comment_ids.append(comment.content_id)
898
        return comment_ids
899
900
    # Context-related
901
    @property
902
    def show_in_ui(self) -> bool:
903
        # TODO - G.M - 31-05-2018 - Enable Show_in_ui params
904
        # if false, then do not show content in the treeview.
905
        # This may his maybe used for specific contents or for sub-contents.
906
        # Default is True.
907
        # In first version of the API, this field is always True
908
        return True
909
910
    @property
911
    def slug(self) -> str:
912
        return slugify(self.revision.label)
913
914
    # file specific
915
    @property
916
    def nb_pages(self):
917
        if self.revision.depot_file:
918
            from tracim_backend.lib.core.content import ContentApi
919
            content_api = ContentApi(
920
                current_user=self._user,
921
                session=self.dbsession,
922
                config=self.config
923
            )
924
            return content_api.get_preview_nb_pages(self.revision.revision_id)
925
        else:
926
            return None
927
928
    @property
929
    def mimetype(self):
930
        return self.revision.file_mimetype
931
932
    @property
933
    def size(self):
934
        if self.revision.depot_file:
935
            from tracim_backend.lib.core.content import ContentApi
936
            content_api = ContentApi(
937
                current_user=self._user,
938
                session=self.dbsession,
939
                config=self.config
940
            )
941
            return content_api.get_file_size(self.revision.revision_id)
942
        else:
943
            return None
944