##// END OF EJS Templates
added useful system info + packages to settings page.
marcink -
r2192:a801c454 beta
parent child Browse files
Show More
@@ -1,414 +1,421 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
30 import platform
29
31
30 from sqlalchemy import func
32 from sqlalchemy import func
31 from formencode import htmlfill
33 from formencode import htmlfill
32 from pylons import request, session, tmpl_context as c, url, config
34 from pylons import request, session, tmpl_context as c, url, config
33 from pylons.controllers.util import abort, redirect
35 from pylons.controllers.util import abort, redirect
34 from pylons.i18n.translation import _
36 from pylons.i18n.translation import _
35
37
36 from rhodecode.lib import helpers as h
38 from rhodecode.lib import helpers as h
37 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
38 HasPermissionAnyDecorator, NotAnonymous
40 HasPermissionAnyDecorator, NotAnonymous
39 from rhodecode.lib.base import BaseController, render
41 from rhodecode.lib.base import BaseController, render
40 from rhodecode.lib.celerylib import tasks, run_task
42 from rhodecode.lib.celerylib import tasks, run_task
41 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
43 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
42 set_rhodecode_config, repo_name_slug
44 set_rhodecode_config, repo_name_slug
43 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
45 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
44 RhodeCodeSetting
46 RhodeCodeSetting
45 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
47 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
46 ApplicationUiSettingsForm
48 ApplicationUiSettingsForm
47 from rhodecode.model.scm import ScmModel
49 from rhodecode.model.scm import ScmModel
48 from rhodecode.model.user import UserModel
50 from rhodecode.model.user import UserModel
49 from rhodecode.model.db import User
51 from rhodecode.model.db import User
50 from rhodecode.model.notification import EmailNotificationModel
52 from rhodecode.model.notification import EmailNotificationModel
51 from rhodecode.model.meta import Session
53 from rhodecode.model.meta import Session
52
54
53 log = logging.getLogger(__name__)
55 log = logging.getLogger(__name__)
54
56
55
57
56 class SettingsController(BaseController):
58 class SettingsController(BaseController):
57 """REST Controller styled on the Atom Publishing Protocol"""
59 """REST Controller styled on the Atom Publishing Protocol"""
58 # To properly map this controller, ensure your config/routing.py
60 # To properly map this controller, ensure your config/routing.py
59 # file has a resource setup:
61 # file has a resource setup:
60 # map.resource('setting', 'settings', controller='admin/settings',
62 # map.resource('setting', 'settings', controller='admin/settings',
61 # path_prefix='/admin', name_prefix='admin_')
63 # path_prefix='/admin', name_prefix='admin_')
62
64
63 @LoginRequired()
65 @LoginRequired()
64 def __before__(self):
66 def __before__(self):
65 c.admin_user = session.get('admin_user')
67 c.admin_user = session.get('admin_user')
66 c.admin_username = session.get('admin_username')
68 c.admin_username = session.get('admin_username')
69 c.modules = sorted([(p.project_name, p.version)
70 for p in pkg_resources.working_set])
71 c.py_version = platform.python_version()
72 c.platform = platform.platform()
67 super(SettingsController, self).__before__()
73 super(SettingsController, self).__before__()
68
74
69 @HasPermissionAllDecorator('hg.admin')
75 @HasPermissionAllDecorator('hg.admin')
70 def index(self, format='html'):
76 def index(self, format='html'):
71 """GET /admin/settings: All items in the collection"""
77 """GET /admin/settings: All items in the collection"""
72 # url('admin_settings')
78 # url('admin_settings')
73
79
74 defaults = RhodeCodeSetting.get_app_settings()
80 defaults = RhodeCodeSetting.get_app_settings()
75 defaults.update(self.get_hg_ui_settings())
81 defaults.update(self.get_hg_ui_settings())
82
76 return htmlfill.render(
83 return htmlfill.render(
77 render('admin/settings/settings.html'),
84 render('admin/settings/settings.html'),
78 defaults=defaults,
85 defaults=defaults,
79 encoding="UTF-8",
86 encoding="UTF-8",
80 force_defaults=False
87 force_defaults=False
81 )
88 )
82
89
83 @HasPermissionAllDecorator('hg.admin')
90 @HasPermissionAllDecorator('hg.admin')
84 def create(self):
91 def create(self):
85 """POST /admin/settings: Create a new item"""
92 """POST /admin/settings: Create a new item"""
86 # url('admin_settings')
93 # url('admin_settings')
87
94
88 @HasPermissionAllDecorator('hg.admin')
95 @HasPermissionAllDecorator('hg.admin')
89 def new(self, format='html'):
96 def new(self, format='html'):
90 """GET /admin/settings/new: Form to create a new item"""
97 """GET /admin/settings/new: Form to create a new item"""
91 # url('admin_new_setting')
98 # url('admin_new_setting')
92
99
93 @HasPermissionAllDecorator('hg.admin')
100 @HasPermissionAllDecorator('hg.admin')
94 def update(self, setting_id):
101 def update(self, setting_id):
95 """PUT /admin/settings/setting_id: Update an existing item"""
102 """PUT /admin/settings/setting_id: Update an existing item"""
96 # Forms posted to this method should contain a hidden field:
103 # Forms posted to this method should contain a hidden field:
97 # <input type="hidden" name="_method" value="PUT" />
104 # <input type="hidden" name="_method" value="PUT" />
98 # Or using helpers:
105 # Or using helpers:
99 # h.form(url('admin_setting', setting_id=ID),
106 # h.form(url('admin_setting', setting_id=ID),
100 # method='put')
107 # method='put')
101 # url('admin_setting', setting_id=ID)
108 # url('admin_setting', setting_id=ID)
102 if setting_id == 'mapping':
109 if setting_id == 'mapping':
103 rm_obsolete = request.POST.get('destroy', False)
110 rm_obsolete = request.POST.get('destroy', False)
104 log.debug('Rescanning directories with destroy=%s' % rm_obsolete)
111 log.debug('Rescanning directories with destroy=%s' % rm_obsolete)
105 initial = ScmModel().repo_scan()
112 initial = ScmModel().repo_scan()
106 log.debug('invalidating all repositories')
113 log.debug('invalidating all repositories')
107 for repo_name in initial.keys():
114 for repo_name in initial.keys():
108 invalidate_cache('get_repo_cached_%s' % repo_name)
115 invalidate_cache('get_repo_cached_%s' % repo_name)
109
116
110 added, removed = repo2db_mapper(initial, rm_obsolete)
117 added, removed = repo2db_mapper(initial, rm_obsolete)
111
118
112 h.flash(_('Repositories successfully'
119 h.flash(_('Repositories successfully'
113 ' rescanned added: %s,removed: %s') % (added, removed),
120 ' rescanned added: %s,removed: %s') % (added, removed),
114 category='success')
121 category='success')
115
122
116 if setting_id == 'whoosh':
123 if setting_id == 'whoosh':
117 repo_location = self.get_hg_ui_settings()['paths_root_path']
124 repo_location = self.get_hg_ui_settings()['paths_root_path']
118 full_index = request.POST.get('full_index', False)
125 full_index = request.POST.get('full_index', False)
119 run_task(tasks.whoosh_index, repo_location, full_index)
126 run_task(tasks.whoosh_index, repo_location, full_index)
120
127
121 h.flash(_('Whoosh reindex task scheduled'), category='success')
128 h.flash(_('Whoosh reindex task scheduled'), category='success')
122 if setting_id == 'global':
129 if setting_id == 'global':
123
130
124 application_form = ApplicationSettingsForm()()
131 application_form = ApplicationSettingsForm()()
125 try:
132 try:
126 form_result = application_form.to_python(dict(request.POST))
133 form_result = application_form.to_python(dict(request.POST))
127
134
128 try:
135 try:
129 hgsettings1 = RhodeCodeSetting.get_by_name('title')
136 hgsettings1 = RhodeCodeSetting.get_by_name('title')
130 hgsettings1.app_settings_value = \
137 hgsettings1.app_settings_value = \
131 form_result['rhodecode_title']
138 form_result['rhodecode_title']
132
139
133 hgsettings2 = RhodeCodeSetting.get_by_name('realm')
140 hgsettings2 = RhodeCodeSetting.get_by_name('realm')
134 hgsettings2.app_settings_value = \
141 hgsettings2.app_settings_value = \
135 form_result['rhodecode_realm']
142 form_result['rhodecode_realm']
136
143
137 hgsettings3 = RhodeCodeSetting.get_by_name('ga_code')
144 hgsettings3 = RhodeCodeSetting.get_by_name('ga_code')
138 hgsettings3.app_settings_value = \
145 hgsettings3.app_settings_value = \
139 form_result['rhodecode_ga_code']
146 form_result['rhodecode_ga_code']
140
147
141 self.sa.add(hgsettings1)
148 self.sa.add(hgsettings1)
142 self.sa.add(hgsettings2)
149 self.sa.add(hgsettings2)
143 self.sa.add(hgsettings3)
150 self.sa.add(hgsettings3)
144 self.sa.commit()
151 self.sa.commit()
145 set_rhodecode_config(config)
152 set_rhodecode_config(config)
146 h.flash(_('Updated application settings'),
153 h.flash(_('Updated application settings'),
147 category='success')
154 category='success')
148
155
149 except Exception:
156 except Exception:
150 log.error(traceback.format_exc())
157 log.error(traceback.format_exc())
151 h.flash(_('error occurred during updating '
158 h.flash(_('error occurred during updating '
152 'application settings'),
159 'application settings'),
153 category='error')
160 category='error')
154
161
155 self.sa.rollback()
162 self.sa.rollback()
156
163
157 except formencode.Invalid, errors:
164 except formencode.Invalid, errors:
158 return htmlfill.render(
165 return htmlfill.render(
159 render('admin/settings/settings.html'),
166 render('admin/settings/settings.html'),
160 defaults=errors.value,
167 defaults=errors.value,
161 errors=errors.error_dict or {},
168 errors=errors.error_dict or {},
162 prefix_error=False,
169 prefix_error=False,
163 encoding="UTF-8")
170 encoding="UTF-8")
164
171
165 if setting_id == 'mercurial':
172 if setting_id == 'mercurial':
166 application_form = ApplicationUiSettingsForm()()
173 application_form = ApplicationUiSettingsForm()()
167 try:
174 try:
168 form_result = application_form.to_python(dict(request.POST))
175 form_result = application_form.to_python(dict(request.POST))
169
176
170 try:
177 try:
171
178
172 hgsettings1 = self.sa.query(RhodeCodeUi)\
179 hgsettings1 = self.sa.query(RhodeCodeUi)\
173 .filter(RhodeCodeUi.ui_key == 'push_ssl').one()
180 .filter(RhodeCodeUi.ui_key == 'push_ssl').one()
174 hgsettings1.ui_value = form_result['web_push_ssl']
181 hgsettings1.ui_value = form_result['web_push_ssl']
175
182
176 hgsettings2 = self.sa.query(RhodeCodeUi)\
183 hgsettings2 = self.sa.query(RhodeCodeUi)\
177 .filter(RhodeCodeUi.ui_key == '/').one()
184 .filter(RhodeCodeUi.ui_key == '/').one()
178 hgsettings2.ui_value = form_result['paths_root_path']
185 hgsettings2.ui_value = form_result['paths_root_path']
179
186
180 #HOOKS
187 #HOOKS
181 hgsettings3 = self.sa.query(RhodeCodeUi)\
188 hgsettings3 = self.sa.query(RhodeCodeUi)\
182 .filter(RhodeCodeUi.ui_key == 'changegroup.update').one()
189 .filter(RhodeCodeUi.ui_key == 'changegroup.update').one()
183 hgsettings3.ui_active = \
190 hgsettings3.ui_active = \
184 bool(form_result['hooks_changegroup_update'])
191 bool(form_result['hooks_changegroup_update'])
185
192
186 hgsettings4 = self.sa.query(RhodeCodeUi)\
193 hgsettings4 = self.sa.query(RhodeCodeUi)\
187 .filter(RhodeCodeUi.ui_key ==
194 .filter(RhodeCodeUi.ui_key ==
188 'changegroup.repo_size').one()
195 'changegroup.repo_size').one()
189 hgsettings4.ui_active = \
196 hgsettings4.ui_active = \
190 bool(form_result['hooks_changegroup_repo_size'])
197 bool(form_result['hooks_changegroup_repo_size'])
191
198
192 hgsettings5 = self.sa.query(RhodeCodeUi)\
199 hgsettings5 = self.sa.query(RhodeCodeUi)\
193 .filter(RhodeCodeUi.ui_key ==
200 .filter(RhodeCodeUi.ui_key ==
194 'pretxnchangegroup.push_logger').one()
201 'pretxnchangegroup.push_logger').one()
195 hgsettings5.ui_active = \
202 hgsettings5.ui_active = \
196 bool(form_result['hooks_pretxnchangegroup'
203 bool(form_result['hooks_pretxnchangegroup'
197 '_push_logger'])
204 '_push_logger'])
198
205
199 hgsettings6 = self.sa.query(RhodeCodeUi)\
206 hgsettings6 = self.sa.query(RhodeCodeUi)\
200 .filter(RhodeCodeUi.ui_key ==
207 .filter(RhodeCodeUi.ui_key ==
201 'preoutgoing.pull_logger').one()
208 'preoutgoing.pull_logger').one()
202 hgsettings6.ui_active = \
209 hgsettings6.ui_active = \
203 bool(form_result['hooks_preoutgoing_pull_logger'])
210 bool(form_result['hooks_preoutgoing_pull_logger'])
204
211
205 self.sa.add(hgsettings1)
212 self.sa.add(hgsettings1)
206 self.sa.add(hgsettings2)
213 self.sa.add(hgsettings2)
207 self.sa.add(hgsettings3)
214 self.sa.add(hgsettings3)
208 self.sa.add(hgsettings4)
215 self.sa.add(hgsettings4)
209 self.sa.add(hgsettings5)
216 self.sa.add(hgsettings5)
210 self.sa.add(hgsettings6)
217 self.sa.add(hgsettings6)
211 self.sa.commit()
218 self.sa.commit()
212
219
213 h.flash(_('Updated mercurial settings'),
220 h.flash(_('Updated mercurial settings'),
214 category='success')
221 category='success')
215
222
216 except:
223 except:
217 log.error(traceback.format_exc())
224 log.error(traceback.format_exc())
218 h.flash(_('error occurred during updating '
225 h.flash(_('error occurred during updating '
219 'application settings'), category='error')
226 'application settings'), category='error')
220
227
221 self.sa.rollback()
228 self.sa.rollback()
222
229
223 except formencode.Invalid, errors:
230 except formencode.Invalid, errors:
224 return htmlfill.render(
231 return htmlfill.render(
225 render('admin/settings/settings.html'),
232 render('admin/settings/settings.html'),
226 defaults=errors.value,
233 defaults=errors.value,
227 errors=errors.error_dict or {},
234 errors=errors.error_dict or {},
228 prefix_error=False,
235 prefix_error=False,
229 encoding="UTF-8")
236 encoding="UTF-8")
230
237
231 if setting_id == 'hooks':
238 if setting_id == 'hooks':
232 ui_key = request.POST.get('new_hook_ui_key')
239 ui_key = request.POST.get('new_hook_ui_key')
233 ui_value = request.POST.get('new_hook_ui_value')
240 ui_value = request.POST.get('new_hook_ui_value')
234 try:
241 try:
235
242
236 if ui_value and ui_key:
243 if ui_value and ui_key:
237 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
244 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
238 h.flash(_('Added new hook'),
245 h.flash(_('Added new hook'),
239 category='success')
246 category='success')
240
247
241 # check for edits
248 # check for edits
242 update = False
249 update = False
243 _d = request.POST.dict_of_lists()
250 _d = request.POST.dict_of_lists()
244 for k, v in zip(_d.get('hook_ui_key', []),
251 for k, v in zip(_d.get('hook_ui_key', []),
245 _d.get('hook_ui_value_new', [])):
252 _d.get('hook_ui_value_new', [])):
246 RhodeCodeUi.create_or_update_hook(k, v)
253 RhodeCodeUi.create_or_update_hook(k, v)
247 update = True
254 update = True
248
255
249 if update:
256 if update:
250 h.flash(_('Updated hooks'), category='success')
257 h.flash(_('Updated hooks'), category='success')
251 self.sa.commit()
258 self.sa.commit()
252 except:
259 except:
253 log.error(traceback.format_exc())
260 log.error(traceback.format_exc())
254 h.flash(_('error occurred during hook creation'),
261 h.flash(_('error occurred during hook creation'),
255 category='error')
262 category='error')
256
263
257 return redirect(url('admin_edit_setting', setting_id='hooks'))
264 return redirect(url('admin_edit_setting', setting_id='hooks'))
258
265
259 if setting_id == 'email':
266 if setting_id == 'email':
260 test_email = request.POST.get('test_email')
267 test_email = request.POST.get('test_email')
261 test_email_subj = 'RhodeCode TestEmail'
268 test_email_subj = 'RhodeCode TestEmail'
262 test_email_body = 'RhodeCode Email test'
269 test_email_body = 'RhodeCode Email test'
263
270
264 test_email_html_body = EmailNotificationModel()\
271 test_email_html_body = EmailNotificationModel()\
265 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
272 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
266 body=test_email_body)
273 body=test_email_body)
267
274
268 recipients = [test_email] if [test_email] else None
275 recipients = [test_email] if [test_email] else None
269
276
270 run_task(tasks.send_email, recipients, test_email_subj,
277 run_task(tasks.send_email, recipients, test_email_subj,
271 test_email_body, test_email_html_body)
278 test_email_body, test_email_html_body)
272
279
273 h.flash(_('Email task created'), category='success')
280 h.flash(_('Email task created'), category='success')
274 return redirect(url('admin_settings'))
281 return redirect(url('admin_settings'))
275
282
276 @HasPermissionAllDecorator('hg.admin')
283 @HasPermissionAllDecorator('hg.admin')
277 def delete(self, setting_id):
284 def delete(self, setting_id):
278 """DELETE /admin/settings/setting_id: Delete an existing item"""
285 """DELETE /admin/settings/setting_id: Delete an existing item"""
279 # Forms posted to this method should contain a hidden field:
286 # Forms posted to this method should contain a hidden field:
280 # <input type="hidden" name="_method" value="DELETE" />
287 # <input type="hidden" name="_method" value="DELETE" />
281 # Or using helpers:
288 # Or using helpers:
282 # h.form(url('admin_setting', setting_id=ID),
289 # h.form(url('admin_setting', setting_id=ID),
283 # method='delete')
290 # method='delete')
284 # url('admin_setting', setting_id=ID)
291 # url('admin_setting', setting_id=ID)
285 if setting_id == 'hooks':
292 if setting_id == 'hooks':
286 hook_id = request.POST.get('hook_id')
293 hook_id = request.POST.get('hook_id')
287 RhodeCodeUi.delete(hook_id)
294 RhodeCodeUi.delete(hook_id)
288 self.sa.commit()
295 self.sa.commit()
289
296
290 @HasPermissionAllDecorator('hg.admin')
297 @HasPermissionAllDecorator('hg.admin')
291 def show(self, setting_id, format='html'):
298 def show(self, setting_id, format='html'):
292 """
299 """
293 GET /admin/settings/setting_id: Show a specific item"""
300 GET /admin/settings/setting_id: Show a specific item"""
294 # url('admin_setting', setting_id=ID)
301 # url('admin_setting', setting_id=ID)
295
302
296 @HasPermissionAllDecorator('hg.admin')
303 @HasPermissionAllDecorator('hg.admin')
297 def edit(self, setting_id, format='html'):
304 def edit(self, setting_id, format='html'):
298 """
305 """
299 GET /admin/settings/setting_id/edit: Form to
306 GET /admin/settings/setting_id/edit: Form to
300 edit an existing item"""
307 edit an existing item"""
301 # url('admin_edit_setting', setting_id=ID)
308 # url('admin_edit_setting', setting_id=ID)
302
309
303 c.hooks = RhodeCodeUi.get_builtin_hooks()
310 c.hooks = RhodeCodeUi.get_builtin_hooks()
304 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
311 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
305
312
306 return htmlfill.render(
313 return htmlfill.render(
307 render('admin/settings/hooks.html'),
314 render('admin/settings/hooks.html'),
308 defaults={},
315 defaults={},
309 encoding="UTF-8",
316 encoding="UTF-8",
310 force_defaults=False
317 force_defaults=False
311 )
318 )
312
319
313 @NotAnonymous()
320 @NotAnonymous()
314 def my_account(self):
321 def my_account(self):
315 """
322 """
316 GET /_admin/my_account Displays info about my account
323 GET /_admin/my_account Displays info about my account
317 """
324 """
318 # url('admin_settings_my_account')
325 # url('admin_settings_my_account')
319
326
320 c.user = User.get(self.rhodecode_user.user_id)
327 c.user = User.get(self.rhodecode_user.user_id)
321 all_repos = self.sa.query(Repository)\
328 all_repos = self.sa.query(Repository)\
322 .filter(Repository.user_id == c.user.user_id)\
329 .filter(Repository.user_id == c.user.user_id)\
323 .order_by(func.lower(Repository.repo_name)).all()
330 .order_by(func.lower(Repository.repo_name)).all()
324
331
325 c.user_repos = ScmModel().get_repos(all_repos)
332 c.user_repos = ScmModel().get_repos(all_repos)
326
333
327 if c.user.username == 'default':
334 if c.user.username == 'default':
328 h.flash(_("You can't edit this user since it's"
335 h.flash(_("You can't edit this user since it's"
329 " crucial for entire application"), category='warning')
336 " crucial for entire application"), category='warning')
330 return redirect(url('users'))
337 return redirect(url('users'))
331
338
332 defaults = c.user.get_dict()
339 defaults = c.user.get_dict()
333 return htmlfill.render(
340 return htmlfill.render(
334 render('admin/users/user_edit_my_account.html'),
341 render('admin/users/user_edit_my_account.html'),
335 defaults=defaults,
342 defaults=defaults,
336 encoding="UTF-8",
343 encoding="UTF-8",
337 force_defaults=False
344 force_defaults=False
338 )
345 )
339
346
340 def my_account_update(self):
347 def my_account_update(self):
341 """PUT /_admin/my_account_update: Update an existing item"""
348 """PUT /_admin/my_account_update: Update an existing item"""
342 # Forms posted to this method should contain a hidden field:
349 # Forms posted to this method should contain a hidden field:
343 # <input type="hidden" name="_method" value="PUT" />
350 # <input type="hidden" name="_method" value="PUT" />
344 # Or using helpers:
351 # Or using helpers:
345 # h.form(url('admin_settings_my_account_update'),
352 # h.form(url('admin_settings_my_account_update'),
346 # method='put')
353 # method='put')
347 # url('admin_settings_my_account_update', id=ID)
354 # url('admin_settings_my_account_update', id=ID)
348 user_model = UserModel()
355 user_model = UserModel()
349 uid = self.rhodecode_user.user_id
356 uid = self.rhodecode_user.user_id
350 _form = UserForm(edit=True,
357 _form = UserForm(edit=True,
351 old_data={'user_id': uid,
358 old_data={'user_id': uid,
352 'email': self.rhodecode_user.email})()
359 'email': self.rhodecode_user.email})()
353 form_result = {}
360 form_result = {}
354 try:
361 try:
355 form_result = _form.to_python(dict(request.POST))
362 form_result = _form.to_python(dict(request.POST))
356 user_model.update_my_account(uid, form_result)
363 user_model.update_my_account(uid, form_result)
357 h.flash(_('Your account was updated successfully'),
364 h.flash(_('Your account was updated successfully'),
358 category='success')
365 category='success')
359 Session.commit()
366 Session.commit()
360 except formencode.Invalid, errors:
367 except formencode.Invalid, errors:
361 c.user = User.get(self.rhodecode_user.user_id)
368 c.user = User.get(self.rhodecode_user.user_id)
362 all_repos = self.sa.query(Repository)\
369 all_repos = self.sa.query(Repository)\
363 .filter(Repository.user_id == c.user.user_id)\
370 .filter(Repository.user_id == c.user.user_id)\
364 .order_by(func.lower(Repository.repo_name))\
371 .order_by(func.lower(Repository.repo_name))\
365 .all()
372 .all()
366 c.user_repos = ScmModel().get_repos(all_repos)
373 c.user_repos = ScmModel().get_repos(all_repos)
367
374
368 return htmlfill.render(
375 return htmlfill.render(
369 render('admin/users/user_edit_my_account.html'),
376 render('admin/users/user_edit_my_account.html'),
370 defaults=errors.value,
377 defaults=errors.value,
371 errors=errors.error_dict or {},
378 errors=errors.error_dict or {},
372 prefix_error=False,
379 prefix_error=False,
373 encoding="UTF-8")
380 encoding="UTF-8")
374 except Exception:
381 except Exception:
375 log.error(traceback.format_exc())
382 log.error(traceback.format_exc())
376 h.flash(_('error occurred during update of user %s') \
383 h.flash(_('error occurred during update of user %s') \
377 % form_result.get('username'), category='error')
384 % form_result.get('username'), category='error')
378
385
379 return redirect(url('my_account'))
386 return redirect(url('my_account'))
380
387
381 @NotAnonymous()
388 @NotAnonymous()
382 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
389 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
383 def create_repository(self):
390 def create_repository(self):
384 """GET /_admin/create_repository: Form to create a new item"""
391 """GET /_admin/create_repository: Form to create a new item"""
385
392
386 c.repo_groups = RepoGroup.groups_choices()
393 c.repo_groups = RepoGroup.groups_choices()
387 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
394 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
388
395
389 new_repo = request.GET.get('repo', '')
396 new_repo = request.GET.get('repo', '')
390 c.new_repo = repo_name_slug(new_repo)
397 c.new_repo = repo_name_slug(new_repo)
391
398
392 return render('admin/repos/repo_add_create_repository.html')
399 return render('admin/repos/repo_add_create_repository.html')
393
400
394 def get_hg_ui_settings(self):
401 def get_hg_ui_settings(self):
395 ret = self.sa.query(RhodeCodeUi).all()
402 ret = self.sa.query(RhodeCodeUi).all()
396
403
397 if not ret:
404 if not ret:
398 raise Exception('Could not get application ui settings !')
405 raise Exception('Could not get application ui settings !')
399 settings = {}
406 settings = {}
400 for each in ret:
407 for each in ret:
401 k = each.ui_key
408 k = each.ui_key
402 v = each.ui_value
409 v = each.ui_value
403 if k == '/':
410 if k == '/':
404 k = 'root_path'
411 k = 'root_path'
405
412
406 if k.find('.') != -1:
413 if k.find('.') != -1:
407 k = k.replace('.', '_')
414 k = k.replace('.', '_')
408
415
409 if each.ui_section == 'hooks':
416 if each.ui_section == 'hooks':
410 v = each.ui_active
417 v = each.ui_active
411
418
412 settings[each.ui_section + '_' + k] = v
419 settings[each.ui_section + '_' + k] = v
413
420
414 return settings
421 return settings
@@ -1,214 +1,246 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')} - ${c.rhodecode_name}
5 ${_('Settings administration')} - ${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'))} &raquo; ${_('Settings')}
9 ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Settings')}
10 </%def>
10 </%def>
11
11
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('admin')}
13 ${self.menu('admin')}
14 </%def>
14 </%def>
15
15
16 <%def name="main()">
16 <%def name="main()">
17 <div class="box">
17 <div class="box">
18 <!-- box / title -->
18 <!-- box / title -->
19 <div class="title">
19 <div class="title">
20 ${self.breadcrumbs()}
20 ${self.breadcrumbs()}
21 </div>
21 </div>
22 <!-- end box / title -->
22 <!-- end box / title -->
23
23
24 <h3>${_('Remap and rescan repositories')}</h3>
24 <h3>${_('Remap and rescan repositories')}</h3>
25 ${h.form(url('admin_setting', setting_id='mapping'),method='put')}
25 ${h.form(url('admin_setting', setting_id='mapping'),method='put')}
26 <div class="form">
26 <div class="form">
27 <!-- fields -->
27 <!-- fields -->
28
28
29 <div class="fields">
29 <div class="fields">
30 <div class="field">
30 <div class="field">
31 <div class="label label-checkbox">
31 <div class="label label-checkbox">
32 <label for="destroy">${_('rescan option')}:</label>
32 <label for="destroy">${_('rescan option')}:</label>
33 </div>
33 </div>
34 <div class="checkboxes">
34 <div class="checkboxes">
35 <div class="checkbox">
35 <div class="checkbox">
36 ${h.checkbox('destroy',True)}
36 ${h.checkbox('destroy',True)}
37 <label for="destroy">
37 <label for="destroy">
38 <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.'))}">
38 <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.'))}">
39 ${_('destroy old data')}</span> </label>
39 ${_('destroy old data')}</span> </label>
40 </div>
40 </div>
41 </div>
41 </div>
42 </div>
42 </div>
43
43
44 <div class="buttons">
44 <div class="buttons">
45 ${h.submit('rescan',_('Rescan repositories'),class_="ui-button")}
45 ${h.submit('rescan',_('Rescan repositories'),class_="ui-button")}
46 </div>
46 </div>
47 </div>
47 </div>
48 </div>
48 </div>
49 ${h.end_form()}
49 ${h.end_form()}
50
50
51 <h3>${_('Whoosh indexing')}</h3>
51 <h3>${_('Whoosh indexing')}</h3>
52 ${h.form(url('admin_setting', setting_id='whoosh'),method='put')}
52 ${h.form(url('admin_setting', setting_id='whoosh'),method='put')}
53 <div class="form">
53 <div class="form">
54 <!-- fields -->
54 <!-- fields -->
55
55
56 <div class="fields">
56 <div class="fields">
57 <div class="field">
57 <div class="field">
58 <div class="label label-checkbox">
58 <div class="label label-checkbox">
59 <label>${_('index build option')}:</label>
59 <label>${_('index build option')}:</label>
60 </div>
60 </div>
61 <div class="checkboxes">
61 <div class="checkboxes">
62 <div class="checkbox">
62 <div class="checkbox">
63 ${h.checkbox('full_index',True)}
63 ${h.checkbox('full_index',True)}
64 <label for="full_index">${_('build from scratch')}</label>
64 <label for="full_index">${_('build from scratch')}</label>
65 </div>
65 </div>
66 </div>
66 </div>
67 </div>
67 </div>
68
68
69 <div class="buttons">
69 <div class="buttons">
70 ${h.submit('reindex',_('Reindex'),class_="ui-button")}
70 ${h.submit('reindex',_('Reindex'),class_="ui-button")}
71 </div>
71 </div>
72 </div>
72 </div>
73 </div>
73 </div>
74 ${h.end_form()}
74 ${h.end_form()}
75
75
76 <h3>${_('Global application settings')}</h3>
76 <h3>${_('Global application settings')}</h3>
77 ${h.form(url('admin_setting', setting_id='global'),method='put')}
77 ${h.form(url('admin_setting', setting_id='global'),method='put')}
78 <div class="form">
78 <div class="form">
79 <!-- fields -->
79 <!-- fields -->
80
80
81 <div class="fields">
81 <div class="fields">
82
82
83 <div class="field">
83 <div class="field">
84 <div class="label">
84 <div class="label">
85 <label for="rhodecode_title">${_('Application name')}:</label>
85 <label for="rhodecode_title">${_('Application name')}:</label>
86 </div>
86 </div>
87 <div class="input">
87 <div class="input">
88 ${h.text('rhodecode_title',size=30)}
88 ${h.text('rhodecode_title',size=30)}
89 </div>
89 </div>
90 </div>
90 </div>
91
91
92 <div class="field">
92 <div class="field">
93 <div class="label">
93 <div class="label">
94 <label for="rhodecode_realm">${_('Realm text')}:</label>
94 <label for="rhodecode_realm">${_('Realm text')}:</label>
95 </div>
95 </div>
96 <div class="input">
96 <div class="input">
97 ${h.text('rhodecode_realm',size=30)}
97 ${h.text('rhodecode_realm',size=30)}
98 </div>
98 </div>
99 </div>
99 </div>
100
100
101 <div class="field">
101 <div class="field">
102 <div class="label">
102 <div class="label">
103 <label for="rhodecode_ga_code">${_('GA code')}:</label>
103 <label for="rhodecode_ga_code">${_('GA code')}:</label>
104 </div>
104 </div>
105 <div class="input">
105 <div class="input">
106 ${h.text('rhodecode_ga_code',size=30)}
106 ${h.text('rhodecode_ga_code',size=30)}
107 </div>
107 </div>
108 </div>
108 </div>
109
109
110 <div class="buttons">
110 <div class="buttons">
111 ${h.submit('save',_('Save settings'),class_="ui-button")}
111 ${h.submit('save',_('Save settings'),class_="ui-button")}
112 ${h.reset('reset',_('Reset'),class_="ui-button")}
112 ${h.reset('reset',_('Reset'),class_="ui-button")}
113 </div>
113 </div>
114 </div>
114 </div>
115 </div>
115 </div>
116 ${h.end_form()}
116 ${h.end_form()}
117
117
118 <h3>${_('Mercurial settings')}</h3>
118 <h3>${_('Mercurial settings')}</h3>
119 ${h.form(url('admin_setting', setting_id='mercurial'),method='put')}
119 ${h.form(url('admin_setting', setting_id='mercurial'),method='put')}
120 <div class="form">
120 <div class="form">
121 <!-- fields -->
121 <!-- fields -->
122
122
123 <div class="fields">
123 <div class="fields">
124
124
125 <div class="field">
125 <div class="field">
126 <div class="label label-checkbox">
126 <div class="label label-checkbox">
127 <label>${_('Web')}:</label>
127 <label>${_('Web')}:</label>
128 </div>
128 </div>
129 <div class="checkboxes">
129 <div class="checkboxes">
130 <div class="checkbox">
130 <div class="checkbox">
131 ${h.checkbox('web_push_ssl','true')}
131 ${h.checkbox('web_push_ssl','true')}
132 <label for="web_push_ssl">${_('require ssl for pushing')}</label>
132 <label for="web_push_ssl">${_('require ssl for pushing')}</label>
133 </div>
133 </div>
134 </div>
134 </div>
135 </div>
135 </div>
136
136
137 <div class="field">
137 <div class="field">
138 <div class="label label-checkbox">
138 <div class="label label-checkbox">
139 <label>${_('Hooks')}:</label>
139 <label>${_('Hooks')}:</label>
140 </div>
140 </div>
141 <div class="checkboxes">
141 <div class="checkboxes">
142 <div class="checkbox">
142 <div class="checkbox">
143 ${h.checkbox('hooks_changegroup_update','True')}
143 ${h.checkbox('hooks_changegroup_update','True')}
144 <label for="hooks_changegroup_update">${_('Update repository after push (hg update)')}</label>
144 <label for="hooks_changegroup_update">${_('Update repository after push (hg update)')}</label>
145 </div>
145 </div>
146 <div class="checkbox">
146 <div class="checkbox">
147 ${h.checkbox('hooks_changegroup_repo_size','True')}
147 ${h.checkbox('hooks_changegroup_repo_size','True')}
148 <label for="hooks_changegroup_repo_size">${_('Show repository size after push')}</label>
148 <label for="hooks_changegroup_repo_size">${_('Show repository size after push')}</label>
149 </div>
149 </div>
150 <div class="checkbox">
150 <div class="checkbox">
151 ${h.checkbox('hooks_pretxnchangegroup_push_logger','True')}
151 ${h.checkbox('hooks_pretxnchangegroup_push_logger','True')}
152 <label for="hooks_pretxnchangegroup_push_logger">${_('Log user push commands')}</label>
152 <label for="hooks_pretxnchangegroup_push_logger">${_('Log user push commands')}</label>
153 </div>
153 </div>
154 <div class="checkbox">
154 <div class="checkbox">
155 ${h.checkbox('hooks_preoutgoing_pull_logger','True')}
155 ${h.checkbox('hooks_preoutgoing_pull_logger','True')}
156 <label for="hooks_preoutgoing_pull_logger">${_('Log user pull commands')}</label>
156 <label for="hooks_preoutgoing_pull_logger">${_('Log user pull commands')}</label>
157 </div>
157 </div>
158 </div>
158 </div>
159 <div class="input" style="margin-top:10px">
159 <div class="input" style="margin-top:10px">
160 ${h.link_to(_('advanced setup'),url('admin_edit_setting',setting_id='hooks'),class_="ui-btn")}
160 ${h.link_to(_('advanced setup'),url('admin_edit_setting',setting_id='hooks'),class_="ui-btn")}
161 </div>
161 </div>
162 </div>
162 </div>
163 <div class="field">
163 <div class="field">
164 <div class="label">
164 <div class="label">
165 <label for="paths_root_path">${_('Repositories location')}:</label>
165 <label for="paths_root_path">${_('Repositories location')}:</label>
166 </div>
166 </div>
167 <div class="input">
167 <div class="input">
168 ${h.text('paths_root_path',size=30,readonly="readonly")}
168 ${h.text('paths_root_path',size=30,readonly="readonly")}
169 <span id="path_unlock" class="tooltip"
169 <span id="path_unlock" class="tooltip"
170 title="${h.tooltip(_('This a crucial application setting. If you are really sure you need to change this, you must restart application in order to make this setting take effect. Click this label to unlock.'))}">
170 title="${h.tooltip(_('This a crucial application setting. If you are really sure you need to change this, you must restart application in order to make this setting take effect. Click this label to unlock.'))}">
171 ${_('unlock')}</span>
171 ${_('unlock')}</span>
172 </div>
172 </div>
173 </div>
173 </div>
174
174
175 <div class="buttons">
175 <div class="buttons">
176 ${h.submit('save',_('Save settings'),class_="ui-button")}
176 ${h.submit('save',_('Save settings'),class_="ui-button")}
177 ${h.reset('reset',_('Reset'),class_="ui-button")}
177 ${h.reset('reset',_('Reset'),class_="ui-button")}
178 </div>
178 </div>
179 </div>
179 </div>
180 </div>
180 </div>
181 ${h.end_form()}
181 ${h.end_form()}
182
182
183 <script type="text/javascript">
183 <script type="text/javascript">
184 YAHOO.util.Event.onDOMReady(function(){
184 YAHOO.util.Event.onDOMReady(function(){
185 YAHOO.util.Event.addListener('path_unlock','click',function(){
185 YAHOO.util.Event.addListener('path_unlock','click',function(){
186 YAHOO.util.Dom.get('paths_root_path').removeAttribute('readonly');
186 YAHOO.util.Dom.get('paths_root_path').removeAttribute('readonly');
187 });
187 });
188 });
188 });
189 </script>
189 </script>
190
190
191 <h3>${_('Test Email')}</h3>
191 <h3>${_('Test Email')}</h3>
192 ${h.form(url('admin_setting', setting_id='email'),method='put')}
192 ${h.form(url('admin_setting', setting_id='email'),method='put')}
193 <div class="form">
193 <div class="form">
194 <!-- fields -->
194 <!-- fields -->
195
195
196 <div class="fields">
196 <div class="fields">
197 <div class="field">
197 <div class="field">
198 <div class="label">
198 <div class="label">
199 <label for="test_email">${_('Email to')}:</label>
199 <label for="test_email">${_('Email to')}:</label>
200 </div>
200 </div>
201 <div class="input">
201 <div class="input">
202 ${h.text('test_email',size=30)}
202 ${h.text('test_email',size=30)}
203 </div>
203 </div>
204 </div>
204 </div>
205
205
206 <div class="buttons">
206 <div class="buttons">
207 ${h.submit('send',_('Send'),class_="ui-button")}
207 ${h.submit('send',_('Send'),class_="ui-button")}
208 </div>
208 </div>
209 </div>
209 </div>
210 </div>
210 </div>
211 ${h.end_form()}
211 ${h.end_form()}
212
212
213 <h3>${_('System Info and Packages')}</h3>
214 <div class="form">
215 <div>
216 <h5 id="expand_modules" style="cursor: pointer">&darr; ${_('show')} &darr;</h5>
217 </div>
218 <div id="expand_modules_table" style="display:none">
219 <h5>Python - ${c.py_version}</h5>
220 <h5>System - ${c.platform}</h5>
221
222 <table class="table" style="margin:0px 0px 0px 20px">
223 <colgroup>
224 <col style="width:220px">
225 </colgroup>
226 <tbody>
227 %for key, value in c.modules:
228 <tr>
229 <th>${key}</th>
230 <td>${value}</td>
231 </tr>
232 %endfor
233 </tbody>
234 </table>
235 </div>
236 </div>
237
238 <script type="text/javascript">
239 YUE.on('expand_modules','click',function(e){
240 YUD.setStyle('expand_modules_table','display','');
241 YUD.setStyle('expand_modules','display','none');
242 })
243 </script>
244
213 </div>
245 </div>
214 </%def>
246 </%def>
General Comments 0
You need to be logged in to leave comments. Login now