<commit_before>from datetime import datetime
import logging
import pkgutil

import pytz
import babel
from babel import Locale
import babel.dates
import formencode
from pylons.i18n import _
from pylons.i18n import add_fallback, set_lang
from pylons import config, tmpl_context as c

from adhocracy.lib import cache

log = logging.getLogger(__name__)

LOCALES = [babel.Locale('de', 'DE'),
           babel.Locale('en', 'US'),
           babel.Locale('fr', 'FR'),
           babel.Locale('it', 'IT'),
           babel.Locale('nl', 'NL'),
           babel.Locale('pl', 'PL'),
           babel.Locale('pt', 'BR'),
           babel.Locale('ro', 'RO'),
           babel.Locale('ru', 'RU')]

LOCALE_STRINGS = map(str, LOCALES)

FALLBACK_TZ = 'Europe/Berlin'

@cache.memoize('_translations_root')
def _get_translations_root():
    translations_module = config.get('adhocracy.translations', 'adhocracy')
    translations_module_loader = pkgutil.get_loader(translations_module)
    if translations_module_loader is None:
        raise ValueError(('Cannot import the module "%s" configured for '
                          '"adhocracy.translations". Make sure it is an '
                          'importable module (and contains the '
                          'translation files in a subdirectory '
                          '"i18n"') % translations_module)

    return translations_module_loader.filename

def get_default_locale():
    try:
        if c.instance and c.instance.locale:
            return c.instance.locale
        locale = config.get('adhocracy.language', 'en_US')
        return babel.Locale.parse(locale)
    except TypeError:
        return babel.Locale.parse('en_US')

def handle_request():
    """
    Given a request, try to determine the appropriate locale to use for the
    request. When a user is logged in, his or her settings will first be
    queried.
    Otherwise, an appropriate locale will be negotiated between the browser
    accept headers and the available locales.
    """
    from pylons import request, tmpl_context as c

    try:
        al = request.accept_language
        request_languages = [lang for lang, q in
                             sorted(al._parsed, key=lambda lq: -lq[1])]
    except AttributeError:
        # request.languages fails if no accept_language is set
        # becaues of incompatibility between WebOb >= 1.1.1 and Paste-1.7.5.1
        request_languages = []
    c.locale = user_language(c.user, request_languages)

def user_language(user, fallbacks=[]):
    # find out the locale
    locale = None
    if user and user.locale:
        locale = user.locale

    if locale is None:
        locale = Locale.parse(Locale.negotiate(fallbacks, LOCALE_STRINGS)) \
            or get_default_locale()

    # determinate from which path we load the translations
    translations_config = {'pylons.paths': {'root': _get_translations_root()},
                           'pylons.package': config.get('pylons.package')}

    # set language and fallback
    set_lang(locale.language, pylons_config=translations_config)
    add_fallback(get_default_locale().language,
                 pylons_config=translations_config)
    formencode.api.set_stdtranslation(domain="FormEncode",
                                      languages=[locale.language])
    return locale

def countdown_time(dt, default):
    # THIS IS A HACK TO GET RID OF BABEL
    if dt is not None:
        delta = dt - datetime.utcnow()
        default = delta.days
    return _("%d days") % default

def local_datetime(dt):
    """
    Calculates a datetime object with the configured timezone information set
    from a given datetime ``dt``.
    """
    tz_setting = config.get('adhocracy.timezone', FALLBACK_TZ)
    try:
        tz = pytz.timezone(tz_setting)
    except pytz.UnknownTimeZoneError:
        log.warn('Invalid time zone setting: %s' % tz_setting)
        tz = pytz.timezone(FALLBACK_TZ)

    if dt.tzinfo is None:
        return tz.fromutc(dt)
    else:
        return dt.astimezone(tz)

