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