|
@@ -13,37 +13,28 @@ convert them into boolean, for example, you should use the
|
13
|
13
|
|
14
|
14
|
"""
|
15
|
15
|
import imp
|
16
|
|
-import importlib
|
17
|
16
|
import os
|
18
|
17
|
from urllib.parse import urlparse
|
19
|
18
|
|
20
|
|
-import tg
|
|
19
|
+from depot.manager import DepotManager
|
21
|
20
|
from paste.deploy.converters import asbool
|
|
21
|
+import tg
|
22
|
22
|
from tg.configuration.milestones import environment_loaded
|
23
|
|
-
|
24
|
23
|
from tgext.pluggable import plug
|
25
|
24
|
from tgext.pluggable import replace_template
|
26
|
|
-from tracim.lib.system import InterruptManager
|
27
|
|
-
|
28
|
|
-from tracim.lib.utils import lazy_ugettext as l_
|
29
|
25
|
|
30
|
26
|
import tracim
|
31
|
|
-from tracim import model
|
32
|
27
|
from tracim.config import TracimAppConfig
|
33
|
28
|
from tracim.lib.base import logger
|
34
|
29
|
from tracim.lib.daemons import DaemonsManager
|
35
|
30
|
from tracim.lib.daemons import MailSenderDaemon
|
36
|
31
|
from tracim.lib.daemons import RadicaleDaemon
|
37
|
32
|
from tracim.lib.daemons import WsgiDavDaemon
|
|
33
|
+from tracim.lib.system import InterruptManager
|
|
34
|
+from tracim.lib.utils import lazy_ugettext as l_
|
38
|
35
|
from tracim.model.data import ActionDescription
|
39
|
36
|
from tracim.model.data import ContentType
|
40
|
37
|
|
41
|
|
-from depot.manager import DepotManager
|
42
|
|
-DepotManager.configure(
|
43
|
|
- 'default',
|
44
|
|
- {'depot.storage_path': '/tmp/depot_storage_path/'}
|
45
|
|
-)
|
46
|
|
-
|
47
|
38
|
base_config = TracimAppConfig()
|
48
|
39
|
base_config.renderers = []
|
49
|
40
|
base_config.use_toscawidgets = False
|
|
@@ -51,25 +42,28 @@ base_config.use_toscawidgets2 = True
|
51
|
42
|
|
52
|
43
|
base_config.package = tracim
|
53
|
44
|
|
54
|
|
-#Enable json in expose
|
|
45
|
+# Enable json in expose
|
55
|
46
|
base_config.renderers.append('json')
|
56
|
|
-#Enable genshi in expose to have a lingua franca for extensions and pluggable apps
|
57
|
|
-#you can remove this if you don't plan to use it.
|
|
47
|
+# Enable genshi in expose to have a lingua franca for extensions and pluggable
|
|
48
|
+# apps
|
|
49
|
+# you can remove this if you don't plan to use it.
|
58
|
50
|
base_config.renderers.append('genshi')
|
59
|
51
|
|
60
|
|
-#Set the default renderer
|
|
52
|
+# Set the default renderer
|
61
|
53
|
base_config.default_renderer = 'mako'
|
62
|
54
|
base_config.renderers.append('mako')
|
63
|
|
-#Configure the base SQLALchemy Setup
|
|
55
|
+# Configure the base SQLALchemy Setup
|
64
|
56
|
base_config.use_sqlalchemy = True
|
65
|
57
|
base_config.model = tracim.model
|
66
|
58
|
base_config.DBSession = tracim.model.DBSession
|
67
|
59
|
|
68
|
|
-# This value can be modified by tracim.lib.auth.wrapper.AuthConfigWrapper but have to be specified before
|
|
60
|
+# This value can be modified by tracim.lib.auth.wrapper.AuthConfigWrapper but
|
|
61
|
+# have to be specified before
|
69
|
62
|
base_config.auth_backend = 'sqlalchemy'
|
70
|
63
|
|
71
|
64
|
# base_config.flash.cookie_name
|
72
|
|
-# base_config.flash.default_status -> Default message status if not specified (ok by default)
|
|
65
|
+# base_config.flash.default_status -> Default message status if not specified
|
|
66
|
+# (ok by default)
|
73
|
67
|
base_config['flash.template'] = '''
|
74
|
68
|
<div class="alert alert-${status}" style="margin-top: 1em;">
|
75
|
69
|
<button type="button" class="close" data-dismiss="alert">×</button>
|
|
@@ -79,9 +73,20 @@ base_config['flash.template'] = '''
|
79
|
73
|
</div>
|
80
|
74
|
</div>
|
81
|
75
|
'''
|
82
|
|
-# -> string.Template instance used as the flash template when rendered from server side, will receive $container_id, $message and $status variables.
|
83
|
|
-# flash.js_call -> javascript code which will be run when displaying the flash from javascript. Default is webflash.render(), you can use webflash.payload() to retrieve the message and show it with your favourite library.
|
84
|
|
-# flash.js_template -> string.Template instance used to replace full javascript support for flash messages. When rendering flash message for javascript usage the following code will be used instead of providing the standard webflash object. If you replace js_template you must also ensure cookie parsing and delete it for already displayed messages. The template will receive: $container_id, $cookie_name, $js_call variables.
|
|
76
|
+
|
|
77
|
+# -> string.Template instance used as the flash template when rendered from
|
|
78
|
+# server side, will receive $container_id, $message and $status variables.
|
|
79
|
+
|
|
80
|
+# flash.js_call -> javascript code which will be run when displaying the flash
|
|
81
|
+# from javascript. Default is webflash.render(), you can use webflash.payload()
|
|
82
|
+# to retrieve the message and show it with your favourite library.
|
|
83
|
+
|
|
84
|
+# flash.js_template -> string.Template instance used to replace full javascript
|
|
85
|
+# support for flash messages. When rendering flash message for javascript usage
|
|
86
|
+# the following code will be used instead of providing the standard webflash
|
|
87
|
+# object. If you replace js_template you must also ensure cookie parsing and
|
|
88
|
+# delete it for already displayed messages. The template will receive:
|
|
89
|
+# $container_id, $cookie_name, $js_call variables.
|
85
|
90
|
|
86
|
91
|
base_config['templating.genshi.name_constant_patch'] = True
|
87
|
92
|
|
|
@@ -91,19 +96,24 @@ base_config['templating.genshi.name_constant_patch'] = True
|
91
|
96
|
base_config.sa_auth.cookie_secret = "3283411b-1904-4554-b0e1-883863b53080"
|
92
|
97
|
|
93
|
98
|
# INFO - This is the way to specialize the resetpassword email properties
|
94
|
|
-# plug(base_config, 'resetpassword', None, mail_subject=reset_password_email_subject)
|
|
99
|
+# plug(base_config,
|
|
100
|
+# 'resetpassword',
|
|
101
|
+# None,
|
|
102
|
+# mail_subject=reset_password_email_subject)
|
95
|
103
|
plug(base_config, 'resetpassword', 'reset_password')
|
96
|
104
|
|
97
|
|
-replace_template(base_config, 'resetpassword.templates.index', 'tracim.templates.reset_password_index')
|
98
|
|
-replace_template(base_config, 'resetpassword.templates.change_password', 'mako:tracim.templates.reset_password_change_password')
|
|
105
|
+replace_template(base_config,
|
|
106
|
+ 'resetpassword.templates.index',
|
|
107
|
+ 'tracim.templates.reset_password_index')
|
|
108
|
+replace_template(base_config,
|
|
109
|
+ 'resetpassword.templates.change_password',
|
|
110
|
+ 'mako:tracim.templates.reset_password_change_password')
|
99
|
111
|
|
100
|
112
|
daemons = DaemonsManager()
|
101
|
113
|
|
102
|
114
|
|
103
|
115
|
def start_daemons(manager: DaemonsManager):
|
104
|
|
- """
|
105
|
|
- Sart Tracim daemons
|
106
|
|
- """
|
|
116
|
+ """Start Tracim daemons."""
|
107
|
117
|
from tg import config
|
108
|
118
|
cfg = CFG.get_instance()
|
109
|
119
|
# Don't start daemons if they are disabled
|
|
@@ -116,24 +126,27 @@ def start_daemons(manager: DaemonsManager):
|
116
|
126
|
if cfg.EMAIL_PROCESSING_MODE == CFG.CST.ASYNC:
|
117
|
127
|
manager.run('mail_sender', MailSenderDaemon)
|
118
|
128
|
|
119
|
|
-environment_loaded.register(lambda: start_daemons(daemons))
|
120
|
|
-interrupt_manager = InterruptManager(os.getpid(), daemons_manager=daemons)
|
121
|
129
|
|
122
|
|
-# Note: here are fake translatable strings that allow to translate messages for reset password email content
|
123
|
|
-duplicated_email_subject = l_('Password reset request')
|
124
|
|
-duplicated_email_body = l_('''
|
125
|
|
-We've received a request to reset the password for this account.
|
126
|
|
-Please click this link to reset your password:
|
|
130
|
+def configure_depot():
|
|
131
|
+ """Configure Depot."""
|
|
132
|
+ depot_storage_name = 'default'
|
|
133
|
+ depot_storage_path = CFG.get_instance().DEPOT_STORAGE_DIR
|
|
134
|
+ depot_storage_settings = {'depot.storage_path': depot_storage_path}
|
|
135
|
+ DepotManager.configure(
|
|
136
|
+ depot_storage_name,
|
|
137
|
+ depot_storage_settings,
|
|
138
|
+ )
|
127
|
139
|
|
128
|
|
-%(password_reset_link)s
|
129
|
140
|
|
130
|
|
-If you no longer wish to make the above change, or if you did not initiate this request, please disregard and/or delete this e-mail.
|
131
|
|
-''')
|
|
141
|
+environment_loaded.register(lambda: start_daemons(daemons))
|
|
142
|
+environment_loaded.register(lambda: configure_depot())
|
|
143
|
+
|
|
144
|
+interrupt_manager = InterruptManager(os.getpid(), daemons_manager=daemons)
|
132
|
145
|
|
133
|
146
|
#######
|
134
|
147
|
#
|
135
|
148
|
# INFO - D.A. - 2014-10-31
|
136
|
|
-# The following code is a dirty way to integrate translation for resetpassword tgapp in tracim
|
|
149
|
+# fake strings allowing to translate resetpassword tgapp.
|
137
|
150
|
# TODO - Integrate these translations into tgapp-resetpassword
|
138
|
151
|
#
|
139
|
152
|
|
|
@@ -143,6 +156,7 @@ l_('Save new password')
|
143
|
156
|
l_('Email address')
|
144
|
157
|
l_('Send Request')
|
145
|
158
|
|
|
159
|
+l_('Password reset request')
|
146
|
160
|
|
147
|
161
|
l_('Password reset request sent')
|
148
|
162
|
l_('Invalid password reset request')
|
|
@@ -159,22 +173,24 @@ Please click this link to reset your password:
|
159
|
173
|
If you no longer wish to make the above change, or if you did not initiate this request, please disregard and/or delete this e-mail.
|
160
|
174
|
''')
|
161
|
175
|
|
|
176
|
+
|
162
|
177
|
class CFG(object):
|
163
|
|
- """
|
164
|
|
- Singleton used for easy access to config file parameters
|
165
|
|
- """
|
|
178
|
+ """Singleton used for easy access to config file parameters."""
|
166
|
179
|
|
167
|
180
|
_instance = None
|
168
|
181
|
|
169
|
182
|
@classmethod
|
170
|
183
|
def get_instance(cls) -> 'CFG':
|
|
184
|
+ """Get configuration singleton."""
|
171
|
185
|
if not CFG._instance:
|
172
|
186
|
CFG._instance = CFG()
|
173
|
187
|
return CFG._instance
|
174
|
188
|
|
175
|
189
|
def __setattr__(self, key, value):
|
176
|
190
|
"""
|
177
|
|
- Log-ready setter. this is used for logging configuration (every parameter except password)
|
|
191
|
+ Log-ready setter.
|
|
192
|
+
|
|
193
|
+ Logs all configuration parameters except password.
|
178
|
194
|
:param key:
|
179
|
195
|
:param value:
|
180
|
196
|
:return:
|
|
@@ -183,7 +199,8 @@ class CFG(object):
|
183
|
199
|
('URL' not in key or type(value) == str) and \
|
184
|
200
|
'CONTENT' not in key:
|
185
|
201
|
# We do not show PASSWORD for security reason
|
186
|
|
- # we do not show URL because the associated config uses tg.lurl() which is evaluated when at display time.
|
|
202
|
+ # we do not show URL because the associated config uses tg.lurl()
|
|
203
|
+ # which is evaluated when at display time.
|
187
|
204
|
# At the time of configuration setup, it can't be evaluated
|
188
|
205
|
# We do not show CONTENT in order not to pollute log files
|
189
|
206
|
logger.info(self, 'CONFIG: [ {} | {} ]'.format(key, value))
|
|
@@ -193,17 +210,41 @@ class CFG(object):
|
193
|
210
|
self.__dict__[key] = value
|
194
|
211
|
|
195
|
212
|
def __init__(self):
|
|
213
|
+ """Parse configuration file."""
|
|
214
|
+ self.DEPOT_STORAGE_DIR = tg.config.get(
|
|
215
|
+ 'depot_storage_dir',
|
|
216
|
+ )
|
|
217
|
+ self.PREVIEW_CACHE_DIR = tg.config.get(
|
|
218
|
+ 'preview_cache_dir',
|
|
219
|
+ )
|
196
|
220
|
|
197
|
|
- self.PREVIEW_CACHE = str(tg.config.get('preview_cache_dir'))
|
198
|
|
-
|
199
|
|
- self.DATA_UPDATE_ALLOWED_DURATION = int(tg.config.get('content.update.allowed.duration', 0))
|
|
221
|
+ self.DATA_UPDATE_ALLOWED_DURATION = int(tg.config.get(
|
|
222
|
+ 'content.update.allowed.duration',
|
|
223
|
+ 0,
|
|
224
|
+ ))
|
200
|
225
|
|
201
|
|
- self.WEBSITE_TITLE = tg.config.get('website.title', 'TRACIM')
|
202
|
|
- self.WEBSITE_HOME_TITLE_COLOR = tg.config.get('website.title.color', '#555')
|
203
|
|
- self.WEBSITE_HOME_IMAGE_URL = tg.lurl('/assets/img/home_illustration.jpg')
|
204
|
|
- self.WEBSITE_HOME_BACKGROUND_IMAGE_URL = tg.lurl('/assets/img/bg.jpg')
|
205
|
|
- self.WEBSITE_BASE_URL = tg.config.get('website.base_url', '')
|
206
|
|
- self.WEBSITE_SERVER_NAME = tg.config.get('website.server_name', None)
|
|
226
|
+ self.WEBSITE_TITLE = tg.config.get(
|
|
227
|
+ 'website.title',
|
|
228
|
+ 'TRACIM',
|
|
229
|
+ )
|
|
230
|
+ self.WEBSITE_HOME_TITLE_COLOR = tg.config.get(
|
|
231
|
+ 'website.title.color',
|
|
232
|
+ '#555',
|
|
233
|
+ )
|
|
234
|
+ self.WEBSITE_HOME_IMAGE_URL = tg.lurl(
|
|
235
|
+ '/assets/img/home_illustration.jpg',
|
|
236
|
+ )
|
|
237
|
+ self.WEBSITE_HOME_BACKGROUND_IMAGE_URL = tg.lurl(
|
|
238
|
+ '/assets/img/bg.jpg',
|
|
239
|
+ )
|
|
240
|
+ self.WEBSITE_BASE_URL = tg.config.get(
|
|
241
|
+ 'website.base_url',
|
|
242
|
+ '',
|
|
243
|
+ )
|
|
244
|
+ self.WEBSITE_SERVER_NAME = tg.config.get(
|
|
245
|
+ 'website.server_name',
|
|
246
|
+ None,
|
|
247
|
+ )
|
207
|
248
|
|
208
|
249
|
if not self.WEBSITE_SERVER_NAME:
|
209
|
250
|
self.WEBSITE_SERVER_NAME = urlparse(self.WEBSITE_BASE_URL).hostname
|
|
@@ -214,9 +255,18 @@ class CFG(object):
|
214
|
255
|
.format(self.WEBSITE_SERVER_NAME)
|
215
|
256
|
)
|
216
|
257
|
|
217
|
|
- self.WEBSITE_HOME_TAG_LINE = tg.config.get('website.home.tag_line', '')
|
218
|
|
- self.WEBSITE_SUBTITLE = tg.config.get('website.home.subtitle', '')
|
219
|
|
- self.WEBSITE_HOME_BELOW_LOGIN_FORM = tg.config.get('website.home.below_login_form', '')
|
|
258
|
+ self.WEBSITE_HOME_TAG_LINE = tg.config.get(
|
|
259
|
+ 'website.home.tag_line',
|
|
260
|
+ '',
|
|
261
|
+ )
|
|
262
|
+ self.WEBSITE_SUBTITLE = tg.config.get(
|
|
263
|
+ 'website.home.subtitle',
|
|
264
|
+ '',
|
|
265
|
+ )
|
|
266
|
+ self.WEBSITE_HOME_BELOW_LOGIN_FORM = tg.config.get(
|
|
267
|
+ 'website.home.below_login_form',
|
|
268
|
+ '',
|
|
269
|
+ )
|
220
|
270
|
|
221
|
271
|
if tg.config.get('email.notification.from'):
|
222
|
272
|
raise Exception(
|
|
@@ -225,12 +275,18 @@ class CFG(object):
|
225
|
275
|
'email.notification.from.default_label.'
|
226
|
276
|
)
|
227
|
277
|
|
228
|
|
- self.EMAIL_NOTIFICATION_FROM_EMAIL = \
|
229
|
|
- tg.config.get('email.notification.from.email')
|
230
|
|
- self.EMAIL_NOTIFICATION_FROM_DEFAULT_LABEL = \
|
231
|
|
- tg.config.get('email.notification.from.default_label')
|
232
|
|
- self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_HTML = tg.config.get('email.notification.content_update.template.html')
|
233
|
|
- self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_TEXT = tg.config.get('email.notification.content_update.template.text')
|
|
278
|
+ self.EMAIL_NOTIFICATION_FROM_EMAIL = tg.config.get(
|
|
279
|
+ 'email.notification.from.email',
|
|
280
|
+ )
|
|
281
|
+ self.EMAIL_NOTIFICATION_FROM_DEFAULT_LABEL = tg.config.get(
|
|
282
|
+ 'email.notification.from.default_label'
|
|
283
|
+ )
|
|
284
|
+ self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_HTML = tg.config.get(
|
|
285
|
+ 'email.notification.content_update.template.html',
|
|
286
|
+ )
|
|
287
|
+ self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_TEXT = tg.config.get(
|
|
288
|
+ 'email.notification.content_update.template.text',
|
|
289
|
+ )
|
234
|
290
|
self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_HTML = tg.config.get(
|
235
|
291
|
'email.notification.created_account.template.html',
|
236
|
292
|
'./tracim/templates/mail/created_account_body_html.mak',
|
|
@@ -239,24 +295,43 @@ class CFG(object):
|
239
|
295
|
'email.notification.created_account.template.text',
|
240
|
296
|
'./tracim/templates/mail/created_account_body_text.mak',
|
241
|
297
|
)
|
242
|
|
- self.EMAIL_NOTIFICATION_CONTENT_UPDATE_SUBJECT = tg.config.get('email.notification.content_update.subject')
|
|
298
|
+ self.EMAIL_NOTIFICATION_CONTENT_UPDATE_SUBJECT = tg.config.get(
|
|
299
|
+ 'email.notification.content_update.subject',
|
|
300
|
+ )
|
243
|
301
|
self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_SUBJECT = tg.config.get(
|
244
|
302
|
'email.notification.created_account.subject',
|
245
|
303
|
'[{website_title}] Created account',
|
246
|
304
|
)
|
247
|
|
- self.EMAIL_NOTIFICATION_PROCESSING_MODE = tg.config.get('email.notification.processing_mode')
|
248
|
|
-
|
|
305
|
+ self.EMAIL_NOTIFICATION_PROCESSING_MODE = tg.config.get(
|
|
306
|
+ 'email.notification.processing_mode',
|
|
307
|
+ )
|
249
|
308
|
|
250
|
|
- self.EMAIL_NOTIFICATION_ACTIVATED = asbool(tg.config.get('email.notification.activated'))
|
251
|
|
- self.EMAIL_NOTIFICATION_SMTP_SERVER = tg.config.get('email.notification.smtp.server')
|
252
|
|
- self.EMAIL_NOTIFICATION_SMTP_PORT = tg.config.get('email.notification.smtp.port')
|
253
|
|
- self.EMAIL_NOTIFICATION_SMTP_USER = tg.config.get('email.notification.smtp.user')
|
254
|
|
- self.EMAIL_NOTIFICATION_SMTP_PASSWORD = tg.config.get('email.notification.smtp.password')
|
|
309
|
+ self.EMAIL_NOTIFICATION_ACTIVATED = asbool(tg.config.get(
|
|
310
|
+ 'email.notification.activated',
|
|
311
|
+ ))
|
|
312
|
+ self.EMAIL_NOTIFICATION_SMTP_SERVER = tg.config.get(
|
|
313
|
+ 'email.notification.smtp.server',
|
|
314
|
+ )
|
|
315
|
+ self.EMAIL_NOTIFICATION_SMTP_PORT = tg.config.get(
|
|
316
|
+ 'email.notification.smtp.port',
|
|
317
|
+ )
|
|
318
|
+ self.EMAIL_NOTIFICATION_SMTP_USER = tg.config.get(
|
|
319
|
+ 'email.notification.smtp.user',
|
|
320
|
+ )
|
|
321
|
+ self.EMAIL_NOTIFICATION_SMTP_PASSWORD = tg.config.get(
|
|
322
|
+ 'email.notification.smtp.password',
|
|
323
|
+ )
|
255
|
324
|
|
256
|
|
- self.TRACKER_JS_PATH = tg.config.get('js_tracker_path')
|
257
|
|
- self.TRACKER_JS_CONTENT = self.get_tracker_js_content(self.TRACKER_JS_PATH)
|
|
325
|
+ self.TRACKER_JS_PATH = tg.config.get(
|
|
326
|
+ 'js_tracker_path',
|
|
327
|
+ )
|
|
328
|
+ self.TRACKER_JS_CONTENT = self.get_tracker_js_content(
|
|
329
|
+ self.TRACKER_JS_PATH,
|
|
330
|
+ )
|
258
|
331
|
|
259
|
|
- self.WEBSITE_TREEVIEW_CONTENT = tg.config.get('website.treeview.content')
|
|
332
|
+ self.WEBSITE_TREEVIEW_CONTENT = tg.config.get(
|
|
333
|
+ 'website.treeview.content',
|
|
334
|
+ )
|
260
|
335
|
|
261
|
336
|
self.EMAIL_NOTIFICATION_NOTIFIED_EVENTS = [
|
262
|
337
|
ActionDescription.COMMENT,
|
|
@@ -274,12 +349,19 @@ class CFG(object):
|
274
|
349
|
# ContentType.Folder -- Folder is skipped
|
275
|
350
|
]
|
276
|
351
|
|
277
|
|
- self.RADICALE_SERVER_HOST = tg.config.get('radicale.server.host', '0.0.0.0')
|
278
|
|
- self.RADICALE_SERVER_PORT = int(
|
279
|
|
- tg.config.get('radicale.server.port', 5232)
|
|
352
|
+ self.RADICALE_SERVER_HOST = tg.config.get(
|
|
353
|
+ 'radicale.server.host',
|
|
354
|
+ '127.0.0.1',
|
280
|
355
|
)
|
|
356
|
+ self.RADICALE_SERVER_PORT = int(tg.config.get(
|
|
357
|
+ 'radicale.server.port',
|
|
358
|
+ 5232,
|
|
359
|
+ ))
|
281
|
360
|
# Note: Other parameters needed to work in SSL (cert file, etc)
|
282
|
|
- self.RADICALE_SERVER_SSL = asbool(tg.config.get('radicale.server.ssl', False))
|
|
361
|
+ self.RADICALE_SERVER_SSL = asbool(tg.config.get(
|
|
362
|
+ 'radicale.server.ssl',
|
|
363
|
+ False,
|
|
364
|
+ ))
|
283
|
365
|
self.RADICALE_SERVER_FILE_SYSTEM_FOLDER = tg.config.get(
|
284
|
366
|
'radicale.server.filesystem.folder',
|
285
|
367
|
'./radicale/collections',
|
|
@@ -302,11 +384,15 @@ class CFG(object):
|
302
|
384
|
'Tracim Calendar - Password Required',
|
303
|
385
|
)
|
304
|
386
|
|
305
|
|
- self.RADICALE_CLIENT_BASE_URL_HOST = \
|
306
|
|
- tg.config.get('radicale.client.base_url.host', None)
|
|
387
|
+ self.RADICALE_CLIENT_BASE_URL_HOST = tg.config.get(
|
|
388
|
+ 'radicale.client.base_url.host',
|
|
389
|
+ None,
|
|
390
|
+ )
|
307
|
391
|
|
308
|
|
- self.RADICALE_CLIENT_BASE_URL_PREFIX = \
|
309
|
|
- tg.config.get('radicale.client.base_url.prefix', '/')
|
|
392
|
+ self.RADICALE_CLIENT_BASE_URL_PREFIX = tg.config.get(
|
|
393
|
+ 'radicale.client.base_url.prefix',
|
|
394
|
+ '/',
|
|
395
|
+ )
|
310
|
396
|
# Ensure finished by '/'
|
311
|
397
|
if '/' != self.RADICALE_CLIENT_BASE_URL_PREFIX[-1]:
|
312
|
398
|
self.RADICALE_CLIENT_BASE_URL_PREFIX += '/'
|
|
@@ -337,14 +423,18 @@ class CFG(object):
|
337
|
423
|
'wsgidav.config_path',
|
338
|
424
|
'wsgidav.conf',
|
339
|
425
|
)
|
340
|
|
- # TODO: Convert to importlib (cf http://stackoverflow.com/questions/41063938/use-importlib-instead-imp-for-non-py-file)
|
|
426
|
+
|
|
427
|
+ # TODO: Convert to importlib
|
|
428
|
+ # http://stackoverflow.com/questions/41063938/use-importlib-instead-imp-for-non-py-file
|
341
|
429
|
self.wsgidav_config = imp.load_source(
|
342
|
430
|
'wsgidav_config',
|
343
|
431
|
self.WSGIDAV_CONFIG_PATH,
|
344
|
432
|
)
|
345
|
433
|
self.WSGIDAV_PORT = self.wsgidav_config.port
|
346
|
|
- self.WSGIDAV_CLIENT_BASE_URL = \
|
347
|
|
- tg.config.get('wsgidav.client.base_url', None)
|
|
434
|
+ self.WSGIDAV_CLIENT_BASE_URL = tg.config.get(
|
|
435
|
+ 'wsgidav.client.base_url',
|
|
436
|
+ None,
|
|
437
|
+ )
|
348
|
438
|
|
349
|
439
|
if not self.WSGIDAV_CLIENT_BASE_URL:
|
350
|
440
|
self.WSGIDAV_CLIENT_BASE_URL = \
|
|
@@ -395,17 +485,17 @@ class CFG(object):
|
395
|
485
|
0,
|
396
|
486
|
))
|
397
|
487
|
|
398
|
|
- def get_tracker_js_content(self, js_tracker_file_path = None):
|
|
488
|
+ def get_tracker_js_content(self, js_tracker_file_path=None):
|
|
489
|
+ """Get frontend analytics file."""
|
|
490
|
+ result = ''
|
399
|
491
|
js_tracker_file_path = tg.config.get('js_tracker_path', None)
|
400
|
492
|
if js_tracker_file_path:
|
401
|
|
- logger.info(self, 'Reading JS tracking code from file {}'.format(js_tracker_file_path))
|
402
|
|
- with open (js_tracker_file_path, 'r') as js_file:
|
|
493
|
+ info_log = 'Reading JS tracking code from file {}'
|
|
494
|
+ logger.info(self, info_log.format(js_tracker_file_path))
|
|
495
|
+ with open(js_tracker_file_path, 'r') as js_file:
|
403
|
496
|
data = js_file.read()
|
404
|
|
- return data
|
405
|
|
- else:
|
406
|
|
- return ''
|
407
|
|
-
|
408
|
|
-
|
|
497
|
+ result = data
|
|
498
|
+ return result
|
409
|
499
|
|
410
|
500
|
class CST(object):
|
411
|
501
|
ASYNC = 'ASYNC'
|
|
@@ -414,6 +504,7 @@ class CFG(object):
|
414
|
504
|
TREEVIEW_FOLDERS = 'folders'
|
415
|
505
|
TREEVIEW_ALL = 'all'
|
416
|
506
|
|
|
507
|
+
|
417
|
508
|
#######
|
418
|
509
|
#
|
419
|
510
|
# INFO - D.A. - 2014-11-05
|