def format_date(dt, set_timezone=True, format=None):
    '''
    Format the date in a local aware format.
    '''
    from pylons import tmpl_context as c
    if format is None:
        format = u'long'
    if set_timezone:
        dt = local_datetime(dt)
    return babel.dates.format_date(dt, format=format, locale=c.locale or
                                   babel.Locale('en', 'US'))

def format_time(dt, set_timezone=True, format=None):
    '''
    Format the date in a local aware format.
    '''
    from pylons import tmpl_context as c
    if format is None:
        format = u'short'
    if set_timezone:
        dt = local_datetime(dt)
    return babel.dates.format_time(dt, format=format, locale=c.locale or
                                   babel.Locale('en', 'US'))

def date_tag(dt, format=None):
    """ Display a <time> html tag for the given datetime ``dt``. """
    fmt = "<time datetime='%(iso)s'>%(formatted)s</time>"
    dt = dt.replace(microsecond=0)
    dt = local_datetime(dt)

    formatted = format_date(dt, False, format)
    return fmt % dict(iso=dt.isoformat(), formatted=formatted)

def datetime_tag(dt):
    """
    Display a <time> html tag for the given datetime ``dt``.
    """
    fmt = "<time class='ts' datetime='%(iso)s'>%(formatted)s</time>"
    dt = dt.replace(microsecond=0)
    tz_dt = local_datetime(dt)

    formatted = "%s %s" % (format_date(dt), format_time(dt))
    return fmt % dict(iso=tz_dt.isoformat(), formatted=formatted)
<commit_msg>Take locale territory into account<commit_after>from datetime import datetime
import logging
import pkgutil

import pytz
import babel
from babel import Locale
import babel.dates
import formencode
from pylons.i18n import _
from pylons.i18n import add_fallback, set_lang
from pylons import config, tmpl_context as c

from adhocracy.lib import cache

log = logging.getLogger(__name__)

LOCALES = [babel.Locale('de', 'DE'),
           babel.Locale('en', 'US'),
           babel.Locale('fr', 'FR'),
           babel.Locale('it', 'IT'),
           babel.Locale('nl', 'NL'),
           babel.Locale('pl', 'PL'),
           babel.Locale('pt', 'BR'),
           babel.Locale('ro', 'RO'),
           babel.Locale('ru', 'RU')]

LOCALE_STRINGS = map(str, LOCALES)

FALLBACK_TZ = 'Europe/Berlin'

@cache.memoize('_translations_root')
def _get_translations_root():
    translations_module = config.get('adhocracy.translations', 'adhocracy')
    translations_module_loader = pkgutil.get_loader(translations_module)
    if translations_module_loader is None:
        raise ValueError(('Cannot import the module "%s" configured for '
                          '"adhocracy.translations". Make sure it is an '
                          'importable module (and contains the '
                          'translation files in a subdirectory '
                          '"i18n"') % translations_module)

    return translations_module_loader.filename

def get_default_locale():
    try:
        if c.instance and c.instance.locale:
            return c.instance.locale
        locale = config.get('adhocracy.language', 'en_US')
        return babel.Locale.parse(locale)
    except TypeError:
        return babel.Locale.parse('en_US')

def handle_request():
    """
    Given a request, try to determine the appropriate locale to use for the
    request. When a user is logged in, his or her settings will first be
    queried.
    Otherwise, an appropriate locale will be negotiated between the browser
    accept headers and the available locales.
    """
    from pylons import request, tmpl_context as c

    try:
        al = request.accept_language
        request_languages = [lang for lang, q in
                             sorted(al._parsed, key=lambda lq: -lq[1])]
    except AttributeError:
        # request.languages fails if no accept_language is set
        # becaues of incompatibility between WebOb >= 1.1.1 and Paste-1.7.5.1
        request_languages = []
    c.locale = user_language(c.user, request_languages)

