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