haldis/app/app.py
mcbloch d0863325a5
Restructuring the codebase!
But for real, it's a real shitstorm in there.
- Added context by making the init go through a function
  and not implicitly happen via imports
- Fixup all context and contextless function mixups
- splitup the models in sensible different files
- give the dump of view functions in views/__init__.py their own file
- add all routes via blueprints, not half of them
- move the slack notifications function and class to its own file,
    no idea what it was doing in a views file in the first place.
2019-08-28 03:46:04 +02:00

148 lines
4.4 KiB
Python

import logging
from datetime import datetime
from logging.handlers import TimedRotatingFileHandler
from airbrake import Airbrake, AirbrakeHandler
from flask import Flask, render_template
from flask_bootstrap import Bootstrap, StaticCDN
from flask_debugtoolbar import DebugToolbarExtension
from flask_login import LoginManager
from flask_migrate import Migrate, MigrateCommand
from flask_oauthlib.client import OAuth, OAuthException
from flask_script import Manager
from admin import init_admin
from login import init_login
from models import db
from models.anonymous_user import AnonymouseUser
from utils import euro_string
from zeus import init_oauth
def create_app():
app = Flask(__name__)
# Load the config file
app.config.from_object('config.Configuration')
manager = register_plugins(app, debug=app.debug)
add_handlers(app)
add_routes(app)
add_template_filters(app)
# TODO do we need to return and then run the manager?
return app
def register_plugins(app, debug: bool):
# Register Airbrake and enable the logrotation
if not app.debug:
timedFileHandler = TimedRotatingFileHandler(app.config['LOGFILE'],
when='midnight',
backupCount=100)
timedFileHandler.setLevel(logging.DEBUG)
loglogger = logging.getLogger('werkzeug')
loglogger.setLevel(logging.DEBUG)
loglogger.addHandler(timedFileHandler)
app.logger.addHandler(timedFileHandler)
airbrakelogger = logging.getLogger('airbrake')
# Airbrake
airbrake = Airbrake(project_id=app.config['AIRBRAKE_ID'],
api_key=app.config['AIRBRAKE_KEY'])
# ugly hack to make this work for out errbit
airbrake._api_url = "http://errbit.awesomepeople.tv/api/v3/projects/{}/notices".format(
airbrake.project_id)
airbrakelogger.addHandler(AirbrakeHandler(airbrake=airbrake))
app.logger.addHandler(AirbrakeHandler(airbrake=airbrake))
# Initialize SQLAlchemy
db.init_app(app)
# Initialize Flask-Migrate
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
# Add admin interface
init_admin(app, db)
# Init login manager
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.anonymous_user = AnonymouseUser
init_login(app)
# Add oauth
zeus = init_oauth(app)
app.zeus = zeus
# Load the bootstrap local cdn
Bootstrap(app)
app.config['BOOTSTRAP_SERVE_LOCAL'] = True
# use our own bootstrap theme
app.extensions['bootstrap']['cdns']['bootstrap'] = StaticCDN()
# Load the flask debug toolbar
toolbar = DebugToolbarExtension(app)
return manager
def add_handlers(app):
@app.errorhandler(404)
def handle404(e):
return render_template('errors/404.html'), 404
@app.errorhandler(401)
def handle401(e):
return render_template('errors/401.html'), 401
def add_routes(application):
# import views # TODO convert to blueprint
# import views.stats # TODO convert to blueprint
from views.order import order_bp
from views.general import general_bp
from views.stats import stats_blueprint
from login import auth_bp
from zeus import oauth_bp
application.register_blueprint(general_bp, url_prefix='/')
application.register_blueprint(order_bp, url_prefix='/order')
application.register_blueprint(stats_blueprint, url_prefix='/stats')
application.register_blueprint(auth_bp, url_prefix='/')
application.register_blueprint(oauth_bp, url_prefix='/')
def add_template_filters(app):
@app.template_filter('countdown')
def countdown(value, only_positive=True, show_text=True):
delta = value - datetime.now()
if delta.total_seconds() < 0 and only_positive:
return "closed"
hours, remainder = divmod(delta.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
time = '%02d:%02d:%02d' % (hours, minutes, seconds)
if show_text:
return 'closes in ' + time
return time
@app.template_filter('year')
def current_year(value):
return str(datetime.now().year)
@app.template_filter('euro')
def euro(value):
euro_string(value)
# For usage when you directly call the script with python
if __name__ == '__main__':
app = create_app()
app.run(threaded=True, host='0.0.0.0')