##// END OF EJS Templates
errorpages: fix case when a pyramid httperror was not being rendered...
dan -
r449:e17b1d9d default
parent child Browse files
Show More
@@ -1,389 +1,387 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Pylons middleware initialization
22 Pylons middleware initialization
23 """
23 """
24 import logging
24 import logging
25
25
26 from paste.registry import RegistryManager
26 from paste.registry import RegistryManager
27 from paste.gzipper import make_gzip_middleware
27 from paste.gzipper import make_gzip_middleware
28 from pylons.wsgiapp import PylonsApp
28 from pylons.wsgiapp import PylonsApp
29 from pyramid.authorization import ACLAuthorizationPolicy
29 from pyramid.authorization import ACLAuthorizationPolicy
30 from pyramid.config import Configurator
30 from pyramid.config import Configurator
31 from pyramid.static import static_view
31 from pyramid.static import static_view
32 from pyramid.settings import asbool, aslist
32 from pyramid.settings import asbool, aslist
33 from pyramid.wsgi import wsgiapp
33 from pyramid.wsgi import wsgiapp
34 from pyramid.httpexceptions import HTTPError, HTTPInternalServerError
34 from pyramid.httpexceptions import HTTPError, HTTPInternalServerError
35 import pyramid.httpexceptions as httpexceptions
35 import pyramid.httpexceptions as httpexceptions
36 from pyramid.renderers import render_to_response, render
36 from pyramid.renderers import render_to_response, render
37 from routes.middleware import RoutesMiddleware
37 from routes.middleware import RoutesMiddleware
38 import routes.util
38 import routes.util
39
39
40 import rhodecode
40 import rhodecode
41 import rhodecode.integrations # do not remove this as it registers celery tasks
41 import rhodecode.integrations # do not remove this as it registers celery tasks
42 from rhodecode.config import patches
42 from rhodecode.config import patches
43 from rhodecode.config.environment import (
43 from rhodecode.config.environment import (
44 load_environment, load_pyramid_environment)
44 load_environment, load_pyramid_environment)
45 from rhodecode.lib.middleware import csrf
45 from rhodecode.lib.middleware import csrf
46 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
46 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
47 from rhodecode.lib.middleware.disable_vcs import DisableVCSPagesWrapper
47 from rhodecode.lib.middleware.disable_vcs import DisableVCSPagesWrapper
48 from rhodecode.lib.middleware.https_fixup import HttpsFixup
48 from rhodecode.lib.middleware.https_fixup import HttpsFixup
49 from rhodecode.lib.middleware.vcs import VCSMiddleware
49 from rhodecode.lib.middleware.vcs import VCSMiddleware
50 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
50 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
51
51
52
52
53 log = logging.getLogger(__name__)
53 log = logging.getLogger(__name__)
54
54
55
55
56 def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
56 def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
57 """Create a Pylons WSGI application and return it
57 """Create a Pylons WSGI application and return it
58
58
59 ``global_conf``
59 ``global_conf``
60 The inherited configuration for this application. Normally from
60 The inherited configuration for this application. Normally from
61 the [DEFAULT] section of the Paste ini file.
61 the [DEFAULT] section of the Paste ini file.
62
62
63 ``full_stack``
63 ``full_stack``
64 Whether or not this application provides a full WSGI stack (by
64 Whether or not this application provides a full WSGI stack (by
65 default, meaning it handles its own exceptions and errors).
65 default, meaning it handles its own exceptions and errors).
66 Disable full_stack when this application is "managed" by
66 Disable full_stack when this application is "managed" by
67 another WSGI middleware.
67 another WSGI middleware.
68
68
69 ``app_conf``
69 ``app_conf``
70 The application's local configuration. Normally specified in
70 The application's local configuration. Normally specified in
71 the [app:<name>] section of the Paste ini file (where <name>
71 the [app:<name>] section of the Paste ini file (where <name>
72 defaults to main).
72 defaults to main).
73
73
74 """
74 """
75 # Apply compatibility patches
75 # Apply compatibility patches
76 patches.kombu_1_5_1_python_2_7_11()
76 patches.kombu_1_5_1_python_2_7_11()
77 patches.inspect_getargspec()
77 patches.inspect_getargspec()
78
78
79 # Configure the Pylons environment
79 # Configure the Pylons environment
80 config = load_environment(global_conf, app_conf)
80 config = load_environment(global_conf, app_conf)
81
81
82 # The Pylons WSGI app
82 # The Pylons WSGI app
83 app = PylonsApp(config=config)
83 app = PylonsApp(config=config)
84 if rhodecode.is_test:
84 if rhodecode.is_test:
85 app = csrf.CSRFDetector(app)
85 app = csrf.CSRFDetector(app)
86
86
87 expected_origin = config.get('expected_origin')
87 expected_origin = config.get('expected_origin')
88 if expected_origin:
88 if expected_origin:
89 # The API can be accessed from other Origins.
89 # The API can be accessed from other Origins.
90 app = csrf.OriginChecker(app, expected_origin,
90 app = csrf.OriginChecker(app, expected_origin,
91 skip_urls=[routes.util.url_for('api')])
91 skip_urls=[routes.util.url_for('api')])
92
92
93
93
94 if asbool(full_stack):
94 if asbool(full_stack):
95
95
96 # Appenlight monitoring and error handler
96 # Appenlight monitoring and error handler
97 app, appenlight_client = wrap_in_appenlight_if_enabled(app, config)
97 app, appenlight_client = wrap_in_appenlight_if_enabled(app, config)
98
98
99 # we want our low level middleware to get to the request ASAP. We don't
99 # we want our low level middleware to get to the request ASAP. We don't
100 # need any pylons stack middleware in them
100 # need any pylons stack middleware in them
101 app = VCSMiddleware(app, config, appenlight_client)
101 app = VCSMiddleware(app, config, appenlight_client)
102
102
103 # Establish the Registry for this application
103 # Establish the Registry for this application
104 app = RegistryManager(app)
104 app = RegistryManager(app)
105
105
106 app.config = config
106 app.config = config
107
107
108 return app
108 return app
109
109
110
110
111 def make_pyramid_app(global_config, **settings):
111 def make_pyramid_app(global_config, **settings):
112 """
112 """
113 Constructs the WSGI application based on Pyramid and wraps the Pylons based
113 Constructs the WSGI application based on Pyramid and wraps the Pylons based
114 application.
114 application.
115
115
116 Specials:
116 Specials:
117
117
118 * We migrate from Pylons to Pyramid. While doing this, we keep both
118 * We migrate from Pylons to Pyramid. While doing this, we keep both
119 frameworks functional. This involves moving some WSGI middlewares around
119 frameworks functional. This involves moving some WSGI middlewares around
120 and providing access to some data internals, so that the old code is
120 and providing access to some data internals, so that the old code is
121 still functional.
121 still functional.
122
122
123 * The application can also be integrated like a plugin via the call to
123 * The application can also be integrated like a plugin via the call to
124 `includeme`. This is accompanied with the other utility functions which
124 `includeme`. This is accompanied with the other utility functions which
125 are called. Changing this should be done with great care to not break
125 are called. Changing this should be done with great care to not break
126 cases when these fragments are assembled from another place.
126 cases when these fragments are assembled from another place.
127
127
128 """
128 """
129 # The edition string should be available in pylons too, so we add it here
129 # The edition string should be available in pylons too, so we add it here
130 # before copying the settings.
130 # before copying the settings.
131 settings.setdefault('rhodecode.edition', 'Community Edition')
131 settings.setdefault('rhodecode.edition', 'Community Edition')
132
132
133 # As long as our Pylons application does expect "unprepared" settings, make
133 # As long as our Pylons application does expect "unprepared" settings, make
134 # sure that we keep an unmodified copy. This avoids unintentional change of
134 # sure that we keep an unmodified copy. This avoids unintentional change of
135 # behavior in the old application.
135 # behavior in the old application.
136 settings_pylons = settings.copy()
136 settings_pylons = settings.copy()
137
137
138 sanitize_settings_and_apply_defaults(settings)
138 sanitize_settings_and_apply_defaults(settings)
139 config = Configurator(settings=settings)
139 config = Configurator(settings=settings)
140 add_pylons_compat_data(config.registry, global_config, settings_pylons)
140 add_pylons_compat_data(config.registry, global_config, settings_pylons)
141
141
142 load_pyramid_environment(global_config, settings)
142 load_pyramid_environment(global_config, settings)
143
143
144 includeme(config)
144 includeme(config)
145 includeme_last(config)
145 includeme_last(config)
146 pyramid_app = config.make_wsgi_app()
146 pyramid_app = config.make_wsgi_app()
147 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
147 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
148 return pyramid_app
148 return pyramid_app
149
149
150
150
151 def add_pylons_compat_data(registry, global_config, settings):
151 def add_pylons_compat_data(registry, global_config, settings):
152 """
152 """
153 Attach data to the registry to support the Pylons integration.
153 Attach data to the registry to support the Pylons integration.
154 """
154 """
155 registry._pylons_compat_global_config = global_config
155 registry._pylons_compat_global_config = global_config
156 registry._pylons_compat_settings = settings
156 registry._pylons_compat_settings = settings
157
157
158
158
159 def webob_to_pyramid_http_response(webob_response):
159 def webob_to_pyramid_http_response(webob_response):
160 ResponseClass = httpexceptions.status_map[webob_response.status_int]
160 ResponseClass = httpexceptions.status_map[webob_response.status_int]
161 pyramid_response = ResponseClass(webob_response.status)
161 pyramid_response = ResponseClass(webob_response.status)
162 pyramid_response.status = webob_response.status
162 pyramid_response.status = webob_response.status
163 pyramid_response.headers.update(webob_response.headers)
163 pyramid_response.headers.update(webob_response.headers)
164 if pyramid_response.headers['content-type'] == 'text/html':
164 if pyramid_response.headers['content-type'] == 'text/html':
165 pyramid_response.headers['content-type'] = 'text/html; charset=UTF-8'
165 pyramid_response.headers['content-type'] = 'text/html; charset=UTF-8'
166 return pyramid_response
166 return pyramid_response
167
167
168
168
169 def error_handler(exception, request):
169 def error_handler(exception, request):
170 # TODO: dan: replace the old pylons error controller with this
170 # TODO: dan: replace the old pylons error controller with this
171 from rhodecode.model.settings import SettingsModel
171 from rhodecode.model.settings import SettingsModel
172 from rhodecode.lib.utils2 import AttributeDict
172 from rhodecode.lib.utils2 import AttributeDict
173
173
174 try:
174 try:
175 rc_config = SettingsModel().get_all_settings()
175 rc_config = SettingsModel().get_all_settings()
176 except Exception:
176 except Exception:
177 log.exception('failed to fetch settings')
177 log.exception('failed to fetch settings')
178 rc_config = {}
178 rc_config = {}
179
179
180 base_response = HTTPInternalServerError()
180 base_response = HTTPInternalServerError()
181 # prefer original exception for the response since it may have headers set
181 # prefer original exception for the response since it may have headers set
182 if isinstance(exception, HTTPError):
182 if isinstance(exception, HTTPError):
183 base_response = exception
183 base_response = exception
184
184
185 c = AttributeDict()
185 c = AttributeDict()
186 c.error_message = base_response.status
186 c.error_message = base_response.status
187 c.error_explanation = base_response.explanation or str(base_response)
187 c.error_explanation = base_response.explanation or str(base_response)
188 c.visual = AttributeDict()
188 c.visual = AttributeDict()
189
189
190 c.visual.rhodecode_support_url = (
190 c.visual.rhodecode_support_url = (
191 request.registry.settings.get('rhodecode_support_url') or
191 request.registry.settings.get('rhodecode_support_url') or
192 request.route_url('rhodecode_support')
192 request.route_url('rhodecode_support')
193 )
193 )
194 c.redirect_time = 0
194 c.redirect_time = 0
195 c.rhodecode_name = rc_config.get('rhodecode_title', '')
195 c.rhodecode_name = rc_config.get('rhodecode_title', '')
196 if not c.rhodecode_name:
196 if not c.rhodecode_name:
197 c.rhodecode_name = 'Rhodecode'
197 c.rhodecode_name = 'Rhodecode'
198
198
199 response = render_to_response(
199 response = render_to_response(
200 '/errors/error_document.html', {'c': c}, request=request,
200 '/errors/error_document.html', {'c': c}, request=request,
201 response=base_response)
201 response=base_response)
202
202
203 return response
203 return response
204
204
205
205
206 def includeme(config):
206 def includeme(config):
207 settings = config.registry.settings
207 settings = config.registry.settings
208
208
209 if asbool(settings.get('appenlight', 'false')):
209 if asbool(settings.get('appenlight', 'false')):
210 config.include('appenlight_client.ext.pyramid_tween')
210 config.include('appenlight_client.ext.pyramid_tween')
211
211
212 # Includes which are required. The application would fail without them.
212 # Includes which are required. The application would fail without them.
213 config.include('pyramid_mako')
213 config.include('pyramid_mako')
214 config.include('pyramid_beaker')
214 config.include('pyramid_beaker')
215 config.include('rhodecode.admin')
215 config.include('rhodecode.admin')
216 config.include('rhodecode.authentication')
216 config.include('rhodecode.authentication')
217 config.include('rhodecode.integrations')
217 config.include('rhodecode.integrations')
218 config.include('rhodecode.login')
218 config.include('rhodecode.login')
219 config.include('rhodecode.tweens')
219 config.include('rhodecode.tweens')
220 config.include('rhodecode.api')
220 config.include('rhodecode.api')
221 config.add_route(
221 config.add_route(
222 'rhodecode_support', 'https://rhodecode.com/help/', static=True)
222 'rhodecode_support', 'https://rhodecode.com/help/', static=True)
223
223
224 # Set the authorization policy.
224 # Set the authorization policy.
225 authz_policy = ACLAuthorizationPolicy()
225 authz_policy = ACLAuthorizationPolicy()
226 config.set_authorization_policy(authz_policy)
226 config.set_authorization_policy(authz_policy)
227
227
228 # Set the default renderer for HTML templates to mako.
228 # Set the default renderer for HTML templates to mako.
229 config.add_mako_renderer('.html')
229 config.add_mako_renderer('.html')
230
230
231 # plugin information
231 # plugin information
232 config.registry.rhodecode_plugins = {}
232 config.registry.rhodecode_plugins = {}
233
233
234 config.add_directive(
234 config.add_directive(
235 'register_rhodecode_plugin', register_rhodecode_plugin)
235 'register_rhodecode_plugin', register_rhodecode_plugin)
236 # include RhodeCode plugins
236 # include RhodeCode plugins
237 includes = aslist(settings.get('rhodecode.includes', []))
237 includes = aslist(settings.get('rhodecode.includes', []))
238 for inc in includes:
238 for inc in includes:
239 config.include(inc)
239 config.include(inc)
240
240
241 pylons_app = make_app(
241 pylons_app = make_app(
242 config.registry._pylons_compat_global_config,
242 config.registry._pylons_compat_global_config,
243 **config.registry._pylons_compat_settings)
243 **config.registry._pylons_compat_settings)
244 config.registry._pylons_compat_config = pylons_app.config
244 config.registry._pylons_compat_config = pylons_app.config
245
245
246 pylons_app_as_view = wsgiapp(pylons_app)
246 pylons_app_as_view = wsgiapp(pylons_app)
247
247
248 # Protect from VCS Server error related pages when server is not available
248 # Protect from VCS Server error related pages when server is not available
249 vcs_server_enabled = asbool(settings.get('vcs.server.enable', 'true'))
249 vcs_server_enabled = asbool(settings.get('vcs.server.enable', 'true'))
250 if not vcs_server_enabled:
250 if not vcs_server_enabled:
251 pylons_app_as_view = DisableVCSPagesWrapper(pylons_app_as_view)
251 pylons_app_as_view = DisableVCSPagesWrapper(pylons_app_as_view)
252
252
253
253
254 def pylons_app_with_error_handler(context, request):
254 def pylons_app_with_error_handler(context, request):
255 """
255 """
256 Handle exceptions from rc pylons app:
256 Handle exceptions from rc pylons app:
257
257
258 - old webob type exceptions get converted to pyramid exceptions
258 - old webob type exceptions get converted to pyramid exceptions
259 - pyramid exceptions are passed to the error handler view
259 - pyramid exceptions are passed to the error handler view
260 """
260 """
261 try:
261 try:
262 response = pylons_app_as_view(context, request)
262 response = pylons_app_as_view(context, request)
263 if 400 <= response.status_int <= 599: # webob type error responses
263 if 400 <= response.status_int <= 599: # webob type error responses
264 return error_handler(
264 return error_handler(
265 webob_to_pyramid_http_response(response), request)
265 webob_to_pyramid_http_response(response), request)
266 except HTTPError as e: # pyramid type exceptions
266 except HTTPError as e: # pyramid type exceptions
267 return error_handler(e, request)
267 return error_handler(e, request)
268 except Exception:
268 except Exception:
269 if settings.get('debugtoolbar.enabled', False):
269 if settings.get('debugtoolbar.enabled', False):
270 raise
270 raise
271 return error_handler(HTTPInternalServerError(), request)
271 return error_handler(HTTPInternalServerError(), request)
272 return response
272 return response
273
273
274 # This is the glue which allows us to migrate in chunks. By registering the
274 # This is the glue which allows us to migrate in chunks. By registering the
275 # pylons based application as the "Not Found" view in Pyramid, we will
275 # pylons based application as the "Not Found" view in Pyramid, we will
276 # fallback to the old application each time the new one does not yet know
276 # fallback to the old application each time the new one does not yet know
277 # how to handle a request.
277 # how to handle a request.
278 config.add_notfound_view(pylons_app_with_error_handler)
278 config.add_notfound_view(pylons_app_with_error_handler)
279
279
280 if settings.get('debugtoolbar.enabled', False):
280 if not settings.get('debugtoolbar.enabled', False):
281 # if toolbar, then only http type exceptions get caught and rendered
282 ExcClass = HTTPError
283 else:
284 # if no toolbar, then any exception gets caught and rendered
281 # if no toolbar, then any exception gets caught and rendered
285 ExcClass = Exception
282 config.add_view(error_handler, context=Exception)
286 config.add_view(error_handler, context=ExcClass)
283
284 config.add_view(error_handler, context=HTTPError)
287
285
288
286
289 def includeme_last(config):
287 def includeme_last(config):
290 """
288 """
291 The static file catchall needs to be last in the view configuration.
289 The static file catchall needs to be last in the view configuration.
292 """
290 """
293 settings = config.registry.settings
291 settings = config.registry.settings
294
292
295 # Note: johbo: I would prefer to register a prefix for static files at some
293 # Note: johbo: I would prefer to register a prefix for static files at some
296 # point, e.g. move them under '_static/'. This would fully avoid that we
294 # point, e.g. move them under '_static/'. This would fully avoid that we
297 # can have name clashes with a repository name. Imaging someone calling his
295 # can have name clashes with a repository name. Imaging someone calling his
298 # repo "css" ;-) Also having an external web server to serve out the static
296 # repo "css" ;-) Also having an external web server to serve out the static
299 # files seems to be easier to set up if they have a common prefix.
297 # files seems to be easier to set up if they have a common prefix.
300 #
298 #
301 # Example: config.add_static_view('_static', path='rhodecode:public')
299 # Example: config.add_static_view('_static', path='rhodecode:public')
302 #
300 #
303 # It might be an option to register both paths for a while and then migrate
301 # It might be an option to register both paths for a while and then migrate
304 # over to the new location.
302 # over to the new location.
305
303
306 # Serving static files with a catchall.
304 # Serving static files with a catchall.
307 if settings['static_files']:
305 if settings['static_files']:
308 config.add_route('catchall_static', '/*subpath')
306 config.add_route('catchall_static', '/*subpath')
309 config.add_view(
307 config.add_view(
310 static_view('rhodecode:public'), route_name='catchall_static')
308 static_view('rhodecode:public'), route_name='catchall_static')
311
309
312
310
313 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
311 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
314 """
312 """
315 Apply outer WSGI middlewares around the application.
313 Apply outer WSGI middlewares around the application.
316
314
317 Part of this has been moved up from the Pylons layer, so that the
315 Part of this has been moved up from the Pylons layer, so that the
318 data is also available if old Pylons code is hit through an already ported
316 data is also available if old Pylons code is hit through an already ported
319 view.
317 view.
320 """
318 """
321 settings = config.registry.settings
319 settings = config.registry.settings
322
320
323 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
321 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
324 pyramid_app = HttpsFixup(pyramid_app, settings)
322 pyramid_app = HttpsFixup(pyramid_app, settings)
325
323
326 # Add RoutesMiddleware to support the pylons compatibility tween during
324 # Add RoutesMiddleware to support the pylons compatibility tween during
327
325
328 # migration to pyramid.
326 # migration to pyramid.
329 pyramid_app = RoutesMiddleware(
327 pyramid_app = RoutesMiddleware(
330 pyramid_app, config.registry._pylons_compat_config['routes.map'])
328 pyramid_app, config.registry._pylons_compat_config['routes.map'])
331
329
332 if asbool(settings.get('appenlight', 'false')):
330 if asbool(settings.get('appenlight', 'false')):
333 pyramid_app, _ = wrap_in_appenlight_if_enabled(
331 pyramid_app, _ = wrap_in_appenlight_if_enabled(
334 pyramid_app, config.registry._pylons_compat_config)
332 pyramid_app, config.registry._pylons_compat_config)
335
333
336 # TODO: johbo: Don't really see why we enable the gzip middleware when
334 # TODO: johbo: Don't really see why we enable the gzip middleware when
337 # serving static files, might be something that should have its own setting
335 # serving static files, might be something that should have its own setting
338 # as well?
336 # as well?
339 if settings['static_files']:
337 if settings['static_files']:
340 pyramid_app = make_gzip_middleware(
338 pyramid_app = make_gzip_middleware(
341 pyramid_app, settings, compress_level=1)
339 pyramid_app, settings, compress_level=1)
342
340
343 return pyramid_app
341 return pyramid_app
344
342
345
343
346 def sanitize_settings_and_apply_defaults(settings):
344 def sanitize_settings_and_apply_defaults(settings):
347 """
345 """
348 Applies settings defaults and does all type conversion.
346 Applies settings defaults and does all type conversion.
349
347
350 We would move all settings parsing and preparation into this place, so that
348 We would move all settings parsing and preparation into this place, so that
351 we have only one place left which deals with this part. The remaining parts
349 we have only one place left which deals with this part. The remaining parts
352 of the application would start to rely fully on well prepared settings.
350 of the application would start to rely fully on well prepared settings.
353
351
354 This piece would later be split up per topic to avoid a big fat monster
352 This piece would later be split up per topic to avoid a big fat monster
355 function.
353 function.
356 """
354 """
357
355
358 # Pyramid's mako renderer has to search in the templates folder so that the
356 # Pyramid's mako renderer has to search in the templates folder so that the
359 # old templates still work. Ported and new templates are expected to use
357 # old templates still work. Ported and new templates are expected to use
360 # real asset specifications for the includes.
358 # real asset specifications for the includes.
361 mako_directories = settings.setdefault('mako.directories', [
359 mako_directories = settings.setdefault('mako.directories', [
362 # Base templates of the original Pylons application
360 # Base templates of the original Pylons application
363 'rhodecode:templates',
361 'rhodecode:templates',
364 ])
362 ])
365 log.debug(
363 log.debug(
366 "Using the following Mako template directories: %s",
364 "Using the following Mako template directories: %s",
367 mako_directories)
365 mako_directories)
368
366
369 # Default includes, possible to change as a user
367 # Default includes, possible to change as a user
370 pyramid_includes = settings.setdefault('pyramid.includes', [
368 pyramid_includes = settings.setdefault('pyramid.includes', [
371 'rhodecode.lib.middleware.request_wrapper',
369 'rhodecode.lib.middleware.request_wrapper',
372 ])
370 ])
373 log.debug(
371 log.debug(
374 "Using the following pyramid.includes: %s",
372 "Using the following pyramid.includes: %s",
375 pyramid_includes)
373 pyramid_includes)
376
374
377 # TODO: johbo: Re-think this, usually the call to config.include
375 # TODO: johbo: Re-think this, usually the call to config.include
378 # should allow to pass in a prefix.
376 # should allow to pass in a prefix.
379 settings.setdefault('rhodecode.api.url', '/_admin/api')
377 settings.setdefault('rhodecode.api.url', '/_admin/api')
380
378
381 _bool_setting(settings, 'vcs.server.enable', 'true')
379 _bool_setting(settings, 'vcs.server.enable', 'true')
382 _bool_setting(settings, 'static_files', 'true')
380 _bool_setting(settings, 'static_files', 'true')
383 _bool_setting(settings, 'is_test', 'false')
381 _bool_setting(settings, 'is_test', 'false')
384
382
385 return settings
383 return settings
386
384
387
385
388 def _bool_setting(settings, name, default):
386 def _bool_setting(settings, name, default):
389 settings[name] = asbool(settings.get(name, default))
387 settings[name] = asbool(settings.get(name, default))
General Comments 0
You need to be logged in to leave comments. Login now