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