##// END OF EJS Templates
svn-support: Add missing argument to tmplate context....
Martin Bornhold -
r1023:7d893c6f default
parent child Browse files
Show More
@@ -1,803 +1,807 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 """
22 """
23 settings controller for rhodecode admin
23 settings controller for rhodecode admin
24 """
24 """
25
25
26 import collections
26 import collections
27 import logging
27 import logging
28 import urllib2
28 import urllib2
29
29
30 import datetime
30 import datetime
31 import formencode
31 import formencode
32 from formencode import htmlfill
32 from formencode import htmlfill
33 import packaging.version
33 import packaging.version
34 from pylons import request, tmpl_context as c, url, config
34 from pylons import request, tmpl_context as c, url, config
35 from pylons.controllers.util import redirect
35 from pylons.controllers.util import redirect
36 from pylons.i18n.translation import _, lazy_ugettext
36 from pylons.i18n.translation import _, lazy_ugettext
37 from pyramid.threadlocal import get_current_registry
37 from pyramid.threadlocal import get_current_registry
38 from webob.exc import HTTPBadRequest
38 from webob.exc import HTTPBadRequest
39
39
40 import rhodecode
40 import rhodecode
41 from rhodecode.admin.navigation import navigation_list
41 from rhodecode.admin.navigation import navigation_list
42 from rhodecode.lib import auth
42 from rhodecode.lib import auth
43 from rhodecode.lib import helpers as h
43 from rhodecode.lib import helpers as h
44 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
44 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
45 from rhodecode.lib.base import BaseController, render
45 from rhodecode.lib.base import BaseController, render
46 from rhodecode.lib.celerylib import tasks, run_task
46 from rhodecode.lib.celerylib import tasks, run_task
47 from rhodecode.lib.utils import repo2db_mapper
47 from rhodecode.lib.utils import repo2db_mapper
48 from rhodecode.lib.utils2 import (
48 from rhodecode.lib.utils2 import (
49 str2bool, safe_unicode, AttributeDict, safe_int)
49 str2bool, safe_unicode, AttributeDict, safe_int)
50 from rhodecode.lib.compat import OrderedDict
50 from rhodecode.lib.compat import OrderedDict
51 from rhodecode.lib.ext_json import json
51 from rhodecode.lib.ext_json import json
52 from rhodecode.lib.utils import jsonify
52 from rhodecode.lib.utils import jsonify
53
53
54 from rhodecode.model.db import RhodeCodeUi, Repository
54 from rhodecode.model.db import RhodeCodeUi, Repository
55 from rhodecode.model.forms import ApplicationSettingsForm, \
55 from rhodecode.model.forms import ApplicationSettingsForm, \
56 ApplicationUiSettingsForm, ApplicationVisualisationForm, \
56 ApplicationUiSettingsForm, ApplicationVisualisationForm, \
57 LabsSettingsForm, IssueTrackerPatternsForm
57 LabsSettingsForm, IssueTrackerPatternsForm
58
58
59 from rhodecode.model.scm import ScmModel
59 from rhodecode.model.scm import ScmModel
60 from rhodecode.model.notification import EmailNotificationModel
60 from rhodecode.model.notification import EmailNotificationModel
61 from rhodecode.model.meta import Session
61 from rhodecode.model.meta import Session
62 from rhodecode.model.settings import (
62 from rhodecode.model.settings import (
63 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
63 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
64 SettingsModel)
64 SettingsModel)
65
65
66 from rhodecode.model.supervisor import SupervisorModel, SUPERVISOR_MASTER
66 from rhodecode.model.supervisor import SupervisorModel, SUPERVISOR_MASTER
67 from rhodecode.svn_support.config_keys import generate_config
67 from rhodecode.svn_support.config_keys import generate_config
68
68
69
69
70 log = logging.getLogger(__name__)
70 log = logging.getLogger(__name__)
71
71
72
72
73 class SettingsController(BaseController):
73 class SettingsController(BaseController):
74 """REST Controller styled on the Atom Publishing Protocol"""
74 """REST Controller styled on the Atom Publishing Protocol"""
75 # To properly map this controller, ensure your config/routing.py
75 # To properly map this controller, ensure your config/routing.py
76 # file has a resource setup:
76 # file has a resource setup:
77 # map.resource('setting', 'settings', controller='admin/settings',
77 # map.resource('setting', 'settings', controller='admin/settings',
78 # path_prefix='/admin', name_prefix='admin_')
78 # path_prefix='/admin', name_prefix='admin_')
79
79
80 @LoginRequired()
80 @LoginRequired()
81 def __before__(self):
81 def __before__(self):
82 super(SettingsController, self).__before__()
82 super(SettingsController, self).__before__()
83 c.labs_active = str2bool(
83 c.labs_active = str2bool(
84 rhodecode.CONFIG.get('labs_settings_active', 'true'))
84 rhodecode.CONFIG.get('labs_settings_active', 'true'))
85 c.navlist = navigation_list(request)
85 c.navlist = navigation_list(request)
86
86
87 def _get_hg_ui_settings(self):
87 def _get_hg_ui_settings(self):
88 ret = RhodeCodeUi.query().all()
88 ret = RhodeCodeUi.query().all()
89
89
90 if not ret:
90 if not ret:
91 raise Exception('Could not get application ui settings !')
91 raise Exception('Could not get application ui settings !')
92 settings = {}
92 settings = {}
93 for each in ret:
93 for each in ret:
94 k = each.ui_key
94 k = each.ui_key
95 v = each.ui_value
95 v = each.ui_value
96 if k == '/':
96 if k == '/':
97 k = 'root_path'
97 k = 'root_path'
98
98
99 if k in ['push_ssl', 'publish']:
99 if k in ['push_ssl', 'publish']:
100 v = str2bool(v)
100 v = str2bool(v)
101
101
102 if k.find('.') != -1:
102 if k.find('.') != -1:
103 k = k.replace('.', '_')
103 k = k.replace('.', '_')
104
104
105 if each.ui_section in ['hooks', 'extensions']:
105 if each.ui_section in ['hooks', 'extensions']:
106 v = each.ui_active
106 v = each.ui_active
107
107
108 settings[each.ui_section + '_' + k] = v
108 settings[each.ui_section + '_' + k] = v
109 return settings
109 return settings
110
110
111 @HasPermissionAllDecorator('hg.admin')
111 @HasPermissionAllDecorator('hg.admin')
112 @auth.CSRFRequired()
112 @auth.CSRFRequired()
113 @jsonify
113 @jsonify
114 def delete_svn_pattern(self):
114 def delete_svn_pattern(self):
115 if not request.is_xhr:
115 if not request.is_xhr:
116 raise HTTPBadRequest()
116 raise HTTPBadRequest()
117
117
118 delete_pattern_id = request.POST.get('delete_svn_pattern')
118 delete_pattern_id = request.POST.get('delete_svn_pattern')
119 model = VcsSettingsModel()
119 model = VcsSettingsModel()
120 try:
120 try:
121 model.delete_global_svn_pattern(delete_pattern_id)
121 model.delete_global_svn_pattern(delete_pattern_id)
122 except SettingNotFound:
122 except SettingNotFound:
123 raise HTTPBadRequest()
123 raise HTTPBadRequest()
124
124
125 Session().commit()
125 Session().commit()
126 return True
126 return True
127
127
128 @HasPermissionAllDecorator('hg.admin')
128 @HasPermissionAllDecorator('hg.admin')
129 @auth.CSRFRequired()
129 @auth.CSRFRequired()
130 def settings_vcs_update(self):
130 def settings_vcs_update(self):
131 """POST /admin/settings: All items in the collection"""
131 """POST /admin/settings: All items in the collection"""
132 # url('admin_settings_vcs')
132 # url('admin_settings_vcs')
133 c.active = 'vcs'
133 c.active = 'vcs'
134
134
135 model = VcsSettingsModel()
135 model = VcsSettingsModel()
136 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
136 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
137 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
137 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
138
138
139 # TODO: Replace with request.registry after migrating to pyramid.
140 pyramid_settings = get_current_registry().settings
141 c.svn_proxy_generate_config = pyramid_settings[generate_config]
142
139 application_form = ApplicationUiSettingsForm()()
143 application_form = ApplicationUiSettingsForm()()
140
144
141 try:
145 try:
142 form_result = application_form.to_python(dict(request.POST))
146 form_result = application_form.to_python(dict(request.POST))
143 except formencode.Invalid as errors:
147 except formencode.Invalid as errors:
144 h.flash(
148 h.flash(
145 _("Some form inputs contain invalid data."),
149 _("Some form inputs contain invalid data."),
146 category='error')
150 category='error')
147 return htmlfill.render(
151 return htmlfill.render(
148 render('admin/settings/settings.html'),
152 render('admin/settings/settings.html'),
149 defaults=errors.value,
153 defaults=errors.value,
150 errors=errors.error_dict or {},
154 errors=errors.error_dict or {},
151 prefix_error=False,
155 prefix_error=False,
152 encoding="UTF-8",
156 encoding="UTF-8",
153 force_defaults=False
157 force_defaults=False
154 )
158 )
155
159
156 try:
160 try:
157 if c.visual.allow_repo_location_change:
161 if c.visual.allow_repo_location_change:
158 model.update_global_path_setting(
162 model.update_global_path_setting(
159 form_result['paths_root_path'])
163 form_result['paths_root_path'])
160
164
161 model.update_global_ssl_setting(form_result['web_push_ssl'])
165 model.update_global_ssl_setting(form_result['web_push_ssl'])
162 model.update_global_hook_settings(form_result)
166 model.update_global_hook_settings(form_result)
163
167
164 model.create_or_update_global_svn_settings(form_result)
168 model.create_or_update_global_svn_settings(form_result)
165 model.create_or_update_global_hg_settings(form_result)
169 model.create_or_update_global_hg_settings(form_result)
166 model.create_or_update_global_pr_settings(form_result)
170 model.create_or_update_global_pr_settings(form_result)
167 except Exception:
171 except Exception:
168 log.exception("Exception while updating settings")
172 log.exception("Exception while updating settings")
169 h.flash(_('Error occurred during updating '
173 h.flash(_('Error occurred during updating '
170 'application settings'), category='error')
174 'application settings'), category='error')
171 else:
175 else:
172 Session().commit()
176 Session().commit()
173 h.flash(_('Updated VCS settings'), category='success')
177 h.flash(_('Updated VCS settings'), category='success')
174 return redirect(url('admin_settings_vcs'))
178 return redirect(url('admin_settings_vcs'))
175
179
176 return htmlfill.render(
180 return htmlfill.render(
177 render('admin/settings/settings.html'),
181 render('admin/settings/settings.html'),
178 defaults=self._form_defaults(),
182 defaults=self._form_defaults(),
179 encoding="UTF-8",
183 encoding="UTF-8",
180 force_defaults=False)
184 force_defaults=False)
181
185
182 @HasPermissionAllDecorator('hg.admin')
186 @HasPermissionAllDecorator('hg.admin')
183 def settings_vcs(self):
187 def settings_vcs(self):
184 """GET /admin/settings: All items in the collection"""
188 """GET /admin/settings: All items in the collection"""
185 # url('admin_settings_vcs')
189 # url('admin_settings_vcs')
186 c.active = 'vcs'
190 c.active = 'vcs'
187 model = VcsSettingsModel()
191 model = VcsSettingsModel()
188 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
192 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
189 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
193 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
190
194
191 # TODO: Replace with request.registry after migrating to pyramid.
195 # TODO: Replace with request.registry after migrating to pyramid.
192 pyramid_settings = get_current_registry().settings
196 pyramid_settings = get_current_registry().settings
193 c.svn_proxy_generate_config = pyramid_settings[generate_config]
197 c.svn_proxy_generate_config = pyramid_settings[generate_config]
194
198
195 return htmlfill.render(
199 return htmlfill.render(
196 render('admin/settings/settings.html'),
200 render('admin/settings/settings.html'),
197 defaults=self._form_defaults(),
201 defaults=self._form_defaults(),
198 encoding="UTF-8",
202 encoding="UTF-8",
199 force_defaults=False)
203 force_defaults=False)
200
204
201 @HasPermissionAllDecorator('hg.admin')
205 @HasPermissionAllDecorator('hg.admin')
202 @auth.CSRFRequired()
206 @auth.CSRFRequired()
203 def settings_mapping_update(self):
207 def settings_mapping_update(self):
204 """POST /admin/settings/mapping: All items in the collection"""
208 """POST /admin/settings/mapping: All items in the collection"""
205 # url('admin_settings_mapping')
209 # url('admin_settings_mapping')
206 c.active = 'mapping'
210 c.active = 'mapping'
207 rm_obsolete = request.POST.get('destroy', False)
211 rm_obsolete = request.POST.get('destroy', False)
208 invalidate_cache = request.POST.get('invalidate', False)
212 invalidate_cache = request.POST.get('invalidate', False)
209 log.debug(
213 log.debug(
210 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
214 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
211
215
212 if invalidate_cache:
216 if invalidate_cache:
213 log.debug('invalidating all repositories cache')
217 log.debug('invalidating all repositories cache')
214 for repo in Repository.get_all():
218 for repo in Repository.get_all():
215 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
219 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
216
220
217 filesystem_repos = ScmModel().repo_scan()
221 filesystem_repos = ScmModel().repo_scan()
218 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
222 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
219 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
223 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
220 h.flash(_('Repositories successfully '
224 h.flash(_('Repositories successfully '
221 'rescanned added: %s ; removed: %s') %
225 'rescanned added: %s ; removed: %s') %
222 (_repr(added), _repr(removed)),
226 (_repr(added), _repr(removed)),
223 category='success')
227 category='success')
224 return redirect(url('admin_settings_mapping'))
228 return redirect(url('admin_settings_mapping'))
225
229
226 @HasPermissionAllDecorator('hg.admin')
230 @HasPermissionAllDecorator('hg.admin')
227 def settings_mapping(self):
231 def settings_mapping(self):
228 """GET /admin/settings/mapping: All items in the collection"""
232 """GET /admin/settings/mapping: All items in the collection"""
229 # url('admin_settings_mapping')
233 # url('admin_settings_mapping')
230 c.active = 'mapping'
234 c.active = 'mapping'
231
235
232 return htmlfill.render(
236 return htmlfill.render(
233 render('admin/settings/settings.html'),
237 render('admin/settings/settings.html'),
234 defaults=self._form_defaults(),
238 defaults=self._form_defaults(),
235 encoding="UTF-8",
239 encoding="UTF-8",
236 force_defaults=False)
240 force_defaults=False)
237
241
238 @HasPermissionAllDecorator('hg.admin')
242 @HasPermissionAllDecorator('hg.admin')
239 @auth.CSRFRequired()
243 @auth.CSRFRequired()
240 def settings_global_update(self):
244 def settings_global_update(self):
241 """POST /admin/settings/global: All items in the collection"""
245 """POST /admin/settings/global: All items in the collection"""
242 # url('admin_settings_global')
246 # url('admin_settings_global')
243 c.active = 'global'
247 c.active = 'global'
244 application_form = ApplicationSettingsForm()()
248 application_form = ApplicationSettingsForm()()
245 try:
249 try:
246 form_result = application_form.to_python(dict(request.POST))
250 form_result = application_form.to_python(dict(request.POST))
247 except formencode.Invalid as errors:
251 except formencode.Invalid as errors:
248 return htmlfill.render(
252 return htmlfill.render(
249 render('admin/settings/settings.html'),
253 render('admin/settings/settings.html'),
250 defaults=errors.value,
254 defaults=errors.value,
251 errors=errors.error_dict or {},
255 errors=errors.error_dict or {},
252 prefix_error=False,
256 prefix_error=False,
253 encoding="UTF-8",
257 encoding="UTF-8",
254 force_defaults=False)
258 force_defaults=False)
255
259
256 try:
260 try:
257 settings = [
261 settings = [
258 ('title', 'rhodecode_title'),
262 ('title', 'rhodecode_title'),
259 ('realm', 'rhodecode_realm'),
263 ('realm', 'rhodecode_realm'),
260 ('pre_code', 'rhodecode_pre_code'),
264 ('pre_code', 'rhodecode_pre_code'),
261 ('post_code', 'rhodecode_post_code'),
265 ('post_code', 'rhodecode_post_code'),
262 ('captcha_public_key', 'rhodecode_captcha_public_key'),
266 ('captcha_public_key', 'rhodecode_captcha_public_key'),
263 ('captcha_private_key', 'rhodecode_captcha_private_key'),
267 ('captcha_private_key', 'rhodecode_captcha_private_key'),
264 ]
268 ]
265 for setting, form_key in settings:
269 for setting, form_key in settings:
266 sett = SettingsModel().create_or_update_setting(
270 sett = SettingsModel().create_or_update_setting(
267 setting, form_result[form_key])
271 setting, form_result[form_key])
268 Session().add(sett)
272 Session().add(sett)
269
273
270 Session().commit()
274 Session().commit()
271 SettingsModel().invalidate_settings_cache()
275 SettingsModel().invalidate_settings_cache()
272 h.flash(_('Updated application settings'), category='success')
276 h.flash(_('Updated application settings'), category='success')
273 except Exception:
277 except Exception:
274 log.exception("Exception while updating application settings")
278 log.exception("Exception while updating application settings")
275 h.flash(
279 h.flash(
276 _('Error occurred during updating application settings'),
280 _('Error occurred during updating application settings'),
277 category='error')
281 category='error')
278
282
279 return redirect(url('admin_settings_global'))
283 return redirect(url('admin_settings_global'))
280
284
281 @HasPermissionAllDecorator('hg.admin')
285 @HasPermissionAllDecorator('hg.admin')
282 def settings_global(self):
286 def settings_global(self):
283 """GET /admin/settings/global: All items in the collection"""
287 """GET /admin/settings/global: All items in the collection"""
284 # url('admin_settings_global')
288 # url('admin_settings_global')
285 c.active = 'global'
289 c.active = 'global'
286
290
287 return htmlfill.render(
291 return htmlfill.render(
288 render('admin/settings/settings.html'),
292 render('admin/settings/settings.html'),
289 defaults=self._form_defaults(),
293 defaults=self._form_defaults(),
290 encoding="UTF-8",
294 encoding="UTF-8",
291 force_defaults=False)
295 force_defaults=False)
292
296
293 @HasPermissionAllDecorator('hg.admin')
297 @HasPermissionAllDecorator('hg.admin')
294 @auth.CSRFRequired()
298 @auth.CSRFRequired()
295 def settings_visual_update(self):
299 def settings_visual_update(self):
296 """POST /admin/settings/visual: All items in the collection"""
300 """POST /admin/settings/visual: All items in the collection"""
297 # url('admin_settings_visual')
301 # url('admin_settings_visual')
298 c.active = 'visual'
302 c.active = 'visual'
299 application_form = ApplicationVisualisationForm()()
303 application_form = ApplicationVisualisationForm()()
300 try:
304 try:
301 form_result = application_form.to_python(dict(request.POST))
305 form_result = application_form.to_python(dict(request.POST))
302 except formencode.Invalid as errors:
306 except formencode.Invalid as errors:
303 return htmlfill.render(
307 return htmlfill.render(
304 render('admin/settings/settings.html'),
308 render('admin/settings/settings.html'),
305 defaults=errors.value,
309 defaults=errors.value,
306 errors=errors.error_dict or {},
310 errors=errors.error_dict or {},
307 prefix_error=False,
311 prefix_error=False,
308 encoding="UTF-8",
312 encoding="UTF-8",
309 force_defaults=False
313 force_defaults=False
310 )
314 )
311
315
312 try:
316 try:
313 settings = [
317 settings = [
314 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
318 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
315 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
319 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
316 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
320 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
317 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
321 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
318 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
322 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
319 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
323 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
320 ('show_version', 'rhodecode_show_version', 'bool'),
324 ('show_version', 'rhodecode_show_version', 'bool'),
321 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
325 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
322 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
326 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
323 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
327 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
324 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
328 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
325 ('support_url', 'rhodecode_support_url', 'unicode'),
329 ('support_url', 'rhodecode_support_url', 'unicode'),
326 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
330 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
327 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
331 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
328 ]
332 ]
329 for setting, form_key, type_ in settings:
333 for setting, form_key, type_ in settings:
330 sett = SettingsModel().create_or_update_setting(
334 sett = SettingsModel().create_or_update_setting(
331 setting, form_result[form_key], type_)
335 setting, form_result[form_key], type_)
332 Session().add(sett)
336 Session().add(sett)
333
337
334 Session().commit()
338 Session().commit()
335 SettingsModel().invalidate_settings_cache()
339 SettingsModel().invalidate_settings_cache()
336 h.flash(_('Updated visualisation settings'), category='success')
340 h.flash(_('Updated visualisation settings'), category='success')
337 except Exception:
341 except Exception:
338 log.exception("Exception updating visualization settings")
342 log.exception("Exception updating visualization settings")
339 h.flash(_('Error occurred during updating '
343 h.flash(_('Error occurred during updating '
340 'visualisation settings'),
344 'visualisation settings'),
341 category='error')
345 category='error')
342
346
343 return redirect(url('admin_settings_visual'))
347 return redirect(url('admin_settings_visual'))
344
348
345 @HasPermissionAllDecorator('hg.admin')
349 @HasPermissionAllDecorator('hg.admin')
346 def settings_visual(self):
350 def settings_visual(self):
347 """GET /admin/settings/visual: All items in the collection"""
351 """GET /admin/settings/visual: All items in the collection"""
348 # url('admin_settings_visual')
352 # url('admin_settings_visual')
349 c.active = 'visual'
353 c.active = 'visual'
350
354
351 return htmlfill.render(
355 return htmlfill.render(
352 render('admin/settings/settings.html'),
356 render('admin/settings/settings.html'),
353 defaults=self._form_defaults(),
357 defaults=self._form_defaults(),
354 encoding="UTF-8",
358 encoding="UTF-8",
355 force_defaults=False)
359 force_defaults=False)
356
360
357 @HasPermissionAllDecorator('hg.admin')
361 @HasPermissionAllDecorator('hg.admin')
358 @auth.CSRFRequired()
362 @auth.CSRFRequired()
359 def settings_issuetracker_test(self):
363 def settings_issuetracker_test(self):
360 if request.is_xhr:
364 if request.is_xhr:
361 return h.urlify_commit_message(
365 return h.urlify_commit_message(
362 request.POST.get('test_text', ''),
366 request.POST.get('test_text', ''),
363 'repo_group/test_repo1')
367 'repo_group/test_repo1')
364 else:
368 else:
365 raise HTTPBadRequest()
369 raise HTTPBadRequest()
366
370
367 @HasPermissionAllDecorator('hg.admin')
371 @HasPermissionAllDecorator('hg.admin')
368 @auth.CSRFRequired()
372 @auth.CSRFRequired()
369 def settings_issuetracker_delete(self):
373 def settings_issuetracker_delete(self):
370 uid = request.POST.get('uid')
374 uid = request.POST.get('uid')
371 IssueTrackerSettingsModel().delete_entries(uid)
375 IssueTrackerSettingsModel().delete_entries(uid)
372 h.flash(_('Removed issue tracker entry'), category='success')
376 h.flash(_('Removed issue tracker entry'), category='success')
373 return redirect(url('admin_settings_issuetracker'))
377 return redirect(url('admin_settings_issuetracker'))
374
378
375 @HasPermissionAllDecorator('hg.admin')
379 @HasPermissionAllDecorator('hg.admin')
376 def settings_issuetracker(self):
380 def settings_issuetracker(self):
377 """GET /admin/settings/issue-tracker: All items in the collection"""
381 """GET /admin/settings/issue-tracker: All items in the collection"""
378 # url('admin_settings_issuetracker')
382 # url('admin_settings_issuetracker')
379 c.active = 'issuetracker'
383 c.active = 'issuetracker'
380 defaults = SettingsModel().get_all_settings()
384 defaults = SettingsModel().get_all_settings()
381
385
382 entry_key = 'rhodecode_issuetracker_pat_'
386 entry_key = 'rhodecode_issuetracker_pat_'
383
387
384 c.issuetracker_entries = {}
388 c.issuetracker_entries = {}
385 for k, v in defaults.items():
389 for k, v in defaults.items():
386 if k.startswith(entry_key):
390 if k.startswith(entry_key):
387 uid = k[len(entry_key):]
391 uid = k[len(entry_key):]
388 c.issuetracker_entries[uid] = None
392 c.issuetracker_entries[uid] = None
389
393
390 for uid in c.issuetracker_entries:
394 for uid in c.issuetracker_entries:
391 c.issuetracker_entries[uid] = AttributeDict({
395 c.issuetracker_entries[uid] = AttributeDict({
392 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
396 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
393 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
397 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
394 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
398 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
395 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
399 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
396 })
400 })
397
401
398 return render('admin/settings/settings.html')
402 return render('admin/settings/settings.html')
399
403
400 @HasPermissionAllDecorator('hg.admin')
404 @HasPermissionAllDecorator('hg.admin')
401 @auth.CSRFRequired()
405 @auth.CSRFRequired()
402 def settings_issuetracker_save(self):
406 def settings_issuetracker_save(self):
403 settings_model = IssueTrackerSettingsModel()
407 settings_model = IssueTrackerSettingsModel()
404
408
405 form = IssueTrackerPatternsForm()().to_python(request.POST)
409 form = IssueTrackerPatternsForm()().to_python(request.POST)
406 if form:
410 if form:
407 for uid in form.get('delete_patterns', []):
411 for uid in form.get('delete_patterns', []):
408 settings_model.delete_entries(uid)
412 settings_model.delete_entries(uid)
409
413
410 for pattern in form.get('patterns', []):
414 for pattern in form.get('patterns', []):
411 for setting, value, type_ in pattern:
415 for setting, value, type_ in pattern:
412 sett = settings_model.create_or_update_setting(
416 sett = settings_model.create_or_update_setting(
413 setting, value, type_)
417 setting, value, type_)
414 Session().add(sett)
418 Session().add(sett)
415
419
416 Session().commit()
420 Session().commit()
417
421
418 SettingsModel().invalidate_settings_cache()
422 SettingsModel().invalidate_settings_cache()
419 h.flash(_('Updated issue tracker entries'), category='success')
423 h.flash(_('Updated issue tracker entries'), category='success')
420 return redirect(url('admin_settings_issuetracker'))
424 return redirect(url('admin_settings_issuetracker'))
421
425
422 @HasPermissionAllDecorator('hg.admin')
426 @HasPermissionAllDecorator('hg.admin')
423 @auth.CSRFRequired()
427 @auth.CSRFRequired()
424 def settings_email_update(self):
428 def settings_email_update(self):
425 """POST /admin/settings/email: All items in the collection"""
429 """POST /admin/settings/email: All items in the collection"""
426 # url('admin_settings_email')
430 # url('admin_settings_email')
427 c.active = 'email'
431 c.active = 'email'
428
432
429 test_email = request.POST.get('test_email')
433 test_email = request.POST.get('test_email')
430
434
431 if not test_email:
435 if not test_email:
432 h.flash(_('Please enter email address'), category='error')
436 h.flash(_('Please enter email address'), category='error')
433 return redirect(url('admin_settings_email'))
437 return redirect(url('admin_settings_email'))
434
438
435 email_kwargs = {
439 email_kwargs = {
436 'date': datetime.datetime.now(),
440 'date': datetime.datetime.now(),
437 'user': c.rhodecode_user,
441 'user': c.rhodecode_user,
438 'rhodecode_version': c.rhodecode_version
442 'rhodecode_version': c.rhodecode_version
439 }
443 }
440
444
441 (subject, headers, email_body,
445 (subject, headers, email_body,
442 email_body_plaintext) = EmailNotificationModel().render_email(
446 email_body_plaintext) = EmailNotificationModel().render_email(
443 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
447 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
444
448
445 recipients = [test_email] if test_email else None
449 recipients = [test_email] if test_email else None
446
450
447 run_task(tasks.send_email, recipients, subject,
451 run_task(tasks.send_email, recipients, subject,
448 email_body_plaintext, email_body)
452 email_body_plaintext, email_body)
449
453
450 h.flash(_('Send email task created'), category='success')
454 h.flash(_('Send email task created'), category='success')
451 return redirect(url('admin_settings_email'))
455 return redirect(url('admin_settings_email'))
452
456
453 @HasPermissionAllDecorator('hg.admin')
457 @HasPermissionAllDecorator('hg.admin')
454 def settings_email(self):
458 def settings_email(self):
455 """GET /admin/settings/email: All items in the collection"""
459 """GET /admin/settings/email: All items in the collection"""
456 # url('admin_settings_email')
460 # url('admin_settings_email')
457 c.active = 'email'
461 c.active = 'email'
458 c.rhodecode_ini = rhodecode.CONFIG
462 c.rhodecode_ini = rhodecode.CONFIG
459
463
460 return htmlfill.render(
464 return htmlfill.render(
461 render('admin/settings/settings.html'),
465 render('admin/settings/settings.html'),
462 defaults=self._form_defaults(),
466 defaults=self._form_defaults(),
463 encoding="UTF-8",
467 encoding="UTF-8",
464 force_defaults=False)
468 force_defaults=False)
465
469
466 @HasPermissionAllDecorator('hg.admin')
470 @HasPermissionAllDecorator('hg.admin')
467 @auth.CSRFRequired()
471 @auth.CSRFRequired()
468 def settings_hooks_update(self):
472 def settings_hooks_update(self):
469 """POST or DELETE /admin/settings/hooks: All items in the collection"""
473 """POST or DELETE /admin/settings/hooks: All items in the collection"""
470 # url('admin_settings_hooks')
474 # url('admin_settings_hooks')
471 c.active = 'hooks'
475 c.active = 'hooks'
472 if c.visual.allow_custom_hooks_settings:
476 if c.visual.allow_custom_hooks_settings:
473 ui_key = request.POST.get('new_hook_ui_key')
477 ui_key = request.POST.get('new_hook_ui_key')
474 ui_value = request.POST.get('new_hook_ui_value')
478 ui_value = request.POST.get('new_hook_ui_value')
475
479
476 hook_id = request.POST.get('hook_id')
480 hook_id = request.POST.get('hook_id')
477 new_hook = False
481 new_hook = False
478
482
479 model = SettingsModel()
483 model = SettingsModel()
480 try:
484 try:
481 if ui_value and ui_key:
485 if ui_value and ui_key:
482 model.create_or_update_hook(ui_key, ui_value)
486 model.create_or_update_hook(ui_key, ui_value)
483 h.flash(_('Added new hook'), category='success')
487 h.flash(_('Added new hook'), category='success')
484 new_hook = True
488 new_hook = True
485 elif hook_id:
489 elif hook_id:
486 RhodeCodeUi.delete(hook_id)
490 RhodeCodeUi.delete(hook_id)
487 Session().commit()
491 Session().commit()
488
492
489 # check for edits
493 # check for edits
490 update = False
494 update = False
491 _d = request.POST.dict_of_lists()
495 _d = request.POST.dict_of_lists()
492 for k, v in zip(_d.get('hook_ui_key', []),
496 for k, v in zip(_d.get('hook_ui_key', []),
493 _d.get('hook_ui_value_new', [])):
497 _d.get('hook_ui_value_new', [])):
494 model.create_or_update_hook(k, v)
498 model.create_or_update_hook(k, v)
495 update = True
499 update = True
496
500
497 if update and not new_hook:
501 if update and not new_hook:
498 h.flash(_('Updated hooks'), category='success')
502 h.flash(_('Updated hooks'), category='success')
499 Session().commit()
503 Session().commit()
500 except Exception:
504 except Exception:
501 log.exception("Exception during hook creation")
505 log.exception("Exception during hook creation")
502 h.flash(_('Error occurred during hook creation'),
506 h.flash(_('Error occurred during hook creation'),
503 category='error')
507 category='error')
504
508
505 return redirect(url('admin_settings_hooks'))
509 return redirect(url('admin_settings_hooks'))
506
510
507 @HasPermissionAllDecorator('hg.admin')
511 @HasPermissionAllDecorator('hg.admin')
508 def settings_hooks(self):
512 def settings_hooks(self):
509 """GET /admin/settings/hooks: All items in the collection"""
513 """GET /admin/settings/hooks: All items in the collection"""
510 # url('admin_settings_hooks')
514 # url('admin_settings_hooks')
511 c.active = 'hooks'
515 c.active = 'hooks'
512
516
513 model = SettingsModel()
517 model = SettingsModel()
514 c.hooks = model.get_builtin_hooks()
518 c.hooks = model.get_builtin_hooks()
515 c.custom_hooks = model.get_custom_hooks()
519 c.custom_hooks = model.get_custom_hooks()
516
520
517 return htmlfill.render(
521 return htmlfill.render(
518 render('admin/settings/settings.html'),
522 render('admin/settings/settings.html'),
519 defaults=self._form_defaults(),
523 defaults=self._form_defaults(),
520 encoding="UTF-8",
524 encoding="UTF-8",
521 force_defaults=False)
525 force_defaults=False)
522
526
523 @HasPermissionAllDecorator('hg.admin')
527 @HasPermissionAllDecorator('hg.admin')
524 def settings_search(self):
528 def settings_search(self):
525 """GET /admin/settings/search: All items in the collection"""
529 """GET /admin/settings/search: All items in the collection"""
526 # url('admin_settings_search')
530 # url('admin_settings_search')
527 c.active = 'search'
531 c.active = 'search'
528
532
529 from rhodecode.lib.index import searcher_from_config
533 from rhodecode.lib.index import searcher_from_config
530 searcher = searcher_from_config(config)
534 searcher = searcher_from_config(config)
531 c.statistics = searcher.statistics()
535 c.statistics = searcher.statistics()
532
536
533 return render('admin/settings/settings.html')
537 return render('admin/settings/settings.html')
534
538
535 @HasPermissionAllDecorator('hg.admin')
539 @HasPermissionAllDecorator('hg.admin')
536 def settings_system(self):
540 def settings_system(self):
537 """GET /admin/settings/system: All items in the collection"""
541 """GET /admin/settings/system: All items in the collection"""
538 # url('admin_settings_system')
542 # url('admin_settings_system')
539 snapshot = str2bool(request.GET.get('snapshot'))
543 snapshot = str2bool(request.GET.get('snapshot'))
540 c.active = 'system'
544 c.active = 'system'
541
545
542 defaults = self._form_defaults()
546 defaults = self._form_defaults()
543 c.rhodecode_ini = rhodecode.CONFIG
547 c.rhodecode_ini = rhodecode.CONFIG
544 c.rhodecode_update_url = defaults.get('rhodecode_update_url')
548 c.rhodecode_update_url = defaults.get('rhodecode_update_url')
545 server_info = ScmModel().get_server_info(request.environ)
549 server_info = ScmModel().get_server_info(request.environ)
546 for key, val in server_info.iteritems():
550 for key, val in server_info.iteritems():
547 setattr(c, key, val)
551 setattr(c, key, val)
548
552
549 if c.disk['percent'] > 90:
553 if c.disk['percent'] > 90:
550 h.flash(h.literal(_(
554 h.flash(h.literal(_(
551 'Critical: your disk space is very low <b>%s%%</b> used' %
555 'Critical: your disk space is very low <b>%s%%</b> used' %
552 c.disk['percent'])), 'error')
556 c.disk['percent'])), 'error')
553 elif c.disk['percent'] > 70:
557 elif c.disk['percent'] > 70:
554 h.flash(h.literal(_(
558 h.flash(h.literal(_(
555 'Warning: your disk space is running low <b>%s%%</b> used' %
559 'Warning: your disk space is running low <b>%s%%</b> used' %
556 c.disk['percent'])), 'warning')
560 c.disk['percent'])), 'warning')
557
561
558 try:
562 try:
559 c.uptime_age = h._age(
563 c.uptime_age = h._age(
560 h.time_to_datetime(c.boot_time), False, show_suffix=False)
564 h.time_to_datetime(c.boot_time), False, show_suffix=False)
561 except TypeError:
565 except TypeError:
562 c.uptime_age = c.boot_time
566 c.uptime_age = c.boot_time
563
567
564 try:
568 try:
565 c.system_memory = '%s/%s, %s%% (%s%%) used%s' % (
569 c.system_memory = '%s/%s, %s%% (%s%%) used%s' % (
566 h.format_byte_size_binary(c.memory['used']),
570 h.format_byte_size_binary(c.memory['used']),
567 h.format_byte_size_binary(c.memory['total']),
571 h.format_byte_size_binary(c.memory['total']),
568 c.memory['percent2'],
572 c.memory['percent2'],
569 c.memory['percent'],
573 c.memory['percent'],
570 ' %s' % c.memory['error'] if 'error' in c.memory else '')
574 ' %s' % c.memory['error'] if 'error' in c.memory else '')
571 except TypeError:
575 except TypeError:
572 c.system_memory = 'NOT AVAILABLE'
576 c.system_memory = 'NOT AVAILABLE'
573
577
574 rhodecode_ini_safe = rhodecode.CONFIG.copy()
578 rhodecode_ini_safe = rhodecode.CONFIG.copy()
575 blacklist = [
579 blacklist = [
576 'rhodecode_license_key',
580 'rhodecode_license_key',
577 'routes.map',
581 'routes.map',
578 'pylons.h',
582 'pylons.h',
579 'pylons.app_globals',
583 'pylons.app_globals',
580 'pylons.environ_config',
584 'pylons.environ_config',
581 'sqlalchemy.db1.url',
585 'sqlalchemy.db1.url',
582 ('app_conf', 'sqlalchemy.db1.url')
586 ('app_conf', 'sqlalchemy.db1.url')
583 ]
587 ]
584 for k in blacklist:
588 for k in blacklist:
585 if isinstance(k, tuple):
589 if isinstance(k, tuple):
586 section, key = k
590 section, key = k
587 if section in rhodecode_ini_safe:
591 if section in rhodecode_ini_safe:
588 rhodecode_ini_safe[section].pop(key, None)
592 rhodecode_ini_safe[section].pop(key, None)
589 else:
593 else:
590 rhodecode_ini_safe.pop(k, None)
594 rhodecode_ini_safe.pop(k, None)
591
595
592 c.rhodecode_ini_safe = rhodecode_ini_safe
596 c.rhodecode_ini_safe = rhodecode_ini_safe
593
597
594 # TODO: marcink, figure out how to allow only selected users to do this
598 # TODO: marcink, figure out how to allow only selected users to do this
595 c.allowed_to_snapshot = False
599 c.allowed_to_snapshot = False
596
600
597 if snapshot:
601 if snapshot:
598 if c.allowed_to_snapshot:
602 if c.allowed_to_snapshot:
599 return render('admin/settings/settings_system_snapshot.html')
603 return render('admin/settings/settings_system_snapshot.html')
600 else:
604 else:
601 h.flash('You are not allowed to do this', category='warning')
605 h.flash('You are not allowed to do this', category='warning')
602
606
603 return htmlfill.render(
607 return htmlfill.render(
604 render('admin/settings/settings.html'),
608 render('admin/settings/settings.html'),
605 defaults=defaults,
609 defaults=defaults,
606 encoding="UTF-8",
610 encoding="UTF-8",
607 force_defaults=False)
611 force_defaults=False)
608
612
609 @staticmethod
613 @staticmethod
610 def get_update_data(update_url):
614 def get_update_data(update_url):
611 """Return the JSON update data."""
615 """Return the JSON update data."""
612 ver = rhodecode.__version__
616 ver = rhodecode.__version__
613 log.debug('Checking for upgrade on `%s` server', update_url)
617 log.debug('Checking for upgrade on `%s` server', update_url)
614 opener = urllib2.build_opener()
618 opener = urllib2.build_opener()
615 opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)]
619 opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)]
616 response = opener.open(update_url)
620 response = opener.open(update_url)
617 response_data = response.read()
621 response_data = response.read()
618 data = json.loads(response_data)
622 data = json.loads(response_data)
619
623
620 return data
624 return data
621
625
622 @HasPermissionAllDecorator('hg.admin')
626 @HasPermissionAllDecorator('hg.admin')
623 def settings_system_update(self):
627 def settings_system_update(self):
624 """GET /admin/settings/system/updates: All items in the collection"""
628 """GET /admin/settings/system/updates: All items in the collection"""
625 # url('admin_settings_system_update')
629 # url('admin_settings_system_update')
626 defaults = self._form_defaults()
630 defaults = self._form_defaults()
627 update_url = defaults.get('rhodecode_update_url', '')
631 update_url = defaults.get('rhodecode_update_url', '')
628
632
629 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s)
633 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s)
630 try:
634 try:
631 data = self.get_update_data(update_url)
635 data = self.get_update_data(update_url)
632 except urllib2.URLError as e:
636 except urllib2.URLError as e:
633 log.exception("Exception contacting upgrade server")
637 log.exception("Exception contacting upgrade server")
634 return _err('Failed to contact upgrade server: %r' % e)
638 return _err('Failed to contact upgrade server: %r' % e)
635 except ValueError as e:
639 except ValueError as e:
636 log.exception("Bad data sent from update server")
640 log.exception("Bad data sent from update server")
637 return _err('Bad data sent from update server')
641 return _err('Bad data sent from update server')
638
642
639 latest = data['versions'][0]
643 latest = data['versions'][0]
640
644
641 c.update_url = update_url
645 c.update_url = update_url
642 c.latest_data = latest
646 c.latest_data = latest
643 c.latest_ver = latest['version']
647 c.latest_ver = latest['version']
644 c.cur_ver = rhodecode.__version__
648 c.cur_ver = rhodecode.__version__
645 c.should_upgrade = False
649 c.should_upgrade = False
646
650
647 if (packaging.version.Version(c.latest_ver) >
651 if (packaging.version.Version(c.latest_ver) >
648 packaging.version.Version(c.cur_ver)):
652 packaging.version.Version(c.cur_ver)):
649 c.should_upgrade = True
653 c.should_upgrade = True
650 c.important_notices = latest['general']
654 c.important_notices = latest['general']
651
655
652 return render('admin/settings/settings_system_update.html')
656 return render('admin/settings/settings_system_update.html')
653
657
654 @HasPermissionAllDecorator('hg.admin')
658 @HasPermissionAllDecorator('hg.admin')
655 def settings_supervisor(self):
659 def settings_supervisor(self):
656 c.rhodecode_ini = rhodecode.CONFIG
660 c.rhodecode_ini = rhodecode.CONFIG
657 c.active = 'supervisor'
661 c.active = 'supervisor'
658
662
659 c.supervisor_procs = OrderedDict([
663 c.supervisor_procs = OrderedDict([
660 (SUPERVISOR_MASTER, {}),
664 (SUPERVISOR_MASTER, {}),
661 ])
665 ])
662
666
663 c.log_size = 10240
667 c.log_size = 10240
664 supervisor = SupervisorModel()
668 supervisor = SupervisorModel()
665
669
666 _connection = supervisor.get_connection(
670 _connection = supervisor.get_connection(
667 c.rhodecode_ini.get('supervisor.uri'))
671 c.rhodecode_ini.get('supervisor.uri'))
668 c.connection_error = None
672 c.connection_error = None
669 try:
673 try:
670 _connection.supervisor.getAllProcessInfo()
674 _connection.supervisor.getAllProcessInfo()
671 except Exception as e:
675 except Exception as e:
672 c.connection_error = str(e)
676 c.connection_error = str(e)
673 log.exception("Exception reading supervisor data")
677 log.exception("Exception reading supervisor data")
674 return render('admin/settings/settings.html')
678 return render('admin/settings/settings.html')
675
679
676 groupid = c.rhodecode_ini.get('supervisor.group_id')
680 groupid = c.rhodecode_ini.get('supervisor.group_id')
677
681
678 # feed our group processes to the main
682 # feed our group processes to the main
679 for proc in supervisor.get_group_processes(_connection, groupid):
683 for proc in supervisor.get_group_processes(_connection, groupid):
680 c.supervisor_procs[proc['name']] = {}
684 c.supervisor_procs[proc['name']] = {}
681
685
682 for k in c.supervisor_procs.keys():
686 for k in c.supervisor_procs.keys():
683 try:
687 try:
684 # master process info
688 # master process info
685 if k == SUPERVISOR_MASTER:
689 if k == SUPERVISOR_MASTER:
686 _data = supervisor.get_master_state(_connection)
690 _data = supervisor.get_master_state(_connection)
687 _data['name'] = 'supervisor master'
691 _data['name'] = 'supervisor master'
688 _data['description'] = 'pid %s, id: %s, ver: %s' % (
692 _data['description'] = 'pid %s, id: %s, ver: %s' % (
689 _data['pid'], _data['id'], _data['ver'])
693 _data['pid'], _data['id'], _data['ver'])
690 c.supervisor_procs[k] = _data
694 c.supervisor_procs[k] = _data
691 else:
695 else:
692 procid = groupid + ":" + k
696 procid = groupid + ":" + k
693 c.supervisor_procs[k] = supervisor.get_process_info(_connection, procid)
697 c.supervisor_procs[k] = supervisor.get_process_info(_connection, procid)
694 except Exception as e:
698 except Exception as e:
695 log.exception("Exception reading supervisor data")
699 log.exception("Exception reading supervisor data")
696 c.supervisor_procs[k] = {'_rhodecode_error': str(e)}
700 c.supervisor_procs[k] = {'_rhodecode_error': str(e)}
697
701
698 return render('admin/settings/settings.html')
702 return render('admin/settings/settings.html')
699
703
700 @HasPermissionAllDecorator('hg.admin')
704 @HasPermissionAllDecorator('hg.admin')
701 def settings_supervisor_log(self, procid):
705 def settings_supervisor_log(self, procid):
702 import rhodecode
706 import rhodecode
703 c.rhodecode_ini = rhodecode.CONFIG
707 c.rhodecode_ini = rhodecode.CONFIG
704 c.active = 'supervisor_tail'
708 c.active = 'supervisor_tail'
705
709
706 supervisor = SupervisorModel()
710 supervisor = SupervisorModel()
707 _connection = supervisor.get_connection(c.rhodecode_ini.get('supervisor.uri'))
711 _connection = supervisor.get_connection(c.rhodecode_ini.get('supervisor.uri'))
708 groupid = c.rhodecode_ini.get('supervisor.group_id')
712 groupid = c.rhodecode_ini.get('supervisor.group_id')
709 procid = groupid + ":" + procid if procid != SUPERVISOR_MASTER else procid
713 procid = groupid + ":" + procid if procid != SUPERVISOR_MASTER else procid
710
714
711 c.log_size = 10240
715 c.log_size = 10240
712 offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1
716 offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1
713 c.log = supervisor.read_process_log(_connection, procid, offset, 0)
717 c.log = supervisor.read_process_log(_connection, procid, offset, 0)
714
718
715 return render('admin/settings/settings.html')
719 return render('admin/settings/settings.html')
716
720
717 @HasPermissionAllDecorator('hg.admin')
721 @HasPermissionAllDecorator('hg.admin')
718 @auth.CSRFRequired()
722 @auth.CSRFRequired()
719 def settings_labs_update(self):
723 def settings_labs_update(self):
720 """POST /admin/settings/labs: All items in the collection"""
724 """POST /admin/settings/labs: All items in the collection"""
721 # url('admin_settings/labs', method={'POST'})
725 # url('admin_settings/labs', method={'POST'})
722 c.active = 'labs'
726 c.active = 'labs'
723
727
724 application_form = LabsSettingsForm()()
728 application_form = LabsSettingsForm()()
725 try:
729 try:
726 form_result = application_form.to_python(dict(request.POST))
730 form_result = application_form.to_python(dict(request.POST))
727 except formencode.Invalid as errors:
731 except formencode.Invalid as errors:
728 h.flash(
732 h.flash(
729 _('Some form inputs contain invalid data.'),
733 _('Some form inputs contain invalid data.'),
730 category='error')
734 category='error')
731 return htmlfill.render(
735 return htmlfill.render(
732 render('admin/settings/settings.html'),
736 render('admin/settings/settings.html'),
733 defaults=errors.value,
737 defaults=errors.value,
734 errors=errors.error_dict or {},
738 errors=errors.error_dict or {},
735 prefix_error=False,
739 prefix_error=False,
736 encoding='UTF-8',
740 encoding='UTF-8',
737 force_defaults=False
741 force_defaults=False
738 )
742 )
739
743
740 try:
744 try:
741 session = Session()
745 session = Session()
742 for setting in _LAB_SETTINGS:
746 for setting in _LAB_SETTINGS:
743 setting_name = setting.key[len('rhodecode_'):]
747 setting_name = setting.key[len('rhodecode_'):]
744 sett = SettingsModel().create_or_update_setting(
748 sett = SettingsModel().create_or_update_setting(
745 setting_name, form_result[setting.key], setting.type)
749 setting_name, form_result[setting.key], setting.type)
746 session.add(sett)
750 session.add(sett)
747
751
748 except Exception:
752 except Exception:
749 log.exception('Exception while updating lab settings')
753 log.exception('Exception while updating lab settings')
750 h.flash(_('Error occurred during updating labs settings'),
754 h.flash(_('Error occurred during updating labs settings'),
751 category='error')
755 category='error')
752 else:
756 else:
753 Session().commit()
757 Session().commit()
754 SettingsModel().invalidate_settings_cache()
758 SettingsModel().invalidate_settings_cache()
755 h.flash(_('Updated Labs settings'), category='success')
759 h.flash(_('Updated Labs settings'), category='success')
756 return redirect(url('admin_settings_labs'))
760 return redirect(url('admin_settings_labs'))
757
761
758 return htmlfill.render(
762 return htmlfill.render(
759 render('admin/settings/settings.html'),
763 render('admin/settings/settings.html'),
760 defaults=self._form_defaults(),
764 defaults=self._form_defaults(),
761 encoding='UTF-8',
765 encoding='UTF-8',
762 force_defaults=False)
766 force_defaults=False)
763
767
764 @HasPermissionAllDecorator('hg.admin')
768 @HasPermissionAllDecorator('hg.admin')
765 def settings_labs(self):
769 def settings_labs(self):
766 """GET /admin/settings/labs: All items in the collection"""
770 """GET /admin/settings/labs: All items in the collection"""
767 # url('admin_settings_labs')
771 # url('admin_settings_labs')
768 if not c.labs_active:
772 if not c.labs_active:
769 redirect(url('admin_settings'))
773 redirect(url('admin_settings'))
770
774
771 c.active = 'labs'
775 c.active = 'labs'
772 c.lab_settings = _LAB_SETTINGS
776 c.lab_settings = _LAB_SETTINGS
773
777
774 return htmlfill.render(
778 return htmlfill.render(
775 render('admin/settings/settings.html'),
779 render('admin/settings/settings.html'),
776 defaults=self._form_defaults(),
780 defaults=self._form_defaults(),
777 encoding='UTF-8',
781 encoding='UTF-8',
778 force_defaults=False)
782 force_defaults=False)
779
783
780 def _form_defaults(self):
784 def _form_defaults(self):
781 defaults = SettingsModel().get_all_settings()
785 defaults = SettingsModel().get_all_settings()
782 defaults.update(self._get_hg_ui_settings())
786 defaults.update(self._get_hg_ui_settings())
783 defaults.update({
787 defaults.update({
784 'new_svn_branch': '',
788 'new_svn_branch': '',
785 'new_svn_tag': '',
789 'new_svn_tag': '',
786 })
790 })
787 return defaults
791 return defaults
788
792
789
793
790 # :param key: name of the setting including the 'rhodecode_' prefix
794 # :param key: name of the setting including the 'rhodecode_' prefix
791 # :param type: the RhodeCodeSetting type to use.
795 # :param type: the RhodeCodeSetting type to use.
792 # :param group: the i18ned group in which we should dispaly this setting
796 # :param group: the i18ned group in which we should dispaly this setting
793 # :param label: the i18ned label we should display for this setting
797 # :param label: the i18ned label we should display for this setting
794 # :param help: the i18ned help we should dispaly for this setting
798 # :param help: the i18ned help we should dispaly for this setting
795 LabSetting = collections.namedtuple(
799 LabSetting = collections.namedtuple(
796 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
800 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
797
801
798
802
799 # This list has to be kept in sync with the form
803 # This list has to be kept in sync with the form
800 # rhodecode.model.forms.LabsSettingsForm.
804 # rhodecode.model.forms.LabsSettingsForm.
801 _LAB_SETTINGS = [
805 _LAB_SETTINGS = [
802
806
803 ]
807 ]
General Comments 0
You need to be logged in to leave comments. Login now