def user_language(user, fallbacks=[]):
    # find out the locale
    locale = None
    if user and user.locale:
        locale = user.locale

    if locale is None:
        locale = Locale.parse(Locale.negotiate(fallbacks, LOCALE_STRINGS)) \
            or get_default_locale()

    # determinate from which path we load the translations
    translations_config = {'pylons.paths': {'root': _get_translations_root()},
                           'pylons.package': config.get('pylons.package')}

    # set language and fallback
    set_lang(str(locale), pylons_config=translations_config)
    add_fallback(get_default_locale().language,
                 pylons_config=translations_config)
    formencode.api.set_stdtranslation(domain="FormEncode",
                                      languages=[locale.language])
    return locale

def countdown_time(dt, default):
    # THIS IS A HACK TO GET RID OF BABEL
    if dt is not None:
        delta = dt - datetime.utcnow()
        default = delta.days
    return _("%d days") % default

def local_datetime(dt):
    """
    Calculates a datetime object with the configured timezone information set
    from a given datetime ``dt``.
    """
    tz_setting = config.get('adhocracy.timezone', FALLBACK_TZ)
    try:
        tz = pytz.timezone(tz_setting)
    except pytz.UnknownTimeZoneError:
        log.warn('Invalid time zone setting: %s' % tz_setting)
        tz = pytz.timezone(FALLBACK_TZ)

    if dt.tzinfo is None:
        return tz.fromutc(dt)
    else:
        return dt.astimezone(tz)

def format_date(dt, set_timezone=True, format=None):
    '''
    Format the date in a local aware format.
    '''
    from pylons import tmpl_context as c
    if format is None:
        format = u'long'
    if set_timezone:
        dt = local_datetime(dt)
    return babel.dates.format_date(dt, format=format, locale=c.locale or
                                   babel.Locale('en', 'US'))

def format_time(dt, set_timezone=True, format=None):
    '''
    Format the date in a local aware format.
    '''
    from pylons import tmpl_context as c
    if format is None:
        format = u'short'
    if set_timezone:
        dt = local_datetime(dt)
    return babel.dates.format_time(dt, format=format, locale=c.locale or
                                   babel.Locale('en', 'US'))

def date_tag(dt, format=None):
    """ Display a <time> html tag for the given datetime ``dt``. """
    fmt = "<time datetime='%(iso)s'>%(formatted)s</time>"
    dt = dt.replace(microsecond=0)
    dt = local_datetime(dt)

    formatted = format_date(dt, False, format)
    return fmt % dict(iso=dt.isoformat(), formatted=formatted)

def datetime_tag(dt):
    """
    Display a <time> html tag for the given datetime ``dt``.
    """
    fmt = "<time class='ts' datetime='%(iso)s'>%(formatted)s</time>"
    dt = dt.replace(microsecond=0)
    tz_dt = local_datetime(dt)

    formatted = "%s %s" % (format_date(dt), format_time(dt))
    return fmt % dict(iso=tz_dt.isoformat(), formatted=formatted)
<|endoftext|>


<commit_before>"""Accessors for Amber TI datasets.

"""

from os.path import dirname, join
from os import listdir
from glob import glob

from .. import Bunch

def load_bace_improper():
    """Load Amber Bace improper solvated vdw example

    Returns
    -------
    data: Bunch
        Dictionary-like object, the interesting attributes are:

        - 'data' : the data files for improper solvated vdw alchemical leg

    """
    module_path = dirname(__file__)
    data = {'vdw': glob(join(module_path, 'bace_improper/solvated/vdw/*/ti-*.out.bz2'))}

    with open(join(module_path, 'bace_improper', 'descr.rst')) as rst_file:
        fdescr = rst_file.read()

    return Bunch(data=data,
                 DESCR=fdescr)

