##// END OF EJS Templates
nicer representation of list of rescanned repositories
marcink -
r3145:bee09f31 beta
parent child Browse files
Show More
@@ -1,517 +1,517 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.admin.settings
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 settings controller for rhodecode admin
7 7
8 8 :created_on: Jul 14, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software: you can redistribute it and/or modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26 26 import logging
27 27 import traceback
28 28 import formencode
29 29 import pkg_resources
30 30 import platform
31 31
32 32 from sqlalchemy import func
33 33 from formencode import htmlfill
34 34 from pylons import request, session, tmpl_context as c, url, config
35 35 from pylons.controllers.util import abort, redirect
36 36 from pylons.i18n.translation import _
37 37
38 38 from rhodecode.lib import helpers as h
39 39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
40 40 HasPermissionAnyDecorator, NotAnonymous
41 41 from rhodecode.lib.base import BaseController, render
42 42 from rhodecode.lib.celerylib import tasks, run_task
43 43 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
44 44 set_rhodecode_config, repo_name_slug, check_git_version
45 45 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
46 46 RhodeCodeSetting, PullRequest, PullRequestReviewers
47 47 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
48 48 ApplicationUiSettingsForm, ApplicationVisualisationForm
49 49 from rhodecode.model.scm import ScmModel
50 50 from rhodecode.model.user import UserModel
51 51 from rhodecode.model.db import User
52 52 from rhodecode.model.notification import EmailNotificationModel
53 53 from rhodecode.model.meta import Session
54 from rhodecode.lib.utils2 import str2bool
54 from rhodecode.lib.utils2 import str2bool, safe_unicode
55 55
56 56 log = logging.getLogger(__name__)
57 57
58 58
59 59 class SettingsController(BaseController):
60 60 """REST Controller styled on the Atom Publishing Protocol"""
61 61 # To properly map this controller, ensure your config/routing.py
62 62 # file has a resource setup:
63 63 # map.resource('setting', 'settings', controller='admin/settings',
64 64 # path_prefix='/admin', name_prefix='admin_')
65 65
66 66 @LoginRequired()
67 67 def __before__(self):
68 68 c.admin_user = session.get('admin_user')
69 69 c.admin_username = session.get('admin_username')
70 70 c.modules = sorted([(p.project_name, p.version)
71 71 for p in pkg_resources.working_set]
72 72 + [('git', check_git_version())],
73 73 key=lambda k: k[0].lower())
74 74 c.py_version = platform.python_version()
75 75 c.platform = platform.platform()
76 76 super(SettingsController, self).__before__()
77 77
78 78 @HasPermissionAllDecorator('hg.admin')
79 79 def index(self, format='html'):
80 80 """GET /admin/settings: All items in the collection"""
81 81 # url('admin_settings')
82 82
83 83 defaults = RhodeCodeSetting.get_app_settings()
84 84 defaults.update(self._get_hg_ui_settings())
85 85
86 86 return htmlfill.render(
87 87 render('admin/settings/settings.html'),
88 88 defaults=defaults,
89 89 encoding="UTF-8",
90 90 force_defaults=False
91 91 )
92 92
93 93 @HasPermissionAllDecorator('hg.admin')
94 94 def create(self):
95 95 """POST /admin/settings: Create a new item"""
96 96 # url('admin_settings')
97 97
98 98 @HasPermissionAllDecorator('hg.admin')
99 99 def new(self, format='html'):
100 100 """GET /admin/settings/new: Form to create a new item"""
101 101 # url('admin_new_setting')
102 102
103 103 @HasPermissionAllDecorator('hg.admin')
104 104 def update(self, setting_id):
105 105 """PUT /admin/settings/setting_id: Update an existing item"""
106 106 # Forms posted to this method should contain a hidden field:
107 107 # <input type="hidden" name="_method" value="PUT" />
108 108 # Or using helpers:
109 109 # h.form(url('admin_setting', setting_id=ID),
110 110 # method='put')
111 111 # url('admin_setting', setting_id=ID)
112 112
113 113 if setting_id == 'mapping':
114 114 rm_obsolete = request.POST.get('destroy', False)
115 115 log.debug('Rescanning directories with destroy=%s' % rm_obsolete)
116 116 initial = ScmModel().repo_scan()
117 117 log.debug('invalidating all repositories')
118 118 for repo_name in initial.keys():
119 119 invalidate_cache('get_repo_cached_%s' % repo_name)
120 120
121 121 added, removed = repo2db_mapper(initial, rm_obsolete)
122
122 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
123 123 h.flash(_('Repositories successfully'
124 ' rescanned added: %s, removed: %s') %
125 (len(added), len(removed)),
124 'rescanned added: %s ; removed: %s') %
125 (_repr(added), _repr(removed)),
126 126 category='success')
127 127
128 128 if setting_id == 'whoosh':
129 129 repo_location = self._get_hg_ui_settings()['paths_root_path']
130 130 full_index = request.POST.get('full_index', False)
131 131 run_task(tasks.whoosh_index, repo_location, full_index)
132 132 h.flash(_('Whoosh reindex task scheduled'), category='success')
133 133
134 134 if setting_id == 'global':
135 135
136 136 application_form = ApplicationSettingsForm()()
137 137 try:
138 138 form_result = application_form.to_python(dict(request.POST))
139 139 except formencode.Invalid, errors:
140 140 return htmlfill.render(
141 141 render('admin/settings/settings.html'),
142 142 defaults=errors.value,
143 143 errors=errors.error_dict or {},
144 144 prefix_error=False,
145 145 encoding="UTF-8"
146 146 )
147 147
148 148 try:
149 149 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
150 150 sett1.app_settings_value = form_result['rhodecode_title']
151 151 Session().add(sett1)
152 152
153 153 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
154 154 sett2.app_settings_value = form_result['rhodecode_realm']
155 155 Session().add(sett2)
156 156
157 157 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
158 158 sett3.app_settings_value = form_result['rhodecode_ga_code']
159 159 Session().add(sett3)
160 160
161 161 Session().commit()
162 162 set_rhodecode_config(config)
163 163 h.flash(_('Updated application settings'), category='success')
164 164
165 165 except Exception:
166 166 log.error(traceback.format_exc())
167 167 h.flash(_('error occurred during updating '
168 168 'application settings'),
169 169 category='error')
170 170
171 171 if setting_id == 'visual':
172 172
173 173 application_form = ApplicationVisualisationForm()()
174 174 try:
175 175 form_result = application_form.to_python(dict(request.POST))
176 176 except formencode.Invalid, errors:
177 177 return htmlfill.render(
178 178 render('admin/settings/settings.html'),
179 179 defaults=errors.value,
180 180 errors=errors.error_dict or {},
181 181 prefix_error=False,
182 182 encoding="UTF-8"
183 183 )
184 184
185 185 try:
186 186 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
187 187 sett1.app_settings_value = \
188 188 form_result['rhodecode_show_public_icon']
189 189 Session().add(sett1)
190 190
191 191 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
192 192 sett2.app_settings_value = \
193 193 form_result['rhodecode_show_private_icon']
194 194 Session().add(sett2)
195 195
196 196 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
197 197 sett3.app_settings_value = \
198 198 form_result['rhodecode_stylify_metatags']
199 199 Session().add(sett3)
200 200
201 201 sett4 = RhodeCodeSetting.get_by_name_or_create('lightweight_dashboard')
202 202 sett4.app_settings_value = \
203 203 form_result['rhodecode_lightweight_dashboard']
204 204 Session().add(sett4)
205 205
206 206 Session().commit()
207 207 set_rhodecode_config(config)
208 208 h.flash(_('Updated visualisation settings'),
209 209 category='success')
210 210
211 211 except Exception:
212 212 log.error(traceback.format_exc())
213 213 h.flash(_('error occurred during updating '
214 214 'visualisation settings'),
215 215 category='error')
216 216
217 217 if setting_id == 'vcs':
218 218 application_form = ApplicationUiSettingsForm()()
219 219 try:
220 220 form_result = application_form.to_python(dict(request.POST))
221 221 except formencode.Invalid, errors:
222 222 return htmlfill.render(
223 223 render('admin/settings/settings.html'),
224 224 defaults=errors.value,
225 225 errors=errors.error_dict or {},
226 226 prefix_error=False,
227 227 encoding="UTF-8"
228 228 )
229 229
230 230 try:
231 231 # fix namespaces for hooks and extensions
232 232 _f = lambda s: s.replace('.', '_')
233 233
234 234 sett = RhodeCodeUi.get_by_key('push_ssl')
235 235 sett.ui_value = form_result['web_push_ssl']
236 236 Session().add(sett)
237 237
238 238 sett = RhodeCodeUi.get_by_key('/')
239 239 sett.ui_value = form_result['paths_root_path']
240 240 Session().add(sett)
241 241
242 242 #HOOKS
243 243 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE)
244 244 sett.ui_active = form_result[_f('hooks_%s' %
245 245 RhodeCodeUi.HOOK_UPDATE)]
246 246 Session().add(sett)
247 247
248 248 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_REPO_SIZE)
249 249 sett.ui_active = form_result[_f('hooks_%s' %
250 250 RhodeCodeUi.HOOK_REPO_SIZE)]
251 251 Session().add(sett)
252 252
253 253 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PUSH)
254 254 sett.ui_active = form_result[_f('hooks_%s' %
255 255 RhodeCodeUi.HOOK_PUSH)]
256 256 Session().add(sett)
257 257
258 258 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PULL)
259 259 sett.ui_active = form_result[_f('hooks_%s' %
260 260 RhodeCodeUi.HOOK_PULL)]
261 261
262 262 Session().add(sett)
263 263
264 264 ## EXTENSIONS
265 265 sett = RhodeCodeUi.get_by_key('largefiles')
266 266 if not sett:
267 267 #make one if it's not there !
268 268 sett = RhodeCodeUi()
269 269 sett.ui_key = 'largefiles'
270 270 sett.ui_section = 'extensions'
271 271 sett.ui_active = form_result[_f('extensions_largefiles')]
272 272 Session().add(sett)
273 273
274 274 sett = RhodeCodeUi.get_by_key('hgsubversion')
275 275 if not sett:
276 276 #make one if it's not there !
277 277 sett = RhodeCodeUi()
278 278 sett.ui_key = 'hgsubversion'
279 279 sett.ui_section = 'extensions'
280 280
281 281 sett.ui_active = form_result[_f('extensions_hgsubversion')]
282 282 Session().add(sett)
283 283
284 284 # sett = RhodeCodeUi.get_by_key('hggit')
285 285 # if not sett:
286 286 # #make one if it's not there !
287 287 # sett = RhodeCodeUi()
288 288 # sett.ui_key = 'hggit'
289 289 # sett.ui_section = 'extensions'
290 290 #
291 291 # sett.ui_active = form_result[_f('extensions_hggit')]
292 292 # Session().add(sett)
293 293
294 294 Session().commit()
295 295
296 296 h.flash(_('Updated VCS settings'), category='success')
297 297
298 298 except Exception:
299 299 log.error(traceback.format_exc())
300 300 h.flash(_('error occurred during updating '
301 301 'application settings'), category='error')
302 302
303 303 if setting_id == 'hooks':
304 304 ui_key = request.POST.get('new_hook_ui_key')
305 305 ui_value = request.POST.get('new_hook_ui_value')
306 306 try:
307 307
308 308 if ui_value and ui_key:
309 309 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
310 310 h.flash(_('Added new hook'),
311 311 category='success')
312 312
313 313 # check for edits
314 314 update = False
315 315 _d = request.POST.dict_of_lists()
316 316 for k, v in zip(_d.get('hook_ui_key', []),
317 317 _d.get('hook_ui_value_new', [])):
318 318 RhodeCodeUi.create_or_update_hook(k, v)
319 319 update = True
320 320
321 321 if update:
322 322 h.flash(_('Updated hooks'), category='success')
323 323 Session().commit()
324 324 except Exception:
325 325 log.error(traceback.format_exc())
326 326 h.flash(_('error occurred during hook creation'),
327 327 category='error')
328 328
329 329 return redirect(url('admin_edit_setting', setting_id='hooks'))
330 330
331 331 if setting_id == 'email':
332 332 test_email = request.POST.get('test_email')
333 333 test_email_subj = 'RhodeCode TestEmail'
334 334 test_email_body = 'RhodeCode Email test'
335 335
336 336 test_email_html_body = EmailNotificationModel()\
337 337 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
338 338 body=test_email_body)
339 339
340 340 recipients = [test_email] if test_email else None
341 341
342 342 run_task(tasks.send_email, recipients, test_email_subj,
343 343 test_email_body, test_email_html_body)
344 344
345 345 h.flash(_('Email task created'), category='success')
346 346 return redirect(url('admin_settings'))
347 347
348 348 @HasPermissionAllDecorator('hg.admin')
349 349 def delete(self, setting_id):
350 350 """DELETE /admin/settings/setting_id: Delete an existing item"""
351 351 # Forms posted to this method should contain a hidden field:
352 352 # <input type="hidden" name="_method" value="DELETE" />
353 353 # Or using helpers:
354 354 # h.form(url('admin_setting', setting_id=ID),
355 355 # method='delete')
356 356 # url('admin_setting', setting_id=ID)
357 357 if setting_id == 'hooks':
358 358 hook_id = request.POST.get('hook_id')
359 359 RhodeCodeUi.delete(hook_id)
360 360 Session().commit()
361 361
362 362 @HasPermissionAllDecorator('hg.admin')
363 363 def show(self, setting_id, format='html'):
364 364 """
365 365 GET /admin/settings/setting_id: Show a specific item"""
366 366 # url('admin_setting', setting_id=ID)
367 367
368 368 @HasPermissionAllDecorator('hg.admin')
369 369 def edit(self, setting_id, format='html'):
370 370 """
371 371 GET /admin/settings/setting_id/edit: Form to
372 372 edit an existing item"""
373 373 # url('admin_edit_setting', setting_id=ID)
374 374
375 375 c.hooks = RhodeCodeUi.get_builtin_hooks()
376 376 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
377 377
378 378 return htmlfill.render(
379 379 render('admin/settings/hooks.html'),
380 380 defaults={},
381 381 encoding="UTF-8",
382 382 force_defaults=False
383 383 )
384 384
385 385 @NotAnonymous()
386 386 def my_account(self):
387 387 """
388 388 GET /_admin/my_account Displays info about my account
389 389 """
390 390 # url('admin_settings_my_account')
391 391
392 392 c.user = User.get(self.rhodecode_user.user_id)
393 393 all_repos = Session().query(Repository)\
394 394 .filter(Repository.user_id == c.user.user_id)\
395 395 .order_by(func.lower(Repository.repo_name)).all()
396 396
397 397 c.user_repos = ScmModel().get_repos(all_repos)
398 398
399 399 if c.user.username == 'default':
400 400 h.flash(_("You can't edit this user since it's"
401 401 " crucial for entire application"), category='warning')
402 402 return redirect(url('users'))
403 403
404 404 defaults = c.user.get_dict()
405 405
406 406 c.form = htmlfill.render(
407 407 render('admin/users/user_edit_my_account_form.html'),
408 408 defaults=defaults,
409 409 encoding="UTF-8",
410 410 force_defaults=False
411 411 )
412 412 return render('admin/users/user_edit_my_account.html')
413 413
414 414 @NotAnonymous()
415 415 def my_account_update(self):
416 416 """PUT /_admin/my_account_update: Update an existing item"""
417 417 # Forms posted to this method should contain a hidden field:
418 418 # <input type="hidden" name="_method" value="PUT" />
419 419 # Or using helpers:
420 420 # h.form(url('admin_settings_my_account_update'),
421 421 # method='put')
422 422 # url('admin_settings_my_account_update', id=ID)
423 423 uid = self.rhodecode_user.user_id
424 424 email = self.rhodecode_user.email
425 425 _form = UserForm(edit=True,
426 426 old_data={'user_id': uid, 'email': email})()
427 427 form_result = {}
428 428 try:
429 429 form_result = _form.to_python(dict(request.POST))
430 430 UserModel().update_my_account(uid, form_result)
431 431 h.flash(_('Your account was updated successfully'),
432 432 category='success')
433 433 Session().commit()
434 434 except formencode.Invalid, errors:
435 435 c.user = User.get(self.rhodecode_user.user_id)
436 436
437 437 c.form = htmlfill.render(
438 438 render('admin/users/user_edit_my_account_form.html'),
439 439 defaults=errors.value,
440 440 errors=errors.error_dict or {},
441 441 prefix_error=False,
442 442 encoding="UTF-8")
443 443 return render('admin/users/user_edit_my_account.html')
444 444 except Exception:
445 445 log.error(traceback.format_exc())
446 446 h.flash(_('error occurred during update of user %s') \
447 447 % form_result.get('username'), category='error')
448 448
449 449 return redirect(url('my_account'))
450 450
451 451 @NotAnonymous()
452 452 def my_account_my_repos(self):
453 453 all_repos = Session().query(Repository)\
454 454 .filter(Repository.user_id == self.rhodecode_user.user_id)\
455 455 .order_by(func.lower(Repository.repo_name))\
456 456 .all()
457 457 c.user_repos = ScmModel().get_repos(all_repos)
458 458 return render('admin/users/user_edit_my_account_repos.html')
459 459
460 460 @NotAnonymous()
461 461 def my_account_my_pullrequests(self):
462 462 c.my_pull_requests = PullRequest.query()\
463 463 .filter(PullRequest.user_id==
464 464 self.rhodecode_user.user_id)\
465 465 .all()
466 466 c.participate_in_pull_requests = \
467 467 [x.pull_request for x in PullRequestReviewers.query()\
468 468 .filter(PullRequestReviewers.user_id==
469 469 self.rhodecode_user.user_id)\
470 470 .all()]
471 471 return render('admin/users/user_edit_my_account_pullrequests.html')
472 472
473 473 @NotAnonymous()
474 474 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
475 475 def create_repository(self):
476 476 """GET /_admin/create_repository: Form to create a new item"""
477 477
478 478 c.repo_groups = RepoGroup.groups_choices(check_perms=True)
479 479 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
480 480 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
481 481
482 482 new_repo = request.GET.get('repo', '')
483 483 c.new_repo = repo_name_slug(new_repo)
484 484
485 485 ## apply the defaults from defaults page
486 486 defaults = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
487 487 return htmlfill.render(
488 488 render('admin/repos/repo_add_create_repository.html'),
489 489 defaults=defaults,
490 490 errors={},
491 491 prefix_error=False,
492 492 encoding="UTF-8"
493 493 )
494 494
495 495 def _get_hg_ui_settings(self):
496 496 ret = RhodeCodeUi.query().all()
497 497
498 498 if not ret:
499 499 raise Exception('Could not get application ui settings !')
500 500 settings = {}
501 501 for each in ret:
502 502 k = each.ui_key
503 503 v = each.ui_value
504 504 if k == '/':
505 505 k = 'root_path'
506 506
507 507 if k == 'push_ssl':
508 508 v = str2bool(v)
509 509
510 510 if k.find('.') != -1:
511 511 k = k.replace('.', '_')
512 512
513 513 if each.ui_section in ['hooks', 'extensions']:
514 514 v = each.ui_active
515 515
516 516 settings[each.ui_section + '_' + k] = v
517 517 return settings
General Comments 0
You need to be logged in to leave comments. Login now