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