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