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