__init__.py
3.63 KB
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
#! ../venv/bin/python
import os
from dotenv import load_dotenv, find_dotenv, dotenv_values
from markdown import markdown
# Load config from .env ; do this before importing local libs (and flask)
# 1. Write into OS environment -- if this fails you forgot to create .env file
load_dotenv(find_dotenv(raise_error_if_not_found=True), override=True)
# 2. Load it as well to inject it later into app.config
local_env = dotenv_values(find_dotenv())
# 3. Cast integers to integers
for key in local_env.keys():
try:
local_env[key] = int(local_env[key])
except ValueError:
pass
from flask import Flask, url_for
from flask.cli import ScriptInfo
from webassets.loaders import PythonLoader as PythonAssetsLoader
from flaskr import assets
from flaskr.models import db, Estimation, EstimationView
from flaskr.controllers.main_controller import main
from flaskr.extensions import (
admin,
assets_env,
basic_auth,
cache,
debug_toolbar,
login_manager,
mail,
session,
captcha,
icon2html,
)
from flaskr.content import content
from flaskr.core import increment_hit_counter, get_hit_counter
def create_app(object_name):
"""
A flask application factory, as explained here:
http://flask.pocoo.org/docs/patterns/appfactories/
Arguments:
object_name: the python path of the config object,
e.g. flaskr.settings.ProductionConfig
"""
app = Flask(__name__)
# We bypass object_name (for dev with flask run)
if type(object_name) == ScriptInfo:
object_name = 'flaskr.settings.DevelopmentConfig'
# Load the configuration
app.config.from_object(object_name)
app.config.update(**local_env)
app.config['BASIC_AUTH_USERNAME'] = os.getenv('ADMIN_USERNAME')
app.config['BASIC_AUTH_PASSWORD'] = os.getenv('ADMIN_PASSWORD')
app.config['CAPTCHA_ENABLE'] = False
app.config['CAPTCHA_LENGTH'] = 5
app.config['CAPTCHA_WIDTH'] = 256
app.config['CAPTCHA_HEIGHT'] = 158
app.config['SESSION_TYPE'] = 'sqlalchemy'
# Initialize
cache.init_app(app)
session.init_app(app)
captcha.init_app(app)
mail.init_app(app)
debug_toolbar.init_app(app)
db.init_app(app)
login_manager.init_app(app)
admin.init_app(app)
admin.add_view(EstimationView(Estimation, db.session))
basic_auth.init_app(app)
# For session storage
app.session_interface.db.create_all()
# Import and register the different asset bundles
assets_env.init_app(app)
assets_loader = PythonAssetsLoader(assets)
for name, bundle in assets_loader.load_bundles().items():
assets_env.register(name, bundle)
# Register our blueprints
app.register_blueprint(main)
# VERSION (move to version.py ?)
version = "0.0.0"
with open('VERSION', 'r') as version_file:
version = version_file.read().strip()
# Inject it as global template var
@app.context_processor
def inject_template_global_variables():
return dict(
content=content,
version=version,
visits=get_hit_counter(),
)
# Markdown jinja2 filter
@app.template_filter('markdown')
def markdown_filter(text):
text = icon2html(text)
return markdown(text, extensions=['extra'])
# Authentication Gate for the Admin
@app.before_first_request
def restrict_admin_url():
endpoint = 'admin.index'
url = url_for(endpoint)
admin_index = app.view_functions.pop(endpoint)
@app.route(url, endpoint=endpoint)
@basic_auth.required
# @roles_required('admin')
def secure_admin_index():
return admin_index()
return app