import os import os.path import warnings from flask import Flask, g, request, session from flask_babel import Babel from flask_migrate import Migrate, upgrade, stamp from raven.contrib.flask import Sentry from web import main, db, mail from api import api from utils import PrefixedWSGI from utils import minimal_round app = Flask(__name__, instance_path='/etc/ihatemoney', instance_relative_config=True) def pre_alembic_db(): """ Checks if we are migrating from a pre-alembic ihatemoney """ con = db.engine.connect() tables_exist = db.engine.dialect.has_table(con, 'project') alembic_setup = db.engine.dialect.has_table(con, 'alembic_version') return tables_exist and not alembic_setup def configure(): """ A way to (re)configure the app, specially reset the settings """ default_config_file = os.path.join(app.root_path, 'default_settings.py') config_file = os.environ.get('IHATEMONEY_SETTINGS_FILE_PATH') # Load default settings first # Then load the settings from the path set in IHATEMONEY_SETTINGS_FILE_PATH var # If not set, default to /etc/ihatemoney/ihatemoney.cfg # If the latter doesn't exist no error is raised and the default settings are used app.config.from_pyfile(default_config_file) if config_file: app.config.from_pyfile(config_file) else: app.config.from_pyfile('ihatemoney.cfg', silent=True) app.wsgi_app = PrefixedWSGI(app) # Deprecations if 'DEFAULT_MAIL_SENDER' in app.config: # Since flask-mail 0.8 warnings.warn( "DEFAULT_MAIL_SENDER is deprecated in favor of MAIL_DEFAULT_SENDER" +" and will be removed in further version", UserWarning ) if not 'MAIL_DEFAULT_SENDER' in app.config: app.config['MAIL_DEFAULT_SENDER'] = DEFAULT_MAIL_SENDER configure() app.register_blueprint(main) app.register_blueprint(api) # custom jinja2 filters app.jinja_env.filters['minimal_round'] = minimal_round # db db.init_app(app) db.app = app # db migrations migrate = Migrate(app, db) migrations_path = os.path.join(app.root_path, 'migrations') if pre_alembic_db(): with app.app_context(): # fake the first migration stamp(migrations_path, revision='b9a10d5d63ce') # auto-execute migrations on runtime with app.app_context(): upgrade(migrations_path) # mail mail.init_app(app) # translations babel = Babel(app) # sentry sentry = Sentry(app) @babel.localeselector def get_locale(): # get the lang from the session if defined, fallback on the browser "accept # languages" header. lang = session.get('lang', request.accept_languages.best_match(['fr', 'en'])) setattr(g, 'lang', lang) return lang def main(): app.run(host="0.0.0.0", debug=True) if __name__ == '__main__': main()