1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
# -*- coding: utf-8 -*-
# Author: G.J.J. van den Burg <gvandenburg@turing.ac.uk>
# License: See LICENSE file
# Copyright: 2020 (c) The Alan Turing Institute
__version__ = "0.4.5"
import logging
import os
from logging.handlers import SMTPHandler, RotatingFileHandler
from flask import Flask
from flask_bootstrap import Bootstrap, WebCDN
from flask_login import LoginManager
from flask_mail import Mail
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from config import Config
db = SQLAlchemy()
migrate = Migrate()
login = LoginManager()
login.login_view = "auth.login"
mail = Mail()
bootstrap = Bootstrap()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
# Set the app version in the config (we use it in templates)
app.config["APP_VERSION"] = __version__
# Initialize all extensions
db.init_app(app)
migrate.init_app(app, db)
login.init_app(app)
mail.init_app(app)
bootstrap.init_app(app)
# Register CDNs
app.extensions["bootstrap"]["cdns"]["bootstrap"] = WebCDN(
"/static/resources/bootstrap/"
)
app.extensions["bootstrap"]["cdns"]["jquery"] = WebCDN(
"/static/resources/jquery/"
)
app.extensions["bootstrap"]["cdns"]["datatables"] = WebCDN(
"/static/resources/datatables/"
)
app.extensions["bootstrap"]["cdns"]["d3"] = WebCDN("/static/resources/d3/")
# Initialize the instance directory and necessary subdirectories
os.makedirs(app.instance_path, exist_ok=True)
os.makedirs(
os.path.join(app.instance_path, app.config["TEMP_DIR"]), exist_ok=True
)
os.makedirs(
os.path.join(app.instance_path, app.config["DATASET_DIR"]),
exist_ok=True,
)
# Register all the blueprints
from app.errors import bp as errors_bp
app.register_blueprint(errors_bp)
from app.auth import bp as auth_bp
app.register_blueprint(auth_bp, url_prefix="/auth")
from app.main import bp as main_bp
app.register_blueprint(main_bp)
from app.admin import bp as admin_bp
app.register_blueprint(admin_bp)
# Register the auto_logout function
from app.auth.routes import auto_logout
app.before_request(auto_logout)
if not app.debug:
if app.config["MAIL_SERVER"]:
auth = None
if app.config["MAIL_USERNAME"] or app.config["MAIL_PASSWORD"]:
auth = (
app.config["MAIL_USERNAME"],
app.config["MAIL_PASSWORD"],
)
secure = None
if app.config["MAIL_USE_TLS"]:
secure = ()
mail_handler = SMTPHandler(
mailhost=(app.config["MAIL_SERVER"], app.config["MAIL_PORT"]),
fromaddr="no-reply@" + app.config["MAIL_SERVER"],
toaddrs=app.config["ADMINS"],
subject="AnnotateChange Failure",
credentials=auth,
secure=secure,
)
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)
if not os.path.exists("logs"):
os.mkdir("logs")
file_handler = RotatingFileHandler(
"logs/annotatechange.log", maxBytes=10240, backupCount=10
)
file_handler.setFormatter(
logging.Formatter(
"%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]"
)
)
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info("AnnotateChange startup")
return app
from app import models
|