##// END OF EJS Templates
oss-licenses: Remove pylons view.
Martin Bornhold -
r203:f501ebf3 default
parent child Browse files
Show More
@@ -1,1145 +1,1141 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Routes configuration
22 Routes configuration
23
23
24 The more specific and detailed routes should be defined first so they
24 The more specific and detailed routes should be defined first so they
25 may take precedent over the more generic routes. For more information
25 may take precedent over the more generic routes. For more information
26 refer to the routes manual at http://routes.groovie.org/docs/
26 refer to the routes manual at http://routes.groovie.org/docs/
27
27
28 IMPORTANT: if you change any routing here, make sure to take a look at lib/base.py
28 IMPORTANT: if you change any routing here, make sure to take a look at lib/base.py
29 and _route_name variable which uses some of stored naming here to do redirects.
29 and _route_name variable which uses some of stored naming here to do redirects.
30 """
30 """
31 import os
31 import os
32 import re
32 import re
33 from routes import Mapper
33 from routes import Mapper
34
34
35 from rhodecode.config import routing_links
35 from rhodecode.config import routing_links
36
36
37 # prefix for non repository related links needs to be prefixed with `/`
37 # prefix for non repository related links needs to be prefixed with `/`
38 ADMIN_PREFIX = '/_admin'
38 ADMIN_PREFIX = '/_admin'
39
39
40 # Default requirements for URL parts
40 # Default requirements for URL parts
41 URL_NAME_REQUIREMENTS = {
41 URL_NAME_REQUIREMENTS = {
42 # group name can have a slash in them, but they must not end with a slash
42 # group name can have a slash in them, but they must not end with a slash
43 'group_name': r'.*?[^/]',
43 'group_name': r'.*?[^/]',
44 # repo names can have a slash in them, but they must not end with a slash
44 # repo names can have a slash in them, but they must not end with a slash
45 'repo_name': r'.*?[^/]',
45 'repo_name': r'.*?[^/]',
46 # file path eats up everything at the end
46 # file path eats up everything at the end
47 'f_path': r'.*',
47 'f_path': r'.*',
48 # reference types
48 # reference types
49 'source_ref_type': '(branch|book|tag|rev|\%\(source_ref_type\)s)',
49 'source_ref_type': '(branch|book|tag|rev|\%\(source_ref_type\)s)',
50 'target_ref_type': '(branch|book|tag|rev|\%\(target_ref_type\)s)',
50 'target_ref_type': '(branch|book|tag|rev|\%\(target_ref_type\)s)',
51 }
51 }
52
52
53
53
54 class JSRoutesMapper(Mapper):
54 class JSRoutesMapper(Mapper):
55 """
55 """
56 Wrapper for routes.Mapper to make pyroutes compatible url definitions
56 Wrapper for routes.Mapper to make pyroutes compatible url definitions
57 """
57 """
58 _named_route_regex = re.compile(r'^[a-z-_0-9A-Z]+$')
58 _named_route_regex = re.compile(r'^[a-z-_0-9A-Z]+$')
59 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
59 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
60 def __init__(self, *args, **kw):
60 def __init__(self, *args, **kw):
61 super(JSRoutesMapper, self).__init__(*args, **kw)
61 super(JSRoutesMapper, self).__init__(*args, **kw)
62 self._jsroutes = []
62 self._jsroutes = []
63
63
64 def connect(self, *args, **kw):
64 def connect(self, *args, **kw):
65 """
65 """
66 Wrapper for connect to take an extra argument jsroute=True
66 Wrapper for connect to take an extra argument jsroute=True
67
67
68 :param jsroute: boolean, if True will add the route to the pyroutes list
68 :param jsroute: boolean, if True will add the route to the pyroutes list
69 """
69 """
70 if kw.pop('jsroute', False):
70 if kw.pop('jsroute', False):
71 if not self._named_route_regex.match(args[0]):
71 if not self._named_route_regex.match(args[0]):
72 raise Exception('only named routes can be added to pyroutes')
72 raise Exception('only named routes can be added to pyroutes')
73 self._jsroutes.append(args[0])
73 self._jsroutes.append(args[0])
74
74
75 super(JSRoutesMapper, self).connect(*args, **kw)
75 super(JSRoutesMapper, self).connect(*args, **kw)
76
76
77 def _extract_route_information(self, route):
77 def _extract_route_information(self, route):
78 """
78 """
79 Convert a route into tuple(name, path, args), eg:
79 Convert a route into tuple(name, path, args), eg:
80 ('user_profile', '/profile/%(username)s', ['username'])
80 ('user_profile', '/profile/%(username)s', ['username'])
81 """
81 """
82 routepath = route.routepath
82 routepath = route.routepath
83 def replace(matchobj):
83 def replace(matchobj):
84 if matchobj.group(1):
84 if matchobj.group(1):
85 return "%%(%s)s" % matchobj.group(1).split(':')[0]
85 return "%%(%s)s" % matchobj.group(1).split(':')[0]
86 else:
86 else:
87 return "%%(%s)s" % matchobj.group(2)
87 return "%%(%s)s" % matchobj.group(2)
88
88
89 routepath = self._argument_prog.sub(replace, routepath)
89 routepath = self._argument_prog.sub(replace, routepath)
90 return (
90 return (
91 route.name,
91 route.name,
92 routepath,
92 routepath,
93 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
93 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
94 for arg in self._argument_prog.findall(route.routepath)]
94 for arg in self._argument_prog.findall(route.routepath)]
95 )
95 )
96
96
97 def jsroutes(self):
97 def jsroutes(self):
98 """
98 """
99 Return a list of pyroutes.js compatible routes
99 Return a list of pyroutes.js compatible routes
100 """
100 """
101 for route_name in self._jsroutes:
101 for route_name in self._jsroutes:
102 yield self._extract_route_information(self._routenames[route_name])
102 yield self._extract_route_information(self._routenames[route_name])
103
103
104
104
105 def make_map(config):
105 def make_map(config):
106 """Create, configure and return the routes Mapper"""
106 """Create, configure and return the routes Mapper"""
107 rmap = JSRoutesMapper(directory=config['pylons.paths']['controllers'],
107 rmap = JSRoutesMapper(directory=config['pylons.paths']['controllers'],
108 always_scan=config['debug'])
108 always_scan=config['debug'])
109 rmap.minimization = False
109 rmap.minimization = False
110 rmap.explicit = False
110 rmap.explicit = False
111
111
112 from rhodecode.lib.utils2 import str2bool
112 from rhodecode.lib.utils2 import str2bool
113 from rhodecode.model import repo, repo_group
113 from rhodecode.model import repo, repo_group
114
114
115 def check_repo(environ, match_dict):
115 def check_repo(environ, match_dict):
116 """
116 """
117 check for valid repository for proper 404 handling
117 check for valid repository for proper 404 handling
118
118
119 :param environ:
119 :param environ:
120 :param match_dict:
120 :param match_dict:
121 """
121 """
122 repo_name = match_dict.get('repo_name')
122 repo_name = match_dict.get('repo_name')
123
123
124 if match_dict.get('f_path'):
124 if match_dict.get('f_path'):
125 # fix for multiple initial slashes that causes errors
125 # fix for multiple initial slashes that causes errors
126 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
126 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
127 repo_model = repo.RepoModel()
127 repo_model = repo.RepoModel()
128 by_name_match = repo_model.get_by_repo_name(repo_name)
128 by_name_match = repo_model.get_by_repo_name(repo_name)
129 # if we match quickly from database, short circuit the operation,
129 # if we match quickly from database, short circuit the operation,
130 # and validate repo based on the type.
130 # and validate repo based on the type.
131 if by_name_match:
131 if by_name_match:
132 return True
132 return True
133
133
134 by_id_match = repo_model.get_repo_by_id(repo_name)
134 by_id_match = repo_model.get_repo_by_id(repo_name)
135 if by_id_match:
135 if by_id_match:
136 repo_name = by_id_match.repo_name
136 repo_name = by_id_match.repo_name
137 match_dict['repo_name'] = repo_name
137 match_dict['repo_name'] = repo_name
138 return True
138 return True
139
139
140 return False
140 return False
141
141
142 def check_group(environ, match_dict):
142 def check_group(environ, match_dict):
143 """
143 """
144 check for valid repository group path for proper 404 handling
144 check for valid repository group path for proper 404 handling
145
145
146 :param environ:
146 :param environ:
147 :param match_dict:
147 :param match_dict:
148 """
148 """
149 repo_group_name = match_dict.get('group_name')
149 repo_group_name = match_dict.get('group_name')
150 repo_group_model = repo_group.RepoGroupModel()
150 repo_group_model = repo_group.RepoGroupModel()
151 by_name_match = repo_group_model.get_by_group_name(repo_group_name)
151 by_name_match = repo_group_model.get_by_group_name(repo_group_name)
152 if by_name_match:
152 if by_name_match:
153 return True
153 return True
154
154
155 return False
155 return False
156
156
157 def check_user_group(environ, match_dict):
157 def check_user_group(environ, match_dict):
158 """
158 """
159 check for valid user group for proper 404 handling
159 check for valid user group for proper 404 handling
160
160
161 :param environ:
161 :param environ:
162 :param match_dict:
162 :param match_dict:
163 """
163 """
164 return True
164 return True
165
165
166 def check_int(environ, match_dict):
166 def check_int(environ, match_dict):
167 return match_dict.get('id').isdigit()
167 return match_dict.get('id').isdigit()
168
168
169
169
170 #==========================================================================
170 #==========================================================================
171 # CUSTOM ROUTES HERE
171 # CUSTOM ROUTES HERE
172 #==========================================================================
172 #==========================================================================
173
173
174 # MAIN PAGE
174 # MAIN PAGE
175 rmap.connect('home', '/', controller='home', action='index', jsroute=True)
175 rmap.connect('home', '/', controller='home', action='index', jsroute=True)
176 rmap.connect('goto_switcher_data', '/_goto_data', controller='home',
176 rmap.connect('goto_switcher_data', '/_goto_data', controller='home',
177 action='goto_switcher_data')
177 action='goto_switcher_data')
178 rmap.connect('repo_list_data', '/_repos', controller='home',
178 rmap.connect('repo_list_data', '/_repos', controller='home',
179 action='repo_list_data')
179 action='repo_list_data')
180
180
181 rmap.connect('user_autocomplete_data', '/_users', controller='home',
181 rmap.connect('user_autocomplete_data', '/_users', controller='home',
182 action='user_autocomplete_data', jsroute=True)
182 action='user_autocomplete_data', jsroute=True)
183 rmap.connect('user_group_autocomplete_data', '/_user_groups', controller='home',
183 rmap.connect('user_group_autocomplete_data', '/_user_groups', controller='home',
184 action='user_group_autocomplete_data')
184 action='user_group_autocomplete_data')
185
185
186 rmap.connect(
186 rmap.connect(
187 'user_profile', '/_profiles/{username}', controller='users',
187 'user_profile', '/_profiles/{username}', controller='users',
188 action='user_profile')
188 action='user_profile')
189
189
190 # TODO: johbo: Static links, to be replaced by our redirection mechanism
190 # TODO: johbo: Static links, to be replaced by our redirection mechanism
191 rmap.connect('rst_help',
191 rmap.connect('rst_help',
192 'http://docutils.sourceforge.net/docs/user/rst/quickref.html',
192 'http://docutils.sourceforge.net/docs/user/rst/quickref.html',
193 _static=True)
193 _static=True)
194 rmap.connect('markdown_help',
194 rmap.connect('markdown_help',
195 'http://daringfireball.net/projects/markdown/syntax',
195 'http://daringfireball.net/projects/markdown/syntax',
196 _static=True)
196 _static=True)
197 rmap.connect('rhodecode_official', 'https://rhodecode.com', _static=True)
197 rmap.connect('rhodecode_official', 'https://rhodecode.com', _static=True)
198 rmap.connect('rhodecode_support', 'https://rhodecode.com/help/', _static=True)
198 rmap.connect('rhodecode_support', 'https://rhodecode.com/help/', _static=True)
199 rmap.connect('rhodecode_translations', 'https://rhodecode.com/translate/enterprise', _static=True)
199 rmap.connect('rhodecode_translations', 'https://rhodecode.com/translate/enterprise', _static=True)
200 # TODO: anderson - making this a static link since redirect won't play
200 # TODO: anderson - making this a static link since redirect won't play
201 # nice with POST requests
201 # nice with POST requests
202 rmap.connect('enterprise_license_convert_from_old',
202 rmap.connect('enterprise_license_convert_from_old',
203 'https://rhodecode.com/u/license-upgrade',
203 'https://rhodecode.com/u/license-upgrade',
204 _static=True)
204 _static=True)
205
205
206 routing_links.connect_redirection_links(rmap)
206 routing_links.connect_redirection_links(rmap)
207
207
208 rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping')
208 rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping')
209 rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test')
209 rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test')
210
210
211 # ADMIN REPOSITORY ROUTES
211 # ADMIN REPOSITORY ROUTES
212 with rmap.submapper(path_prefix=ADMIN_PREFIX,
212 with rmap.submapper(path_prefix=ADMIN_PREFIX,
213 controller='admin/repos') as m:
213 controller='admin/repos') as m:
214 m.connect('repos', '/repos',
214 m.connect('repos', '/repos',
215 action='create', conditions={'method': ['POST']})
215 action='create', conditions={'method': ['POST']})
216 m.connect('repos', '/repos',
216 m.connect('repos', '/repos',
217 action='index', conditions={'method': ['GET']})
217 action='index', conditions={'method': ['GET']})
218 m.connect('new_repo', '/create_repository', jsroute=True,
218 m.connect('new_repo', '/create_repository', jsroute=True,
219 action='create_repository', conditions={'method': ['GET']})
219 action='create_repository', conditions={'method': ['GET']})
220 m.connect('/repos/{repo_name}',
220 m.connect('/repos/{repo_name}',
221 action='update', conditions={'method': ['PUT'],
221 action='update', conditions={'method': ['PUT'],
222 'function': check_repo},
222 'function': check_repo},
223 requirements=URL_NAME_REQUIREMENTS)
223 requirements=URL_NAME_REQUIREMENTS)
224 m.connect('delete_repo', '/repos/{repo_name}',
224 m.connect('delete_repo', '/repos/{repo_name}',
225 action='delete', conditions={'method': ['DELETE']},
225 action='delete', conditions={'method': ['DELETE']},
226 requirements=URL_NAME_REQUIREMENTS)
226 requirements=URL_NAME_REQUIREMENTS)
227 m.connect('repo', '/repos/{repo_name}',
227 m.connect('repo', '/repos/{repo_name}',
228 action='show', conditions={'method': ['GET'],
228 action='show', conditions={'method': ['GET'],
229 'function': check_repo},
229 'function': check_repo},
230 requirements=URL_NAME_REQUIREMENTS)
230 requirements=URL_NAME_REQUIREMENTS)
231
231
232 # ADMIN REPOSITORY GROUPS ROUTES
232 # ADMIN REPOSITORY GROUPS ROUTES
233 with rmap.submapper(path_prefix=ADMIN_PREFIX,
233 with rmap.submapper(path_prefix=ADMIN_PREFIX,
234 controller='admin/repo_groups') as m:
234 controller='admin/repo_groups') as m:
235 m.connect('repo_groups', '/repo_groups',
235 m.connect('repo_groups', '/repo_groups',
236 action='create', conditions={'method': ['POST']})
236 action='create', conditions={'method': ['POST']})
237 m.connect('repo_groups', '/repo_groups',
237 m.connect('repo_groups', '/repo_groups',
238 action='index', conditions={'method': ['GET']})
238 action='index', conditions={'method': ['GET']})
239 m.connect('new_repo_group', '/repo_groups/new',
239 m.connect('new_repo_group', '/repo_groups/new',
240 action='new', conditions={'method': ['GET']})
240 action='new', conditions={'method': ['GET']})
241 m.connect('update_repo_group', '/repo_groups/{group_name}',
241 m.connect('update_repo_group', '/repo_groups/{group_name}',
242 action='update', conditions={'method': ['PUT'],
242 action='update', conditions={'method': ['PUT'],
243 'function': check_group},
243 'function': check_group},
244 requirements=URL_NAME_REQUIREMENTS)
244 requirements=URL_NAME_REQUIREMENTS)
245
245
246 # EXTRAS REPO GROUP ROUTES
246 # EXTRAS REPO GROUP ROUTES
247 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
247 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
248 action='edit',
248 action='edit',
249 conditions={'method': ['GET'], 'function': check_group},
249 conditions={'method': ['GET'], 'function': check_group},
250 requirements=URL_NAME_REQUIREMENTS)
250 requirements=URL_NAME_REQUIREMENTS)
251 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
251 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
252 action='edit',
252 action='edit',
253 conditions={'method': ['PUT'], 'function': check_group},
253 conditions={'method': ['PUT'], 'function': check_group},
254 requirements=URL_NAME_REQUIREMENTS)
254 requirements=URL_NAME_REQUIREMENTS)
255
255
256 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
256 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
257 action='edit_repo_group_advanced',
257 action='edit_repo_group_advanced',
258 conditions={'method': ['GET'], 'function': check_group},
258 conditions={'method': ['GET'], 'function': check_group},
259 requirements=URL_NAME_REQUIREMENTS)
259 requirements=URL_NAME_REQUIREMENTS)
260 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
260 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
261 action='edit_repo_group_advanced',
261 action='edit_repo_group_advanced',
262 conditions={'method': ['PUT'], 'function': check_group},
262 conditions={'method': ['PUT'], 'function': check_group},
263 requirements=URL_NAME_REQUIREMENTS)
263 requirements=URL_NAME_REQUIREMENTS)
264
264
265 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
265 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
266 action='edit_repo_group_perms',
266 action='edit_repo_group_perms',
267 conditions={'method': ['GET'], 'function': check_group},
267 conditions={'method': ['GET'], 'function': check_group},
268 requirements=URL_NAME_REQUIREMENTS)
268 requirements=URL_NAME_REQUIREMENTS)
269 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
269 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
270 action='update_perms',
270 action='update_perms',
271 conditions={'method': ['PUT'], 'function': check_group},
271 conditions={'method': ['PUT'], 'function': check_group},
272 requirements=URL_NAME_REQUIREMENTS)
272 requirements=URL_NAME_REQUIREMENTS)
273
273
274 m.connect('delete_repo_group', '/repo_groups/{group_name}',
274 m.connect('delete_repo_group', '/repo_groups/{group_name}',
275 action='delete', conditions={'method': ['DELETE'],
275 action='delete', conditions={'method': ['DELETE'],
276 'function': check_group},
276 'function': check_group},
277 requirements=URL_NAME_REQUIREMENTS)
277 requirements=URL_NAME_REQUIREMENTS)
278
278
279 # ADMIN USER ROUTES
279 # ADMIN USER ROUTES
280 with rmap.submapper(path_prefix=ADMIN_PREFIX,
280 with rmap.submapper(path_prefix=ADMIN_PREFIX,
281 controller='admin/users') as m:
281 controller='admin/users') as m:
282 m.connect('users', '/users',
282 m.connect('users', '/users',
283 action='create', conditions={'method': ['POST']})
283 action='create', conditions={'method': ['POST']})
284 m.connect('users', '/users',
284 m.connect('users', '/users',
285 action='index', conditions={'method': ['GET']})
285 action='index', conditions={'method': ['GET']})
286 m.connect('new_user', '/users/new',
286 m.connect('new_user', '/users/new',
287 action='new', conditions={'method': ['GET']})
287 action='new', conditions={'method': ['GET']})
288 m.connect('update_user', '/users/{user_id}',
288 m.connect('update_user', '/users/{user_id}',
289 action='update', conditions={'method': ['PUT']})
289 action='update', conditions={'method': ['PUT']})
290 m.connect('delete_user', '/users/{user_id}',
290 m.connect('delete_user', '/users/{user_id}',
291 action='delete', conditions={'method': ['DELETE']})
291 action='delete', conditions={'method': ['DELETE']})
292 m.connect('edit_user', '/users/{user_id}/edit',
292 m.connect('edit_user', '/users/{user_id}/edit',
293 action='edit', conditions={'method': ['GET']})
293 action='edit', conditions={'method': ['GET']})
294 m.connect('user', '/users/{user_id}',
294 m.connect('user', '/users/{user_id}',
295 action='show', conditions={'method': ['GET']})
295 action='show', conditions={'method': ['GET']})
296 m.connect('force_password_reset_user', '/users/{user_id}/password_reset',
296 m.connect('force_password_reset_user', '/users/{user_id}/password_reset',
297 action='reset_password', conditions={'method': ['POST']})
297 action='reset_password', conditions={'method': ['POST']})
298 m.connect('create_personal_repo_group', '/users/{user_id}/create_repo_group',
298 m.connect('create_personal_repo_group', '/users/{user_id}/create_repo_group',
299 action='create_personal_repo_group', conditions={'method': ['POST']})
299 action='create_personal_repo_group', conditions={'method': ['POST']})
300
300
301 # EXTRAS USER ROUTES
301 # EXTRAS USER ROUTES
302 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
302 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
303 action='edit_advanced', conditions={'method': ['GET']})
303 action='edit_advanced', conditions={'method': ['GET']})
304 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
304 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
305 action='update_advanced', conditions={'method': ['PUT']})
305 action='update_advanced', conditions={'method': ['PUT']})
306
306
307 m.connect('edit_user_auth_tokens', '/users/{user_id}/edit/auth_tokens',
307 m.connect('edit_user_auth_tokens', '/users/{user_id}/edit/auth_tokens',
308 action='edit_auth_tokens', conditions={'method': ['GET']})
308 action='edit_auth_tokens', conditions={'method': ['GET']})
309 m.connect('edit_user_auth_tokens', '/users/{user_id}/edit/auth_tokens',
309 m.connect('edit_user_auth_tokens', '/users/{user_id}/edit/auth_tokens',
310 action='add_auth_token', conditions={'method': ['PUT']})
310 action='add_auth_token', conditions={'method': ['PUT']})
311 m.connect('edit_user_auth_tokens', '/users/{user_id}/edit/auth_tokens',
311 m.connect('edit_user_auth_tokens', '/users/{user_id}/edit/auth_tokens',
312 action='delete_auth_token', conditions={'method': ['DELETE']})
312 action='delete_auth_token', conditions={'method': ['DELETE']})
313
313
314 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
314 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
315 action='edit_global_perms', conditions={'method': ['GET']})
315 action='edit_global_perms', conditions={'method': ['GET']})
316 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
316 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
317 action='update_global_perms', conditions={'method': ['PUT']})
317 action='update_global_perms', conditions={'method': ['PUT']})
318
318
319 m.connect('edit_user_perms_summary', '/users/{user_id}/edit/permissions_summary',
319 m.connect('edit_user_perms_summary', '/users/{user_id}/edit/permissions_summary',
320 action='edit_perms_summary', conditions={'method': ['GET']})
320 action='edit_perms_summary', conditions={'method': ['GET']})
321
321
322 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
322 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
323 action='edit_emails', conditions={'method': ['GET']})
323 action='edit_emails', conditions={'method': ['GET']})
324 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
324 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
325 action='add_email', conditions={'method': ['PUT']})
325 action='add_email', conditions={'method': ['PUT']})
326 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
326 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
327 action='delete_email', conditions={'method': ['DELETE']})
327 action='delete_email', conditions={'method': ['DELETE']})
328
328
329 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
329 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
330 action='edit_ips', conditions={'method': ['GET']})
330 action='edit_ips', conditions={'method': ['GET']})
331 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
331 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
332 action='add_ip', conditions={'method': ['PUT']})
332 action='add_ip', conditions={'method': ['PUT']})
333 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
333 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
334 action='delete_ip', conditions={'method': ['DELETE']})
334 action='delete_ip', conditions={'method': ['DELETE']})
335
335
336 # ADMIN USER GROUPS REST ROUTES
336 # ADMIN USER GROUPS REST ROUTES
337 with rmap.submapper(path_prefix=ADMIN_PREFIX,
337 with rmap.submapper(path_prefix=ADMIN_PREFIX,
338 controller='admin/user_groups') as m:
338 controller='admin/user_groups') as m:
339 m.connect('users_groups', '/user_groups',
339 m.connect('users_groups', '/user_groups',
340 action='create', conditions={'method': ['POST']})
340 action='create', conditions={'method': ['POST']})
341 m.connect('users_groups', '/user_groups',
341 m.connect('users_groups', '/user_groups',
342 action='index', conditions={'method': ['GET']})
342 action='index', conditions={'method': ['GET']})
343 m.connect('new_users_group', '/user_groups/new',
343 m.connect('new_users_group', '/user_groups/new',
344 action='new', conditions={'method': ['GET']})
344 action='new', conditions={'method': ['GET']})
345 m.connect('update_users_group', '/user_groups/{user_group_id}',
345 m.connect('update_users_group', '/user_groups/{user_group_id}',
346 action='update', conditions={'method': ['PUT']})
346 action='update', conditions={'method': ['PUT']})
347 m.connect('delete_users_group', '/user_groups/{user_group_id}',
347 m.connect('delete_users_group', '/user_groups/{user_group_id}',
348 action='delete', conditions={'method': ['DELETE']})
348 action='delete', conditions={'method': ['DELETE']})
349 m.connect('edit_users_group', '/user_groups/{user_group_id}/edit',
349 m.connect('edit_users_group', '/user_groups/{user_group_id}/edit',
350 action='edit', conditions={'method': ['GET']},
350 action='edit', conditions={'method': ['GET']},
351 function=check_user_group)
351 function=check_user_group)
352
352
353 # EXTRAS USER GROUP ROUTES
353 # EXTRAS USER GROUP ROUTES
354 m.connect('edit_user_group_global_perms',
354 m.connect('edit_user_group_global_perms',
355 '/user_groups/{user_group_id}/edit/global_permissions',
355 '/user_groups/{user_group_id}/edit/global_permissions',
356 action='edit_global_perms', conditions={'method': ['GET']})
356 action='edit_global_perms', conditions={'method': ['GET']})
357 m.connect('edit_user_group_global_perms',
357 m.connect('edit_user_group_global_perms',
358 '/user_groups/{user_group_id}/edit/global_permissions',
358 '/user_groups/{user_group_id}/edit/global_permissions',
359 action='update_global_perms', conditions={'method': ['PUT']})
359 action='update_global_perms', conditions={'method': ['PUT']})
360 m.connect('edit_user_group_perms_summary',
360 m.connect('edit_user_group_perms_summary',
361 '/user_groups/{user_group_id}/edit/permissions_summary',
361 '/user_groups/{user_group_id}/edit/permissions_summary',
362 action='edit_perms_summary', conditions={'method': ['GET']})
362 action='edit_perms_summary', conditions={'method': ['GET']})
363
363
364 m.connect('edit_user_group_perms',
364 m.connect('edit_user_group_perms',
365 '/user_groups/{user_group_id}/edit/permissions',
365 '/user_groups/{user_group_id}/edit/permissions',
366 action='edit_perms', conditions={'method': ['GET']})
366 action='edit_perms', conditions={'method': ['GET']})
367 m.connect('edit_user_group_perms',
367 m.connect('edit_user_group_perms',
368 '/user_groups/{user_group_id}/edit/permissions',
368 '/user_groups/{user_group_id}/edit/permissions',
369 action='update_perms', conditions={'method': ['PUT']})
369 action='update_perms', conditions={'method': ['PUT']})
370
370
371 m.connect('edit_user_group_advanced',
371 m.connect('edit_user_group_advanced',
372 '/user_groups/{user_group_id}/edit/advanced',
372 '/user_groups/{user_group_id}/edit/advanced',
373 action='edit_advanced', conditions={'method': ['GET']})
373 action='edit_advanced', conditions={'method': ['GET']})
374
374
375 m.connect('edit_user_group_members',
375 m.connect('edit_user_group_members',
376 '/user_groups/{user_group_id}/edit/members', jsroute=True,
376 '/user_groups/{user_group_id}/edit/members', jsroute=True,
377 action='edit_members', conditions={'method': ['GET']})
377 action='edit_members', conditions={'method': ['GET']})
378
378
379 # ADMIN PERMISSIONS ROUTES
379 # ADMIN PERMISSIONS ROUTES
380 with rmap.submapper(path_prefix=ADMIN_PREFIX,
380 with rmap.submapper(path_prefix=ADMIN_PREFIX,
381 controller='admin/permissions') as m:
381 controller='admin/permissions') as m:
382 m.connect('admin_permissions_application', '/permissions/application',
382 m.connect('admin_permissions_application', '/permissions/application',
383 action='permission_application_update', conditions={'method': ['POST']})
383 action='permission_application_update', conditions={'method': ['POST']})
384 m.connect('admin_permissions_application', '/permissions/application',
384 m.connect('admin_permissions_application', '/permissions/application',
385 action='permission_application', conditions={'method': ['GET']})
385 action='permission_application', conditions={'method': ['GET']})
386
386
387 m.connect('admin_permissions_global', '/permissions/global',
387 m.connect('admin_permissions_global', '/permissions/global',
388 action='permission_global_update', conditions={'method': ['POST']})
388 action='permission_global_update', conditions={'method': ['POST']})
389 m.connect('admin_permissions_global', '/permissions/global',
389 m.connect('admin_permissions_global', '/permissions/global',
390 action='permission_global', conditions={'method': ['GET']})
390 action='permission_global', conditions={'method': ['GET']})
391
391
392 m.connect('admin_permissions_object', '/permissions/object',
392 m.connect('admin_permissions_object', '/permissions/object',
393 action='permission_objects_update', conditions={'method': ['POST']})
393 action='permission_objects_update', conditions={'method': ['POST']})
394 m.connect('admin_permissions_object', '/permissions/object',
394 m.connect('admin_permissions_object', '/permissions/object',
395 action='permission_objects', conditions={'method': ['GET']})
395 action='permission_objects', conditions={'method': ['GET']})
396
396
397 m.connect('admin_permissions_ips', '/permissions/ips',
397 m.connect('admin_permissions_ips', '/permissions/ips',
398 action='permission_ips', conditions={'method': ['POST']})
398 action='permission_ips', conditions={'method': ['POST']})
399 m.connect('admin_permissions_ips', '/permissions/ips',
399 m.connect('admin_permissions_ips', '/permissions/ips',
400 action='permission_ips', conditions={'method': ['GET']})
400 action='permission_ips', conditions={'method': ['GET']})
401
401
402 m.connect('admin_permissions_overview', '/permissions/overview',
402 m.connect('admin_permissions_overview', '/permissions/overview',
403 action='permission_perms', conditions={'method': ['GET']})
403 action='permission_perms', conditions={'method': ['GET']})
404
404
405 # ADMIN DEFAULTS REST ROUTES
405 # ADMIN DEFAULTS REST ROUTES
406 with rmap.submapper(path_prefix=ADMIN_PREFIX,
406 with rmap.submapper(path_prefix=ADMIN_PREFIX,
407 controller='admin/defaults') as m:
407 controller='admin/defaults') as m:
408 m.connect('admin_defaults_repositories', '/defaults/repositories',
408 m.connect('admin_defaults_repositories', '/defaults/repositories',
409 action='update_repository_defaults', conditions={'method': ['POST']})
409 action='update_repository_defaults', conditions={'method': ['POST']})
410 m.connect('admin_defaults_repositories', '/defaults/repositories',
410 m.connect('admin_defaults_repositories', '/defaults/repositories',
411 action='index', conditions={'method': ['GET']})
411 action='index', conditions={'method': ['GET']})
412
412
413 # ADMIN DEBUG STYLE ROUTES
413 # ADMIN DEBUG STYLE ROUTES
414 if str2bool(config.get('debug_style')):
414 if str2bool(config.get('debug_style')):
415 with rmap.submapper(path_prefix=ADMIN_PREFIX + '/debug_style',
415 with rmap.submapper(path_prefix=ADMIN_PREFIX + '/debug_style',
416 controller='debug_style') as m:
416 controller='debug_style') as m:
417 m.connect('debug_style_home', '',
417 m.connect('debug_style_home', '',
418 action='index', conditions={'method': ['GET']})
418 action='index', conditions={'method': ['GET']})
419 m.connect('debug_style_template', '/t/{t_path}',
419 m.connect('debug_style_template', '/t/{t_path}',
420 action='template', conditions={'method': ['GET']})
420 action='template', conditions={'method': ['GET']})
421
421
422 # ADMIN SETTINGS ROUTES
422 # ADMIN SETTINGS ROUTES
423 with rmap.submapper(path_prefix=ADMIN_PREFIX,
423 with rmap.submapper(path_prefix=ADMIN_PREFIX,
424 controller='admin/settings') as m:
424 controller='admin/settings') as m:
425
425
426 # default
426 # default
427 m.connect('admin_settings', '/settings',
427 m.connect('admin_settings', '/settings',
428 action='settings_global_update',
428 action='settings_global_update',
429 conditions={'method': ['POST']})
429 conditions={'method': ['POST']})
430 m.connect('admin_settings', '/settings',
430 m.connect('admin_settings', '/settings',
431 action='settings_global', conditions={'method': ['GET']})
431 action='settings_global', conditions={'method': ['GET']})
432
432
433 m.connect('admin_settings_vcs', '/settings/vcs',
433 m.connect('admin_settings_vcs', '/settings/vcs',
434 action='settings_vcs_update',
434 action='settings_vcs_update',
435 conditions={'method': ['POST']})
435 conditions={'method': ['POST']})
436 m.connect('admin_settings_vcs', '/settings/vcs',
436 m.connect('admin_settings_vcs', '/settings/vcs',
437 action='settings_vcs',
437 action='settings_vcs',
438 conditions={'method': ['GET']})
438 conditions={'method': ['GET']})
439 m.connect('admin_settings_vcs', '/settings/vcs',
439 m.connect('admin_settings_vcs', '/settings/vcs',
440 action='delete_svn_pattern',
440 action='delete_svn_pattern',
441 conditions={'method': ['DELETE']})
441 conditions={'method': ['DELETE']})
442
442
443 m.connect('admin_settings_mapping', '/settings/mapping',
443 m.connect('admin_settings_mapping', '/settings/mapping',
444 action='settings_mapping_update',
444 action='settings_mapping_update',
445 conditions={'method': ['POST']})
445 conditions={'method': ['POST']})
446 m.connect('admin_settings_mapping', '/settings/mapping',
446 m.connect('admin_settings_mapping', '/settings/mapping',
447 action='settings_mapping', conditions={'method': ['GET']})
447 action='settings_mapping', conditions={'method': ['GET']})
448
448
449 m.connect('admin_settings_global', '/settings/global',
449 m.connect('admin_settings_global', '/settings/global',
450 action='settings_global_update',
450 action='settings_global_update',
451 conditions={'method': ['POST']})
451 conditions={'method': ['POST']})
452 m.connect('admin_settings_global', '/settings/global',
452 m.connect('admin_settings_global', '/settings/global',
453 action='settings_global', conditions={'method': ['GET']})
453 action='settings_global', conditions={'method': ['GET']})
454
454
455 m.connect('admin_settings_visual', '/settings/visual',
455 m.connect('admin_settings_visual', '/settings/visual',
456 action='settings_visual_update',
456 action='settings_visual_update',
457 conditions={'method': ['POST']})
457 conditions={'method': ['POST']})
458 m.connect('admin_settings_visual', '/settings/visual',
458 m.connect('admin_settings_visual', '/settings/visual',
459 action='settings_visual', conditions={'method': ['GET']})
459 action='settings_visual', conditions={'method': ['GET']})
460
460
461 m.connect('admin_settings_issuetracker',
461 m.connect('admin_settings_issuetracker',
462 '/settings/issue-tracker', action='settings_issuetracker',
462 '/settings/issue-tracker', action='settings_issuetracker',
463 conditions={'method': ['GET']})
463 conditions={'method': ['GET']})
464 m.connect('admin_settings_issuetracker_save',
464 m.connect('admin_settings_issuetracker_save',
465 '/settings/issue-tracker/save',
465 '/settings/issue-tracker/save',
466 action='settings_issuetracker_save',
466 action='settings_issuetracker_save',
467 conditions={'method': ['POST']})
467 conditions={'method': ['POST']})
468 m.connect('admin_issuetracker_test', '/settings/issue-tracker/test',
468 m.connect('admin_issuetracker_test', '/settings/issue-tracker/test',
469 action='settings_issuetracker_test',
469 action='settings_issuetracker_test',
470 conditions={'method': ['POST']})
470 conditions={'method': ['POST']})
471 m.connect('admin_issuetracker_delete',
471 m.connect('admin_issuetracker_delete',
472 '/settings/issue-tracker/delete',
472 '/settings/issue-tracker/delete',
473 action='settings_issuetracker_delete',
473 action='settings_issuetracker_delete',
474 conditions={'method': ['DELETE']})
474 conditions={'method': ['DELETE']})
475
475
476 m.connect('admin_settings_email', '/settings/email',
476 m.connect('admin_settings_email', '/settings/email',
477 action='settings_email_update',
477 action='settings_email_update',
478 conditions={'method': ['POST']})
478 conditions={'method': ['POST']})
479 m.connect('admin_settings_email', '/settings/email',
479 m.connect('admin_settings_email', '/settings/email',
480 action='settings_email', conditions={'method': ['GET']})
480 action='settings_email', conditions={'method': ['GET']})
481
481
482 m.connect('admin_settings_hooks', '/settings/hooks',
482 m.connect('admin_settings_hooks', '/settings/hooks',
483 action='settings_hooks_update',
483 action='settings_hooks_update',
484 conditions={'method': ['POST', 'DELETE']})
484 conditions={'method': ['POST', 'DELETE']})
485 m.connect('admin_settings_hooks', '/settings/hooks',
485 m.connect('admin_settings_hooks', '/settings/hooks',
486 action='settings_hooks', conditions={'method': ['GET']})
486 action='settings_hooks', conditions={'method': ['GET']})
487
487
488 m.connect('admin_settings_search', '/settings/search',
488 m.connect('admin_settings_search', '/settings/search',
489 action='settings_search', conditions={'method': ['GET']})
489 action='settings_search', conditions={'method': ['GET']})
490
490
491 m.connect('admin_settings_system', '/settings/system',
491 m.connect('admin_settings_system', '/settings/system',
492 action='settings_system', conditions={'method': ['GET']})
492 action='settings_system', conditions={'method': ['GET']})
493
493
494 m.connect('admin_settings_system_update', '/settings/system/updates',
494 m.connect('admin_settings_system_update', '/settings/system/updates',
495 action='settings_system_update', conditions={'method': ['GET']})
495 action='settings_system_update', conditions={'method': ['GET']})
496
496
497 m.connect('admin_settings_supervisor', '/settings/supervisor',
497 m.connect('admin_settings_supervisor', '/settings/supervisor',
498 action='settings_supervisor', conditions={'method': ['GET']})
498 action='settings_supervisor', conditions={'method': ['GET']})
499 m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log',
499 m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log',
500 action='settings_supervisor_log', conditions={'method': ['GET']})
500 action='settings_supervisor_log', conditions={'method': ['GET']})
501
501
502 m.connect('admin_settings_labs', '/settings/labs',
502 m.connect('admin_settings_labs', '/settings/labs',
503 action='settings_labs_update',
503 action='settings_labs_update',
504 conditions={'method': ['POST']})
504 conditions={'method': ['POST']})
505 m.connect('admin_settings_labs', '/settings/labs',
505 m.connect('admin_settings_labs', '/settings/labs',
506 action='settings_labs', conditions={'method': ['GET']})
506 action='settings_labs', conditions={'method': ['GET']})
507
507
508 m.connect('admin_settings_open_source', '/settings/open_source',
509 action='settings_open_source',
510 conditions={'method': ['GET']})
511
512 # ADMIN MY ACCOUNT
508 # ADMIN MY ACCOUNT
513 with rmap.submapper(path_prefix=ADMIN_PREFIX,
509 with rmap.submapper(path_prefix=ADMIN_PREFIX,
514 controller='admin/my_account') as m:
510 controller='admin/my_account') as m:
515
511
516 m.connect('my_account', '/my_account',
512 m.connect('my_account', '/my_account',
517 action='my_account', conditions={'method': ['GET']})
513 action='my_account', conditions={'method': ['GET']})
518 m.connect('my_account_edit', '/my_account/edit',
514 m.connect('my_account_edit', '/my_account/edit',
519 action='my_account_edit', conditions={'method': ['GET']})
515 action='my_account_edit', conditions={'method': ['GET']})
520 m.connect('my_account', '/my_account',
516 m.connect('my_account', '/my_account',
521 action='my_account_update', conditions={'method': ['POST']})
517 action='my_account_update', conditions={'method': ['POST']})
522
518
523 m.connect('my_account_password', '/my_account/password',
519 m.connect('my_account_password', '/my_account/password',
524 action='my_account_password', conditions={'method': ['GET']})
520 action='my_account_password', conditions={'method': ['GET']})
525 m.connect('my_account_password', '/my_account/password',
521 m.connect('my_account_password', '/my_account/password',
526 action='my_account_password_update', conditions={'method': ['POST']})
522 action='my_account_password_update', conditions={'method': ['POST']})
527
523
528 m.connect('my_account_repos', '/my_account/repos',
524 m.connect('my_account_repos', '/my_account/repos',
529 action='my_account_repos', conditions={'method': ['GET']})
525 action='my_account_repos', conditions={'method': ['GET']})
530
526
531 m.connect('my_account_watched', '/my_account/watched',
527 m.connect('my_account_watched', '/my_account/watched',
532 action='my_account_watched', conditions={'method': ['GET']})
528 action='my_account_watched', conditions={'method': ['GET']})
533
529
534 m.connect('my_account_pullrequests', '/my_account/pull_requests',
530 m.connect('my_account_pullrequests', '/my_account/pull_requests',
535 action='my_account_pullrequests', conditions={'method': ['GET']})
531 action='my_account_pullrequests', conditions={'method': ['GET']})
536
532
537 m.connect('my_account_perms', '/my_account/perms',
533 m.connect('my_account_perms', '/my_account/perms',
538 action='my_account_perms', conditions={'method': ['GET']})
534 action='my_account_perms', conditions={'method': ['GET']})
539
535
540 m.connect('my_account_emails', '/my_account/emails',
536 m.connect('my_account_emails', '/my_account/emails',
541 action='my_account_emails', conditions={'method': ['GET']})
537 action='my_account_emails', conditions={'method': ['GET']})
542 m.connect('my_account_emails', '/my_account/emails',
538 m.connect('my_account_emails', '/my_account/emails',
543 action='my_account_emails_add', conditions={'method': ['POST']})
539 action='my_account_emails_add', conditions={'method': ['POST']})
544 m.connect('my_account_emails', '/my_account/emails',
540 m.connect('my_account_emails', '/my_account/emails',
545 action='my_account_emails_delete', conditions={'method': ['DELETE']})
541 action='my_account_emails_delete', conditions={'method': ['DELETE']})
546
542
547 m.connect('my_account_auth_tokens', '/my_account/auth_tokens',
543 m.connect('my_account_auth_tokens', '/my_account/auth_tokens',
548 action='my_account_auth_tokens', conditions={'method': ['GET']})
544 action='my_account_auth_tokens', conditions={'method': ['GET']})
549 m.connect('my_account_auth_tokens', '/my_account/auth_tokens',
545 m.connect('my_account_auth_tokens', '/my_account/auth_tokens',
550 action='my_account_auth_tokens_add', conditions={'method': ['POST']})
546 action='my_account_auth_tokens_add', conditions={'method': ['POST']})
551 m.connect('my_account_auth_tokens', '/my_account/auth_tokens',
547 m.connect('my_account_auth_tokens', '/my_account/auth_tokens',
552 action='my_account_auth_tokens_delete', conditions={'method': ['DELETE']})
548 action='my_account_auth_tokens_delete', conditions={'method': ['DELETE']})
553
549
554 # NOTIFICATION REST ROUTES
550 # NOTIFICATION REST ROUTES
555 with rmap.submapper(path_prefix=ADMIN_PREFIX,
551 with rmap.submapper(path_prefix=ADMIN_PREFIX,
556 controller='admin/notifications') as m:
552 controller='admin/notifications') as m:
557 m.connect('notifications', '/notifications',
553 m.connect('notifications', '/notifications',
558 action='index', conditions={'method': ['GET']})
554 action='index', conditions={'method': ['GET']})
559 m.connect('notifications_mark_all_read', '/notifications/mark_all_read',
555 m.connect('notifications_mark_all_read', '/notifications/mark_all_read',
560 action='mark_all_read', conditions={'method': ['POST']})
556 action='mark_all_read', conditions={'method': ['POST']})
561
557
562 m.connect('/notifications/{notification_id}',
558 m.connect('/notifications/{notification_id}',
563 action='update', conditions={'method': ['PUT']})
559 action='update', conditions={'method': ['PUT']})
564 m.connect('/notifications/{notification_id}',
560 m.connect('/notifications/{notification_id}',
565 action='delete', conditions={'method': ['DELETE']})
561 action='delete', conditions={'method': ['DELETE']})
566 m.connect('notification', '/notifications/{notification_id}',
562 m.connect('notification', '/notifications/{notification_id}',
567 action='show', conditions={'method': ['GET']})
563 action='show', conditions={'method': ['GET']})
568
564
569 # ADMIN GIST
565 # ADMIN GIST
570 with rmap.submapper(path_prefix=ADMIN_PREFIX,
566 with rmap.submapper(path_prefix=ADMIN_PREFIX,
571 controller='admin/gists') as m:
567 controller='admin/gists') as m:
572 m.connect('gists', '/gists',
568 m.connect('gists', '/gists',
573 action='create', conditions={'method': ['POST']})
569 action='create', conditions={'method': ['POST']})
574 m.connect('gists', '/gists', jsroute=True,
570 m.connect('gists', '/gists', jsroute=True,
575 action='index', conditions={'method': ['GET']})
571 action='index', conditions={'method': ['GET']})
576 m.connect('new_gist', '/gists/new', jsroute=True,
572 m.connect('new_gist', '/gists/new', jsroute=True,
577 action='new', conditions={'method': ['GET']})
573 action='new', conditions={'method': ['GET']})
578
574
579 m.connect('/gists/{gist_id}',
575 m.connect('/gists/{gist_id}',
580 action='delete', conditions={'method': ['DELETE']})
576 action='delete', conditions={'method': ['DELETE']})
581 m.connect('edit_gist', '/gists/{gist_id}/edit',
577 m.connect('edit_gist', '/gists/{gist_id}/edit',
582 action='edit_form', conditions={'method': ['GET']})
578 action='edit_form', conditions={'method': ['GET']})
583 m.connect('edit_gist', '/gists/{gist_id}/edit',
579 m.connect('edit_gist', '/gists/{gist_id}/edit',
584 action='edit', conditions={'method': ['POST']})
580 action='edit', conditions={'method': ['POST']})
585 m.connect(
581 m.connect(
586 'edit_gist_check_revision', '/gists/{gist_id}/edit/check_revision',
582 'edit_gist_check_revision', '/gists/{gist_id}/edit/check_revision',
587 action='check_revision', conditions={'method': ['GET']})
583 action='check_revision', conditions={'method': ['GET']})
588
584
589 m.connect('gist', '/gists/{gist_id}',
585 m.connect('gist', '/gists/{gist_id}',
590 action='show', conditions={'method': ['GET']})
586 action='show', conditions={'method': ['GET']})
591 m.connect('gist_rev', '/gists/{gist_id}/{revision}',
587 m.connect('gist_rev', '/gists/{gist_id}/{revision}',
592 revision='tip',
588 revision='tip',
593 action='show', conditions={'method': ['GET']})
589 action='show', conditions={'method': ['GET']})
594 m.connect('formatted_gist', '/gists/{gist_id}/{revision}/{format}',
590 m.connect('formatted_gist', '/gists/{gist_id}/{revision}/{format}',
595 revision='tip',
591 revision='tip',
596 action='show', conditions={'method': ['GET']})
592 action='show', conditions={'method': ['GET']})
597 m.connect('formatted_gist_file', '/gists/{gist_id}/{revision}/{format}/{f_path}',
593 m.connect('formatted_gist_file', '/gists/{gist_id}/{revision}/{format}/{f_path}',
598 revision='tip',
594 revision='tip',
599 action='show', conditions={'method': ['GET']},
595 action='show', conditions={'method': ['GET']},
600 requirements=URL_NAME_REQUIREMENTS)
596 requirements=URL_NAME_REQUIREMENTS)
601
597
602 # ADMIN MAIN PAGES
598 # ADMIN MAIN PAGES
603 with rmap.submapper(path_prefix=ADMIN_PREFIX,
599 with rmap.submapper(path_prefix=ADMIN_PREFIX,
604 controller='admin/admin') as m:
600 controller='admin/admin') as m:
605 m.connect('admin_home', '', action='index')
601 m.connect('admin_home', '', action='index')
606 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
602 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
607 action='add_repo')
603 action='add_repo')
608 m.connect(
604 m.connect(
609 'pull_requests_global_0', '/pull_requests/{pull_request_id:[0-9]+}',
605 'pull_requests_global_0', '/pull_requests/{pull_request_id:[0-9]+}',
610 action='pull_requests')
606 action='pull_requests')
611 m.connect(
607 m.connect(
612 'pull_requests_global', '/pull-requests/{pull_request_id:[0-9]+}',
608 'pull_requests_global', '/pull-requests/{pull_request_id:[0-9]+}',
613 action='pull_requests')
609 action='pull_requests')
614
610
615
611
616 # USER JOURNAL
612 # USER JOURNAL
617 rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
613 rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
618 controller='journal', action='index')
614 controller='journal', action='index')
619 rmap.connect('journal_rss', '%s/journal/rss' % (ADMIN_PREFIX,),
615 rmap.connect('journal_rss', '%s/journal/rss' % (ADMIN_PREFIX,),
620 controller='journal', action='journal_rss')
616 controller='journal', action='journal_rss')
621 rmap.connect('journal_atom', '%s/journal/atom' % (ADMIN_PREFIX,),
617 rmap.connect('journal_atom', '%s/journal/atom' % (ADMIN_PREFIX,),
622 controller='journal', action='journal_atom')
618 controller='journal', action='journal_atom')
623
619
624 rmap.connect('public_journal', '%s/public_journal' % (ADMIN_PREFIX,),
620 rmap.connect('public_journal', '%s/public_journal' % (ADMIN_PREFIX,),
625 controller='journal', action='public_journal')
621 controller='journal', action='public_journal')
626
622
627 rmap.connect('public_journal_rss', '%s/public_journal/rss' % (ADMIN_PREFIX,),
623 rmap.connect('public_journal_rss', '%s/public_journal/rss' % (ADMIN_PREFIX,),
628 controller='journal', action='public_journal_rss')
624 controller='journal', action='public_journal_rss')
629
625
630 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % (ADMIN_PREFIX,),
626 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % (ADMIN_PREFIX,),
631 controller='journal', action='public_journal_rss')
627 controller='journal', action='public_journal_rss')
632
628
633 rmap.connect('public_journal_atom',
629 rmap.connect('public_journal_atom',
634 '%s/public_journal/atom' % (ADMIN_PREFIX,), controller='journal',
630 '%s/public_journal/atom' % (ADMIN_PREFIX,), controller='journal',
635 action='public_journal_atom')
631 action='public_journal_atom')
636
632
637 rmap.connect('public_journal_atom_old',
633 rmap.connect('public_journal_atom_old',
638 '%s/public_journal_atom' % (ADMIN_PREFIX,), controller='journal',
634 '%s/public_journal_atom' % (ADMIN_PREFIX,), controller='journal',
639 action='public_journal_atom')
635 action='public_journal_atom')
640
636
641 rmap.connect('toggle_following', '%s/toggle_following' % (ADMIN_PREFIX,),
637 rmap.connect('toggle_following', '%s/toggle_following' % (ADMIN_PREFIX,),
642 controller='journal', action='toggle_following', jsroute=True,
638 controller='journal', action='toggle_following', jsroute=True,
643 conditions={'method': ['POST']})
639 conditions={'method': ['POST']})
644
640
645 # FULL TEXT SEARCH
641 # FULL TEXT SEARCH
646 rmap.connect('search', '%s/search' % (ADMIN_PREFIX,),
642 rmap.connect('search', '%s/search' % (ADMIN_PREFIX,),
647 controller='search')
643 controller='search')
648 rmap.connect('search_repo_home', '/{repo_name}/search',
644 rmap.connect('search_repo_home', '/{repo_name}/search',
649 controller='search',
645 controller='search',
650 action='index',
646 action='index',
651 conditions={'function': check_repo},
647 conditions={'function': check_repo},
652 requirements=URL_NAME_REQUIREMENTS)
648 requirements=URL_NAME_REQUIREMENTS)
653
649
654 # FEEDS
650 # FEEDS
655 rmap.connect('rss_feed_home', '/{repo_name}/feed/rss',
651 rmap.connect('rss_feed_home', '/{repo_name}/feed/rss',
656 controller='feed', action='rss',
652 controller='feed', action='rss',
657 conditions={'function': check_repo},
653 conditions={'function': check_repo},
658 requirements=URL_NAME_REQUIREMENTS)
654 requirements=URL_NAME_REQUIREMENTS)
659
655
660 rmap.connect('atom_feed_home', '/{repo_name}/feed/atom',
656 rmap.connect('atom_feed_home', '/{repo_name}/feed/atom',
661 controller='feed', action='atom',
657 controller='feed', action='atom',
662 conditions={'function': check_repo},
658 conditions={'function': check_repo},
663 requirements=URL_NAME_REQUIREMENTS)
659 requirements=URL_NAME_REQUIREMENTS)
664
660
665 #==========================================================================
661 #==========================================================================
666 # REPOSITORY ROUTES
662 # REPOSITORY ROUTES
667 #==========================================================================
663 #==========================================================================
668
664
669 rmap.connect('repo_creating_home', '/{repo_name}/repo_creating',
665 rmap.connect('repo_creating_home', '/{repo_name}/repo_creating',
670 controller='admin/repos', action='repo_creating',
666 controller='admin/repos', action='repo_creating',
671 requirements=URL_NAME_REQUIREMENTS)
667 requirements=URL_NAME_REQUIREMENTS)
672 rmap.connect('repo_check_home', '/{repo_name}/crepo_check',
668 rmap.connect('repo_check_home', '/{repo_name}/crepo_check',
673 controller='admin/repos', action='repo_check',
669 controller='admin/repos', action='repo_check',
674 requirements=URL_NAME_REQUIREMENTS)
670 requirements=URL_NAME_REQUIREMENTS)
675
671
676 rmap.connect('repo_stats', '/{repo_name}/repo_stats/{commit_id}',
672 rmap.connect('repo_stats', '/{repo_name}/repo_stats/{commit_id}',
677 controller='summary', action='repo_stats',
673 controller='summary', action='repo_stats',
678 conditions={'function': check_repo},
674 conditions={'function': check_repo},
679 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
675 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
680
676
681 rmap.connect('repo_refs_data', '/{repo_name}/refs-data',
677 rmap.connect('repo_refs_data', '/{repo_name}/refs-data',
682 controller='summary', action='repo_refs_data', jsroute=True,
678 controller='summary', action='repo_refs_data', jsroute=True,
683 requirements=URL_NAME_REQUIREMENTS)
679 requirements=URL_NAME_REQUIREMENTS)
684 rmap.connect('repo_refs_changelog_data', '/{repo_name}/refs-data-changelog',
680 rmap.connect('repo_refs_changelog_data', '/{repo_name}/refs-data-changelog',
685 controller='summary', action='repo_refs_changelog_data',
681 controller='summary', action='repo_refs_changelog_data',
686 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
682 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
687
683
688 rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}',
684 rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}',
689 controller='changeset', revision='tip', jsroute=True,
685 controller='changeset', revision='tip', jsroute=True,
690 conditions={'function': check_repo},
686 conditions={'function': check_repo},
691 requirements=URL_NAME_REQUIREMENTS)
687 requirements=URL_NAME_REQUIREMENTS)
692 rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}',
688 rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}',
693 controller='changeset', revision='tip', action='changeset_children',
689 controller='changeset', revision='tip', action='changeset_children',
694 conditions={'function': check_repo},
690 conditions={'function': check_repo},
695 requirements=URL_NAME_REQUIREMENTS)
691 requirements=URL_NAME_REQUIREMENTS)
696 rmap.connect('changeset_parents', '/{repo_name}/changeset_parents/{revision}',
692 rmap.connect('changeset_parents', '/{repo_name}/changeset_parents/{revision}',
697 controller='changeset', revision='tip', action='changeset_parents',
693 controller='changeset', revision='tip', action='changeset_parents',
698 conditions={'function': check_repo},
694 conditions={'function': check_repo},
699 requirements=URL_NAME_REQUIREMENTS)
695 requirements=URL_NAME_REQUIREMENTS)
700
696
701 # repo edit options
697 # repo edit options
702 rmap.connect('edit_repo', '/{repo_name}/settings', jsroute=True,
698 rmap.connect('edit_repo', '/{repo_name}/settings', jsroute=True,
703 controller='admin/repos', action='edit',
699 controller='admin/repos', action='edit',
704 conditions={'method': ['GET'], 'function': check_repo},
700 conditions={'method': ['GET'], 'function': check_repo},
705 requirements=URL_NAME_REQUIREMENTS)
701 requirements=URL_NAME_REQUIREMENTS)
706
702
707 rmap.connect('edit_repo_perms', '/{repo_name}/settings/permissions',
703 rmap.connect('edit_repo_perms', '/{repo_name}/settings/permissions',
708 jsroute=True,
704 jsroute=True,
709 controller='admin/repos', action='edit_permissions',
705 controller='admin/repos', action='edit_permissions',
710 conditions={'method': ['GET'], 'function': check_repo},
706 conditions={'method': ['GET'], 'function': check_repo},
711 requirements=URL_NAME_REQUIREMENTS)
707 requirements=URL_NAME_REQUIREMENTS)
712 rmap.connect('edit_repo_perms_update', '/{repo_name}/settings/permissions',
708 rmap.connect('edit_repo_perms_update', '/{repo_name}/settings/permissions',
713 controller='admin/repos', action='edit_permissions_update',
709 controller='admin/repos', action='edit_permissions_update',
714 conditions={'method': ['PUT'], 'function': check_repo},
710 conditions={'method': ['PUT'], 'function': check_repo},
715 requirements=URL_NAME_REQUIREMENTS)
711 requirements=URL_NAME_REQUIREMENTS)
716
712
717 rmap.connect('edit_repo_fields', '/{repo_name}/settings/fields',
713 rmap.connect('edit_repo_fields', '/{repo_name}/settings/fields',
718 controller='admin/repos', action='edit_fields',
714 controller='admin/repos', action='edit_fields',
719 conditions={'method': ['GET'], 'function': check_repo},
715 conditions={'method': ['GET'], 'function': check_repo},
720 requirements=URL_NAME_REQUIREMENTS)
716 requirements=URL_NAME_REQUIREMENTS)
721 rmap.connect('create_repo_fields', '/{repo_name}/settings/fields/new',
717 rmap.connect('create_repo_fields', '/{repo_name}/settings/fields/new',
722 controller='admin/repos', action='create_repo_field',
718 controller='admin/repos', action='create_repo_field',
723 conditions={'method': ['PUT'], 'function': check_repo},
719 conditions={'method': ['PUT'], 'function': check_repo},
724 requirements=URL_NAME_REQUIREMENTS)
720 requirements=URL_NAME_REQUIREMENTS)
725 rmap.connect('delete_repo_fields', '/{repo_name}/settings/fields/{field_id}',
721 rmap.connect('delete_repo_fields', '/{repo_name}/settings/fields/{field_id}',
726 controller='admin/repos', action='delete_repo_field',
722 controller='admin/repos', action='delete_repo_field',
727 conditions={'method': ['DELETE'], 'function': check_repo},
723 conditions={'method': ['DELETE'], 'function': check_repo},
728 requirements=URL_NAME_REQUIREMENTS)
724 requirements=URL_NAME_REQUIREMENTS)
729
725
730 rmap.connect('edit_repo_advanced', '/{repo_name}/settings/advanced',
726 rmap.connect('edit_repo_advanced', '/{repo_name}/settings/advanced',
731 controller='admin/repos', action='edit_advanced',
727 controller='admin/repos', action='edit_advanced',
732 conditions={'method': ['GET'], 'function': check_repo},
728 conditions={'method': ['GET'], 'function': check_repo},
733 requirements=URL_NAME_REQUIREMENTS)
729 requirements=URL_NAME_REQUIREMENTS)
734
730
735 rmap.connect('edit_repo_advanced_locking', '/{repo_name}/settings/advanced/locking',
731 rmap.connect('edit_repo_advanced_locking', '/{repo_name}/settings/advanced/locking',
736 controller='admin/repos', action='edit_advanced_locking',
732 controller='admin/repos', action='edit_advanced_locking',
737 conditions={'method': ['PUT'], 'function': check_repo},
733 conditions={'method': ['PUT'], 'function': check_repo},
738 requirements=URL_NAME_REQUIREMENTS)
734 requirements=URL_NAME_REQUIREMENTS)
739 rmap.connect('toggle_locking', '/{repo_name}/settings/advanced/locking_toggle',
735 rmap.connect('toggle_locking', '/{repo_name}/settings/advanced/locking_toggle',
740 controller='admin/repos', action='toggle_locking',
736 controller='admin/repos', action='toggle_locking',
741 conditions={'method': ['GET'], 'function': check_repo},
737 conditions={'method': ['GET'], 'function': check_repo},
742 requirements=URL_NAME_REQUIREMENTS)
738 requirements=URL_NAME_REQUIREMENTS)
743
739
744 rmap.connect('edit_repo_advanced_journal', '/{repo_name}/settings/advanced/journal',
740 rmap.connect('edit_repo_advanced_journal', '/{repo_name}/settings/advanced/journal',
745 controller='admin/repos', action='edit_advanced_journal',
741 controller='admin/repos', action='edit_advanced_journal',
746 conditions={'method': ['PUT'], 'function': check_repo},
742 conditions={'method': ['PUT'], 'function': check_repo},
747 requirements=URL_NAME_REQUIREMENTS)
743 requirements=URL_NAME_REQUIREMENTS)
748
744
749 rmap.connect('edit_repo_advanced_fork', '/{repo_name}/settings/advanced/fork',
745 rmap.connect('edit_repo_advanced_fork', '/{repo_name}/settings/advanced/fork',
750 controller='admin/repos', action='edit_advanced_fork',
746 controller='admin/repos', action='edit_advanced_fork',
751 conditions={'method': ['PUT'], 'function': check_repo},
747 conditions={'method': ['PUT'], 'function': check_repo},
752 requirements=URL_NAME_REQUIREMENTS)
748 requirements=URL_NAME_REQUIREMENTS)
753
749
754 rmap.connect('edit_repo_caches', '/{repo_name}/settings/caches',
750 rmap.connect('edit_repo_caches', '/{repo_name}/settings/caches',
755 controller='admin/repos', action='edit_caches_form',
751 controller='admin/repos', action='edit_caches_form',
756 conditions={'method': ['GET'], 'function': check_repo},
752 conditions={'method': ['GET'], 'function': check_repo},
757 requirements=URL_NAME_REQUIREMENTS)
753 requirements=URL_NAME_REQUIREMENTS)
758 rmap.connect('edit_repo_caches', '/{repo_name}/settings/caches',
754 rmap.connect('edit_repo_caches', '/{repo_name}/settings/caches',
759 controller='admin/repos', action='edit_caches',
755 controller='admin/repos', action='edit_caches',
760 conditions={'method': ['PUT'], 'function': check_repo},
756 conditions={'method': ['PUT'], 'function': check_repo},
761 requirements=URL_NAME_REQUIREMENTS)
757 requirements=URL_NAME_REQUIREMENTS)
762
758
763 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
759 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
764 controller='admin/repos', action='edit_remote_form',
760 controller='admin/repos', action='edit_remote_form',
765 conditions={'method': ['GET'], 'function': check_repo},
761 conditions={'method': ['GET'], 'function': check_repo},
766 requirements=URL_NAME_REQUIREMENTS)
762 requirements=URL_NAME_REQUIREMENTS)
767 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
763 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
768 controller='admin/repos', action='edit_remote',
764 controller='admin/repos', action='edit_remote',
769 conditions={'method': ['PUT'], 'function': check_repo},
765 conditions={'method': ['PUT'], 'function': check_repo},
770 requirements=URL_NAME_REQUIREMENTS)
766 requirements=URL_NAME_REQUIREMENTS)
771
767
772 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
768 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
773 controller='admin/repos', action='edit_statistics_form',
769 controller='admin/repos', action='edit_statistics_form',
774 conditions={'method': ['GET'], 'function': check_repo},
770 conditions={'method': ['GET'], 'function': check_repo},
775 requirements=URL_NAME_REQUIREMENTS)
771 requirements=URL_NAME_REQUIREMENTS)
776 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
772 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
777 controller='admin/repos', action='edit_statistics',
773 controller='admin/repos', action='edit_statistics',
778 conditions={'method': ['PUT'], 'function': check_repo},
774 conditions={'method': ['PUT'], 'function': check_repo},
779 requirements=URL_NAME_REQUIREMENTS)
775 requirements=URL_NAME_REQUIREMENTS)
780 rmap.connect('repo_settings_issuetracker',
776 rmap.connect('repo_settings_issuetracker',
781 '/{repo_name}/settings/issue-tracker',
777 '/{repo_name}/settings/issue-tracker',
782 controller='admin/repos', action='repo_issuetracker',
778 controller='admin/repos', action='repo_issuetracker',
783 conditions={'method': ['GET'], 'function': check_repo},
779 conditions={'method': ['GET'], 'function': check_repo},
784 requirements=URL_NAME_REQUIREMENTS)
780 requirements=URL_NAME_REQUIREMENTS)
785 rmap.connect('repo_issuetracker_test',
781 rmap.connect('repo_issuetracker_test',
786 '/{repo_name}/settings/issue-tracker/test',
782 '/{repo_name}/settings/issue-tracker/test',
787 controller='admin/repos', action='repo_issuetracker_test',
783 controller='admin/repos', action='repo_issuetracker_test',
788 conditions={'method': ['POST'], 'function': check_repo},
784 conditions={'method': ['POST'], 'function': check_repo},
789 requirements=URL_NAME_REQUIREMENTS)
785 requirements=URL_NAME_REQUIREMENTS)
790 rmap.connect('repo_issuetracker_delete',
786 rmap.connect('repo_issuetracker_delete',
791 '/{repo_name}/settings/issue-tracker/delete',
787 '/{repo_name}/settings/issue-tracker/delete',
792 controller='admin/repos', action='repo_issuetracker_delete',
788 controller='admin/repos', action='repo_issuetracker_delete',
793 conditions={'method': ['DELETE'], 'function': check_repo},
789 conditions={'method': ['DELETE'], 'function': check_repo},
794 requirements=URL_NAME_REQUIREMENTS)
790 requirements=URL_NAME_REQUIREMENTS)
795 rmap.connect('repo_issuetracker_save',
791 rmap.connect('repo_issuetracker_save',
796 '/{repo_name}/settings/issue-tracker/save',
792 '/{repo_name}/settings/issue-tracker/save',
797 controller='admin/repos', action='repo_issuetracker_save',
793 controller='admin/repos', action='repo_issuetracker_save',
798 conditions={'method': ['POST'], 'function': check_repo},
794 conditions={'method': ['POST'], 'function': check_repo},
799 requirements=URL_NAME_REQUIREMENTS)
795 requirements=URL_NAME_REQUIREMENTS)
800 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
796 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
801 controller='admin/repos', action='repo_settings_vcs_update',
797 controller='admin/repos', action='repo_settings_vcs_update',
802 conditions={'method': ['POST'], 'function': check_repo},
798 conditions={'method': ['POST'], 'function': check_repo},
803 requirements=URL_NAME_REQUIREMENTS)
799 requirements=URL_NAME_REQUIREMENTS)
804 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
800 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
805 controller='admin/repos', action='repo_settings_vcs',
801 controller='admin/repos', action='repo_settings_vcs',
806 conditions={'method': ['GET'], 'function': check_repo},
802 conditions={'method': ['GET'], 'function': check_repo},
807 requirements=URL_NAME_REQUIREMENTS)
803 requirements=URL_NAME_REQUIREMENTS)
808 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
804 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
809 controller='admin/repos', action='repo_delete_svn_pattern',
805 controller='admin/repos', action='repo_delete_svn_pattern',
810 conditions={'method': ['DELETE'], 'function': check_repo},
806 conditions={'method': ['DELETE'], 'function': check_repo},
811 requirements=URL_NAME_REQUIREMENTS)
807 requirements=URL_NAME_REQUIREMENTS)
812
808
813 # still working url for backward compat.
809 # still working url for backward compat.
814 rmap.connect('raw_changeset_home_depraced',
810 rmap.connect('raw_changeset_home_depraced',
815 '/{repo_name}/raw-changeset/{revision}',
811 '/{repo_name}/raw-changeset/{revision}',
816 controller='changeset', action='changeset_raw',
812 controller='changeset', action='changeset_raw',
817 revision='tip', conditions={'function': check_repo},
813 revision='tip', conditions={'function': check_repo},
818 requirements=URL_NAME_REQUIREMENTS)
814 requirements=URL_NAME_REQUIREMENTS)
819
815
820 # new URLs
816 # new URLs
821 rmap.connect('changeset_raw_home',
817 rmap.connect('changeset_raw_home',
822 '/{repo_name}/changeset-diff/{revision}',
818 '/{repo_name}/changeset-diff/{revision}',
823 controller='changeset', action='changeset_raw',
819 controller='changeset', action='changeset_raw',
824 revision='tip', conditions={'function': check_repo},
820 revision='tip', conditions={'function': check_repo},
825 requirements=URL_NAME_REQUIREMENTS)
821 requirements=URL_NAME_REQUIREMENTS)
826
822
827 rmap.connect('changeset_patch_home',
823 rmap.connect('changeset_patch_home',
828 '/{repo_name}/changeset-patch/{revision}',
824 '/{repo_name}/changeset-patch/{revision}',
829 controller='changeset', action='changeset_patch',
825 controller='changeset', action='changeset_patch',
830 revision='tip', conditions={'function': check_repo},
826 revision='tip', conditions={'function': check_repo},
831 requirements=URL_NAME_REQUIREMENTS)
827 requirements=URL_NAME_REQUIREMENTS)
832
828
833 rmap.connect('changeset_download_home',
829 rmap.connect('changeset_download_home',
834 '/{repo_name}/changeset-download/{revision}',
830 '/{repo_name}/changeset-download/{revision}',
835 controller='changeset', action='changeset_download',
831 controller='changeset', action='changeset_download',
836 revision='tip', conditions={'function': check_repo},
832 revision='tip', conditions={'function': check_repo},
837 requirements=URL_NAME_REQUIREMENTS)
833 requirements=URL_NAME_REQUIREMENTS)
838
834
839 rmap.connect('changeset_comment',
835 rmap.connect('changeset_comment',
840 '/{repo_name}/changeset/{revision}/comment', jsroute=True,
836 '/{repo_name}/changeset/{revision}/comment', jsroute=True,
841 controller='changeset', revision='tip', action='comment',
837 controller='changeset', revision='tip', action='comment',
842 conditions={'function': check_repo},
838 conditions={'function': check_repo},
843 requirements=URL_NAME_REQUIREMENTS)
839 requirements=URL_NAME_REQUIREMENTS)
844
840
845 rmap.connect('changeset_comment_preview',
841 rmap.connect('changeset_comment_preview',
846 '/{repo_name}/changeset/comment/preview', jsroute=True,
842 '/{repo_name}/changeset/comment/preview', jsroute=True,
847 controller='changeset', action='preview_comment',
843 controller='changeset', action='preview_comment',
848 conditions={'function': check_repo, 'method': ['POST']},
844 conditions={'function': check_repo, 'method': ['POST']},
849 requirements=URL_NAME_REQUIREMENTS)
845 requirements=URL_NAME_REQUIREMENTS)
850
846
851 rmap.connect('changeset_comment_delete',
847 rmap.connect('changeset_comment_delete',
852 '/{repo_name}/changeset/comment/{comment_id}/delete',
848 '/{repo_name}/changeset/comment/{comment_id}/delete',
853 controller='changeset', action='delete_comment',
849 controller='changeset', action='delete_comment',
854 conditions={'function': check_repo, 'method': ['DELETE']},
850 conditions={'function': check_repo, 'method': ['DELETE']},
855 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
851 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
856
852
857 rmap.connect('changeset_info', '/changeset_info/{repo_name}/{revision}',
853 rmap.connect('changeset_info', '/changeset_info/{repo_name}/{revision}',
858 controller='changeset', action='changeset_info',
854 controller='changeset', action='changeset_info',
859 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
855 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
860
856
861 rmap.connect('compare_home',
857 rmap.connect('compare_home',
862 '/{repo_name}/compare',
858 '/{repo_name}/compare',
863 controller='compare', action='index',
859 controller='compare', action='index',
864 conditions={'function': check_repo},
860 conditions={'function': check_repo},
865 requirements=URL_NAME_REQUIREMENTS)
861 requirements=URL_NAME_REQUIREMENTS)
866
862
867 rmap.connect('compare_url',
863 rmap.connect('compare_url',
868 '/{repo_name}/compare/{source_ref_type}@{source_ref:.*?}...{target_ref_type}@{target_ref:.*?}',
864 '/{repo_name}/compare/{source_ref_type}@{source_ref:.*?}...{target_ref_type}@{target_ref:.*?}',
869 controller='compare', action='compare',
865 controller='compare', action='compare',
870 conditions={'function': check_repo},
866 conditions={'function': check_repo},
871 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
867 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
872
868
873 rmap.connect('pullrequest_home',
869 rmap.connect('pullrequest_home',
874 '/{repo_name}/pull-request/new', controller='pullrequests',
870 '/{repo_name}/pull-request/new', controller='pullrequests',
875 action='index', conditions={'function': check_repo,
871 action='index', conditions={'function': check_repo,
876 'method': ['GET']},
872 'method': ['GET']},
877 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
873 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
878
874
879 rmap.connect('pullrequest',
875 rmap.connect('pullrequest',
880 '/{repo_name}/pull-request/new', controller='pullrequests',
876 '/{repo_name}/pull-request/new', controller='pullrequests',
881 action='create', conditions={'function': check_repo,
877 action='create', conditions={'function': check_repo,
882 'method': ['POST']},
878 'method': ['POST']},
883 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
879 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
884
880
885 rmap.connect('pullrequest_repo_refs',
881 rmap.connect('pullrequest_repo_refs',
886 '/{repo_name}/pull-request/refs/{target_repo_name:.*?[^/]}',
882 '/{repo_name}/pull-request/refs/{target_repo_name:.*?[^/]}',
887 controller='pullrequests',
883 controller='pullrequests',
888 action='get_repo_refs',
884 action='get_repo_refs',
889 conditions={'function': check_repo, 'method': ['GET']},
885 conditions={'function': check_repo, 'method': ['GET']},
890 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
886 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
891
887
892 rmap.connect('pullrequest_repo_destinations',
888 rmap.connect('pullrequest_repo_destinations',
893 '/{repo_name}/pull-request/repo-destinations',
889 '/{repo_name}/pull-request/repo-destinations',
894 controller='pullrequests',
890 controller='pullrequests',
895 action='get_repo_destinations',
891 action='get_repo_destinations',
896 conditions={'function': check_repo, 'method': ['GET']},
892 conditions={'function': check_repo, 'method': ['GET']},
897 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
893 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
898
894
899 rmap.connect('pullrequest_show',
895 rmap.connect('pullrequest_show',
900 '/{repo_name}/pull-request/{pull_request_id}',
896 '/{repo_name}/pull-request/{pull_request_id}',
901 controller='pullrequests',
897 controller='pullrequests',
902 action='show', conditions={'function': check_repo,
898 action='show', conditions={'function': check_repo,
903 'method': ['GET']},
899 'method': ['GET']},
904 requirements=URL_NAME_REQUIREMENTS)
900 requirements=URL_NAME_REQUIREMENTS)
905
901
906 rmap.connect('pullrequest_update',
902 rmap.connect('pullrequest_update',
907 '/{repo_name}/pull-request/{pull_request_id}',
903 '/{repo_name}/pull-request/{pull_request_id}',
908 controller='pullrequests',
904 controller='pullrequests',
909 action='update', conditions={'function': check_repo,
905 action='update', conditions={'function': check_repo,
910 'method': ['PUT']},
906 'method': ['PUT']},
911 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
907 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
912
908
913 rmap.connect('pullrequest_merge',
909 rmap.connect('pullrequest_merge',
914 '/{repo_name}/pull-request/{pull_request_id}',
910 '/{repo_name}/pull-request/{pull_request_id}',
915 controller='pullrequests',
911 controller='pullrequests',
916 action='merge', conditions={'function': check_repo,
912 action='merge', conditions={'function': check_repo,
917 'method': ['POST']},
913 'method': ['POST']},
918 requirements=URL_NAME_REQUIREMENTS)
914 requirements=URL_NAME_REQUIREMENTS)
919
915
920 rmap.connect('pullrequest_delete',
916 rmap.connect('pullrequest_delete',
921 '/{repo_name}/pull-request/{pull_request_id}',
917 '/{repo_name}/pull-request/{pull_request_id}',
922 controller='pullrequests',
918 controller='pullrequests',
923 action='delete', conditions={'function': check_repo,
919 action='delete', conditions={'function': check_repo,
924 'method': ['DELETE']},
920 'method': ['DELETE']},
925 requirements=URL_NAME_REQUIREMENTS)
921 requirements=URL_NAME_REQUIREMENTS)
926
922
927 rmap.connect('pullrequest_show_all',
923 rmap.connect('pullrequest_show_all',
928 '/{repo_name}/pull-request',
924 '/{repo_name}/pull-request',
929 controller='pullrequests',
925 controller='pullrequests',
930 action='show_all', conditions={'function': check_repo,
926 action='show_all', conditions={'function': check_repo,
931 'method': ['GET']},
927 'method': ['GET']},
932 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
928 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
933
929
934 rmap.connect('pullrequest_comment',
930 rmap.connect('pullrequest_comment',
935 '/{repo_name}/pull-request-comment/{pull_request_id}',
931 '/{repo_name}/pull-request-comment/{pull_request_id}',
936 controller='pullrequests',
932 controller='pullrequests',
937 action='comment', conditions={'function': check_repo,
933 action='comment', conditions={'function': check_repo,
938 'method': ['POST']},
934 'method': ['POST']},
939 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
935 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
940
936
941 rmap.connect('pullrequest_comment_delete',
937 rmap.connect('pullrequest_comment_delete',
942 '/{repo_name}/pull-request-comment/{comment_id}/delete',
938 '/{repo_name}/pull-request-comment/{comment_id}/delete',
943 controller='pullrequests', action='delete_comment',
939 controller='pullrequests', action='delete_comment',
944 conditions={'function': check_repo, 'method': ['DELETE']},
940 conditions={'function': check_repo, 'method': ['DELETE']},
945 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
941 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
946
942
947 rmap.connect('summary_home_explicit', '/{repo_name}/summary',
943 rmap.connect('summary_home_explicit', '/{repo_name}/summary',
948 controller='summary', conditions={'function': check_repo},
944 controller='summary', conditions={'function': check_repo},
949 requirements=URL_NAME_REQUIREMENTS)
945 requirements=URL_NAME_REQUIREMENTS)
950
946
951 rmap.connect('branches_home', '/{repo_name}/branches',
947 rmap.connect('branches_home', '/{repo_name}/branches',
952 controller='branches', conditions={'function': check_repo},
948 controller='branches', conditions={'function': check_repo},
953 requirements=URL_NAME_REQUIREMENTS)
949 requirements=URL_NAME_REQUIREMENTS)
954
950
955 rmap.connect('tags_home', '/{repo_name}/tags',
951 rmap.connect('tags_home', '/{repo_name}/tags',
956 controller='tags', conditions={'function': check_repo},
952 controller='tags', conditions={'function': check_repo},
957 requirements=URL_NAME_REQUIREMENTS)
953 requirements=URL_NAME_REQUIREMENTS)
958
954
959 rmap.connect('bookmarks_home', '/{repo_name}/bookmarks',
955 rmap.connect('bookmarks_home', '/{repo_name}/bookmarks',
960 controller='bookmarks', conditions={'function': check_repo},
956 controller='bookmarks', conditions={'function': check_repo},
961 requirements=URL_NAME_REQUIREMENTS)
957 requirements=URL_NAME_REQUIREMENTS)
962
958
963 rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
959 rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
964 controller='changelog', conditions={'function': check_repo},
960 controller='changelog', conditions={'function': check_repo},
965 requirements=URL_NAME_REQUIREMENTS)
961 requirements=URL_NAME_REQUIREMENTS)
966
962
967 rmap.connect('changelog_summary_home', '/{repo_name}/changelog_summary',
963 rmap.connect('changelog_summary_home', '/{repo_name}/changelog_summary',
968 controller='changelog', action='changelog_summary',
964 controller='changelog', action='changelog_summary',
969 conditions={'function': check_repo},
965 conditions={'function': check_repo},
970 requirements=URL_NAME_REQUIREMENTS)
966 requirements=URL_NAME_REQUIREMENTS)
971
967
972 rmap.connect('changelog_file_home',
968 rmap.connect('changelog_file_home',
973 '/{repo_name}/changelog/{revision}/{f_path}',
969 '/{repo_name}/changelog/{revision}/{f_path}',
974 controller='changelog', f_path=None,
970 controller='changelog', f_path=None,
975 conditions={'function': check_repo},
971 conditions={'function': check_repo},
976 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
972 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
977
973
978 rmap.connect('changelog_details', '/{repo_name}/changelog_details/{cs}',
974 rmap.connect('changelog_details', '/{repo_name}/changelog_details/{cs}',
979 controller='changelog', action='changelog_details',
975 controller='changelog', action='changelog_details',
980 conditions={'function': check_repo},
976 conditions={'function': check_repo},
981 requirements=URL_NAME_REQUIREMENTS)
977 requirements=URL_NAME_REQUIREMENTS)
982
978
983 rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}',
979 rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}',
984 controller='files', revision='tip', f_path='',
980 controller='files', revision='tip', f_path='',
985 conditions={'function': check_repo},
981 conditions={'function': check_repo},
986 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
982 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
987
983
988 rmap.connect('files_home_simple_catchrev',
984 rmap.connect('files_home_simple_catchrev',
989 '/{repo_name}/files/{revision}',
985 '/{repo_name}/files/{revision}',
990 controller='files', revision='tip', f_path='',
986 controller='files', revision='tip', f_path='',
991 conditions={'function': check_repo},
987 conditions={'function': check_repo},
992 requirements=URL_NAME_REQUIREMENTS)
988 requirements=URL_NAME_REQUIREMENTS)
993
989
994 rmap.connect('files_home_simple_catchall',
990 rmap.connect('files_home_simple_catchall',
995 '/{repo_name}/files',
991 '/{repo_name}/files',
996 controller='files', revision='tip', f_path='',
992 controller='files', revision='tip', f_path='',
997 conditions={'function': check_repo},
993 conditions={'function': check_repo},
998 requirements=URL_NAME_REQUIREMENTS)
994 requirements=URL_NAME_REQUIREMENTS)
999
995
1000 rmap.connect('files_history_home',
996 rmap.connect('files_history_home',
1001 '/{repo_name}/history/{revision}/{f_path}',
997 '/{repo_name}/history/{revision}/{f_path}',
1002 controller='files', action='history', revision='tip', f_path='',
998 controller='files', action='history', revision='tip', f_path='',
1003 conditions={'function': check_repo},
999 conditions={'function': check_repo},
1004 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1000 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1005
1001
1006 rmap.connect('files_authors_home',
1002 rmap.connect('files_authors_home',
1007 '/{repo_name}/authors/{revision}/{f_path}',
1003 '/{repo_name}/authors/{revision}/{f_path}',
1008 controller='files', action='authors', revision='tip', f_path='',
1004 controller='files', action='authors', revision='tip', f_path='',
1009 conditions={'function': check_repo},
1005 conditions={'function': check_repo},
1010 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1006 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1011
1007
1012 rmap.connect('files_diff_home', '/{repo_name}/diff/{f_path}',
1008 rmap.connect('files_diff_home', '/{repo_name}/diff/{f_path}',
1013 controller='files', action='diff', f_path='',
1009 controller='files', action='diff', f_path='',
1014 conditions={'function': check_repo},
1010 conditions={'function': check_repo},
1015 requirements=URL_NAME_REQUIREMENTS)
1011 requirements=URL_NAME_REQUIREMENTS)
1016
1012
1017 rmap.connect('files_diff_2way_home',
1013 rmap.connect('files_diff_2way_home',
1018 '/{repo_name}/diff-2way/{f_path}',
1014 '/{repo_name}/diff-2way/{f_path}',
1019 controller='files', action='diff_2way', f_path='',
1015 controller='files', action='diff_2way', f_path='',
1020 conditions={'function': check_repo},
1016 conditions={'function': check_repo},
1021 requirements=URL_NAME_REQUIREMENTS)
1017 requirements=URL_NAME_REQUIREMENTS)
1022
1018
1023 rmap.connect('files_rawfile_home',
1019 rmap.connect('files_rawfile_home',
1024 '/{repo_name}/rawfile/{revision}/{f_path}',
1020 '/{repo_name}/rawfile/{revision}/{f_path}',
1025 controller='files', action='rawfile', revision='tip',
1021 controller='files', action='rawfile', revision='tip',
1026 f_path='', conditions={'function': check_repo},
1022 f_path='', conditions={'function': check_repo},
1027 requirements=URL_NAME_REQUIREMENTS)
1023 requirements=URL_NAME_REQUIREMENTS)
1028
1024
1029 rmap.connect('files_raw_home',
1025 rmap.connect('files_raw_home',
1030 '/{repo_name}/raw/{revision}/{f_path}',
1026 '/{repo_name}/raw/{revision}/{f_path}',
1031 controller='files', action='raw', revision='tip', f_path='',
1027 controller='files', action='raw', revision='tip', f_path='',
1032 conditions={'function': check_repo},
1028 conditions={'function': check_repo},
1033 requirements=URL_NAME_REQUIREMENTS)
1029 requirements=URL_NAME_REQUIREMENTS)
1034
1030
1035 rmap.connect('files_render_home',
1031 rmap.connect('files_render_home',
1036 '/{repo_name}/render/{revision}/{f_path}',
1032 '/{repo_name}/render/{revision}/{f_path}',
1037 controller='files', action='index', revision='tip', f_path='',
1033 controller='files', action='index', revision='tip', f_path='',
1038 rendered=True, conditions={'function': check_repo},
1034 rendered=True, conditions={'function': check_repo},
1039 requirements=URL_NAME_REQUIREMENTS)
1035 requirements=URL_NAME_REQUIREMENTS)
1040
1036
1041 rmap.connect('files_annotate_home',
1037 rmap.connect('files_annotate_home',
1042 '/{repo_name}/annotate/{revision}/{f_path}',
1038 '/{repo_name}/annotate/{revision}/{f_path}',
1043 controller='files', action='index', revision='tip',
1039 controller='files', action='index', revision='tip',
1044 f_path='', annotate=True, conditions={'function': check_repo},
1040 f_path='', annotate=True, conditions={'function': check_repo},
1045 requirements=URL_NAME_REQUIREMENTS)
1041 requirements=URL_NAME_REQUIREMENTS)
1046
1042
1047 rmap.connect('files_edit',
1043 rmap.connect('files_edit',
1048 '/{repo_name}/edit/{revision}/{f_path}',
1044 '/{repo_name}/edit/{revision}/{f_path}',
1049 controller='files', action='edit', revision='tip',
1045 controller='files', action='edit', revision='tip',
1050 f_path='',
1046 f_path='',
1051 conditions={'function': check_repo, 'method': ['POST']},
1047 conditions={'function': check_repo, 'method': ['POST']},
1052 requirements=URL_NAME_REQUIREMENTS)
1048 requirements=URL_NAME_REQUIREMENTS)
1053
1049
1054 rmap.connect('files_edit_home',
1050 rmap.connect('files_edit_home',
1055 '/{repo_name}/edit/{revision}/{f_path}',
1051 '/{repo_name}/edit/{revision}/{f_path}',
1056 controller='files', action='edit_home', revision='tip',
1052 controller='files', action='edit_home', revision='tip',
1057 f_path='', conditions={'function': check_repo},
1053 f_path='', conditions={'function': check_repo},
1058 requirements=URL_NAME_REQUIREMENTS)
1054 requirements=URL_NAME_REQUIREMENTS)
1059
1055
1060 rmap.connect('files_add',
1056 rmap.connect('files_add',
1061 '/{repo_name}/add/{revision}/{f_path}',
1057 '/{repo_name}/add/{revision}/{f_path}',
1062 controller='files', action='add', revision='tip',
1058 controller='files', action='add', revision='tip',
1063 f_path='',
1059 f_path='',
1064 conditions={'function': check_repo, 'method': ['POST']},
1060 conditions={'function': check_repo, 'method': ['POST']},
1065 requirements=URL_NAME_REQUIREMENTS)
1061 requirements=URL_NAME_REQUIREMENTS)
1066
1062
1067 rmap.connect('files_add_home',
1063 rmap.connect('files_add_home',
1068 '/{repo_name}/add/{revision}/{f_path}',
1064 '/{repo_name}/add/{revision}/{f_path}',
1069 controller='files', action='add_home', revision='tip',
1065 controller='files', action='add_home', revision='tip',
1070 f_path='', conditions={'function': check_repo},
1066 f_path='', conditions={'function': check_repo},
1071 requirements=URL_NAME_REQUIREMENTS)
1067 requirements=URL_NAME_REQUIREMENTS)
1072
1068
1073 rmap.connect('files_delete',
1069 rmap.connect('files_delete',
1074 '/{repo_name}/delete/{revision}/{f_path}',
1070 '/{repo_name}/delete/{revision}/{f_path}',
1075 controller='files', action='delete', revision='tip',
1071 controller='files', action='delete', revision='tip',
1076 f_path='',
1072 f_path='',
1077 conditions={'function': check_repo, 'method': ['POST']},
1073 conditions={'function': check_repo, 'method': ['POST']},
1078 requirements=URL_NAME_REQUIREMENTS)
1074 requirements=URL_NAME_REQUIREMENTS)
1079
1075
1080 rmap.connect('files_delete_home',
1076 rmap.connect('files_delete_home',
1081 '/{repo_name}/delete/{revision}/{f_path}',
1077 '/{repo_name}/delete/{revision}/{f_path}',
1082 controller='files', action='delete_home', revision='tip',
1078 controller='files', action='delete_home', revision='tip',
1083 f_path='', conditions={'function': check_repo},
1079 f_path='', conditions={'function': check_repo},
1084 requirements=URL_NAME_REQUIREMENTS)
1080 requirements=URL_NAME_REQUIREMENTS)
1085
1081
1086 rmap.connect('files_archive_home', '/{repo_name}/archive/{fname}',
1082 rmap.connect('files_archive_home', '/{repo_name}/archive/{fname}',
1087 controller='files', action='archivefile',
1083 controller='files', action='archivefile',
1088 conditions={'function': check_repo},
1084 conditions={'function': check_repo},
1089 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1085 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1090
1086
1091 rmap.connect('files_nodelist_home',
1087 rmap.connect('files_nodelist_home',
1092 '/{repo_name}/nodelist/{revision}/{f_path}',
1088 '/{repo_name}/nodelist/{revision}/{f_path}',
1093 controller='files', action='nodelist',
1089 controller='files', action='nodelist',
1094 conditions={'function': check_repo},
1090 conditions={'function': check_repo},
1095 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1091 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1096
1092
1097 rmap.connect('files_metadata_list_home',
1093 rmap.connect('files_metadata_list_home',
1098 '/{repo_name}/metadata_list/{revision}/{f_path}',
1094 '/{repo_name}/metadata_list/{revision}/{f_path}',
1099 controller='files', action='metadata_list',
1095 controller='files', action='metadata_list',
1100 conditions={'function': check_repo},
1096 conditions={'function': check_repo},
1101 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1097 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1102
1098
1103 rmap.connect('repo_fork_create_home', '/{repo_name}/fork',
1099 rmap.connect('repo_fork_create_home', '/{repo_name}/fork',
1104 controller='forks', action='fork_create',
1100 controller='forks', action='fork_create',
1105 conditions={'function': check_repo, 'method': ['POST']},
1101 conditions={'function': check_repo, 'method': ['POST']},
1106 requirements=URL_NAME_REQUIREMENTS)
1102 requirements=URL_NAME_REQUIREMENTS)
1107
1103
1108 rmap.connect('repo_fork_home', '/{repo_name}/fork',
1104 rmap.connect('repo_fork_home', '/{repo_name}/fork',
1109 controller='forks', action='fork',
1105 controller='forks', action='fork',
1110 conditions={'function': check_repo},
1106 conditions={'function': check_repo},
1111 requirements=URL_NAME_REQUIREMENTS)
1107 requirements=URL_NAME_REQUIREMENTS)
1112
1108
1113 rmap.connect('repo_forks_home', '/{repo_name}/forks',
1109 rmap.connect('repo_forks_home', '/{repo_name}/forks',
1114 controller='forks', action='forks',
1110 controller='forks', action='forks',
1115 conditions={'function': check_repo},
1111 conditions={'function': check_repo},
1116 requirements=URL_NAME_REQUIREMENTS)
1112 requirements=URL_NAME_REQUIREMENTS)
1117
1113
1118 rmap.connect('repo_followers_home', '/{repo_name}/followers',
1114 rmap.connect('repo_followers_home', '/{repo_name}/followers',
1119 controller='followers', action='followers',
1115 controller='followers', action='followers',
1120 conditions={'function': check_repo},
1116 conditions={'function': check_repo},
1121 requirements=URL_NAME_REQUIREMENTS)
1117 requirements=URL_NAME_REQUIREMENTS)
1122
1118
1123 # must be here for proper group/repo catching pattern
1119 # must be here for proper group/repo catching pattern
1124 _connect_with_slash(
1120 _connect_with_slash(
1125 rmap, 'repo_group_home', '/{group_name}',
1121 rmap, 'repo_group_home', '/{group_name}',
1126 controller='home', action='index_repo_group',
1122 controller='home', action='index_repo_group',
1127 conditions={'function': check_group},
1123 conditions={'function': check_group},
1128 requirements=URL_NAME_REQUIREMENTS)
1124 requirements=URL_NAME_REQUIREMENTS)
1129
1125
1130 # catch all, at the end
1126 # catch all, at the end
1131 _connect_with_slash(
1127 _connect_with_slash(
1132 rmap, 'summary_home', '/{repo_name}', jsroute=True,
1128 rmap, 'summary_home', '/{repo_name}', jsroute=True,
1133 controller='summary', action='index',
1129 controller='summary', action='index',
1134 conditions={'function': check_repo},
1130 conditions={'function': check_repo},
1135 requirements=URL_NAME_REQUIREMENTS)
1131 requirements=URL_NAME_REQUIREMENTS)
1136
1132
1137 return rmap
1133 return rmap
1138
1134
1139
1135
1140 def _connect_with_slash(mapper, name, path, *args, **kwargs):
1136 def _connect_with_slash(mapper, name, path, *args, **kwargs):
1141 """
1137 """
1142 Connect a route with an optional trailing slash in `path`.
1138 Connect a route with an optional trailing slash in `path`.
1143 """
1139 """
1144 mapper.connect(name + '_slash', path + '/', *args, **kwargs)
1140 mapper.connect(name + '_slash', path + '/', *args, **kwargs)
1145 mapper.connect(name, path, *args, **kwargs)
1141 mapper.connect(name, path, *args, **kwargs)
@@ -1,866 +1,852 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 """
22 """
23 settings controller for rhodecode admin
23 settings controller for rhodecode admin
24 """
24 """
25
25
26 import collections
26 import collections
27 import logging
27 import logging
28 import urllib2
28 import urllib2
29
29
30 import datetime
30 import datetime
31 import formencode
31 import formencode
32 from formencode import htmlfill
32 from formencode import htmlfill
33 import packaging.version
33 import packaging.version
34 from pylons import request, tmpl_context as c, url, config
34 from pylons import request, tmpl_context as c, url, config
35 from pylons.controllers.util import redirect
35 from pylons.controllers.util import redirect
36 from pylons.i18n.translation import _, lazy_ugettext
36 from pylons.i18n.translation import _, lazy_ugettext
37 from webob.exc import HTTPBadRequest
37 from webob.exc import HTTPBadRequest
38
38
39 import rhodecode
39 import rhodecode
40 from rhodecode.lib import auth
40 from rhodecode.lib import auth
41 from rhodecode.lib import helpers as h
41 from rhodecode.lib import helpers as h
42 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
42 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
43 from rhodecode.lib.base import BaseController, render
43 from rhodecode.lib.base import BaseController, render
44 from rhodecode.lib.celerylib import tasks, run_task
44 from rhodecode.lib.celerylib import tasks, run_task
45 from rhodecode.lib.utils import repo2db_mapper
45 from rhodecode.lib.utils import repo2db_mapper
46 from rhodecode.lib.utils2 import (
46 from rhodecode.lib.utils2 import (
47 str2bool, safe_unicode, AttributeDict, safe_int)
47 str2bool, safe_unicode, AttributeDict, safe_int)
48 from rhodecode.lib.compat import OrderedDict
48 from rhodecode.lib.compat import OrderedDict
49 from rhodecode.lib.ext_json import json
49 from rhodecode.lib.ext_json import json
50 from rhodecode.lib.utils import jsonify, read_opensource_licenses
50 from rhodecode.lib.utils import jsonify
51
51
52 from rhodecode.model.db import RhodeCodeUi, Repository
52 from rhodecode.model.db import RhodeCodeUi, Repository
53 from rhodecode.model.forms import ApplicationSettingsForm, \
53 from rhodecode.model.forms import ApplicationSettingsForm, \
54 ApplicationUiSettingsForm, ApplicationVisualisationForm, \
54 ApplicationUiSettingsForm, ApplicationVisualisationForm, \
55 LabsSettingsForm, IssueTrackerPatternsForm
55 LabsSettingsForm, IssueTrackerPatternsForm
56
56
57 from rhodecode.model.scm import ScmModel
57 from rhodecode.model.scm import ScmModel
58 from rhodecode.model.notification import EmailNotificationModel
58 from rhodecode.model.notification import EmailNotificationModel
59 from rhodecode.model.meta import Session
59 from rhodecode.model.meta import Session
60 from rhodecode.model.settings import (
60 from rhodecode.model.settings import (
61 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
61 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
62 SettingsModel)
62 SettingsModel)
63 from rhodecode.model.supervisor import SupervisorModel, SUPERVISOR_MASTER
63 from rhodecode.model.supervisor import SupervisorModel, SUPERVISOR_MASTER
64 from rhodecode.model.user import UserModel
64
65
65
66 log = logging.getLogger(__name__)
66 log = logging.getLogger(__name__)
67
67
68
68
69 class SettingsController(BaseController):
69 class SettingsController(BaseController):
70 """REST Controller styled on the Atom Publishing Protocol"""
70 """REST Controller styled on the Atom Publishing Protocol"""
71 # To properly map this controller, ensure your config/routing.py
71 # To properly map this controller, ensure your config/routing.py
72 # file has a resource setup:
72 # file has a resource setup:
73 # map.resource('setting', 'settings', controller='admin/settings',
73 # map.resource('setting', 'settings', controller='admin/settings',
74 # path_prefix='/admin', name_prefix='admin_')
74 # path_prefix='/admin', name_prefix='admin_')
75
75
76 @LoginRequired()
76 @LoginRequired()
77 def __before__(self):
77 def __before__(self):
78 super(SettingsController, self).__before__()
78 super(SettingsController, self).__before__()
79 c.labs_active = str2bool(
79 c.labs_active = str2bool(
80 rhodecode.CONFIG.get('labs_settings_active', 'false'))
80 rhodecode.CONFIG.get('labs_settings_active', 'false'))
81 c.navlist = navigation.get_navlist(request)
81 c.navlist = navigation.get_navlist(request)
82
82
83 def _get_hg_ui_settings(self):
83 def _get_hg_ui_settings(self):
84 ret = RhodeCodeUi.query().all()
84 ret = RhodeCodeUi.query().all()
85
85
86 if not ret:
86 if not ret:
87 raise Exception('Could not get application ui settings !')
87 raise Exception('Could not get application ui settings !')
88 settings = {}
88 settings = {}
89 for each in ret:
89 for each in ret:
90 k = each.ui_key
90 k = each.ui_key
91 v = each.ui_value
91 v = each.ui_value
92 if k == '/':
92 if k == '/':
93 k = 'root_path'
93 k = 'root_path'
94
94
95 if k in ['push_ssl', 'publish']:
95 if k in ['push_ssl', 'publish']:
96 v = str2bool(v)
96 v = str2bool(v)
97
97
98 if k.find('.') != -1:
98 if k.find('.') != -1:
99 k = k.replace('.', '_')
99 k = k.replace('.', '_')
100
100
101 if each.ui_section in ['hooks', 'extensions']:
101 if each.ui_section in ['hooks', 'extensions']:
102 v = each.ui_active
102 v = each.ui_active
103
103
104 settings[each.ui_section + '_' + k] = v
104 settings[each.ui_section + '_' + k] = v
105 return settings
105 return settings
106
106
107 @HasPermissionAllDecorator('hg.admin')
107 @HasPermissionAllDecorator('hg.admin')
108 @auth.CSRFRequired()
108 @auth.CSRFRequired()
109 @jsonify
109 @jsonify
110 def delete_svn_pattern(self):
110 def delete_svn_pattern(self):
111 if not request.is_xhr:
111 if not request.is_xhr:
112 raise HTTPBadRequest()
112 raise HTTPBadRequest()
113
113
114 delete_pattern_id = request.POST.get('delete_svn_pattern')
114 delete_pattern_id = request.POST.get('delete_svn_pattern')
115 model = VcsSettingsModel()
115 model = VcsSettingsModel()
116 try:
116 try:
117 model.delete_global_svn_pattern(delete_pattern_id)
117 model.delete_global_svn_pattern(delete_pattern_id)
118 except SettingNotFound:
118 except SettingNotFound:
119 raise HTTPBadRequest()
119 raise HTTPBadRequest()
120
120
121 Session().commit()
121 Session().commit()
122 return True
122 return True
123
123
124 @HasPermissionAllDecorator('hg.admin')
124 @HasPermissionAllDecorator('hg.admin')
125 @auth.CSRFRequired()
125 @auth.CSRFRequired()
126 def settings_vcs_update(self):
126 def settings_vcs_update(self):
127 """POST /admin/settings: All items in the collection"""
127 """POST /admin/settings: All items in the collection"""
128 # url('admin_settings_vcs')
128 # url('admin_settings_vcs')
129 c.active = 'vcs'
129 c.active = 'vcs'
130
130
131 model = VcsSettingsModel()
131 model = VcsSettingsModel()
132 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
132 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
133 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
133 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
134
134
135 application_form = ApplicationUiSettingsForm()()
135 application_form = ApplicationUiSettingsForm()()
136 try:
136 try:
137 form_result = application_form.to_python(dict(request.POST))
137 form_result = application_form.to_python(dict(request.POST))
138 except formencode.Invalid as errors:
138 except formencode.Invalid as errors:
139 h.flash(
139 h.flash(
140 _("Some form inputs contain invalid data."),
140 _("Some form inputs contain invalid data."),
141 category='error')
141 category='error')
142 return htmlfill.render(
142 return htmlfill.render(
143 render('admin/settings/settings.html'),
143 render('admin/settings/settings.html'),
144 defaults=errors.value,
144 defaults=errors.value,
145 errors=errors.error_dict or {},
145 errors=errors.error_dict or {},
146 prefix_error=False,
146 prefix_error=False,
147 encoding="UTF-8",
147 encoding="UTF-8",
148 force_defaults=False
148 force_defaults=False
149 )
149 )
150
150
151 try:
151 try:
152 model.update_global_ssl_setting(form_result['web_push_ssl'])
152 model.update_global_ssl_setting(form_result['web_push_ssl'])
153 if c.visual.allow_repo_location_change:
153 if c.visual.allow_repo_location_change:
154 model.update_global_path_setting(
154 model.update_global_path_setting(
155 form_result['paths_root_path'])
155 form_result['paths_root_path'])
156 model.update_global_hook_settings(form_result)
156 model.update_global_hook_settings(form_result)
157 model.create_global_svn_settings(form_result)
157 model.create_global_svn_settings(form_result)
158 model.create_or_update_global_hg_settings(form_result)
158 model.create_or_update_global_hg_settings(form_result)
159 model.create_or_update_global_pr_settings(form_result)
159 model.create_or_update_global_pr_settings(form_result)
160 except Exception:
160 except Exception:
161 log.exception("Exception while updating settings")
161 log.exception("Exception while updating settings")
162 h.flash(_('Error occurred during updating '
162 h.flash(_('Error occurred during updating '
163 'application settings'), category='error')
163 'application settings'), category='error')
164 else:
164 else:
165 Session().commit()
165 Session().commit()
166 h.flash(_('Updated VCS settings'), category='success')
166 h.flash(_('Updated VCS settings'), category='success')
167 return redirect(url('admin_settings_vcs'))
167 return redirect(url('admin_settings_vcs'))
168
168
169 return htmlfill.render(
169 return htmlfill.render(
170 render('admin/settings/settings.html'),
170 render('admin/settings/settings.html'),
171 defaults=self._form_defaults(),
171 defaults=self._form_defaults(),
172 encoding="UTF-8",
172 encoding="UTF-8",
173 force_defaults=False)
173 force_defaults=False)
174
174
175 @HasPermissionAllDecorator('hg.admin')
175 @HasPermissionAllDecorator('hg.admin')
176 def settings_vcs(self):
176 def settings_vcs(self):
177 """GET /admin/settings: All items in the collection"""
177 """GET /admin/settings: All items in the collection"""
178 # url('admin_settings_vcs')
178 # url('admin_settings_vcs')
179 c.active = 'vcs'
179 c.active = 'vcs'
180 model = VcsSettingsModel()
180 model = VcsSettingsModel()
181 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
181 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
182 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
182 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
183
183
184 return htmlfill.render(
184 return htmlfill.render(
185 render('admin/settings/settings.html'),
185 render('admin/settings/settings.html'),
186 defaults=self._form_defaults(),
186 defaults=self._form_defaults(),
187 encoding="UTF-8",
187 encoding="UTF-8",
188 force_defaults=False)
188 force_defaults=False)
189
189
190 @HasPermissionAllDecorator('hg.admin')
190 @HasPermissionAllDecorator('hg.admin')
191 @auth.CSRFRequired()
191 @auth.CSRFRequired()
192 def settings_mapping_update(self):
192 def settings_mapping_update(self):
193 """POST /admin/settings/mapping: All items in the collection"""
193 """POST /admin/settings/mapping: All items in the collection"""
194 # url('admin_settings_mapping')
194 # url('admin_settings_mapping')
195 c.active = 'mapping'
195 c.active = 'mapping'
196 rm_obsolete = request.POST.get('destroy', False)
196 rm_obsolete = request.POST.get('destroy', False)
197 invalidate_cache = request.POST.get('invalidate', False)
197 invalidate_cache = request.POST.get('invalidate', False)
198 log.debug(
198 log.debug(
199 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
199 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
200
200
201 if invalidate_cache:
201 if invalidate_cache:
202 log.debug('invalidating all repositories cache')
202 log.debug('invalidating all repositories cache')
203 for repo in Repository.get_all():
203 for repo in Repository.get_all():
204 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
204 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
205
205
206 filesystem_repos = ScmModel().repo_scan()
206 filesystem_repos = ScmModel().repo_scan()
207 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
207 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
208 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
208 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
209 h.flash(_('Repositories successfully '
209 h.flash(_('Repositories successfully '
210 'rescanned added: %s ; removed: %s') %
210 'rescanned added: %s ; removed: %s') %
211 (_repr(added), _repr(removed)),
211 (_repr(added), _repr(removed)),
212 category='success')
212 category='success')
213 return redirect(url('admin_settings_mapping'))
213 return redirect(url('admin_settings_mapping'))
214
214
215 @HasPermissionAllDecorator('hg.admin')
215 @HasPermissionAllDecorator('hg.admin')
216 def settings_mapping(self):
216 def settings_mapping(self):
217 """GET /admin/settings/mapping: All items in the collection"""
217 """GET /admin/settings/mapping: All items in the collection"""
218 # url('admin_settings_mapping')
218 # url('admin_settings_mapping')
219 c.active = 'mapping'
219 c.active = 'mapping'
220
220
221 return htmlfill.render(
221 return htmlfill.render(
222 render('admin/settings/settings.html'),
222 render('admin/settings/settings.html'),
223 defaults=self._form_defaults(),
223 defaults=self._form_defaults(),
224 encoding="UTF-8",
224 encoding="UTF-8",
225 force_defaults=False)
225 force_defaults=False)
226
226
227 @HasPermissionAllDecorator('hg.admin')
227 @HasPermissionAllDecorator('hg.admin')
228 @auth.CSRFRequired()
228 @auth.CSRFRequired()
229 def settings_global_update(self):
229 def settings_global_update(self):
230 """POST /admin/settings/global: All items in the collection"""
230 """POST /admin/settings/global: All items in the collection"""
231 # url('admin_settings_global')
231 # url('admin_settings_global')
232 c.active = 'global'
232 c.active = 'global'
233 application_form = ApplicationSettingsForm()()
233 application_form = ApplicationSettingsForm()()
234 try:
234 try:
235 form_result = application_form.to_python(dict(request.POST))
235 form_result = application_form.to_python(dict(request.POST))
236 except formencode.Invalid as errors:
236 except formencode.Invalid as errors:
237 return htmlfill.render(
237 return htmlfill.render(
238 render('admin/settings/settings.html'),
238 render('admin/settings/settings.html'),
239 defaults=errors.value,
239 defaults=errors.value,
240 errors=errors.error_dict or {},
240 errors=errors.error_dict or {},
241 prefix_error=False,
241 prefix_error=False,
242 encoding="UTF-8",
242 encoding="UTF-8",
243 force_defaults=False)
243 force_defaults=False)
244
244
245 try:
245 try:
246 settings = [
246 settings = [
247 ('title', 'rhodecode_title'),
247 ('title', 'rhodecode_title'),
248 ('realm', 'rhodecode_realm'),
248 ('realm', 'rhodecode_realm'),
249 ('pre_code', 'rhodecode_pre_code'),
249 ('pre_code', 'rhodecode_pre_code'),
250 ('post_code', 'rhodecode_post_code'),
250 ('post_code', 'rhodecode_post_code'),
251 ('captcha_public_key', 'rhodecode_captcha_public_key'),
251 ('captcha_public_key', 'rhodecode_captcha_public_key'),
252 ('captcha_private_key', 'rhodecode_captcha_private_key'),
252 ('captcha_private_key', 'rhodecode_captcha_private_key'),
253 ]
253 ]
254 for setting, form_key in settings:
254 for setting, form_key in settings:
255 sett = SettingsModel().create_or_update_setting(
255 sett = SettingsModel().create_or_update_setting(
256 setting, form_result[form_key])
256 setting, form_result[form_key])
257 Session().add(sett)
257 Session().add(sett)
258
258
259 Session().commit()
259 Session().commit()
260 h.flash(_('Updated application settings'), category='success')
260 h.flash(_('Updated application settings'), category='success')
261
261
262 except Exception:
262 except Exception:
263 log.exception("Exception while updating application settings")
263 log.exception("Exception while updating application settings")
264 h.flash(
264 h.flash(
265 _('Error occurred during updating application settings'),
265 _('Error occurred during updating application settings'),
266 category='error')
266 category='error')
267
267
268 return redirect(url('admin_settings_global'))
268 return redirect(url('admin_settings_global'))
269
269
270 @HasPermissionAllDecorator('hg.admin')
270 @HasPermissionAllDecorator('hg.admin')
271 def settings_global(self):
271 def settings_global(self):
272 """GET /admin/settings/global: All items in the collection"""
272 """GET /admin/settings/global: All items in the collection"""
273 # url('admin_settings_global')
273 # url('admin_settings_global')
274 c.active = 'global'
274 c.active = 'global'
275
275
276 return htmlfill.render(
276 return htmlfill.render(
277 render('admin/settings/settings.html'),
277 render('admin/settings/settings.html'),
278 defaults=self._form_defaults(),
278 defaults=self._form_defaults(),
279 encoding="UTF-8",
279 encoding="UTF-8",
280 force_defaults=False)
280 force_defaults=False)
281
281
282 @HasPermissionAllDecorator('hg.admin')
282 @HasPermissionAllDecorator('hg.admin')
283 @auth.CSRFRequired()
283 @auth.CSRFRequired()
284 def settings_visual_update(self):
284 def settings_visual_update(self):
285 """POST /admin/settings/visual: All items in the collection"""
285 """POST /admin/settings/visual: All items in the collection"""
286 # url('admin_settings_visual')
286 # url('admin_settings_visual')
287 c.active = 'visual'
287 c.active = 'visual'
288 application_form = ApplicationVisualisationForm()()
288 application_form = ApplicationVisualisationForm()()
289 try:
289 try:
290 form_result = application_form.to_python(dict(request.POST))
290 form_result = application_form.to_python(dict(request.POST))
291 except formencode.Invalid as errors:
291 except formencode.Invalid as errors:
292 return htmlfill.render(
292 return htmlfill.render(
293 render('admin/settings/settings.html'),
293 render('admin/settings/settings.html'),
294 defaults=errors.value,
294 defaults=errors.value,
295 errors=errors.error_dict or {},
295 errors=errors.error_dict or {},
296 prefix_error=False,
296 prefix_error=False,
297 encoding="UTF-8",
297 encoding="UTF-8",
298 force_defaults=False
298 force_defaults=False
299 )
299 )
300
300
301 try:
301 try:
302 settings = [
302 settings = [
303 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
303 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
304 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
304 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
305 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
305 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
306 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
306 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
307 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
307 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
308 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
308 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
309 ('show_version', 'rhodecode_show_version', 'bool'),
309 ('show_version', 'rhodecode_show_version', 'bool'),
310 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
310 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
311 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
311 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
312 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
312 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
313 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
313 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
314 ('support_url', 'rhodecode_support_url', 'unicode'),
314 ('support_url', 'rhodecode_support_url', 'unicode'),
315 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
315 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
316 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
316 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
317 ]
317 ]
318 for setting, form_key, type_ in settings:
318 for setting, form_key, type_ in settings:
319 sett = SettingsModel().create_or_update_setting(
319 sett = SettingsModel().create_or_update_setting(
320 setting, form_result[form_key], type_)
320 setting, form_result[form_key], type_)
321 Session().add(sett)
321 Session().add(sett)
322
322
323 Session().commit()
323 Session().commit()
324
324
325 h.flash(_('Updated visualisation settings'), category='success')
325 h.flash(_('Updated visualisation settings'), category='success')
326 except Exception:
326 except Exception:
327 log.exception("Exception updating visualization settings")
327 log.exception("Exception updating visualization settings")
328 h.flash(_('Error occurred during updating '
328 h.flash(_('Error occurred during updating '
329 'visualisation settings'),
329 'visualisation settings'),
330 category='error')
330 category='error')
331
331
332 return redirect(url('admin_settings_visual'))
332 return redirect(url('admin_settings_visual'))
333
333
334 @HasPermissionAllDecorator('hg.admin')
334 @HasPermissionAllDecorator('hg.admin')
335 def settings_visual(self):
335 def settings_visual(self):
336 """GET /admin/settings/visual: All items in the collection"""
336 """GET /admin/settings/visual: All items in the collection"""
337 # url('admin_settings_visual')
337 # url('admin_settings_visual')
338 c.active = 'visual'
338 c.active = 'visual'
339
339
340 return htmlfill.render(
340 return htmlfill.render(
341 render('admin/settings/settings.html'),
341 render('admin/settings/settings.html'),
342 defaults=self._form_defaults(),
342 defaults=self._form_defaults(),
343 encoding="UTF-8",
343 encoding="UTF-8",
344 force_defaults=False)
344 force_defaults=False)
345
345
346 @HasPermissionAllDecorator('hg.admin')
346 @HasPermissionAllDecorator('hg.admin')
347 @auth.CSRFRequired()
347 @auth.CSRFRequired()
348 def settings_issuetracker_test(self):
348 def settings_issuetracker_test(self):
349 if request.is_xhr:
349 if request.is_xhr:
350 return h.urlify_commit_message(
350 return h.urlify_commit_message(
351 request.POST.get('test_text', ''),
351 request.POST.get('test_text', ''),
352 'repo_group/test_repo1')
352 'repo_group/test_repo1')
353 else:
353 else:
354 raise HTTPBadRequest()
354 raise HTTPBadRequest()
355
355
356 @HasPermissionAllDecorator('hg.admin')
356 @HasPermissionAllDecorator('hg.admin')
357 @auth.CSRFRequired()
357 @auth.CSRFRequired()
358 def settings_issuetracker_delete(self):
358 def settings_issuetracker_delete(self):
359 uid = request.POST.get('uid')
359 uid = request.POST.get('uid')
360 IssueTrackerSettingsModel().delete_entries(uid)
360 IssueTrackerSettingsModel().delete_entries(uid)
361 h.flash(_('Removed issue tracker entry'), category='success')
361 h.flash(_('Removed issue tracker entry'), category='success')
362 return redirect(url('admin_settings_issuetracker'))
362 return redirect(url('admin_settings_issuetracker'))
363
363
364 @HasPermissionAllDecorator('hg.admin')
364 @HasPermissionAllDecorator('hg.admin')
365 def settings_issuetracker(self):
365 def settings_issuetracker(self):
366 """GET /admin/settings/issue-tracker: All items in the collection"""
366 """GET /admin/settings/issue-tracker: All items in the collection"""
367 # url('admin_settings_issuetracker')
367 # url('admin_settings_issuetracker')
368 c.active = 'issuetracker'
368 c.active = 'issuetracker'
369 defaults = SettingsModel().get_all_settings()
369 defaults = SettingsModel().get_all_settings()
370
370
371 entry_key = 'rhodecode_issuetracker_pat_'
371 entry_key = 'rhodecode_issuetracker_pat_'
372
372
373 c.issuetracker_entries = {}
373 c.issuetracker_entries = {}
374 for k, v in defaults.items():
374 for k, v in defaults.items():
375 if k.startswith(entry_key):
375 if k.startswith(entry_key):
376 uid = k[len(entry_key):]
376 uid = k[len(entry_key):]
377 c.issuetracker_entries[uid] = None
377 c.issuetracker_entries[uid] = None
378
378
379 for uid in c.issuetracker_entries:
379 for uid in c.issuetracker_entries:
380 c.issuetracker_entries[uid] = AttributeDict({
380 c.issuetracker_entries[uid] = AttributeDict({
381 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
381 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
382 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
382 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
383 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
383 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
384 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
384 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
385 })
385 })
386
386
387 return render('admin/settings/settings.html')
387 return render('admin/settings/settings.html')
388
388
389 @HasPermissionAllDecorator('hg.admin')
389 @HasPermissionAllDecorator('hg.admin')
390 @auth.CSRFRequired()
390 @auth.CSRFRequired()
391 def settings_issuetracker_save(self):
391 def settings_issuetracker_save(self):
392 settings_model = IssueTrackerSettingsModel()
392 settings_model = IssueTrackerSettingsModel()
393
393
394 form = IssueTrackerPatternsForm()().to_python(request.POST)
394 form = IssueTrackerPatternsForm()().to_python(request.POST)
395 for uid in form['delete_patterns']:
395 for uid in form['delete_patterns']:
396 settings_model.delete_entries(uid)
396 settings_model.delete_entries(uid)
397
397
398 for pattern in form['patterns']:
398 for pattern in form['patterns']:
399 for setting, value, type_ in pattern:
399 for setting, value, type_ in pattern:
400 sett = settings_model.create_or_update_setting(
400 sett = settings_model.create_or_update_setting(
401 setting, value, type_)
401 setting, value, type_)
402 Session().add(sett)
402 Session().add(sett)
403
403
404 Session().commit()
404 Session().commit()
405
405
406 h.flash(_('Updated issue tracker entries'), category='success')
406 h.flash(_('Updated issue tracker entries'), category='success')
407 return redirect(url('admin_settings_issuetracker'))
407 return redirect(url('admin_settings_issuetracker'))
408
408
409 @HasPermissionAllDecorator('hg.admin')
409 @HasPermissionAllDecorator('hg.admin')
410 @auth.CSRFRequired()
410 @auth.CSRFRequired()
411 def settings_email_update(self):
411 def settings_email_update(self):
412 """POST /admin/settings/email: All items in the collection"""
412 """POST /admin/settings/email: All items in the collection"""
413 # url('admin_settings_email')
413 # url('admin_settings_email')
414 c.active = 'email'
414 c.active = 'email'
415
415
416 test_email = request.POST.get('test_email')
416 test_email = request.POST.get('test_email')
417
417
418 if not test_email:
418 if not test_email:
419 h.flash(_('Please enter email address'), category='error')
419 h.flash(_('Please enter email address'), category='error')
420 return redirect(url('admin_settings_email'))
420 return redirect(url('admin_settings_email'))
421
421
422 email_kwargs = {
422 email_kwargs = {
423 'date': datetime.datetime.now(),
423 'date': datetime.datetime.now(),
424 'user': c.rhodecode_user,
424 'user': c.rhodecode_user,
425 'rhodecode_version': c.rhodecode_version
425 'rhodecode_version': c.rhodecode_version
426 }
426 }
427
427
428 (subject, headers, email_body,
428 (subject, headers, email_body,
429 email_body_plaintext) = EmailNotificationModel().render_email(
429 email_body_plaintext) = EmailNotificationModel().render_email(
430 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
430 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
431
431
432 recipients = [test_email] if test_email else None
432 recipients = [test_email] if test_email else None
433
433
434 run_task(tasks.send_email, recipients, subject,
434 run_task(tasks.send_email, recipients, subject,
435 email_body_plaintext, email_body)
435 email_body_plaintext, email_body)
436
436
437 h.flash(_('Send email task created'), category='success')
437 h.flash(_('Send email task created'), category='success')
438 return redirect(url('admin_settings_email'))
438 return redirect(url('admin_settings_email'))
439
439
440 @HasPermissionAllDecorator('hg.admin')
440 @HasPermissionAllDecorator('hg.admin')
441 def settings_email(self):
441 def settings_email(self):
442 """GET /admin/settings/email: All items in the collection"""
442 """GET /admin/settings/email: All items in the collection"""
443 # url('admin_settings_email')
443 # url('admin_settings_email')
444 c.active = 'email'
444 c.active = 'email'
445 c.rhodecode_ini = rhodecode.CONFIG
445 c.rhodecode_ini = rhodecode.CONFIG
446
446
447 return htmlfill.render(
447 return htmlfill.render(
448 render('admin/settings/settings.html'),
448 render('admin/settings/settings.html'),
449 defaults=self._form_defaults(),
449 defaults=self._form_defaults(),
450 encoding="UTF-8",
450 encoding="UTF-8",
451 force_defaults=False)
451 force_defaults=False)
452
452
453 @HasPermissionAllDecorator('hg.admin')
453 @HasPermissionAllDecorator('hg.admin')
454 @auth.CSRFRequired()
454 @auth.CSRFRequired()
455 def settings_hooks_update(self):
455 def settings_hooks_update(self):
456 """POST or DELETE /admin/settings/hooks: All items in the collection"""
456 """POST or DELETE /admin/settings/hooks: All items in the collection"""
457 # url('admin_settings_hooks')
457 # url('admin_settings_hooks')
458 c.active = 'hooks'
458 c.active = 'hooks'
459 if c.visual.allow_custom_hooks_settings:
459 if c.visual.allow_custom_hooks_settings:
460 ui_key = request.POST.get('new_hook_ui_key')
460 ui_key = request.POST.get('new_hook_ui_key')
461 ui_value = request.POST.get('new_hook_ui_value')
461 ui_value = request.POST.get('new_hook_ui_value')
462
462
463 hook_id = request.POST.get('hook_id')
463 hook_id = request.POST.get('hook_id')
464 new_hook = False
464 new_hook = False
465
465
466 model = SettingsModel()
466 model = SettingsModel()
467 try:
467 try:
468 if ui_value and ui_key:
468 if ui_value and ui_key:
469 model.create_or_update_hook(ui_key, ui_value)
469 model.create_or_update_hook(ui_key, ui_value)
470 h.flash(_('Added new hook'), category='success')
470 h.flash(_('Added new hook'), category='success')
471 new_hook = True
471 new_hook = True
472 elif hook_id:
472 elif hook_id:
473 RhodeCodeUi.delete(hook_id)
473 RhodeCodeUi.delete(hook_id)
474 Session().commit()
474 Session().commit()
475
475
476 # check for edits
476 # check for edits
477 update = False
477 update = False
478 _d = request.POST.dict_of_lists()
478 _d = request.POST.dict_of_lists()
479 for k, v in zip(_d.get('hook_ui_key', []),
479 for k, v in zip(_d.get('hook_ui_key', []),
480 _d.get('hook_ui_value_new', [])):
480 _d.get('hook_ui_value_new', [])):
481 model.create_or_update_hook(k, v)
481 model.create_or_update_hook(k, v)
482 update = True
482 update = True
483
483
484 if update and not new_hook:
484 if update and not new_hook:
485 h.flash(_('Updated hooks'), category='success')
485 h.flash(_('Updated hooks'), category='success')
486 Session().commit()
486 Session().commit()
487 except Exception:
487 except Exception:
488 log.exception("Exception during hook creation")
488 log.exception("Exception during hook creation")
489 h.flash(_('Error occurred during hook creation'),
489 h.flash(_('Error occurred during hook creation'),
490 category='error')
490 category='error')
491
491
492 return redirect(url('admin_settings_hooks'))
492 return redirect(url('admin_settings_hooks'))
493
493
494 @HasPermissionAllDecorator('hg.admin')
494 @HasPermissionAllDecorator('hg.admin')
495 def settings_hooks(self):
495 def settings_hooks(self):
496 """GET /admin/settings/hooks: All items in the collection"""
496 """GET /admin/settings/hooks: All items in the collection"""
497 # url('admin_settings_hooks')
497 # url('admin_settings_hooks')
498 c.active = 'hooks'
498 c.active = 'hooks'
499
499
500 model = SettingsModel()
500 model = SettingsModel()
501 c.hooks = model.get_builtin_hooks()
501 c.hooks = model.get_builtin_hooks()
502 c.custom_hooks = model.get_custom_hooks()
502 c.custom_hooks = model.get_custom_hooks()
503
503
504 return htmlfill.render(
504 return htmlfill.render(
505 render('admin/settings/settings.html'),
505 render('admin/settings/settings.html'),
506 defaults=self._form_defaults(),
506 defaults=self._form_defaults(),
507 encoding="UTF-8",
507 encoding="UTF-8",
508 force_defaults=False)
508 force_defaults=False)
509
509
510 @HasPermissionAllDecorator('hg.admin')
510 @HasPermissionAllDecorator('hg.admin')
511 def settings_search(self):
511 def settings_search(self):
512 """GET /admin/settings/search: All items in the collection"""
512 """GET /admin/settings/search: All items in the collection"""
513 # url('admin_settings_search')
513 # url('admin_settings_search')
514 c.active = 'search'
514 c.active = 'search'
515
515
516 from rhodecode.lib.index import searcher_from_config
516 from rhodecode.lib.index import searcher_from_config
517 searcher = searcher_from_config(config)
517 searcher = searcher_from_config(config)
518 c.statistics = searcher.statistics()
518 c.statistics = searcher.statistics()
519
519
520 return render('admin/settings/settings.html')
520 return render('admin/settings/settings.html')
521
521
522 @HasPermissionAllDecorator('hg.admin')
522 @HasPermissionAllDecorator('hg.admin')
523 def settings_system(self):
523 def settings_system(self):
524 """GET /admin/settings/system: All items in the collection"""
524 """GET /admin/settings/system: All items in the collection"""
525 # url('admin_settings_system')
525 # url('admin_settings_system')
526 c.active = 'system'
526 c.active = 'system'
527
527
528 defaults = self._form_defaults()
528 defaults = self._form_defaults()
529 c.rhodecode_ini = rhodecode.CONFIG
529 c.rhodecode_ini = rhodecode.CONFIG
530 c.rhodecode_update_url = defaults.get('rhodecode_update_url')
530 c.rhodecode_update_url = defaults.get('rhodecode_update_url')
531 server_info = ScmModel().get_server_info(request.environ)
531 server_info = ScmModel().get_server_info(request.environ)
532 for key, val in server_info.iteritems():
532 for key, val in server_info.iteritems():
533 setattr(c, key, val)
533 setattr(c, key, val)
534
534
535 if c.disk['percent'] > 90:
535 if c.disk['percent'] > 90:
536 h.flash(h.literal(_(
536 h.flash(h.literal(_(
537 'Critical: your disk space is very low <b>%s%%</b> used' %
537 'Critical: your disk space is very low <b>%s%%</b> used' %
538 c.disk['percent'])), 'error')
538 c.disk['percent'])), 'error')
539 elif c.disk['percent'] > 70:
539 elif c.disk['percent'] > 70:
540 h.flash(h.literal(_(
540 h.flash(h.literal(_(
541 'Warning: your disk space is running low <b>%s%%</b> used' %
541 'Warning: your disk space is running low <b>%s%%</b> used' %
542 c.disk['percent'])), 'warning')
542 c.disk['percent'])), 'warning')
543
543
544 try:
544 try:
545 c.uptime_age = h._age(
545 c.uptime_age = h._age(
546 h.time_to_datetime(c.boot_time), False, show_suffix=False)
546 h.time_to_datetime(c.boot_time), False, show_suffix=False)
547 except TypeError:
547 except TypeError:
548 c.uptime_age = c.boot_time
548 c.uptime_age = c.boot_time
549
549
550 try:
550 try:
551 c.system_memory = '%s/%s, %s%% (%s%%) used%s' % (
551 c.system_memory = '%s/%s, %s%% (%s%%) used%s' % (
552 h.format_byte_size_binary(c.memory['used']),
552 h.format_byte_size_binary(c.memory['used']),
553 h.format_byte_size_binary(c.memory['total']),
553 h.format_byte_size_binary(c.memory['total']),
554 c.memory['percent2'],
554 c.memory['percent2'],
555 c.memory['percent'],
555 c.memory['percent'],
556 ' %s' % c.memory['error'] if 'error' in c.memory else '')
556 ' %s' % c.memory['error'] if 'error' in c.memory else '')
557 except TypeError:
557 except TypeError:
558 c.system_memory = 'NOT AVAILABLE'
558 c.system_memory = 'NOT AVAILABLE'
559
559
560 return htmlfill.render(
560 return htmlfill.render(
561 render('admin/settings/settings.html'),
561 render('admin/settings/settings.html'),
562 defaults=defaults,
562 defaults=defaults,
563 encoding="UTF-8",
563 encoding="UTF-8",
564 force_defaults=False)
564 force_defaults=False)
565
565
566 @staticmethod
566 @staticmethod
567 def get_update_data(update_url):
567 def get_update_data(update_url):
568 """Return the JSON update data."""
568 """Return the JSON update data."""
569 ver = rhodecode.__version__
569 ver = rhodecode.__version__
570 log.debug('Checking for upgrade on `%s` server', update_url)
570 log.debug('Checking for upgrade on `%s` server', update_url)
571 opener = urllib2.build_opener()
571 opener = urllib2.build_opener()
572 opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)]
572 opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)]
573 response = opener.open(update_url)
573 response = opener.open(update_url)
574 response_data = response.read()
574 response_data = response.read()
575 data = json.loads(response_data)
575 data = json.loads(response_data)
576
576
577 return data
577 return data
578
578
579 @HasPermissionAllDecorator('hg.admin')
579 @HasPermissionAllDecorator('hg.admin')
580 def settings_system_update(self):
580 def settings_system_update(self):
581 """GET /admin/settings/system/updates: All items in the collection"""
581 """GET /admin/settings/system/updates: All items in the collection"""
582 # url('admin_settings_system_update')
582 # url('admin_settings_system_update')
583 defaults = self._form_defaults()
583 defaults = self._form_defaults()
584 update_url = defaults.get('rhodecode_update_url', '')
584 update_url = defaults.get('rhodecode_update_url', '')
585
585
586 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s)
586 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s)
587 try:
587 try:
588 data = self.get_update_data(update_url)
588 data = self.get_update_data(update_url)
589 except urllib2.URLError as e:
589 except urllib2.URLError as e:
590 log.exception("Exception contacting upgrade server")
590 log.exception("Exception contacting upgrade server")
591 return _err('Failed to contact upgrade server: %r' % e)
591 return _err('Failed to contact upgrade server: %r' % e)
592 except ValueError as e:
592 except ValueError as e:
593 log.exception("Bad data sent from update server")
593 log.exception("Bad data sent from update server")
594 return _err('Bad data sent from update server')
594 return _err('Bad data sent from update server')
595
595
596 latest = data['versions'][0]
596 latest = data['versions'][0]
597
597
598 c.update_url = update_url
598 c.update_url = update_url
599 c.latest_data = latest
599 c.latest_data = latest
600 c.latest_ver = latest['version']
600 c.latest_ver = latest['version']
601 c.cur_ver = rhodecode.__version__
601 c.cur_ver = rhodecode.__version__
602 c.should_upgrade = False
602 c.should_upgrade = False
603
603
604 if (packaging.version.Version(c.latest_ver) >
604 if (packaging.version.Version(c.latest_ver) >
605 packaging.version.Version(c.cur_ver)):
605 packaging.version.Version(c.cur_ver)):
606 c.should_upgrade = True
606 c.should_upgrade = True
607 c.important_notices = latest['general']
607 c.important_notices = latest['general']
608
608
609 return render('admin/settings/settings_system_update.html')
609 return render('admin/settings/settings_system_update.html')
610
610
611 @HasPermissionAllDecorator('hg.admin')
611 @HasPermissionAllDecorator('hg.admin')
612 def settings_supervisor(self):
612 def settings_supervisor(self):
613 c.rhodecode_ini = rhodecode.CONFIG
613 c.rhodecode_ini = rhodecode.CONFIG
614 c.active = 'supervisor'
614 c.active = 'supervisor'
615
615
616 c.supervisor_procs = OrderedDict([
616 c.supervisor_procs = OrderedDict([
617 (SUPERVISOR_MASTER, {}),
617 (SUPERVISOR_MASTER, {}),
618 ])
618 ])
619
619
620 c.log_size = 10240
620 c.log_size = 10240
621 supervisor = SupervisorModel()
621 supervisor = SupervisorModel()
622
622
623 _connection = supervisor.get_connection(
623 _connection = supervisor.get_connection(
624 c.rhodecode_ini.get('supervisor.uri'))
624 c.rhodecode_ini.get('supervisor.uri'))
625 c.connection_error = None
625 c.connection_error = None
626 try:
626 try:
627 _connection.supervisor.getAllProcessInfo()
627 _connection.supervisor.getAllProcessInfo()
628 except Exception as e:
628 except Exception as e:
629 c.connection_error = str(e)
629 c.connection_error = str(e)
630 log.exception("Exception reading supervisor data")
630 log.exception("Exception reading supervisor data")
631 return render('admin/settings/settings.html')
631 return render('admin/settings/settings.html')
632
632
633 groupid = c.rhodecode_ini.get('supervisor.group_id')
633 groupid = c.rhodecode_ini.get('supervisor.group_id')
634
634
635 # feed our group processes to the main
635 # feed our group processes to the main
636 for proc in supervisor.get_group_processes(_connection, groupid):
636 for proc in supervisor.get_group_processes(_connection, groupid):
637 c.supervisor_procs[proc['name']] = {}
637 c.supervisor_procs[proc['name']] = {}
638
638
639 for k in c.supervisor_procs.keys():
639 for k in c.supervisor_procs.keys():
640 try:
640 try:
641 # master process info
641 # master process info
642 if k == SUPERVISOR_MASTER:
642 if k == SUPERVISOR_MASTER:
643 _data = supervisor.get_master_state(_connection)
643 _data = supervisor.get_master_state(_connection)
644 _data['name'] = 'supervisor master'
644 _data['name'] = 'supervisor master'
645 _data['description'] = 'pid %s, id: %s, ver: %s' % (
645 _data['description'] = 'pid %s, id: %s, ver: %s' % (
646 _data['pid'], _data['id'], _data['ver'])
646 _data['pid'], _data['id'], _data['ver'])
647 c.supervisor_procs[k] = _data
647 c.supervisor_procs[k] = _data
648 else:
648 else:
649 procid = groupid + ":" + k
649 procid = groupid + ":" + k
650 c.supervisor_procs[k] = supervisor.get_process_info(_connection, procid)
650 c.supervisor_procs[k] = supervisor.get_process_info(_connection, procid)
651 except Exception as e:
651 except Exception as e:
652 log.exception("Exception reading supervisor data")
652 log.exception("Exception reading supervisor data")
653 c.supervisor_procs[k] = {'_rhodecode_error': str(e)}
653 c.supervisor_procs[k] = {'_rhodecode_error': str(e)}
654
654
655 return render('admin/settings/settings.html')
655 return render('admin/settings/settings.html')
656
656
657 @HasPermissionAllDecorator('hg.admin')
657 @HasPermissionAllDecorator('hg.admin')
658 def settings_supervisor_log(self, procid):
658 def settings_supervisor_log(self, procid):
659 import rhodecode
659 import rhodecode
660 c.rhodecode_ini = rhodecode.CONFIG
660 c.rhodecode_ini = rhodecode.CONFIG
661 c.active = 'supervisor_tail'
661 c.active = 'supervisor_tail'
662
662
663 supervisor = SupervisorModel()
663 supervisor = SupervisorModel()
664 _connection = supervisor.get_connection(c.rhodecode_ini.get('supervisor.uri'))
664 _connection = supervisor.get_connection(c.rhodecode_ini.get('supervisor.uri'))
665 groupid = c.rhodecode_ini.get('supervisor.group_id')
665 groupid = c.rhodecode_ini.get('supervisor.group_id')
666 procid = groupid + ":" + procid if procid != SUPERVISOR_MASTER else procid
666 procid = groupid + ":" + procid if procid != SUPERVISOR_MASTER else procid
667
667
668 c.log_size = 10240
668 c.log_size = 10240
669 offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1
669 offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1
670 c.log = supervisor.read_process_log(_connection, procid, offset, 0)
670 c.log = supervisor.read_process_log(_connection, procid, offset, 0)
671
671
672 return render('admin/settings/settings.html')
672 return render('admin/settings/settings.html')
673
673
674 @HasPermissionAllDecorator('hg.admin')
674 @HasPermissionAllDecorator('hg.admin')
675 @auth.CSRFRequired()
675 @auth.CSRFRequired()
676 def settings_labs_update(self):
676 def settings_labs_update(self):
677 """POST /admin/settings/labs: All items in the collection"""
677 """POST /admin/settings/labs: All items in the collection"""
678 # url('admin_settings/labs', method={'POST'})
678 # url('admin_settings/labs', method={'POST'})
679 c.active = 'labs'
679 c.active = 'labs'
680
680
681 application_form = LabsSettingsForm()()
681 application_form = LabsSettingsForm()()
682 try:
682 try:
683 form_result = application_form.to_python(dict(request.POST))
683 form_result = application_form.to_python(dict(request.POST))
684 except formencode.Invalid as errors:
684 except formencode.Invalid as errors:
685 h.flash(
685 h.flash(
686 _('Some form inputs contain invalid data.'),
686 _('Some form inputs contain invalid data.'),
687 category='error')
687 category='error')
688 return htmlfill.render(
688 return htmlfill.render(
689 render('admin/settings/settings.html'),
689 render('admin/settings/settings.html'),
690 defaults=errors.value,
690 defaults=errors.value,
691 errors=errors.error_dict or {},
691 errors=errors.error_dict or {},
692 prefix_error=False,
692 prefix_error=False,
693 encoding='UTF-8',
693 encoding='UTF-8',
694 force_defaults=False
694 force_defaults=False
695 )
695 )
696
696
697 try:
697 try:
698 session = Session()
698 session = Session()
699 for setting in _LAB_SETTINGS:
699 for setting in _LAB_SETTINGS:
700 setting_name = setting.key[len('rhodecode_'):]
700 setting_name = setting.key[len('rhodecode_'):]
701 sett = SettingsModel().create_or_update_setting(
701 sett = SettingsModel().create_or_update_setting(
702 setting_name, form_result[setting.key], setting.type)
702 setting_name, form_result[setting.key], setting.type)
703 session.add(sett)
703 session.add(sett)
704
704
705 except Exception:
705 except Exception:
706 log.exception('Exception while updating lab settings')
706 log.exception('Exception while updating lab settings')
707 h.flash(_('Error occurred during updating labs settings'),
707 h.flash(_('Error occurred during updating labs settings'),
708 category='error')
708 category='error')
709 else:
709 else:
710 Session().commit()
710 Session().commit()
711 h.flash(_('Updated Labs settings'), category='success')
711 h.flash(_('Updated Labs settings'), category='success')
712 return redirect(url('admin_settings_labs'))
712 return redirect(url('admin_settings_labs'))
713
713
714 return htmlfill.render(
714 return htmlfill.render(
715 render('admin/settings/settings.html'),
715 render('admin/settings/settings.html'),
716 defaults=self._form_defaults(),
716 defaults=self._form_defaults(),
717 encoding='UTF-8',
717 encoding='UTF-8',
718 force_defaults=False)
718 force_defaults=False)
719
719
720 @HasPermissionAllDecorator('hg.admin')
720 @HasPermissionAllDecorator('hg.admin')
721 def settings_labs(self):
721 def settings_labs(self):
722 """GET /admin/settings/labs: All items in the collection"""
722 """GET /admin/settings/labs: All items in the collection"""
723 # url('admin_settings_labs')
723 # url('admin_settings_labs')
724 if not c.labs_active:
724 if not c.labs_active:
725 redirect(url('admin_settings'))
725 redirect(url('admin_settings'))
726
726
727 c.active = 'labs'
727 c.active = 'labs'
728 c.lab_settings = _LAB_SETTINGS
728 c.lab_settings = _LAB_SETTINGS
729
729
730 return htmlfill.render(
730 return htmlfill.render(
731 render('admin/settings/settings.html'),
731 render('admin/settings/settings.html'),
732 defaults=self._form_defaults(),
732 defaults=self._form_defaults(),
733 encoding='UTF-8',
733 encoding='UTF-8',
734 force_defaults=False)
734 force_defaults=False)
735
735
736 @HasPermissionAllDecorator('hg.admin')
737 def settings_open_source(self):
738 # url('admin_settings_open_source')
739
740 c.active = 'open_source'
741 c.opensource_licenses = collections.OrderedDict(
742 sorted(read_opensource_licenses().items(), key=lambda t: t[0]))
743
744 return htmlfill.render(
745 render('admin/settings/settings.html'),
746 defaults=self._form_defaults(),
747 encoding='UTF-8',
748 force_defaults=False)
749
750 def _form_defaults(self):
736 def _form_defaults(self):
751 defaults = SettingsModel().get_all_settings()
737 defaults = SettingsModel().get_all_settings()
752 defaults.update(self._get_hg_ui_settings())
738 defaults.update(self._get_hg_ui_settings())
753 defaults.update({
739 defaults.update({
754 'new_svn_branch': '',
740 'new_svn_branch': '',
755 'new_svn_tag': '',
741 'new_svn_tag': '',
756 })
742 })
757 return defaults
743 return defaults
758
744
759
745
760 # :param key: name of the setting including the 'rhodecode_' prefix
746 # :param key: name of the setting including the 'rhodecode_' prefix
761 # :param type: the RhodeCodeSetting type to use.
747 # :param type: the RhodeCodeSetting type to use.
762 # :param group: the i18ned group in which we should dispaly this setting
748 # :param group: the i18ned group in which we should dispaly this setting
763 # :param label: the i18ned label we should display for this setting
749 # :param label: the i18ned label we should display for this setting
764 # :param help: the i18ned help we should dispaly for this setting
750 # :param help: the i18ned help we should dispaly for this setting
765 LabSetting = collections.namedtuple(
751 LabSetting = collections.namedtuple(
766 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
752 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
767
753
768
754
769 # This list has to be kept in sync with the form
755 # This list has to be kept in sync with the form
770 # rhodecode.model.forms.LabsSettingsForm.
756 # rhodecode.model.forms.LabsSettingsForm.
771 _LAB_SETTINGS = [
757 _LAB_SETTINGS = [
772 LabSetting(
758 LabSetting(
773 key='rhodecode_hg_use_rebase_for_merging',
759 key='rhodecode_hg_use_rebase_for_merging',
774 type='bool',
760 type='bool',
775 group=lazy_ugettext('Mercurial server-side merge'),
761 group=lazy_ugettext('Mercurial server-side merge'),
776 label=lazy_ugettext('Use rebase instead of creating a merge commit when merging via web interface'),
762 label=lazy_ugettext('Use rebase instead of creating a merge commit when merging via web interface'),
777 help='' # Do not translate the empty string!
763 help='' # Do not translate the empty string!
778 ),
764 ),
779 LabSetting(
765 LabSetting(
780 key='rhodecode_proxy_subversion_http_requests',
766 key='rhodecode_proxy_subversion_http_requests',
781 type='bool',
767 type='bool',
782 group=lazy_ugettext('Subversion HTTP Support'),
768 group=lazy_ugettext('Subversion HTTP Support'),
783 label=lazy_ugettext('Proxy subversion HTTP requests'),
769 label=lazy_ugettext('Proxy subversion HTTP requests'),
784 help='' # Do not translate the empty string!
770 help='' # Do not translate the empty string!
785 ),
771 ),
786 LabSetting(
772 LabSetting(
787 key='rhodecode_subversion_http_server_url',
773 key='rhodecode_subversion_http_server_url',
788 type='str',
774 type='str',
789 group=lazy_ugettext('Subversion HTTP Server URL'),
775 group=lazy_ugettext('Subversion HTTP Server URL'),
790 label='', # Do not translate the empty string!
776 label='', # Do not translate the empty string!
791 help=lazy_ugettext('e.g. http://localhost:8080/')
777 help=lazy_ugettext('e.g. http://localhost:8080/')
792 ),
778 ),
793 ]
779 ]
794
780
795
781
796 NavListEntry = collections.namedtuple('NavListEntry', ['key', 'name', 'url'])
782 NavListEntry = collections.namedtuple('NavListEntry', ['key', 'name', 'url'])
797
783
798
784
799 class NavEntry(object):
785 class NavEntry(object):
800
786
801 def __init__(self, key, name, view_name, pyramid=False):
787 def __init__(self, key, name, view_name, pyramid=False):
802 self.key = key
788 self.key = key
803 self.name = name
789 self.name = name
804 self.view_name = view_name
790 self.view_name = view_name
805 self.pyramid = pyramid
791 self.pyramid = pyramid
806
792
807 def generate_url(self, request):
793 def generate_url(self, request):
808 if self.pyramid:
794 if self.pyramid:
809 if hasattr(request, 'route_path'):
795 if hasattr(request, 'route_path'):
810 return request.route_path(self.view_name)
796 return request.route_path(self.view_name)
811 else:
797 else:
812 # TODO: johbo: Remove this after migrating to pyramid.
798 # TODO: johbo: Remove this after migrating to pyramid.
813 # We need the pyramid request here to generate URLs to pyramid
799 # We need the pyramid request here to generate URLs to pyramid
814 # views from within pylons views.
800 # views from within pylons views.
815 from pyramid.threadlocal import get_current_request
801 from pyramid.threadlocal import get_current_request
816 pyramid_request = get_current_request()
802 pyramid_request = get_current_request()
817 return pyramid_request.route_path(self.view_name)
803 return pyramid_request.route_path(self.view_name)
818 else:
804 else:
819 return url(self.view_name)
805 return url(self.view_name)
820
806
821
807
822 class NavigationRegistry(object):
808 class NavigationRegistry(object):
823
809
824 _base_entries = [
810 _base_entries = [
825 NavEntry('global', lazy_ugettext('Global'), 'admin_settings_global'),
811 NavEntry('global', lazy_ugettext('Global'), 'admin_settings_global'),
826 NavEntry('vcs', lazy_ugettext('VCS'), 'admin_settings_vcs'),
812 NavEntry('vcs', lazy_ugettext('VCS'), 'admin_settings_vcs'),
827 NavEntry('visual', lazy_ugettext('Visual'), 'admin_settings_visual'),
813 NavEntry('visual', lazy_ugettext('Visual'), 'admin_settings_visual'),
828 NavEntry('mapping', lazy_ugettext('Remap and Rescan'),
814 NavEntry('mapping', lazy_ugettext('Remap and Rescan'),
829 'admin_settings_mapping'),
815 'admin_settings_mapping'),
830 NavEntry('issuetracker', lazy_ugettext('Issue Tracker'),
816 NavEntry('issuetracker', lazy_ugettext('Issue Tracker'),
831 'admin_settings_issuetracker'),
817 'admin_settings_issuetracker'),
832 NavEntry('email', lazy_ugettext('Email'), 'admin_settings_email'),
818 NavEntry('email', lazy_ugettext('Email'), 'admin_settings_email'),
833 NavEntry('hooks', lazy_ugettext('Hooks'), 'admin_settings_hooks'),
819 NavEntry('hooks', lazy_ugettext('Hooks'), 'admin_settings_hooks'),
834 NavEntry('search', lazy_ugettext('Full Text Search'),
820 NavEntry('search', lazy_ugettext('Full Text Search'),
835 'admin_settings_search'),
821 'admin_settings_search'),
836 NavEntry('system', lazy_ugettext('System Info'),
822 NavEntry('system', lazy_ugettext('System Info'),
837 'admin_settings_system'),
823 'admin_settings_system'),
838 NavEntry('open_source', lazy_ugettext('Open Source Licenses'),
824 NavEntry('open_source', lazy_ugettext('Open Source Licenses'),
839 'admin_settings_open_source'),
825 'admin_settings_open_source'),
840 # TODO: marcink: we disable supervisor now until the supervisor stats
826 # TODO: marcink: we disable supervisor now until the supervisor stats
841 # page is fixed in the nix configuration
827 # page is fixed in the nix configuration
842 # NavEntry('supervisor', lazy_ugettext('Supervisor'),
828 # NavEntry('supervisor', lazy_ugettext('Supervisor'),
843 # 'admin_settings_supervisor'),
829 # 'admin_settings_supervisor'),
844 ]
830 ]
845
831
846 def __init__(self):
832 def __init__(self):
847 self._registered_entries = collections.OrderedDict([
833 self._registered_entries = collections.OrderedDict([
848 (item.key, item) for item in self.__class__._base_entries
834 (item.key, item) for item in self.__class__._base_entries
849 ])
835 ])
850
836
851 # Add the labs entry when it's activated.
837 # Add the labs entry when it's activated.
852 labs_active = str2bool(
838 labs_active = str2bool(
853 rhodecode.CONFIG.get('labs_settings_active', 'false'))
839 rhodecode.CONFIG.get('labs_settings_active', 'false'))
854 if labs_active:
840 if labs_active:
855 self.add_entry(
841 self.add_entry(
856 NavEntry('labs', lazy_ugettext('Labs'), 'admin_settings_labs'))
842 NavEntry('labs', lazy_ugettext('Labs'), 'admin_settings_labs'))
857
843
858 def add_entry(self, entry):
844 def add_entry(self, entry):
859 self._registered_entries[entry.key] = entry
845 self._registered_entries[entry.key] = entry
860
846
861 def get_navlist(self, request):
847 def get_navlist(self, request):
862 navlist = [NavListEntry(i.key, i.name, i.generate_url(request))
848 navlist = [NavListEntry(i.key, i.name, i.generate_url(request))
863 for i in self._registered_entries.values()]
849 for i in self._registered_entries.values()]
864 return navlist
850 return navlist
865
851
866 navigation = NavigationRegistry()
852 navigation = NavigationRegistry()
General Comments 0
You need to be logged in to leave comments. Login now