comparison foodtruck/blueprint.py @ 772:3885421c29a3

admin: Make the whole FoodTruck site into a blueprint. This makes it possible to use an app factory, which makes it easier to write unit tests.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 03 Jul 2016 07:54:54 -0700
parents
children
comparison
equal deleted inserted replaced
771:673979a5d548 772:3885421c29a3
1 import os
2 import os.path
3 import time
4 import logging
5 from flask import Blueprint, current_app, g, request, render_template
6 from .configuration import (
7 FoodTruckConfigNotFoundError, get_foodtruck_config)
8 from .sites import FoodTruckSites, InvalidSiteError
9
10
11 logger = logging.getLogger(__name__)
12
13
14 # Prepare the Login extension.
15 from flask.ext.login import LoginManager, UserMixin
16
17
18 class User(UserMixin):
19 def __init__(self, uid, pwd):
20 self.id = uid
21 self.password = pwd
22
23
24 def load_user(user_id):
25 admin_id = g.config.get('security/username')
26 if admin_id == user_id:
27 admin_pwd = g.config.get('security/password')
28 return User(admin_id, admin_pwd)
29 return None
30
31
32 login_manager = LoginManager()
33 login_manager.login_view = 'login'
34 login_manager.user_loader(load_user)
35
36
37 def record_login_manager(state):
38 if state.app.secret_key == 'temp-key':
39 def _handler():
40 raise FoodTruckConfigNotFoundError()
41
42 logger.debug("No secret key found, disabling website login.")
43 login_manager.unauthorized_handler(_handler)
44 login_manager.login_view = None
45
46
47 # Setup Bcrypt.
48 from foodtruck.bcryptfallback import Bcrypt
49 bcrypt_ext = Bcrypt()
50
51
52 def record_bcrypt(state):
53 if (getattr(Bcrypt, 'is_fallback_bcrypt', None) is True and
54 not state.app.config.get('FOODTRUCK_CMDLINE_MODE', False)):
55 raise Exception(
56 "You're running FoodTruck outside of `chef`, and will need to "
57 "install Flask-Bcrypt to get more proper security.")
58
59
60 # Create the FoodTruck blueprint.
61 foodtruck_bp = Blueprint(
62 'FoodTruck', __name__,
63 template_folder='templates',
64 static_folder='static')
65
66 foodtruck_bp.record(record_login_manager)
67 foodtruck_bp.record(record_bcrypt)
68
69
70 def after_this_request(f):
71 if not hasattr(g, 'after_request_callbacks'):
72 g.after_request_callbacks = []
73 g.after_request_callbacks.append(f)
74 return f
75
76
77 class LazySomething(object):
78 def __init__(self, factory):
79 self._factory = factory
80 self._something = None
81
82 def __getattr__(self, name):
83 if self._something is not None:
84 return getattr(self._something, name)
85
86 self._something = self._factory()
87 return getattr(self._something, name)
88
89
90 @foodtruck_bp.before_request
91 def _setup_foodtruck_globals():
92 def _get_config():
93 admin_root = current_app.config['FOODTRUCK_ROOT']
94 procedural_config = current_app.config['FOODTRUCK_PROCEDURAL_CONFIG']
95 return get_foodtruck_config(admin_root, procedural_config)
96
97 def _get_sites():
98 names = g.config.get('sites')
99 if not names or not isinstance(names, dict):
100 raise InvalidSiteError(
101 "No sites are defined in the configuration file.")
102
103 current = request.cookies.get('foodtruck_site_name')
104 if current is not None and current not in names:
105 current = None
106 if current is None:
107 current = next(iter(names.keys()))
108 s = FoodTruckSites(g.config, current)
109 return s
110
111 def _get_current_site():
112 return g.sites.get()
113
114 g.config = LazySomething(_get_config)
115 g.sites = LazySomething(_get_sites)
116 g.site = LazySomething(_get_current_site)
117
118
119 @foodtruck_bp.after_request
120 def _call_after_request_callbacks(response):
121 for callback in getattr(g, 'after_request_callbacks', ()):
122 callback(response)
123 return response
124
125
126 @foodtruck_bp.errorhandler
127 def _on_error(ex):
128 logging.exception(ex)
129
130
131 @foodtruck_bp.app_template_filter('iso8601')
132 def timestamp_to_iso8601(t):
133 t = time.localtime(t)
134 return time.strftime('%Y-%m-%dT%H:%M:%SZ', t)
135
136
137 @foodtruck_bp.app_template_filter('datetime')
138 def timestamp_to_datetime(t, fmt=None):
139 fmt = fmt or '%x'
140 t = time.localtime(t)
141 return time.strftime(fmt, t)
142
143
144 import foodtruck.views.create # NOQA
145 import foodtruck.views.dashboard # NOQA
146 import foodtruck.views.edit # NOQA
147 import foodtruck.views.menu # NOQA
148 import foodtruck.views.preview # NOQA
149 import foodtruck.views.publish # NOQA
150 import foodtruck.views.sources # NOQA
151
152