##// END OF EJS Templates
fix(pyroutes): fixed generated JS routes for EE
super-admin -
r5257:557dc90c default
parent child Browse files
Show More
@@ -1,637 +1,637 b''
1 # Copyright (C) 2010-2023 RhodeCode GmbH
1 # Copyright (C) 2010-2023 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
5 # (only), as published by the Free Software Foundation.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU Affero General Public License
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
14 #
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 import os
19 import os
20 import sys
20 import sys
21 import collections
21 import collections
22 import tempfile
22 import tempfile
23 import time
23 import time
24 import logging.config
24 import logging.config
25
25
26 from paste.gzipper import make_gzip_middleware
26 from paste.gzipper import make_gzip_middleware
27 import pyramid.events
27 import pyramid.events
28 from pyramid.wsgi import wsgiapp
28 from pyramid.wsgi import wsgiapp
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.settings import asbool, aslist
31 from pyramid.settings import asbool, aslist
32 from pyramid.httpexceptions import (
32 from pyramid.httpexceptions import (
33 HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound)
33 HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound)
34 from pyramid.renderers import render_to_response
34 from pyramid.renderers import render_to_response
35
35
36 from rhodecode.model import meta
36 from rhodecode.model import meta
37 from rhodecode.config import patches
37 from rhodecode.config import patches
38 from rhodecode.config import utils as config_utils
38 from rhodecode.config import utils as config_utils
39 from rhodecode.config.settings_maker import SettingsMaker
39 from rhodecode.config.settings_maker import SettingsMaker
40 from rhodecode.config.environment import load_pyramid_environment
40 from rhodecode.config.environment import load_pyramid_environment
41
41
42 import rhodecode.events
42 import rhodecode.events
43 from rhodecode.lib.middleware.vcs import VCSMiddleware
43 from rhodecode.lib.middleware.vcs import VCSMiddleware
44 from rhodecode.lib.request import Request
44 from rhodecode.lib.request import Request
45 from rhodecode.lib.vcs import VCSCommunicationError
45 from rhodecode.lib.vcs import VCSCommunicationError
46 from rhodecode.lib.exceptions import VCSServerUnavailable
46 from rhodecode.lib.exceptions import VCSServerUnavailable
47 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
47 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
48 from rhodecode.lib.middleware.https_fixup import HttpsFixup
48 from rhodecode.lib.middleware.https_fixup import HttpsFixup
49 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
49 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
50 from rhodecode.lib.utils2 import AttributeDict
50 from rhodecode.lib.utils2 import AttributeDict
51 from rhodecode.lib.exc_tracking import store_exception, format_exc
51 from rhodecode.lib.exc_tracking import store_exception, format_exc
52 from rhodecode.subscribers import (
52 from rhodecode.subscribers import (
53 scan_repositories_if_enabled, write_js_routes_if_enabled,
53 scan_repositories_if_enabled, write_js_routes_if_enabled,
54 write_metadata_if_needed, write_usage_data)
54 write_metadata_if_needed, write_usage_data)
55 from rhodecode.lib.statsd_client import StatsdClient
55 from rhodecode.lib.statsd_client import StatsdClient
56
56
57 log = logging.getLogger(__name__)
57 log = logging.getLogger(__name__)
58
58
59
59
60 def is_http_error(response):
60 def is_http_error(response):
61 # error which should have traceback
61 # error which should have traceback
62 return response.status_code > 499
62 return response.status_code > 499
63
63
64
64
65 def should_load_all():
65 def should_load_all():
66 """
66 """
67 Returns if all application components should be loaded. In some cases it's
67 Returns if all application components should be loaded. In some cases it's
68 desired to skip apps loading for faster shell script execution
68 desired to skip apps loading for faster shell script execution
69 """
69 """
70 ssh_cmd = os.environ.get('RC_CMD_SSH_WRAPPER')
70 ssh_cmd = os.environ.get('RC_CMD_SSH_WRAPPER')
71 if ssh_cmd:
71 if ssh_cmd:
72 return False
72 return False
73
73
74 return True
74 return True
75
75
76
76
77 def make_pyramid_app(global_config, **settings):
77 def make_pyramid_app(global_config, **settings):
78 """
78 """
79 Constructs the WSGI application based on Pyramid.
79 Constructs the WSGI application based on Pyramid.
80
80
81 Specials:
81 Specials:
82
82
83 * The application can also be integrated like a plugin via the call to
83 * The application can also be integrated like a plugin via the call to
84 `includeme`. This is accompanied with the other utility functions which
84 `includeme`. This is accompanied with the other utility functions which
85 are called. Changing this should be done with great care to not break
85 are called. Changing this should be done with great care to not break
86 cases when these fragments are assembled from another place.
86 cases when these fragments are assembled from another place.
87
87
88 """
88 """
89 start_time = time.time()
89 start_time = time.time()
90 log.info('Pyramid app config starting')
90 log.info('Pyramid app config starting')
91
91
92 sanitize_settings_and_apply_defaults(global_config, settings)
92 sanitize_settings_and_apply_defaults(global_config, settings)
93
93
94 # init and bootstrap StatsdClient
94 # init and bootstrap StatsdClient
95 StatsdClient.setup(settings)
95 StatsdClient.setup(settings)
96
96
97 config = Configurator(settings=settings)
97 config = Configurator(settings=settings)
98 # Init our statsd at very start
98 # Init our statsd at very start
99 config.registry.statsd = StatsdClient.statsd
99 config.registry.statsd = StatsdClient.statsd
100
100
101 # Apply compatibility patches
101 # Apply compatibility patches
102 patches.inspect_getargspec()
102 patches.inspect_getargspec()
103
103
104 load_pyramid_environment(global_config, settings)
104 load_pyramid_environment(global_config, settings)
105
105
106 # Static file view comes first
106 # Static file view comes first
107 includeme_first(config)
107 includeme_first(config)
108
108
109 includeme(config)
109 includeme(config)
110
110
111 pyramid_app = config.make_wsgi_app()
111 pyramid_app = config.make_wsgi_app()
112 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
112 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
113 pyramid_app.config = config
113 pyramid_app.config = config
114
114
115 celery_settings = get_celery_config(settings)
115 celery_settings = get_celery_config(settings)
116 config.configure_celery(celery_settings)
116 config.configure_celery(celery_settings)
117
117
118 # creating the app uses a connection - return it after we are done
118 # creating the app uses a connection - return it after we are done
119 meta.Session.remove()
119 meta.Session.remove()
120
120
121 total_time = time.time() - start_time
121 total_time = time.time() - start_time
122 log.info('Pyramid app created and configured in %.2fs', total_time)
122 log.info('Pyramid app created and configured in %.2fs', total_time)
123 return pyramid_app
123 return pyramid_app
124
124
125
125
126 def get_celery_config(settings):
126 def get_celery_config(settings):
127 """
127 """
128 Converts basic ini configuration into celery 4.X options
128 Converts basic ini configuration into celery 4.X options
129 """
129 """
130
130
131 def key_converter(key_name):
131 def key_converter(key_name):
132 pref = 'celery.'
132 pref = 'celery.'
133 if key_name.startswith(pref):
133 if key_name.startswith(pref):
134 return key_name[len(pref):].replace('.', '_').lower()
134 return key_name[len(pref):].replace('.', '_').lower()
135
135
136 def type_converter(parsed_key, value):
136 def type_converter(parsed_key, value):
137 # cast to int
137 # cast to int
138 if value.isdigit():
138 if value.isdigit():
139 return int(value)
139 return int(value)
140
140
141 # cast to bool
141 # cast to bool
142 if value.lower() in ['true', 'false', 'True', 'False']:
142 if value.lower() in ['true', 'false', 'True', 'False']:
143 return value.lower() == 'true'
143 return value.lower() == 'true'
144 return value
144 return value
145
145
146 celery_config = {}
146 celery_config = {}
147 for k, v in settings.items():
147 for k, v in settings.items():
148 pref = 'celery.'
148 pref = 'celery.'
149 if k.startswith(pref):
149 if k.startswith(pref):
150 celery_config[key_converter(k)] = type_converter(key_converter(k), v)
150 celery_config[key_converter(k)] = type_converter(key_converter(k), v)
151
151
152 # TODO:rethink if we want to support celerybeat based file config, probably NOT
152 # TODO:rethink if we want to support celerybeat based file config, probably NOT
153 # beat_config = {}
153 # beat_config = {}
154 # for section in parser.sections():
154 # for section in parser.sections():
155 # if section.startswith('celerybeat:'):
155 # if section.startswith('celerybeat:'):
156 # name = section.split(':', 1)[1]
156 # name = section.split(':', 1)[1]
157 # beat_config[name] = get_beat_config(parser, section)
157 # beat_config[name] = get_beat_config(parser, section)
158
158
159 # final compose of settings
159 # final compose of settings
160 celery_settings = {}
160 celery_settings = {}
161
161
162 if celery_config:
162 if celery_config:
163 celery_settings.update(celery_config)
163 celery_settings.update(celery_config)
164 # if beat_config:
164 # if beat_config:
165 # celery_settings.update({'beat_schedule': beat_config})
165 # celery_settings.update({'beat_schedule': beat_config})
166
166
167 return celery_settings
167 return celery_settings
168
168
169
169
170 def not_found_view(request):
170 def not_found_view(request):
171 """
171 """
172 This creates the view which should be registered as not-found-view to
172 This creates the view which should be registered as not-found-view to
173 pyramid.
173 pyramid.
174 """
174 """
175
175
176 if not getattr(request, 'vcs_call', None):
176 if not getattr(request, 'vcs_call', None):
177 # handle like regular case with our error_handler
177 # handle like regular case with our error_handler
178 return error_handler(HTTPNotFound(), request)
178 return error_handler(HTTPNotFound(), request)
179
179
180 # handle not found view as a vcs call
180 # handle not found view as a vcs call
181 settings = request.registry.settings
181 settings = request.registry.settings
182 ae_client = getattr(request, 'ae_client', None)
182 ae_client = getattr(request, 'ae_client', None)
183 vcs_app = VCSMiddleware(
183 vcs_app = VCSMiddleware(
184 HTTPNotFound(), request.registry, settings,
184 HTTPNotFound(), request.registry, settings,
185 appenlight_client=ae_client)
185 appenlight_client=ae_client)
186
186
187 return wsgiapp(vcs_app)(None, request)
187 return wsgiapp(vcs_app)(None, request)
188
188
189
189
190 def error_handler(exception, request):
190 def error_handler(exception, request):
191 import rhodecode
191 import rhodecode
192 from rhodecode.lib import helpers
192 from rhodecode.lib import helpers
193
193
194 rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
194 rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
195
195
196 base_response = HTTPInternalServerError()
196 base_response = HTTPInternalServerError()
197 # prefer original exception for the response since it may have headers set
197 # prefer original exception for the response since it may have headers set
198 if isinstance(exception, HTTPException):
198 if isinstance(exception, HTTPException):
199 base_response = exception
199 base_response = exception
200 elif isinstance(exception, VCSCommunicationError):
200 elif isinstance(exception, VCSCommunicationError):
201 base_response = VCSServerUnavailable()
201 base_response = VCSServerUnavailable()
202
202
203 if is_http_error(base_response):
203 if is_http_error(base_response):
204 traceback_info = format_exc(request.exc_info)
204 traceback_info = format_exc(request.exc_info)
205 log.error(
205 log.error(
206 'error occurred handling this request for path: %s, \n%s',
206 'error occurred handling this request for path: %s, \n%s',
207 request.path, traceback_info)
207 request.path, traceback_info)
208
208
209 error_explanation = base_response.explanation or str(base_response)
209 error_explanation = base_response.explanation or str(base_response)
210 if base_response.status_code == 404:
210 if base_response.status_code == 404:
211 error_explanation += " Optionally you don't have permission to access this page."
211 error_explanation += " Optionally you don't have permission to access this page."
212 c = AttributeDict()
212 c = AttributeDict()
213 c.error_message = base_response.status
213 c.error_message = base_response.status
214 c.error_explanation = error_explanation
214 c.error_explanation = error_explanation
215 c.visual = AttributeDict()
215 c.visual = AttributeDict()
216
216
217 c.visual.rhodecode_support_url = (
217 c.visual.rhodecode_support_url = (
218 request.registry.settings.get('rhodecode_support_url') or
218 request.registry.settings.get('rhodecode_support_url') or
219 request.route_url('rhodecode_support')
219 request.route_url('rhodecode_support')
220 )
220 )
221 c.redirect_time = 0
221 c.redirect_time = 0
222 c.rhodecode_name = rhodecode_title
222 c.rhodecode_name = rhodecode_title
223 if not c.rhodecode_name:
223 if not c.rhodecode_name:
224 c.rhodecode_name = 'Rhodecode'
224 c.rhodecode_name = 'Rhodecode'
225
225
226 c.causes = []
226 c.causes = []
227 if is_http_error(base_response):
227 if is_http_error(base_response):
228 c.causes.append('Server is overloaded.')
228 c.causes.append('Server is overloaded.')
229 c.causes.append('Server database connection is lost.')
229 c.causes.append('Server database connection is lost.')
230 c.causes.append('Server expected unhandled error.')
230 c.causes.append('Server expected unhandled error.')
231
231
232 if hasattr(base_response, 'causes'):
232 if hasattr(base_response, 'causes'):
233 c.causes = base_response.causes
233 c.causes = base_response.causes
234
234
235 c.messages = helpers.flash.pop_messages(request=request)
235 c.messages = helpers.flash.pop_messages(request=request)
236 exc_info = sys.exc_info()
236 exc_info = sys.exc_info()
237 c.exception_id = id(exc_info)
237 c.exception_id = id(exc_info)
238 c.show_exception_id = isinstance(base_response, VCSServerUnavailable) \
238 c.show_exception_id = isinstance(base_response, VCSServerUnavailable) \
239 or base_response.status_code > 499
239 or base_response.status_code > 499
240 c.exception_id_url = request.route_url(
240 c.exception_id_url = request.route_url(
241 'admin_settings_exception_tracker_show', exception_id=c.exception_id)
241 'admin_settings_exception_tracker_show', exception_id=c.exception_id)
242
242
243 debug_mode = rhodecode.ConfigGet().get_bool('debug')
243 debug_mode = rhodecode.ConfigGet().get_bool('debug')
244 if c.show_exception_id:
244 if c.show_exception_id:
245 store_exception(c.exception_id, exc_info)
245 store_exception(c.exception_id, exc_info)
246 c.exception_debug = debug_mode
246 c.exception_debug = debug_mode
247 c.exception_config_ini = rhodecode.CONFIG.get('__file__')
247 c.exception_config_ini = rhodecode.CONFIG.get('__file__')
248
248
249 if debug_mode:
249 if debug_mode:
250 try:
250 try:
251 from rich.traceback import install
251 from rich.traceback import install
252 install(show_locals=True)
252 install(show_locals=True)
253 log.debug('Installing rich tracebacks...')
253 log.debug('Installing rich tracebacks...')
254 except ImportError:
254 except ImportError:
255 pass
255 pass
256
256
257 response = render_to_response(
257 response = render_to_response(
258 '/errors/error_document.mako', {'c': c, 'h': helpers}, request=request,
258 '/errors/error_document.mako', {'c': c, 'h': helpers}, request=request,
259 response=base_response)
259 response=base_response)
260
260
261 response.headers["X-RC-Exception-Id"] = str(c.exception_id)
261 response.headers["X-RC-Exception-Id"] = str(c.exception_id)
262
262
263 statsd = request.registry.statsd
263 statsd = request.registry.statsd
264 if statsd and base_response.status_code > 499:
264 if statsd and base_response.status_code > 499:
265 exc_type = f"{exception.__class__.__module__}.{exception.__class__.__name__}"
265 exc_type = f"{exception.__class__.__module__}.{exception.__class__.__name__}"
266 statsd.incr('rhodecode_exception_total',
266 statsd.incr('rhodecode_exception_total',
267 tags=["exc_source:web",
267 tags=["exc_source:web",
268 f"http_code:{base_response.status_code}",
268 f"http_code:{base_response.status_code}",
269 f"type:{exc_type}"])
269 f"type:{exc_type}"])
270
270
271 return response
271 return response
272
272
273
273
274 def includeme_first(config):
274 def includeme_first(config):
275 # redirect automatic browser favicon.ico requests to correct place
275 # redirect automatic browser favicon.ico requests to correct place
276 def favicon_redirect(context, request):
276 def favicon_redirect(context, request):
277 return HTTPFound(
277 return HTTPFound(
278 request.static_path('rhodecode:public/images/favicon.ico'))
278 request.static_path('rhodecode:public/images/favicon.ico'))
279
279
280 config.add_view(favicon_redirect, route_name='favicon')
280 config.add_view(favicon_redirect, route_name='favicon')
281 config.add_route('favicon', '/favicon.ico')
281 config.add_route('favicon', '/favicon.ico')
282
282
283 def robots_redirect(context, request):
283 def robots_redirect(context, request):
284 return HTTPFound(
284 return HTTPFound(
285 request.static_path('rhodecode:public/robots.txt'))
285 request.static_path('rhodecode:public/robots.txt'))
286
286
287 config.add_view(robots_redirect, route_name='robots')
287 config.add_view(robots_redirect, route_name='robots')
288 config.add_route('robots', '/robots.txt')
288 config.add_route('robots', '/robots.txt')
289
289
290 config.add_static_view(
290 config.add_static_view(
291 '_static/deform', 'deform:static')
291 '_static/deform', 'deform:static')
292 config.add_static_view(
292 config.add_static_view(
293 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
293 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
294
294
295
295
296 ce_auth_resources = [
296 ce_auth_resources = [
297 'rhodecode.authentication.plugins.auth_crowd',
297 'rhodecode.authentication.plugins.auth_crowd',
298 'rhodecode.authentication.plugins.auth_headers',
298 'rhodecode.authentication.plugins.auth_headers',
299 'rhodecode.authentication.plugins.auth_jasig_cas',
299 'rhodecode.authentication.plugins.auth_jasig_cas',
300 'rhodecode.authentication.plugins.auth_ldap',
300 'rhodecode.authentication.plugins.auth_ldap',
301 'rhodecode.authentication.plugins.auth_pam',
301 'rhodecode.authentication.plugins.auth_pam',
302 'rhodecode.authentication.plugins.auth_rhodecode',
302 'rhodecode.authentication.plugins.auth_rhodecode',
303 'rhodecode.authentication.plugins.auth_token',
303 'rhodecode.authentication.plugins.auth_token',
304 ]
304 ]
305
305
306
306
307 def includeme(config, auth_resources=None):
307 def includeme(config, auth_resources=None):
308 from rhodecode.lib.celerylib.loader import configure_celery
308 from rhodecode.lib.celerylib.loader import configure_celery
309 log.debug('Initializing main includeme from %s', os.path.basename(__file__))
309 log.debug('Initializing main includeme from %s', os.path.basename(__file__))
310 settings = config.registry.settings
310 settings = config.registry.settings
311 config.set_request_factory(Request)
311 config.set_request_factory(Request)
312
312
313 # plugin information
313 # plugin information
314 config.registry.rhodecode_plugins = collections.OrderedDict()
314 config.registry.rhodecode_plugins = collections.OrderedDict()
315
315
316 config.add_directive(
316 config.add_directive(
317 'register_rhodecode_plugin', register_rhodecode_plugin)
317 'register_rhodecode_plugin', register_rhodecode_plugin)
318
318
319 config.add_directive('configure_celery', configure_celery)
319 config.add_directive('configure_celery', configure_celery)
320
320
321 if settings.get('appenlight', False):
321 if settings.get('appenlight', False):
322 config.include('appenlight_client.ext.pyramid_tween')
322 config.include('appenlight_client.ext.pyramid_tween')
323
323
324 load_all = should_load_all()
324 load_all = should_load_all()
325
325
326 # Includes which are required. The application would fail without them.
326 # Includes which are required. The application would fail without them.
327 config.include('pyramid_mako')
327 config.include('pyramid_mako')
328 config.include('rhodecode.lib.rc_beaker')
328 config.include('rhodecode.lib.rc_beaker')
329 config.include('rhodecode.lib.rc_cache')
329 config.include('rhodecode.lib.rc_cache')
330 config.include('rhodecode.lib.rc_cache.archive_cache')
330 config.include('rhodecode.lib.rc_cache.archive_cache')
331
331
332 config.include('rhodecode.apps._base.navigation')
332 config.include('rhodecode.apps._base.navigation')
333 config.include('rhodecode.apps._base.subscribers')
333 config.include('rhodecode.apps._base.subscribers')
334 config.include('rhodecode.tweens')
334 config.include('rhodecode.tweens')
335 config.include('rhodecode.authentication')
335 config.include('rhodecode.authentication')
336
336
337 if load_all:
337 if load_all:
338
338
339 # load CE authentication plugins
339 # load CE authentication plugins
340
340
341 if auth_resources:
341 if auth_resources:
342 ce_auth_resources.extend(auth_resources)
342 ce_auth_resources.extend(auth_resources)
343
343
344 for resource in ce_auth_resources:
344 for resource in ce_auth_resources:
345 config.include(resource)
345 config.include(resource)
346
346
347 # Auto discover authentication plugins and include their configuration.
347 # Auto discover authentication plugins and include their configuration.
348 if asbool(settings.get('auth_plugin.import_legacy_plugins', 'true')):
348 if asbool(settings.get('auth_plugin.import_legacy_plugins', 'true')):
349 from rhodecode.authentication import discover_legacy_plugins
349 from rhodecode.authentication import discover_legacy_plugins
350 discover_legacy_plugins(config)
350 discover_legacy_plugins(config)
351
351
352 # apps
352 # apps
353 if load_all:
353 if load_all:
354 log.debug('Starting config.include() calls')
354 log.debug('Starting config.include() calls')
355 config.include('rhodecode.api.includeme')
355 config.include('rhodecode.api.includeme')
356 config.include('rhodecode.apps._base.includeme')
356 config.include('rhodecode.apps._base.includeme')
357 config.include('rhodecode.apps._base.navigation.includeme')
357 config.include('rhodecode.apps._base.navigation.includeme')
358 config.include('rhodecode.apps._base.subscribers.includeme')
358 config.include('rhodecode.apps._base.subscribers.includeme')
359 config.include('rhodecode.apps.hovercards.includeme')
359 config.include('rhodecode.apps.hovercards.includeme')
360 config.include('rhodecode.apps.ops.includeme')
360 config.include('rhodecode.apps.ops.includeme')
361 config.include('rhodecode.apps.channelstream.includeme')
361 config.include('rhodecode.apps.channelstream.includeme')
362 config.include('rhodecode.apps.file_store.includeme')
362 config.include('rhodecode.apps.file_store.includeme')
363 config.include('rhodecode.apps.admin.includeme')
363 config.include('rhodecode.apps.admin.includeme')
364 config.include('rhodecode.apps.login.includeme')
364 config.include('rhodecode.apps.login.includeme')
365 config.include('rhodecode.apps.home.includeme')
365 config.include('rhodecode.apps.home.includeme')
366 config.include('rhodecode.apps.journal.includeme')
366 config.include('rhodecode.apps.journal.includeme')
367
367
368 config.include('rhodecode.apps.repository.includeme')
368 config.include('rhodecode.apps.repository.includeme')
369 config.include('rhodecode.apps.repo_group.includeme')
369 config.include('rhodecode.apps.repo_group.includeme')
370 config.include('rhodecode.apps.user_group.includeme')
370 config.include('rhodecode.apps.user_group.includeme')
371 config.include('rhodecode.apps.search.includeme')
371 config.include('rhodecode.apps.search.includeme')
372 config.include('rhodecode.apps.user_profile.includeme')
372 config.include('rhodecode.apps.user_profile.includeme')
373 config.include('rhodecode.apps.user_group_profile.includeme')
373 config.include('rhodecode.apps.user_group_profile.includeme')
374 config.include('rhodecode.apps.my_account.includeme')
374 config.include('rhodecode.apps.my_account.includeme')
375 config.include('rhodecode.apps.gist.includeme')
375 config.include('rhodecode.apps.gist.includeme')
376
376
377 config.include('rhodecode.apps.svn_support.includeme')
377 config.include('rhodecode.apps.svn_support.includeme')
378 config.include('rhodecode.apps.ssh_support.includeme')
378 config.include('rhodecode.apps.ssh_support.includeme')
379 config.include('rhodecode.apps.debug_style')
379 config.include('rhodecode.apps.debug_style')
380
380
381 if load_all:
381 if load_all:
382 config.include('rhodecode.integrations.includeme')
382 config.include('rhodecode.integrations.includeme')
383 config.include('rhodecode.integrations.routes.includeme')
383 config.include('rhodecode.integrations.routes.includeme')
384
384
385 config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True)
385 config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True)
386 settings['default_locale_name'] = settings.get('lang', 'en')
386 settings['default_locale_name'] = settings.get('lang', 'en')
387 config.add_translation_dirs('rhodecode:i18n/')
387 config.add_translation_dirs('rhodecode:i18n/')
388
388
389 # Add subscribers.
389 # Add subscribers.
390 if load_all:
390 if load_all:
391 log.debug('Adding subscribers....')
391 log.debug('Adding subscribers...')
392 config.add_subscriber(scan_repositories_if_enabled,
392 config.add_subscriber(scan_repositories_if_enabled,
393 pyramid.events.ApplicationCreated)
393 pyramid.events.ApplicationCreated)
394 config.add_subscriber(write_metadata_if_needed,
394 config.add_subscriber(write_metadata_if_needed,
395 pyramid.events.ApplicationCreated)
395 pyramid.events.ApplicationCreated)
396 config.add_subscriber(write_usage_data,
396 config.add_subscriber(write_usage_data,
397 pyramid.events.ApplicationCreated)
397 pyramid.events.ApplicationCreated)
398 config.add_subscriber(write_js_routes_if_enabled,
398 config.add_subscriber(write_js_routes_if_enabled,
399 pyramid.events.ApplicationCreated)
399 pyramid.events.ApplicationCreated)
400
400
401
401
402 # Set the default renderer for HTML templates to mako.
402 # Set the default renderer for HTML templates to mako.
403 config.add_mako_renderer('.html')
403 config.add_mako_renderer('.html')
404
404
405 config.add_renderer(
405 config.add_renderer(
406 name='json_ext',
406 name='json_ext',
407 factory='rhodecode.lib.ext_json_renderer.pyramid_ext_json')
407 factory='rhodecode.lib.ext_json_renderer.pyramid_ext_json')
408
408
409 config.add_renderer(
409 config.add_renderer(
410 name='string_html',
410 name='string_html',
411 factory='rhodecode.lib.string_renderer.html')
411 factory='rhodecode.lib.string_renderer.html')
412
412
413 # include RhodeCode plugins
413 # include RhodeCode plugins
414 includes = aslist(settings.get('rhodecode.includes', []))
414 includes = aslist(settings.get('rhodecode.includes', []))
415 log.debug('processing rhodecode.includes data...')
415 log.debug('processing rhodecode.includes data...')
416 for inc in includes:
416 for inc in includes:
417 config.include(inc)
417 config.include(inc)
418
418
419 # custom not found view, if our pyramid app doesn't know how to handle
419 # custom not found view, if our pyramid app doesn't know how to handle
420 # the request pass it to potential VCS handling ap
420 # the request pass it to potential VCS handling ap
421 config.add_notfound_view(not_found_view)
421 config.add_notfound_view(not_found_view)
422 if not settings.get('debugtoolbar.enabled', False):
422 if not settings.get('debugtoolbar.enabled', False):
423 # disabled debugtoolbar handle all exceptions via the error_handlers
423 # disabled debugtoolbar handle all exceptions via the error_handlers
424 config.add_view(error_handler, context=Exception)
424 config.add_view(error_handler, context=Exception)
425
425
426 # all errors including 403/404/50X
426 # all errors including 403/404/50X
427 config.add_view(error_handler, context=HTTPError)
427 config.add_view(error_handler, context=HTTPError)
428
428
429
429
430 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
430 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
431 """
431 """
432 Apply outer WSGI middlewares around the application.
432 Apply outer WSGI middlewares around the application.
433 """
433 """
434 registry = config.registry
434 registry = config.registry
435 settings = registry.settings
435 settings = registry.settings
436
436
437 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
437 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
438 pyramid_app = HttpsFixup(pyramid_app, settings)
438 pyramid_app = HttpsFixup(pyramid_app, settings)
439
439
440 pyramid_app, _ae_client = wrap_in_appenlight_if_enabled(
440 pyramid_app, _ae_client = wrap_in_appenlight_if_enabled(
441 pyramid_app, settings)
441 pyramid_app, settings)
442 registry.ae_client = _ae_client
442 registry.ae_client = _ae_client
443
443
444 if settings['gzip_responses']:
444 if settings['gzip_responses']:
445 pyramid_app = make_gzip_middleware(
445 pyramid_app = make_gzip_middleware(
446 pyramid_app, settings, compress_level=1)
446 pyramid_app, settings, compress_level=1)
447
447
448 # this should be the outer most middleware in the wsgi stack since
448 # this should be the outer most middleware in the wsgi stack since
449 # middleware like Routes make database calls
449 # middleware like Routes make database calls
450 def pyramid_app_with_cleanup(environ, start_response):
450 def pyramid_app_with_cleanup(environ, start_response):
451 start = time.time()
451 start = time.time()
452 try:
452 try:
453 return pyramid_app(environ, start_response)
453 return pyramid_app(environ, start_response)
454 finally:
454 finally:
455 # Dispose current database session and rollback uncommitted
455 # Dispose current database session and rollback uncommitted
456 # transactions.
456 # transactions.
457 meta.Session.remove()
457 meta.Session.remove()
458
458
459 # In a single threaded mode server, on non sqlite db we should have
459 # In a single threaded mode server, on non sqlite db we should have
460 # '0 Current Checked out connections' at the end of a request,
460 # '0 Current Checked out connections' at the end of a request,
461 # if not, then something, somewhere is leaving a connection open
461 # if not, then something, somewhere is leaving a connection open
462 pool = meta.get_engine().pool
462 pool = meta.get_engine().pool
463 log.debug('sa pool status: %s', pool.status())
463 log.debug('sa pool status: %s', pool.status())
464 total = time.time() - start
464 total = time.time() - start
465 log.debug('Request processing finalized: %.4fs', total)
465 log.debug('Request processing finalized: %.4fs', total)
466
466
467 return pyramid_app_with_cleanup
467 return pyramid_app_with_cleanup
468
468
469
469
470 def sanitize_settings_and_apply_defaults(global_config, settings):
470 def sanitize_settings_and_apply_defaults(global_config, settings):
471 """
471 """
472 Applies settings defaults and does all type conversion.
472 Applies settings defaults and does all type conversion.
473
473
474 We would move all settings parsing and preparation into this place, so that
474 We would move all settings parsing and preparation into this place, so that
475 we have only one place left which deals with this part. The remaining parts
475 we have only one place left which deals with this part. The remaining parts
476 of the application would start to rely fully on well prepared settings.
476 of the application would start to rely fully on well prepared settings.
477
477
478 This piece would later be split up per topic to avoid a big fat monster
478 This piece would later be split up per topic to avoid a big fat monster
479 function.
479 function.
480 """
480 """
481 jn = os.path.join
481 jn = os.path.join
482
482
483 global_settings_maker = SettingsMaker(global_config)
483 global_settings_maker = SettingsMaker(global_config)
484 global_settings_maker.make_setting('debug', default=False, parser='bool')
484 global_settings_maker.make_setting('debug', default=False, parser='bool')
485 debug_enabled = asbool(global_config.get('debug'))
485 debug_enabled = asbool(global_config.get('debug'))
486
486
487 settings_maker = SettingsMaker(settings)
487 settings_maker = SettingsMaker(settings)
488
488
489 settings_maker.make_setting(
489 settings_maker.make_setting(
490 'logging.autoconfigure',
490 'logging.autoconfigure',
491 default=False,
491 default=False,
492 parser='bool')
492 parser='bool')
493
493
494 logging_conf = jn(os.path.dirname(global_config.get('__file__')), 'logging.ini')
494 logging_conf = jn(os.path.dirname(global_config.get('__file__')), 'logging.ini')
495 settings_maker.enable_logging(logging_conf, level='INFO' if debug_enabled else 'DEBUG')
495 settings_maker.enable_logging(logging_conf, level='INFO' if debug_enabled else 'DEBUG')
496
496
497 # Default includes, possible to change as a user
497 # Default includes, possible to change as a user
498 pyramid_includes = settings_maker.make_setting('pyramid.includes', [], parser='list:newline')
498 pyramid_includes = settings_maker.make_setting('pyramid.includes', [], parser='list:newline')
499 log.debug(
499 log.debug(
500 "Using the following pyramid.includes: %s",
500 "Using the following pyramid.includes: %s",
501 pyramid_includes)
501 pyramid_includes)
502
502
503 settings_maker.make_setting('rhodecode.edition', 'Community Edition')
503 settings_maker.make_setting('rhodecode.edition', 'Community Edition')
504 settings_maker.make_setting('rhodecode.edition_id', 'CE')
504 settings_maker.make_setting('rhodecode.edition_id', 'CE')
505
505
506 if 'mako.default_filters' not in settings:
506 if 'mako.default_filters' not in settings:
507 # set custom default filters if we don't have it defined
507 # set custom default filters if we don't have it defined
508 settings['mako.imports'] = 'from rhodecode.lib.base import h_filter'
508 settings['mako.imports'] = 'from rhodecode.lib.base import h_filter'
509 settings['mako.default_filters'] = 'h_filter'
509 settings['mako.default_filters'] = 'h_filter'
510
510
511 if 'mako.directories' not in settings:
511 if 'mako.directories' not in settings:
512 mako_directories = settings.setdefault('mako.directories', [
512 mako_directories = settings.setdefault('mako.directories', [
513 # Base templates of the original application
513 # Base templates of the original application
514 'rhodecode:templates',
514 'rhodecode:templates',
515 ])
515 ])
516 log.debug(
516 log.debug(
517 "Using the following Mako template directories: %s",
517 "Using the following Mako template directories: %s",
518 mako_directories)
518 mako_directories)
519
519
520 # NOTE(marcink): fix redis requirement for schema of connection since 3.X
520 # NOTE(marcink): fix redis requirement for schema of connection since 3.X
521 if 'beaker.session.type' in settings and settings['beaker.session.type'] == 'ext:redis':
521 if 'beaker.session.type' in settings and settings['beaker.session.type'] == 'ext:redis':
522 raw_url = settings['beaker.session.url']
522 raw_url = settings['beaker.session.url']
523 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
523 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
524 settings['beaker.session.url'] = 'redis://' + raw_url
524 settings['beaker.session.url'] = 'redis://' + raw_url
525
525
526 settings_maker.make_setting('__file__', global_config.get('__file__'))
526 settings_maker.make_setting('__file__', global_config.get('__file__'))
527
527
528 # TODO: johbo: Re-think this, usually the call to config.include
528 # TODO: johbo: Re-think this, usually the call to config.include
529 # should allow to pass in a prefix.
529 # should allow to pass in a prefix.
530 settings_maker.make_setting('rhodecode.api.url', '/_admin/api')
530 settings_maker.make_setting('rhodecode.api.url', '/_admin/api')
531
531
532 # Sanitize generic settings.
532 # Sanitize generic settings.
533 settings_maker.make_setting('default_encoding', 'UTF-8', parser='list')
533 settings_maker.make_setting('default_encoding', 'UTF-8', parser='list')
534 settings_maker.make_setting('is_test', False, parser='bool')
534 settings_maker.make_setting('is_test', False, parser='bool')
535 settings_maker.make_setting('gzip_responses', False, parser='bool')
535 settings_maker.make_setting('gzip_responses', False, parser='bool')
536
536
537 # statsd
537 # statsd
538 settings_maker.make_setting('statsd.enabled', False, parser='bool')
538 settings_maker.make_setting('statsd.enabled', False, parser='bool')
539 settings_maker.make_setting('statsd.statsd_host', 'statsd-exporter', parser='string')
539 settings_maker.make_setting('statsd.statsd_host', 'statsd-exporter', parser='string')
540 settings_maker.make_setting('statsd.statsd_port', 9125, parser='int')
540 settings_maker.make_setting('statsd.statsd_port', 9125, parser='int')
541 settings_maker.make_setting('statsd.statsd_prefix', '')
541 settings_maker.make_setting('statsd.statsd_prefix', '')
542 settings_maker.make_setting('statsd.statsd_ipv6', False, parser='bool')
542 settings_maker.make_setting('statsd.statsd_ipv6', False, parser='bool')
543
543
544 settings_maker.make_setting('vcs.svn.compatible_version', '')
544 settings_maker.make_setting('vcs.svn.compatible_version', '')
545 settings_maker.make_setting('vcs.hooks.protocol', 'http')
545 settings_maker.make_setting('vcs.hooks.protocol', 'http')
546 settings_maker.make_setting('vcs.hooks.host', '*')
546 settings_maker.make_setting('vcs.hooks.host', '*')
547 settings_maker.make_setting('vcs.scm_app_implementation', 'http')
547 settings_maker.make_setting('vcs.scm_app_implementation', 'http')
548 settings_maker.make_setting('vcs.server', '')
548 settings_maker.make_setting('vcs.server', '')
549 settings_maker.make_setting('vcs.server.protocol', 'http')
549 settings_maker.make_setting('vcs.server.protocol', 'http')
550 settings_maker.make_setting('vcs.server.enable', 'true', parser='bool')
550 settings_maker.make_setting('vcs.server.enable', 'true', parser='bool')
551 settings_maker.make_setting('startup.import_repos', 'false', parser='bool')
551 settings_maker.make_setting('startup.import_repos', 'false', parser='bool')
552 settings_maker.make_setting('vcs.hooks.direct_calls', 'false', parser='bool')
552 settings_maker.make_setting('vcs.hooks.direct_calls', 'false', parser='bool')
553 settings_maker.make_setting('vcs.start_server', 'false', parser='bool')
553 settings_maker.make_setting('vcs.start_server', 'false', parser='bool')
554 settings_maker.make_setting('vcs.backends', 'hg, git, svn', parser='list')
554 settings_maker.make_setting('vcs.backends', 'hg, git, svn', parser='list')
555 settings_maker.make_setting('vcs.connection_timeout', 3600, parser='int')
555 settings_maker.make_setting('vcs.connection_timeout', 3600, parser='int')
556
556
557 settings_maker.make_setting('vcs.methods.cache', True, parser='bool')
557 settings_maker.make_setting('vcs.methods.cache', True, parser='bool')
558
558
559 # Support legacy values of vcs.scm_app_implementation. Legacy
559 # Support legacy values of vcs.scm_app_implementation. Legacy
560 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
560 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
561 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
561 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
562 scm_app_impl = settings['vcs.scm_app_implementation']
562 scm_app_impl = settings['vcs.scm_app_implementation']
563 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
563 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
564 settings['vcs.scm_app_implementation'] = 'http'
564 settings['vcs.scm_app_implementation'] = 'http'
565
565
566 settings_maker.make_setting('appenlight', False, parser='bool')
566 settings_maker.make_setting('appenlight', False, parser='bool')
567
567
568 temp_store = tempfile.gettempdir()
568 temp_store = tempfile.gettempdir()
569 tmp_cache_dir = jn(temp_store, 'rc_cache')
569 tmp_cache_dir = jn(temp_store, 'rc_cache')
570
570
571 # save default, cache dir, and use it for all backends later.
571 # save default, cache dir, and use it for all backends later.
572 default_cache_dir = settings_maker.make_setting(
572 default_cache_dir = settings_maker.make_setting(
573 'cache_dir',
573 'cache_dir',
574 default=tmp_cache_dir, default_when_empty=True,
574 default=tmp_cache_dir, default_when_empty=True,
575 parser='dir:ensured')
575 parser='dir:ensured')
576
576
577 # exception store cache
577 # exception store cache
578 settings_maker.make_setting(
578 settings_maker.make_setting(
579 'exception_tracker.store_path',
579 'exception_tracker.store_path',
580 default=jn(default_cache_dir, 'exc_store'), default_when_empty=True,
580 default=jn(default_cache_dir, 'exc_store'), default_when_empty=True,
581 parser='dir:ensured'
581 parser='dir:ensured'
582 )
582 )
583
583
584 settings_maker.make_setting(
584 settings_maker.make_setting(
585 'celerybeat-schedule.path',
585 'celerybeat-schedule.path',
586 default=jn(default_cache_dir, 'celerybeat_schedule', 'celerybeat-schedule.db'), default_when_empty=True,
586 default=jn(default_cache_dir, 'celerybeat_schedule', 'celerybeat-schedule.db'), default_when_empty=True,
587 parser='file:ensured'
587 parser='file:ensured'
588 )
588 )
589
589
590 settings_maker.make_setting('exception_tracker.send_email', False, parser='bool')
590 settings_maker.make_setting('exception_tracker.send_email', False, parser='bool')
591 settings_maker.make_setting('exception_tracker.email_prefix', '[RHODECODE ERROR]', default_when_empty=True)
591 settings_maker.make_setting('exception_tracker.email_prefix', '[RHODECODE ERROR]', default_when_empty=True)
592
592
593 # sessions, ensure file since no-value is memory
593 # sessions, ensure file since no-value is memory
594 settings_maker.make_setting('beaker.session.type', 'file')
594 settings_maker.make_setting('beaker.session.type', 'file')
595 settings_maker.make_setting('beaker.session.data_dir', jn(default_cache_dir, 'session_data'))
595 settings_maker.make_setting('beaker.session.data_dir', jn(default_cache_dir, 'session_data'))
596
596
597 # cache_general
597 # cache_general
598 settings_maker.make_setting('rc_cache.cache_general.backend', 'dogpile.cache.rc.file_namespace')
598 settings_maker.make_setting('rc_cache.cache_general.backend', 'dogpile.cache.rc.file_namespace')
599 settings_maker.make_setting('rc_cache.cache_general.expiration_time', 60 * 60 * 12, parser='int')
599 settings_maker.make_setting('rc_cache.cache_general.expiration_time', 60 * 60 * 12, parser='int')
600 settings_maker.make_setting('rc_cache.cache_general.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_general.db'))
600 settings_maker.make_setting('rc_cache.cache_general.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_general.db'))
601
601
602 # cache_perms
602 # cache_perms
603 settings_maker.make_setting('rc_cache.cache_perms.backend', 'dogpile.cache.rc.file_namespace')
603 settings_maker.make_setting('rc_cache.cache_perms.backend', 'dogpile.cache.rc.file_namespace')
604 settings_maker.make_setting('rc_cache.cache_perms.expiration_time', 60 * 60, parser='int')
604 settings_maker.make_setting('rc_cache.cache_perms.expiration_time', 60 * 60, parser='int')
605 settings_maker.make_setting('rc_cache.cache_perms.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_perms_db'))
605 settings_maker.make_setting('rc_cache.cache_perms.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_perms_db'))
606
606
607 # cache_repo
607 # cache_repo
608 settings_maker.make_setting('rc_cache.cache_repo.backend', 'dogpile.cache.rc.file_namespace')
608 settings_maker.make_setting('rc_cache.cache_repo.backend', 'dogpile.cache.rc.file_namespace')
609 settings_maker.make_setting('rc_cache.cache_repo.expiration_time', 60 * 60 * 24 * 30, parser='int')
609 settings_maker.make_setting('rc_cache.cache_repo.expiration_time', 60 * 60 * 24 * 30, parser='int')
610 settings_maker.make_setting('rc_cache.cache_repo.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_repo_db'))
610 settings_maker.make_setting('rc_cache.cache_repo.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_repo_db'))
611
611
612 # cache_license
612 # cache_license
613 settings_maker.make_setting('rc_cache.cache_license.backend', 'dogpile.cache.rc.file_namespace')
613 settings_maker.make_setting('rc_cache.cache_license.backend', 'dogpile.cache.rc.file_namespace')
614 settings_maker.make_setting('rc_cache.cache_license.expiration_time', 60 * 5, parser='int')
614 settings_maker.make_setting('rc_cache.cache_license.expiration_time', 60 * 5, parser='int')
615 settings_maker.make_setting('rc_cache.cache_license.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_license_db'))
615 settings_maker.make_setting('rc_cache.cache_license.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_license_db'))
616
616
617 # cache_repo_longterm memory, 96H
617 # cache_repo_longterm memory, 96H
618 settings_maker.make_setting('rc_cache.cache_repo_longterm.backend', 'dogpile.cache.rc.memory_lru')
618 settings_maker.make_setting('rc_cache.cache_repo_longterm.backend', 'dogpile.cache.rc.memory_lru')
619 settings_maker.make_setting('rc_cache.cache_repo_longterm.expiration_time', 345600, parser='int')
619 settings_maker.make_setting('rc_cache.cache_repo_longterm.expiration_time', 345600, parser='int')
620 settings_maker.make_setting('rc_cache.cache_repo_longterm.max_size', 10000, parser='int')
620 settings_maker.make_setting('rc_cache.cache_repo_longterm.max_size', 10000, parser='int')
621
621
622 # sql_cache_short
622 # sql_cache_short
623 settings_maker.make_setting('rc_cache.sql_cache_short.backend', 'dogpile.cache.rc.memory_lru')
623 settings_maker.make_setting('rc_cache.sql_cache_short.backend', 'dogpile.cache.rc.memory_lru')
624 settings_maker.make_setting('rc_cache.sql_cache_short.expiration_time', 30, parser='int')
624 settings_maker.make_setting('rc_cache.sql_cache_short.expiration_time', 30, parser='int')
625 settings_maker.make_setting('rc_cache.sql_cache_short.max_size', 10000, parser='int')
625 settings_maker.make_setting('rc_cache.sql_cache_short.max_size', 10000, parser='int')
626
626
627 # archive_cache
627 # archive_cache
628 settings_maker.make_setting('archive_cache.store_dir', jn(default_cache_dir, 'archive_cache'), default_when_empty=True,)
628 settings_maker.make_setting('archive_cache.store_dir', jn(default_cache_dir, 'archive_cache'), default_when_empty=True,)
629 settings_maker.make_setting('archive_cache.cache_size_gb', 10, parser='float')
629 settings_maker.make_setting('archive_cache.cache_size_gb', 10, parser='float')
630 settings_maker.make_setting('archive_cache.cache_shards', 10, parser='int')
630 settings_maker.make_setting('archive_cache.cache_shards', 10, parser='int')
631
631
632 settings_maker.env_expand()
632 settings_maker.env_expand()
633
633
634 # configure instance id
634 # configure instance id
635 config_utils.set_instance_id(settings)
635 config_utils.set_instance_id(settings)
636
636
637 return settings
637 return settings
@@ -1,382 +1,412 b''
1
1
2 /******************************************************************************
2 /******************************************************************************
3 * *
3 * *
4 * DO NOT CHANGE THIS FILE MANUALLY *
4 * DO NOT CHANGE THIS FILE MANUALLY *
5 * *
5 * *
6 * *
6 * *
7 * This file is automatically generated when the app starts up with *
7 * This file is automatically generated when the app starts up with *
8 * generate_js_files = true *
8 * generate_js_files = true *
9 * *
9 * *
10 * To add a route here pass jsroute=True to the route definition in the app *
10 * To add a route here pass jsroute=True to the route definition in the app *
11 * *
11 * *
12 ******************************************************************************/
12 ******************************************************************************/
13 function registerRCRoutes() {
13 function registerRCRoutes() {
14 // routes registration
14 // routes registration
15 pyroutes.register('admin_artifacts', '/_admin/_admin/artifacts', []);
15 pyroutes.register('admin_artifacts', '/_admin/artifacts', []);
16 pyroutes.register('admin_artifacts_delete', '/_admin/_admin/artifacts/%(uid)s/delete', ['uid']);
16 pyroutes.register('admin_artifacts_data', '/_admin/artifacts-data', []);
17 pyroutes.register('admin_artifacts_show_all', '/_admin/_admin/artifacts', []);
17 pyroutes.register('admin_artifacts_delete', '/_admin/artifacts/%(uid)s/delete', ['uid']);
18 pyroutes.register('admin_artifacts_show_info', '/_admin/_admin/artifacts/%(uid)s', ['uid']);
18 pyroutes.register('admin_artifacts_show_all', '/_admin/artifacts', []);
19 pyroutes.register('admin_artifacts_update', '/_admin/_admin/artifacts/%(uid)s/update', ['uid']);
19 pyroutes.register('admin_artifacts_show_info', '/_admin/artifacts/%(uid)s', ['uid']);
20 pyroutes.register('admin_artifacts_update', '/_admin/artifacts/%(uid)s/update', ['uid']);
20 pyroutes.register('admin_audit_log_entry', '/_admin/audit_logs/%(audit_log_id)s', ['audit_log_id']);
21 pyroutes.register('admin_audit_log_entry', '/_admin/audit_logs/%(audit_log_id)s', ['audit_log_id']);
21 pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []);
22 pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []);
22 pyroutes.register('admin_automation', '/_admin/_admin/automation', []);
23 pyroutes.register('admin_automation', '/_admin/automation', []);
24 pyroutes.register('admin_automation_update', '/_admin/automation/%(entry_id)s/update', ['entry_id']);
23 pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []);
25 pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []);
24 pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []);
26 pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []);
25 pyroutes.register('admin_home', '/_admin', []);
27 pyroutes.register('admin_home', '/_admin', []);
26 pyroutes.register('admin_permissions_application', '/_admin/permissions/application', []);
28 pyroutes.register('admin_permissions_application', '/_admin/permissions/application', []);
27 pyroutes.register('admin_permissions_application_update', '/_admin/permissions/application/update', []);
29 pyroutes.register('admin_permissions_application_update', '/_admin/permissions/application/update', []);
28 pyroutes.register('admin_permissions_auth_token_access', '/_admin/permissions/auth_token_access', []);
30 pyroutes.register('admin_permissions_auth_token_access', '/_admin/permissions/auth_token_access', []);
29 pyroutes.register('admin_permissions_branch', '/_admin/permissions/branch', []);
31 pyroutes.register('admin_permissions_branch', '/_admin/permissions/branch', []);
32 pyroutes.register('admin_permissions_branch_update', '/_admin/permissions/branch/update', []);
30 pyroutes.register('admin_permissions_global', '/_admin/permissions/global', []);
33 pyroutes.register('admin_permissions_global', '/_admin/permissions/global', []);
31 pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []);
34 pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []);
32 pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []);
35 pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []);
33 pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []);
36 pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []);
34 pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []);
37 pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []);
35 pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []);
38 pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []);
36 pyroutes.register('admin_permissions_ssh_keys', '/_admin/permissions/ssh_keys', []);
39 pyroutes.register('admin_permissions_ssh_keys', '/_admin/permissions/ssh_keys', []);
37 pyroutes.register('admin_permissions_ssh_keys_data', '/_admin/permissions/ssh_keys/data', []);
40 pyroutes.register('admin_permissions_ssh_keys_data', '/_admin/permissions/ssh_keys/data', []);
38 pyroutes.register('admin_permissions_ssh_keys_update', '/_admin/permissions/ssh_keys/update', []);
41 pyroutes.register('admin_permissions_ssh_keys_update', '/_admin/permissions/ssh_keys/update', []);
39 pyroutes.register('admin_scheduler', '/_admin/_admin/scheduler', []);
42 pyroutes.register('admin_scheduler', '/_admin/scheduler', []);
43 pyroutes.register('admin_scheduler_show_tasks', '/_admin/scheduler/_tasks', []);
40 pyroutes.register('admin_settings', '/_admin/settings', []);
44 pyroutes.register('admin_settings', '/_admin/settings', []);
41 pyroutes.register('admin_settings_email', '/_admin/settings/email', []);
45 pyroutes.register('admin_settings_email', '/_admin/settings/email', []);
42 pyroutes.register('admin_settings_email_update', '/_admin/settings/email/update', []);
46 pyroutes.register('admin_settings_email_update', '/_admin/settings/email/update', []);
43 pyroutes.register('admin_settings_exception_tracker', '/_admin/settings/exceptions', []);
47 pyroutes.register('admin_settings_exception_tracker', '/_admin/settings/exceptions', []);
44 pyroutes.register('admin_settings_exception_tracker_delete', '/_admin/settings/exceptions/%(exception_id)s/delete', ['exception_id']);
48 pyroutes.register('admin_settings_exception_tracker_delete', '/_admin/settings/exceptions/%(exception_id)s/delete', ['exception_id']);
45 pyroutes.register('admin_settings_exception_tracker_delete_all', '/_admin/settings/exceptions_delete_all', []);
49 pyroutes.register('admin_settings_exception_tracker_delete_all', '/_admin/settings/exceptions_delete_all', []);
46 pyroutes.register('admin_settings_exception_tracker_show', '/_admin/settings/exceptions/%(exception_id)s', ['exception_id']);
50 pyroutes.register('admin_settings_exception_tracker_show', '/_admin/settings/exceptions/%(exception_id)s', ['exception_id']);
47 pyroutes.register('admin_settings_global', '/_admin/settings/global', []);
51 pyroutes.register('admin_settings_global', '/_admin/settings/global', []);
48 pyroutes.register('admin_settings_global_update', '/_admin/settings/global/update', []);
52 pyroutes.register('admin_settings_global_update', '/_admin/settings/global/update', []);
49 pyroutes.register('admin_settings_hooks', '/_admin/settings/hooks', []);
53 pyroutes.register('admin_settings_hooks', '/_admin/settings/hooks', []);
50 pyroutes.register('admin_settings_hooks_delete', '/_admin/settings/hooks/delete', []);
54 pyroutes.register('admin_settings_hooks_delete', '/_admin/settings/hooks/delete', []);
51 pyroutes.register('admin_settings_hooks_update', '/_admin/settings/hooks/update', []);
55 pyroutes.register('admin_settings_hooks_update', '/_admin/settings/hooks/update', []);
52 pyroutes.register('admin_settings_issuetracker', '/_admin/settings/issue-tracker', []);
56 pyroutes.register('admin_settings_issuetracker', '/_admin/settings/issue-tracker', []);
53 pyroutes.register('admin_settings_issuetracker_delete', '/_admin/settings/issue-tracker/delete', []);
57 pyroutes.register('admin_settings_issuetracker_delete', '/_admin/settings/issue-tracker/delete', []);
54 pyroutes.register('admin_settings_issuetracker_test', '/_admin/settings/issue-tracker/test', []);
58 pyroutes.register('admin_settings_issuetracker_test', '/_admin/settings/issue-tracker/test', []);
55 pyroutes.register('admin_settings_issuetracker_update', '/_admin/settings/issue-tracker/update', []);
59 pyroutes.register('admin_settings_issuetracker_update', '/_admin/settings/issue-tracker/update', []);
56 pyroutes.register('admin_settings_labs', '/_admin/settings/labs', []);
60 pyroutes.register('admin_settings_labs', '/_admin/settings/labs', []);
57 pyroutes.register('admin_settings_labs_update', '/_admin/settings/labs/update', []);
61 pyroutes.register('admin_settings_labs_update', '/_admin/settings/labs/update', []);
62 pyroutes.register('admin_settings_license', '/_admin/settings/license', []);
63 pyroutes.register('admin_settings_license_unlock', '/_admin/settings/license_unlock', []);
58 pyroutes.register('admin_settings_mapping', '/_admin/settings/mapping', []);
64 pyroutes.register('admin_settings_mapping', '/_admin/settings/mapping', []);
59 pyroutes.register('admin_settings_mapping_update', '/_admin/settings/mapping/update', []);
65 pyroutes.register('admin_settings_mapping_update', '/_admin/settings/mapping/update', []);
60 pyroutes.register('admin_settings_open_source', '/_admin/settings/open_source', []);
66 pyroutes.register('admin_settings_open_source', '/_admin/settings/open_source', []);
61 pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []);
67 pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []);
62 pyroutes.register('admin_settings_process_management_data', '/_admin/settings/process_management/data', []);
68 pyroutes.register('admin_settings_process_management_data', '/_admin/settings/process_management/data', []);
63 pyroutes.register('admin_settings_process_management_master_signal', '/_admin/settings/process_management/master_signal', []);
69 pyroutes.register('admin_settings_process_management_master_signal', '/_admin/settings/process_management/master_signal', []);
64 pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
70 pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
71 pyroutes.register('admin_settings_scheduler_create', '/_admin/scheduler/create', []);
72 pyroutes.register('admin_settings_scheduler_delete', '/_admin/scheduler/%(schedule_id)s/delete', ['schedule_id']);
73 pyroutes.register('admin_settings_scheduler_edit', '/_admin/scheduler/%(schedule_id)s', ['schedule_id']);
74 pyroutes.register('admin_settings_scheduler_execute', '/_admin/scheduler/%(schedule_id)s/execute', ['schedule_id']);
75 pyroutes.register('admin_settings_scheduler_new', '/_admin/scheduler/new', []);
76 pyroutes.register('admin_settings_scheduler_update', '/_admin/scheduler/%(schedule_id)s/update', ['schedule_id']);
65 pyroutes.register('admin_settings_search', '/_admin/settings/search', []);
77 pyroutes.register('admin_settings_search', '/_admin/settings/search', []);
66 pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []);
78 pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []);
67 pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []);
79 pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []);
68 pyroutes.register('admin_settings_system', '/_admin/settings/system', []);
80 pyroutes.register('admin_settings_system', '/_admin/settings/system', []);
69 pyroutes.register('admin_settings_system_update', '/_admin/settings/system/updates', []);
81 pyroutes.register('admin_settings_system_update', '/_admin/settings/system/updates', []);
70 pyroutes.register('admin_settings_update', '/_admin/settings/update', []);
82 pyroutes.register('admin_settings_update', '/_admin/settings/update', []);
71 pyroutes.register('admin_settings_vcs', '/_admin/settings/vcs', []);
83 pyroutes.register('admin_settings_vcs', '/_admin/settings/vcs', []);
72 pyroutes.register('admin_settings_vcs_svn_generate_cfg', '/_admin/settings/vcs/svn_generate_cfg', []);
84 pyroutes.register('admin_settings_vcs_svn_generate_cfg', '/_admin/settings/vcs/svn_generate_cfg', []);
73 pyroutes.register('admin_settings_vcs_svn_pattern_delete', '/_admin/settings/vcs/svn_pattern_delete', []);
85 pyroutes.register('admin_settings_vcs_svn_pattern_delete', '/_admin/settings/vcs/svn_pattern_delete', []);
74 pyroutes.register('admin_settings_vcs_update', '/_admin/settings/vcs/update', []);
86 pyroutes.register('admin_settings_vcs_update', '/_admin/settings/vcs/update', []);
75 pyroutes.register('admin_settings_visual', '/_admin/settings/visual', []);
87 pyroutes.register('admin_settings_visual', '/_admin/settings/visual', []);
76 pyroutes.register('admin_settings_visual_update', '/_admin/settings/visual/update', []);
88 pyroutes.register('admin_settings_visual_update', '/_admin/settings/visual/update', []);
77 pyroutes.register('apiv2', '/_admin/api', []);
89 pyroutes.register('apiv2', '/_admin/api', []);
78 pyroutes.register('atom_feed_home', '/%(repo_name)s/feed-atom', ['repo_name']);
90 pyroutes.register('atom_feed_home', '/%(repo_name)s/feed-atom', ['repo_name']);
79 pyroutes.register('atom_feed_home_old', '/%(repo_name)s/feed/atom', ['repo_name']);
91 pyroutes.register('atom_feed_home_old', '/%(repo_name)s/feed/atom', ['repo_name']);
80 pyroutes.register('auth_home', '/_admin/auth*traverse', []);
92 pyroutes.register('auth_home', '/_admin/auth*traverse', []);
81 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
93 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
82 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
94 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
83 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
95 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
84 pyroutes.register('channelstream_proxy', '/_channelstream', []);
96 pyroutes.register('channelstream_proxy', '/_channelstream', []);
85 pyroutes.register('channelstream_subscribe', '/_admin/channelstream/subscribe', []);
97 pyroutes.register('channelstream_subscribe', '/_admin/channelstream/subscribe', []);
98 pyroutes.register('commit_draft_comments_submit', '/%(repo_name)s/changeset/%(commit_id)s/draft_comments_submit', ['repo_name', 'commit_id']);
86 pyroutes.register('debug_style_email', '/_admin/debug_style/email/%(email_id)s', ['email_id']);
99 pyroutes.register('debug_style_email', '/_admin/debug_style/email/%(email_id)s', ['email_id']);
87 pyroutes.register('debug_style_email_plain_rendered', '/_admin/debug_style/email-rendered/%(email_id)s', ['email_id']);
100 pyroutes.register('debug_style_email_plain_rendered', '/_admin/debug_style/email-rendered/%(email_id)s', ['email_id']);
88 pyroutes.register('debug_style_home', '/_admin/debug_style', []);
101 pyroutes.register('debug_style_home', '/_admin/debug_style', []);
89 pyroutes.register('debug_style_template', '/_admin/debug_style/t/%(t_path)s', ['t_path']);
102 pyroutes.register('debug_style_template', '/_admin/debug_style/t/%(t_path)s', ['t_path']);
90 pyroutes.register('download_file', '/_file_store/download/%(fid)s', ['fid']);
103 pyroutes.register('download_file', '/_file_store/download/%(fid)s', ['fid']);
91 pyroutes.register('download_file_by_token', '/_file_store/token-download/%(_auth_token)s/%(fid)s', ['_auth_token', 'fid']);
104 pyroutes.register('download_file_by_token', '/_file_store/token-download/%(_auth_token)s/%(fid)s', ['_auth_token', 'fid']);
92 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
105 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
93 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
106 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
94 pyroutes.register('edit_repo_advanced_archive', '/%(repo_name)s/settings/advanced/archive', ['repo_name']);
107 pyroutes.register('edit_repo_advanced_archive', '/%(repo_name)s/settings/advanced/archive', ['repo_name']);
95 pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
108 pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
96 pyroutes.register('edit_repo_advanced_fork', '/%(repo_name)s/settings/advanced/fork', ['repo_name']);
109 pyroutes.register('edit_repo_advanced_fork', '/%(repo_name)s/settings/advanced/fork', ['repo_name']);
97 pyroutes.register('edit_repo_advanced_hooks', '/%(repo_name)s/settings/advanced/hooks', ['repo_name']);
110 pyroutes.register('edit_repo_advanced_hooks', '/%(repo_name)s/settings/advanced/hooks', ['repo_name']);
98 pyroutes.register('edit_repo_advanced_journal', '/%(repo_name)s/settings/advanced/journal', ['repo_name']);
111 pyroutes.register('edit_repo_advanced_journal', '/%(repo_name)s/settings/advanced/journal', ['repo_name']);
99 pyroutes.register('edit_repo_advanced_locking', '/%(repo_name)s/settings/advanced/locking', ['repo_name']);
112 pyroutes.register('edit_repo_advanced_locking', '/%(repo_name)s/settings/advanced/locking', ['repo_name']);
100 pyroutes.register('edit_repo_audit_logs', '/%(repo_name)s/settings/audit_logs', ['repo_name']);
113 pyroutes.register('edit_repo_audit_logs', '/%(repo_name)s/settings/audit_logs', ['repo_name']);
101 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
114 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
102 pyroutes.register('edit_repo_fields', '/%(repo_name)s/settings/fields', ['repo_name']);
115 pyroutes.register('edit_repo_fields', '/%(repo_name)s/settings/fields', ['repo_name']);
103 pyroutes.register('edit_repo_fields_create', '/%(repo_name)s/settings/fields/create', ['repo_name']);
116 pyroutes.register('edit_repo_fields_create', '/%(repo_name)s/settings/fields/create', ['repo_name']);
104 pyroutes.register('edit_repo_fields_delete', '/%(repo_name)s/settings/fields/%(field_id)s/delete', ['repo_name', 'field_id']);
117 pyroutes.register('edit_repo_fields_delete', '/%(repo_name)s/settings/fields/%(field_id)s/delete', ['repo_name', 'field_id']);
105 pyroutes.register('edit_repo_group', '/%(repo_group_name)s/_edit', ['repo_group_name']);
118 pyroutes.register('edit_repo_group', '/%(repo_group_name)s/_edit', ['repo_group_name']);
106 pyroutes.register('edit_repo_group_advanced', '/%(repo_group_name)s/_settings/advanced', ['repo_group_name']);
119 pyroutes.register('edit_repo_group_advanced', '/%(repo_group_name)s/_settings/advanced', ['repo_group_name']);
107 pyroutes.register('edit_repo_group_advanced_delete', '/%(repo_group_name)s/_settings/advanced/delete', ['repo_group_name']);
120 pyroutes.register('edit_repo_group_advanced_delete', '/%(repo_group_name)s/_settings/advanced/delete', ['repo_group_name']);
108 pyroutes.register('edit_repo_group_perms', '/%(repo_group_name)s/_settings/permissions', ['repo_group_name']);
121 pyroutes.register('edit_repo_group_perms', '/%(repo_group_name)s/_settings/permissions', ['repo_group_name']);
109 pyroutes.register('edit_repo_group_perms_update', '/%(repo_group_name)s/_settings/permissions/update', ['repo_group_name']);
122 pyroutes.register('edit_repo_group_perms_update', '/%(repo_group_name)s/_settings/permissions/update', ['repo_group_name']);
110 pyroutes.register('edit_repo_issuetracker', '/%(repo_name)s/settings/issue_trackers', ['repo_name']);
123 pyroutes.register('edit_repo_issuetracker', '/%(repo_name)s/settings/issue_trackers', ['repo_name']);
111 pyroutes.register('edit_repo_issuetracker_delete', '/%(repo_name)s/settings/issue_trackers/delete', ['repo_name']);
124 pyroutes.register('edit_repo_issuetracker_delete', '/%(repo_name)s/settings/issue_trackers/delete', ['repo_name']);
112 pyroutes.register('edit_repo_issuetracker_test', '/%(repo_name)s/settings/issue_trackers/test', ['repo_name']);
125 pyroutes.register('edit_repo_issuetracker_test', '/%(repo_name)s/settings/issue_trackers/test', ['repo_name']);
113 pyroutes.register('edit_repo_issuetracker_update', '/%(repo_name)s/settings/issue_trackers/update', ['repo_name']);
126 pyroutes.register('edit_repo_issuetracker_update', '/%(repo_name)s/settings/issue_trackers/update', ['repo_name']);
114 pyroutes.register('edit_repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
127 pyroutes.register('edit_repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
115 pyroutes.register('edit_repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
128 pyroutes.register('edit_repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
116 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
129 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
117 pyroutes.register('edit_repo_perms_branch', '/%(repo_name)s/settings/branch_permissions', ['repo_name']);
130 pyroutes.register('edit_repo_perms_branch', '/%(repo_name)s/settings/branch_permissions', ['repo_name']);
118 pyroutes.register('edit_repo_perms_branch_delete', '/%(repo_name)s/settings/branch_permissions/%(rule_id)s/delete', ['repo_name', 'rule_id']);
131 pyroutes.register('edit_repo_perms_branch_delete', '/%(repo_name)s/settings/branch_permissions/%(rule_id)s/delete', ['repo_name', 'rule_id']);
119 pyroutes.register('edit_repo_perms_set_private', '/%(repo_name)s/settings/permissions/set_private', ['repo_name']);
132 pyroutes.register('edit_repo_perms_set_private', '/%(repo_name)s/settings/permissions/set_private', ['repo_name']);
120 pyroutes.register('edit_repo_remote', '/%(repo_name)s/settings/remote', ['repo_name']);
133 pyroutes.register('edit_repo_remote', '/%(repo_name)s/settings/remote', ['repo_name']);
121 pyroutes.register('edit_repo_remote_pull', '/%(repo_name)s/settings/remote/pull', ['repo_name']);
134 pyroutes.register('edit_repo_remote_pull', '/%(repo_name)s/settings/remote/pull', ['repo_name']);
122 pyroutes.register('edit_repo_remote_push', '/%(repo_name)s/settings/remote/push', ['repo_name']);
135 pyroutes.register('edit_repo_remote_push', '/%(repo_name)s/settings/remote/push', ['repo_name']);
123 pyroutes.register('edit_repo_statistics', '/%(repo_name)s/settings/statistics', ['repo_name']);
136 pyroutes.register('edit_repo_statistics', '/%(repo_name)s/settings/statistics', ['repo_name']);
124 pyroutes.register('edit_repo_statistics_reset', '/%(repo_name)s/settings/statistics/update', ['repo_name']);
137 pyroutes.register('edit_repo_statistics_reset', '/%(repo_name)s/settings/statistics/update', ['repo_name']);
125 pyroutes.register('edit_repo_strip', '/%(repo_name)s/settings/strip', ['repo_name']);
138 pyroutes.register('edit_repo_strip', '/%(repo_name)s/settings/strip', ['repo_name']);
126 pyroutes.register('edit_repo_vcs', '/%(repo_name)s/settings/vcs', ['repo_name']);
139 pyroutes.register('edit_repo_vcs', '/%(repo_name)s/settings/vcs', ['repo_name']);
127 pyroutes.register('edit_repo_vcs_svn_pattern_delete', '/%(repo_name)s/settings/vcs/svn_pattern/delete', ['repo_name']);
140 pyroutes.register('edit_repo_vcs_svn_pattern_delete', '/%(repo_name)s/settings/vcs/svn_pattern/delete', ['repo_name']);
128 pyroutes.register('edit_repo_vcs_update', '/%(repo_name)s/settings/vcs/update', ['repo_name']);
141 pyroutes.register('edit_repo_vcs_update', '/%(repo_name)s/settings/vcs/update', ['repo_name']);
129 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
142 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
130 pyroutes.register('edit_user_audit_logs_download', '/_admin/users/%(user_id)s/edit/audit/download', ['user_id']);
143 pyroutes.register('edit_user_audit_logs_download', '/_admin/users/%(user_id)s/edit/audit/download', ['user_id']);
131 pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
144 pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
132 pyroutes.register('edit_user_auth_tokens_add', '/_admin/users/%(user_id)s/edit/auth_tokens/new', ['user_id']);
145 pyroutes.register('edit_user_auth_tokens_add', '/_admin/users/%(user_id)s/edit/auth_tokens/new', ['user_id']);
133 pyroutes.register('edit_user_auth_tokens_delete', '/_admin/users/%(user_id)s/edit/auth_tokens/delete', ['user_id']);
146 pyroutes.register('edit_user_auth_tokens_delete', '/_admin/users/%(user_id)s/edit/auth_tokens/delete', ['user_id']);
134 pyroutes.register('edit_user_auth_tokens_view', '/_admin/users/%(user_id)s/edit/auth_tokens/view', ['user_id']);
147 pyroutes.register('edit_user_auth_tokens_view', '/_admin/users/%(user_id)s/edit/auth_tokens/view', ['user_id']);
135 pyroutes.register('edit_user_caches', '/_admin/users/%(user_id)s/edit/caches', ['user_id']);
148 pyroutes.register('edit_user_caches', '/_admin/users/%(user_id)s/edit/caches', ['user_id']);
136 pyroutes.register('edit_user_caches_update', '/_admin/users/%(user_id)s/edit/caches/update', ['user_id']);
149 pyroutes.register('edit_user_caches_update', '/_admin/users/%(user_id)s/edit/caches/update', ['user_id']);
137 pyroutes.register('edit_user_emails', '/_admin/users/%(user_id)s/edit/emails', ['user_id']);
150 pyroutes.register('edit_user_emails', '/_admin/users/%(user_id)s/edit/emails', ['user_id']);
138 pyroutes.register('edit_user_emails_add', '/_admin/users/%(user_id)s/edit/emails/new', ['user_id']);
151 pyroutes.register('edit_user_emails_add', '/_admin/users/%(user_id)s/edit/emails/new', ['user_id']);
139 pyroutes.register('edit_user_emails_delete', '/_admin/users/%(user_id)s/edit/emails/delete', ['user_id']);
152 pyroutes.register('edit_user_emails_delete', '/_admin/users/%(user_id)s/edit/emails/delete', ['user_id']);
140 pyroutes.register('edit_user_group', '/_admin/user_groups/%(user_group_id)s/edit', ['user_group_id']);
153 pyroutes.register('edit_user_group', '/_admin/user_groups/%(user_group_id)s/edit', ['user_group_id']);
141 pyroutes.register('edit_user_group_advanced', '/_admin/user_groups/%(user_group_id)s/edit/advanced', ['user_group_id']);
154 pyroutes.register('edit_user_group_advanced', '/_admin/user_groups/%(user_group_id)s/edit/advanced', ['user_group_id']);
142 pyroutes.register('edit_user_group_advanced_sync', '/_admin/user_groups/%(user_group_id)s/edit/advanced/sync', ['user_group_id']);
155 pyroutes.register('edit_user_group_advanced_sync', '/_admin/user_groups/%(user_group_id)s/edit/advanced/sync', ['user_group_id']);
143 pyroutes.register('edit_user_group_global_perms', '/_admin/user_groups/%(user_group_id)s/edit/global_permissions', ['user_group_id']);
156 pyroutes.register('edit_user_group_global_perms', '/_admin/user_groups/%(user_group_id)s/edit/global_permissions', ['user_group_id']);
144 pyroutes.register('edit_user_group_global_perms_update', '/_admin/user_groups/%(user_group_id)s/edit/global_permissions/update', ['user_group_id']);
157 pyroutes.register('edit_user_group_global_perms_update', '/_admin/user_groups/%(user_group_id)s/edit/global_permissions/update', ['user_group_id']);
145 pyroutes.register('edit_user_group_perms', '/_admin/user_groups/%(user_group_id)s/edit/permissions', ['user_group_id']);
158 pyroutes.register('edit_user_group_perms', '/_admin/user_groups/%(user_group_id)s/edit/permissions', ['user_group_id']);
146 pyroutes.register('edit_user_group_perms_summary', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary', ['user_group_id']);
159 pyroutes.register('edit_user_group_perms_summary', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary', ['user_group_id']);
147 pyroutes.register('edit_user_group_perms_summary_json', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary/json', ['user_group_id']);
160 pyroutes.register('edit_user_group_perms_summary_json', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary/json', ['user_group_id']);
148 pyroutes.register('edit_user_group_perms_update', '/_admin/user_groups/%(user_group_id)s/edit/permissions/update', ['user_group_id']);
161 pyroutes.register('edit_user_group_perms_update', '/_admin/user_groups/%(user_group_id)s/edit/permissions/update', ['user_group_id']);
149 pyroutes.register('edit_user_groups_management', '/_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
162 pyroutes.register('edit_user_groups_management', '/_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
150 pyroutes.register('edit_user_groups_management_updates', '/_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
163 pyroutes.register('edit_user_groups_management_updates', '/_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
151 pyroutes.register('edit_user_ips', '/_admin/users/%(user_id)s/edit/ips', ['user_id']);
164 pyroutes.register('edit_user_ips', '/_admin/users/%(user_id)s/edit/ips', ['user_id']);
152 pyroutes.register('edit_user_ips_add', '/_admin/users/%(user_id)s/edit/ips/new', ['user_id']);
165 pyroutes.register('edit_user_ips_add', '/_admin/users/%(user_id)s/edit/ips/new', ['user_id']);
153 pyroutes.register('edit_user_ips_delete', '/_admin/users/%(user_id)s/edit/ips/delete', ['user_id']);
166 pyroutes.register('edit_user_ips_delete', '/_admin/users/%(user_id)s/edit/ips/delete', ['user_id']);
154 pyroutes.register('edit_user_perms_summary', '/_admin/users/%(user_id)s/edit/permissions_summary', ['user_id']);
167 pyroutes.register('edit_user_perms_summary', '/_admin/users/%(user_id)s/edit/permissions_summary', ['user_id']);
155 pyroutes.register('edit_user_perms_summary_json', '/_admin/users/%(user_id)s/edit/permissions_summary/json', ['user_id']);
168 pyroutes.register('edit_user_perms_summary_json', '/_admin/users/%(user_id)s/edit/permissions_summary/json', ['user_id']);
156 pyroutes.register('edit_user_ssh_keys', '/_admin/users/%(user_id)s/edit/ssh_keys', ['user_id']);
169 pyroutes.register('edit_user_ssh_keys', '/_admin/users/%(user_id)s/edit/ssh_keys', ['user_id']);
157 pyroutes.register('edit_user_ssh_keys_add', '/_admin/users/%(user_id)s/edit/ssh_keys/new', ['user_id']);
170 pyroutes.register('edit_user_ssh_keys_add', '/_admin/users/%(user_id)s/edit/ssh_keys/new', ['user_id']);
158 pyroutes.register('edit_user_ssh_keys_delete', '/_admin/users/%(user_id)s/edit/ssh_keys/delete', ['user_id']);
171 pyroutes.register('edit_user_ssh_keys_delete', '/_admin/users/%(user_id)s/edit/ssh_keys/delete', ['user_id']);
159 pyroutes.register('edit_user_ssh_keys_generate_keypair', '/_admin/users/%(user_id)s/edit/ssh_keys/generate', ['user_id']);
172 pyroutes.register('edit_user_ssh_keys_generate_keypair', '/_admin/users/%(user_id)s/edit/ssh_keys/generate', ['user_id']);
160 pyroutes.register('favicon', '/favicon.ico', []);
173 pyroutes.register('favicon', '/favicon.ico', []);
161 pyroutes.register('file_preview', '/_file_preview', []);
174 pyroutes.register('file_preview', '/_file_preview', []);
162 pyroutes.register('gist_delete', '/_admin/gists/%(gist_id)s/delete', ['gist_id']);
175 pyroutes.register('gist_delete', '/_admin/gists/%(gist_id)s/delete', ['gist_id']);
163 pyroutes.register('gist_edit', '/_admin/gists/%(gist_id)s/edit', ['gist_id']);
176 pyroutes.register('gist_edit', '/_admin/gists/%(gist_id)s/edit', ['gist_id']);
164 pyroutes.register('gist_edit_check_revision', '/_admin/gists/%(gist_id)s/edit/check_revision', ['gist_id']);
177 pyroutes.register('gist_edit_check_revision', '/_admin/gists/%(gist_id)s/edit/check_revision', ['gist_id']);
165 pyroutes.register('gist_show', '/_admin/gists/%(gist_id)s', ['gist_id']);
178 pyroutes.register('gist_show', '/_admin/gists/%(gist_id)s', ['gist_id']);
166 pyroutes.register('gist_show_formatted', '/_admin/gists/%(gist_id)s/rev/%(revision)s/%(format)s', ['gist_id', 'revision', 'format']);
179 pyroutes.register('gist_show_formatted', '/_admin/gists/%(gist_id)s/rev/%(revision)s/%(format)s', ['gist_id', 'revision', 'format']);
167 pyroutes.register('gist_show_formatted_path', '/_admin/gists/%(gist_id)s/rev/%(revision)s/%(format)s/%(f_path)s', ['gist_id', 'revision', 'format', 'f_path']);
180 pyroutes.register('gist_show_formatted_path', '/_admin/gists/%(gist_id)s/rev/%(revision)s/%(format)s/%(f_path)s', ['gist_id', 'revision', 'format', 'f_path']);
168 pyroutes.register('gist_show_rev', '/_admin/gists/%(gist_id)s/rev/%(revision)s', ['gist_id', 'revision']);
181 pyroutes.register('gist_show_rev', '/_admin/gists/%(gist_id)s/rev/%(revision)s', ['gist_id', 'revision']);
169 pyroutes.register('gist_update', '/_admin/gists/%(gist_id)s/update', ['gist_id']);
182 pyroutes.register('gist_update', '/_admin/gists/%(gist_id)s/update', ['gist_id']);
170 pyroutes.register('gists_create', '/_admin/gists/create', []);
183 pyroutes.register('gists_create', '/_admin/gists/create', []);
171 pyroutes.register('gists_new', '/_admin/gists/new', []);
184 pyroutes.register('gists_new', '/_admin/gists/new', []);
172 pyroutes.register('gists_show', '/_admin/gists', []);
185 pyroutes.register('gists_show', '/_admin/gists', []);
173 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
186 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
174 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
187 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
175 pyroutes.register('global_integrations_home', '/_admin/integrations', []);
188 pyroutes.register('global_integrations_home', '/_admin/integrations', []);
176 pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']);
189 pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']);
177 pyroutes.register('global_integrations_new', '/_admin/integrations/new', []);
190 pyroutes.register('global_integrations_new', '/_admin/integrations/new', []);
178 pyroutes.register('goto_switcher_data', '/_goto_data', []);
191 pyroutes.register('goto_switcher_data', '/_goto_data', []);
179 pyroutes.register('home', '/', []);
192 pyroutes.register('home', '/', []);
180 pyroutes.register('hovercard_pull_request', '/_hovercard/pull_request/%(pull_request_id)s', ['pull_request_id']);
193 pyroutes.register('hovercard_pull_request', '/_hovercard/pull_request/%(pull_request_id)s', ['pull_request_id']);
181 pyroutes.register('hovercard_repo_commit', '/_hovercard/commit/%(repo_name)s/%(commit_id)s', ['repo_name', 'commit_id']);
194 pyroutes.register('hovercard_repo_commit', '/_hovercard/commit/%(repo_name)s/%(commit_id)s', ['repo_name', 'commit_id']);
182 pyroutes.register('hovercard_user', '/_hovercard/user/%(user_id)s', ['user_id']);
195 pyroutes.register('hovercard_user', '/_hovercard/user/%(user_id)s', ['user_id']);
183 pyroutes.register('hovercard_user_group', '/_hovercard/user_group/%(user_group_id)s', ['user_group_id']);
196 pyroutes.register('hovercard_user_group', '/_hovercard/user_group/%(user_group_id)s', ['user_group_id']);
184 pyroutes.register('hovercard_username', '/_hovercard/username/%(username)s', ['username']);
197 pyroutes.register('hovercard_username', '/_hovercard/username/%(username)s', ['username']);
185 pyroutes.register('journal', '/_admin/journal', []);
198 pyroutes.register('journal', '/_admin/journal', []);
186 pyroutes.register('journal_atom', '/_admin/journal/atom', []);
199 pyroutes.register('journal_atom', '/_admin/journal/atom', []);
187 pyroutes.register('journal_public', '/_admin/public_journal', []);
200 pyroutes.register('journal_public', '/_admin/public_journal', []);
188 pyroutes.register('journal_public_atom', '/_admin/public_journal/atom', []);
201 pyroutes.register('journal_public_atom', '/_admin/public_journal/atom', []);
189 pyroutes.register('journal_public_atom_old', '/_admin/public_journal_atom', []);
202 pyroutes.register('journal_public_atom_old', '/_admin/public_journal_atom', []);
190 pyroutes.register('journal_public_rss', '/_admin/public_journal/rss', []);
203 pyroutes.register('journal_public_rss', '/_admin/public_journal/rss', []);
191 pyroutes.register('journal_public_rss_old', '/_admin/public_journal_rss', []);
204 pyroutes.register('journal_public_rss_old', '/_admin/public_journal_rss', []);
192 pyroutes.register('journal_rss', '/_admin/journal/rss', []);
205 pyroutes.register('journal_rss', '/_admin/journal/rss', []);
193 pyroutes.register('login', '/_admin/login', []);
206 pyroutes.register('login', '/_admin/login', []);
194 pyroutes.register('logout', '/_admin/logout', []);
207 pyroutes.register('logout', '/_admin/logout', []);
195 pyroutes.register('main_page_repo_groups_data', '/_home_repo_groups', []);
208 pyroutes.register('main_page_repo_groups_data', '/_home_repo_groups', []);
196 pyroutes.register('main_page_repos_data', '/_home_repos', []);
209 pyroutes.register('main_page_repos_data', '/_home_repos', []);
197 pyroutes.register('markup_preview', '/_markup_preview', []);
210 pyroutes.register('markup_preview', '/_markup_preview', []);
198 pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
211 pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
199 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
212 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
200 pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
213 pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
201 pyroutes.register('my_account_auth_tokens_view', '/_admin/my_account/auth_tokens/view', []);
214 pyroutes.register('my_account_auth_tokens_view', '/_admin/my_account/auth_tokens/view', []);
202 pyroutes.register('my_account_bookmarks', '/_admin/my_account/bookmarks', []);
215 pyroutes.register('my_account_bookmarks', '/_admin/my_account/bookmarks', []);
203 pyroutes.register('my_account_bookmarks_update', '/_admin/my_account/bookmarks/update', []);
216 pyroutes.register('my_account_bookmarks_update', '/_admin/my_account/bookmarks/update', []);
204 pyroutes.register('my_account_edit', '/_admin/my_account/edit', []);
217 pyroutes.register('my_account_edit', '/_admin/my_account/edit', []);
205 pyroutes.register('my_account_emails', '/_admin/my_account/emails', []);
218 pyroutes.register('my_account_emails', '/_admin/my_account/emails', []);
206 pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []);
219 pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []);
207 pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []);
220 pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []);
221 pyroutes.register('my_account_external_identity', '/_admin/my_account/external-identity', []);
222 pyroutes.register('my_account_external_identity_delete', '/_admin/my_account/external-identity/delete', []);
208 pyroutes.register('my_account_goto_bookmark', '/_admin/my_account/bookmark/%(bookmark_id)s', ['bookmark_id']);
223 pyroutes.register('my_account_goto_bookmark', '/_admin/my_account/bookmark/%(bookmark_id)s', ['bookmark_id']);
209 pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []);
224 pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []);
210 pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
225 pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
211 pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []);
226 pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []);
212 pyroutes.register('my_account_password', '/_admin/my_account/password', []);
227 pyroutes.register('my_account_password', '/_admin/my_account/password', []);
213 pyroutes.register('my_account_password_update', '/_admin/my_account/password/update', []);
228 pyroutes.register('my_account_password_update', '/_admin/my_account/password/update', []);
214 pyroutes.register('my_account_perms', '/_admin/my_account/perms', []);
229 pyroutes.register('my_account_perms', '/_admin/my_account/perms', []);
215 pyroutes.register('my_account_profile', '/_admin/my_account/profile', []);
230 pyroutes.register('my_account_profile', '/_admin/my_account/profile', []);
216 pyroutes.register('my_account_pullrequests', '/_admin/my_account/pull_requests', []);
231 pyroutes.register('my_account_pullrequests', '/_admin/my_account/pull_requests', []);
217 pyroutes.register('my_account_pullrequests_data', '/_admin/my_account/pull_requests/data', []);
232 pyroutes.register('my_account_pullrequests_data', '/_admin/my_account/pull_requests/data', []);
218 pyroutes.register('my_account_repos', '/_admin/my_account/repos', []);
233 pyroutes.register('my_account_repos', '/_admin/my_account/repos', []);
219 pyroutes.register('my_account_ssh_keys', '/_admin/my_account/ssh_keys', []);
234 pyroutes.register('my_account_ssh_keys', '/_admin/my_account/ssh_keys', []);
220 pyroutes.register('my_account_ssh_keys_add', '/_admin/my_account/ssh_keys/new', []);
235 pyroutes.register('my_account_ssh_keys_add', '/_admin/my_account/ssh_keys/new', []);
221 pyroutes.register('my_account_ssh_keys_delete', '/_admin/my_account/ssh_keys/delete', []);
236 pyroutes.register('my_account_ssh_keys_delete', '/_admin/my_account/ssh_keys/delete', []);
222 pyroutes.register('my_account_ssh_keys_generate', '/_admin/my_account/ssh_keys/generate', []);
237 pyroutes.register('my_account_ssh_keys_generate', '/_admin/my_account/ssh_keys/generate', []);
223 pyroutes.register('my_account_update', '/_admin/my_account/update', []);
238 pyroutes.register('my_account_update', '/_admin/my_account/update', []);
224 pyroutes.register('my_account_user_group_membership', '/_admin/my_account/user_group_membership', []);
239 pyroutes.register('my_account_user_group_membership', '/_admin/my_account/user_group_membership', []);
225 pyroutes.register('my_account_watched', '/_admin/my_account/watched', []);
240 pyroutes.register('my_account_watched', '/_admin/my_account/watched', []);
226 pyroutes.register('notifications_delete', '/_admin/notifications/%(notification_id)s/delete', ['notification_id']);
241 pyroutes.register('notifications_delete', '/_admin/notifications/%(notification_id)s/delete', ['notification_id']);
227 pyroutes.register('notifications_mark_all_read', '/_admin/notifications_mark_all_read', []);
242 pyroutes.register('notifications_mark_all_read', '/_admin/notifications_mark_all_read', []);
228 pyroutes.register('notifications_show', '/_admin/notifications/%(notification_id)s', ['notification_id']);
243 pyroutes.register('notifications_show', '/_admin/notifications/%(notification_id)s', ['notification_id']);
229 pyroutes.register('notifications_show_all', '/_admin/notifications', []);
244 pyroutes.register('notifications_show_all', '/_admin/notifications', []);
230 pyroutes.register('notifications_update', '/_admin/notifications/%(notification_id)s/update', ['notification_id']);
245 pyroutes.register('notifications_update', '/_admin/notifications/%(notification_id)s/update', ['notification_id']);
231 pyroutes.register('ops_error_test', '/_admin/ops/error', []);
246 pyroutes.register('ops_error_test', '/_admin/ops/error', []);
232 pyroutes.register('ops_healthcheck', '/_admin/ops/status', []);
247 pyroutes.register('ops_healthcheck', '/_admin/ops/status', []);
233 pyroutes.register('ops_ping', '/_admin/ops/ping', []);
248 pyroutes.register('ops_ping', '/_admin/ops/ping', []);
234 pyroutes.register('ops_redirect_test', '/_admin/ops/redirect', []);
249 pyroutes.register('ops_redirect_test', '/_admin/ops/redirect', []);
250 pyroutes.register('plugin_admin_chat', '/_admin/plugin_admin_chat/%(action)s', ['action']);
235 pyroutes.register('pull_requests_global', '/_admin/pull-request/%(pull_request_id)s', ['pull_request_id']);
251 pyroutes.register('pull_requests_global', '/_admin/pull-request/%(pull_request_id)s', ['pull_request_id']);
236 pyroutes.register('pull_requests_global_0', '/_admin/pull_requests/%(pull_request_id)s', ['pull_request_id']);
252 pyroutes.register('pull_requests_global_0', '/_admin/pull_requests/%(pull_request_id)s', ['pull_request_id']);
237 pyroutes.register('pull_requests_global_1', '/_admin/pull-requests/%(pull_request_id)s', ['pull_request_id']);
253 pyroutes.register('pull_requests_global_1', '/_admin/pull-requests/%(pull_request_id)s', ['pull_request_id']);
238 pyroutes.register('pullrequest_comment_create', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment', ['repo_name', 'pull_request_id']);
254 pyroutes.register('pullrequest_comment_create', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment', ['repo_name', 'pull_request_id']);
239 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/delete', ['repo_name', 'pull_request_id', 'comment_id']);
255 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/delete', ['repo_name', 'pull_request_id', 'comment_id']);
240 pyroutes.register('pullrequest_comment_edit', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/edit', ['repo_name', 'pull_request_id', 'comment_id']);
256 pyroutes.register('pullrequest_comment_edit', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/edit', ['repo_name', 'pull_request_id', 'comment_id']);
241 pyroutes.register('pullrequest_comments', '/%(repo_name)s/pull-request/%(pull_request_id)s/comments', ['repo_name', 'pull_request_id']);
257 pyroutes.register('pullrequest_comments', '/%(repo_name)s/pull-request/%(pull_request_id)s/comments', ['repo_name', 'pull_request_id']);
242 pyroutes.register('pullrequest_create', '/%(repo_name)s/pull-request/create', ['repo_name']);
258 pyroutes.register('pullrequest_create', '/%(repo_name)s/pull-request/create', ['repo_name']);
243 pyroutes.register('pullrequest_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/delete', ['repo_name', 'pull_request_id']);
259 pyroutes.register('pullrequest_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/delete', ['repo_name', 'pull_request_id']);
260 pyroutes.register('pullrequest_draft_comments_submit', '/%(repo_name)s/pull-request/%(pull_request_id)s/draft_comments_submit', ['repo_name', 'pull_request_id']);
244 pyroutes.register('pullrequest_drafts', '/%(repo_name)s/pull-request/%(pull_request_id)s/drafts', ['repo_name', 'pull_request_id']);
261 pyroutes.register('pullrequest_drafts', '/%(repo_name)s/pull-request/%(pull_request_id)s/drafts', ['repo_name', 'pull_request_id']);
245 pyroutes.register('pullrequest_merge', '/%(repo_name)s/pull-request/%(pull_request_id)s/merge', ['repo_name', 'pull_request_id']);
262 pyroutes.register('pullrequest_merge', '/%(repo_name)s/pull-request/%(pull_request_id)s/merge', ['repo_name', 'pull_request_id']);
246 pyroutes.register('pullrequest_new', '/%(repo_name)s/pull-request/new', ['repo_name']);
263 pyroutes.register('pullrequest_new', '/%(repo_name)s/pull-request/new', ['repo_name']);
247 pyroutes.register('pullrequest_repo_refs', '/%(repo_name)s/pull-request/refs/%(target_repo_name)s', ['repo_name', 'target_repo_name']);
264 pyroutes.register('pullrequest_repo_refs', '/%(repo_name)s/pull-request/refs/%(target_repo_name)s', ['repo_name', 'target_repo_name']);
248 pyroutes.register('pullrequest_repo_targets', '/%(repo_name)s/pull-request/repo-targets', ['repo_name']);
265 pyroutes.register('pullrequest_repo_targets', '/%(repo_name)s/pull-request/repo-targets', ['repo_name']);
249 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
266 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
250 pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
267 pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
251 pyroutes.register('pullrequest_show_all_data', '/%(repo_name)s/pull-request-data', ['repo_name']);
268 pyroutes.register('pullrequest_show_all_data', '/%(repo_name)s/pull-request-data', ['repo_name']);
252 pyroutes.register('pullrequest_todos', '/%(repo_name)s/pull-request/%(pull_request_id)s/todos', ['repo_name', 'pull_request_id']);
269 pyroutes.register('pullrequest_todos', '/%(repo_name)s/pull-request/%(pull_request_id)s/todos', ['repo_name', 'pull_request_id']);
253 pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s/update', ['repo_name', 'pull_request_id']);
270 pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s/update', ['repo_name', 'pull_request_id']);
254 pyroutes.register('register', '/_admin/register', []);
271 pyroutes.register('register', '/_admin/register', []);
255 pyroutes.register('repo_archivefile', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
272 pyroutes.register('repo_archivefile', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
273 pyroutes.register('repo_artifacts_data', '/%(repo_name)s/artifacts_data', ['repo_name']);
274 pyroutes.register('repo_artifacts_delete', '/%(repo_name)s/artifacts/delete/%(uid)s', ['repo_name', 'uid']);
275 pyroutes.register('repo_artifacts_get', '/%(repo_name)s/artifacts/download/%(uid)s', ['repo_name', 'uid']);
276 pyroutes.register('repo_artifacts_info', '/%(repo_name)s/artifacts/info/%(uid)s', ['repo_name', 'uid']);
256 pyroutes.register('repo_artifacts_list', '/%(repo_name)s/artifacts', ['repo_name']);
277 pyroutes.register('repo_artifacts_list', '/%(repo_name)s/artifacts', ['repo_name']);
278 pyroutes.register('repo_artifacts_new', '/%(repo_name)s/artifacts/new', ['repo_name']);
279 pyroutes.register('repo_artifacts_store', '/%(repo_name)s/artifacts/store', ['repo_name']);
280 pyroutes.register('repo_artifacts_stream_script', '/_file_store/stream-upload-script', []);
281 pyroutes.register('repo_artifacts_stream_store', '/_file_store/stream-upload', []);
282 pyroutes.register('repo_artifacts_update', '/%(repo_name)s/artifacts/update/%(uid)s', ['repo_name', 'uid']);
257 pyroutes.register('repo_automation', '/%(repo_name)s/settings/automation', ['repo_name']);
283 pyroutes.register('repo_automation', '/%(repo_name)s/settings/automation', ['repo_name']);
284 pyroutes.register('repo_automation_update', '/%(repo_name)s/settings/automation/%(entry_id)s/update', ['repo_name', 'entry_id']);
258 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
285 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
259 pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
286 pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
260 pyroutes.register('repo_commit', '/%(repo_name)s/changeset/%(commit_id)s', ['repo_name', 'commit_id']);
287 pyroutes.register('repo_commit', '/%(repo_name)s/changeset/%(commit_id)s', ['repo_name', 'commit_id']);
261 pyroutes.register('repo_commit_children', '/%(repo_name)s/changeset_children/%(commit_id)s', ['repo_name', 'commit_id']);
288 pyroutes.register('repo_commit_children', '/%(repo_name)s/changeset_children/%(commit_id)s', ['repo_name', 'commit_id']);
262 pyroutes.register('repo_commit_comment_attachment_upload', '/%(repo_name)s/changeset/%(commit_id)s/comment/attachment_upload', ['repo_name', 'commit_id']);
289 pyroutes.register('repo_commit_comment_attachment_upload', '/%(repo_name)s/changeset/%(commit_id)s/comment/attachment_upload', ['repo_name', 'commit_id']);
263 pyroutes.register('repo_commit_comment_create', '/%(repo_name)s/changeset/%(commit_id)s/comment/create', ['repo_name', 'commit_id']);
290 pyroutes.register('repo_commit_comment_create', '/%(repo_name)s/changeset/%(commit_id)s/comment/create', ['repo_name', 'commit_id']);
264 pyroutes.register('repo_commit_comment_delete', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/delete', ['repo_name', 'commit_id', 'comment_id']);
291 pyroutes.register('repo_commit_comment_delete', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/delete', ['repo_name', 'commit_id', 'comment_id']);
265 pyroutes.register('repo_commit_comment_edit', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/edit', ['repo_name', 'commit_id', 'comment_id']);
292 pyroutes.register('repo_commit_comment_edit', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/edit', ['repo_name', 'commit_id', 'comment_id']);
266 pyroutes.register('repo_commit_comment_history_view', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/history_view/%(comment_history_id)s', ['repo_name', 'commit_id', 'comment_id', 'comment_history_id']);
293 pyroutes.register('repo_commit_comment_history_view', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/history_view/%(comment_history_id)s', ['repo_name', 'commit_id', 'comment_id', 'comment_history_id']);
267 pyroutes.register('repo_commit_comment_preview', '/%(repo_name)s/changeset/%(commit_id)s/comment/preview', ['repo_name', 'commit_id']);
294 pyroutes.register('repo_commit_comment_preview', '/%(repo_name)s/changeset/%(commit_id)s/comment/preview', ['repo_name', 'commit_id']);
268 pyroutes.register('repo_commit_data', '/%(repo_name)s/changeset-data/%(commit_id)s', ['repo_name', 'commit_id']);
295 pyroutes.register('repo_commit_data', '/%(repo_name)s/changeset-data/%(commit_id)s', ['repo_name', 'commit_id']);
269 pyroutes.register('repo_commit_download', '/%(repo_name)s/changeset-download/%(commit_id)s', ['repo_name', 'commit_id']);
296 pyroutes.register('repo_commit_download', '/%(repo_name)s/changeset-download/%(commit_id)s', ['repo_name', 'commit_id']);
270 pyroutes.register('repo_commit_parents', '/%(repo_name)s/changeset_parents/%(commit_id)s', ['repo_name', 'commit_id']);
297 pyroutes.register('repo_commit_parents', '/%(repo_name)s/changeset_parents/%(commit_id)s', ['repo_name', 'commit_id']);
271 pyroutes.register('repo_commit_patch', '/%(repo_name)s/changeset-patch/%(commit_id)s', ['repo_name', 'commit_id']);
298 pyroutes.register('repo_commit_patch', '/%(repo_name)s/changeset-patch/%(commit_id)s', ['repo_name', 'commit_id']);
272 pyroutes.register('repo_commit_raw', '/%(repo_name)s/changeset-diff/%(commit_id)s', ['repo_name', 'commit_id']);
299 pyroutes.register('repo_commit_raw', '/%(repo_name)s/changeset-diff/%(commit_id)s', ['repo_name', 'commit_id']);
273 pyroutes.register('repo_commit_raw_deprecated', '/%(repo_name)s/raw-changeset/%(commit_id)s', ['repo_name', 'commit_id']);
300 pyroutes.register('repo_commit_raw_deprecated', '/%(repo_name)s/raw-changeset/%(commit_id)s', ['repo_name', 'commit_id']);
274 pyroutes.register('repo_commits', '/%(repo_name)s/commits', ['repo_name']);
301 pyroutes.register('repo_commits', '/%(repo_name)s/commits', ['repo_name']);
275 pyroutes.register('repo_commits_elements', '/%(repo_name)s/commits_elements', ['repo_name']);
302 pyroutes.register('repo_commits_elements', '/%(repo_name)s/commits_elements', ['repo_name']);
276 pyroutes.register('repo_commits_elements_file', '/%(repo_name)s/commits_elements/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
303 pyroutes.register('repo_commits_elements_file', '/%(repo_name)s/commits_elements/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
277 pyroutes.register('repo_commits_file', '/%(repo_name)s/commits/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
304 pyroutes.register('repo_commits_file', '/%(repo_name)s/commits/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
278 pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
305 pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
279 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
306 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
280 pyroutes.register('repo_create', '/_admin/repos/create', []);
307 pyroutes.register('repo_create', '/_admin/repos/create', []);
281 pyroutes.register('repo_creating', '/%(repo_name)s/repo_creating', ['repo_name']);
308 pyroutes.register('repo_creating', '/%(repo_name)s/repo_creating', ['repo_name']);
282 pyroutes.register('repo_creating_check', '/%(repo_name)s/repo_creating_check', ['repo_name']);
309 pyroutes.register('repo_creating_check', '/%(repo_name)s/repo_creating_check', ['repo_name']);
283 pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']);
310 pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']);
284 pyroutes.register('repo_file_authors', '/%(repo_name)s/authors/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
311 pyroutes.register('repo_file_authors', '/%(repo_name)s/authors/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
285 pyroutes.register('repo_file_download', '/%(repo_name)s/download/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
312 pyroutes.register('repo_file_download', '/%(repo_name)s/download/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
286 pyroutes.register('repo_file_download:legacy', '/%(repo_name)s/rawfile/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
313 pyroutes.register('repo_file_download:legacy', '/%(repo_name)s/rawfile/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
287 pyroutes.register('repo_file_history', '/%(repo_name)s/history/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
314 pyroutes.register('repo_file_history', '/%(repo_name)s/history/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
288 pyroutes.register('repo_file_raw', '/%(repo_name)s/raw/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
315 pyroutes.register('repo_file_raw', '/%(repo_name)s/raw/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
289 pyroutes.register('repo_files', '/%(repo_name)s/files/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
316 pyroutes.register('repo_files', '/%(repo_name)s/files/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
290 pyroutes.register('repo_files:annotated', '/%(repo_name)s/annotate/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
317 pyroutes.register('repo_files:annotated', '/%(repo_name)s/annotate/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
291 pyroutes.register('repo_files:annotated_previous', '/%(repo_name)s/annotate-previous/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
318 pyroutes.register('repo_files:annotated_previous', '/%(repo_name)s/annotate-previous/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
292 pyroutes.register('repo_files:default_commit', '/%(repo_name)s/files', ['repo_name']);
319 pyroutes.register('repo_files:default_commit', '/%(repo_name)s/files', ['repo_name']);
293 pyroutes.register('repo_files:default_path', '/%(repo_name)s/files/%(commit_id)s/', ['repo_name', 'commit_id']);
320 pyroutes.register('repo_files:default_path', '/%(repo_name)s/files/%(commit_id)s/', ['repo_name', 'commit_id']);
294 pyroutes.register('repo_files:rendered', '/%(repo_name)s/render/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
321 pyroutes.register('repo_files:rendered', '/%(repo_name)s/render/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
295 pyroutes.register('repo_files_add_file', '/%(repo_name)s/add_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
322 pyroutes.register('repo_files_add_file', '/%(repo_name)s/add_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
296 pyroutes.register('repo_files_check_head', '/%(repo_name)s/check_head/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
323 pyroutes.register('repo_files_check_head', '/%(repo_name)s/check_head/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
297 pyroutes.register('repo_files_create_file', '/%(repo_name)s/create_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
324 pyroutes.register('repo_files_create_file', '/%(repo_name)s/create_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
298 pyroutes.register('repo_files_delete_file', '/%(repo_name)s/delete_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
325 pyroutes.register('repo_files_delete_file', '/%(repo_name)s/delete_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
299 pyroutes.register('repo_files_diff', '/%(repo_name)s/diff/%(f_path)s', ['repo_name', 'f_path']);
326 pyroutes.register('repo_files_diff', '/%(repo_name)s/diff/%(f_path)s', ['repo_name', 'f_path']);
300 pyroutes.register('repo_files_diff_2way_redirect', '/%(repo_name)s/diff-2way/%(f_path)s', ['repo_name', 'f_path']);
327 pyroutes.register('repo_files_diff_2way_redirect', '/%(repo_name)s/diff-2way/%(f_path)s', ['repo_name', 'f_path']);
301 pyroutes.register('repo_files_edit_file', '/%(repo_name)s/edit_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
328 pyroutes.register('repo_files_edit_file', '/%(repo_name)s/edit_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
302 pyroutes.register('repo_files_nodelist', '/%(repo_name)s/nodelist/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
329 pyroutes.register('repo_files_nodelist', '/%(repo_name)s/nodelist/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
303 pyroutes.register('repo_files_remove_file', '/%(repo_name)s/remove_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
330 pyroutes.register('repo_files_remove_file', '/%(repo_name)s/remove_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
304 pyroutes.register('repo_files_update_file', '/%(repo_name)s/update_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
331 pyroutes.register('repo_files_update_file', '/%(repo_name)s/update_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
305 pyroutes.register('repo_files_upload_file', '/%(repo_name)s/upload_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
332 pyroutes.register('repo_files_upload_file', '/%(repo_name)s/upload_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
306 pyroutes.register('repo_fork_create', '/%(repo_name)s/fork/create', ['repo_name']);
333 pyroutes.register('repo_fork_create', '/%(repo_name)s/fork/create', ['repo_name']);
307 pyroutes.register('repo_fork_new', '/%(repo_name)s/fork', ['repo_name']);
334 pyroutes.register('repo_fork_new', '/%(repo_name)s/fork', ['repo_name']);
308 pyroutes.register('repo_forks_data', '/%(repo_name)s/forks/data', ['repo_name']);
335 pyroutes.register('repo_forks_data', '/%(repo_name)s/forks/data', ['repo_name']);
309 pyroutes.register('repo_forks_show_all', '/%(repo_name)s/forks', ['repo_name']);
336 pyroutes.register('repo_forks_show_all', '/%(repo_name)s/forks', ['repo_name']);
310 pyroutes.register('repo_group_create', '/_admin/repo_group/create', []);
337 pyroutes.register('repo_group_create', '/_admin/repo_group/create', []);
311 pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
338 pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
312 pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
339 pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
313 pyroutes.register('repo_group_integrations_create', '/%(repo_group_name)s/_settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
340 pyroutes.register('repo_group_integrations_create', '/%(repo_group_name)s/_settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
314 pyroutes.register('repo_group_integrations_edit', '/%(repo_group_name)s/_settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
341 pyroutes.register('repo_group_integrations_edit', '/%(repo_group_name)s/_settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
315 pyroutes.register('repo_group_integrations_home', '/%(repo_group_name)s/_settings/integrations', ['repo_group_name']);
342 pyroutes.register('repo_group_integrations_home', '/%(repo_group_name)s/_settings/integrations', ['repo_group_name']);
316 pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/_settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
343 pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/_settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
317 pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/_settings/integrations/new', ['repo_group_name']);
344 pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/_settings/integrations/new', ['repo_group_name']);
318 pyroutes.register('repo_group_list_data', '/_repo_groups', []);
345 pyroutes.register('repo_group_list_data', '/_repo_groups', []);
319 pyroutes.register('repo_group_new', '/_admin/repo_group/new', []);
346 pyroutes.register('repo_group_new', '/_admin/repo_group/new', []);
320 pyroutes.register('repo_groups', '/_admin/repo_groups', []);
347 pyroutes.register('repo_groups', '/_admin/repo_groups', []);
321 pyroutes.register('repo_groups_data', '/_admin/repo_groups_data', []);
348 pyroutes.register('repo_groups_data', '/_admin/repo_groups_data', []);
322 pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
349 pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
323 pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
350 pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
324 pyroutes.register('repo_integrations_home', '/%(repo_name)s/settings/integrations', ['repo_name']);
351 pyroutes.register('repo_integrations_home', '/%(repo_name)s/settings/integrations', ['repo_name']);
325 pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
352 pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
326 pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
353 pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
327 pyroutes.register('repo_list_data', '/_repos', []);
354 pyroutes.register('repo_list_data', '/_repos', []);
328 pyroutes.register('repo_new', '/_admin/repos/new', []);
355 pyroutes.register('repo_new', '/_admin/repos/new', []);
329 pyroutes.register('repo_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
356 pyroutes.register('repo_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
330 pyroutes.register('repo_nodetree_full:default_path', '/%(repo_name)s/nodetree_full/%(commit_id)s/', ['repo_name', 'commit_id']);
357 pyroutes.register('repo_nodetree_full:default_path', '/%(repo_name)s/nodetree_full/%(commit_id)s/', ['repo_name', 'commit_id']);
331 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
358 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
332 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
359 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
333 pyroutes.register('repo_reviewers', '/%(repo_name)s/settings/review/rules', ['repo_name']);
360 pyroutes.register('repo_reviewers', '/%(repo_name)s/settings/review/rules', ['repo_name']);
361 pyroutes.register('repo_reviewers_review_rule_delete', '/%(repo_name)s/settings/review/rules/%(rule_id)s/delete', ['repo_name', 'rule_id']);
362 pyroutes.register('repo_reviewers_review_rule_edit', '/%(repo_name)s/settings/review/rules/%(rule_id)s', ['repo_name', 'rule_id']);
363 pyroutes.register('repo_reviewers_review_rule_new', '/%(repo_name)s/settings/review/rules/new', ['repo_name']);
334 pyroutes.register('repo_settings_quick_actions', '/%(repo_name)s/settings/quick-action', ['repo_name']);
364 pyroutes.register('repo_settings_quick_actions', '/%(repo_name)s/settings/quick-action', ['repo_name']);
335 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
365 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
336 pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
366 pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
337 pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']);
367 pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']);
338 pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
368 pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
339 pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
369 pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
340 pyroutes.register('repos', '/_admin/repos', []);
370 pyroutes.register('repos', '/_admin/repos', []);
341 pyroutes.register('repos_data', '/_admin/repos_data', []);
371 pyroutes.register('repos_data', '/_admin/repos_data', []);
342 pyroutes.register('reset_password', '/_admin/password_reset', []);
372 pyroutes.register('reset_password', '/_admin/password_reset', []);
343 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
373 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
344 pyroutes.register('robots', '/robots.txt', []);
374 pyroutes.register('robots', '/robots.txt', []);
345 pyroutes.register('rss_feed_home', '/%(repo_name)s/feed-rss', ['repo_name']);
375 pyroutes.register('rss_feed_home', '/%(repo_name)s/feed-rss', ['repo_name']);
346 pyroutes.register('rss_feed_home_old', '/%(repo_name)s/feed/rss', ['repo_name']);
376 pyroutes.register('rss_feed_home_old', '/%(repo_name)s/feed/rss', ['repo_name']);
347 pyroutes.register('search', '/_admin/search', []);
377 pyroutes.register('search', '/_admin/search', []);
348 pyroutes.register('search_repo', '/%(repo_name)s/_search', ['repo_name']);
378 pyroutes.register('search_repo', '/%(repo_name)s/_search', ['repo_name']);
349 pyroutes.register('search_repo_alt', '/%(repo_name)s/search', ['repo_name']);
379 pyroutes.register('search_repo_alt', '/%(repo_name)s/search', ['repo_name']);
350 pyroutes.register('search_repo_group', '/%(repo_group_name)s/_search', ['repo_group_name']);
380 pyroutes.register('search_repo_group', '/%(repo_group_name)s/_search', ['repo_group_name']);
351 pyroutes.register('store_user_session_value', '/_store_session_attr', []);
381 pyroutes.register('store_user_session_value', '/_store_session_attr', []);
352 pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
382 pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
353 pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
383 pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
354 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
384 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
355 pyroutes.register('toggle_following', '/_admin/toggle_following', []);
385 pyroutes.register('toggle_following', '/_admin/toggle_following', []);
356 pyroutes.register('upload_file', '/_file_store/upload', []);
386 pyroutes.register('upload_file', '/_file_store/upload', []);
357 pyroutes.register('user_autocomplete_data', '/_users', []);
387 pyroutes.register('user_autocomplete_data', '/_users', []);
358 pyroutes.register('user_create_personal_repo_group', '/_admin/users/%(user_id)s/create_repo_group', ['user_id']);
388 pyroutes.register('user_create_personal_repo_group', '/_admin/users/%(user_id)s/create_repo_group', ['user_id']);
359 pyroutes.register('user_delete', '/_admin/users/%(user_id)s/delete', ['user_id']);
389 pyroutes.register('user_delete', '/_admin/users/%(user_id)s/delete', ['user_id']);
360 pyroutes.register('user_disable_force_password_reset', '/_admin/users/%(user_id)s/password_reset_disable', ['user_id']);
390 pyroutes.register('user_disable_force_password_reset', '/_admin/users/%(user_id)s/password_reset_disable', ['user_id']);
361 pyroutes.register('user_edit', '/_admin/users/%(user_id)s/edit', ['user_id']);
391 pyroutes.register('user_edit', '/_admin/users/%(user_id)s/edit', ['user_id']);
362 pyroutes.register('user_edit_advanced', '/_admin/users/%(user_id)s/edit/advanced', ['user_id']);
392 pyroutes.register('user_edit_advanced', '/_admin/users/%(user_id)s/edit/advanced', ['user_id']);
363 pyroutes.register('user_edit_global_perms', '/_admin/users/%(user_id)s/edit/global_permissions', ['user_id']);
393 pyroutes.register('user_edit_global_perms', '/_admin/users/%(user_id)s/edit/global_permissions', ['user_id']);
364 pyroutes.register('user_edit_global_perms_update', '/_admin/users/%(user_id)s/edit/global_permissions/update', ['user_id']);
394 pyroutes.register('user_edit_global_perms_update', '/_admin/users/%(user_id)s/edit/global_permissions/update', ['user_id']);
365 pyroutes.register('user_enable_force_password_reset', '/_admin/users/%(user_id)s/password_reset_enable', ['user_id']);
395 pyroutes.register('user_enable_force_password_reset', '/_admin/users/%(user_id)s/password_reset_enable', ['user_id']);
366 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
396 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
367 pyroutes.register('user_group_members_data', '/_admin/user_groups/%(user_group_id)s/members', ['user_group_id']);
397 pyroutes.register('user_group_members_data', '/_admin/user_groups/%(user_group_id)s/members', ['user_group_id']);
368 pyroutes.register('user_group_profile', '/_profile_user_group/%(user_group_name)s', ['user_group_name']);
398 pyroutes.register('user_group_profile', '/_profile_user_group/%(user_group_name)s', ['user_group_name']);
369 pyroutes.register('user_groups', '/_admin/user_groups', []);
399 pyroutes.register('user_groups', '/_admin/user_groups', []);
370 pyroutes.register('user_groups_create', '/_admin/user_groups/create', []);
400 pyroutes.register('user_groups_create', '/_admin/user_groups/create', []);
371 pyroutes.register('user_groups_data', '/_admin/user_groups_data', []);
401 pyroutes.register('user_groups_data', '/_admin/user_groups_data', []);
372 pyroutes.register('user_groups_delete', '/_admin/user_groups/%(user_group_id)s/delete', ['user_group_id']);
402 pyroutes.register('user_groups_delete', '/_admin/user_groups/%(user_group_id)s/delete', ['user_group_id']);
373 pyroutes.register('user_groups_new', '/_admin/user_groups/new', []);
403 pyroutes.register('user_groups_new', '/_admin/user_groups/new', []);
374 pyroutes.register('user_groups_update', '/_admin/user_groups/%(user_group_id)s/update', ['user_group_id']);
404 pyroutes.register('user_groups_update', '/_admin/user_groups/%(user_group_id)s/update', ['user_group_id']);
375 pyroutes.register('user_notice_dismiss', '/_admin/users/%(user_id)s/notice_dismiss', ['user_id']);
405 pyroutes.register('user_notice_dismiss', '/_admin/users/%(user_id)s/notice_dismiss', ['user_id']);
376 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
406 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
377 pyroutes.register('user_update', '/_admin/users/%(user_id)s/update', ['user_id']);
407 pyroutes.register('user_update', '/_admin/users/%(user_id)s/update', ['user_id']);
378 pyroutes.register('users', '/_admin/users', []);
408 pyroutes.register('users', '/_admin/users', []);
379 pyroutes.register('users_create', '/_admin/users/create', []);
409 pyroutes.register('users_create', '/_admin/users/create', []);
380 pyroutes.register('users_data', '/_admin/users_data', []);
410 pyroutes.register('users_data', '/_admin/users_data', []);
381 pyroutes.register('users_new', '/_admin/users/new', []);
411 pyroutes.register('users_new', '/_admin/users/new', []);
382 }
412 }
@@ -1,397 +1,398 b''
1 # Copyright (C) 2010-2023 RhodeCode GmbH
1 # Copyright (C) 2010-2023 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
5 # (only), as published by the Free Software Foundation.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU Affero General Public License
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
14 #
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 import io
18 import io
19 import shlex
19 import shlex
20
20
21 import math
21 import math
22 import re
22 import re
23 import os
23 import os
24 import datetime
24 import datetime
25 import logging
25 import logging
26 import queue
26 import queue
27 import subprocess
27 import subprocess
28
28
29
29
30 from dateutil.parser import parse
30 from dateutil.parser import parse
31 from pyramid.interfaces import IRoutesMapper
31 from pyramid.interfaces import IRoutesMapper
32 from pyramid.settings import asbool
32 from pyramid.settings import asbool
33 from pyramid.path import AssetResolver
33 from pyramid.path import AssetResolver
34 from threading import Thread
34 from threading import Thread
35
35
36 from rhodecode.config.jsroutes import generate_jsroutes_content
36 from rhodecode.config.jsroutes import generate_jsroutes_content
37 from rhodecode.lib.base import get_auth_user
37 from rhodecode.lib.base import get_auth_user
38 from rhodecode.lib.celerylib.loader import set_celery_conf
38 from rhodecode.lib.celerylib.loader import set_celery_conf
39
39
40 import rhodecode
40 import rhodecode
41
41
42
42
43 log = logging.getLogger(__name__)
43 log = logging.getLogger(__name__)
44
44
45
45
46 def add_renderer_globals(event):
46 def add_renderer_globals(event):
47 from rhodecode.lib import helpers
47 from rhodecode.lib import helpers
48
48
49 # TODO: When executed in pyramid view context the request is not available
49 # TODO: When executed in pyramid view context the request is not available
50 # in the event. Find a better solution to get the request.
50 # in the event. Find a better solution to get the request.
51 from pyramid.threadlocal import get_current_request
51 from pyramid.threadlocal import get_current_request
52 request = event['request'] or get_current_request()
52 request = event['request'] or get_current_request()
53
53
54 # Add Pyramid translation as '_' to context
54 # Add Pyramid translation as '_' to context
55 event['_'] = request.translate
55 event['_'] = request.translate
56 event['_ungettext'] = request.plularize
56 event['_ungettext'] = request.plularize
57 event['h'] = helpers
57 event['h'] = helpers
58
58
59
59
60 def set_user_lang(event):
60 def set_user_lang(event):
61 request = event.request
61 request = event.request
62 cur_user = getattr(request, 'user', None)
62 cur_user = getattr(request, 'user', None)
63
63
64 if cur_user:
64 if cur_user:
65 user_lang = cur_user.get_instance().user_data.get('language')
65 user_lang = cur_user.get_instance().user_data.get('language')
66 if user_lang:
66 if user_lang:
67 log.debug('lang: setting current user:%s language to: %s', cur_user, user_lang)
67 log.debug('lang: setting current user:%s language to: %s', cur_user, user_lang)
68 event.request._LOCALE_ = user_lang
68 event.request._LOCALE_ = user_lang
69
69
70
70
71 def update_celery_conf(event):
71 def update_celery_conf(event):
72 log.debug('Setting celery config from new request')
72 log.debug('Setting celery config from new request')
73 set_celery_conf(request=event.request, registry=event.request.registry)
73 set_celery_conf(request=event.request, registry=event.request.registry)
74
74
75
75
76 def add_request_user_context(event):
76 def add_request_user_context(event):
77 """
77 """
78 Adds auth user into request context
78 Adds auth user into request context
79 """
79 """
80
80
81 request = event.request
81 request = event.request
82 # access req_id as soon as possible
82 # access req_id as soon as possible
83 req_id = request.req_id
83 req_id = request.req_id
84
84
85 if hasattr(request, 'vcs_call'):
85 if hasattr(request, 'vcs_call'):
86 # skip vcs calls
86 # skip vcs calls
87 return
87 return
88
88
89 if hasattr(request, 'rpc_method'):
89 if hasattr(request, 'rpc_method'):
90 # skip api calls
90 # skip api calls
91 return
91 return
92
92
93 auth_user, auth_token = get_auth_user(request)
93 auth_user, auth_token = get_auth_user(request)
94 request.user = auth_user
94 request.user = auth_user
95 request.user_auth_token = auth_token
95 request.user_auth_token = auth_token
96 request.environ['rc_auth_user'] = auth_user
96 request.environ['rc_auth_user'] = auth_user
97 request.environ['rc_auth_user_id'] = str(auth_user.user_id)
97 request.environ['rc_auth_user_id'] = str(auth_user.user_id)
98 request.environ['rc_req_id'] = req_id
98 request.environ['rc_req_id'] = req_id
99
99
100
100
101 def reset_log_bucket(event):
101 def reset_log_bucket(event):
102 """
102 """
103 reset the log bucket on new request
103 reset the log bucket on new request
104 """
104 """
105 request = event.request
105 request = event.request
106 request.req_id_records_init()
106 request.req_id_records_init()
107
107
108
108
109 def scan_repositories_if_enabled(event):
109 def scan_repositories_if_enabled(event):
110 """
110 """
111 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
111 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
112 does a repository scan if enabled in the settings.
112 does a repository scan if enabled in the settings.
113 """
113 """
114 settings = event.app.registry.settings
114 settings = event.app.registry.settings
115 vcs_server_enabled = settings['vcs.server.enable']
115 vcs_server_enabled = settings['vcs.server.enable']
116 import_on_startup = settings['startup.import_repos']
116 import_on_startup = settings['startup.import_repos']
117 if vcs_server_enabled and import_on_startup:
117 if vcs_server_enabled and import_on_startup:
118 from rhodecode.model.scm import ScmModel
118 from rhodecode.model.scm import ScmModel
119 from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_base_path
119 from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_base_path
120 repositories = ScmModel().repo_scan(get_rhodecode_base_path())
120 repositories = ScmModel().repo_scan(get_rhodecode_base_path())
121 repo2db_mapper(repositories, remove_obsolete=False)
121 repo2db_mapper(repositories, remove_obsolete=False)
122
122
123
123
124 def write_metadata_if_needed(event):
124 def write_metadata_if_needed(event):
125 """
125 """
126 Writes upgrade metadata
126 Writes upgrade metadata
127 """
127 """
128 import rhodecode
128 import rhodecode
129 from rhodecode.lib import system_info
129 from rhodecode.lib import system_info
130 from rhodecode.lib import ext_json
130 from rhodecode.lib import ext_json
131
131
132 fname = '.rcmetadata.json'
132 fname = '.rcmetadata.json'
133 ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__'))
133 ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__'))
134 metadata_destination = os.path.join(ini_loc, fname)
134 metadata_destination = os.path.join(ini_loc, fname)
135
135
136 def get_update_age():
136 def get_update_age():
137 now = datetime.datetime.utcnow()
137 now = datetime.datetime.utcnow()
138
138
139 with open(metadata_destination, 'rb') as f:
139 with open(metadata_destination, 'rb') as f:
140 data = ext_json.json.loads(f.read())
140 data = ext_json.json.loads(f.read())
141 if 'created_on' in data:
141 if 'created_on' in data:
142 update_date = parse(data['created_on'])
142 update_date = parse(data['created_on'])
143 diff = now - update_date
143 diff = now - update_date
144 return diff.total_seconds() / 60.0
144 return diff.total_seconds() / 60.0
145
145
146 return 0
146 return 0
147
147
148 def write():
148 def write():
149 configuration = system_info.SysInfo(
149 configuration = system_info.SysInfo(
150 system_info.rhodecode_config)()['value']
150 system_info.rhodecode_config)()['value']
151 license_token = configuration['config']['license_token']
151 license_token = configuration['config']['license_token']
152
152
153 setup = dict(
153 setup = dict(
154 workers=configuration['config']['server:main'].get(
154 workers=configuration['config']['server:main'].get(
155 'workers', '?'),
155 'workers', '?'),
156 worker_type=configuration['config']['server:main'].get(
156 worker_type=configuration['config']['server:main'].get(
157 'worker_class', 'sync'),
157 'worker_class', 'sync'),
158 )
158 )
159 dbinfo = system_info.SysInfo(system_info.database_info)()['value']
159 dbinfo = system_info.SysInfo(system_info.database_info)()['value']
160 del dbinfo['url']
160 del dbinfo['url']
161
161
162 metadata = dict(
162 metadata = dict(
163 desc='upgrade metadata info',
163 desc='upgrade metadata info',
164 license_token=license_token,
164 license_token=license_token,
165 created_on=datetime.datetime.utcnow().isoformat(),
165 created_on=datetime.datetime.utcnow().isoformat(),
166 usage=system_info.SysInfo(system_info.usage_info)()['value'],
166 usage=system_info.SysInfo(system_info.usage_info)()['value'],
167 platform=system_info.SysInfo(system_info.platform_type)()['value'],
167 platform=system_info.SysInfo(system_info.platform_type)()['value'],
168 database=dbinfo,
168 database=dbinfo,
169 cpu=system_info.SysInfo(system_info.cpu)()['value'],
169 cpu=system_info.SysInfo(system_info.cpu)()['value'],
170 memory=system_info.SysInfo(system_info.memory)()['value'],
170 memory=system_info.SysInfo(system_info.memory)()['value'],
171 setup=setup
171 setup=setup
172 )
172 )
173
173
174 with open(metadata_destination, 'wb') as f:
174 with open(metadata_destination, 'wb') as f:
175 f.write(ext_json.json.dumps(metadata))
175 f.write(ext_json.json.dumps(metadata))
176
176
177 settings = event.app.registry.settings
177 settings = event.app.registry.settings
178 if settings.get('metadata.skip'):
178 if settings.get('metadata.skip'):
179 return
179 return
180
180
181 # only write this every 24h, workers restart caused unwanted delays
181 # only write this every 24h, workers restart caused unwanted delays
182 try:
182 try:
183 age_in_min = get_update_age()
183 age_in_min = get_update_age()
184 except Exception:
184 except Exception:
185 age_in_min = 0
185 age_in_min = 0
186
186
187 if age_in_min > 60 * 60 * 24:
187 if age_in_min > 60 * 60 * 24:
188 return
188 return
189
189
190 try:
190 try:
191 write()
191 write()
192 except Exception:
192 except Exception:
193 pass
193 pass
194
194
195
195
196 def write_usage_data(event):
196 def write_usage_data(event):
197 import rhodecode
197 import rhodecode
198 from rhodecode.lib import system_info
198 from rhodecode.lib import system_info
199 from rhodecode.lib import ext_json
199 from rhodecode.lib import ext_json
200
200
201 settings = event.app.registry.settings
201 settings = event.app.registry.settings
202 instance_tag = settings.get('metadata.write_usage_tag')
202 instance_tag = settings.get('metadata.write_usage_tag')
203 if not settings.get('metadata.write_usage'):
203 if not settings.get('metadata.write_usage'):
204 return
204 return
205
205
206 def get_update_age(dest_file):
206 def get_update_age(dest_file):
207 now = datetime.datetime.utcnow()
207 now = datetime.datetime.utcnow()
208
208
209 with open(dest_file, 'rb') as f:
209 with open(dest_file, 'rb') as f:
210 data = ext_json.json.loads(f.read())
210 data = ext_json.json.loads(f.read())
211 if 'created_on' in data:
211 if 'created_on' in data:
212 update_date = parse(data['created_on'])
212 update_date = parse(data['created_on'])
213 diff = now - update_date
213 diff = now - update_date
214 return math.ceil(diff.total_seconds() / 60.0)
214 return math.ceil(diff.total_seconds() / 60.0)
215
215
216 return 0
216 return 0
217
217
218 utc_date = datetime.datetime.utcnow()
218 utc_date = datetime.datetime.utcnow()
219 hour_quarter = int(math.ceil((utc_date.hour + utc_date.minute/60.0) / 6.))
219 hour_quarter = int(math.ceil((utc_date.hour + utc_date.minute/60.0) / 6.))
220 fname = '.rc_usage_{date.year}{date.month:02d}{date.day:02d}_{hour}.json'.format(
220 fname = '.rc_usage_{date.year}{date.month:02d}{date.day:02d}_{hour}.json'.format(
221 date=utc_date, hour=hour_quarter)
221 date=utc_date, hour=hour_quarter)
222 ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__'))
222 ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__'))
223
223
224 usage_dir = os.path.join(ini_loc, '.rcusage')
224 usage_dir = os.path.join(ini_loc, '.rcusage')
225 if not os.path.isdir(usage_dir):
225 if not os.path.isdir(usage_dir):
226 os.makedirs(usage_dir)
226 os.makedirs(usage_dir)
227 usage_metadata_destination = os.path.join(usage_dir, fname)
227 usage_metadata_destination = os.path.join(usage_dir, fname)
228
228
229 try:
229 try:
230 age_in_min = get_update_age(usage_metadata_destination)
230 age_in_min = get_update_age(usage_metadata_destination)
231 except Exception:
231 except Exception:
232 age_in_min = 0
232 age_in_min = 0
233
233
234 # write every 6th hour
234 # write every 6th hour
235 if age_in_min and age_in_min < 60 * 6:
235 if age_in_min and age_in_min < 60 * 6:
236 log.debug('Usage file created %s minutes ago, skipping (threshold: %s minutes)...',
236 log.debug('Usage file created %s minutes ago, skipping (threshold: %s minutes)...',
237 age_in_min, 60 * 6)
237 age_in_min, 60 * 6)
238 return
238 return
239
239
240 def write(dest_file):
240 def write(dest_file):
241 configuration = system_info.SysInfo(system_info.rhodecode_config)()['value']
241 configuration = system_info.SysInfo(system_info.rhodecode_config)()['value']
242 license_token = configuration['config']['license_token']
242 license_token = configuration['config']['license_token']
243
243
244 metadata = dict(
244 metadata = dict(
245 desc='Usage data',
245 desc='Usage data',
246 instance_tag=instance_tag,
246 instance_tag=instance_tag,
247 license_token=license_token,
247 license_token=license_token,
248 created_on=datetime.datetime.utcnow().isoformat(),
248 created_on=datetime.datetime.utcnow().isoformat(),
249 usage=system_info.SysInfo(system_info.usage_info)()['value'],
249 usage=system_info.SysInfo(system_info.usage_info)()['value'],
250 )
250 )
251
251
252 with open(dest_file, 'wb') as f:
252 with open(dest_file, 'wb') as f:
253 f.write(ext_json.formatted_json(metadata))
253 f.write(ext_json.formatted_json(metadata))
254
254
255 try:
255 try:
256 log.debug('Writing usage file at: %s', usage_metadata_destination)
256 log.debug('Writing usage file at: %s', usage_metadata_destination)
257 write(usage_metadata_destination)
257 write(usage_metadata_destination)
258 except Exception:
258 except Exception:
259 pass
259 pass
260
260
261
261
262 def write_js_routes_if_enabled(event):
262 def write_js_routes_if_enabled(event):
263 registry = event.app.registry
263 registry = event.app.registry
264
264
265 mapper = registry.queryUtility(IRoutesMapper)
265 mapper = registry.queryUtility(IRoutesMapper)
266 _argument_prog = re.compile(r'\{(.*?)\}|:\((.*)\)')
266 _argument_prog = re.compile(r'\{(.*?)\}|:\((.*)\)')
267
267
268 def _extract_route_information(route):
268 def _extract_route_information(route):
269 """
269 """
270 Convert a route into tuple(name, path, args), eg:
270 Convert a route into tuple(name, path, args), eg:
271 ('show_user', '/profile/%(username)s', ['username'])
271 ('show_user', '/profile/%(username)s', ['username'])
272 """
272 """
273
273
274 routepath = route.pattern
274 route_path = route.pattern
275 pattern = route.pattern
275 pattern = route.pattern
276
276
277 def replace(matchobj):
277 def replace(matchobj):
278 if matchobj.group(1):
278 if matchobj.group(1):
279 return "%%(%s)s" % matchobj.group(1).split(':')[0]
279 return "%%(%s)s" % matchobj.group(1).split(':')[0]
280 else:
280 else:
281 return "%%(%s)s" % matchobj.group(2)
281 return "%%(%s)s" % matchobj.group(2)
282
282
283 routepath = _argument_prog.sub(replace, routepath)
283 route_path = _argument_prog.sub(replace, route_path)
284
284
285 if not routepath.startswith('/'):
285 if not route_path.startswith('/'):
286 routepath = '/'+routepath
286 route_path = f'/{route_path}'
287
287
288 return (
288 return (
289 route.name,
289 route.name,
290 routepath,
290 route_path,
291 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
291 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
292 for arg in _argument_prog.findall(pattern)]
292 for arg in _argument_prog.findall(pattern)]
293 )
293 )
294
294
295 def get_routes():
295 def get_routes():
296 # pyramid routes
296 # pyramid routes
297 for route in mapper.get_routes():
297 for route in mapper.get_routes():
298 if not route.name.startswith('__'):
298 if not route.name.startswith('__'):
299 yield _extract_route_information(route)
299 yield _extract_route_information(route)
300
300
301 if asbool(registry.settings.get('generate_js_files', 'false')):
301 if asbool(registry.settings.get('generate_js_files', 'false')):
302 static_path = AssetResolver().resolve('rhodecode:public').abspath()
302 static_path = AssetResolver().resolve('rhodecode:public').abspath()
303 jsroutes = get_routes()
303 jsroutes = get_routes()
304 jsroutes_file_content = generate_jsroutes_content(jsroutes)
304 jsroutes_file_content = generate_jsroutes_content(jsroutes)
305 jsroutes_file_path = os.path.join(
305 jsroutes_file_path = os.path.join(
306 static_path, 'js', 'rhodecode', 'routes.js')
306 static_path, 'js', 'rhodecode', 'routes.js')
307
307
308 try:
308 try:
309 with open(jsroutes_file_path, 'w', encoding='utf-8') as f:
309 with open(jsroutes_file_path, 'w', encoding='utf-8') as f:
310 f.write(jsroutes_file_content)
310 f.write(jsroutes_file_content)
311 log.debug('generated JS files in %s', jsroutes_file_path)
311 except Exception:
312 except Exception:
312 log.exception('Failed to write routes.js into %s', jsroutes_file_path)
313 log.exception('Failed to write routes.js into %s', jsroutes_file_path)
313
314
314
315
315 class Subscriber(object):
316 class Subscriber(object):
316 """
317 """
317 Base class for subscribers to the pyramid event system.
318 Base class for subscribers to the pyramid event system.
318 """
319 """
319 def __call__(self, event):
320 def __call__(self, event):
320 self.run(event)
321 self.run(event)
321
322
322 def run(self, event):
323 def run(self, event):
323 raise NotImplementedError('Subclass has to implement this.')
324 raise NotImplementedError('Subclass has to implement this.')
324
325
325
326
326 class AsyncSubscriber(Subscriber):
327 class AsyncSubscriber(Subscriber):
327 """
328 """
328 Subscriber that handles the execution of events in a separate task to not
329 Subscriber that handles the execution of events in a separate task to not
329 block the execution of the code which triggers the event. It puts the
330 block the execution of the code which triggers the event. It puts the
330 received events into a queue from which the worker process takes them in
331 received events into a queue from which the worker process takes them in
331 order.
332 order.
332 """
333 """
333 def __init__(self):
334 def __init__(self):
334 self._stop = False
335 self._stop = False
335 self._eventq = queue.Queue()
336 self._eventq = queue.Queue()
336 self._worker = self.create_worker()
337 self._worker = self.create_worker()
337 self._worker.start()
338 self._worker.start()
338
339
339 def __call__(self, event):
340 def __call__(self, event):
340 self._eventq.put(event)
341 self._eventq.put(event)
341
342
342 def create_worker(self):
343 def create_worker(self):
343 worker = Thread(target=self.do_work)
344 worker = Thread(target=self.do_work)
344 worker.daemon = True
345 worker.daemon = True
345 return worker
346 return worker
346
347
347 def stop_worker(self):
348 def stop_worker(self):
348 self._stop = False
349 self._stop = False
349 self._eventq.put(None)
350 self._eventq.put(None)
350 self._worker.join()
351 self._worker.join()
351
352
352 def do_work(self):
353 def do_work(self):
353 while not self._stop:
354 while not self._stop:
354 event = self._eventq.get()
355 event = self._eventq.get()
355 if event is not None:
356 if event is not None:
356 self.run(event)
357 self.run(event)
357
358
358
359
359 class AsyncSubprocessSubscriber(AsyncSubscriber):
360 class AsyncSubprocessSubscriber(AsyncSubscriber):
360 """
361 """
361 Subscriber that uses the subprocess module to execute a command if an
362 Subscriber that uses the subprocess module to execute a command if an
362 event is received. Events are handled asynchronously::
363 event is received. Events are handled asynchronously::
363
364
364 subscriber = AsyncSubprocessSubscriber('ls -la', timeout=10)
365 subscriber = AsyncSubprocessSubscriber('ls -la', timeout=10)
365 subscriber(dummyEvent) # running __call__(event)
366 subscriber(dummyEvent) # running __call__(event)
366
367
367 """
368 """
368
369
369 def __init__(self, cmd, timeout=None):
370 def __init__(self, cmd, timeout=None):
370 if not isinstance(cmd, (list, tuple)):
371 if not isinstance(cmd, (list, tuple)):
371 cmd = shlex.split(cmd)
372 cmd = shlex.split(cmd)
372 super().__init__()
373 super().__init__()
373 self._cmd = cmd
374 self._cmd = cmd
374 self._timeout = timeout
375 self._timeout = timeout
375
376
376 def run(self, event):
377 def run(self, event):
377 cmd = self._cmd
378 cmd = self._cmd
378 timeout = self._timeout
379 timeout = self._timeout
379 log.debug('Executing command %s.', cmd)
380 log.debug('Executing command %s.', cmd)
380
381
381 try:
382 try:
382 output = subprocess.check_output(
383 output = subprocess.check_output(
383 cmd, timeout=timeout, stderr=subprocess.STDOUT)
384 cmd, timeout=timeout, stderr=subprocess.STDOUT)
384 log.debug('Command finished %s', cmd)
385 log.debug('Command finished %s', cmd)
385 if output:
386 if output:
386 log.debug('Command output: %s', output)
387 log.debug('Command output: %s', output)
387 except subprocess.TimeoutExpired as e:
388 except subprocess.TimeoutExpired as e:
388 log.exception('Timeout while executing command.')
389 log.exception('Timeout while executing command.')
389 if e.output:
390 if e.output:
390 log.error('Command output: %s', e.output)
391 log.error('Command output: %s', e.output)
391 except subprocess.CalledProcessError as e:
392 except subprocess.CalledProcessError as e:
392 log.exception('Error while executing command.')
393 log.exception('Error while executing command.')
393 if e.output:
394 if e.output:
394 log.error('Command output: %s', e.output)
395 log.error('Command output: %s', e.output)
395 except Exception:
396 except Exception:
396 log.exception(
397 log.exception(
397 'Exception while executing command %s.', cmd)
398 'Exception while executing command %s.', cmd)
General Comments 0
You need to be logged in to leave comments. Login now