def load_bace_example():
    """Load Amber Bace example perturbation.

    Returns
    -------
    data: Bunch
        Dictionary-like object, the interesting attributes are:

        - 'data' : the data files by system and alchemical leg

    """
    module_path = dirname(__file__)
    data = {'complex':
                {'decharge': glob(join(module_path, 'bace_CAT-13d~CAT-17a/complex/decharge/*/ti-*.out.bz2')),
                 'recharge': glob(join(module_path, 'bace_CAT-13d~CAT-17a/complex/recharge/*/ti-*.out.bz2')),
                 'vdw': glob(join(module_path, 'bace_CAT-13d~CAT-17a/complex/vdw/*/ti-*.out.bz2'))
                 },
            'solvated':
                {'decharge': glob(join(module_path, 'bace_CAT-13d~CAT-17a/solvated/decharge/*/ti-*.out.bz2')),
                 'recharge': glob(join(module_path, 'bace_CAT-13d~CAT-17a/solvated/recharge/*/ti-*.out.bz2')),
                 'vdw': glob(join(module_path, 'bace_CAT-13d~CAT-17a/solvated/vdw/*/ti-*.out.bz2'))
                 }
            }

    with open(join(module_path, 'bace_CAT-13d~CAT-17a', 'descr.rst')) as rst_file:
        fdescr = rst_file.read()

    return Bunch(data=data,
                 DESCR=fdescr)

def load_simplesolvated():
    """Load the Amber solvated dataset.

    Returns
    -------
    data : Bunch
        Dictionary-like object, the interesting attributes are:

        - 'data' : the data files by alchemical leg
        - 'DESCR': the full description of the dataset

    """

    module_path = dirname(__file__)
    data = {'charge': glob(join(module_path, 'simplesolvated/charge/*/ti-*.tar.bz2')),
            'vdw': glob(join(module_path, 'simplesolvated/vdw/*/ti-*.tar.bz2'))}

    with open(join(module_path, 'simplesolvated', 'descr.rst')) as rst_file:
        fdescr = rst_file.read()

    return Bunch(data=data,
                 DESCR=fdescr)

def load_invalidfiles():
    """Load the invalid files.

    Returns
    -------
    data : Bunch
        Dictionary-like object, the interesting attributes are:

        - 'data' : the example of invalid data files
        - 'DESCR': the full description of the dataset

    .. deprecated:: 0.7
       use :func:`load_testfiles` instead

    """

    import warnings
    warnings.warn(
        "load_invalidfiles() was deprecated in 0.7.0 and will be removed in the following release."
        " Use load_testfiles() instead",
        DeprecationWarning)
    module_path = dirname(__file__)
    data = [
        glob(join(module_path, 'testfiles', 'no_useful_data.out.tar.bz2')),
        glob(join(module_path, 'testfiles', 'no_control_data.out.tar.bz2')),
        glob(join(module_path, 'testfiles', 'no_temp0_setted.out.tar.bz2')),
        glob(join(module_path, 'testfiles', 'no_free_energy_info.out.tar.bz2')),
        glob(join(module_path, 'testfiles', 'no_atomic_section.out.tar.bz2')),
        glob(join(module_path, 'testfiles', 'no_results_section.out.tar.bz2'))]

    with open(join(module_path, 'testfiles', 'descr_invalid.rst')) as rst_file:
        fdescr = rst_file.read()

    return Bunch(data=data,
                 DESCR=fdescr)

def load_testfiles():
    """Load incomplete-wrongly formatted files to be used to test the AMBER parsers.

    Returns
    -------
    data : Bunch
        Dictionary-like object, the interesting attributes are:

        - 'data' : the data files
        - 'DESCR': the full description of all the files

    """

    module_path = dirname(__file__)

    data = {}
    for f in listdir(join(module_path, 'testfiles')):
        if f.endswith('bz2'):
            data[f[:-12]] = [join(module_path, 'testfiles', f)]

    with open(join(module_path, 'testfiles', 'descr.rst')) as rst_file:
        fdescr = rst_file.read()

    return Bunch(data=data,
                 DESCR=fdescr)
<commit_msg>edited docstring of load_testfiles<commit_after>"""Accessors for Amber TI datasets.

"""

from os.path import dirname, join
from os import listdir
from glob import glob

