Passed
Pull Request — develop (#110)
by inkhey
01:45
created

contents.ContentStatusList.__init__()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nop 2
1
# -*- coding: utf-8 -*-
2
import typing
3
from enum import Enum
4
5
from tracim_backend.exceptions import ContentStatusNotExist
6
from tracim_backend.exceptions import ContentTypeNotExist
7
from tracim_backend.extensions import app_list
8
####
9
# Content Status
10
from tracim_backend.lib.core.application import ApplicationApi
11
from tracim_backend.lib.utils.markup_conversion import HTML_MARKUP
12
from tracim_backend.lib.utils.markup_conversion import TEXT_MARKUP
13
14
if typing.TYPE_CHECKING:
15
    from tracim_backend.app_models.applications import Application
16
17
18
class GlobalStatus(Enum):
19
    OPEN = 'open'
20
    CLOSED = 'closed'
21
22
class ContentStatus(object):
23
    """
24
    ContentStatus object class
25
    """
26
    def __init__(
27
            self,
28
            slug: str,
29
            global_status: str,
30
            label: str,
31
            fa_icon: str,
32
            hexcolor: str,
33
    ):
34
        self.slug = slug
35
        self.global_status = global_status
36
        self.label = label
37
        self.fa_icon = fa_icon
38
        self.hexcolor = hexcolor
39
40
    def is_editable(self):
41
        return self.global_status == GlobalStatus.OPEN.value
42
43
44
open_status = ContentStatus(
45
    slug='open',
46
    global_status=GlobalStatus.OPEN.value,
47
    label='Open',
48
    fa_icon='square-o',
49
    hexcolor='#3f52e3',
50
)
51
52
closed_validated_status = ContentStatus(
53
    slug='closed-validated',
54
    global_status=GlobalStatus.CLOSED.value,
55
    label='Validated',
56
    fa_icon='check-square-o',
57
    hexcolor='#008000',
58
)
59
60
closed_unvalidated_status = ContentStatus(
61
    slug='closed-unvalidated',
62
    global_status=GlobalStatus.CLOSED.value,
63
    label='Cancelled',
64
    fa_icon='close',
65
    hexcolor='#f63434',
66
)
67
68
closed_deprecated_status = ContentStatus(
69
    slug='closed-deprecated',
70
    global_status=GlobalStatus.CLOSED.value,
71
    label='Deprecated',
72
    fa_icon='warning',
73
    hexcolor='#ababab',
74
)
75
76
77
class ContentStatusList(object):
78
79
    OPEN = open_status
80
81
    def __init__(self, extend_content_status: typing.List[ContentStatus]):
82
        self._content_status = [self.OPEN]
83
        self._content_status.extend(extend_content_status)
84
85
    def get_one_by_slug(self, slug: str) -> ContentStatus:
86
        for item in self._content_status:
87
            if item.slug == slug:
88
                return item
89
        raise ContentStatusNotExist()
90
91
    def get_all_slugs_values(self) -> typing.List[str]:
92
        """ Get alls slugs"""
93
        return [item.slug for item in self._content_status]
94
95
    def get_all(self) -> typing.List[ContentStatus]:
96
        """ Get all status"""
97
        return [item for item in self._content_status]
98
99
    def get_default_status(self) -> ContentStatus:
100
        return self.OPEN
101
102
103
content_status_list = ContentStatusList(
104
    [
105
        closed_validated_status,
106
        closed_unvalidated_status,
107
        closed_deprecated_status,
108
    ]
109
)
110
####
111
# ContentType
112
113
114
class ContentType(object):
115
    """
116
    Future ContentType object class
117
    """
118
    def __init__(
119
            self,
120
            slug: str,
121
            fa_icon: str,
122
            hexcolor: str,
123
            label: str,
124
            creation_label: str,
125
            available_statuses: typing.List[ContentStatus],
126
            slug_alias: typing.List[str] = None,
127
            allow_sub_content: bool = False,
128
            file_extension: typing.Optional[str] = None,
129
            raw_content_markup: str = HTML_MARKUP
130
    ):
131
        self.slug = slug
132
        self.fa_icon = fa_icon
133
        self.hexcolor = hexcolor
134
        self.label = label
135
        self.creation_label = creation_label
136
        self.available_statuses = available_statuses
137
        self.slug_alias = slug_alias
138
        self.allow_sub_content = allow_sub_content
139
        self.file_extension = file_extension
140
        self.raw_content_markup = raw_content_markup
141
142
143
THREAD_TYPE = 'thread'
144
FILE_TYPE = 'file'
145
MARKDOWNPLUSPAGE_TYPE = 'markdownpage'
146
HTML_DOCUMENTS_TYPE = 'html-document'
147
FOLDER_TYPE = 'folder'
148
149
# TODO - G.M - 31-05-2018 - Set Better Event params
150
event_type = ContentType(
151
    slug='event',
152
    fa_icon='',
153
    hexcolor='',
154
    label='Event',
155
    creation_label='Event',
156
    available_statuses=content_status_list.get_all(),
157
    raw_content_markup=HTML_MARKUP,
158
)
159
160
# TODO - G.M - 31-05-2018 - Set Better Event params
161
comment_type = ContentType(
162
    slug='comment',
163
    fa_icon='',
164
    hexcolor='',
165
    label='Comment',
166
    creation_label='Comment',
167
    available_statuses=content_status_list.get_all(),
168
    raw_content_markup=HTML_MARKUP
169
)
170
171
172
class ContentMarkupList(object):
173
174
    def __init__(self, app_list: typing.List['Application']):
175
        self.app_list = app_list
176
        self._special_content_markup = [TEXT_MARKUP, HTML_MARKUP]
177
178
    def get_all(self):
179
        app_api = ApplicationApi(self.app_list)
180
        content_types = app_api.get_content_types()
181
        markup_list = self._special_content_markup.copy()
182
        for content_type in content_types:
183
            if content_type.raw_content_markup not in markup_list:
184
                markup_list.append(content_type.raw_content_markup)
185
        return markup_list
186
187
188
class ContentTypeList(object):
189
    """
190
    ContentType List
191
    """
192
    Any_SLUG = 'any'
193
    Comment = comment_type
194
    Event = event_type
195
196
    @property
197
    def Folder(self):
198
        return self.get_one_by_slug(FOLDER_TYPE)
199
200
    @property
201
    def File(self):
202
        return self.get_one_by_slug(FILE_TYPE)
203
204
    @property
205
    def Page(self):
206
        return self.get_one_by_slug(HTML_DOCUMENTS_TYPE)
207
208
    @property
209
    def Thread(self):
210
        return self.get_one_by_slug(THREAD_TYPE)
211
212
    def __init__(self, app_list: typing.List['Application']):
213
        self.app_list = app_list
214
        self._special_contents_types = [self.Comment]
215
        self._extra_slugs = [self.Any_SLUG]
216
217
    @property
218
    def _content_types(self):
219
        app_api = ApplicationApi(self.app_list)
220
        content_types = app_api.get_content_types()
221
        return content_types
222
223
    def get_one_by_slug(self, slug: str) -> ContentType:
224
        """
225
        Get ContentType object according to slug
226
        match for both slug and slug_alias
227
        """
228
        content_types = self._content_types.copy()
229
        content_types.extend(self._special_contents_types)
230
        content_types.append(self.Event)
231
        for item in content_types:
232
            if item.slug == slug or (item.slug_alias and slug in item.slug_alias):  # nopep8
233
                return item
234
        raise ContentTypeNotExist()
235
236
    def restricted_allowed_types_slug(self) -> typing.List[str]:
237
        """
238
        Return restricted list of content_type: don't return
239
        "any" slug, dont return content type slug alias , don't return event.
240
        Useful to restrict slug param in schema.
241
        """
242
        allowed_type_slug = [contents_type.slug for contents_type in self._content_types]  # nopep8
243
        return allowed_type_slug
244
245
    def endpoint_allowed_types_slug(self) -> typing.List[str]:
246
        """
247
        Same as restricted_allowed_types_slug but with special content_type
248
        included like comments.
249
        """
250
        content_types = self._content_types
251
        content_types.extend(self._special_contents_types)
252
        allowed_type_slug = [contents_type.slug for contents_type in content_types]  # nopep8
253
        return allowed_type_slug
254
255
    def query_allowed_types_slugs(self) -> typing.List[str]:
256
        """
257
        Return alls allowed types slug : content_type slug + all alias, any
258
        and special content_type like comment. Do not return event.
259
        Usefull allowed value to perform query to database.
260
        """
261
        allowed_types_slug = []
262
        content_types = self._content_types
263
        content_types.extend(self._special_contents_types)
264
        for content_type in content_types:
265
            allowed_types_slug.append(content_type.slug)
266
            if content_type.slug_alias:
267
                allowed_types_slug.extend(content_type.slug_alias)
268
        allowed_types_slug.extend(self._extra_slugs)
269
        return allowed_types_slug
270
271
    def default_allowed_content_properties(self, slug) -> dict:
272
        content_type = self.get_one_by_slug(slug)
273
        if content_type.allow_sub_content:
274
            sub_content_allowed = self.endpoint_allowed_types_slug()
275
        else:
276
            sub_content_allowed = [self.Comment.slug]
277
278
        properties_dict = {}
279
        for elem in sub_content_allowed:
280
            properties_dict[elem] = True
281
        return properties_dict
282
283
284
content_type_list = ContentTypeList(app_list)
285
content_markup_list = ContentMarkupList(app_list)
286