示例#1
0
文件: predicates.py 项目: qyqx/tracim
 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()
示例#2
0
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
示例#3
0
 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__()))
示例#4
0
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
示例#5
0
文件: app_cfg.py 项目: qyqx/tracim
    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,
            ))
示例#6
0
 def append_thread_callback(self, callback: collections.Callable) -> None:
     logger.warning('MailSenderDaemon not implement append_thread_callback')
     pass
示例#7
0
    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')
示例#8
0
    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)))
示例#9
0
    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)
示例#10
0
文件: app_cfg.py 项目: buxx/tracim
    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,
                )
            )
示例#11
0
    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,
        ))