from .. import Bunch

def load_bace_improper():
    """Load Amber Bace improper solvated vdw example

    Returns
    -------
    data: Bunch
        Dictionary-like object, the interesting attributes are:

        - 'data' : the data files for improper solvated vdw alchemical leg

    """
    module_path = dirname(__file__)
    data = {'vdw': glob(join(module_path, 'bace_improper/solvated/vdw/*/ti-*.out.bz2'))}

    with open(join(module_path, 'bace_improper', 'descr.rst')) as rst_file:
        fdescr = rst_file.read()

    return Bunch(data=data,
                 DESCR=fdescr)

def load_bace_example():
    """Load Amber Bace example perturbation.

    Returns
    -------
    data: Bunch
        Dictionary-like object, the interesting attributes are:

        - 'data' : the data files by system and alchemical leg

    """
    module_path = dirname(__file__)
    data = {'complex':
                {'decharge': glob(join(module_path, 'bace_CAT-13d~CAT-17a/complex/decharge/*/ti-*.out.bz2')),
                 'recharge': glob(join(module_path, 'bace_CAT-13d~CAT-17a/complex/recharge/*/ti-*.out.bz2')),
                 'vdw': glob(join(module_path, 'bace_CAT-13d~CAT-17a/complex/vdw/*/ti-*.out.bz2'))
                 },
            'solvated':
                {'decharge': glob(join(module_path, 'bace_CAT-13d~CAT-17a/solvated/decharge/*/ti-*.out.bz2')),
                 'recharge': glob(join(module_path, 'bace_CAT-13d~CAT-17a/solvated/recharge/*/ti-*.out.bz2')),
                 'vdw': glob(join(module_path, 'bace_CAT-13d~CAT-17a/solvated/vdw/*/ti-*.out.bz2'))
                 }
            }

    with open(join(module_path, 'bace_CAT-13d~CAT-17a', 'descr.rst')) as rst_file:
        fdescr = rst_file.read()

    return Bunch(data=data,
                 DESCR=fdescr)

def load_simplesolvated():
    """Load the Amber solvated dataset.

    Returns
    -------
    data : Bunch
        Dictionary-like object, the interesting attributes are:

        - 'data' : the data files by alchemical leg
        - 'DESCR': the full description of the dataset

    """

    module_path = dirname(__file__)
    data = {'charge': glob(join(module_path, 'simplesolvated/charge/*/ti-*.tar.bz2')),
            'vdw': glob(join(module_path, 'simplesolvated/vdw/*/ti-*.tar.bz2'))}

    with open(join(module_path, 'simplesolvated', 'descr.rst')) as rst_file:
        fdescr = rst_file.read()

    return Bunch(data=data,
                 DESCR=fdescr)

def load_invalidfiles():
    """Load the invalid files.

    Returns
    -------
    data : Bunch
        Dictionary-like object, the interesting attributes are:

        - 'data' : the example of invalid data files
        - 'DESCR': the full description of the dataset

    .. deprecated:: 0.7
       use :func:`load_testfiles` instead

    """

    import warnings
    warnings.warn(
        "load_invalidfiles() was deprecated in 0.7.0 and will be removed in the following release."
        " Use load_testfiles() instead",
        DeprecationWarning)
    module_path = dirname(__file__)
    data = [
        glob(join(module_path, 'testfiles', 'no_useful_data.out.tar.bz2')),
        glob(join(module_path, 'testfiles', 'no_control_data.out.tar.bz2')),
        glob(join(module_path, 'testfiles', 'no_temp0_setted.out.tar.bz2')),
        glob(join(module_path, 'testfiles', 'no_free_energy_info.out.tar.bz2')),
        glob(join(module_path, 'testfiles', 'no_atomic_section.out.tar.bz2')),
        glob(join(module_path, 'testfiles', 'no_results_section.out.tar.bz2'))]

    with open(join(module_path, 'testfiles', 'descr_invalid.rst')) as rst_file:
        fdescr = rst_file.read()

    return Bunch(data=data,
                 DESCR=fdescr)

