config.py 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. # -*- coding: utf-8 -*-
  2. from urllib.parse import urlparse
  3. from paste.deploy.converters import asbool
  4. from tracim.lib.utils.logger import logger
  5. from depot.manager import DepotManager
  6. from pyramid.request import Request
  7. class RequestWithCFG(Request):
  8. def app_config(self):
  9. cfg = CFG(self.registry.settings)
  10. #cfg.configure_filedepot()
  11. return cfg
  12. class CFG(object):
  13. """Object used for easy access to config file parameters."""
  14. def __setattr__(self, key, value):
  15. """
  16. Log-ready setter.
  17. Logs all configuration parameters except password.
  18. :param key:
  19. :param value:
  20. :return:
  21. """
  22. if 'PASSWORD' not in key and \
  23. ('URL' not in key or type(value) == str) and \
  24. 'CONTENT' not in key:
  25. # We do not show PASSWORD for security reason
  26. # we do not show URL because At the time of configuration setup,
  27. # it can't be evaluated
  28. # We do not show CONTENT in order not to pollute log files
  29. logger.info(self, 'CONFIG: [ {} | {} ]'.format(key, value))
  30. else:
  31. logger.info(self, 'CONFIG: [ {} | <value not shown> ]'.format(key))
  32. self.__dict__[key] = value
  33. def __init__(self, settings):
  34. """Parse configuration file."""
  35. ###
  36. # General
  37. ###
  38. mandatory_msg = \
  39. 'ERROR: {} configuration is mandatory. Set it before continuing.'
  40. self.DEPOT_STORAGE_DIR = settings.get(
  41. 'depot_storage_dir',
  42. )
  43. if not self.DEPOT_STORAGE_DIR:
  44. raise Exception(
  45. mandatory_msg.format('depot_storage_dir')
  46. )
  47. self.DEPOT_STORAGE_NAME = settings.get(
  48. 'depot_storage_name',
  49. )
  50. if not self.DEPOT_STORAGE_NAME:
  51. raise Exception(
  52. mandatory_msg.format('depot_storage_name')
  53. )
  54. self.PREVIEW_CACHE_DIR = settings.get(
  55. 'preview_cache_dir',
  56. )
  57. if not self.PREVIEW_CACHE_DIR:
  58. raise Exception(
  59. 'ERROR: preview_cache_dir configuration is mandatory. '
  60. 'Set it before continuing.'
  61. )
  62. self.DATA_UPDATE_ALLOWED_DURATION = int(settings.get(
  63. 'content.update.allowed.duration',
  64. 0,
  65. ))
  66. self.WEBSITE_TITLE = settings.get(
  67. 'website.title',
  68. 'TRACIM',
  69. )
  70. self.WEBSITE_BASE_URL = settings.get(
  71. 'website.base_url',
  72. '',
  73. )
  74. # TODO - G.M - 26-03-2018 - [Cleanup] These params seems deprecated for tracimv2, # nopep8
  75. # Verify this
  76. #
  77. # self.WEBSITE_HOME_TITLE_COLOR = settings.get(
  78. # 'website.title.color',
  79. # '#555',
  80. # )
  81. # self.WEBSITE_HOME_IMAGE_PATH = settings.get(
  82. # '/assets/img/home_illustration.jpg',
  83. # )
  84. # self.WEBSITE_HOME_BACKGROUND_IMAGE_PATH = settings.get(
  85. # '/assets/img/bg.jpg',
  86. # )
  87. #
  88. self.WEBSITE_SERVER_NAME = settings.get(
  89. 'website.server_name',
  90. None,
  91. )
  92. if not self.WEBSITE_SERVER_NAME:
  93. self.WEBSITE_SERVER_NAME = urlparse(self.WEBSITE_BASE_URL).hostname
  94. logger.warning(
  95. self,
  96. 'NOTE: Generated website.server_name parameter from '
  97. 'website.base_url parameter -> {0}'
  98. .format(self.WEBSITE_SERVER_NAME)
  99. )
  100. self.WEBSITE_HOME_TAG_LINE = settings.get(
  101. 'website.home.tag_line',
  102. '',
  103. )
  104. self.WEBSITE_SUBTITLE = settings.get(
  105. 'website.home.subtitle',
  106. '',
  107. )
  108. self.WEBSITE_HOME_BELOW_LOGIN_FORM = settings.get(
  109. 'website.home.below_login_form',
  110. '',
  111. )
  112. self.WEBSITE_TREEVIEW_CONTENT = settings.get(
  113. 'website.treeview.content',
  114. )
  115. self.USER_AUTH_TOKEN_VALIDITY = int(settings.get(
  116. 'user.auth_token.validity',
  117. '604800',
  118. ))
  119. # TODO - G.M - 27-03-2018 - [Email] Restore email config
  120. ###
  121. # EMAIL related stuff (notification, reply)
  122. ###
  123. #
  124. # self.EMAIL_NOTIFICATION_NOTIFIED_EVENTS = [
  125. # # ActionDescription.COMMENT,
  126. # # ActionDescription.CREATION,
  127. # # ActionDescription.EDITION,
  128. # # ActionDescription.REVISION,
  129. # # ActionDescription.STATUS_UPDATE
  130. # ]
  131. #
  132. # self.EMAIL_NOTIFICATION_NOTIFIED_CONTENTS = [
  133. # # ContentType.Page,
  134. # # ContentType.Thread,
  135. # # ContentType.File,
  136. # # ContentType.Comment,
  137. # # ContentType.Folder -- Folder is skipped
  138. # ]
  139. # if settings.get('email.notification.from'):
  140. # raise Exception(
  141. # 'email.notification.from configuration is deprecated. '
  142. # 'Use instead email.notification.from.email and '
  143. # 'email.notification.from.default_label.'
  144. # )
  145. #
  146. # self.EMAIL_NOTIFICATION_FROM_EMAIL = settings.get(
  147. # 'email.notification.from.email',
  148. # )
  149. # self.EMAIL_NOTIFICATION_FROM_DEFAULT_LABEL = settings.get(
  150. # 'email.notification.from.default_label'
  151. # )
  152. # self.EMAIL_NOTIFICATION_REPLY_TO_EMAIL = settings.get(
  153. # 'email.notification.reply_to.email',
  154. # )
  155. # self.EMAIL_NOTIFICATION_REFERENCES_EMAIL = settings.get(
  156. # 'email.notification.references.email'
  157. # )
  158. # self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_HTML = settings.get(
  159. # 'email.notification.content_update.template.html',
  160. # )
  161. # self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_TEXT = settings.get(
  162. # 'email.notification.content_update.template.text',
  163. # )
  164. # self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_HTML = settings.get(
  165. # 'email.notification.created_account.template.html',
  166. # './tracim/templates/mail/created_account_body_html.mak',
  167. # )
  168. # self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_TEXT = settings.get(
  169. # 'email.notification.created_account.template.text',
  170. # './tracim/templates/mail/created_account_body_text.mak',
  171. # )
  172. # self.EMAIL_NOTIFICATION_CONTENT_UPDATE_SUBJECT = settings.get(
  173. # 'email.notification.content_update.subject',
  174. # )
  175. # self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_SUBJECT = settings.get(
  176. # 'email.notification.created_account.subject',
  177. # '[{website_title}] Created account',
  178. # )
  179. # self.EMAIL_NOTIFICATION_PROCESSING_MODE = settings.get(
  180. # 'email.notification.processing_mode',
  181. # )
  182. #
  183. self.EMAIL_NOTIFICATION_ACTIVATED = asbool(settings.get(
  184. 'email.notification.activated',
  185. ))
  186. # self.EMAIL_NOTIFICATION_SMTP_SERVER = settings.get(
  187. # 'email.notification.smtp.server',
  188. # )
  189. # self.EMAIL_NOTIFICATION_SMTP_PORT = settings.get(
  190. # 'email.notification.smtp.port',
  191. # )
  192. # self.EMAIL_NOTIFICATION_SMTP_USER = settings.get(
  193. # 'email.notification.smtp.user',
  194. # )
  195. # self.EMAIL_NOTIFICATION_SMTP_PASSWORD = settings.get(
  196. # 'email.notification.smtp.password',
  197. # )
  198. # self.EMAIL_NOTIFICATION_LOG_FILE_PATH = settings.get(
  199. # 'email.notification.log_file_path',
  200. # None,
  201. # )
  202. #
  203. # self.EMAIL_REPLY_ACTIVATED = asbool(settings.get(
  204. # 'email.reply.activated',
  205. # False,
  206. # ))
  207. #
  208. # self.EMAIL_REPLY_IMAP_SERVER = settings.get(
  209. # 'email.reply.imap.server',
  210. # )
  211. # self.EMAIL_REPLY_IMAP_PORT = settings.get(
  212. # 'email.reply.imap.port',
  213. # )
  214. # self.EMAIL_REPLY_IMAP_USER = settings.get(
  215. # 'email.reply.imap.user',
  216. # )
  217. # self.EMAIL_REPLY_IMAP_PASSWORD = settings.get(
  218. # 'email.reply.imap.password',
  219. # )
  220. # self.EMAIL_REPLY_IMAP_FOLDER = settings.get(
  221. # 'email.reply.imap.folder',
  222. # )
  223. # self.EMAIL_REPLY_CHECK_HEARTBEAT = int(settings.get(
  224. # 'email.reply.check.heartbeat',
  225. # 60,
  226. # ))
  227. # self.EMAIL_REPLY_TOKEN = settings.get(
  228. # 'email.reply.token',
  229. # )
  230. # self.EMAIL_REPLY_IMAP_USE_SSL = asbool(settings.get(
  231. # 'email.reply.imap.use_ssl',
  232. # ))
  233. # self.EMAIL_REPLY_IMAP_USE_IDLE = asbool(settings.get(
  234. # 'email.reply.imap.use_idle',
  235. # True,
  236. # ))
  237. # self.EMAIL_REPLY_CONNECTION_MAX_LIFETIME = int(settings.get(
  238. # 'email.reply.connection.max_lifetime',
  239. # 600, # 10 minutes
  240. # ))
  241. # self.EMAIL_REPLY_USE_HTML_PARSING = asbool(settings.get(
  242. # 'email.reply.use_html_parsing',
  243. # True,
  244. # ))
  245. # self.EMAIL_REPLY_USE_TXT_PARSING = asbool(settings.get(
  246. # 'email.reply.use_txt_parsing',
  247. # True,
  248. # ))
  249. # self.EMAIL_REPLY_LOCKFILE_PATH = settings.get(
  250. # 'email.reply.lockfile_path',
  251. # ''
  252. # )
  253. # if not self.EMAIL_REPLY_LOCKFILE_PATH and self.EMAIL_REPLY_ACTIVATED:
  254. # raise Exception(
  255. # mandatory_msg.format('email.reply.lockfile_path')
  256. # )
  257. #
  258. # self.EMAIL_PROCESSING_MODE = settings.get(
  259. # 'email.processing_mode',
  260. # 'sync',
  261. # ).upper()
  262. #
  263. # if self.EMAIL_PROCESSING_MODE not in (
  264. # self.CST.ASYNC,
  265. # self.CST.SYNC,
  266. # ):
  267. # raise Exception(
  268. # 'email.processing_mode '
  269. # 'can ''be "{}" or "{}", not "{}"'.format(
  270. # self.CST.ASYNC,
  271. # self.CST.SYNC,
  272. # self.EMAIL_PROCESSING_MODE,
  273. # )
  274. # )
  275. #
  276. # self.EMAIL_SENDER_REDIS_HOST = settings.get(
  277. # 'email.async.redis.host',
  278. # 'localhost',
  279. # )
  280. # self.EMAIL_SENDER_REDIS_PORT = int(settings.get(
  281. # 'email.async.redis.port',
  282. # 6379,
  283. # ))
  284. # self.EMAIL_SENDER_REDIS_DB = int(settings.get(
  285. # 'email.async.redis.db',
  286. # 0,
  287. # ))
  288. ###
  289. # WSGIDAV (Webdav server)
  290. ###
  291. # TODO - G.M - 27-03-2018 - [WebDav] Restore wsgidav config
  292. #self.WSGIDAV_CONFIG_PATH = settings.get(
  293. # 'wsgidav.config_path',
  294. # 'wsgidav.conf',
  295. #)
  296. # TODO: Convert to importlib
  297. # http://stackoverflow.com/questions/41063938/use-importlib-instead-imp-for-non-py-file
  298. #self.wsgidav_config = imp.load_source(
  299. # 'wsgidav_config',
  300. # self.WSGIDAV_CONFIG_PATH,
  301. #)
  302. # self.WSGIDAV_PORT = self.wsgidav_config.port
  303. # self.WSGIDAV_CLIENT_BASE_URL = settings.get(
  304. # 'wsgidav.client.base_url',
  305. # None,
  306. # )
  307. #
  308. # if not self.WSGIDAV_CLIENT_BASE_URL:
  309. # self.WSGIDAV_CLIENT_BASE_URL = \
  310. # '{0}:{1}'.format(
  311. # self.WEBSITE_SERVER_NAME,
  312. # self.WSGIDAV_PORT,
  313. # )
  314. # logger.warning(self,
  315. # 'NOTE: Generated wsgidav.client.base_url parameter with '
  316. # 'followings parameters: website.server_name and '
  317. # 'wsgidav.conf port'.format(
  318. # self.WSGIDAV_CLIENT_BASE_URL,
  319. # )
  320. # )
  321. #
  322. # if not self.WSGIDAV_CLIENT_BASE_URL.endswith('/'):
  323. # self.WSGIDAV_CLIENT_BASE_URL += '/'
  324. # TODO - G.M - 27-03-2018 - [Caldav] Restore radicale config
  325. ###
  326. # RADICALE (Caldav server)
  327. ###
  328. # self.RADICALE_SERVER_HOST = settings.get(
  329. # 'radicale.server.host',
  330. # '127.0.0.1',
  331. # )
  332. # self.RADICALE_SERVER_PORT = int(settings.get(
  333. # 'radicale.server.port',
  334. # 5232,
  335. # ))
  336. # # Note: Other parameters needed to work in SSL (cert file, etc)
  337. # self.RADICALE_SERVER_SSL = asbool(settings.get(
  338. # 'radicale.server.ssl',
  339. # False,
  340. # ))
  341. # self.RADICALE_SERVER_FILE_SYSTEM_FOLDER = settings.get(
  342. # 'radicale.server.filesystem.folder',
  343. # )
  344. # if not self.RADICALE_SERVER_FILE_SYSTEM_FOLDER:
  345. # raise Exception(
  346. # mandatory_msg.format('radicale.server.filesystem.folder')
  347. # )
  348. # self.RADICALE_SERVER_ALLOW_ORIGIN = settings.get(
  349. # 'radicale.server.allow_origin',
  350. # None,
  351. # )
  352. # if not self.RADICALE_SERVER_ALLOW_ORIGIN:
  353. # self.RADICALE_SERVER_ALLOW_ORIGIN = self.WEBSITE_BASE_URL
  354. # logger.warning(self,
  355. # 'NOTE: Generated radicale.server.allow_origin parameter with '
  356. # 'followings parameters: website.base_url ({0})'
  357. # .format(self.WEBSITE_BASE_URL)
  358. # )
  359. #
  360. # self.RADICALE_SERVER_REALM_MESSAGE = settings.get(
  361. # 'radicale.server.realm_message',
  362. # 'Tracim Calendar - Password Required',
  363. # )
  364. #
  365. # self.RADICALE_CLIENT_BASE_URL_HOST = settings.get(
  366. # 'radicale.client.base_url.host',
  367. # 'http://{}:{}'.format(
  368. # self.RADICALE_SERVER_HOST,
  369. # self.RADICALE_SERVER_PORT,
  370. # ),
  371. # )
  372. #
  373. # self.RADICALE_CLIENT_BASE_URL_PREFIX = settings.get(
  374. # 'radicale.client.base_url.prefix',
  375. # '/',
  376. # )
  377. # # Ensure finished by '/'
  378. # if '/' != self.RADICALE_CLIENT_BASE_URL_PREFIX[-1]:
  379. # self.RADICALE_CLIENT_BASE_URL_PREFIX += '/'
  380. # if '/' != self.RADICALE_CLIENT_BASE_URL_PREFIX[0]:
  381. # self.RADICALE_CLIENT_BASE_URL_PREFIX \
  382. # = '/' + self.RADICALE_CLIENT_BASE_URL_PREFIX
  383. #
  384. # if not self.RADICALE_CLIENT_BASE_URL_HOST:
  385. # logger.warning(self,
  386. # 'Generated radicale.client.base_url.host parameter with '
  387. # 'followings parameters: website.server_name -> {}'
  388. # .format(self.WEBSITE_SERVER_NAME)
  389. # )
  390. # self.RADICALE_CLIENT_BASE_URL_HOST = self.WEBSITE_SERVER_NAME
  391. #
  392. # self.RADICALE_CLIENT_BASE_URL_TEMPLATE = '{}{}'.format(
  393. # self.RADICALE_CLIENT_BASE_URL_HOST,
  394. # self.RADICALE_CLIENT_BASE_URL_PREFIX,
  395. # )
  396. def configure_filedepot(self):
  397. depot_storage_name = self.DEPOT_STORAGE_NAME
  398. depot_storage_path = self.DEPOT_STORAGE_DIR
  399. depot_storage_settings = {'depot.storage_path': depot_storage_path}
  400. DepotManager.configure(
  401. depot_storage_name,
  402. depot_storage_settings,
  403. )
  404. class CST(object):
  405. ASYNC = 'ASYNC'
  406. SYNC = 'SYNC'
  407. TREEVIEW_FOLDERS = 'folders'
  408. TREEVIEW_ALL = 'all'