def evaluate(self, environ, credentials): # Comment next line if you want to activate the debug controller try: current_user = tmpl_context.current_user workspace = tmpl_context.workspace if workspace.get_user_role(current_user)>= self.minimal_role_level(): return except Exception as e: logger.warning(self, 'Exception catched: {}'.format(e.__str__)) self.unmet() self.unmet()
def is_item_still_editable(CFG, item): if item.type.id != 'comment': return False # HACK - D.A - 2014-12-24 - item contains a datetime object!!! # 'item' is a variable which is created by serialization and it should be an instance of DictLikeClass. # therefore, it contains strins, integers and booleans (something json-ready or almost json-ready) # # BUT, the property 'created' is still a datetime object # edit_duration = CFG.get_instance().DATA_UPDATE_ALLOWED_DURATION if edit_duration<0: return True elif edit_duration==0: return False else: time_limit = item.created + datetime.timedelta(0, edit_duration) logger.warning(is_item_still_editable, 'limit is: {}'.format(time_limit)) if datetime.datetime.now() < time_limit: return True return False
def run(self) -> None: logger.info(self, 'Starting MailFetcher') while self._is_active: logger.debug(self, 'sleep for {}'.format(self.delay)) time.sleep(self.delay) try: self._connect() with self.lock.acquire(timeout=MAIL_FETCHER_FILELOCK_TIMEOUT): messages = self._fetch() cleaned_mails = [ DecodedMail(m.message, m.uid) for m in messages ] self._notify_tracim(cleaned_mails) self._disconnect() except filelock.Timeout as e: log = 'Mail Fetcher Lock Timeout {}' logger.warning(self, log.format(e.__str__())) except Exception as e: # TODO - G.M - 2017-11-23 - Identify possible exceptions log = 'IMAP error: {}' logger.warning(self, log.format(e.__str__()))
def is_item_still_editable(CFG, item): if item.type.id != 'comment': return False # HACK - D.A - 2014-12-24 - item contains a datetime object!!! # 'item' is a variable which is created by serialization and it should be an instance of DictLikeClass. # therefore, it contains strins, integers and booleans (something json-ready or almost json-ready) # # BUT, the property 'created' is still a datetime object # edit_duration = CFG.get_instance().DATA_UPDATE_ALLOWED_DURATION if edit_duration < 0: return True elif edit_duration == 0: return False else: time_limit = item.created + datetime.timedelta(0, edit_duration) logger.warning(is_item_still_editable, 'limit is: {}'.format(time_limit)) if datetime.datetime.now() < time_limit: return True return False
def __init__(self): self.PREVIEW_CACHE = str(tg.config.get('preview_cache_dir')) self.DATA_UPDATE_ALLOWED_DURATION = int( tg.config.get('content.update.allowed.duration', 0)) self.WEBSITE_TITLE = tg.config.get('website.title', 'TRACIM') self.WEBSITE_HOME_TITLE_COLOR = tg.config.get('website.title.color', '#555') self.WEBSITE_HOME_IMAGE_URL = tg.lurl( '/assets/img/home_illustration.jpg') self.WEBSITE_HOME_BACKGROUND_IMAGE_URL = tg.lurl('/assets/img/bg.jpg') self.WEBSITE_BASE_URL = tg.config.get('website.base_url', '') self.WEBSITE_SERVER_NAME = tg.config.get('website.server_name', None) if not self.WEBSITE_SERVER_NAME: self.WEBSITE_SERVER_NAME = urlparse(self.WEBSITE_BASE_URL).hostname logger.warning( self, 'NOTE: Generated website.server_name parameter from ' 'website.base_url parameter -> {0}'.format( self.WEBSITE_SERVER_NAME)) self.WEBSITE_HOME_TAG_LINE = tg.config.get('website.home.tag_line', '') self.WEBSITE_SUBTITLE = tg.config.get('website.home.subtitle', '') self.WEBSITE_HOME_BELOW_LOGIN_FORM = tg.config.get( 'website.home.below_login_form', '') if tg.config.get('email.notification.from'): raise Exception( 'email.notification.from configuration is deprecated. ' 'Use instead email.notification.from.email and ' 'email.notification.from.default_label.') self.EMAIL_NOTIFICATION_FROM_EMAIL = \ tg.config.get('email.notification.from.email') self.EMAIL_NOTIFICATION_FROM_DEFAULT_LABEL = \ tg.config.get('email.notification.from.default_label') self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_HTML = tg.config.get( 'email.notification.content_update.template.html') self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_TEXT = tg.config.get( 'email.notification.content_update.template.text') self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_HTML = tg.config.get( 'email.notification.created_account.template.html', './tracim/templates/mail/created_account_body_html.mak', ) self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_TEXT = tg.config.get( 'email.notification.created_account.template.text', './tracim/templates/mail/created_account_body_text.mak', ) self.EMAIL_NOTIFICATION_CONTENT_UPDATE_SUBJECT = tg.config.get( 'email.notification.content_update.subject') self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_SUBJECT = tg.config.get( 'email.notification.created_account.subject', '[{website_title}] Created account', ) self.EMAIL_NOTIFICATION_PROCESSING_MODE = tg.config.get( 'email.notification.processing_mode') self.EMAIL_NOTIFICATION_ACTIVATED = asbool( tg.config.get('email.notification.activated')) self.EMAIL_NOTIFICATION_SMTP_SERVER = tg.config.get( 'email.notification.smtp.server') self.EMAIL_NOTIFICATION_SMTP_PORT = tg.config.get( 'email.notification.smtp.port') self.EMAIL_NOTIFICATION_SMTP_USER = tg.config.get( 'email.notification.smtp.user') self.EMAIL_NOTIFICATION_SMTP_PASSWORD = tg.config.get( 'email.notification.smtp.password') self.TRACKER_JS_PATH = tg.config.get('js_tracker_path') self.TRACKER_JS_CONTENT = self.get_tracker_js_content( self.TRACKER_JS_PATH) self.WEBSITE_TREEVIEW_CONTENT = tg.config.get( 'website.treeview.content') self.EMAIL_NOTIFICATION_NOTIFIED_EVENTS = [ ActionDescription.COMMENT, ActionDescription.CREATION, ActionDescription.EDITION, ActionDescription.REVISION, ActionDescription.STATUS_UPDATE ] self.EMAIL_NOTIFICATION_NOTIFIED_CONTENTS = [ ContentType.Page, ContentType.Thread, ContentType.File, ContentType.Comment, # ContentType.Folder -- Folder is skipped ] self.RADICALE_SERVER_HOST = tg.config.get('radicale.server.host', '0.0.0.0') self.RADICALE_SERVER_PORT = int( tg.config.get('radicale.server.port', 5232)) # Note: Other parameters needed to work in SSL (cert file, etc) self.RADICALE_SERVER_SSL = asbool( tg.config.get('radicale.server.ssl', False)) self.RADICALE_SERVER_FILE_SYSTEM_FOLDER = tg.config.get( 'radicale.server.filesystem.folder', './radicale/collections', ) self.RADICALE_SERVER_ALLOW_ORIGIN = tg.config.get( 'radicale.server.allow_origin', None, ) if not self.RADICALE_SERVER_ALLOW_ORIGIN: self.RADICALE_SERVER_ALLOW_ORIGIN = self.WEBSITE_BASE_URL logger.warning( self, 'NOTE: Generated radicale.server.allow_origin parameter with ' 'followings parameters: website.base_url ({0})'.format( self.WEBSITE_BASE_URL)) self.RADICALE_SERVER_REALM_MESSAGE = tg.config.get( 'radicale.server.realm_message', 'Tracim Calendar - Password Required', ) self.RADICALE_CLIENT_BASE_URL_HOST = \ tg.config.get('radicale.client.base_url.host', None) self.RADICALE_CLIENT_BASE_URL_PREFIX = \ tg.config.get('radicale.client.base_url.prefix', '/') # Ensure finished by '/' if '/' != self.RADICALE_CLIENT_BASE_URL_PREFIX[-1]: self.RADICALE_CLIENT_BASE_URL_PREFIX += '/' if '/' != self.RADICALE_CLIENT_BASE_URL_PREFIX[0]: self.RADICALE_CLIENT_BASE_URL_PREFIX \ = '/' + self.RADICALE_CLIENT_BASE_URL_PREFIX if not self.RADICALE_CLIENT_BASE_URL_HOST: logger.warning( self, 'Generated radicale.client.base_url.host parameter with ' 'followings parameters: website.server_name -> {}'.format( self.WEBSITE_SERVER_NAME)) self.RADICALE_CLIENT_BASE_URL_HOST = self.WEBSITE_SERVER_NAME self.RADICALE_CLIENT_BASE_URL_TEMPLATE = '{}{}'.format( self.RADICALE_CLIENT_BASE_URL_HOST, self.RADICALE_CLIENT_BASE_URL_PREFIX, ) self.USER_AUTH_TOKEN_VALIDITY = int( tg.config.get( 'user.auth_token.validity', '604800', )) self.WSGIDAV_CONFIG_PATH = tg.config.get( 'wsgidav.config_path', 'wsgidav.conf', ) # TODO: Convert to importlib (cf http://stackoverflow.com/questions/41063938/use-importlib-instead-imp-for-non-py-file) self.wsgidav_config = imp.load_source( 'wsgidav_config', self.WSGIDAV_CONFIG_PATH, ) self.WSGIDAV_PORT = self.wsgidav_config.port self.WSGIDAV_CLIENT_BASE_URL = \ tg.config.get('wsgidav.client.base_url', None) if not self.WSGIDAV_CLIENT_BASE_URL: self.WSGIDAV_CLIENT_BASE_URL = \ '{0}:{1}'.format( self.WEBSITE_SERVER_NAME, self.WSGIDAV_PORT, ) logger.warning( self, 'NOTE: Generated wsgidav.client.base_url parameter with ' 'followings parameters: website.server_name and ' 'wsgidav.conf port'.format(self.WSGIDAV_CLIENT_BASE_URL, )) if not self.WSGIDAV_CLIENT_BASE_URL.endswith('/'): self.WSGIDAV_CLIENT_BASE_URL += '/' self.EMAIL_PROCESSING_MODE = tg.config.get( 'email.processing_mode', 'sync', ).upper() if self.EMAIL_PROCESSING_MODE not in ( self.CST.ASYNC, self.CST.SYNC, ): raise Exception('email.processing_mode ' 'can ' 'be "{}" or "{}", not "{}"'.format( self.CST.ASYNC, self.CST.SYNC, self.EMAIL_PROCESSING_MODE, )) self.EMAIL_SENDER_REDIS_HOST = tg.config.get( 'email.async.redis.host', 'localhost', ) self.EMAIL_SENDER_REDIS_PORT = int( tg.config.get( 'email.async.redis.port', 6379, )) self.EMAIL_SENDER_REDIS_DB = int( tg.config.get( 'email.async.redis.db', 0, ))
def append_thread_callback(self, callback: collections.Callable) -> None: logger.warning('MailSenderDaemon not implement append_thread_callback') pass
def __init__(self): self.DATA_UPDATE_ALLOWED_DURATION = int( tg.config.get('content.update.allowed.duration', 0)) self.WEBSITE_TITLE = tg.config.get('website.title', 'TRACIM') self.WEBSITE_HOME_TITLE_COLOR = tg.config.get('website.title.color', '#555') self.WEBSITE_HOME_IMAGE_URL = tg.lurl( '/assets/img/home_illustration.jpg') self.WEBSITE_HOME_BACKGROUND_IMAGE_URL = tg.lurl('/assets/img/bg.jpg') self.WEBSITE_BASE_URL = tg.config.get('website.base_url', '') self.WEBSITE_SERVER_NAME = tg.config.get('website.server_name', None) if not self.WEBSITE_SERVER_NAME: self.WEBSITE_SERVER_NAME = urlparse(self.WEBSITE_BASE_URL).hostname logger.warning( self, 'NOTE: Generated website.server_name parameter from ' 'website.base_url parameter -> {0}'.format( self.WEBSITE_SERVER_NAME)) self.WEBSITE_HOME_TAG_LINE = tg.config.get('website.home.tag_line', '') self.WEBSITE_SUBTITLE = tg.config.get('website.home.subtitle', '') self.WEBSITE_HOME_BELOW_LOGIN_FORM = tg.config.get( 'website.home.below_login_form', '') self.EMAIL_NOTIFICATION_FROM = tg.config.get('email.notification.from') self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_HTML = tg.config.get( 'email.notification.content_update.template.html') self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_TEXT = tg.config.get( 'email.notification.content_update.template.text') self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_HTML = tg.config.get( 'email.notification.created_account.template.html', './tracim/templates/mail/created_account_body_html.mak', ) self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_TEXT = tg.config.get( 'email.notification.created_account.template.text', './tracim/templates/mail/created_account_body_text.mak', ) self.EMAIL_NOTIFICATION_CONTENT_UPDATE_SUBJECT = tg.config.get( 'email.notification.content_update.subject') self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_SUBJECT = tg.config.get( 'email.notification.created_account.subject', '[{website_title}] Created account', ) self.EMAIL_NOTIFICATION_PROCESSING_MODE = tg.config.get( 'email.notification.processing_mode') self.EMAIL_NOTIFICATION_ACTIVATED = asbool( tg.config.get('email.notification.activated')) self.EMAIL_NOTIFICATION_SMTP_SERVER = tg.config.get( 'email.notification.smtp.server') self.EMAIL_NOTIFICATION_SMTP_PORT = tg.config.get( 'email.notification.smtp.port') self.EMAIL_NOTIFICATION_SMTP_USER = tg.config.get( 'email.notification.smtp.user') self.EMAIL_NOTIFICATION_SMTP_PASSWORD = tg.config.get( 'email.notification.smtp.password') self.TRACKER_JS_PATH = tg.config.get('js_tracker_path') self.TRACKER_JS_CONTENT = self.get_tracker_js_content( self.TRACKER_JS_PATH) self.WEBSITE_TREEVIEW_CONTENT = tg.config.get( 'website.treeview.content') self.EMAIL_NOTIFICATION_NOTIFIED_EVENTS = [ ActionDescription.COMMENT, ActionDescription.CREATION, ActionDescription.EDITION, ActionDescription.REVISION, ActionDescription.STATUS_UPDATE ] self.EMAIL_NOTIFICATION_NOTIFIED_CONTENTS = [ ContentType.Page, ContentType.Thread, ContentType.File, ContentType.Comment, # ContentType.Folder -- Folder is skipped ] self.RADICALE_SERVER_HOST = tg.config.get('radicale.server.host', '0.0.0.0') self.RADICALE_SERVER_PORT = int( tg.config.get('radicale.server.port', 5232)) # Note: Other parameters needed to work in SSL (cert file, etc) self.RADICALE_SERVER_SSL = asbool( tg.config.get('radicale.server.ssl', False)) self.RADICALE_SERVER_FILE_SYSTEM_FOLDER = tg.config.get( 'radicale.server.filesystem.folder', '~/.config/radicale/collections') self.RADICALE_SERVER_ALLOW_ORIGIN = tg.config.get( 'radicale.server.allow_origin', None, ) if not self.RADICALE_SERVER_ALLOW_ORIGIN: self.RADICALE_SERVER_ALLOW_ORIGIN = self.WEBSITE_BASE_URL logger.warning( self, 'NOTE: Generated radicale.server.allow_origin parameter with ' 'followings parameters: website.base_url ({0})'.format( self.WEBSITE_BASE_URL)) self.RADICALE_SERVER_REALM_MESSAGE = tg.config.get( 'radicale.server.realm_message', 'Tracim Calendar - Password Required', ) self.RADICALE_CLIENT_BASE_URL_TEMPLATE = \ tg.config.get('radicale.client.base_url', None) if not self.RADICALE_CLIENT_BASE_URL_TEMPLATE: self.RADICALE_CLIENT_BASE_URL_TEMPLATE = \ 'http://{0}:{1}'.format( self.WEBSITE_SERVER_NAME, self.RADICALE_SERVER_PORT, ) logger.warning( self, 'NOTE: Generated radicale.client.base_url parameter with ' 'followings parameters: website.server_name, ' 'radicale.server.port -> {0}'.format( self.RADICALE_CLIENT_BASE_URL_TEMPLATE)) self.USER_AUTH_TOKEN_VALIDITY = int( tg.config.get( 'user.auth_token.validity', '604800', )) self.WSGIDAV_CONFIG_PATH = tg.config.get('wsgidav.config_path')
def _notify_tracim(self, mails: typing.List[DecodedMail], imapc: imapclient.IMAPClient) -> None: """ Send http request to tracim endpoint :param mails: list of mails to send :return: none """ logger.debug( self, 'Notify tracim about {} new responses'.format(len(mails), )) # TODO BS 20171124: Look around mail.get_from_address(), mail.get_key() # , mail.get_body() etc ... for raise InvalidEmailError if missing # required informations (actually get_from_address raise IndexError # if no from address for example) and catch it here while mails: mail = mails.pop() body = mail.get_body( use_html_parsing=self.use_html_parsing, use_txt_parsing=self.use_txt_parsing, ) from_address = mail.get_from_address() # don't create element for 'empty' mail if not body: logger.warning( self, 'Mail from {} has not valable content'.format( from_address), ) continue msg = { 'token': self.token, 'user_mail': from_address, 'content_id': mail.get_key(), 'payload': { 'content': body, } } try: logger.debug( self, 'Contact API on {} with body {}'.format( self.endpoint, json.dumps(msg), ), ) r = requests.post(self.endpoint, json=msg) if r.status_code not in [200, 204]: details = r.json().get('msg') log = 'bad status code {} response when sending mail to tracim: {}' # nopep8 logger.error(self, log.format( str(r.status_code), details, )) # Flag all correctly checked mail if r.status_code in [200, 204, 400]: imapc.add_flags((mail.uid, ), IMAP_CHECKED_FLAG) imapc.add_flags((mail.uid, ), IMAP_SEEN_FLAG) # TODO - G.M - Verify exception correctly works except requests.exceptions.Timeout as e: log = 'Timeout error to transmit fetched mail to tracim : {}' logger.error(self, log.format(str(e))) except requests.exceptions.RequestException as e: log = 'Fail to transmit fetched mail to tracim : {}' logger.error(self, log.format(str(e)))
def run(self) -> None: logger.info(self, 'Starting MailFetcher') while self._is_active: imapc = None sleep_after_connection = True try: imapc = imapclient.IMAPClient( self.host, self.port, ssl=self.use_ssl, timeout=MAIL_FETCHER_CONNECTION_TIMEOUT) imapc.login(self.user, self.password) logger.debug(self, 'Select folder {}'.format(self.folder, )) imapc.select_folder(self.folder) # force renew connection when deadline is reached deadline = time.time() + self.connection_max_lifetime while True: if not self._is_active: logger.warning(self, 'Mail Fetcher process aborted') sleep_after_connection = False break if time.time() > deadline: logger.debug( self, "MailFetcher Connection Lifetime limit excess" ", Try Re-new connection") sleep_after_connection = False break # check for new mails self._check_mail(imapc) if self.use_idle and imapc.has_capability('IDLE'): # IDLE_mode wait until event from server logger.debug(self, 'wail for event(IDLE)') imapc.idle() imapc.idle_check( timeout=MAIL_FETCHER_IDLE_RESPONSE_TIMEOUT) imapc.idle_done() else: if self.use_idle and not imapc.has_capability('IDLE'): log = 'IDLE mode activated but server do not' \ 'support it, use polling instead.' logger.warning(self, log) # normal polling mode : sleep a define duration logger.debug(self, 'sleep for {}'.format(self.heartbeat)) time.sleep(self.heartbeat) # Socket except (socket.error, socket.gaierror, socket.herror) as e: log = 'Socket fail with IMAP connection {}' logger.error(self, log.format(e.__str__())) except socket.timeout as e: log = 'Socket timeout on IMAP connection {}' logger.error(self, log.format(e.__str__())) # SSL except ssl.SSLError as e: log = 'SSL error on IMAP connection' logger.error(self, log.format(e.__str__())) except ssl.CertificateError as e: log = 'SSL Certificate verification failed on IMAP connection' logger.error(self, log.format(e.__str__())) # Filelock except filelock.Timeout as e: log = 'Mail Fetcher Lock Timeout {}' logger.warning(self, log.format(e.__str__())) # IMAP # TODO - G.M - 10-01-2017 - Support imapclient exceptions # when Imapclient stable will be 2.0+ except BadIMAPFetchResponse as e: log = 'Imap Fetch command return bad response.' \ 'Is someone else connected to the mailbox ?: ' \ '{}' logger.error(self, log.format(e.__str__())) # Others except Exception as e: log = 'Mail Fetcher error {}' logger.error(self, log.format(e.__str__())) finally: # INFO - G.M - 2018-01-09 - Connection closing # Properly close connection according to # https://github.com/mjs/imapclient/pull/279/commits/043e4bd0c5c775c5a08cb5f1baa93876a46732ee # TODO : Use __exit__ method instead when imapclient stable will # be 2.0+ . if imapc: logger.debug(self, 'Try logout') try: imapc.logout() except Exception: try: imapc.shutdown() except Exception as e: log = "Can't logout, connection broken ? {}" logger.error(self, log.format(e.__str__())) if sleep_after_connection: logger.debug(self, 'sleep for {}'.format(self.heartbeat)) time.sleep(self.heartbeat) log = 'Mail Fetcher stopped' logger.debug(self, log)
def __init__(self): self.DATA_UPDATE_ALLOWED_DURATION = int(tg.config.get('content.update.allowed.duration', 0)) self.WEBSITE_TITLE = tg.config.get('website.title', 'TRACIM') self.WEBSITE_HOME_TITLE_COLOR = tg.config.get('website.title.color', '#555') self.WEBSITE_HOME_IMAGE_URL = tg.lurl('/assets/img/home_illustration.jpg') self.WEBSITE_HOME_BACKGROUND_IMAGE_URL = tg.lurl('/assets/img/bg.jpg') self.WEBSITE_BASE_URL = tg.config.get('website.base_url', '') self.WEBSITE_SERVER_NAME = tg.config.get('website.server_name', None) if not self.WEBSITE_SERVER_NAME: self.WEBSITE_SERVER_NAME = urlparse(self.WEBSITE_BASE_URL).hostname logger.warning( self, 'NOTE: Generated website.server_name parameter from ' 'website.base_url parameter -> {0}' .format(self.WEBSITE_SERVER_NAME) ) self.WEBSITE_HOME_TAG_LINE = tg.config.get('website.home.tag_line', '') self.WEBSITE_SUBTITLE = tg.config.get('website.home.subtitle', '') self.WEBSITE_HOME_BELOW_LOGIN_FORM = tg.config.get('website.home.below_login_form', '') self.EMAIL_NOTIFICATION_FROM = tg.config.get('email.notification.from') self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_HTML = tg.config.get('email.notification.content_update.template.html') self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_TEXT = tg.config.get('email.notification.content_update.template.text') self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_HTML = tg.config.get( 'email.notification.created_account.template.html', './tracim/templates/mail/created_account_body_html.mak', ) self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_TEXT = tg.config.get( 'email.notification.created_account.template.text', './tracim/templates/mail/created_account_body_text.mak', ) self.EMAIL_NOTIFICATION_CONTENT_UPDATE_SUBJECT = tg.config.get('email.notification.content_update.subject') self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_SUBJECT = tg.config.get( 'email.notification.created_account.subject', '[{website_title}] Created account', ) self.EMAIL_NOTIFICATION_PROCESSING_MODE = tg.config.get('email.notification.processing_mode') self.EMAIL_NOTIFICATION_ACTIVATED = asbool(tg.config.get('email.notification.activated')) self.EMAIL_NOTIFICATION_SMTP_SERVER = tg.config.get('email.notification.smtp.server') self.EMAIL_NOTIFICATION_SMTP_PORT = tg.config.get('email.notification.smtp.port') self.EMAIL_NOTIFICATION_SMTP_USER = tg.config.get('email.notification.smtp.user') self.EMAIL_NOTIFICATION_SMTP_PASSWORD = tg.config.get('email.notification.smtp.password') self.TRACKER_JS_PATH = tg.config.get('js_tracker_path') self.TRACKER_JS_CONTENT = self.get_tracker_js_content(self.TRACKER_JS_PATH) self.WEBSITE_TREEVIEW_CONTENT = tg.config.get('website.treeview.content') self.EMAIL_NOTIFICATION_NOTIFIED_EVENTS = [ ActionDescription.COMMENT, ActionDescription.CREATION, ActionDescription.EDITION, ActionDescription.REVISION, ActionDescription.STATUS_UPDATE ] self.EMAIL_NOTIFICATION_NOTIFIED_CONTENTS = [ ContentType.Page, ContentType.Thread, ContentType.File, ContentType.Comment, # ContentType.Folder -- Folder is skipped ] self.RADICALE_SERVER_HOST = tg.config.get('radicale.server.host', '0.0.0.0') self.RADICALE_SERVER_PORT = int( tg.config.get('radicale.server.port', 5232) ) # Note: Other parameters needed to work in SSL (cert file, etc) self.RADICALE_SERVER_SSL = asbool(tg.config.get('radicale.server.ssl', False)) self.RADICALE_SERVER_FILE_SYSTEM_FOLDER = tg.config.get( 'radicale.server.filesystem.folder', '~/.config/radicale/collections' ) self.RADICALE_SERVER_ALLOW_ORIGIN = tg.config.get( 'radicale.server.allow_origin', None, ) if not self.RADICALE_SERVER_ALLOW_ORIGIN: self.RADICALE_SERVER_ALLOW_ORIGIN = self.WEBSITE_BASE_URL logger.warning( self, 'NOTE: Generated radicale.server.allow_origin parameter with ' 'followings parameters: website.base_url ({0})' .format(self.WEBSITE_BASE_URL) ) self.RADICALE_SERVER_REALM_MESSAGE = tg.config.get( 'radicale.server.realm_message', 'Tracim Calendar - Password Required', ) self.RADICALE_CLIENT_BASE_URL_TEMPLATE = \ tg.config.get('radicale.client.base_url', None) if not self.RADICALE_CLIENT_BASE_URL_TEMPLATE: self.RADICALE_CLIENT_BASE_URL_TEMPLATE = \ 'http://{0}:{1}'.format( self.WEBSITE_SERVER_NAME, self.RADICALE_SERVER_PORT, ) logger.warning( self, 'NOTE: Generated radicale.client.base_url parameter with ' 'followings parameters: website.server_name, ' 'radicale.server.port -> {0}' .format(self.RADICALE_CLIENT_BASE_URL_TEMPLATE) ) self.USER_AUTH_TOKEN_VALIDITY = int(tg.config.get( 'user.auth_token.validity', '604800', )) self.WSGIDAV_CONFIG_PATH = tg.config.get( 'wsgidav.config_path', 'wsgidav.conf', ) # TODO: Convert to importlib (cf http://stackoverflow.com/questions/41063938/use-importlib-instead-imp-for-non-py-file) self.wsgidav_config = imp.load_source( 'wsgidav_config', self.WSGIDAV_CONFIG_PATH, ) self.WSGIDAV_PORT = self.wsgidav_config.port self.WSGIDAV_CLIENT_BASE_URL = \ tg.config.get('wsgidav.client.base_url', None) if not self.WSGIDAV_CLIENT_BASE_URL: self.WSGIDAV_CLIENT_BASE_URL = \ '{0}:{1}'.format( self.WEBSITE_SERVER_NAME, self.WSGIDAV_PORT, ) logger.warning( self, 'NOTE: Generated wsgidav.client.base_url parameter with ' 'followings parameters: website.server_name and ' 'wsgidav.conf port'.format( self.WSGIDAV_CLIENT_BASE_URL, ) )
def __init__(self): """Parse configuration file.""" mandatory_msg = \ 'ERROR: {} configuration is mandatory. Set it before continuing.' self.DEPOT_STORAGE_DIR = tg.config.get( 'depot_storage_dir', ) if not self.DEPOT_STORAGE_DIR: raise Exception( mandatory_msg.format('depot_storage_dir') ) self.DEPOT_STORAGE_NAME = tg.config.get( 'depot_storage_name', ) if not self.DEPOT_STORAGE_NAME: raise Exception( mandatory_msg.format('depot_storage_name') ) self.PREVIEW_CACHE_DIR = tg.config.get( 'preview_cache_dir', ) if not self.PREVIEW_CACHE_DIR: raise Exception( 'ERROR: preview_cache_dir configuration is mandatory. ' 'Set it before continuing.' ) self.DATA_UPDATE_ALLOWED_DURATION = int(tg.config.get( 'content.update.allowed.duration', 0, )) self.WEBSITE_TITLE = tg.config.get( 'website.title', 'TRACIM', ) self.WEBSITE_HOME_TITLE_COLOR = tg.config.get( 'website.title.color', '#555', ) self.WEBSITE_HOME_IMAGE_URL = tg.lurl( '/assets/img/home_illustration.jpg', ) self.WEBSITE_HOME_BACKGROUND_IMAGE_URL = tg.lurl( '/assets/img/bg.jpg', ) self.WEBSITE_BASE_URL = tg.config.get( 'website.base_url', '', ) self.WEBSITE_SERVER_NAME = tg.config.get( 'website.server_name', None, ) if not self.WEBSITE_SERVER_NAME: self.WEBSITE_SERVER_NAME = urlparse(self.WEBSITE_BASE_URL).hostname logger.warning( self, 'NOTE: Generated website.server_name parameter from ' 'website.base_url parameter -> {0}' .format(self.WEBSITE_SERVER_NAME) ) self.WEBSITE_HOME_TAG_LINE = tg.config.get( 'website.home.tag_line', '', ) self.WEBSITE_SUBTITLE = tg.config.get( 'website.home.subtitle', '', ) self.WEBSITE_HOME_BELOW_LOGIN_FORM = tg.config.get( 'website.home.below_login_form', '', ) if tg.config.get('email.notification.from'): raise Exception( 'email.notification.from configuration is deprecated. ' 'Use instead email.notification.from.email and ' 'email.notification.from.default_label.' ) self.EMAIL_NOTIFICATION_FROM_EMAIL = tg.config.get( 'email.notification.from.email', ) self.EMAIL_NOTIFICATION_FROM_DEFAULT_LABEL = tg.config.get( 'email.notification.from.default_label' ) self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_HTML = tg.config.get( 'email.notification.content_update.template.html', ) self.EMAIL_NOTIFICATION_CONTENT_UPDATE_TEMPLATE_TEXT = tg.config.get( 'email.notification.content_update.template.text', ) self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_HTML = tg.config.get( 'email.notification.created_account.template.html', './tracim/templates/mail/created_account_body_html.mak', ) self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_TEXT = tg.config.get( 'email.notification.created_account.template.text', './tracim/templates/mail/created_account_body_text.mak', ) self.EMAIL_NOTIFICATION_CONTENT_UPDATE_SUBJECT = tg.config.get( 'email.notification.content_update.subject', ) self.EMAIL_NOTIFICATION_CREATED_ACCOUNT_SUBJECT = tg.config.get( 'email.notification.created_account.subject', '[{website_title}] Created account', ) self.EMAIL_NOTIFICATION_PROCESSING_MODE = tg.config.get( 'email.notification.processing_mode', ) self.EMAIL_NOTIFICATION_ACTIVATED = asbool(tg.config.get( 'email.notification.activated', )) self.EMAIL_NOTIFICATION_SMTP_SERVER = tg.config.get( 'email.notification.smtp.server', ) self.EMAIL_NOTIFICATION_SMTP_PORT = tg.config.get( 'email.notification.smtp.port', ) self.EMAIL_NOTIFICATION_SMTP_USER = tg.config.get( 'email.notification.smtp.user', ) self.EMAIL_NOTIFICATION_SMTP_PASSWORD = tg.config.get( 'email.notification.smtp.password', ) self.EMAIL_NOTIFICATION_LOG_FILE_PATH = tg.config.get( 'email.notification.log_file_path', None, ) self.TRACKER_JS_PATH = tg.config.get( 'js_tracker_path', ) self.TRACKER_JS_CONTENT = self.get_tracker_js_content( self.TRACKER_JS_PATH, ) self.WEBSITE_TREEVIEW_CONTENT = tg.config.get( 'website.treeview.content', ) self.EMAIL_NOTIFICATION_NOTIFIED_EVENTS = [ ActionDescription.COMMENT, ActionDescription.CREATION, ActionDescription.EDITION, ActionDescription.REVISION, ActionDescription.STATUS_UPDATE ] self.EMAIL_NOTIFICATION_NOTIFIED_CONTENTS = [ ContentType.Page, ContentType.Thread, ContentType.File, ContentType.Comment, # ContentType.Folder -- Folder is skipped ] self.RADICALE_SERVER_HOST = tg.config.get( 'radicale.server.host', '127.0.0.1', ) self.RADICALE_SERVER_PORT = int(tg.config.get( 'radicale.server.port', 5232, )) # Note: Other parameters needed to work in SSL (cert file, etc) self.RADICALE_SERVER_SSL = asbool(tg.config.get( 'radicale.server.ssl', False, )) self.RADICALE_SERVER_FILE_SYSTEM_FOLDER = tg.config.get( 'radicale.server.filesystem.folder', ) if not self.RADICALE_SERVER_FILE_SYSTEM_FOLDER: raise Exception( mandatory_msg.format('radicale.server.filesystem.folder') ) self.RADICALE_SERVER_ALLOW_ORIGIN = tg.config.get( 'radicale.server.allow_origin', None, ) if not self.RADICALE_SERVER_ALLOW_ORIGIN: self.RADICALE_SERVER_ALLOW_ORIGIN = self.WEBSITE_BASE_URL logger.warning( self, 'NOTE: Generated radicale.server.allow_origin parameter with ' 'followings parameters: website.base_url ({0})' .format(self.WEBSITE_BASE_URL) ) self.RADICALE_SERVER_REALM_MESSAGE = tg.config.get( 'radicale.server.realm_message', 'Tracim Calendar - Password Required', ) self.RADICALE_CLIENT_BASE_URL_HOST = tg.config.get( 'radicale.client.base_url.host', 'http://{}:{}'.format( self.RADICALE_SERVER_HOST, self.RADICALE_SERVER_PORT, ), ) self.RADICALE_CLIENT_BASE_URL_PREFIX = tg.config.get( 'radicale.client.base_url.prefix', '/', ) # Ensure finished by '/' if '/' != self.RADICALE_CLIENT_BASE_URL_PREFIX[-1]: self.RADICALE_CLIENT_BASE_URL_PREFIX += '/' if '/' != self.RADICALE_CLIENT_BASE_URL_PREFIX[0]: self.RADICALE_CLIENT_BASE_URL_PREFIX \ = '/' + self.RADICALE_CLIENT_BASE_URL_PREFIX if not self.RADICALE_CLIENT_BASE_URL_HOST: logger.warning( self, 'Generated radicale.client.base_url.host parameter with ' 'followings parameters: website.server_name -> {}' .format(self.WEBSITE_SERVER_NAME) ) self.RADICALE_CLIENT_BASE_URL_HOST = self.WEBSITE_SERVER_NAME self.RADICALE_CLIENT_BASE_URL_TEMPLATE = '{}{}'.format( self.RADICALE_CLIENT_BASE_URL_HOST, self.RADICALE_CLIENT_BASE_URL_PREFIX, ) self.USER_AUTH_TOKEN_VALIDITY = int(tg.config.get( 'user.auth_token.validity', '604800', )) self.WSGIDAV_CONFIG_PATH = tg.config.get( 'wsgidav.config_path', 'wsgidav.conf', ) # TODO: Convert to importlib # http://stackoverflow.com/questions/41063938/use-importlib-instead-imp-for-non-py-file self.wsgidav_config = imp.load_source( 'wsgidav_config', self.WSGIDAV_CONFIG_PATH, ) self.WSGIDAV_PORT = self.wsgidav_config.port self.WSGIDAV_CLIENT_BASE_URL = tg.config.get( 'wsgidav.client.base_url', None, ) if not self.WSGIDAV_CLIENT_BASE_URL: self.WSGIDAV_CLIENT_BASE_URL = \ '{0}:{1}'.format( self.WEBSITE_SERVER_NAME, self.WSGIDAV_PORT, ) logger.warning( self, 'NOTE: Generated wsgidav.client.base_url parameter with ' 'followings parameters: website.server_name and ' 'wsgidav.conf port'.format( self.WSGIDAV_CLIENT_BASE_URL, ) ) if not self.WSGIDAV_CLIENT_BASE_URL.endswith('/'): self.WSGIDAV_CLIENT_BASE_URL += '/' self.EMAIL_PROCESSING_MODE = tg.config.get( 'email.processing_mode', 'sync', ).upper() if self.EMAIL_PROCESSING_MODE not in ( self.CST.ASYNC, self.CST.SYNC, ): raise Exception( 'email.processing_mode ' 'can ''be "{}" or "{}", not "{}"'.format( self.CST.ASYNC, self.CST.SYNC, self.EMAIL_PROCESSING_MODE, ) ) self.EMAIL_SENDER_REDIS_HOST = tg.config.get( 'email.async.redis.host', 'localhost', ) self.EMAIL_SENDER_REDIS_PORT = int(tg.config.get( 'email.async.redis.port', 6379, )) self.EMAIL_SENDER_REDIS_DB = int(tg.config.get( 'email.async.redis.db', 0, ))