# -*- coding: utf-8 -*- """ app.factory ~~~~~~~~~~~ Create the WSGI application. :copyright: (c) 2017 European Spallation Source ERIC :license: BSD 2-Clause, see LICENSE for more details. """ import sqlalchemy as sa from flask import Flask from . import settings from .extensions import db, migrate, login_manager, ldap_manager, bootstrap, admin, mail, jwt from .models import Action, Manufacturer, Model, Location, Status from .admin.views import AdminModelView, ItemAdmin, UserAdmin, GroupAdmin from .main.views import bp as main from .users.views import bp as users from .api.main import bp as api from .defaults import defaults def register_cli(app): @app.cli.command() def initdb(): """Create the database tables and initialize them with default values""" db.engine.execute('CREATE EXTENSION IF NOT EXISTS citext') db.create_all() for instance in defaults: db.session.add(instance) try: db.session.commit() except sa.exc.IntegrityError as e: db.session.rollback() app.logger.debug(f'{instance} already exists') def create_app(config=None): app = Flask(__name__) app.config.from_object(settings) app.config.from_envvar('LOCAL_SETTINGS', silent=True) app.config.update(config or {}) if not app.debug: import logging # Send ERROR via mail from logging.handlers import SMTPHandler mail_handler = SMTPHandler(app.config['MAIL_SERVER'], app.config['EMAIL_SENDER'], app.config['ADMIN_EMAILS'], 'Inventory: ERROR raised') mail_handler.setFormatter(logging.Formatter(""" Message type: %(levelname)s Location: %(pathname)s:%(lineno)d Module: %(module)s Function: %(funcName)s Time: %(asctime)s Message: %(message)s """)) mail_handler.setLevel(logging.ERROR) app.logger.addHandler(mail_handler) # Log to stderr handler = logging.StreamHandler() handler.setFormatter(logging.Formatter( '%(asctime)s %(levelname)s: %(message)s ' '[in %(pathname)s:%(lineno)d]' )) # Set app logger level to DEBUG # otherwise only WARNING and above are propagated app.logger.setLevel(logging.DEBUG) handler.setLevel(logging.DEBUG) app.logger.addHandler(handler) app.logger.info('Inventory created!') app.logger.info('Settings:\n{}'.format( '\n'.join(['{}: {}'.format(key, value) for key, value in app.config.items() if key not in ('SECRET_KEY', 'LDAP_BIND_USER_PASSWORD')]))) bootstrap.init_app(app) db.init_app(app) migrate.init_app(app) login_manager.init_app(app) login_manager.login_view = 'users.login' ldap_manager.init_app(app) mail.init_app(app) jwt.init_app(app) admin.init_app(app) admin.add_view(GroupAdmin(db.session)) admin.add_view(UserAdmin(db.session)) admin.add_view(AdminModelView(Action, db.session)) admin.add_view(AdminModelView(Manufacturer, db.session)) admin.add_view(AdminModelView(Model, db.session)) admin.add_view(AdminModelView(Location, db.session)) admin.add_view(AdminModelView(Status, db.session)) admin.add_view(ItemAdmin(db.session)) app.register_blueprint(main) app.register_blueprint(users) app.register_blueprint(api, url_prefix='/api') register_cli(app) return app