def load_testfiles():
    """Load incomplete or wrongly formatted files to be used to test the AMBER parsers.

    Returns
    -------
    data : Bunch
        Dictionary-like object, the interesting attributes are:

        - 'data' : the data files
        - 'DESCR': the full description of all the files

    """

    module_path = dirname(__file__)

    data = {}
    for f in listdir(join(module_path, 'testfiles')):
        if f.endswith('bz2'):
            data[f[:-12]] = [join(module_path, 'testfiles', f)]

    with open(join(module_path, 'testfiles', 'descr.rst')) as rst_file:
        fdescr = rst_file.read()

    return Bunch(data=data,
                 DESCR=fdescr)
<|endoftext|>


<commit_before>from clint.textui import colored

class DatacatsError(Exception):

    def __init__(self, message, format_args=(), parent_exception=None):
        self.message = message
        if parent_exception and hasattr(parent_exception, 'user_description'):
            vals = {
                "original": self.message,
                "type_description": parent_exception.user_description,
                "message": parent_exception.__str__(),
            }
            self.message = "".join(["{original}\n\n",
                                    "~" * 30,
                                    "\n{type_description}:\n",
                                    "{message}",
                                    "~" * 30, "\n"]).format(**vals)

        self.format_args = format_args
        super(DatacatsError, self).__init__(message, format_args)

    def __str__(self):
        return self.message.format(*self.format_args)

    def pretty_print(self):
        """
        Print the error message to stdout with colors and borders
        """
        print colored.blue("-" * 40)
        print colored.red("datacats: problem was encountered:")
        for line in self.message.format(*self.format_args).split('\n'):
            print "    ", line
        print colored.blue("-" * 40)

class WebCommandError(Exception):
    user_description = "Docker container \"/web\" command failed"

    def __init__(self, command, logs):
        super(WebCommandError, self).__init__()
        self.command = command
        self.logs = logs

    def __str__(self):
        return ('    Command: {0}\n'
                '    Docker Error Log:\n'
                '    {1}\n'
                ).format(" ".join(self.command), self.logs)

class PortAllocatedError(Exception):
    user_description = "Unable to allocate port"
<commit_msg>Make error message formatting prettier and shinier<commit_after>from clint.textui import colored

class DatacatsError(Exception):

    def __init__(self, message, format_args=(), parent_exception=None):
        self.message = message
        if parent_exception and hasattr(parent_exception, 'user_description'):
            vals = {
                "original": self.message,
                "type_description": parent_exception.user_description,
                "message": parent_exception.__str__(),
            }
            self.message = "".join([colored.blue("{original}\n\n").__str__(),
                                    "~" * 30,
                                    "\n{type_description}:\n",
                                    colored.yellow("{message}\n").__str__()]
                                    ).format(**vals)

        self.format_args = format_args
        super(DatacatsError, self).__init__(message, format_args)

    def __str__(self):
        return self.message.format(*self.format_args)

    def pretty_print(self):
        """
        Print the error message to stdout with colors and borders
        """
        print colored.blue("-" * 40)
        print colored.red("datacats: problem was encountered:")
        print self.message.format(*self.format_args)
        print colored.blue("-" * 40)

class WebCommandError(Exception):
    user_description = "Docker container \"/web\" command failed"

    def __init__(self, command, logs):
        super(WebCommandError, self).__init__()
        self.command = command
        self.logs = logs

    def __str__(self):
        return ('    Command: {0}\n'
                '    Docker Error Log:\n'
                '    {1}\n'
                ).format(" ".join(self.command), self.logs)

class PortAllocatedError(Exception):
    user_description = "Unable to allocate port"
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
'''The app module, containing the app factory function.'''
from flask import Flask, render_template

