Passed
Pull Request — develop (#62)
by inkhey
02:25
created

tracim_backend.config.CFG._set_default_app()   B

Complexity

Conditions 3

Size

Total Lines 115
Code Lines 88

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 88
dl 0
loc 115
rs 7.3927
c 0
b 0
f 0
cc 3
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
# -*- coding: utf-8 -*-
2
import json
3
from collections import OrderedDict
4
from urllib.parse import urlparse
5
6
import os
7
8
import typing
9
10
from paste.deploy.converters import asbool
11
from tracim_backend.app_models.validator import update_validators
12
from tracim_backend.extensions import app_list
13
from tracim_backend.lib.utils.logger import logger
14
from depot.manager import DepotManager
15
from tracim_backend.app_models.applications import Application
16
from tracim_backend.app_models.contents import CONTENT_TYPES
17
from tracim_backend.app_models.contents import CONTENT_STATUS
18
from tracim_backend.models.data import ActionDescription
19
20
21
class CFG(object):
22
    """Object used for easy access to config file parameters."""
23
24
    def __setattr__(self, key, value):
25
        """
26
        Log-ready setter.
27
28
        Logs all configuration parameters except password.
29
        :param key:
30
        :param value:
31
        :return:
32
        """
33
        if 'PASSWORD' not in key and \
34
                ('URL' not in key or type(value) == str) and \
35
                'CONTENT' not in key:
36
            # We do not show PASSWORD for security reason
37
            # we do not show URL because At the time of configuration setup,
38
            # it can't be evaluated
39
            # We do not show CONTENT in order not to pollute log files
40
            logger.info(self, 'CONFIG: [ {} | {} ]'.format(key, value))
41
        else:
42
            logger.info(self, 'CONFIG: [ {} | <value not shown> ]'.format(key))
43
44
        self.__dict__[key] = value
45
46
    def __init__(self, settings):
47
        """Parse configuration file."""
48
49
        ###
50
        # General
51
        ###
52
        backend_folder = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # nopep8
53
        tracim_v2_folder = os.path.dirname(backend_folder)
54
        default_color_config_file_path = os.path.join(tracim_v2_folder, 'color.json')  # nopep8
55
        self.COLOR_CONFIG_FILE_PATH = settings.get(
56
            'color.config_file_path', default_color_config_file_path
57
        )
58
        if not os.path.exists(self.COLOR_CONFIG_FILE_PATH):
59
            raise Exception(
60
                'ERROR: {} file does not exist. '
61
                'please create it or set color.config_file_path'
62
                'with a correct value'.format(self.COLOR_CONFIG_FILE_PATH)
63
            )
64
65
        try:
66
            with open(self.COLOR_CONFIG_FILE_PATH) as json_file:
67
                self.APPS_COLORS = json.load(json_file)
68
        except Exception as e:
69
            raise Exception(
70
                'Error: {} file could not be load as json'.format(self.COLOR_CONFIG_FILE_PATH) # nopep8
71
            ) from e
72
73
        try:
74
            self.APPS_COLORS['primary']
75
        except KeyError as e:
76
            raise Exception(
77
                'Error: primary color is required in {} file'.format(
78
                    self.COLOR_CONFIG_FILE_PATH)  # nopep8
79
            ) from e
80
81
        default_enabled_app = [
82
            'contents/thread',
83
            'contents/file',
84
            'contents/html-document',
85
        ]
86
        enabled_app = []
87
        enabled_app_str = settings.get('app.enabled', None)
88
        if enabled_app_str:
89
            for app in enabled_app_str.split(','):
90
                app_name = app.strip()
91
                enabled_app.append(app_name)
92
        else:
93
            enabled_app = default_enabled_app
94
        self.ENABLED_APP = enabled_app
95
        self._set_default_app(self.ENABLED_APP)
96
        mandatory_msg = \
97
            'ERROR: {} configuration is mandatory. Set it before continuing.'
98
        self.DEPOT_STORAGE_DIR = settings.get(
99
            'depot_storage_dir',
100
        )
101
        if not self.DEPOT_STORAGE_DIR:
102
            raise Exception(
103
                mandatory_msg.format('depot_storage_dir')
104
            )
105
        self.DEPOT_STORAGE_NAME = settings.get(
106
            'depot_storage_name',
107
        )
108
        if not self.DEPOT_STORAGE_NAME:
109
            raise Exception(
110
                mandatory_msg.format('depot_storage_name')
111
            )
112
        self.PREVIEW_CACHE_DIR = settings.get(
113
            'preview_cache_dir',
114
        )
115
        if not self.PREVIEW_CACHE_DIR:
116
            raise Exception(
117
                'ERROR: preview_cache_dir configuration is mandatory. '
118
                'Set it before continuing.'
119
            )
120
121
        # TODO - G.M - 2018-09-11 - Deprecated param
122
        # self.DATA_UPDATE_ALLOWED_DURATION = int(settings.get(
123
        #     'content.update.allowed.duration',
124
        #     0,
125
        # ))
126
127
        self.API_KEY = settings.get(
128
            'api.key',
129
            ''
130
        )
131
        self.SESSION_REISSUE_TIME = int(settings.get(
132
            'session.reissue_time',
133
            120
134
        ))
135
136
        self.WEBSITE_TITLE = settings.get(
137
            'website.title',
138
            'TRACIM',
139
        )
140
141
        # base url of the frontend
142
        self.WEBSITE_BASE_URL = settings.get(
143
            'website.base_url',
144
            '',
145
        )
146
        if not self.WEBSITE_BASE_URL:
147
            raise Exception(
148
                'website.base_url is needed in order to have correct path in'
149
                'few place like in email.'
150
                'You should set it with frontend root url.'
151
            )
152
153
        self.API_BASE_URL = settings.get(
154
            'api.base_url',
155
            self.WEBSITE_BASE_URL,
156
        )
157
        allowed_origin = []
158
        allowed_origin_string = settings.get(
159
            'cors.access-control-allowed-origin',
160
            ''
161
        )
162
        if allowed_origin_string:
163
            allowed_origin.extend(allowed_origin_string.split(','))  # nopep8
164
        if not allowed_origin:
165
            allowed_origin.append(self.WEBSITE_BASE_URL)
166
            if self.API_BASE_URL != self.WEBSITE_BASE_URL:
167
                allowed_origin.append(self.API_BASE_URL)
168
        self.CORS_ALLOWED_ORIGIN = allowed_origin
169
170
        # TODO - G.M - 26-03-2018 - [Cleanup] These params seems deprecated for tracimv2,  # nopep8
171
        # Verify this
172
        #
173
        # self.WEBSITE_HOME_TITLE_COLOR = settings.get(
174
        #     'website.title.color',
175
        #     '#555',
176
        # )
177
        # self.WEBSITE_HOME_IMAGE_PATH = settings.get(
178
        #     '/assets/img/home_illustration.jpg',
179
        # )
180
        # self.WEBSITE_HOME_BACKGROUND_IMAGE_PATH = settings.get(
181
        #     '/assets/img/bg.jpg',
182
        # )
183
        #
184
        website_server_name = settings.get(
185
            'website.server_name',
186
            None,
187
        )
188
        if not website_server_name:
189
            website_server_name= urlparse(self.WEBSITE_BASE_URL).hostname
190
            logger.warning(
191
                self,
192
                'NOTE: Generated website.server_name parameter from '
193
                'website.base_url parameter -> {0}'
194
                .format(website_server_name)
195
            )
196
        self.WEBSITE_SERVER_NAME = website_server_name
197
        # TODO - G.M - 2018-09-11 - Deprecated params
198
        # self.WEBSITE_HOME_TAG_LINE = settings.get(
199
        #     'website.home.tag_line',
200
        #     '',
201
        # )
202
        # self.WEBSITE_SUBTITLE = settings.get(
203
        #     'website.home.subtitle',
204
        #     '',
205
        # )
206
        # self.WEBSITE_HOME_BELOW_LOGIN_FORM = settings.get(
207
        #     'website.home.below_login_form',
208
        #     '',
209
        # )
210
        #
211
        # self.WEBSITE_TREEVIEW_CONTENT = settings.get(
212
        #     'website.treeview.content',
213
        # )
214
215
        self.USER_AUTH_TOKEN_VALIDITY = int(settings.get(
216
            'user.auth_token.validity',
217
            '604800',
218
        ))
219
        self.USER_RESET_PASSWORD_TOKEN_VALIDITY = int(settings.get(
220
            'user.reset_password.validity',
221
            '900'
222
        ))
223
224
        self.DEBUG = asbool(settings.get('debug', False))
225
        # TODO - G.M - 27-03-2018 - [Email] Restore email config
226
        ###
227
        # EMAIL related stuff (notification, reply)
228
        ##
229
230
        self.EMAIL_NOTIFICATION_NOTIFIED_EVENTS = [
231
            ActionDescription.COMMENT,
232
            ActionDescription.CREATION,
233
            ActionDescription.EDITION,
234
            ActionDescription.REVISION,
235
            ActionDescription.STATUS_UPDATE
236
        ]
237
238
        self.EMAIL_NOTIFICATION_NOTIFIED_CONTENTS = [
239
            CONTENT_TYPES.Page.slug,
240
            CONTENT_TYPES.Thread.slug,
241
            CONTENT_TYPES.File.slug,
242
            CONTENT_TYPES.Comment.slug,
243
            # CONTENT_TYPES.Folder.slug -- Folder is skipped
244
        ]
245
        if settings.get('email.notification.from'):
246
            raise Exception(
247
                'email.notification.from configuration is deprecated. '
248
                'Use instead email.notification.from.email and '
249
                'email.notification.from.default_label.'
250
            )
251
        self.EMAIL_NOTIFICATION_FROM_EMAIL = settings.get(
252
            'email.notification.from.email',
253
            'noreply+{user_id}@trac.im'
254
        )
255
        self.EMAIL_NOTIFICATION_FROM_DEFAULT_LABEL = settings.get(
256
            'email.notification.from.default_label',
257
            'Tracim Notifications'
258
        )
259
        self.EMAIL_NOTIFICATION_REPLY_TO_EMAIL = settings.get(
260
            'email.notification.reply_to.email',
261
        )
262
        self.EMAIL_NOTIFICATION_REFERENCES_EMAIL = settings.get(
263
            'email.notification.references.email'
264
        )
265
        # Content update notification
266
        self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_HTML = settings.get(
267
            'email.notification.content_update.template.html',
268
        )
269
        self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_TEXT = settings.get(
270
            'email.notification.content_update.template.text',
271
        )
272
        self.EMAIL_NOTIFICATION_CONTENT_UPDATE_SUBJECT = settings.get(
273
            'email.notification.content_update.subject',
274
        )
275
        # Created account notification
276
        self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_HTML = settings.get(
277
            'email.notification.created_account.template.html',
278
            './tracim_backend/templates/mail/created_account_body_html.mak',
279
        )
280
        self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_TEXT = settings.get(
281
            'email.notification.created_account.template.text',
282
            './tracim_backend/templates/mail/created_account_body_text.mak',
283
        )
284
        self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_SUBJECT = settings.get(
285
            'email.notification.created_account.subject',
286
            '[{website_title}] Created account',
287
        )
288
289
        # Reset password notification
290
        self.EMAIL_NOTIFICATION_RESET_PASSWORD_TEMPLATE_HTML = settings.get(
291
            'email.notification.reset_password_request.template.html',
292
            './tracim_backend/templates/mail/reset_password_body_html.mak',
293
        )
294
        self.EMAIL_NOTIFICATION_RESET_PASSWORD_TEMPLATE_TEXT = settings.get(
295
            'email.notification.reset_password_request.template.text',
296
            './tracim_backend/templates/mail/reset_password_body_text.mak',
297
        )
298
        self.EMAIL_NOTIFICATION_RESET_PASSWORD_SUBJECT = settings.get(
299
            'email.notification.reset_password_request.subject',
300
            '[{website_title}] Reset Password Request'
301
        )
302
303
        self.EMAIL_NOTIFICATION_PROCESSING_MODE = settings.get(
304
            'email.notification.processing_mode',
305
        )
306
307
        self.EMAIL_NOTIFICATION_ACTIVATED = asbool(settings.get(
308
            'email.notification.activated',
309
        ))
310
        self.EMAIL_NOTIFICATION_SMTP_SERVER = settings.get(
311
            'email.notification.smtp.server',
312
        )
313
        self.EMAIL_NOTIFICATION_SMTP_PORT = settings.get(
314
            'email.notification.smtp.port',
315
        )
316
        self.EMAIL_NOTIFICATION_SMTP_USER = settings.get(
317
            'email.notification.smtp.user',
318
        )
319
        self.EMAIL_NOTIFICATION_SMTP_PASSWORD = settings.get(
320
            'email.notification.smtp.password',
321
        )
322
        self.EMAIL_NOTIFICATION_LOG_FILE_PATH = settings.get(
323
            'email.notification.log_file_path',
324
            None,
325
        )
326
327
        # self.EMAIL_REPLY_ACTIVATED = asbool(settings.get(
328
        #     'email.reply.activated',
329
        #     False,
330
        # ))
331
        #
332
        # self.EMAIL_REPLY_IMAP_SERVER = settings.get(
333
        #     'email.reply.imap.server',
334
        # )
335
        # self.EMAIL_REPLY_IMAP_PORT = settings.get(
336
        #     'email.reply.imap.port',
337
        # )
338
        # self.EMAIL_REPLY_IMAP_USER = settings.get(
339
        #     'email.reply.imap.user',
340
        # )
341
        # self.EMAIL_REPLY_IMAP_PASSWORD = settings.get(
342
        #     'email.reply.imap.password',
343
        # )
344
        # self.EMAIL_REPLY_IMAP_FOLDER = settings.get(
345
        #     'email.reply.imap.folder',
346
        # )
347
        # self.EMAIL_REPLY_CHECK_HEARTBEAT = int(settings.get(
348
        #     'email.reply.check.heartbeat',
349
        #     60,
350
        # ))
351
        # self.EMAIL_REPLY_TOKEN = settings.get(
352
        #     'email.reply.token',
353
        # )
354
        # self.EMAIL_REPLY_IMAP_USE_SSL = asbool(settings.get(
355
        #     'email.reply.imap.use_ssl',
356
        # ))
357
        # self.EMAIL_REPLY_IMAP_USE_IDLE = asbool(settings.get(
358
        #     'email.reply.imap.use_idle',
359
        #     True,
360
        # ))
361
        # self.EMAIL_REPLY_CONNECTION_MAX_LIFETIME = int(settings.get(
362
        #     'email.reply.connection.max_lifetime',
363
        #     600,  # 10 minutes
364
        # ))
365
        # self.EMAIL_REPLY_USE_HTML_PARSING = asbool(settings.get(
366
        #     'email.reply.use_html_parsing',
367
        #     True,
368
        # ))
369
        # self.EMAIL_REPLY_USE_TXT_PARSING = asbool(settings.get(
370
        #     'email.reply.use_txt_parsing',
371
        #     True,
372
        # ))
373
        # self.EMAIL_REPLY_LOCKFILE_PATH = settings.get(
374
        #     'email.reply.lockfile_path',
375
        #     ''
376
        # )
377
        # if not self.EMAIL_REPLY_LOCKFILE_PATH and self.EMAIL_REPLY_ACTIVATED:
378
        #     raise Exception(
379
        #         mandatory_msg.format('email.reply.lockfile_path')
380
        #     )
381
        #
382
        self.EMAIL_PROCESSING_MODE = settings.get(
383
            'email.processing_mode',
384
            'sync',
385
        ).upper()
386
387
        if self.EMAIL_PROCESSING_MODE not in (
388
                self.CST.ASYNC,
389
                self.CST.SYNC,
390
        ):
391
            raise Exception(
392
                'email.processing_mode '
393
                'can ''be "{}" or "{}", not "{}"'.format(
394
                    self.CST.ASYNC,
395
                    self.CST.SYNC,
396
                    self.EMAIL_PROCESSING_MODE,
397
                )
398
            )
399
400
        self.EMAIL_SENDER_REDIS_HOST = settings.get(
401
            'email.async.redis.host',
402
            'localhost',
403
        )
404
        self.EMAIL_SENDER_REDIS_PORT = int(settings.get(
405
            'email.async.redis.port',
406
            6379,
407
        ))
408
        self.EMAIL_SENDER_REDIS_DB = int(settings.get(
409
            'email.async.redis.db',
410
            0,
411
        ))
412
413
        ###
414
        # WSGIDAV (Webdav server)
415
        ###
416
417
        # TODO - G.M - 27-03-2018 - [WebDav] Restore wsgidav config
418
        #self.WSGIDAV_CONFIG_PATH = settings.get(
419
        #    'wsgidav.config_path',
420
        #    'wsgidav.conf',
421
        #)
422
        # TODO: Convert to importlib
423
        # http://stackoverflow.com/questions/41063938/use-importlib-instead-imp-for-non-py-file
424
        #self.wsgidav_config = imp.load_source(
425
        #    'wsgidav_config',
426
        #    self.WSGIDAV_CONFIG_PATH,
427
        #)
428
        # self.WSGIDAV_PORT = self.wsgidav_config.port
429
        # self.WSGIDAV_CLIENT_BASE_URL = settings.get(
430
        #     'wsgidav.client.base_url',
431
        #     None,
432
        # )
433
        #
434
        # if not self.WSGIDAV_CLIENT_BASE_URL:
435
        #     self.WSGIDAV_CLIENT_BASE_URL = \
436
        #         '{0}:{1}'.format(
437
        #             self.WEBSITE_SERVER_NAME,
438
        #             self.WSGIDAV_PORT,
439
        #         )
440
        #     logger.warning(self,
441
        #         'NOTE: Generated wsgidav.client.base_url parameter with '
442
        #         'followings parameters: website.server_name and '
443
        #         'wsgidav.conf port'.format(
444
        #             self.WSGIDAV_CLIENT_BASE_URL,
445
        #         )
446
        #     )
447
        #
448
        # if not self.WSGIDAV_CLIENT_BASE_URL.endswith('/'):
449
        #     self.WSGIDAV_CLIENT_BASE_URL += '/'
450
451
        # TODO - G.M - 27-03-2018 - [Caldav] Restore radicale config
452
        ###
453
        # RADICALE (Caldav server)
454
        ###
455
        # self.RADICALE_SERVER_HOST = settings.get(
456
        #     'radicale.server.host',
457
        #     '127.0.0.1',
458
        # )
459
        # self.RADICALE_SERVER_PORT = int(settings.get(
460
        #     'radicale.server.port',
461
        #     5232,
462
        # ))
463
        # # Note: Other parameters needed to work in SSL (cert file, etc)
464
        # self.RADICALE_SERVER_SSL = asbool(settings.get(
465
        #     'radicale.server.ssl',
466
        #     False,
467
        # ))
468
        # self.RADICALE_SERVER_FILE_SYSTEM_FOLDER = settings.get(
469
        #     'radicale.server.filesystem.folder',
470
        # )
471
        # if not self.RADICALE_SERVER_FILE_SYSTEM_FOLDER:
472
        #     raise Exception(
473
        #         mandatory_msg.format('radicale.server.filesystem.folder')
474
        #     )
475
        # self.RADICALE_SERVER_ALLOW_ORIGIN = settings.get(
476
        #     'radicale.server.allow_origin',
477
        #     None,
478
        # )
479
        # if not self.RADICALE_SERVER_ALLOW_ORIGIN:
480
        #     self.RADICALE_SERVER_ALLOW_ORIGIN = self.WEBSITE_BASE_URL
481
        #     logger.warning(self,
482
        #         'NOTE: Generated radicale.server.allow_origin parameter with '
483
        #         'followings parameters: website.base_url ({0})'
484
        #         .format(self.WEBSITE_BASE_URL)
485
        #     )
486
        #
487
        # self.RADICALE_SERVER_REALM_MESSAGE = settings.get(
488
        #     'radicale.server.realm_message',
489
        #     'Tracim Calendar - Password Required',
490
        # )
491
        #
492
        # self.RADICALE_CLIENT_BASE_URL_HOST = settings.get(
493
        #     'radicale.client.base_url.host',
494
        #     'http://{}:{}'.format(
495
        #         self.RADICALE_SERVER_HOST,
496
        #         self.RADICALE_SERVER_PORT,
497
        #     ),
498
        # )
499
        #
500
        # self.RADICALE_CLIENT_BASE_URL_PREFIX = settings.get(
501
        #     'radicale.client.base_url.prefix',
502
        #     '/',
503
        # )
504
        # # Ensure finished by '/'
505
        # if '/' != self.RADICALE_CLIENT_BASE_URL_PREFIX[-1]:
506
        #     self.RADICALE_CLIENT_BASE_URL_PREFIX += '/'
507
        # if '/' != self.RADICALE_CLIENT_BASE_URL_PREFIX[0]:
508
        #     self.RADICALE_CLIENT_BASE_URL_PREFIX \
509
        #         = '/' + self.RADICALE_CLIENT_BASE_URL_PREFIX
510
        #
511
        # if not self.RADICALE_CLIENT_BASE_URL_HOST:
512
        #     logger.warning(self,
513
        #         'Generated radicale.client.base_url.host parameter with '
514
        #         'followings parameters: website.server_name -> {}'
515
        #         .format(self.WEBSITE_SERVER_NAME)
516
        #     )
517
        #     self.RADICALE_CLIENT_BASE_URL_HOST = self.WEBSITE_SERVER_NAME
518
        #
519
        # self.RADICALE_CLIENT_BASE_URL_TEMPLATE = '{}{}'.format(
520
        #     self.RADICALE_CLIENT_BASE_URL_HOST,
521
        #     self.RADICALE_CLIENT_BASE_URL_PREFIX,
522
        # )
523
        self.PREVIEW_JPG_RESTRICTED_DIMS = asbool(settings.get(
524
            'preview.jpg.restricted_dims', False
525
        ))
526
        preview_jpg_allowed_dims_str = settings.get('preview.jpg.allowed_dims', '')  # nopep8
527
        allowed_dims = []
528
        if preview_jpg_allowed_dims_str:
529
            for sizes in preview_jpg_allowed_dims_str.split(','):
530
                parts = sizes.split('x')
531
                assert len(parts) == 2
532
                width, height = parts
533
                assert width.isdecimal()
534
                assert height.isdecimal()
535
                size = PreviewDim(int(width), int(height))
536
                allowed_dims.append(size)
537
538
        if not allowed_dims:
539
            size = PreviewDim(256, 256)
540
            allowed_dims.append(size)
541
542
        self.PREVIEW_JPG_ALLOWED_DIMS = allowed_dims
543
544
        self.FRONTEND_SERVE = asbool(settings.get(
545
            'frontend.serve', False
546
        ))
547
        # INFO - G.M - 2018-08-06 - we pretend that frontend_dist_folder
548
        # is probably in frontend subfolder
549
        # of tracim_v2 parent of both backend and frontend
550
        backend_folder = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # nopep8
551
        tracim_v2_folder = os.path.dirname(backend_folder)
552
        backend_i18n_folder = os.path.join(backend_folder,'tracim_backend', 'locale')  # nopep8
553
554
        self.BACKEND_I18N_FOLDER = settings.get(
555
            'backend.18n_folder_path', backend_i18n_folder
556
        )
557
        if not os.path.isdir(self.BACKEND_I18N_FOLDER):
558
            raise Exception(
559
                'ERROR: {} folder does not exist as folder. '
560
                'please set backend.i8n_folder_path'
561
                'with a correct value'.format(self.BACKEND_I18N_FOLDER)
562
            )
563
564
        frontend_dist_folder = os.path.join(tracim_v2_folder, 'frontend', 'dist')  # nopep8
565
        self.FRONTEND_DIST_FOLDER_PATH = settings.get(
566
            'frontend.dist_folder_path', frontend_dist_folder
567
        )
568
569
        # INFO - G.M - 2018-08-06 - We check dist folder existence
570
        if self.FRONTEND_SERVE and not os.path.isdir(self.FRONTEND_DIST_FOLDER_PATH):  # nopep8
571
            raise Exception(
572
                'ERROR: {} folder does not exist as folder. '
573
                'please set frontend.dist_folder.path'
574
                'with a correct value'.format(self.FRONTEND_DIST_FOLDER_PATH)
575
            )
576
577
    def configure_filedepot(self):
578
579
        # TODO - G.M - 2018-08-08 - [GlobalVar] Refactor Global var
580
        # of tracim_backend, Be careful DepotManager is a Singleton !
581
582
        depot_storage_name = self.DEPOT_STORAGE_NAME
583
        depot_storage_path = self.DEPOT_STORAGE_DIR
584
        depot_storage_settings = {'depot.storage_path': depot_storage_path}
585
        DepotManager.configure(
586
            depot_storage_name,
587
            depot_storage_settings,
588
        )
589
590
    def _set_default_app(self, enabled_app_list: typing.List[str]):
591
592
        # init applications
593
        html_documents = Application(
594
            label='Text Documents',  # TODO - G.M - 24-05-2018 - Check label
595
            slug='contents/html-document',
596
            fa_icon='file-text-o',
597
            is_active=True,
598
            config={},
599
            main_route='/#/workspaces/{workspace_id}/contents?type=html-document',
600
            app_config=self
601
        )
602
        html_documents.add_content_type(
603
            slug='html-document',
604
            label='Text Document',
605
            creation_label='Write a document',
606
            available_statuses=CONTENT_STATUS.get_all(),
607
            slug_alias=['page']
608
        )
609
610
        _file = Application(
611
            label='Files',
612
            slug='contents/file',
613
            fa_icon='paperclip',
614
            is_active=True,
615
            config={},
616
            main_route='/#/workspaces/{workspace_id}/contents?type=file',
617
            app_config=self,
618
        )
619
        _file.add_content_type(
620
            slug='file',
621
            label='File',
622
            creation_label='Upload a file',
623
            available_statuses=CONTENT_STATUS.get_all(),
624
        )
625
626
        thread = Application(
627
            label='Threads',
628
            slug='contents/thread',
629
            fa_icon='comments-o',
630
            is_active=True,
631
            config={},
632
            main_route='/#/workspaces/{workspace_id}/contents?type=thread',
633
            app_config=self
634
        )
635
        thread.add_content_type(
636
            slug='thread',
637
            label='Thread',
638
            creation_label='Discuss about a topic',
639
            available_statuses=CONTENT_STATUS.get_all(),
640
        )
641
642
        folder = Application(
643
            label='Folder',
644
            slug='contents/folder',
645
            fa_icon='folder-open-o',
646
            is_active=True,
647
            config={},
648
            main_route='',
649
            app_config=self
650
        )
651
        folder.add_content_type(
652
            slug='folder',
653
            label='Folder',
654
            creation_label='Create a folder',
655
            available_statuses=CONTENT_STATUS.get_all(),
656
            allow_sub_content=True,
657
        )
658
659
        markdownpluspage = Application(
660
            label='Markdown Plus Documents',
661
            # TODO - G.M - 24-05-2018 - Check label
662
            slug='contents/markdownpluspage',
663
            fa_icon='file-code-o',
664
            is_active=False,
665
            config={},
666
            main_route='/#/workspaces/{workspace_id}/contents?type=markdownpluspage',
667
            # nopep8
668
            app_config=self,
669
        )
670
        markdownpluspage.add_content_type(
671
            slug='markdownpage',
672
            label='Rich Markdown File',
673
            creation_label='Create a Markdown document',
674
            available_statuses=CONTENT_STATUS.get_all(),
675
        )
676
677
        calendar = Application(
678
            label='Calendar',
679
            slug='calendar',
680
            fa_icon='calendar',
681
            is_active=False,
682
            config={},
683
            main_route='/#/workspaces/{workspace_id}/calendar',
684
            app_config=self
685
        )
686
687
        # process activated app list
688
        available_apps = OrderedDict([
689
            (html_documents.slug, html_documents),
690
            (_file.slug, _file),
691
            (thread.slug, thread),
692
            (folder.slug, folder),
693
            (markdownpluspage.slug, markdownpluspage),
694
            (calendar.slug, calendar)
695
        ])
696
        # TODO - G.M - 2018-08-08 - [GlobalVar] Refactor Global var
697
        # of tracim_backend, Be careful app_list is a global_var
698
        app_list.clear()
699
        for app_slug in enabled_app_list:
700
            if app_slug in available_apps.keys():
701
                app_list.append(available_apps[app_slug])
702
        # TODO - G.M - 2018-08-08 - We need to update validators each time
703
        # app_list is updated.
704
        update_validators()
705
706
    class CST(object):
707
        ASYNC = 'ASYNC'
708
        SYNC = 'SYNC'
709
710
        TREEVIEW_FOLDERS = 'folders'
711
        TREEVIEW_ALL = 'all'
712
713
714
class PreviewDim(object):
715
716
    def __init__(self, width: int, height: int) -> None:
717
        self.width = width
718
        self.height = height
719
720
    def __repr__(self):
721
        return "<PreviewDim width:{width} height:{height}>".format(
722
            width=self.width,
723
            height=self.height,
724
        )
725