##// END OF EJS Templates
feat(svn): re-enable manual generation of SVN config that was removed when we moved svn path config to .ini files...
super-admin -
r5394:41153181 default
parent child Browse files
Show More
@@ -1,711 +1,711 b''
1 # Copyright (C) 2010-2023 RhodeCode GmbH
1 # Copyright (C) 2010-2023 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
5 # (only), as published by the Free Software Foundation.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU Affero General Public License
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
14 #
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19
19
20 import logging
20 import logging
21 import collections
21 import collections
22
22
23 import datetime
23 import datetime
24 import formencode
24 import formencode
25 import formencode.htmlfill
25 import formencode.htmlfill
26
26
27 import rhodecode
27 import rhodecode
28
28
29 from pyramid.httpexceptions import HTTPFound, HTTPNotFound
29 from pyramid.httpexceptions import HTTPFound, HTTPNotFound
30 from pyramid.renderers import render
30 from pyramid.renderers import render
31 from pyramid.response import Response
31 from pyramid.response import Response
32
32
33 from rhodecode.apps._base import BaseAppView
33 from rhodecode.apps._base import BaseAppView
34 from rhodecode.apps._base.navigation import navigation_list
34 from rhodecode.apps._base.navigation import navigation_list
35 from rhodecode.apps.svn_support.config_keys import generate_config
35 from rhodecode.apps.svn_support.config_keys import generate_config
36 from rhodecode.lib import helpers as h
36 from rhodecode.lib import helpers as h
37 from rhodecode.lib.auth import (
37 from rhodecode.lib.auth import (
38 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
38 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
39 from rhodecode.lib.celerylib import tasks, run_task
39 from rhodecode.lib.celerylib import tasks, run_task
40 from rhodecode.lib.str_utils import safe_str
40 from rhodecode.lib.str_utils import safe_str
41 from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_repo_store_path
41 from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_repo_store_path
42 from rhodecode.lib.utils2 import str2bool, AttributeDict
42 from rhodecode.lib.utils2 import str2bool, AttributeDict
43 from rhodecode.lib.index import searcher_from_config
43 from rhodecode.lib.index import searcher_from_config
44
44
45 from rhodecode.model.db import RhodeCodeUi, Repository
45 from rhodecode.model.db import RhodeCodeUi, Repository
46 from rhodecode.model.forms import (ApplicationSettingsForm,
46 from rhodecode.model.forms import (ApplicationSettingsForm,
47 ApplicationUiSettingsForm, ApplicationVisualisationForm,
47 ApplicationUiSettingsForm, ApplicationVisualisationForm,
48 LabsSettingsForm, IssueTrackerPatternsForm)
48 LabsSettingsForm, IssueTrackerPatternsForm)
49 from rhodecode.model.permission import PermissionModel
49 from rhodecode.model.permission import PermissionModel
50 from rhodecode.model.repo_group import RepoGroupModel
50 from rhodecode.model.repo_group import RepoGroupModel
51
51
52 from rhodecode.model.scm import ScmModel
52 from rhodecode.model.scm import ScmModel
53 from rhodecode.model.notification import EmailNotificationModel
53 from rhodecode.model.notification import EmailNotificationModel
54 from rhodecode.model.meta import Session
54 from rhodecode.model.meta import Session
55 from rhodecode.model.settings import (
55 from rhodecode.model.settings import (
56 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
56 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
57 SettingsModel)
57 SettingsModel)
58
58
59
59
60 log = logging.getLogger(__name__)
60 log = logging.getLogger(__name__)
61
61
62
62
63 class AdminSettingsView(BaseAppView):
63 class AdminSettingsView(BaseAppView):
64
64
65 def load_default_context(self):
65 def load_default_context(self):
66 c = self._get_local_tmpl_context()
66 c = self._get_local_tmpl_context()
67 c.labs_active = str2bool(
67 c.labs_active = str2bool(
68 rhodecode.CONFIG.get('labs_settings_active', 'true'))
68 rhodecode.CONFIG.get('labs_settings_active', 'true'))
69 c.navlist = navigation_list(self.request)
69 c.navlist = navigation_list(self.request)
70 return c
70 return c
71
71
72 @classmethod
72 @classmethod
73 def _get_ui_settings(cls):
73 def _get_ui_settings(cls):
74 ret = RhodeCodeUi.query().all()
74 ret = RhodeCodeUi.query().all()
75
75
76 if not ret:
76 if not ret:
77 raise Exception('Could not get application ui settings !')
77 raise Exception('Could not get application ui settings !')
78 settings = {}
78 settings = {}
79 for each in ret:
79 for each in ret:
80 k = each.ui_key
80 k = each.ui_key
81 v = each.ui_value
81 v = each.ui_value
82 if k == '/':
82 if k == '/':
83 k = 'root_path'
83 k = 'root_path'
84
84
85 if k in ['push_ssl', 'publish', 'enabled']:
85 if k in ['push_ssl', 'publish', 'enabled']:
86 v = str2bool(v)
86 v = str2bool(v)
87
87
88 if k.find('.') != -1:
88 if k.find('.') != -1:
89 k = k.replace('.', '_')
89 k = k.replace('.', '_')
90
90
91 if each.ui_section in ['hooks', 'extensions']:
91 if each.ui_section in ['hooks', 'extensions']:
92 v = each.ui_active
92 v = each.ui_active
93
93
94 settings[each.ui_section + '_' + k] = v
94 settings[each.ui_section + '_' + k] = v
95 return settings
95 return settings
96
96
97 @classmethod
97 @classmethod
98 def _form_defaults(cls):
98 def _form_defaults(cls):
99 defaults = SettingsModel().get_all_settings()
99 defaults = SettingsModel().get_all_settings()
100 defaults.update(cls._get_ui_settings())
100 defaults.update(cls._get_ui_settings())
101
101
102 defaults.update({
102 defaults.update({
103 'new_svn_branch': '',
103 'new_svn_branch': '',
104 'new_svn_tag': '',
104 'new_svn_tag': '',
105 })
105 })
106 return defaults
106 return defaults
107
107
108 @LoginRequired()
108 @LoginRequired()
109 @HasPermissionAllDecorator('hg.admin')
109 @HasPermissionAllDecorator('hg.admin')
110 def settings_vcs(self):
110 def settings_vcs(self):
111 c = self.load_default_context()
111 c = self.load_default_context()
112 c.active = 'vcs'
112 c.active = 'vcs'
113 model = VcsSettingsModel()
113 model = VcsSettingsModel()
114 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
114 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
115 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
115 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
116
116
117 settings = self.request.registry.settings
117 settings = self.request.registry.settings
118 c.svn_proxy_generate_config = settings[generate_config]
118 c.svn_generate_config = settings[generate_config]
119
119 c.svn_config_path = rhodecode.ConfigGet().get_str('svn.proxy.config_file_path')
120 defaults = self._form_defaults()
120 defaults = self._form_defaults()
121
121
122 model.create_largeobjects_dirs_if_needed(defaults['paths_root_path'])
122 model.create_largeobjects_dirs_if_needed(defaults['paths_root_path'])
123
123
124 data = render('rhodecode:templates/admin/settings/settings.mako',
124 data = render('rhodecode:templates/admin/settings/settings.mako',
125 self._get_template_context(c), self.request)
125 self._get_template_context(c), self.request)
126 html = formencode.htmlfill.render(
126 html = formencode.htmlfill.render(
127 data,
127 data,
128 defaults=defaults,
128 defaults=defaults,
129 encoding="UTF-8",
129 encoding="UTF-8",
130 force_defaults=False
130 force_defaults=False
131 )
131 )
132 return Response(html)
132 return Response(html)
133
133
134 @LoginRequired()
134 @LoginRequired()
135 @HasPermissionAllDecorator('hg.admin')
135 @HasPermissionAllDecorator('hg.admin')
136 @CSRFRequired()
136 @CSRFRequired()
137 def settings_vcs_update(self):
137 def settings_vcs_update(self):
138 _ = self.request.translate
138 _ = self.request.translate
139 c = self.load_default_context()
139 c = self.load_default_context()
140 c.active = 'vcs'
140 c.active = 'vcs'
141
141
142 model = VcsSettingsModel()
142 model = VcsSettingsModel()
143 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
143 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
144 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
144 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
145
145
146 settings = self.request.registry.settings
146 settings = self.request.registry.settings
147 c.svn_proxy_generate_config = settings[generate_config]
147 c.svn_generate_config = settings[generate_config]
148
148 c.svn_config_path = rhodecode.ConfigGet().get_str('svn.proxy.config_file_path')
149 application_form = ApplicationUiSettingsForm(self.request.translate)()
149 application_form = ApplicationUiSettingsForm(self.request.translate)()
150
150
151 try:
151 try:
152 form_result = application_form.to_python(dict(self.request.POST))
152 form_result = application_form.to_python(dict(self.request.POST))
153 except formencode.Invalid as errors:
153 except formencode.Invalid as errors:
154 h.flash(
154 h.flash(
155 _("Some form inputs contain invalid data."),
155 _("Some form inputs contain invalid data."),
156 category='error')
156 category='error')
157 data = render('rhodecode:templates/admin/settings/settings.mako',
157 data = render('rhodecode:templates/admin/settings/settings.mako',
158 self._get_template_context(c), self.request)
158 self._get_template_context(c), self.request)
159 html = formencode.htmlfill.render(
159 html = formencode.htmlfill.render(
160 data,
160 data,
161 defaults=errors.value,
161 defaults=errors.value,
162 errors=errors.unpack_errors() or {},
162 errors=errors.unpack_errors() or {},
163 prefix_error=False,
163 prefix_error=False,
164 encoding="UTF-8",
164 encoding="UTF-8",
165 force_defaults=False
165 force_defaults=False
166 )
166 )
167 return Response(html)
167 return Response(html)
168
168
169 try:
169 try:
170 model.update_global_ssl_setting(form_result['web_push_ssl'])
170 model.update_global_ssl_setting(form_result['web_push_ssl'])
171 model.update_global_hook_settings(form_result)
171 model.update_global_hook_settings(form_result)
172
172
173 model.create_or_update_global_svn_settings(form_result)
173 model.create_or_update_global_svn_settings(form_result)
174 model.create_or_update_global_hg_settings(form_result)
174 model.create_or_update_global_hg_settings(form_result)
175 model.create_or_update_global_git_settings(form_result)
175 model.create_or_update_global_git_settings(form_result)
176 model.create_or_update_global_pr_settings(form_result)
176 model.create_or_update_global_pr_settings(form_result)
177 except Exception:
177 except Exception:
178 log.exception("Exception while updating settings")
178 log.exception("Exception while updating settings")
179 h.flash(_('Error occurred during updating '
179 h.flash(_('Error occurred during updating '
180 'application settings'), category='error')
180 'application settings'), category='error')
181 else:
181 else:
182 Session().commit()
182 Session().commit()
183 h.flash(_('Updated VCS settings'), category='success')
183 h.flash(_('Updated VCS settings'), category='success')
184 raise HTTPFound(h.route_path('admin_settings_vcs'))
184 raise HTTPFound(h.route_path('admin_settings_vcs'))
185
185
186 data = render('rhodecode:templates/admin/settings/settings.mako',
186 data = render('rhodecode:templates/admin/settings/settings.mako',
187 self._get_template_context(c), self.request)
187 self._get_template_context(c), self.request)
188 html = formencode.htmlfill.render(
188 html = formencode.htmlfill.render(
189 data,
189 data,
190 defaults=self._form_defaults(),
190 defaults=self._form_defaults(),
191 encoding="UTF-8",
191 encoding="UTF-8",
192 force_defaults=False
192 force_defaults=False
193 )
193 )
194 return Response(html)
194 return Response(html)
195
195
196 @LoginRequired()
196 @LoginRequired()
197 @HasPermissionAllDecorator('hg.admin')
197 @HasPermissionAllDecorator('hg.admin')
198 @CSRFRequired()
198 @CSRFRequired()
199 def settings_vcs_delete_svn_pattern(self):
199 def settings_vcs_delete_svn_pattern(self):
200 delete_pattern_id = self.request.POST.get('delete_svn_pattern')
200 delete_pattern_id = self.request.POST.get('delete_svn_pattern')
201 model = VcsSettingsModel()
201 model = VcsSettingsModel()
202 try:
202 try:
203 model.delete_global_svn_pattern(delete_pattern_id)
203 model.delete_global_svn_pattern(delete_pattern_id)
204 except SettingNotFound:
204 except SettingNotFound:
205 log.exception(
205 log.exception(
206 'Failed to delete svn_pattern with id %s', delete_pattern_id)
206 'Failed to delete svn_pattern with id %s', delete_pattern_id)
207 raise HTTPNotFound()
207 raise HTTPNotFound()
208
208
209 Session().commit()
209 Session().commit()
210 return True
210 return True
211
211
212 @LoginRequired()
212 @LoginRequired()
213 @HasPermissionAllDecorator('hg.admin')
213 @HasPermissionAllDecorator('hg.admin')
214 def settings_mapping(self):
214 def settings_mapping(self):
215 c = self.load_default_context()
215 c = self.load_default_context()
216 c.active = 'mapping'
216 c.active = 'mapping'
217 c.storage_path = get_rhodecode_repo_store_path()
217 c.storage_path = get_rhodecode_repo_store_path()
218 data = render('rhodecode:templates/admin/settings/settings.mako',
218 data = render('rhodecode:templates/admin/settings/settings.mako',
219 self._get_template_context(c), self.request)
219 self._get_template_context(c), self.request)
220 html = formencode.htmlfill.render(
220 html = formencode.htmlfill.render(
221 data,
221 data,
222 defaults=self._form_defaults(),
222 defaults=self._form_defaults(),
223 encoding="UTF-8",
223 encoding="UTF-8",
224 force_defaults=False
224 force_defaults=False
225 )
225 )
226 return Response(html)
226 return Response(html)
227
227
228 @LoginRequired()
228 @LoginRequired()
229 @HasPermissionAllDecorator('hg.admin')
229 @HasPermissionAllDecorator('hg.admin')
230 @CSRFRequired()
230 @CSRFRequired()
231 def settings_mapping_update(self):
231 def settings_mapping_update(self):
232 _ = self.request.translate
232 _ = self.request.translate
233 c = self.load_default_context()
233 c = self.load_default_context()
234 c.active = 'mapping'
234 c.active = 'mapping'
235 rm_obsolete = self.request.POST.get('destroy', False)
235 rm_obsolete = self.request.POST.get('destroy', False)
236 invalidate_cache = self.request.POST.get('invalidate', False)
236 invalidate_cache = self.request.POST.get('invalidate', False)
237 log.debug('rescanning repo location with destroy obsolete=%s', rm_obsolete)
237 log.debug('rescanning repo location with destroy obsolete=%s', rm_obsolete)
238
238
239 if invalidate_cache:
239 if invalidate_cache:
240 log.debug('invalidating all repositories cache')
240 log.debug('invalidating all repositories cache')
241 for repo in Repository.get_all():
241 for repo in Repository.get_all():
242 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
242 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
243
243
244 filesystem_repos = ScmModel().repo_scan()
244 filesystem_repos = ScmModel().repo_scan()
245 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete, force_hooks_rebuild=True)
245 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete, force_hooks_rebuild=True)
246 PermissionModel().trigger_permission_flush()
246 PermissionModel().trigger_permission_flush()
247
247
248 def _repr(rm_repo):
248 def _repr(rm_repo):
249 return ', '.join(map(safe_str, rm_repo)) or '-'
249 return ', '.join(map(safe_str, rm_repo)) or '-'
250
250
251 h.flash(_('Repositories successfully '
251 h.flash(_('Repositories successfully '
252 'rescanned added: %s ; removed: %s') %
252 'rescanned added: %s ; removed: %s') %
253 (_repr(added), _repr(removed)),
253 (_repr(added), _repr(removed)),
254 category='success')
254 category='success')
255 raise HTTPFound(h.route_path('admin_settings_mapping'))
255 raise HTTPFound(h.route_path('admin_settings_mapping'))
256
256
257 @LoginRequired()
257 @LoginRequired()
258 @HasPermissionAllDecorator('hg.admin')
258 @HasPermissionAllDecorator('hg.admin')
259 def settings_global(self):
259 def settings_global(self):
260 c = self.load_default_context()
260 c = self.load_default_context()
261 c.active = 'global'
261 c.active = 'global'
262 c.personal_repo_group_default_pattern = RepoGroupModel()\
262 c.personal_repo_group_default_pattern = RepoGroupModel()\
263 .get_personal_group_name_pattern()
263 .get_personal_group_name_pattern()
264
264
265 data = render('rhodecode:templates/admin/settings/settings.mako',
265 data = render('rhodecode:templates/admin/settings/settings.mako',
266 self._get_template_context(c), self.request)
266 self._get_template_context(c), self.request)
267 html = formencode.htmlfill.render(
267 html = formencode.htmlfill.render(
268 data,
268 data,
269 defaults=self._form_defaults(),
269 defaults=self._form_defaults(),
270 encoding="UTF-8",
270 encoding="UTF-8",
271 force_defaults=False
271 force_defaults=False
272 )
272 )
273 return Response(html)
273 return Response(html)
274
274
275 @LoginRequired()
275 @LoginRequired()
276 @HasPermissionAllDecorator('hg.admin')
276 @HasPermissionAllDecorator('hg.admin')
277 @CSRFRequired()
277 @CSRFRequired()
278 def settings_global_update(self):
278 def settings_global_update(self):
279 _ = self.request.translate
279 _ = self.request.translate
280 c = self.load_default_context()
280 c = self.load_default_context()
281 c.active = 'global'
281 c.active = 'global'
282 c.personal_repo_group_default_pattern = RepoGroupModel()\
282 c.personal_repo_group_default_pattern = RepoGroupModel()\
283 .get_personal_group_name_pattern()
283 .get_personal_group_name_pattern()
284 application_form = ApplicationSettingsForm(self.request.translate)()
284 application_form = ApplicationSettingsForm(self.request.translate)()
285 try:
285 try:
286 form_result = application_form.to_python(dict(self.request.POST))
286 form_result = application_form.to_python(dict(self.request.POST))
287 except formencode.Invalid as errors:
287 except formencode.Invalid as errors:
288 h.flash(
288 h.flash(
289 _("Some form inputs contain invalid data."),
289 _("Some form inputs contain invalid data."),
290 category='error')
290 category='error')
291 data = render('rhodecode:templates/admin/settings/settings.mako',
291 data = render('rhodecode:templates/admin/settings/settings.mako',
292 self._get_template_context(c), self.request)
292 self._get_template_context(c), self.request)
293 html = formencode.htmlfill.render(
293 html = formencode.htmlfill.render(
294 data,
294 data,
295 defaults=errors.value,
295 defaults=errors.value,
296 errors=errors.unpack_errors() or {},
296 errors=errors.unpack_errors() or {},
297 prefix_error=False,
297 prefix_error=False,
298 encoding="UTF-8",
298 encoding="UTF-8",
299 force_defaults=False
299 force_defaults=False
300 )
300 )
301 return Response(html)
301 return Response(html)
302
302
303 settings = [
303 settings = [
304 ('title', 'rhodecode_title', 'unicode'),
304 ('title', 'rhodecode_title', 'unicode'),
305 ('realm', 'rhodecode_realm', 'unicode'),
305 ('realm', 'rhodecode_realm', 'unicode'),
306 ('pre_code', 'rhodecode_pre_code', 'unicode'),
306 ('pre_code', 'rhodecode_pre_code', 'unicode'),
307 ('post_code', 'rhodecode_post_code', 'unicode'),
307 ('post_code', 'rhodecode_post_code', 'unicode'),
308 ('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'),
308 ('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'),
309 ('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'),
309 ('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'),
310 ('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'),
310 ('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'),
311 ('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'),
311 ('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'),
312 ]
312 ]
313
313
314 try:
314 try:
315 for setting, form_key, type_ in settings:
315 for setting, form_key, type_ in settings:
316 sett = SettingsModel().create_or_update_setting(
316 sett = SettingsModel().create_or_update_setting(
317 setting, form_result[form_key], type_)
317 setting, form_result[form_key], type_)
318 Session().add(sett)
318 Session().add(sett)
319
319
320 Session().commit()
320 Session().commit()
321 SettingsModel().invalidate_settings_cache()
321 SettingsModel().invalidate_settings_cache()
322 h.flash(_('Updated application settings'), category='success')
322 h.flash(_('Updated application settings'), category='success')
323 except Exception:
323 except Exception:
324 log.exception("Exception while updating application settings")
324 log.exception("Exception while updating application settings")
325 h.flash(
325 h.flash(
326 _('Error occurred during updating application settings'),
326 _('Error occurred during updating application settings'),
327 category='error')
327 category='error')
328
328
329 raise HTTPFound(h.route_path('admin_settings_global'))
329 raise HTTPFound(h.route_path('admin_settings_global'))
330
330
331 @LoginRequired()
331 @LoginRequired()
332 @HasPermissionAllDecorator('hg.admin')
332 @HasPermissionAllDecorator('hg.admin')
333 def settings_visual(self):
333 def settings_visual(self):
334 c = self.load_default_context()
334 c = self.load_default_context()
335 c.active = 'visual'
335 c.active = 'visual'
336
336
337 data = render('rhodecode:templates/admin/settings/settings.mako',
337 data = render('rhodecode:templates/admin/settings/settings.mako',
338 self._get_template_context(c), self.request)
338 self._get_template_context(c), self.request)
339 html = formencode.htmlfill.render(
339 html = formencode.htmlfill.render(
340 data,
340 data,
341 defaults=self._form_defaults(),
341 defaults=self._form_defaults(),
342 encoding="UTF-8",
342 encoding="UTF-8",
343 force_defaults=False
343 force_defaults=False
344 )
344 )
345 return Response(html)
345 return Response(html)
346
346
347 @LoginRequired()
347 @LoginRequired()
348 @HasPermissionAllDecorator('hg.admin')
348 @HasPermissionAllDecorator('hg.admin')
349 @CSRFRequired()
349 @CSRFRequired()
350 def settings_visual_update(self):
350 def settings_visual_update(self):
351 _ = self.request.translate
351 _ = self.request.translate
352 c = self.load_default_context()
352 c = self.load_default_context()
353 c.active = 'visual'
353 c.active = 'visual'
354 application_form = ApplicationVisualisationForm(self.request.translate)()
354 application_form = ApplicationVisualisationForm(self.request.translate)()
355 try:
355 try:
356 form_result = application_form.to_python(dict(self.request.POST))
356 form_result = application_form.to_python(dict(self.request.POST))
357 except formencode.Invalid as errors:
357 except formencode.Invalid as errors:
358 h.flash(
358 h.flash(
359 _("Some form inputs contain invalid data."),
359 _("Some form inputs contain invalid data."),
360 category='error')
360 category='error')
361 data = render('rhodecode:templates/admin/settings/settings.mako',
361 data = render('rhodecode:templates/admin/settings/settings.mako',
362 self._get_template_context(c), self.request)
362 self._get_template_context(c), self.request)
363 html = formencode.htmlfill.render(
363 html = formencode.htmlfill.render(
364 data,
364 data,
365 defaults=errors.value,
365 defaults=errors.value,
366 errors=errors.unpack_errors() or {},
366 errors=errors.unpack_errors() or {},
367 prefix_error=False,
367 prefix_error=False,
368 encoding="UTF-8",
368 encoding="UTF-8",
369 force_defaults=False
369 force_defaults=False
370 )
370 )
371 return Response(html)
371 return Response(html)
372
372
373 try:
373 try:
374 settings = [
374 settings = [
375 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
375 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
376 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
376 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
377 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
377 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
378 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
378 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
379 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
379 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
380 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
380 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
381 ('show_version', 'rhodecode_show_version', 'bool'),
381 ('show_version', 'rhodecode_show_version', 'bool'),
382 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
382 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
383 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
383 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
384 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
384 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
385 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
385 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
386 ('clone_uri_id_tmpl', 'rhodecode_clone_uri_id_tmpl', 'unicode'),
386 ('clone_uri_id_tmpl', 'rhodecode_clone_uri_id_tmpl', 'unicode'),
387 ('clone_uri_ssh_tmpl', 'rhodecode_clone_uri_ssh_tmpl', 'unicode'),
387 ('clone_uri_ssh_tmpl', 'rhodecode_clone_uri_ssh_tmpl', 'unicode'),
388 ('support_url', 'rhodecode_support_url', 'unicode'),
388 ('support_url', 'rhodecode_support_url', 'unicode'),
389 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
389 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
390 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
390 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
391 ]
391 ]
392 for setting, form_key, type_ in settings:
392 for setting, form_key, type_ in settings:
393 sett = SettingsModel().create_or_update_setting(
393 sett = SettingsModel().create_or_update_setting(
394 setting, form_result[form_key], type_)
394 setting, form_result[form_key], type_)
395 Session().add(sett)
395 Session().add(sett)
396
396
397 Session().commit()
397 Session().commit()
398 SettingsModel().invalidate_settings_cache()
398 SettingsModel().invalidate_settings_cache()
399 h.flash(_('Updated visualisation settings'), category='success')
399 h.flash(_('Updated visualisation settings'), category='success')
400 except Exception:
400 except Exception:
401 log.exception("Exception updating visualization settings")
401 log.exception("Exception updating visualization settings")
402 h.flash(_('Error occurred during updating '
402 h.flash(_('Error occurred during updating '
403 'visualisation settings'),
403 'visualisation settings'),
404 category='error')
404 category='error')
405
405
406 raise HTTPFound(h.route_path('admin_settings_visual'))
406 raise HTTPFound(h.route_path('admin_settings_visual'))
407
407
408 @LoginRequired()
408 @LoginRequired()
409 @HasPermissionAllDecorator('hg.admin')
409 @HasPermissionAllDecorator('hg.admin')
410 def settings_issuetracker(self):
410 def settings_issuetracker(self):
411 c = self.load_default_context()
411 c = self.load_default_context()
412 c.active = 'issuetracker'
412 c.active = 'issuetracker'
413 defaults = c.rc_config
413 defaults = c.rc_config
414
414
415 entry_key = 'rhodecode_issuetracker_pat_'
415 entry_key = 'rhodecode_issuetracker_pat_'
416
416
417 c.issuetracker_entries = {}
417 c.issuetracker_entries = {}
418 for k, v in defaults.items():
418 for k, v in defaults.items():
419 if k.startswith(entry_key):
419 if k.startswith(entry_key):
420 uid = k[len(entry_key):]
420 uid = k[len(entry_key):]
421 c.issuetracker_entries[uid] = None
421 c.issuetracker_entries[uid] = None
422
422
423 for uid in c.issuetracker_entries:
423 for uid in c.issuetracker_entries:
424 c.issuetracker_entries[uid] = AttributeDict({
424 c.issuetracker_entries[uid] = AttributeDict({
425 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
425 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
426 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
426 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
427 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
427 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
428 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
428 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
429 })
429 })
430
430
431 return self._get_template_context(c)
431 return self._get_template_context(c)
432
432
433 @LoginRequired()
433 @LoginRequired()
434 @HasPermissionAllDecorator('hg.admin')
434 @HasPermissionAllDecorator('hg.admin')
435 @CSRFRequired()
435 @CSRFRequired()
436 def settings_issuetracker_test(self):
436 def settings_issuetracker_test(self):
437 error_container = []
437 error_container = []
438
438
439 urlified_commit = h.urlify_commit_message(
439 urlified_commit = h.urlify_commit_message(
440 self.request.POST.get('test_text', ''),
440 self.request.POST.get('test_text', ''),
441 'repo_group/test_repo1', error_container=error_container)
441 'repo_group/test_repo1', error_container=error_container)
442 if error_container:
442 if error_container:
443 def converter(inp):
443 def converter(inp):
444 return h.html_escape(inp)
444 return h.html_escape(inp)
445
445
446 return 'ERRORS: ' + '\n'.join(map(converter, error_container))
446 return 'ERRORS: ' + '\n'.join(map(converter, error_container))
447
447
448 return urlified_commit
448 return urlified_commit
449
449
450 @LoginRequired()
450 @LoginRequired()
451 @HasPermissionAllDecorator('hg.admin')
451 @HasPermissionAllDecorator('hg.admin')
452 @CSRFRequired()
452 @CSRFRequired()
453 def settings_issuetracker_update(self):
453 def settings_issuetracker_update(self):
454 _ = self.request.translate
454 _ = self.request.translate
455 self.load_default_context()
455 self.load_default_context()
456 settings_model = IssueTrackerSettingsModel()
456 settings_model = IssueTrackerSettingsModel()
457
457
458 try:
458 try:
459 form = IssueTrackerPatternsForm(self.request.translate)()
459 form = IssueTrackerPatternsForm(self.request.translate)()
460 data = form.to_python(self.request.POST)
460 data = form.to_python(self.request.POST)
461 except formencode.Invalid as errors:
461 except formencode.Invalid as errors:
462 log.exception('Failed to add new pattern')
462 log.exception('Failed to add new pattern')
463 error = errors
463 error = errors
464 h.flash(_(f'Invalid issue tracker pattern: {error}'),
464 h.flash(_(f'Invalid issue tracker pattern: {error}'),
465 category='error')
465 category='error')
466 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
466 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
467
467
468 if data:
468 if data:
469 for uid in data.get('delete_patterns', []):
469 for uid in data.get('delete_patterns', []):
470 settings_model.delete_entries(uid)
470 settings_model.delete_entries(uid)
471
471
472 for pattern in data.get('patterns', []):
472 for pattern in data.get('patterns', []):
473 for setting, value, type_ in pattern:
473 for setting, value, type_ in pattern:
474 sett = settings_model.create_or_update_setting(
474 sett = settings_model.create_or_update_setting(
475 setting, value, type_)
475 setting, value, type_)
476 Session().add(sett)
476 Session().add(sett)
477
477
478 Session().commit()
478 Session().commit()
479
479
480 SettingsModel().invalidate_settings_cache()
480 SettingsModel().invalidate_settings_cache()
481 h.flash(_('Updated issue tracker entries'), category='success')
481 h.flash(_('Updated issue tracker entries'), category='success')
482 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
482 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
483
483
484 @LoginRequired()
484 @LoginRequired()
485 @HasPermissionAllDecorator('hg.admin')
485 @HasPermissionAllDecorator('hg.admin')
486 @CSRFRequired()
486 @CSRFRequired()
487 def settings_issuetracker_delete(self):
487 def settings_issuetracker_delete(self):
488 _ = self.request.translate
488 _ = self.request.translate
489 self.load_default_context()
489 self.load_default_context()
490 uid = self.request.POST.get('uid')
490 uid = self.request.POST.get('uid')
491 try:
491 try:
492 IssueTrackerSettingsModel().delete_entries(uid)
492 IssueTrackerSettingsModel().delete_entries(uid)
493 except Exception:
493 except Exception:
494 log.exception('Failed to delete issue tracker setting %s', uid)
494 log.exception('Failed to delete issue tracker setting %s', uid)
495 raise HTTPNotFound()
495 raise HTTPNotFound()
496
496
497 SettingsModel().invalidate_settings_cache()
497 SettingsModel().invalidate_settings_cache()
498 h.flash(_('Removed issue tracker entry.'), category='success')
498 h.flash(_('Removed issue tracker entry.'), category='success')
499
499
500 return {'deleted': uid}
500 return {'deleted': uid}
501
501
502 @LoginRequired()
502 @LoginRequired()
503 @HasPermissionAllDecorator('hg.admin')
503 @HasPermissionAllDecorator('hg.admin')
504 def settings_email(self):
504 def settings_email(self):
505 c = self.load_default_context()
505 c = self.load_default_context()
506 c.active = 'email'
506 c.active = 'email'
507 c.rhodecode_ini = rhodecode.CONFIG
507 c.rhodecode_ini = rhodecode.CONFIG
508
508
509 data = render('rhodecode:templates/admin/settings/settings.mako',
509 data = render('rhodecode:templates/admin/settings/settings.mako',
510 self._get_template_context(c), self.request)
510 self._get_template_context(c), self.request)
511 html = formencode.htmlfill.render(
511 html = formencode.htmlfill.render(
512 data,
512 data,
513 defaults=self._form_defaults(),
513 defaults=self._form_defaults(),
514 encoding="UTF-8",
514 encoding="UTF-8",
515 force_defaults=False
515 force_defaults=False
516 )
516 )
517 return Response(html)
517 return Response(html)
518
518
519 @LoginRequired()
519 @LoginRequired()
520 @HasPermissionAllDecorator('hg.admin')
520 @HasPermissionAllDecorator('hg.admin')
521 @CSRFRequired()
521 @CSRFRequired()
522 def settings_email_update(self):
522 def settings_email_update(self):
523 _ = self.request.translate
523 _ = self.request.translate
524 c = self.load_default_context()
524 c = self.load_default_context()
525 c.active = 'email'
525 c.active = 'email'
526
526
527 test_email = self.request.POST.get('test_email')
527 test_email = self.request.POST.get('test_email')
528
528
529 if not test_email:
529 if not test_email:
530 h.flash(_('Please enter email address'), category='error')
530 h.flash(_('Please enter email address'), category='error')
531 raise HTTPFound(h.route_path('admin_settings_email'))
531 raise HTTPFound(h.route_path('admin_settings_email'))
532
532
533 email_kwargs = {
533 email_kwargs = {
534 'date': datetime.datetime.now(),
534 'date': datetime.datetime.now(),
535 'user': self._rhodecode_db_user
535 'user': self._rhodecode_db_user
536 }
536 }
537
537
538 (subject, email_body, email_body_plaintext) = EmailNotificationModel().render_email(
538 (subject, email_body, email_body_plaintext) = EmailNotificationModel().render_email(
539 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
539 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
540
540
541 recipients = [test_email] if test_email else None
541 recipients = [test_email] if test_email else None
542
542
543 run_task(tasks.send_email, recipients, subject,
543 run_task(tasks.send_email, recipients, subject,
544 email_body_plaintext, email_body)
544 email_body_plaintext, email_body)
545
545
546 h.flash(_('Send email task created'), category='success')
546 h.flash(_('Send email task created'), category='success')
547 raise HTTPFound(h.route_path('admin_settings_email'))
547 raise HTTPFound(h.route_path('admin_settings_email'))
548
548
549 @LoginRequired()
549 @LoginRequired()
550 @HasPermissionAllDecorator('hg.admin')
550 @HasPermissionAllDecorator('hg.admin')
551 def settings_hooks(self):
551 def settings_hooks(self):
552 c = self.load_default_context()
552 c = self.load_default_context()
553 c.active = 'hooks'
553 c.active = 'hooks'
554
554
555 model = SettingsModel()
555 model = SettingsModel()
556 c.hooks = model.get_builtin_hooks()
556 c.hooks = model.get_builtin_hooks()
557 c.custom_hooks = model.get_custom_hooks()
557 c.custom_hooks = model.get_custom_hooks()
558
558
559 data = render('rhodecode:templates/admin/settings/settings.mako',
559 data = render('rhodecode:templates/admin/settings/settings.mako',
560 self._get_template_context(c), self.request)
560 self._get_template_context(c), self.request)
561 html = formencode.htmlfill.render(
561 html = formencode.htmlfill.render(
562 data,
562 data,
563 defaults=self._form_defaults(),
563 defaults=self._form_defaults(),
564 encoding="UTF-8",
564 encoding="UTF-8",
565 force_defaults=False
565 force_defaults=False
566 )
566 )
567 return Response(html)
567 return Response(html)
568
568
569 @LoginRequired()
569 @LoginRequired()
570 @HasPermissionAllDecorator('hg.admin')
570 @HasPermissionAllDecorator('hg.admin')
571 @CSRFRequired()
571 @CSRFRequired()
572 def settings_hooks_update(self):
572 def settings_hooks_update(self):
573 _ = self.request.translate
573 _ = self.request.translate
574 c = self.load_default_context()
574 c = self.load_default_context()
575 c.active = 'hooks'
575 c.active = 'hooks'
576 if c.visual.allow_custom_hooks_settings:
576 if c.visual.allow_custom_hooks_settings:
577 ui_key = self.request.POST.get('new_hook_ui_key')
577 ui_key = self.request.POST.get('new_hook_ui_key')
578 ui_value = self.request.POST.get('new_hook_ui_value')
578 ui_value = self.request.POST.get('new_hook_ui_value')
579
579
580 hook_id = self.request.POST.get('hook_id')
580 hook_id = self.request.POST.get('hook_id')
581 new_hook = False
581 new_hook = False
582
582
583 model = SettingsModel()
583 model = SettingsModel()
584 try:
584 try:
585 if ui_value and ui_key:
585 if ui_value and ui_key:
586 model.create_or_update_hook(ui_key, ui_value)
586 model.create_or_update_hook(ui_key, ui_value)
587 h.flash(_('Added new hook'), category='success')
587 h.flash(_('Added new hook'), category='success')
588 new_hook = True
588 new_hook = True
589 elif hook_id:
589 elif hook_id:
590 RhodeCodeUi.delete(hook_id)
590 RhodeCodeUi.delete(hook_id)
591 Session().commit()
591 Session().commit()
592
592
593 # check for edits
593 # check for edits
594 update = False
594 update = False
595 _d = self.request.POST.dict_of_lists()
595 _d = self.request.POST.dict_of_lists()
596 for k, v in zip(_d.get('hook_ui_key', []),
596 for k, v in zip(_d.get('hook_ui_key', []),
597 _d.get('hook_ui_value_new', [])):
597 _d.get('hook_ui_value_new', [])):
598 model.create_or_update_hook(k, v)
598 model.create_or_update_hook(k, v)
599 update = True
599 update = True
600
600
601 if update and not new_hook:
601 if update and not new_hook:
602 h.flash(_('Updated hooks'), category='success')
602 h.flash(_('Updated hooks'), category='success')
603 Session().commit()
603 Session().commit()
604 except Exception:
604 except Exception:
605 log.exception("Exception during hook creation")
605 log.exception("Exception during hook creation")
606 h.flash(_('Error occurred during hook creation'),
606 h.flash(_('Error occurred during hook creation'),
607 category='error')
607 category='error')
608
608
609 raise HTTPFound(h.route_path('admin_settings_hooks'))
609 raise HTTPFound(h.route_path('admin_settings_hooks'))
610
610
611 @LoginRequired()
611 @LoginRequired()
612 @HasPermissionAllDecorator('hg.admin')
612 @HasPermissionAllDecorator('hg.admin')
613 def settings_search(self):
613 def settings_search(self):
614 c = self.load_default_context()
614 c = self.load_default_context()
615 c.active = 'search'
615 c.active = 'search'
616
616
617 c.searcher = searcher_from_config(self.request.registry.settings)
617 c.searcher = searcher_from_config(self.request.registry.settings)
618 c.statistics = c.searcher.statistics(self.request.translate)
618 c.statistics = c.searcher.statistics(self.request.translate)
619
619
620 return self._get_template_context(c)
620 return self._get_template_context(c)
621
621
622 @LoginRequired()
622 @LoginRequired()
623 @HasPermissionAllDecorator('hg.admin')
623 @HasPermissionAllDecorator('hg.admin')
624 def settings_labs(self):
624 def settings_labs(self):
625 c = self.load_default_context()
625 c = self.load_default_context()
626 if not c.labs_active:
626 if not c.labs_active:
627 raise HTTPFound(h.route_path('admin_settings'))
627 raise HTTPFound(h.route_path('admin_settings'))
628
628
629 c.active = 'labs'
629 c.active = 'labs'
630 c.lab_settings = _LAB_SETTINGS
630 c.lab_settings = _LAB_SETTINGS
631
631
632 data = render('rhodecode:templates/admin/settings/settings.mako',
632 data = render('rhodecode:templates/admin/settings/settings.mako',
633 self._get_template_context(c), self.request)
633 self._get_template_context(c), self.request)
634 html = formencode.htmlfill.render(
634 html = formencode.htmlfill.render(
635 data,
635 data,
636 defaults=self._form_defaults(),
636 defaults=self._form_defaults(),
637 encoding="UTF-8",
637 encoding="UTF-8",
638 force_defaults=False
638 force_defaults=False
639 )
639 )
640 return Response(html)
640 return Response(html)
641
641
642 @LoginRequired()
642 @LoginRequired()
643 @HasPermissionAllDecorator('hg.admin')
643 @HasPermissionAllDecorator('hg.admin')
644 @CSRFRequired()
644 @CSRFRequired()
645 def settings_labs_update(self):
645 def settings_labs_update(self):
646 _ = self.request.translate
646 _ = self.request.translate
647 c = self.load_default_context()
647 c = self.load_default_context()
648 c.active = 'labs'
648 c.active = 'labs'
649
649
650 application_form = LabsSettingsForm(self.request.translate)()
650 application_form = LabsSettingsForm(self.request.translate)()
651 try:
651 try:
652 form_result = application_form.to_python(dict(self.request.POST))
652 form_result = application_form.to_python(dict(self.request.POST))
653 except formencode.Invalid as errors:
653 except formencode.Invalid as errors:
654 h.flash(
654 h.flash(
655 _("Some form inputs contain invalid data."),
655 _("Some form inputs contain invalid data."),
656 category='error')
656 category='error')
657 data = render('rhodecode:templates/admin/settings/settings.mako',
657 data = render('rhodecode:templates/admin/settings/settings.mako',
658 self._get_template_context(c), self.request)
658 self._get_template_context(c), self.request)
659 html = formencode.htmlfill.render(
659 html = formencode.htmlfill.render(
660 data,
660 data,
661 defaults=errors.value,
661 defaults=errors.value,
662 errors=errors.unpack_errors() or {},
662 errors=errors.unpack_errors() or {},
663 prefix_error=False,
663 prefix_error=False,
664 encoding="UTF-8",
664 encoding="UTF-8",
665 force_defaults=False
665 force_defaults=False
666 )
666 )
667 return Response(html)
667 return Response(html)
668
668
669 try:
669 try:
670 session = Session()
670 session = Session()
671 for setting in _LAB_SETTINGS:
671 for setting in _LAB_SETTINGS:
672 setting_name = setting.key[len('rhodecode_'):]
672 setting_name = setting.key[len('rhodecode_'):]
673 sett = SettingsModel().create_or_update_setting(
673 sett = SettingsModel().create_or_update_setting(
674 setting_name, form_result[setting.key], setting.type)
674 setting_name, form_result[setting.key], setting.type)
675 session.add(sett)
675 session.add(sett)
676
676
677 except Exception:
677 except Exception:
678 log.exception('Exception while updating lab settings')
678 log.exception('Exception while updating lab settings')
679 h.flash(_('Error occurred during updating labs settings'),
679 h.flash(_('Error occurred during updating labs settings'),
680 category='error')
680 category='error')
681 else:
681 else:
682 Session().commit()
682 Session().commit()
683 SettingsModel().invalidate_settings_cache()
683 SettingsModel().invalidate_settings_cache()
684 h.flash(_('Updated Labs settings'), category='success')
684 h.flash(_('Updated Labs settings'), category='success')
685 raise HTTPFound(h.route_path('admin_settings_labs'))
685 raise HTTPFound(h.route_path('admin_settings_labs'))
686
686
687 data = render('rhodecode:templates/admin/settings/settings.mako',
687 data = render('rhodecode:templates/admin/settings/settings.mako',
688 self._get_template_context(c), self.request)
688 self._get_template_context(c), self.request)
689 html = formencode.htmlfill.render(
689 html = formencode.htmlfill.render(
690 data,
690 data,
691 defaults=self._form_defaults(),
691 defaults=self._form_defaults(),
692 encoding="UTF-8",
692 encoding="UTF-8",
693 force_defaults=False
693 force_defaults=False
694 )
694 )
695 return Response(html)
695 return Response(html)
696
696
697
697
698 # :param key: name of the setting including the 'rhodecode_' prefix
698 # :param key: name of the setting including the 'rhodecode_' prefix
699 # :param type: the RhodeCodeSetting type to use.
699 # :param type: the RhodeCodeSetting type to use.
700 # :param group: the i18ned group in which we should dispaly this setting
700 # :param group: the i18ned group in which we should dispaly this setting
701 # :param label: the i18ned label we should display for this setting
701 # :param label: the i18ned label we should display for this setting
702 # :param help: the i18ned help we should dispaly for this setting
702 # :param help: the i18ned help we should dispaly for this setting
703 LabSetting = collections.namedtuple(
703 LabSetting = collections.namedtuple(
704 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
704 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
705
705
706
706
707 # This list has to be kept in sync with the form
707 # This list has to be kept in sync with the form
708 # rhodecode.model.forms.LabsSettingsForm.
708 # rhodecode.model.forms.LabsSettingsForm.
709 _LAB_SETTINGS = [
709 _LAB_SETTINGS = [
710
710
711 ]
711 ]
@@ -1,311 +1,328 b''
1 ## snippet for displaying vcs settings
1 ## snippet for displaying vcs settings
2 ## usage:
2 ## usage:
3 ## <%namespace name="vcss" file="/base/vcssettings.mako"/>
3 ## <%namespace name="vcss" file="/base/vcssettings.mako"/>
4 ## ${vcss.vcs_settings_fields()}
4 ## ${vcss.vcs_settings_fields()}
5
5
6 <%def name="vcs_settings_fields(suffix='', svn_branch_patterns=None, svn_tag_patterns=None, repo_type=None, display_globals=False, **kwargs)">
6 <%def name="vcs_settings_fields(suffix='', svn_branch_patterns=None, svn_tag_patterns=None, repo_type=None, display_globals=False, **kwargs)">
7 % if display_globals:
7 % if display_globals:
8 <div class="panel panel-default">
8 <div class="panel panel-default">
9 <div class="panel-heading" id="general">
9 <div class="panel-heading" id="general">
10 <h3 class="panel-title">${_('General')}<a class="permalink" href="#general"></a></h3>
10 <h3 class="panel-title">${_('General')}<a class="permalink" href="#general"></a></h3>
11 </div>
11 </div>
12 <div class="panel-body">
12 <div class="panel-body">
13 <div class="field">
13 <div class="field">
14 <div class="checkbox">
14 <div class="checkbox">
15 ${h.checkbox('web_push_ssl' + suffix, 'True')}
15 ${h.checkbox('web_push_ssl' + suffix, 'True')}
16 <label for="web_push_ssl${suffix}">${_('Require SSL for vcs operations')}</label>
16 <label for="web_push_ssl${suffix}">${_('Require SSL for vcs operations')}</label>
17 </div>
17 </div>
18 <div class="label">
18 <div class="label">
19 <span class="help-block">${_('Activate to set RhodeCode to require SSL for pushing or pulling. If SSL certificate is missing it will return a HTTP Error 406: Not Acceptable.')}</span>
19 <span class="help-block">${_('Activate to set RhodeCode to require SSL for pushing or pulling. If SSL certificate is missing it will return a HTTP Error 406: Not Acceptable.')}</span>
20 </div>
20 </div>
21 </div>
21 </div>
22 </div>
22 </div>
23 </div>
23 </div>
24 % endif
24 % endif
25
25
26 % if display_globals or repo_type in ['git', 'hg']:
26 % if display_globals or repo_type in ['git', 'hg']:
27 <div class="panel panel-default">
27 <div class="panel panel-default">
28 <div class="panel-heading" id="vcs-hooks-options">
28 <div class="panel-heading" id="vcs-hooks-options">
29 <h3 class="panel-title">${_('Internal Hooks')}<a class="permalink" href="#vcs-hooks-options"></a></h3>
29 <h3 class="panel-title">${_('Internal Hooks')}<a class="permalink" href="#vcs-hooks-options"></a></h3>
30 </div>
30 </div>
31 <div class="panel-body">
31 <div class="panel-body">
32 <div class="field">
32 <div class="field">
33 <div class="checkbox">
33 <div class="checkbox">
34 ${h.checkbox('hooks_changegroup_repo_size' + suffix, 'True', **kwargs)}
34 ${h.checkbox('hooks_changegroup_repo_size' + suffix, 'True', **kwargs)}
35 <label for="hooks_changegroup_repo_size${suffix}">${_('Show repository size after push')}</label>
35 <label for="hooks_changegroup_repo_size${suffix}">${_('Show repository size after push')}</label>
36 </div>
36 </div>
37
37
38 <div class="label">
38 <div class="label">
39 <span class="help-block">${_('Trigger a hook that calculates repository size after each push.')}</span>
39 <span class="help-block">${_('Trigger a hook that calculates repository size after each push.')}</span>
40 </div>
40 </div>
41 <div class="checkbox">
41 <div class="checkbox">
42 ${h.checkbox('hooks_changegroup_push_logger' + suffix, 'True', **kwargs)}
42 ${h.checkbox('hooks_changegroup_push_logger' + suffix, 'True', **kwargs)}
43 <label for="hooks_changegroup_push_logger${suffix}">${_('Execute pre/post push hooks')}</label>
43 <label for="hooks_changegroup_push_logger${suffix}">${_('Execute pre/post push hooks')}</label>
44 </div>
44 </div>
45 <div class="label">
45 <div class="label">
46 <span class="help-block">${_('Execute Built in pre/post push hooks. This also executes rcextensions hooks.')}</span>
46 <span class="help-block">${_('Execute Built in pre/post push hooks. This also executes rcextensions hooks.')}</span>
47 </div>
47 </div>
48 <div class="checkbox">
48 <div class="checkbox">
49 ${h.checkbox('hooks_outgoing_pull_logger' + suffix, 'True', **kwargs)}
49 ${h.checkbox('hooks_outgoing_pull_logger' + suffix, 'True', **kwargs)}
50 <label for="hooks_outgoing_pull_logger${suffix}">${_('Execute pre/post pull hooks')}</label>
50 <label for="hooks_outgoing_pull_logger${suffix}">${_('Execute pre/post pull hooks')}</label>
51 </div>
51 </div>
52 <div class="label">
52 <div class="label">
53 <span class="help-block">${_('Execute Built in pre/post pull hooks. This also executes rcextensions hooks.')}</span>
53 <span class="help-block">${_('Execute Built in pre/post pull hooks. This also executes rcextensions hooks.')}</span>
54 </div>
54 </div>
55 </div>
55 </div>
56 </div>
56 </div>
57 </div>
57 </div>
58 % endif
58 % endif
59
59
60 % if display_globals or repo_type in ['hg']:
60 % if display_globals or repo_type in ['hg']:
61 <div class="panel panel-default">
61 <div class="panel panel-default">
62 <div class="panel-heading" id="vcs-hg-options">
62 <div class="panel-heading" id="vcs-hg-options">
63 <h3 class="panel-title">${_('Mercurial Settings')}<a class="permalink" href="#vcs-hg-options"></a></h3>
63 <h3 class="panel-title">${_('Mercurial Settings')}<a class="permalink" href="#vcs-hg-options"></a></h3>
64 </div>
64 </div>
65 <div class="panel-body">
65 <div class="panel-body">
66 <div class="checkbox">
66 <div class="checkbox">
67 ${h.checkbox('extensions_largefiles' + suffix, 'True', **kwargs)}
67 ${h.checkbox('extensions_largefiles' + suffix, 'True', **kwargs)}
68 <label for="extensions_largefiles${suffix}">${_('Enable largefiles extension')}</label>
68 <label for="extensions_largefiles${suffix}">${_('Enable largefiles extension')}</label>
69 </div>
69 </div>
70 <div class="label">
70 <div class="label">
71 % if display_globals:
71 % if display_globals:
72 <span class="help-block">${_('Enable Largefiles extensions for all repositories.')}</span>
72 <span class="help-block">${_('Enable Largefiles extensions for all repositories.')}</span>
73 % else:
73 % else:
74 <span class="help-block">${_('Enable Largefiles extensions for this repository.')}</span>
74 <span class="help-block">${_('Enable Largefiles extensions for this repository.')}</span>
75 % endif
75 % endif
76 </div>
76 </div>
77
77
78 % if display_globals:
78 % if display_globals:
79 <div class="field">
79 <div class="field">
80 <div class="input">
80 <div class="input">
81 ${h.text('largefiles_usercache' + suffix, size=59)}
81 ${h.text('largefiles_usercache' + suffix, size=59)}
82 </div>
82 </div>
83 </div>
83 </div>
84 <div class="label">
84 <div class="label">
85 <span class="help-block">${_('Filesystem location where Mercurial largefile objects should be stored.')}</span>
85 <span class="help-block">${_('Filesystem location where Mercurial largefile objects should be stored.')}</span>
86 </div>
86 </div>
87 % endif
87 % endif
88
88
89 <div class="checkbox">
89 <div class="checkbox">
90 ${h.checkbox('phases_publish' + suffix, 'True', **kwargs)}
90 ${h.checkbox('phases_publish' + suffix, 'True', **kwargs)}
91 <label for="phases_publish${suffix}">${_('Set repositories as publishing') if display_globals else _('Set repository as publishing')}</label>
91 <label for="phases_publish${suffix}">${_('Set repositories as publishing') if display_globals else _('Set repository as publishing')}</label>
92 </div>
92 </div>
93 <div class="label">
93 <div class="label">
94 <span class="help-block">${_('When this is enabled all commits in the repository are seen as public commits by clients.')}</span>
94 <span class="help-block">${_('When this is enabled all commits in the repository are seen as public commits by clients.')}</span>
95 </div>
95 </div>
96
96
97 <div class="checkbox">
97 <div class="checkbox">
98 ${h.checkbox('extensions_evolve' + suffix, 'True', **kwargs)}
98 ${h.checkbox('extensions_evolve' + suffix, 'True', **kwargs)}
99 <label for="extensions_evolve${suffix}">${_('Enable Evolve and Topic extension')}</label>
99 <label for="extensions_evolve${suffix}">${_('Enable Evolve and Topic extension')}</label>
100 </div>
100 </div>
101 <div class="label">
101 <div class="label">
102 % if display_globals:
102 % if display_globals:
103 <span class="help-block">${_('Enable Evolve and Topic extensions for all repositories.')}</span>
103 <span class="help-block">${_('Enable Evolve and Topic extensions for all repositories.')}</span>
104 % else:
104 % else:
105 <span class="help-block">${_('Enable Evolve and Topic extensions for this repository.')}</span>
105 <span class="help-block">${_('Enable Evolve and Topic extensions for this repository.')}</span>
106 % endif
106 % endif
107 </div>
107 </div>
108
108
109 </div>
109 </div>
110 </div>
110 </div>
111 % endif
111 % endif
112
112
113 % if display_globals or repo_type in ['git']:
113 % if display_globals or repo_type in ['git']:
114 <div class="panel panel-default">
114 <div class="panel panel-default">
115 <div class="panel-heading" id="vcs-git-options">
115 <div class="panel-heading" id="vcs-git-options">
116 <h3 class="panel-title">${_('Git Settings')}<a class="permalink" href="#vcs-git-options"></a></h3>
116 <h3 class="panel-title">${_('Git Settings')}<a class="permalink" href="#vcs-git-options"></a></h3>
117 </div>
117 </div>
118 <div class="panel-body">
118 <div class="panel-body">
119 <div class="checkbox">
119 <div class="checkbox">
120 ${h.checkbox('vcs_git_lfs_enabled' + suffix, 'True', **kwargs)}
120 ${h.checkbox('vcs_git_lfs_enabled' + suffix, 'True', **kwargs)}
121 <label for="vcs_git_lfs_enabled${suffix}">${_('Enable lfs extension')}</label>
121 <label for="vcs_git_lfs_enabled${suffix}">${_('Enable lfs extension')}</label>
122 </div>
122 </div>
123 <div class="label">
123 <div class="label">
124 % if display_globals:
124 % if display_globals:
125 <span class="help-block">${_('Enable lfs extensions for all repositories.')}</span>
125 <span class="help-block">${_('Enable lfs extensions for all repositories.')}</span>
126 % else:
126 % else:
127 <span class="help-block">${_('Enable lfs extensions for this repository.')}</span>
127 <span class="help-block">${_('Enable lfs extensions for this repository.')}</span>
128 % endif
128 % endif
129 </div>
129 </div>
130
130
131 % if display_globals:
131 % if display_globals:
132 <div class="field">
132 <div class="field">
133 <div class="input">
133 <div class="input">
134 ${h.text('vcs_git_lfs_store_location' + suffix, size=59)}
134 ${h.text('vcs_git_lfs_store_location' + suffix, size=59)}
135 </div>
135 </div>
136 </div>
136 </div>
137 <div class="label">
137 <div class="label">
138 <span class="help-block">${_('Filesystem location where Git lfs objects should be stored.')}</span>
138 <span class="help-block">${_('Filesystem location where Git lfs objects should be stored.')}</span>
139 </div>
139 </div>
140 % endif
140 % endif
141 </div>
141 </div>
142 </div>
142 </div>
143 % endif
143 % endif
144
144
145 % if display_globals or repo_type in ['svn']:
145 % if display_globals or repo_type in ['svn']:
146 <div class="panel panel-default">
146 <div class="panel panel-default">
147 <div class="panel-heading" id="vcs-svn-options">
147 <div class="panel-heading" id="vcs-svn-options">
148 <h3 class="panel-title">${_('Subversion Settings')}<a class="permalink" href="#vcs-svn-options"></a></h3>
148 <h3 class="panel-title">${_('Subversion Settings')}<a class="permalink" href="#vcs-svn-options"></a></h3>
149 </div>
149 </div>
150 <div class="panel-body">
150 <div class="panel-body">
151 <div class="field">
151 <div class="field">
152 <div class="content" >
152 <div class="content" >
153 <label>${_('mod_dav config')}</label><br/>
154 <code>path: ${c.svn_config_path}</code>
155 </div>
156 <br/>
157
158 <div>
159
160 % if c.svn_generate_config:
161 <span class="buttons">
162 <button class="btn btn-primary" id="vcs_svn_generate_cfg">${_('Re-generate Apache Config')}</button>
163 </span>
164 % endif
165 </div>
166 </div>
167
168 <div class="field">
169 <div class="content" >
153 <label>${_('Repository patterns')}</label><br/>
170 <label>${_('Repository patterns')}</label><br/>
154 </div>
171 </div>
155 </div>
172 </div>
156 <div class="label">
173 <div class="label">
157 <span class="help-block">${_('Patterns for identifying SVN branches and tags. For recursive search, use "*". Eg.: "/branches/*"')}</span>
174 <span class="help-block">${_('Patterns for identifying SVN branches and tags. For recursive search, use "*". Eg.: "/branches/*"')}</span>
158 </div>
175 </div>
159
176
160 <div class="field branch_patterns">
177 <div class="field branch_patterns">
161 <div class="input" >
178 <div class="input" >
162 <label>${_('Branches')}:</label><br/>
179 <label>${_('Branches')}:</label><br/>
163 </div>
180 </div>
164 % if svn_branch_patterns:
181 % if svn_branch_patterns:
165 % for branch in svn_branch_patterns:
182 % for branch in svn_branch_patterns:
166 <div class="input adjacent" id="${'id%s' % branch.ui_id}">
183 <div class="input adjacent" id="${'id%s' % branch.ui_id}">
167 ${h.hidden('branch_ui_key' + suffix, branch.ui_key)}
184 ${h.hidden('branch_ui_key' + suffix, branch.ui_key)}
168 ${h.text('branch_value_%d' % branch.ui_id + suffix, branch.ui_value, size=59, readonly="readonly", class_='disabled')}
185 ${h.text('branch_value_%d' % branch.ui_id + suffix, branch.ui_value, size=59, readonly="readonly", class_='disabled')}
169 % if kwargs.get('disabled') != 'disabled':
186 % if kwargs.get('disabled') != 'disabled':
170 <span class="btn btn-x" onclick="ajaxDeletePattern(${branch.ui_id},'${'id%s' % branch.ui_id}')">
187 <span class="btn btn-x" onclick="ajaxDeletePattern(${branch.ui_id},'${'id%s' % branch.ui_id}')">
171 ${_('Delete')}
188 ${_('Delete')}
172 </span>
189 </span>
173 % endif
190 % endif
174 </div>
191 </div>
175 % endfor
192 % endfor
176 %endif
193 %endif
177 </div>
194 </div>
178 % if kwargs.get('disabled') != 'disabled':
195 % if kwargs.get('disabled') != 'disabled':
179 <div class="field branch_patterns">
196 <div class="field branch_patterns">
180 <div class="input" >
197 <div class="input" >
181 ${h.text('new_svn_branch',size=59,placeholder='New branch pattern')}
198 ${h.text('new_svn_branch',size=59,placeholder='New branch pattern')}
182 </div>
199 </div>
183 </div>
200 </div>
184 % endif
201 % endif
185 <div class="field tag_patterns">
202 <div class="field tag_patterns">
186 <div class="input" >
203 <div class="input" >
187 <label>${_('Tags')}:</label><br/>
204 <label>${_('Tags')}:</label><br/>
188 </div>
205 </div>
189 % if svn_tag_patterns:
206 % if svn_tag_patterns:
190 % for tag in svn_tag_patterns:
207 % for tag in svn_tag_patterns:
191 <div class="input" id="${'id%s' % tag.ui_id + suffix}">
208 <div class="input" id="${'id%s' % tag.ui_id + suffix}">
192 ${h.hidden('tag_ui_key' + suffix, tag.ui_key)}
209 ${h.hidden('tag_ui_key' + suffix, tag.ui_key)}
193 ${h.text('tag_ui_value_new_%d' % tag.ui_id + suffix, tag.ui_value, size=59, readonly="readonly", class_='disabled tag_input')}
210 ${h.text('tag_ui_value_new_%d' % tag.ui_id + suffix, tag.ui_value, size=59, readonly="readonly", class_='disabled tag_input')}
194 % if kwargs.get('disabled') != 'disabled':
211 % if kwargs.get('disabled') != 'disabled':
195 <span class="btn btn-x" onclick="ajaxDeletePattern(${tag.ui_id},'${'id%s' % tag.ui_id}')">
212 <span class="btn btn-x" onclick="ajaxDeletePattern(${tag.ui_id},'${'id%s' % tag.ui_id}')">
196 ${_('Delete')}
213 ${_('Delete')}
197 </span>
214 </span>
198 %endif
215 %endif
199 </div>
216 </div>
200 % endfor
217 % endfor
201 % endif
218 % endif
202 </div>
219 </div>
203 % if kwargs.get('disabled') != 'disabled':
220 % if kwargs.get('disabled') != 'disabled':
204 <div class="field tag_patterns">
221 <div class="field tag_patterns">
205 <div class="input" >
222 <div class="input" >
206 ${h.text('new_svn_tag' + suffix, size=59, placeholder='New tag pattern')}
223 ${h.text('new_svn_tag' + suffix, size=59, placeholder='New tag pattern')}
207 </div>
224 </div>
208 </div>
225 </div>
209 %endif
226 %endif
210 </div>
227 </div>
211 </div>
228 </div>
212 % else:
229 % else:
213 ${h.hidden('new_svn_branch' + suffix, '')}
230 ${h.hidden('new_svn_branch' + suffix, '')}
214 ${h.hidden('new_svn_tag' + suffix, '')}
231 ${h.hidden('new_svn_tag' + suffix, '')}
215 % endif
232 % endif
216
233
217
234
218 % if display_globals or repo_type in ['hg', 'git']:
235 % if display_globals or repo_type in ['hg', 'git']:
219 <div class="panel panel-default">
236 <div class="panel panel-default">
220 <div class="panel-heading" id="vcs-pull-requests-options">
237 <div class="panel-heading" id="vcs-pull-requests-options">
221 <h3 class="panel-title">${_('Pull Request Settings')}<a class="permalink" href="#vcs-pull-requests-options"></a></h3>
238 <h3 class="panel-title">${_('Pull Request Settings')}<a class="permalink" href="#vcs-pull-requests-options"></a></h3>
222 </div>
239 </div>
223 <div class="panel-body">
240 <div class="panel-body">
224 <div class="checkbox">
241 <div class="checkbox">
225 ${h.checkbox('rhodecode_pr_merge_enabled' + suffix, 'True', **kwargs)}
242 ${h.checkbox('rhodecode_pr_merge_enabled' + suffix, 'True', **kwargs)}
226 <label for="rhodecode_pr_merge_enabled${suffix}">${_('Enable server-side merge for pull requests')}</label>
243 <label for="rhodecode_pr_merge_enabled${suffix}">${_('Enable server-side merge for pull requests')}</label>
227 </div>
244 </div>
228 <div class="label">
245 <div class="label">
229 <span class="help-block">${_('Note: when this feature is enabled, it only runs hooks defined in the rcextension package. Custom hooks added on the Admin -> Settings -> Hooks page will not be run when pull requests are automatically merged from the web interface.')}</span>
246 <span class="help-block">${_('Note: when this feature is enabled, it only runs hooks defined in the rcextension package. Custom hooks added on the Admin -> Settings -> Hooks page will not be run when pull requests are automatically merged from the web interface.')}</span>
230 </div>
247 </div>
231 <div class="checkbox">
248 <div class="checkbox">
232 ${h.checkbox('rhodecode_use_outdated_comments' + suffix, 'True', **kwargs)}
249 ${h.checkbox('rhodecode_use_outdated_comments' + suffix, 'True', **kwargs)}
233 <label for="rhodecode_use_outdated_comments${suffix}">${_('Invalidate and relocate inline comments during update')}</label>
250 <label for="rhodecode_use_outdated_comments${suffix}">${_('Invalidate and relocate inline comments during update')}</label>
234 </div>
251 </div>
235 <div class="label">
252 <div class="label">
236 <span class="help-block">${_('During the update of a pull request, the position of inline comments will be updated and outdated inline comments will be hidden.')}</span>
253 <span class="help-block">${_('During the update of a pull request, the position of inline comments will be updated and outdated inline comments will be hidden.')}</span>
237 </div>
254 </div>
238 </div>
255 </div>
239 </div>
256 </div>
240 % endif
257 % endif
241
258
242 % if display_globals or repo_type in ['hg', 'git', 'svn']:
259 % if display_globals or repo_type in ['hg', 'git', 'svn']:
243 <div class="panel panel-default">
260 <div class="panel panel-default">
244 <div class="panel-heading" id="vcs-pull-requests-options">
261 <div class="panel-heading" id="vcs-pull-requests-options">
245 <h3 class="panel-title">${_('Diff cache')}<a class="permalink" href="#vcs-pull-requests-options"></a></h3>
262 <h3 class="panel-title">${_('Diff cache')}<a class="permalink" href="#vcs-pull-requests-options"></a></h3>
246 </div>
263 </div>
247 <div class="panel-body">
264 <div class="panel-body">
248 <div class="checkbox">
265 <div class="checkbox">
249 ${h.checkbox('rhodecode_diff_cache' + suffix, 'True', **kwargs)}
266 ${h.checkbox('rhodecode_diff_cache' + suffix, 'True', **kwargs)}
250 <label for="rhodecode_diff_cache${suffix}">${_('Enable caching diffs for pull requests cache and commits')}</label>
267 <label for="rhodecode_diff_cache${suffix}">${_('Enable caching diffs for pull requests cache and commits')}</label>
251 </div>
268 </div>
252 </div>
269 </div>
253 </div>
270 </div>
254 % endif
271 % endif
255
272
256 % if display_globals or repo_type in ['hg',]:
273 % if display_globals or repo_type in ['hg',]:
257 <div class="panel panel-default">
274 <div class="panel panel-default">
258 <div class="panel-heading" id="vcs-pull-requests-options">
275 <div class="panel-heading" id="vcs-pull-requests-options">
259 <h3 class="panel-title">${_('Mercurial Pull Request Settings')}<a class="permalink" href="#vcs-hg-pull-requests-options"></a></h3>
276 <h3 class="panel-title">${_('Mercurial Pull Request Settings')}<a class="permalink" href="#vcs-hg-pull-requests-options"></a></h3>
260 </div>
277 </div>
261 <div class="panel-body">
278 <div class="panel-body">
262 ## Specific HG settings
279 ## Specific HG settings
263 <div class="checkbox">
280 <div class="checkbox">
264 ${h.checkbox('rhodecode_hg_use_rebase_for_merging' + suffix, 'True', **kwargs)}
281 ${h.checkbox('rhodecode_hg_use_rebase_for_merging' + suffix, 'True', **kwargs)}
265 <label for="rhodecode_hg_use_rebase_for_merging${suffix}">${_('Use rebase as merge strategy')}</label>
282 <label for="rhodecode_hg_use_rebase_for_merging${suffix}">${_('Use rebase as merge strategy')}</label>
266 </div>
283 </div>
267 <div class="label">
284 <div class="label">
268 <span class="help-block">${_('Use rebase instead of creating a merge commit when merging via web interface.')}</span>
285 <span class="help-block">${_('Use rebase instead of creating a merge commit when merging via web interface.')}</span>
269 </div>
286 </div>
270
287
271 <div class="checkbox">
288 <div class="checkbox">
272 ${h.checkbox('rhodecode_hg_close_branch_before_merging' + suffix, 'True', **kwargs)}
289 ${h.checkbox('rhodecode_hg_close_branch_before_merging' + suffix, 'True', **kwargs)}
273 <label for="rhodecode_hg_close_branch_before_merging{suffix}">${_('Close branch before merging it')}</label>
290 <label for="rhodecode_hg_close_branch_before_merging{suffix}">${_('Close branch before merging it')}</label>
274 </div>
291 </div>
275 <div class="label">
292 <div class="label">
276 <span class="help-block">${_('Close branch before merging it into destination branch. No effect when rebase strategy is use.')}</span>
293 <span class="help-block">${_('Close branch before merging it into destination branch. No effect when rebase strategy is use.')}</span>
277 </div>
294 </div>
278
295
279
296
280 </div>
297 </div>
281 </div>
298 </div>
282 % endif
299 % endif
283
300
284 ## DISABLED FOR GIT FOR NOW as the rebase/close is not supported yet
301 ## DISABLED FOR GIT FOR NOW as the rebase/close is not supported yet
285 ## % if display_globals or repo_type in ['git']:
302 ## % if display_globals or repo_type in ['git']:
286 ## <div class="panel panel-default">
303 ## <div class="panel panel-default">
287 ## <div class="panel-heading" id="vcs-pull-requests-options">
304 ## <div class="panel-heading" id="vcs-pull-requests-options">
288 ## <h3 class="panel-title">${_('Git Pull Request Settings')}<a class="permalink" href="#vcs-git-pull-requests-options"> ¶</a></h3>
305 ## <h3 class="panel-title">${_('Git Pull Request Settings')}<a class="permalink" href="#vcs-git-pull-requests-options"> ¶</a></h3>
289 ## </div>
306 ## </div>
290 ## <div class="panel-body">
307 ## <div class="panel-body">
291 ## <div class="checkbox">
308 ## <div class="checkbox">
292 ## ${h.checkbox('rhodecode_git_use_rebase_for_merging' + suffix, 'True', **kwargs)}
309 ## ${h.checkbox('rhodecode_git_use_rebase_for_merging' + suffix, 'True', **kwargs)}
293 ## <label for="rhodecode_git_use_rebase_for_merging${suffix}">${_('Use rebase as merge strategy')}</label>
310 ## <label for="rhodecode_git_use_rebase_for_merging${suffix}">${_('Use rebase as merge strategy')}</label>
294 ## </div>
311 ## </div>
295 ## <div class="label">
312 ## <div class="label">
296 ## <span class="help-block">${_('Use rebase instead of creating a merge commit when merging via web interface.')}</span>
313 ## <span class="help-block">${_('Use rebase instead of creating a merge commit when merging via web interface.')}</span>
297 ## </div>
314 ## </div>
298 ##
315 ##
299 ## <div class="checkbox">
316 ## <div class="checkbox">
300 ## ${h.checkbox('rhodecode_git_close_branch_before_merging' + suffix, 'True', **kwargs)}
317 ## ${h.checkbox('rhodecode_git_close_branch_before_merging' + suffix, 'True', **kwargs)}
301 ## <label for="rhodecode_git_close_branch_before_merging{suffix}">${_('Delete branch after merging it')}</label>
318 ## <label for="rhodecode_git_close_branch_before_merging{suffix}">${_('Delete branch after merging it')}</label>
302 ## </div>
319 ## </div>
303 ## <div class="label">
320 ## <div class="label">
304 ## <span class="help-block">${_('Delete branch after merging it into destination branch. No effect when rebase strategy is use.')}</span>
321 ## <span class="help-block">${_('Delete branch after merging it into destination branch. No effect when rebase strategy is use.')}</span>
305 ## </div>
322 ## </div>
306 ## </div>
323 ## </div>
307 ## </div>
324 ## </div>
308 ## % endif
325 ## % endif
309
326
310
327
311 </%def>
328 </%def>
General Comments 0
You need to be logged in to leave comments. Login now