from dci_notify.settings import ProdConfig
from dci_notify.assets import assets
from dci_notify.admin import admin
from dci_notify.extensions import (
    bcrypt,
    cache,
    db,
    login_manager,
    migrate,
    debug_toolbar,
    mail
)
from dci_notify import public, user

def create_app(config_object=ProdConfig):
    '''An application factory, as explained here:
        http://flask.pocoo.org/docs/patterns/appfactories/

    :param config_object: The configuration object to use.
    '''
    app = Flask(__name__)
    app.config.from_object(config_object)
    register_extensions(app)
    register_blueprints(app)
    register_errorhandlers(app)
    return app

def register_extensions(app):
    assets.init_app(app)
    bcrypt.init_app(app)
    cache.init_app(app)
    db.init_app(app)
    login_manager.init_app(app)
    debug_toolbar.init_app(app)
    migrate.init_app(app, db)
    admin.init_app(app)
    mail.init_app(app)
    return None

def register_blueprints(app):
    app.register_blueprint(public.views.blueprint)
    app.register_blueprint(user.views.blueprint)
    return None

def register_errorhandlers(app):
    def render_error(error):
        # If a HTTPException, pull the `code` attribute; default to 500
        error_code = getattr(error, 'code', 500)
        return render_template("{0}.html".format(error_code)), error_code
    for errcode in [401, 404, 500]:
        app.errorhandler(errcode)(render_error)
    return None
<commit_msg>Added email logger<commit_after># -*- coding: utf-8 -*-
'''The app module, containing the app factory function.'''
from flask import Flask, render_template

from dci_notify.settings import ProdConfig
from dci_notify.assets import assets
from dci_notify.admin import admin
from dci_notify.extensions import (
    bcrypt,
    cache,
    db,
    login_manager,
    migrate,
    debug_toolbar,
    mail
)
from dci_notify import public, user

def create_app(config_object=ProdConfig):
    '''An application factory, as explained here:
        http://flask.pocoo.org/docs/patterns/appfactories/

    :param config_object: The configuration object to use.
    '''
    app = Flask(__name__)
    app.config.from_object(config_object)
    register_extensions(app)
    register_blueprints(app)
    register_errorhandlers(app)
    register_loggers(app)
    return app

def register_extensions(app):
    assets.init_app(app)
    bcrypt.init_app(app)
    cache.init_app(app)
    db.init_app(app)
    login_manager.init_app(app)
    debug_toolbar.init_app(app)
    migrate.init_app(app, db)
    admin.init_app(app)
    mail.init_app(app)
    return None

def register_blueprints(app):
    app.register_blueprint(public.views.blueprint)
    app.register_blueprint(user.views.blueprint)
    return None

def register_errorhandlers(app):
    def render_error(error):
        # If a HTTPException, pull the `code` attribute; default to 500
        error_code = getattr(error, 'code', 500)
        return render_template("{0}.html".format(error_code)), error_code
    for errcode in [401, 404, 500]:
        app.errorhandler(errcode)(render_error)
    return None

def register_loggers(app):
    if not (app.debug or app.config.get('LOGGING_DISABLE', False)):
        import logging
        from logging import Formatter
        from logging.handlers import SMTPHandler
        mail_handler = SMTPHandler(mailhost=app.config['MAIL_SERVER'],
                                   fromaddr=app.config['LOGGING_SENDER'],
                                   toaddrs=app.config['ADMINS'],
                                   subject='dci-notify Server Error',
                                   credentials=(app.config['MAIL_USERNAME'],
                                                app.config['MAIL_PASSWORD']))
        mail_handler.setLevel(logging.ERROR)
        mail_handler.setFormatter(Formatter('''
            Message type:       %(levelname)s
            Location:           %(pathname)s:%(lineno)d
            Module:             %(module)s
            Function:           %(funcName)s
            Time:               %(asctime)s

            Message:

            %(message)s
        '''))
        app.logger.addHandler(mail_handler)
    return None
<|endoftext|>