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