# Path: boiler/config.py
# class DefaultConfig(Config):
#     """
#     Default project configuration
#     Sets up defaults used and/or overridden in environments and deployments
#     """
#     ENV = 'production'
# 
#     SERVER_NAME = None
# 
#     # secret key
#     SECRET_KEY = os.getenv('APP_SECRET_KEY')
# 
#     TIME_RESTARTS = False
#     TESTING = False
#     DEBUG = False
#     DEBUG_TB_ENABLED = False
#     DEBUG_TB_PROFILER_ENABLED = False
#     DEBUG_TB_INTERCEPT_REDIRECTS = False
# 
#     # where built-in server and url_for look for static files (None for default)
#     FLASK_STATIC_URL = None
#     FLASK_STATIC_PATH = None
# 
#     # asset helper settings (server must be capable of serving these files)
#     ASSETS_VERSION = None
#     ASSETS_PATH = None  # None falls back to url_for('static')
# 
#     # do not expose our urls on 404s
#     ERROR_404_HELP = False
# 
#     # uploads
#     MAX_CONTENT_LENGTH = 1024 * 1024 * 16  # megabytes
# 
#     # database
#     # 'mysql://user:password@server/db?charset=utf8mb4'
#     # 'mysql+pymysql://user:password@server/db?charset=utf8mb4'
#     # 'mysql+mysqlconnector://user:password@host:3306/database?charset=utf8mb4'
#     SQLALCHEMY_ECHO = False
#     SQLALCHEMY_TRACK_MODIFICATIONS = False
#     MIGRATIONS_PATH = os.path.join(os.getcwd(), 'migrations')
#     SQLALCHEMY_DATABASE_URI = os.getenv('APP_DATABASE_URI')
#     TEST_DB_PATH = os.path.join(
#         os.getcwd(), 'var', 'data', 'test-db', 'sqlite.db'
#     )
# 
#     # mail server settings
#     MAIL_DEBUG = False
#     MAIL_SERVER = 'smtp.gmail.com'
#     MAIL_PORT = 587
#     MAIL_USE_TLS = True
#     MAIL_USE_SSL = False
#     MAIL_USERNAME = None
#     MAIL_PASSWORD = None
#     MAIL_DEFAULT_SENDER = ('Webapp Mailer', 'mygmail@gmail.com')
# 
#     # logging
#     ADMINS = ['you@domain']
#     LOGGING_EMAIL_EXCEPTIONS_TO_ADMINS = False
# 
#     # localization (babel)
#     DEFAULT_LOCALE = 'en_GB'
#     DEFAULT_TIMEZONE = 'UTC'
# 
#     # csrf protection
#     WTF_CSRF_ENABLED = True
# 
#     # recaptcha
#     RECAPTCHA_PUBLIC_KEY = os.getenv('APP_RECAPTCHA_PUBLIC_KEY')
#     RECAPTCHA_PRIVATE_KEY = os.getenv('APP_RECAPTCHA_PRIVATE_KEY')
# 
# Path: boiler/timer/restart_timer.py
# def time_restarts(data_path):
# 
# Path: boiler/errors.py
# def register_error_handler(app, handler=None):
#     """
#     Register error handler
#     Registers an exception handler on the app instance for every type of
#     exception code werkzeug is aware about.
# 
#     :param app: flask.Flask - flask application instance
#     :param handler: function - the handler
#     :return: None
#     """
#     if not handler:
#         handler = default_error_handler
# 
#     for code in exceptions.default_exceptions.keys():
#         app.register_error_handler(code, handler)
# 
# Path: boiler/jinja/functions.py
# def asset(url=None):
# def dev_proxy():
# 
# Path: boiler/exceptions.py
# class BoilerException(Exception):
# class BootstrapException(BoilerException, RuntimeError):


