##// END OF EJS Templates
config: Move initial repo scan up to the pyramid layer....
Martin Bornhold -
r580:b2c504de default
parent child Browse files
Show More
@@ -1,199 +1,196 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 """
22 22 Pylons environment configuration
23 23 """
24 24
25 25 import os
26 26 import logging
27 27 import rhodecode
28 28 import platform
29 29 import re
30 30 import io
31 31
32 32 from mako.lookup import TemplateLookup
33 33 from pylons.configuration import PylonsConfig
34 34 from pylons.error import handle_mako_error
35 35 from pyramid.settings import asbool
36 36
37 37 # don't remove this import it does magic for celery
38 38 from rhodecode.lib import celerypylons # noqa
39 39
40 40 import rhodecode.lib.app_globals as app_globals
41 41
42 42 from rhodecode.config import utils
43 43 from rhodecode.config.routing import make_map
44 44 from rhodecode.config.jsroutes import generate_jsroutes_content
45 45
46 46 from rhodecode.lib import helpers
47 47 from rhodecode.lib.auth import set_available_permissions
48 48 from rhodecode.lib.utils import (
49 49 repo2db_mapper, make_db_config, set_rhodecode_config,
50 50 load_rcextensions)
51 51 from rhodecode.lib.utils2 import str2bool, aslist
52 52 from rhodecode.lib.vcs import connect_vcs, start_vcs_server
53 53 from rhodecode.model.scm import ScmModel
54 54
55 55 log = logging.getLogger(__name__)
56 56
57 57 def load_environment(global_conf, app_conf, initial=False,
58 58 test_env=None, test_index=None):
59 59 """
60 60 Configure the Pylons environment via the ``pylons.config``
61 61 object
62 62 """
63 63 config = PylonsConfig()
64 64
65 65
66 66 # Pylons paths
67 67 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
68 68 paths = {
69 69 'root': root,
70 70 'controllers': os.path.join(root, 'controllers'),
71 71 'static_files': os.path.join(root, 'public'),
72 72 'templates': [os.path.join(root, 'templates')],
73 73 }
74 74
75 75 # Initialize config with the basic options
76 76 config.init_app(global_conf, app_conf, package='rhodecode', paths=paths)
77 77
78 78 # store some globals into rhodecode
79 79 rhodecode.CELERY_ENABLED = str2bool(config['app_conf'].get('use_celery'))
80 80 rhodecode.CELERY_EAGER = str2bool(
81 81 config['app_conf'].get('celery.always.eager'))
82 82
83 83 config['routes.map'] = make_map(config)
84 84
85 85 if asbool(config.get('generate_js_files', 'false')):
86 86 jsroutes = config['routes.map'].jsroutes()
87 87 jsroutes_file_content = generate_jsroutes_content(jsroutes)
88 88 jsroutes_file_path = os.path.join(
89 89 paths['static_files'], 'js', 'rhodecode', 'routes.js')
90 90
91 91 with io.open(jsroutes_file_path, 'w', encoding='utf-8') as f:
92 92 f.write(jsroutes_file_content)
93 93
94 94 config['pylons.app_globals'] = app_globals.Globals(config)
95 95 config['pylons.h'] = helpers
96 96 rhodecode.CONFIG = config
97 97
98 98 load_rcextensions(root_path=config['here'])
99 99
100 100 # Setup cache object as early as possible
101 101 import pylons
102 102 pylons.cache._push_object(config['pylons.app_globals'].cache)
103 103
104 104 # Create the Mako TemplateLookup, with the default auto-escaping
105 105 config['pylons.app_globals'].mako_lookup = TemplateLookup(
106 106 directories=paths['templates'],
107 107 error_handler=handle_mako_error,
108 108 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
109 109 input_encoding='utf-8', default_filters=['escape'],
110 110 imports=['from webhelpers.html import escape'])
111 111
112 112 # sets the c attribute access when don't existing attribute are accessed
113 113 config['pylons.strict_tmpl_context'] = True
114 114
115 115 # configure channelstream
116 116 config['channelstream_config'] = {
117 117 'enabled': asbool(config.get('channelstream.enabled', False)),
118 118 'server': config.get('channelstream.server'),
119 119 'secret': config.get('channelstream.secret')
120 120 }
121 121
122 122 # Limit backends to "vcs.backends" from configuration
123 123 backends = config['vcs.backends'] = aslist(
124 124 config.get('vcs.backends', 'hg,git'), sep=',')
125 125 for alias in rhodecode.BACKENDS.keys():
126 126 if alias not in backends:
127 127 del rhodecode.BACKENDS[alias]
128 128 log.info("Enabled backends: %s", backends)
129 129
130 130 # initialize vcs client and optionally run the server if enabled
131 131 vcs_server_uri = config.get('vcs.server', '')
132 132 vcs_server_enabled = str2bool(config.get('vcs.server.enable', 'true'))
133 133 start_server = (
134 134 str2bool(config.get('vcs.start_server', 'false')) and
135 135 not int(os.environ.get('RC_VCSSERVER_TEST_DISABLE', '0')))
136 136 if vcs_server_enabled and start_server:
137 137 log.info("Starting vcsserver")
138 138 start_vcs_server(server_and_port=vcs_server_uri,
139 139 protocol=utils.get_vcs_server_protocol(config),
140 140 log_level=config['vcs.server.log_level'])
141 141
142 142 set_available_permissions(config)
143 143 db_cfg = make_db_config(clear_session=True)
144 144
145 145 repos_path = list(db_cfg.items('paths'))[0][1]
146 146 config['base_path'] = repos_path
147 147
148 148 config['vcs.hooks.direct_calls'] = _use_direct_hook_calls(config)
149 149 config['vcs.hooks.protocol'] = _get_vcs_hooks_protocol(config)
150 150
151 151 # store db config also in main global CONFIG
152 152 set_rhodecode_config(config)
153 153
154 154 # configure instance id
155 155 utils.set_instance_id(config)
156 156
157 157 # CONFIGURATION OPTIONS HERE (note: all config options will override
158 158 # any Pylons config options)
159 159
160 160 # store config reference into our module to skip import magic of pylons
161 161 rhodecode.CONFIG.update(config)
162 162
163 163 utils.configure_pyro4(config)
164 164 utils.configure_vcs(config)
165 165 if vcs_server_enabled:
166 166 connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(config))
167 167
168 import_on_startup = str2bool(config.get('startup.import_repos', False))
169 if vcs_server_enabled and import_on_startup:
170 repo2db_mapper(ScmModel().repo_scan(repos_path), remove_obsolete=False)
171 168 return config
172 169
173 170
174 171 def _use_direct_hook_calls(config):
175 172 default_direct_hook_calls = 'false'
176 173 direct_hook_calls = str2bool(
177 174 config.get('vcs.hooks.direct_calls', default_direct_hook_calls))
178 175 return direct_hook_calls
179 176
180 177
181 178 def _get_vcs_hooks_protocol(config):
182 179 protocol = config.get('vcs.hooks.protocol', 'pyro4').lower()
183 180 return protocol
184 181
185 182
186 183 def load_pyramid_environment(global_config, settings):
187 184 # Some parts of the code expect a merge of global and app settings.
188 185 settings_merged = global_config.copy()
189 186 settings_merged.update(settings)
190 187
191 188 # If this is a test run we prepare the test environment like
192 189 # creating a test database, test search index and test repositories.
193 190 # This has to be done before the database connection is initialized.
194 191 if settings['is_test']:
195 192 rhodecode.is_test = True
196 193 utils.initialize_test_environment(settings_merged)
197 194
198 195 # Initialize the database connection.
199 196 utils.initialize_database(settings_merged)
@@ -1,404 +1,409 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 """
22 22 Pylons middleware initialization
23 23 """
24 24 import logging
25 25 from collections import OrderedDict
26 26
27 27 from paste.registry import RegistryManager
28 28 from paste.gzipper import make_gzip_middleware
29 29 from pylons.wsgiapp import PylonsApp
30 30 from pyramid.authorization import ACLAuthorizationPolicy
31 31 from pyramid.config import Configurator
32 32 from pyramid.static import static_view
33 33 from pyramid.settings import asbool, aslist
34 34 from pyramid.wsgi import wsgiapp
35 35 from pyramid.httpexceptions import HTTPError, HTTPInternalServerError
36 36 from pylons.controllers.util import abort, redirect
37 from pyramid.events import ApplicationCreated
37 38 import pyramid.httpexceptions as httpexceptions
38 39 from pyramid.renderers import render_to_response, render
39 40 from routes.middleware import RoutesMiddleware
40 41 import routes.util
41 42
42 43 import rhodecode
43 44 import rhodecode.integrations # do not remove this as it registers celery tasks
44 45 from rhodecode.config import patches
45 46 from rhodecode.config.routing import STATIC_FILE_PREFIX
46 47 from rhodecode.config.environment import (
47 48 load_environment, load_pyramid_environment)
48 49 from rhodecode.lib.middleware import csrf
49 50 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
50 51 from rhodecode.lib.middleware.disable_vcs import DisableVCSPagesWrapper
51 52 from rhodecode.lib.middleware.https_fixup import HttpsFixup
52 53 from rhodecode.lib.middleware.vcs import VCSMiddleware
53 54 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
55 from rhodecode.subscribers import scan_repositories_if_enabled
54 56
55 57
56 58 log = logging.getLogger(__name__)
57 59
58 60
59 61 # this is used to avoid avoid the route lookup overhead in routesmiddleware
60 62 # for certain routes which won't go to pylons to - eg. static files, debugger
61 63 # it is only needed for the pylons migration and can be removed once complete
62 64 class SkippableRoutesMiddleware(RoutesMiddleware):
63 65 """ Routes middleware that allows you to skip prefixes """
64 66
65 67 def __init__(self, *args, **kw):
66 68 self.skip_prefixes = kw.pop('skip_prefixes', [])
67 69 super(SkippableRoutesMiddleware, self).__init__(*args, **kw)
68 70
69 71 def __call__(self, environ, start_response):
70 72 for prefix in self.skip_prefixes:
71 73 if environ['PATH_INFO'].startswith(prefix):
72 74 # added to avoid the case when a missing /_static route falls
73 75 # through to pylons and causes an exception as pylons is
74 76 # expecting wsgiorg.routingargs to be set in the environ
75 77 # by RoutesMiddleware.
76 78 if 'wsgiorg.routing_args' not in environ:
77 79 environ['wsgiorg.routing_args'] = (None, {})
78 80 return self.app(environ, start_response)
79 81
80 82 return super(SkippableRoutesMiddleware, self).__call__(
81 83 environ, start_response)
82 84
83 85
84 86 def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
85 87 """Create a Pylons WSGI application and return it
86 88
87 89 ``global_conf``
88 90 The inherited configuration for this application. Normally from
89 91 the [DEFAULT] section of the Paste ini file.
90 92
91 93 ``full_stack``
92 94 Whether or not this application provides a full WSGI stack (by
93 95 default, meaning it handles its own exceptions and errors).
94 96 Disable full_stack when this application is "managed" by
95 97 another WSGI middleware.
96 98
97 99 ``app_conf``
98 100 The application's local configuration. Normally specified in
99 101 the [app:<name>] section of the Paste ini file (where <name>
100 102 defaults to main).
101 103
102 104 """
103 105 # Apply compatibility patches
104 106 patches.kombu_1_5_1_python_2_7_11()
105 107 patches.inspect_getargspec()
106 108
107 109 # Configure the Pylons environment
108 110 config = load_environment(global_conf, app_conf)
109 111
110 112 # The Pylons WSGI app
111 113 app = PylonsApp(config=config)
112 114 if rhodecode.is_test:
113 115 app = csrf.CSRFDetector(app)
114 116
115 117 expected_origin = config.get('expected_origin')
116 118 if expected_origin:
117 119 # The API can be accessed from other Origins.
118 120 app = csrf.OriginChecker(app, expected_origin,
119 121 skip_urls=[routes.util.url_for('api')])
120 122
121 123
122 124 if asbool(full_stack):
123 125
124 126 # Appenlight monitoring and error handler
125 127 app, appenlight_client = wrap_in_appenlight_if_enabled(app, config)
126 128
127 129 # we want our low level middleware to get to the request ASAP. We don't
128 130 # need any pylons stack middleware in them
129 131 app = VCSMiddleware(app, config, appenlight_client)
130 132
131 133 # Establish the Registry for this application
132 134 app = RegistryManager(app)
133 135
134 136 app.config = config
135 137
136 138 return app
137 139
138 140
139 141 def make_pyramid_app(global_config, **settings):
140 142 """
141 143 Constructs the WSGI application based on Pyramid and wraps the Pylons based
142 144 application.
143 145
144 146 Specials:
145 147
146 148 * We migrate from Pylons to Pyramid. While doing this, we keep both
147 149 frameworks functional. This involves moving some WSGI middlewares around
148 150 and providing access to some data internals, so that the old code is
149 151 still functional.
150 152
151 153 * The application can also be integrated like a plugin via the call to
152 154 `includeme`. This is accompanied with the other utility functions which
153 155 are called. Changing this should be done with great care to not break
154 156 cases when these fragments are assembled from another place.
155 157
156 158 """
157 159 # The edition string should be available in pylons too, so we add it here
158 160 # before copying the settings.
159 161 settings.setdefault('rhodecode.edition', 'Community Edition')
160 162
161 163 # As long as our Pylons application does expect "unprepared" settings, make
162 164 # sure that we keep an unmodified copy. This avoids unintentional change of
163 165 # behavior in the old application.
164 166 settings_pylons = settings.copy()
165 167
166 168 sanitize_settings_and_apply_defaults(settings)
167 169 config = Configurator(settings=settings)
168 170 add_pylons_compat_data(config.registry, global_config, settings_pylons)
169 171
170 172 load_pyramid_environment(global_config, settings)
171 173
172 174 includeme_first(config)
173 175 includeme(config)
174 176 pyramid_app = config.make_wsgi_app()
175 177 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
176 178 return pyramid_app
177 179
178 180
179 181 def add_pylons_compat_data(registry, global_config, settings):
180 182 """
181 183 Attach data to the registry to support the Pylons integration.
182 184 """
183 185 registry._pylons_compat_global_config = global_config
184 186 registry._pylons_compat_settings = settings
185 187
186 188
187 189 def webob_to_pyramid_http_response(webob_response):
188 190 ResponseClass = httpexceptions.status_map[webob_response.status_int]
189 191 pyramid_response = ResponseClass(webob_response.status)
190 192 pyramid_response.status = webob_response.status
191 193 pyramid_response.headers.update(webob_response.headers)
192 194 if pyramid_response.headers['content-type'] == 'text/html':
193 195 pyramid_response.headers['content-type'] = 'text/html; charset=UTF-8'
194 196 return pyramid_response
195 197
196 198
197 199 def error_handler(exception, request):
198 200 # TODO: dan: replace the old pylons error controller with this
199 201 from rhodecode.model.settings import SettingsModel
200 202 from rhodecode.lib.utils2 import AttributeDict
201 203
202 204 try:
203 205 rc_config = SettingsModel().get_all_settings()
204 206 except Exception:
205 207 log.exception('failed to fetch settings')
206 208 rc_config = {}
207 209
208 210 base_response = HTTPInternalServerError()
209 211 # prefer original exception for the response since it may have headers set
210 212 if isinstance(exception, HTTPError):
211 213 base_response = exception
212 214
213 215 c = AttributeDict()
214 216 c.error_message = base_response.status
215 217 c.error_explanation = base_response.explanation or str(base_response)
216 218 c.visual = AttributeDict()
217 219
218 220 c.visual.rhodecode_support_url = (
219 221 request.registry.settings.get('rhodecode_support_url') or
220 222 request.route_url('rhodecode_support')
221 223 )
222 224 c.redirect_time = 0
223 225 c.rhodecode_name = rc_config.get('rhodecode_title', '')
224 226 if not c.rhodecode_name:
225 227 c.rhodecode_name = 'Rhodecode'
226 228
227 229 response = render_to_response(
228 230 '/errors/error_document.html', {'c': c}, request=request,
229 231 response=base_response)
230 232
231 233 return response
232 234
233 235
234 236 def includeme(config):
235 237 settings = config.registry.settings
236 238
237 239 # plugin information
238 240 config.registry.rhodecode_plugins = OrderedDict()
239 241
240 242 config.add_directive(
241 243 'register_rhodecode_plugin', register_rhodecode_plugin)
242 244
243 245 if asbool(settings.get('appenlight', 'false')):
244 246 config.include('appenlight_client.ext.pyramid_tween')
245 247
246 248 # Includes which are required. The application would fail without them.
247 249 config.include('pyramid_mako')
248 250 config.include('pyramid_beaker')
249 251 config.include('rhodecode.channelstream')
250 252 config.include('rhodecode.admin')
251 253 config.include('rhodecode.authentication')
252 254 config.include('rhodecode.integrations')
253 255 config.include('rhodecode.login')
254 256 config.include('rhodecode.tweens')
255 257 config.include('rhodecode.api')
256 258 config.include('rhodecode.svn_support')
257 259 config.add_route(
258 260 'rhodecode_support', 'https://rhodecode.com/help/', static=True)
259 261
262 # Add subscribers.
263 config.add_subscriber(scan_repositories_if_enabled, ApplicationCreated)
264
260 265 # Set the authorization policy.
261 266 authz_policy = ACLAuthorizationPolicy()
262 267 config.set_authorization_policy(authz_policy)
263 268
264 269 # Set the default renderer for HTML templates to mako.
265 270 config.add_mako_renderer('.html')
266 271
267 272 # include RhodeCode plugins
268 273 includes = aslist(settings.get('rhodecode.includes', []))
269 274 for inc in includes:
270 275 config.include(inc)
271 276
272 277 pylons_app = make_app(
273 278 config.registry._pylons_compat_global_config,
274 279 **config.registry._pylons_compat_settings)
275 280 config.registry._pylons_compat_config = pylons_app.config
276 281
277 282 pylons_app_as_view = wsgiapp(pylons_app)
278 283
279 284 # Protect from VCS Server error related pages when server is not available
280 285 vcs_server_enabled = asbool(settings.get('vcs.server.enable', 'true'))
281 286 if not vcs_server_enabled:
282 287 pylons_app_as_view = DisableVCSPagesWrapper(pylons_app_as_view)
283 288
284 289
285 290 def pylons_app_with_error_handler(context, request):
286 291 """
287 292 Handle exceptions from rc pylons app:
288 293
289 294 - old webob type exceptions get converted to pyramid exceptions
290 295 - pyramid exceptions are passed to the error handler view
291 296 """
292 297 try:
293 298 response = pylons_app_as_view(context, request)
294 299 if 400 <= response.status_int <= 599: # webob type error responses
295 300 return error_handler(
296 301 webob_to_pyramid_http_response(response), request)
297 302 except HTTPError as e: # pyramid type exceptions
298 303 return error_handler(e, request)
299 304 except Exception:
300 305 if settings.get('debugtoolbar.enabled', False):
301 306 raise
302 307 return error_handler(HTTPInternalServerError(), request)
303 308 return response
304 309
305 310 # This is the glue which allows us to migrate in chunks. By registering the
306 311 # pylons based application as the "Not Found" view in Pyramid, we will
307 312 # fallback to the old application each time the new one does not yet know
308 313 # how to handle a request.
309 314 config.add_notfound_view(pylons_app_with_error_handler)
310 315
311 316 if not settings.get('debugtoolbar.enabled', False):
312 317 # if no toolbar, then any exception gets caught and rendered
313 318 config.add_view(error_handler, context=Exception)
314 319
315 320 config.add_view(error_handler, context=HTTPError)
316 321
317 322
318 323 def includeme_first(config):
319 324 # redirect automatic browser favicon.ico requests to correct place
320 325 def favicon_redirect(context, request):
321 326 return redirect(
322 327 request.static_path('rhodecode:public/images/favicon.ico'))
323 328
324 329 config.add_view(favicon_redirect, route_name='favicon')
325 330 config.add_route('favicon', '/favicon.ico')
326 331
327 332 config.add_static_view(
328 333 '_static/deform', 'deform:static')
329 334 config.add_static_view(
330 335 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
331 336
332 337 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
333 338 """
334 339 Apply outer WSGI middlewares around the application.
335 340
336 341 Part of this has been moved up from the Pylons layer, so that the
337 342 data is also available if old Pylons code is hit through an already ported
338 343 view.
339 344 """
340 345 settings = config.registry.settings
341 346
342 347 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
343 348 pyramid_app = HttpsFixup(pyramid_app, settings)
344 349
345 350 # Add RoutesMiddleware to support the pylons compatibility tween during
346 351 # migration to pyramid.
347 352 pyramid_app = SkippableRoutesMiddleware(
348 353 pyramid_app, config.registry._pylons_compat_config['routes.map'],
349 354 skip_prefixes=(STATIC_FILE_PREFIX, '/_debug_toolbar'))
350 355
351 356 if asbool(settings.get('appenlight', 'false')):
352 357 pyramid_app, _ = wrap_in_appenlight_if_enabled(
353 358 pyramid_app, config.registry._pylons_compat_config)
354 359
355 360 if asbool(settings.get('gzip_responses', 'true')):
356 361 pyramid_app = make_gzip_middleware(
357 362 pyramid_app, settings, compress_level=1)
358 363
359 364 return pyramid_app
360 365
361 366
362 367 def sanitize_settings_and_apply_defaults(settings):
363 368 """
364 369 Applies settings defaults and does all type conversion.
365 370
366 371 We would move all settings parsing and preparation into this place, so that
367 372 we have only one place left which deals with this part. The remaining parts
368 373 of the application would start to rely fully on well prepared settings.
369 374
370 375 This piece would later be split up per topic to avoid a big fat monster
371 376 function.
372 377 """
373 378
374 379 # Pyramid's mako renderer has to search in the templates folder so that the
375 380 # old templates still work. Ported and new templates are expected to use
376 381 # real asset specifications for the includes.
377 382 mako_directories = settings.setdefault('mako.directories', [
378 383 # Base templates of the original Pylons application
379 384 'rhodecode:templates',
380 385 ])
381 386 log.debug(
382 387 "Using the following Mako template directories: %s",
383 388 mako_directories)
384 389
385 390 # Default includes, possible to change as a user
386 391 pyramid_includes = settings.setdefault('pyramid.includes', [
387 392 'rhodecode.lib.middleware.request_wrapper',
388 393 ])
389 394 log.debug(
390 395 "Using the following pyramid.includes: %s",
391 396 pyramid_includes)
392 397
393 398 # TODO: johbo: Re-think this, usually the call to config.include
394 399 # should allow to pass in a prefix.
395 400 settings.setdefault('rhodecode.api.url', '/_admin/api')
396 401
397 402 _bool_setting(settings, 'vcs.server.enable', 'true')
398 403 _bool_setting(settings, 'is_test', 'false')
399 404
400 405 return settings
401 406
402 407
403 408 def _bool_setting(settings, name, default):
404 409 settings[name] = asbool(settings.get(name, default))
@@ -1,55 +1,70 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 22 import pylons
23 23
24 24 from pyramid.i18n import get_localizer
25 25 from pyramid.threadlocal import get_current_request
26 26
27 27 from rhodecode.translation import _ as tsf
28 28
29 29
30 30 def add_renderer_globals(event):
31 31 # Put pylons stuff into the context. This will be removed as soon as
32 32 # migration to pyramid is finished.
33 33 conf = pylons.config._current_obj()
34 34 event['h'] = conf.get('pylons.h')
35 35 event['c'] = pylons.tmpl_context
36 36 event['url'] = pylons.url
37 37
38 38 # TODO: When executed in pyramid view context the request is not available
39 39 # in the event. Find a better solution to get the request.
40 40 request = event['request'] or get_current_request()
41 41
42 42 # Add Pyramid translation as '_' to context
43 43 event['_'] = request.translate
44 44 event['localizer'] = request.localizer
45 45
46 46
47 47 def add_localizer(event):
48 48 request = event.request
49 49 localizer = get_localizer(request)
50 50
51 51 def auto_translate(*args, **kwargs):
52 52 return localizer.translate(tsf(*args, **kwargs))
53 53
54 54 request.localizer = localizer
55 55 request.translate = auto_translate
56
57
58 def scan_repositories_if_enabled(event):
59 """
60 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
61 does a repository scan if enabled in the settings.
62 """
63 from rhodecode.model.scm import ScmModel
64 from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_base_path
65 settings = event.app.registry.settings
66 vcs_server_enabled = settings['vcs.server.enable']
67 import_on_startup = settings['startup.import_repos']
68 if vcs_server_enabled and import_on_startup:
69 repositories = ScmModel().repo_scan(get_rhodecode_base_path())
70 repo2db_mapper(repositories, remove_obsolete=False)
General Comments 0
You need to be logged in to leave comments. Login now