##// END OF EJS Templates
home: removed old pylons routes and convert them to pyramid ops app
marcink -
r2099:d2ff8722 default
parent child Browse files
Show More
@@ -1,41 +1,46 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 from rhodecode.config.routing import ADMIN_PREFIX
22 22
23 23
24 24 def admin_routes(config):
25 25 config.add_route(
26 26 name='ops_ping',
27 27 pattern='/ping')
28 28 config.add_route(
29 29 name='ops_error_test',
30 30 pattern='/error')
31 31 config.add_route(
32 32 name='ops_redirect_test',
33 33 pattern='/redirect')
34 34
35 35
36 36 def includeme(config):
37 37
38 38 config.include(admin_routes, route_prefix=ADMIN_PREFIX + '/ops')
39 # make OLD entries from pylons work
40 config.add_route(
41 name='ops_ping_legacy', pattern=ADMIN_PREFIX + '/ping')
42 config.add_route(
43 name='ops_error_test_legacy', pattern=ADMIN_PREFIX + '/error_test')
39 44
40 45 # Scan module for configuration decorators.
41 46 config.scan('.views', ignore='.tests')
@@ -1,77 +1,83 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import time
22 22 import logging
23 23
24 24 from pyramid.view import view_config
25 25 from pyramid.httpexceptions import HTTPFound
26 26
27 27 from rhodecode.apps._base import BaseAppView
28 28 from rhodecode.lib import helpers as h
29 29
30 30 log = logging.getLogger(__name__)
31 31
32 32
33 33 class OpsView(BaseAppView):
34 34
35 35 def load_default_context(self):
36 36 c = self._get_local_tmpl_context()
37 37 c.user = c.auth_user.get_instance()
38 38 self._register_global_c(c)
39 39 return c
40 40
41 41 @view_config(
42 42 route_name='ops_ping', request_method='GET',
43 43 renderer='json_ext')
44 @view_config(
45 route_name='ops_ping_legacy', request_method='GET',
46 renderer='json_ext')
44 47 def ops_ping(self):
45 48 data = {
46 49 'instance': self.request.registry.settings.get('instance_id'),
47 50 }
48 51 if getattr(self.request, 'user'):
49 52 data.update({
50 53 'caller_ip': self.request.user.ip_addr,
51 54 'caller_name': self.request.user.username,
52 55 })
53 56 return {'ok': data}
54 57
55 58 @view_config(
56 59 route_name='ops_error_test', request_method='GET',
57 60 renderer='json_ext')
61 @view_config(
62 route_name='ops_error_test_legacy', request_method='GET',
63 renderer='json_ext')
58 64 def ops_error_test(self):
59 65 """
60 66 Test exception handling and emails on errors
61 67 """
62 68 class TestException(Exception):
63 69 pass
64 70
65 71 msg = ('RhodeCode Enterprise test exception. '
66 72 'Generation time: {}'.format(time.time()))
67 73 raise TestException(msg)
68 74
69 75 @view_config(
70 76 route_name='ops_redirect_test', request_method='GET',
71 77 renderer='json_ext')
72 78 def ops_redirect_test(self):
73 79 """
74 80 Test redirect handling
75 81 """
76 82 redirect_to = self.request.GET.get('to') or h.route_path('home')
77 83 raise HTTPFound(redirect_to)
@@ -1,347 +1,343 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 """
22 22 Routes configuration
23 23
24 24 The more specific and detailed routes should be defined first so they
25 25 may take precedent over the more generic routes. For more information
26 26 refer to the routes manual at http://routes.groovie.org/docs/
27 27
28 28 IMPORTANT: if you change any routing here, make sure to take a look at lib/base.py
29 29 and _route_name variable which uses some of stored naming here to do redirects.
30 30 """
31 31 import os
32 32 import re
33 33 from routes import Mapper
34 34
35 35 # prefix for non repository related links needs to be prefixed with `/`
36 36 ADMIN_PREFIX = '/_admin'
37 37 STATIC_FILE_PREFIX = '/_static'
38 38
39 39 # Default requirements for URL parts
40 40 URL_NAME_REQUIREMENTS = {
41 41 # group name can have a slash in them, but they must not end with a slash
42 42 'group_name': r'.*?[^/]',
43 43 'repo_group_name': r'.*?[^/]',
44 44 # repo names can have a slash in them, but they must not end with a slash
45 45 'repo_name': r'.*?[^/]',
46 46 # file path eats up everything at the end
47 47 'f_path': r'.*',
48 48 # reference types
49 49 'source_ref_type': '(branch|book|tag|rev|\%\(source_ref_type\)s)',
50 50 'target_ref_type': '(branch|book|tag|rev|\%\(target_ref_type\)s)',
51 51 }
52 52
53 53
54 54 class JSRoutesMapper(Mapper):
55 55 """
56 56 Wrapper for routes.Mapper to make pyroutes compatible url definitions
57 57 """
58 58 _named_route_regex = re.compile(r'^[a-z-_0-9A-Z]+$')
59 59 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
60 60 def __init__(self, *args, **kw):
61 61 super(JSRoutesMapper, self).__init__(*args, **kw)
62 62 self._jsroutes = []
63 63
64 64 def connect(self, *args, **kw):
65 65 """
66 66 Wrapper for connect to take an extra argument jsroute=True
67 67
68 68 :param jsroute: boolean, if True will add the route to the pyroutes list
69 69 """
70 70 if kw.pop('jsroute', False):
71 71 if not self._named_route_regex.match(args[0]):
72 72 raise Exception('only named routes can be added to pyroutes')
73 73 self._jsroutes.append(args[0])
74 74
75 75 super(JSRoutesMapper, self).connect(*args, **kw)
76 76
77 77 def _extract_route_information(self, route):
78 78 """
79 79 Convert a route into tuple(name, path, args), eg:
80 80 ('show_user', '/profile/%(username)s', ['username'])
81 81 """
82 82 routepath = route.routepath
83 83 def replace(matchobj):
84 84 if matchobj.group(1):
85 85 return "%%(%s)s" % matchobj.group(1).split(':')[0]
86 86 else:
87 87 return "%%(%s)s" % matchobj.group(2)
88 88
89 89 routepath = self._argument_prog.sub(replace, routepath)
90 90 return (
91 91 route.name,
92 92 routepath,
93 93 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
94 94 for arg in self._argument_prog.findall(route.routepath)]
95 95 )
96 96
97 97 def jsroutes(self):
98 98 """
99 99 Return a list of pyroutes.js compatible routes
100 100 """
101 101 for route_name in self._jsroutes:
102 102 yield self._extract_route_information(self._routenames[route_name])
103 103
104 104
105 105 def make_map(config):
106 106 """Create, configure and return the routes Mapper"""
107 107 rmap = JSRoutesMapper(
108 108 directory=config['pylons.paths']['controllers'],
109 109 always_scan=config['debug'])
110 110 rmap.minimization = False
111 111 rmap.explicit = False
112 112
113 113 from rhodecode.lib.utils2 import str2bool
114 114 from rhodecode.model import repo, repo_group
115 115
116 116 def check_repo(environ, match_dict):
117 117 """
118 118 check for valid repository for proper 404 handling
119 119
120 120 :param environ:
121 121 :param match_dict:
122 122 """
123 123 repo_name = match_dict.get('repo_name')
124 124
125 125 if match_dict.get('f_path'):
126 126 # fix for multiple initial slashes that causes errors
127 127 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
128 128 repo_model = repo.RepoModel()
129 129 by_name_match = repo_model.get_by_repo_name(repo_name)
130 130 # if we match quickly from database, short circuit the operation,
131 131 # and validate repo based on the type.
132 132 if by_name_match:
133 133 return True
134 134
135 135 by_id_match = repo_model.get_repo_by_id(repo_name)
136 136 if by_id_match:
137 137 repo_name = by_id_match.repo_name
138 138 match_dict['repo_name'] = repo_name
139 139 return True
140 140
141 141 return False
142 142
143 143 def check_group(environ, match_dict):
144 144 """
145 145 check for valid repository group path for proper 404 handling
146 146
147 147 :param environ:
148 148 :param match_dict:
149 149 """
150 150 repo_group_name = match_dict.get('group_name')
151 151 repo_group_model = repo_group.RepoGroupModel()
152 152 by_name_match = repo_group_model.get_by_group_name(repo_group_name)
153 153 if by_name_match:
154 154 return True
155 155
156 156 return False
157 157
158 158 def check_user_group(environ, match_dict):
159 159 """
160 160 check for valid user group for proper 404 handling
161 161
162 162 :param environ:
163 163 :param match_dict:
164 164 """
165 165 return True
166 166
167 167 def check_int(environ, match_dict):
168 168 return match_dict.get('id').isdigit()
169 169
170 170
171 171 #==========================================================================
172 172 # CUSTOM ROUTES HERE
173 173 #==========================================================================
174 174
175 # ping and pylons error test
176 rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping')
177 rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test')
178
179 175 # ADMIN REPOSITORY GROUPS ROUTES
180 176 with rmap.submapper(path_prefix=ADMIN_PREFIX,
181 177 controller='admin/repo_groups') as m:
182 178 m.connect('repo_groups', '/repo_groups',
183 179 action='create', conditions={'method': ['POST']})
184 180 m.connect('repo_groups', '/repo_groups',
185 181 action='index', conditions={'method': ['GET']})
186 182 m.connect('new_repo_group', '/repo_groups/new',
187 183 action='new', conditions={'method': ['GET']})
188 184 m.connect('update_repo_group', '/repo_groups/{group_name}',
189 185 action='update', conditions={'method': ['PUT'],
190 186 'function': check_group},
191 187 requirements=URL_NAME_REQUIREMENTS)
192 188
193 189 # EXTRAS REPO GROUP ROUTES
194 190 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
195 191 action='edit',
196 192 conditions={'method': ['GET'], 'function': check_group},
197 193 requirements=URL_NAME_REQUIREMENTS)
198 194 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
199 195 action='edit',
200 196 conditions={'method': ['PUT'], 'function': check_group},
201 197 requirements=URL_NAME_REQUIREMENTS)
202 198
203 199 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
204 200 action='edit_repo_group_advanced',
205 201 conditions={'method': ['GET'], 'function': check_group},
206 202 requirements=URL_NAME_REQUIREMENTS)
207 203 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
208 204 action='edit_repo_group_advanced',
209 205 conditions={'method': ['PUT'], 'function': check_group},
210 206 requirements=URL_NAME_REQUIREMENTS)
211 207
212 208 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
213 209 action='edit_repo_group_perms',
214 210 conditions={'method': ['GET'], 'function': check_group},
215 211 requirements=URL_NAME_REQUIREMENTS)
216 212 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
217 213 action='update_perms',
218 214 conditions={'method': ['PUT'], 'function': check_group},
219 215 requirements=URL_NAME_REQUIREMENTS)
220 216
221 217 m.connect('delete_repo_group', '/repo_groups/{group_name}',
222 218 action='delete', conditions={'method': ['DELETE'],
223 219 'function': check_group},
224 220 requirements=URL_NAME_REQUIREMENTS)
225 221
226 222 # ADMIN USER ROUTES
227 223 with rmap.submapper(path_prefix=ADMIN_PREFIX,
228 224 controller='admin/users') as m:
229 225 m.connect('users', '/users',
230 226 action='create', conditions={'method': ['POST']})
231 227 m.connect('new_user', '/users/new',
232 228 action='new', conditions={'method': ['GET']})
233 229 m.connect('update_user', '/users/{user_id}',
234 230 action='update', conditions={'method': ['PUT']})
235 231 m.connect('delete_user', '/users/{user_id}',
236 232 action='delete', conditions={'method': ['DELETE']})
237 233 m.connect('edit_user', '/users/{user_id}/edit',
238 234 action='edit', conditions={'method': ['GET']}, jsroute=True)
239 235 m.connect('user', '/users/{user_id}',
240 236 action='show', conditions={'method': ['GET']})
241 237 m.connect('force_password_reset_user', '/users/{user_id}/password_reset',
242 238 action='reset_password', conditions={'method': ['POST']})
243 239 m.connect('create_personal_repo_group', '/users/{user_id}/create_repo_group',
244 240 action='create_personal_repo_group', conditions={'method': ['POST']})
245 241
246 242 # EXTRAS USER ROUTES
247 243 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
248 244 action='edit_advanced', conditions={'method': ['GET']})
249 245 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
250 246 action='update_advanced', conditions={'method': ['PUT']})
251 247
252 248 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
253 249 action='edit_global_perms', conditions={'method': ['GET']})
254 250 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
255 251 action='update_global_perms', conditions={'method': ['PUT']})
256 252
257 253 # ADMIN SETTINGS ROUTES
258 254 with rmap.submapper(path_prefix=ADMIN_PREFIX,
259 255 controller='admin/settings') as m:
260 256
261 257 # default
262 258 m.connect('admin_settings', '/settings',
263 259 action='settings_global_update',
264 260 conditions={'method': ['POST']})
265 261 m.connect('admin_settings', '/settings',
266 262 action='settings_global', conditions={'method': ['GET']})
267 263
268 264 m.connect('admin_settings_vcs', '/settings/vcs',
269 265 action='settings_vcs_update',
270 266 conditions={'method': ['POST']})
271 267 m.connect('admin_settings_vcs', '/settings/vcs',
272 268 action='settings_vcs',
273 269 conditions={'method': ['GET']})
274 270 m.connect('admin_settings_vcs', '/settings/vcs',
275 271 action='delete_svn_pattern',
276 272 conditions={'method': ['DELETE']})
277 273
278 274 m.connect('admin_settings_mapping', '/settings/mapping',
279 275 action='settings_mapping_update',
280 276 conditions={'method': ['POST']})
281 277 m.connect('admin_settings_mapping', '/settings/mapping',
282 278 action='settings_mapping', conditions={'method': ['GET']})
283 279
284 280 m.connect('admin_settings_global', '/settings/global',
285 281 action='settings_global_update',
286 282 conditions={'method': ['POST']})
287 283 m.connect('admin_settings_global', '/settings/global',
288 284 action='settings_global', conditions={'method': ['GET']})
289 285
290 286 m.connect('admin_settings_visual', '/settings/visual',
291 287 action='settings_visual_update',
292 288 conditions={'method': ['POST']})
293 289 m.connect('admin_settings_visual', '/settings/visual',
294 290 action='settings_visual', conditions={'method': ['GET']})
295 291
296 292 m.connect('admin_settings_issuetracker',
297 293 '/settings/issue-tracker', action='settings_issuetracker',
298 294 conditions={'method': ['GET']})
299 295 m.connect('admin_settings_issuetracker_save',
300 296 '/settings/issue-tracker/save',
301 297 action='settings_issuetracker_save',
302 298 conditions={'method': ['POST']})
303 299 m.connect('admin_issuetracker_test', '/settings/issue-tracker/test',
304 300 action='settings_issuetracker_test',
305 301 conditions={'method': ['POST']})
306 302 m.connect('admin_issuetracker_delete',
307 303 '/settings/issue-tracker/delete',
308 304 action='settings_issuetracker_delete',
309 305 conditions={'method': ['DELETE']})
310 306
311 307 m.connect('admin_settings_email', '/settings/email',
312 308 action='settings_email_update',
313 309 conditions={'method': ['POST']})
314 310 m.connect('admin_settings_email', '/settings/email',
315 311 action='settings_email', conditions={'method': ['GET']})
316 312
317 313 m.connect('admin_settings_hooks', '/settings/hooks',
318 314 action='settings_hooks_update',
319 315 conditions={'method': ['POST', 'DELETE']})
320 316 m.connect('admin_settings_hooks', '/settings/hooks',
321 317 action='settings_hooks', conditions={'method': ['GET']})
322 318
323 319 m.connect('admin_settings_search', '/settings/search',
324 320 action='settings_search', conditions={'method': ['GET']})
325 321
326 322 m.connect('admin_settings_supervisor', '/settings/supervisor',
327 323 action='settings_supervisor', conditions={'method': ['GET']})
328 324 m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log',
329 325 action='settings_supervisor_log', conditions={'method': ['GET']})
330 326
331 327 m.connect('admin_settings_labs', '/settings/labs',
332 328 action='settings_labs_update',
333 329 conditions={'method': ['POST']})
334 330 m.connect('admin_settings_labs', '/settings/labs',
335 331 action='settings_labs', conditions={'method': ['GET']})
336 332
337 333 # ADMIN MY ACCOUNT
338 334 with rmap.submapper(path_prefix=ADMIN_PREFIX,
339 335 controller='admin/my_account') as m:
340 336
341 337 # NOTE(marcink): this needs to be kept for password force flag to be
342 338 # handled in pylons controllers, remove after full migration to pyramid
343 339 m.connect('my_account_password', '/my_account/password',
344 340 action='my_account_password', conditions={'method': ['GET']})
345 341
346 342
347 343 return rmap
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now