import os
from os import path
from flask import Flask
from flask import g
from flask import request
from werkzeug.utils import import_string
from werkzeug.utils import ImportStringError
from jinja2 import ChoiceLoader, FileSystemLoader
from flask_wtf import CSRFProtect
from boiler.config import DefaultConfig
from boiler.timer import restart_timer
from boiler.errors import register_error_handler
from boiler.jinja import functions as jinja_functions
from boiler import exceptions as x
    from boiler.feature.routing import routing_feature
    from boiler.feature.mail import mail_feature
    from boiler.feature.orm import orm_feature
    from boiler.feature.logging import logging_feature
    from boiler.feature.localization import localization_feature
    Create app
    Generalized way of creating a flask app. Use it in your concrete apps and
    do further configuration there: add app-specific options, extensions,
    listeners and other features.

    Note: application name should be its fully qualified __name__, something
    like project.api.app. This is how we fetch routing settings.
    """
    # check import name
    test_import_name(name)

    # check config
    if not config:
        config = DefaultConfig()
    if config.__class__ is type:
        err = 'Config must be an object, got class instead.'
        raise x.BootstrapException(err)

    # check flask params
    flask_params = flask_params or dict()
    flask_params['import_name'] = name

    # configure static assets
    if config.get('FLASK_STATIC_URL') is not None:
        flask_params['static_url_path'] = config.get('FLASK_STATIC_URL')
    if config.get('FLASK_STATIC_PATH') is not None:
        flask_params['static_folder'] = config.get('FLASK_STATIC_PATH')

    # create an app with default config
    app = Flask(**flask_params)

# Path: boiler/config.py
# class DefaultConfig(Config):
#     """
#     Default project configuration
#     Sets up defaults used and/or overridden in environments and deployments
#     """
#     ENV = 'production'
# 
#     SERVER_NAME = None
# 
#     # secret key
#     SECRET_KEY = os.getenv('APP_SECRET_KEY')
# 
#     TIME_RESTARTS = False
#     TESTING = False
#     DEBUG = False
#     DEBUG_TB_ENABLED = False
#     DEBUG_TB_PROFILER_ENABLED = False
#     DEBUG_TB_INTERCEPT_REDIRECTS = False
# 
#     # where built-in server and url_for look for static files (None for default)
#     FLASK_STATIC_URL = None
#     FLASK_STATIC_PATH = None
# 
#     # asset helper settings (server must be capable of serving these files)
#     ASSETS_VERSION = None
#     ASSETS_PATH = None  # None falls back to url_for('static')
# 
#     # do not expose our urls on 404s
#     ERROR_404_HELP = False
# 
#     # uploads
#     MAX_CONTENT_LENGTH = 1024 * 1024 * 16  # megabytes
# 
#     # database
#     # 'mysql://user:password@server/db?charset=utf8mb4'
#     # 'mysql+pymysql://user:password@server/db?charset=utf8mb4'
#     # 'mysql+mysqlconnector://user:password@host:3306/database?charset=utf8mb4'
#     SQLALCHEMY_ECHO = False
#     SQLALCHEMY_TRACK_MODIFICATIONS = False
#     MIGRATIONS_PATH = os.path.join(os.getcwd(), 'migrations')
#     SQLALCHEMY_DATABASE_URI = os.getenv('APP_DATABASE_URI')
#     TEST_DB_PATH = os.path.join(
#         os.getcwd(), 'var', 'data', 'test-db', 'sqlite.db'
#     )
# 
#     # mail server settings
#     MAIL_DEBUG = False
#     MAIL_SERVER = 'smtp.gmail.com'
#     MAIL_PORT = 587
#     MAIL_USE_TLS = True
#     MAIL_USE_SSL = False
#     MAIL_USERNAME = None
#     MAIL_PASSWORD = None
#     MAIL_DEFAULT_SENDER = ('Webapp Mailer', 'mygmail@gmail.com')
# 
#     # logging
#     ADMINS = ['you@domain']
#     LOGGING_EMAIL_EXCEPTIONS_TO_ADMINS = False
# 
#     # localization (babel)
#     DEFAULT_LOCALE = 'en_GB'
#     DEFAULT_TIMEZONE = 'UTC'
# 
#     # csrf protection
#     WTF_CSRF_ENABLED = True
# 
#     # recaptcha
#     RECAPTCHA_PUBLIC_KEY = os.getenv('APP_RECAPTCHA_PUBLIC_KEY')
#     RECAPTCHA_PRIVATE_KEY = os.getenv('APP_RECAPTCHA_PRIVATE_KEY')
# 
# Path: boiler/timer/restart_timer.py
# def time_restarts(data_path):
# 
# Path: boiler/errors.py
# def register_error_handler(app, handler=None):
#     """
#     Register error handler
#     Registers an exception handler on the app instance for every type of
#     exception code werkzeug is aware about.
# 
#     :param app: flask.Flask - flask application instance
#     :param handler: function - the handler
#     :return: None
#     """
#     if not handler:
#         handler = default_error_handler
# 
#     for code in exceptions.default_exceptions.keys():
#         app.register_error_handler(code, handler)
# 
# Path: boiler/jinja/functions.py
# def asset(url=None):
# def dev_proxy():
# 
# Path: boiler/exceptions.py
# class BoilerException(Exception):
# class BootstrapException(BoilerException, RuntimeError):


# Path: boiler/bootstrap.py
import os
from os import path
from flask import Flask
from flask import g
from flask import request
from werkzeug.utils import import_string
from werkzeug.utils import ImportStringError
from jinja2 import ChoiceLoader, FileSystemLoader
from flask_wtf import CSRFProtect
from boiler.config import DefaultConfig
from boiler.timer import restart_timer
from boiler.errors import register_error_handler
from boiler.jinja import functions as jinja_functions
from boiler import exceptions as x
    from boiler.feature.routing import routing_feature
    from boiler.feature.mail import mail_feature
    from boiler.feature.orm import orm_feature
    from boiler.feature.logging import logging_feature
    from boiler.feature.localization import localization_feature

    Create app
    Generalized way of creating a flask app. Use it in your concrete apps and
    do further configuration there: add app-specific options, extensions,
    listeners and other features.

    Note: application name should be its fully qualified __name__, something
    like project.api.app. This is how we fetch routing settings.
    """
    # check import name
    test_import_name(name)

    # check config
    if not config:
        config = DefaultConfig()
    if config.__class__ is type:
        err = 'Config must be an object, got class instead.'
        raise x.BootstrapException(err)

    # check flask params
    flask_params = flask_params or dict()
    flask_params['import_name'] = name

    # configure static assets
    if config.get('FLASK_STATIC_URL') is not None:
        flask_params['static_url_path'] = config.get('FLASK_STATIC_URL')
    if config.get('FLASK_STATIC_PATH') is not None:
        flask_params['static_folder'] = config.get('FLASK_STATIC_PATH')

    # create an app with default config
    app = Flask(**flask_params)

    app.config.from_object(DefaultConfig())