##// END OF EJS Templates
Added extra flag to invalidate caches when doing rescan from web...
marcink -
r3951:9378d864 beta
parent child Browse files
Show More
@@ -1,519 +1,523 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, HasPermissionAny,\
41 41 HasReposGroupPermissionAll, HasReposGroupPermissionAny, AuthUser
42 42 from rhodecode.lib.base import BaseController, render
43 43 from rhodecode.lib.celerylib import tasks, run_task
44 44 from rhodecode.lib.utils import repo2db_mapper, set_rhodecode_config, \
45 45 check_git_version
46 46 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
47 47 RhodeCodeSetting, PullRequest, PullRequestReviewers
48 48 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
49 49 ApplicationUiSettingsForm, ApplicationVisualisationForm
50 50 from rhodecode.model.scm import ScmModel, RepoGroupList
51 51 from rhodecode.model.user import UserModel
52 52 from rhodecode.model.repo import RepoModel
53 53 from rhodecode.model.db import User
54 54 from rhodecode.model.notification import EmailNotificationModel
55 55 from rhodecode.model.meta import Session
56 56 from rhodecode.lib.utils2 import str2bool, safe_unicode
57 57 from rhodecode.lib.compat import json
58 58 log = logging.getLogger(__name__)
59 59
60 60
61 61 class SettingsController(BaseController):
62 62 """REST Controller styled on the Atom Publishing Protocol"""
63 63 # To properly map this controller, ensure your config/routing.py
64 64 # file has a resource setup:
65 65 # map.resource('setting', 'settings', controller='admin/settings',
66 66 # path_prefix='/admin', name_prefix='admin_')
67 67
68 68 @LoginRequired()
69 69 def __before__(self):
70 70 super(SettingsController, self).__before__()
71 71 c.modules = sorted([(p.project_name, p.version)
72 72 for p in pkg_resources.working_set]
73 73 + [('git', check_git_version())],
74 74 key=lambda k: k[0].lower())
75 75 c.py_version = platform.python_version()
76 76 c.platform = platform.platform()
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 log.debug('Rescanning directories with destroy=%s' % rm_obsolete)
115 invalidate_cache = request.POST.get('invalidate', False)
116 log.debug('rescanning directories with destroy obsolete=%s'
117 % (rm_obsolete,))
116 118 initial = ScmModel().repo_scan()
117 log.debug('invalidating all repositories')
118 for repo_name in initial.keys():
119 ScmModel().mark_for_invalidation(repo_name)
119
120 if invalidate_cache:
121 log.debug('invalidating all repositories cache')
122 for repo_name in initial.keys():
123 ScmModel().mark_for_invalidation(repo_name)
120 124
121 125 added, removed = repo2db_mapper(initial, rm_obsolete)
122 126 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
123 127 h.flash(_('Repositories successfully '
124 128 'rescanned added: %s ; removed: %s') %
125 129 (_repr(added), _repr(removed)),
126 130 category='success')
127 131
128 132 if setting_id == 'whoosh':
129 133 repo_location = self._get_hg_ui_settings()['paths_root_path']
130 134 full_index = request.POST.get('full_index', False)
131 135 run_task(tasks.whoosh_index, repo_location, full_index)
132 136 h.flash(_('Whoosh reindex task scheduled'), category='success')
133 137
134 138 if setting_id == 'global':
135 139
136 140 application_form = ApplicationSettingsForm()()
137 141 try:
138 142 form_result = application_form.to_python(dict(request.POST))
139 143 except formencode.Invalid, errors:
140 144 return htmlfill.render(
141 145 render('admin/settings/settings.html'),
142 146 defaults=errors.value,
143 147 errors=errors.error_dict or {},
144 148 prefix_error=False,
145 149 encoding="UTF-8"
146 150 )
147 151
148 152 try:
149 153 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
150 154 sett1.app_settings_value = form_result['rhodecode_title']
151 155 Session().add(sett1)
152 156
153 157 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
154 158 sett2.app_settings_value = form_result['rhodecode_realm']
155 159 Session().add(sett2)
156 160
157 161 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
158 162 sett3.app_settings_value = form_result['rhodecode_ga_code']
159 163 Session().add(sett3)
160 164
161 165 Session().commit()
162 166 set_rhodecode_config(config)
163 167 h.flash(_('Updated application settings'), category='success')
164 168
165 169 except Exception:
166 170 log.error(traceback.format_exc())
167 171 h.flash(_('Error occurred during updating '
168 172 'application settings'),
169 173 category='error')
170 174
171 175 if setting_id == 'visual':
172 176
173 177 application_form = ApplicationVisualisationForm()()
174 178 try:
175 179 form_result = application_form.to_python(dict(request.POST))
176 180 except formencode.Invalid, errors:
177 181 return htmlfill.render(
178 182 render('admin/settings/settings.html'),
179 183 defaults=errors.value,
180 184 errors=errors.error_dict or {},
181 185 prefix_error=False,
182 186 encoding="UTF-8"
183 187 )
184 188
185 189 try:
186 190 #TODO: rewrite this to something less ugly
187 191 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
188 192 sett1.app_settings_value = \
189 193 form_result['rhodecode_show_public_icon']
190 194 Session().add(sett1)
191 195
192 196 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
193 197 sett2.app_settings_value = \
194 198 form_result['rhodecode_show_private_icon']
195 199 Session().add(sett2)
196 200
197 201 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
198 202 sett3.app_settings_value = \
199 203 form_result['rhodecode_stylify_metatags']
200 204 Session().add(sett3)
201 205
202 206 sett4 = RhodeCodeSetting.get_by_name_or_create('repository_fields')
203 207 sett4.app_settings_value = \
204 208 form_result['rhodecode_repository_fields']
205 209 Session().add(sett4)
206 210
207 211 sett5 = RhodeCodeSetting.get_by_name_or_create('dashboard_items')
208 212 sett5.app_settings_value = \
209 213 form_result['rhodecode_dashboard_items']
210 214 Session().add(sett5)
211 215
212 216 sett6 = RhodeCodeSetting.get_by_name_or_create('show_version')
213 217 sett6.app_settings_value = \
214 218 form_result['rhodecode_show_version']
215 219 Session().add(sett6)
216 220
217 221 Session().commit()
218 222 set_rhodecode_config(config)
219 223 h.flash(_('Updated visualisation settings'),
220 224 category='success')
221 225
222 226 except Exception:
223 227 log.error(traceback.format_exc())
224 228 h.flash(_('Error occurred during updating '
225 229 'visualisation settings'),
226 230 category='error')
227 231
228 232 if setting_id == 'vcs':
229 233 application_form = ApplicationUiSettingsForm()()
230 234 try:
231 235 form_result = application_form.to_python(dict(request.POST))
232 236 except formencode.Invalid, errors:
233 237 return htmlfill.render(
234 238 render('admin/settings/settings.html'),
235 239 defaults=errors.value,
236 240 errors=errors.error_dict or {},
237 241 prefix_error=False,
238 242 encoding="UTF-8"
239 243 )
240 244
241 245 try:
242 246 sett = RhodeCodeUi.get_by_key('push_ssl')
243 247 sett.ui_value = form_result['web_push_ssl']
244 248 Session().add(sett)
245 249 if c.visual.allow_repo_location_change:
246 250 sett = RhodeCodeUi.get_by_key('/')
247 251 sett.ui_value = form_result['paths_root_path']
248 252 Session().add(sett)
249 253
250 254 #HOOKS
251 255 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE)
252 256 sett.ui_active = form_result['hooks_changegroup_update']
253 257 Session().add(sett)
254 258
255 259 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_REPO_SIZE)
256 260 sett.ui_active = form_result['hooks_changegroup_repo_size']
257 261 Session().add(sett)
258 262
259 263 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PUSH)
260 264 sett.ui_active = form_result['hooks_changegroup_push_logger']
261 265 Session().add(sett)
262 266
263 267 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PULL)
264 268 sett.ui_active = form_result['hooks_outgoing_pull_logger']
265 269
266 270 Session().add(sett)
267 271
268 272 ## EXTENSIONS
269 273 sett = RhodeCodeUi.get_by_key('largefiles')
270 274 if not sett:
271 275 #make one if it's not there !
272 276 sett = RhodeCodeUi()
273 277 sett.ui_key = 'largefiles'
274 278 sett.ui_section = 'extensions'
275 279 sett.ui_active = form_result['extensions_largefiles']
276 280 Session().add(sett)
277 281
278 282 sett = RhodeCodeUi.get_by_key('hgsubversion')
279 283 if not sett:
280 284 #make one if it's not there !
281 285 sett = RhodeCodeUi()
282 286 sett.ui_key = 'hgsubversion'
283 287 sett.ui_section = 'extensions'
284 288
285 289 sett.ui_active = form_result['extensions_hgsubversion']
286 290 Session().add(sett)
287 291
288 292 # sett = RhodeCodeUi.get_by_key('hggit')
289 293 # if not sett:
290 294 # #make one if it's not there !
291 295 # sett = RhodeCodeUi()
292 296 # sett.ui_key = 'hggit'
293 297 # sett.ui_section = 'extensions'
294 298 #
295 299 # sett.ui_active = form_result['extensions_hggit']
296 300 # Session().add(sett)
297 301
298 302 Session().commit()
299 303
300 304 h.flash(_('Updated VCS settings'), category='success')
301 305
302 306 except Exception:
303 307 log.error(traceback.format_exc())
304 308 h.flash(_('Error occurred during updating '
305 309 'application settings'), category='error')
306 310
307 311 if setting_id == 'hooks':
308 312 ui_key = request.POST.get('new_hook_ui_key')
309 313 ui_value = request.POST.get('new_hook_ui_value')
310 314 try:
311 315
312 316 if ui_value and ui_key:
313 317 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
314 318 h.flash(_('Added new hook'),
315 319 category='success')
316 320
317 321 # check for edits
318 322 update = False
319 323 _d = request.POST.dict_of_lists()
320 324 for k, v in zip(_d.get('hook_ui_key', []),
321 325 _d.get('hook_ui_value_new', [])):
322 326 RhodeCodeUi.create_or_update_hook(k, v)
323 327 update = True
324 328
325 329 if update:
326 330 h.flash(_('Updated hooks'), category='success')
327 331 Session().commit()
328 332 except Exception:
329 333 log.error(traceback.format_exc())
330 334 h.flash(_('Error occurred during hook creation'),
331 335 category='error')
332 336
333 337 return redirect(url('admin_edit_setting', setting_id='hooks'))
334 338
335 339 if setting_id == 'email':
336 340 test_email = request.POST.get('test_email')
337 341 test_email_subj = 'RhodeCode TestEmail'
338 342 test_email_body = 'RhodeCode Email test'
339 343
340 344 test_email_html_body = EmailNotificationModel()\
341 345 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
342 346 body=test_email_body)
343 347
344 348 recipients = [test_email] if test_email else None
345 349
346 350 run_task(tasks.send_email, recipients, test_email_subj,
347 351 test_email_body, test_email_html_body)
348 352
349 353 h.flash(_('Email task created'), category='success')
350 354 return redirect(url('admin_settings'))
351 355
352 356 @HasPermissionAllDecorator('hg.admin')
353 357 def delete(self, setting_id):
354 358 """DELETE /admin/settings/setting_id: Delete an existing item"""
355 359 # Forms posted to this method should contain a hidden field:
356 360 # <input type="hidden" name="_method" value="DELETE" />
357 361 # Or using helpers:
358 362 # h.form(url('admin_setting', setting_id=ID),
359 363 # method='delete')
360 364 # url('admin_setting', setting_id=ID)
361 365 if setting_id == 'hooks':
362 366 hook_id = request.POST.get('hook_id')
363 367 RhodeCodeUi.delete(hook_id)
364 368 Session().commit()
365 369
366 370 @HasPermissionAllDecorator('hg.admin')
367 371 def show(self, setting_id, format='html'):
368 372 """
369 373 GET /admin/settings/setting_id: Show a specific item"""
370 374 # url('admin_setting', setting_id=ID)
371 375
372 376 @HasPermissionAllDecorator('hg.admin')
373 377 def edit(self, setting_id, format='html'):
374 378 """
375 379 GET /admin/settings/setting_id/edit: Form to
376 380 edit an existing item"""
377 381 # url('admin_edit_setting', setting_id=ID)
378 382
379 383 c.hooks = RhodeCodeUi.get_builtin_hooks()
380 384 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
381 385
382 386 return htmlfill.render(
383 387 render('admin/settings/hooks.html'),
384 388 defaults={},
385 389 encoding="UTF-8",
386 390 force_defaults=False
387 391 )
388 392
389 393 def _load_my_repos_data(self):
390 394 repos_list = Session().query(Repository)\
391 395 .filter(Repository.user_id ==
392 396 self.rhodecode_user.user_id)\
393 397 .order_by(func.lower(Repository.repo_name)).all()
394 398
395 399 repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
396 400 admin=True)
397 401 #json used to render the grid
398 402 return json.dumps(repos_data)
399 403
400 404 @NotAnonymous()
401 405 def my_account(self):
402 406 """
403 407 GET /_admin/my_account Displays info about my account
404 408 """
405 409 # url('admin_settings_my_account')
406 410
407 411 c.user = User.get(self.rhodecode_user.user_id)
408 412 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id,
409 413 ip_addr=self.ip_addr)
410 414 c.ldap_dn = c.user.ldap_dn
411 415
412 416 if c.user.username == 'default':
413 417 h.flash(_("You can't edit this user since it's"
414 418 " crucial for entire application"), category='warning')
415 419 return redirect(url('users'))
416 420
417 421 #json used to render the grid
418 422 c.data = self._load_my_repos_data()
419 423
420 424 defaults = c.user.get_dict()
421 425
422 426 c.form = htmlfill.render(
423 427 render('admin/users/user_edit_my_account_form.html'),
424 428 defaults=defaults,
425 429 encoding="UTF-8",
426 430 force_defaults=False
427 431 )
428 432 return render('admin/users/user_edit_my_account.html')
429 433
430 434 @NotAnonymous()
431 435 def my_account_update(self):
432 436 """PUT /_admin/my_account_update: Update an existing item"""
433 437 # Forms posted to this method should contain a hidden field:
434 438 # <input type="hidden" name="_method" value="PUT" />
435 439 # Or using helpers:
436 440 # h.form(url('admin_settings_my_account_update'),
437 441 # method='put')
438 442 # url('admin_settings_my_account_update', id=ID)
439 443 uid = self.rhodecode_user.user_id
440 444 c.user = User.get(self.rhodecode_user.user_id)
441 445 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id,
442 446 ip_addr=self.ip_addr)
443 447 c.ldap_dn = c.user.ldap_dn
444 448 email = self.rhodecode_user.email
445 449 _form = UserForm(edit=True,
446 450 old_data={'user_id': uid, 'email': email})()
447 451 form_result = {}
448 452 try:
449 453 form_result = _form.to_python(dict(request.POST))
450 454 skip_attrs = ['admin', 'active'] # skip attr for my account
451 455 if c.ldap_dn:
452 456 #forbid updating username for ldap accounts
453 457 skip_attrs.append('username')
454 458 UserModel().update(uid, form_result, skip_attrs=skip_attrs)
455 459 h.flash(_('Your account was updated successfully'),
456 460 category='success')
457 461 Session().commit()
458 462 except formencode.Invalid, errors:
459 463 #json used to render the grid
460 464 c.data = self._load_my_repos_data()
461 465 c.form = htmlfill.render(
462 466 render('admin/users/user_edit_my_account_form.html'),
463 467 defaults=errors.value,
464 468 errors=errors.error_dict or {},
465 469 prefix_error=False,
466 470 encoding="UTF-8")
467 471 return render('admin/users/user_edit_my_account.html')
468 472 except Exception:
469 473 log.error(traceback.format_exc())
470 474 h.flash(_('Error occurred during update of user %s') \
471 475 % form_result.get('username'), category='error')
472 476
473 477 return redirect(url('my_account'))
474 478
475 479 @NotAnonymous()
476 480 def my_account_my_pullrequests(self):
477 481 c.show_closed = request.GET.get('pr_show_closed')
478 482
479 483 def _filter(pr):
480 484 s = sorted(pr, key=lambda o: o.created_on, reverse=True)
481 485 if not c.show_closed:
482 486 s = filter(lambda p: p.status != PullRequest.STATUS_CLOSED, s)
483 487 return s
484 488
485 489 c.my_pull_requests = _filter(PullRequest.query()\
486 490 .filter(PullRequest.user_id ==
487 491 self.rhodecode_user.user_id)\
488 492 .all())
489 493
490 494 c.participate_in_pull_requests = _filter([
491 495 x.pull_request for x in PullRequestReviewers.query()\
492 496 .filter(PullRequestReviewers.user_id ==
493 497 self.rhodecode_user.user_id).all()])
494 498
495 499 return render('admin/users/user_edit_my_account_pullrequests.html')
496 500
497 501 def _get_hg_ui_settings(self):
498 502 ret = RhodeCodeUi.query().all()
499 503
500 504 if not ret:
501 505 raise Exception('Could not get application ui settings !')
502 506 settings = {}
503 507 for each in ret:
504 508 k = each.ui_key
505 509 v = each.ui_value
506 510 if k == '/':
507 511 k = 'root_path'
508 512
509 513 if k == 'push_ssl':
510 514 v = str2bool(v)
511 515
512 516 if k.find('.') != -1:
513 517 k = k.replace('.', '_')
514 518
515 519 if each.ui_section in ['hooks', 'extensions']:
516 520 v = each.ui_active
517 521
518 522 settings[each.ui_section + '_' + k] = v
519 523 return settings
@@ -1,358 +1,364 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.html"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Settings administration')} &middot; ${c.rhodecode_name}
6 6 </%def>
7 7
8 8 <%def name="breadcrumbs_links()">
9 9 ${h.link_to(_('Admin'),h.url('admin_home'))}
10 10 &raquo;
11 11 ${_('Settings')}
12 12 </%def>
13 13
14 14 <%def name="page_nav()">
15 15 ${self.menu('admin')}
16 16 </%def>
17 17
18 18 <%def name="main()">
19 19 <div class="box">
20 20 <!-- box / title -->
21 21 <div class="title">
22 22 ${self.breadcrumbs()}
23 23 </div>
24 24 <!-- end box / title -->
25 25
26 26 <h3>${_('Remap and rescan repositories')}</h3>
27 27 ${h.form(url('admin_setting', setting_id='mapping'),method='put')}
28 28 <div class="form">
29 29 <!-- fields -->
30 30
31 31 <div class="fields">
32 32 <div class="field">
33 33 <div class="label label-checkbox">
34 34 <label for="destroy">${_('Rescan option')}:</label>
35 35 </div>
36 36 <div class="checkboxes">
37 37 <div class="checkbox">
38 38 ${h.checkbox('destroy',True)}
39 39 <label for="destroy">
40 40 <span class="tooltip" title="${h.tooltip(_('In case a repository was deleted from filesystem and there are leftovers in the database check this option to scan obsolete data in database and remove it.'))}">
41 41 ${_('Destroy old data')}</span> </label>
42 42 </div>
43 <div class="checkbox">
44 ${h.checkbox('invalidate',True)}
45 <label for="invalidate">
46 <span class="tooltip" title="${h.tooltip(_('Invalidate cache for all repositories during scan'))}">
47 ${_('Invalidate cache for all repositories')}</span> </label>
48 </div>
43 49 <span class="help-block">${_('Rescan repositories location for new repositories. Also deletes obsolete if `destroy` flag is checked ')}</span>
44 50 </div>
45 51 </div>
46 52
47 53 <div class="buttons">
48 54 ${h.submit('rescan',_('Rescan repositories'),class_="ui-btn large")}
49 55 </div>
50 56 </div>
51 57 </div>
52 58 ${h.end_form()}
53 59
54 60 <h3>${_('Whoosh indexing')}</h3>
55 61 ${h.form(url('admin_setting', setting_id='whoosh'),method='put')}
56 62 <div class="form">
57 63 <!-- fields -->
58 64
59 65 <div class="fields">
60 66 <div class="field">
61 67 <div class="label label-checkbox">
62 68 <label>${_('Index build option')}:</label>
63 69 </div>
64 70 <div class="checkboxes">
65 71 <div class="checkbox">
66 72 ${h.checkbox('full_index',True)}
67 73 <label for="full_index">${_('Build from scratch')}</label>
68 74 </div>
69 75 </div>
70 76 </div>
71 77
72 78 <div class="buttons">
73 79 ${h.submit('reindex',_('Reindex'),class_="ui-btn large")}
74 80 </div>
75 81 </div>
76 82 </div>
77 83 ${h.end_form()}
78 84
79 85 <h3>${_('Global application settings')}</h3>
80 86 ${h.form(url('admin_setting', setting_id='global'),method='put')}
81 87 <div class="form">
82 88 <!-- fields -->
83 89
84 90 <div class="fields">
85 91
86 92 <div class="field">
87 93 <div class="label">
88 94 <label for="rhodecode_title">${_('Site branding')}:</label>
89 95 </div>
90 96 <div class="input">
91 97 ${h.text('rhodecode_title',size=30)}
92 98 </div>
93 99 </div>
94 100
95 101 <div class="field">
96 102 <div class="label">
97 103 <label for="rhodecode_realm">${_('HTTP authentication realm')}:</label>
98 104 </div>
99 105 <div class="input">
100 106 ${h.text('rhodecode_realm',size=30)}
101 107 </div>
102 108 </div>
103 109
104 110 <div class="field">
105 111 <div class="label">
106 112 <label for="rhodecode_ga_code">${_('Google Analytics code')}:</label>
107 113 </div>
108 114 <div class="input">
109 115 ${h.text('rhodecode_ga_code',size=30)}
110 116 </div>
111 117 </div>
112 118
113 119 <div class="buttons">
114 120 ${h.submit('save',_('Save settings'),class_="ui-btn large")}
115 121 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
116 122 </div>
117 123 </div>
118 124 </div>
119 125 ${h.end_form()}
120 126
121 127 <h3>${_('Visualisation settings')}</h3>
122 128 ${h.form(url('admin_setting', setting_id='visual'),method='put')}
123 129 <div class="form">
124 130 <!-- fields -->
125 131
126 132 <div class="fields">
127 133 <div class="field">
128 134 <div class="label label-checkbox">
129 135 <label>${_('General')}:</label>
130 136 </div>
131 137 <div class="checkboxes">
132 138 <div class="checkbox">
133 139 ${h.checkbox('rhodecode_repository_fields','True')}
134 140 <label for="rhodecode_repository_fields">${_('Use repository extra fields')}</label>
135 141 </div>
136 142 <span class="help-block">${_('Allows storing additional customized fields per repository.')}</span>
137 143 <div class="checkbox">
138 144 ${h.checkbox('rhodecode_show_version','True')}
139 145 <label for="rhodecode_show_version">${_('Show RhodeCode version')}</label>
140 146 </div>
141 147 <span class="help-block">${_('Shows or hides displayed version of RhodeCode in the footer')}</span>
142 148 </div>
143 149 </div>
144 150 <div class="field">
145 151 <div class="label">
146 152 <label for="rhodecode_realm">${_('Dashboard items')}:</label>
147 153 </div>
148 154 <div class="input">
149 155 ${h.text('rhodecode_dashboard_items',size=5)}
150 156 <span class="help-block">${_('Number of items displayed in lightweight dashboard before pagination is shown.')}</span>
151 157 </div>
152 158 </div>
153 159 <div class="field">
154 160 <div class="label label-checkbox">
155 161 <label>${_('Icons')}:</label>
156 162 </div>
157 163 <div class="checkboxes">
158 164 <div class="checkbox">
159 165 ${h.checkbox('rhodecode_show_public_icon','True')}
160 166 <label for="rhodecode_show_public_icon">${_('Show public repo icon on repositories')}</label>
161 167 </div>
162 168 <div class="checkbox">
163 169 ${h.checkbox('rhodecode_show_private_icon','True')}
164 170 <label for="rhodecode_show_private_icon">${_('Show private repo icon on repositories')}</label>
165 171 </div>
166 172 <span class="help-block">${_('Show public/private icons next to repositories names')}</span>
167 173 </div>
168 174 </div>
169 175
170 176 <div class="field">
171 177 <div class="label label-checkbox">
172 178 <label>${_('Meta-Tagging')}:</label>
173 179 </div>
174 180 <div class="checkboxes">
175 181 <div class="checkbox">
176 182 ${h.checkbox('rhodecode_stylify_metatags','True')}
177 183 <label for="rhodecode_stylify_metatags">${_('Stylify recognised metatags:')}</label>
178 184 </div>
179 185 <div style="padding-left: 20px;">
180 186 <ul> <!-- Fix style here -->
181 187 <li>[featured] <span class="metatag" tag="featured">featured</span></li>
182 188 <li>[stale] <span class="metatag" tag="stale">stale</span></li>
183 189 <li>[dead] <span class="metatag" tag="dead">dead</span></li>
184 190 <li>[lang =&gt; lang] <span class="metatag" tag="lang" >lang</span></li>
185 191 <li>[license =&gt; License] <span class="metatag" tag="license"><a href="http://www.opensource.org/licenses/License" >License</a></span></li>
186 192 <li>[requires =&gt; Repo] <span class="metatag" tag="requires" >requires =&gt; <a href="#" >Repo</a></span></li>
187 193 <li>[recommends =&gt; Repo] <span class="metatag" tag="recommends" >recommends =&gt; <a href="#" >Repo</a></span></li>
188 194 <li>[see =&gt; URI] <span class="metatag" tag="see">see =&gt; <a href="#">URI</a> </span></li>
189 195 </ul>
190 196 </div>
191 197 </div>
192 198 </div>
193 199
194 200 <div class="buttons">
195 201 ${h.submit('save',_('Save settings'),class_="ui-btn large")}
196 202 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
197 203 </div>
198 204
199 205 </div>
200 206 </div>
201 207 ${h.end_form()}
202 208
203 209
204 210 <h3>${_('VCS settings')}</h3>
205 211 ${h.form(url('admin_setting', setting_id='vcs'),method='put')}
206 212 <div class="form">
207 213 <!-- fields -->
208 214
209 215 <div class="fields">
210 216
211 217 <div class="field">
212 218 <div class="label label-checkbox">
213 219 <label>${_('Web')}:</label>
214 220 </div>
215 221 <div class="checkboxes">
216 222 <div class="checkbox">
217 223 ${h.checkbox('web_push_ssl', 'True')}
218 224 <label for="web_push_ssl">${_('Require SSL for vcs operations')}</label>
219 225 </div>
220 226 <span class="help-block">${_('RhodeCode will require SSL for pushing or pulling. If SSL is missing it will return HTTP Error 406: Not Acceptable')}</span>
221 227 </div>
222 228 </div>
223 229
224 230 <div class="field">
225 231 <div class="label label-checkbox">
226 232 <label>${_('Hooks')}:</label>
227 233 </div>
228 234 <div class="checkboxes">
229 235 <div class="checkbox">
230 236 ${h.checkbox('hooks_changegroup_update','True')}
231 237 <label for="hooks_changegroup_update">${_('Update repository after push (hg update)')}</label>
232 238 </div>
233 239 <div class="checkbox">
234 240 ${h.checkbox('hooks_changegroup_repo_size','True')}
235 241 <label for="hooks_changegroup_repo_size">${_('Show repository size after push')}</label>
236 242 </div>
237 243 <div class="checkbox">
238 244 ${h.checkbox('hooks_changegroup_push_logger','True')}
239 245 <label for="hooks_changegroup_push_logger">${_('Log user push commands')}</label>
240 246 </div>
241 247 <div class="checkbox">
242 248 ${h.checkbox('hooks_outgoing_pull_logger','True')}
243 249 <label for="hooks_outgoing_pull_logger">${_('Log user pull commands')}</label>
244 250 </div>
245 251 </div>
246 252 <div class="input" style="margin-top:10px">
247 253 ${h.link_to(_('Advanced setup'),url('admin_edit_setting',setting_id='hooks'))}
248 254 </div>
249 255 </div>
250 256 <div class="field">
251 257 <div class="label label-checkbox">
252 258 <label>${_('Mercurial Extensions')}:</label>
253 259 </div>
254 260 <div class="checkboxes">
255 261 <div class="checkbox">
256 262 ${h.checkbox('extensions_largefiles','True')}
257 263 <label for="extensions_largefiles">${_('Enable largefiles extension')}</label>
258 264 </div>
259 265 <div class="checkbox">
260 266 ${h.checkbox('extensions_hgsubversion','True')}
261 267 <label for="extensions_hgsubversion">${_('Enable hgsubversion extension')}</label>
262 268 </div>
263 269 <span class="help-block">${_('Requires hgsubversion library installed. Allows cloning from svn remote locations')}</span>
264 270 ##<div class="checkbox">
265 271 ## ${h.checkbox('extensions_hggit','True')}
266 272 ## <label for="extensions_hggit">${_('Enable hg-git extension')}</label>
267 273 ##</div>
268 274 ##<span class="help-block">${_('Requires hg-git library installed. Allows cloning from git remote locations')}</span>
269 275 </div>
270 276 </div>
271 277 %if c.visual.allow_repo_location_change:
272 278 <div class="field">
273 279 <div class="label">
274 280 <label for="paths_root_path">${_('Repositories location')}:</label>
275 281 </div>
276 282 <div class="input">
277 283 ${h.text('paths_root_path',size=30,readonly="readonly", class_="disabled")}
278 284 <span id="path_unlock" class="tooltip" style="cursor: pointer"
279 285 title="${h.tooltip(_('Click to unlock. You must restart RhodeCode in order to make this setting take effect.'))}">
280 286 ${_('Unlock')}
281 287 </span>
282 288 <span class="help-block">${_('Location where repositories are stored. After changing this value a restart, and rescan is required')}</span>
283 289 </div>
284 290 </div>
285 291 %endif
286 292 <div class="buttons">
287 293 ${h.submit('save',_('Save settings'),class_="ui-btn large")}
288 294 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
289 295 </div>
290 296 </div>
291 297 </div>
292 298 ${h.end_form()}
293 299
294 300 <script type="text/javascript">
295 301 YAHOO.util.Event.onDOMReady(function(){
296 302 YUE.on('path_unlock','click',function(){
297 303 YUD.get('paths_root_path').removeAttribute('readonly');
298 304 YUD.removeClass('paths_root_path', 'disabled')
299 305 });
300 306 });
301 307 </script>
302 308
303 309 <h3>${_('Test Email')}</h3>
304 310 ${h.form(url('admin_setting', setting_id='email'),method='put')}
305 311 <div class="form">
306 312 <!-- fields -->
307 313
308 314 <div class="fields">
309 315 <div class="field">
310 316 <div class="label">
311 317 <label for="test_email">${_('Email to')}:</label>
312 318 </div>
313 319 <div class="input">
314 320 ${h.text('test_email',size=30)}
315 321 </div>
316 322 </div>
317 323
318 324 <div class="buttons">
319 325 ${h.submit('send',_('Send'),class_="ui-btn large")}
320 326 </div>
321 327 </div>
322 328 </div>
323 329 ${h.end_form()}
324 330
325 331 <h3>${_('System Info and Packages')}</h3>
326 332 <div class="form">
327 333 <div>
328 334 <h5 id="expand_modules" style="cursor: pointer">&darr; ${_('Show')} &darr;</h5>
329 335 </div>
330 336 <div id="expand_modules_table" style="display:none">
331 337 <h5>Python - ${c.py_version}</h5>
332 338 <h5>System - ${c.platform}</h5>
333 339
334 340 <table class="table" style="margin:0px 0px 0px 20px">
335 341 <colgroup>
336 342 <col style="width:220px">
337 343 </colgroup>
338 344 <tbody>
339 345 %for key, value in c.modules:
340 346 <tr>
341 347 <th style="text-align: right;padding-right:5px;">${key}</th>
342 348 <td>${value}</td>
343 349 </tr>
344 350 %endfor
345 351 </tbody>
346 352 </table>
347 353 </div>
348 354 </div>
349 355
350 356 <script type="text/javascript">
351 357 YUE.on('expand_modules','click',function(e){
352 358 YUD.setStyle('expand_modules_table','display','');
353 359 YUD.setStyle('expand_modules','display','none');
354 360 })
355 361 </script>
356 362
357 363 </div>
358 364 </%def>
General Comments 0
You need to be logged in to leave comments. Login now