comparison rhodecode/controllers/admin/settings.py @ 4116:ffd45b185016 rhodecode-2.2.5-gpl

Imported some of the GPLv3'd changes from RhodeCode v2.2.5. This imports changes between changesets 21af6c4eab3d and 6177597791c2 in RhodeCode's original repository, including only changes to Python files and HTML. RhodeCode clearly licensed its changes to these files under GPLv3 in their /LICENSE file, which states the following: The Python code and integrated HTML are licensed under the GPLv3 license. (See: https://code.rhodecode.com/rhodecode/files/v2.2.5/LICENSE or http://web.archive.org/web/20140512193334/https://code.rhodecode.com/rhodecode/files/f3b123159901f15426d18e3dc395e8369f70ebe0/LICENSE for an online copy of that LICENSE file) Conservancy reviewed these changes and confirmed that they can be licensed as a whole to the Kallithea project under GPLv3-only. While some of the contents committed herein are clearly licensed GPLv3-or-later, on the whole we must assume the are GPLv3-only, since the statement above from RhodeCode indicates that they intend GPLv3-only as their license, per GPLv3ยง14 and other relevant sections of GPLv3.
author Bradley M. Kuhn <bkuhn@sfconservancy.org>
date Wed, 02 Jul 2014 19:03:13 -0400
parents 7676606f7622
children 31e119cb02ef
comparison
equal deleted inserted replaced
4115:8b7294a804a0 4116:ffd45b185016
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 """
3 rhodecode.controllers.admin.settings
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 settings controller for rhodecode admin
7
8 :created_on: Jul 14, 2010
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
13 # This program is free software: you can redistribute it and/or modify 2 # 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 3 # 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 4 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version. 5 # (at your option) any later version.
17 # 6 #
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details. 10 # GNU General Public License for more details.
22 # 11 #
23 # You should have received a copy of the GNU General Public License 12 # 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/>. 13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 14 """
15 rhodecode.controllers.admin.settings
16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17
18 settings controller for rhodecode admin
19
20 :created_on: Jul 14, 2010
21 :author: marcink
22 :copyright: (c) 2013 RhodeCode GmbH.
23 :license: GPLv3, see LICENSE for more details.
24 """
25
26 import time
26 import logging 27 import logging
27 import traceback 28 import traceback
28 import formencode 29 import formencode
29 import pkg_resources 30
30 import platform
31
32 from sqlalchemy import func
33 from formencode import htmlfill 31 from formencode import htmlfill
34 from pylons import request, session, tmpl_context as c, url, config 32 from pylons import request, tmpl_context as c, url, config
35 from pylons.controllers.util import abort, redirect 33 from pylons.controllers.util import redirect
36 from pylons.i18n.translation import _ 34 from pylons.i18n.translation import _
37 35
38 from rhodecode.lib import helpers as h 36 from rhodecode.lib import helpers as h
39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \ 37 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
40 HasPermissionAnyDecorator, NotAnonymous, HasPermissionAny,\
41 HasReposGroupPermissionAll, HasReposGroupPermissionAny, AuthUser
42 from rhodecode.lib.base import BaseController, render 38 from rhodecode.lib.base import BaseController, render
43 from rhodecode.lib.celerylib import tasks, run_task 39 from rhodecode.lib.celerylib import tasks, run_task
44 from rhodecode.lib.exceptions import HgsubversionImportError 40 from rhodecode.lib.exceptions import HgsubversionImportError
45 from rhodecode.lib.utils import repo2db_mapper, set_rhodecode_config, \ 41 from rhodecode.lib.utils import repo2db_mapper, set_rhodecode_config
46 check_git_version 42 from rhodecode.model.db import RhodeCodeUi, Repository, RhodeCodeSetting
47 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \ 43 from rhodecode.model.forms import ApplicationSettingsForm, \
48 RhodeCodeSetting, PullRequest, PullRequestReviewers
49 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
50 ApplicationUiSettingsForm, ApplicationVisualisationForm 44 ApplicationUiSettingsForm, ApplicationVisualisationForm
51 from rhodecode.model.scm import ScmModel, RepoGroupList 45 from rhodecode.model.license import LicenseModel
52 from rhodecode.model.user import UserModel 46 from rhodecode.model.scm import ScmModel
53 from rhodecode.model.repo import RepoModel
54 from rhodecode.model.db import User
55 from rhodecode.model.notification import EmailNotificationModel 47 from rhodecode.model.notification import EmailNotificationModel
56 from rhodecode.model.meta import Session 48 from rhodecode.model.meta import Session
57 from rhodecode.lib.utils2 import str2bool, safe_unicode 49 from rhodecode.lib.utils2 import str2bool, safe_unicode, safe_str
58 from rhodecode.lib.compat import json 50 from rhodecode.lib.compat import json
59 log = logging.getLogger(__name__) 51 log = logging.getLogger(__name__)
60 52
61 53
62 class SettingsController(BaseController): 54 class SettingsController(BaseController):
67 # path_prefix='/admin', name_prefix='admin_') 59 # path_prefix='/admin', name_prefix='admin_')
68 60
69 @LoginRequired() 61 @LoginRequired()
70 def __before__(self): 62 def __before__(self):
71 super(SettingsController, self).__before__() 63 super(SettingsController, self).__before__()
72 c.modules = sorted([(p.project_name, p.version) 64
73 for p in pkg_resources.working_set] 65 def _get_hg_ui_settings(self):
74 + [('git', check_git_version())], 66 ret = RhodeCodeUi.query().all()
75 key=lambda k: k[0].lower()) 67
76 c.py_version = platform.python_version() 68 if not ret:
77 c.platform = platform.platform() 69 raise Exception('Could not get application ui settings !')
78 70 settings = {}
79 @HasPermissionAllDecorator('hg.admin') 71 for each in ret:
80 def index(self, format='html'): 72 k = each.ui_key
73 v = each.ui_value
74 if k == '/':
75 k = 'root_path'
76
77 if k == 'push_ssl':
78 v = str2bool(v)
79
80 if k.find('.') != -1:
81 k = k.replace('.', '_')
82
83 if each.ui_section in ['hooks', 'extensions']:
84 v = each.ui_active
85
86 settings[each.ui_section + '_' + k] = v
87 return settings
88
89 @HasPermissionAllDecorator('hg.admin')
90 def settings_vcs(self):
81 """GET /admin/settings: All items in the collection""" 91 """GET /admin/settings: All items in the collection"""
82 # url('admin_settings') 92 # url('admin_settings')
83 93 c.active = 'vcs'
84 defaults = RhodeCodeSetting.get_app_settings() 94 if request.POST:
85 defaults.update(self._get_hg_ui_settings()) 95 application_form = ApplicationUiSettingsForm()()
86
87 return htmlfill.render(
88 render('admin/settings/settings.html'),
89 defaults=defaults,
90 encoding="UTF-8",
91 force_defaults=False
92 )
93
94 @HasPermissionAllDecorator('hg.admin')
95 def create(self):
96 """POST /admin/settings: Create a new item"""
97 # url('admin_settings')
98
99 @HasPermissionAllDecorator('hg.admin')
100 def new(self, format='html'):
101 """GET /admin/settings/new: Form to create a new item"""
102 # url('admin_new_setting')
103
104 @HasPermissionAllDecorator('hg.admin')
105 def update(self, setting_id):
106 """PUT /admin/settings/setting_id: Update an existing item"""
107 # Forms posted to this method should contain a hidden field:
108 # <input type="hidden" name="_method" value="PUT" />
109 # Or using helpers:
110 # h.form(url('admin_setting', setting_id=ID),
111 # method='put')
112 # url('admin_setting', setting_id=ID)
113
114 if setting_id == 'mapping':
115 rm_obsolete = request.POST.get('destroy', False)
116 invalidate_cache = request.POST.get('invalidate', False)
117 log.debug('rescanning repo location with destroy obsolete=%s'
118 % (rm_obsolete,))
119
120 if invalidate_cache:
121 log.debug('invalidating all repositories cache')
122 for repo in Repository.get_all():
123 ScmModel().mark_for_invalidation(repo.repo_name)
124
125 filesystem_repos = ScmModel().repo_scan()
126 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
127 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
128 h.flash(_('Repositories successfully '
129 'rescanned added: %s ; removed: %s') %
130 (_repr(added), _repr(removed)),
131 category='success')
132
133 if setting_id == 'whoosh':
134 repo_location = self._get_hg_ui_settings()['paths_root_path']
135 full_index = request.POST.get('full_index', False)
136 run_task(tasks.whoosh_index, repo_location, full_index)
137 h.flash(_('Whoosh reindex task scheduled'), category='success')
138
139 if setting_id == 'global':
140
141 application_form = ApplicationSettingsForm()()
142 try: 96 try:
143 form_result = application_form.to_python(dict(request.POST)) 97 form_result = application_form.to_python(dict(request.POST))
144 except formencode.Invalid, errors: 98 except formencode.Invalid, errors:
145 return htmlfill.render( 99 return htmlfill.render(
146 render('admin/settings/settings.html'), 100 render('admin/settings/settings.html'),
149 prefix_error=False, 103 prefix_error=False,
150 encoding="UTF-8" 104 encoding="UTF-8"
151 ) 105 )
152 106
153 try: 107 try:
154 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
155 sett1.app_settings_value = form_result['rhodecode_title']
156 Session().add(sett1)
157
158 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
159 sett2.app_settings_value = form_result['rhodecode_realm']
160 Session().add(sett2)
161
162 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
163 sett3.app_settings_value = form_result['rhodecode_ga_code']
164 Session().add(sett3)
165
166 Session().commit()
167 set_rhodecode_config(config)
168 h.flash(_('Updated application settings'), category='success')
169
170 except Exception:
171 log.error(traceback.format_exc())
172 h.flash(_('Error occurred during updating '
173 'application settings'),
174 category='error')
175
176 if setting_id == 'visual':
177
178 application_form = ApplicationVisualisationForm()()
179 try:
180 form_result = application_form.to_python(dict(request.POST))
181 except formencode.Invalid, errors:
182 return htmlfill.render(
183 render('admin/settings/settings.html'),
184 defaults=errors.value,
185 errors=errors.error_dict or {},
186 prefix_error=False,
187 encoding="UTF-8"
188 )
189
190 try:
191 #TODO: rewrite this to something less ugly
192 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
193 sett1.app_settings_value = \
194 form_result['rhodecode_show_public_icon']
195 Session().add(sett1)
196
197 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
198 sett2.app_settings_value = \
199 form_result['rhodecode_show_private_icon']
200 Session().add(sett2)
201
202 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
203 sett3.app_settings_value = \
204 form_result['rhodecode_stylify_metatags']
205 Session().add(sett3)
206
207 sett4 = RhodeCodeSetting.get_by_name_or_create('repository_fields')
208 sett4.app_settings_value = \
209 form_result['rhodecode_repository_fields']
210 Session().add(sett4)
211
212 sett5 = RhodeCodeSetting.get_by_name_or_create('dashboard_items')
213 sett5.app_settings_value = \
214 form_result['rhodecode_dashboard_items']
215 Session().add(sett5)
216
217 sett6 = RhodeCodeSetting.get_by_name_or_create('show_version')
218 sett6.app_settings_value = \
219 form_result['rhodecode_show_version']
220 Session().add(sett6)
221
222 Session().commit()
223 set_rhodecode_config(config)
224 h.flash(_('Updated visualisation settings'),
225 category='success')
226
227 except Exception:
228 log.error(traceback.format_exc())
229 h.flash(_('Error occurred during updating '
230 'visualisation settings'),
231 category='error')
232
233 if setting_id == 'vcs':
234 application_form = ApplicationUiSettingsForm()()
235 try:
236 form_result = application_form.to_python(dict(request.POST))
237 except formencode.Invalid, errors:
238 return htmlfill.render(
239 render('admin/settings/settings.html'),
240 defaults=errors.value,
241 errors=errors.error_dict or {},
242 prefix_error=False,
243 encoding="UTF-8"
244 )
245
246 try:
247 sett = RhodeCodeUi.get_by_key('push_ssl') 108 sett = RhodeCodeUi.get_by_key('push_ssl')
248 sett.ui_value = form_result['web_push_ssl'] 109 sett.ui_value = form_result['web_push_ssl']
249 Session().add(sett) 110 Session().add(sett)
250 if c.visual.allow_repo_location_change: 111 if c.visual.allow_repo_location_change:
251 sett = RhodeCodeUi.get_by_key('/') 112 sett = RhodeCodeUi.get_by_key('/')
288 sett.ui_section = 'extensions' 149 sett.ui_section = 'extensions'
289 150
290 sett.ui_active = form_result['extensions_hgsubversion'] 151 sett.ui_active = form_result['extensions_hgsubversion']
291 if sett.ui_active: 152 if sett.ui_active:
292 try: 153 try:
293 import hgsubversion 154 import hgsubversion # pragma: no cover
294 except ImportError: 155 except ImportError:
295 raise HgsubversionImportError 156 raise HgsubversionImportError
296 Session().add(sett) 157 Session().add(sett)
297 158
298 # sett = RhodeCodeUi.get_by_key('hggit') 159 # sett = RhodeCodeUi.get_by_key('hggit')
318 except Exception: 179 except Exception:
319 log.error(traceback.format_exc()) 180 log.error(traceback.format_exc())
320 h.flash(_('Error occurred during updating ' 181 h.flash(_('Error occurred during updating '
321 'application settings'), category='error') 182 'application settings'), category='error')
322 183
323 if setting_id == 'hooks': 184 defaults = RhodeCodeSetting.get_app_settings()
185 defaults.update(self._get_hg_ui_settings())
186
187 return htmlfill.render(
188 render('admin/settings/settings.html'),
189 defaults=defaults,
190 encoding="UTF-8",
191 force_defaults=False)
192
193 @HasPermissionAllDecorator('hg.admin')
194 def settings_mapping(self):
195 """GET /admin/settings/mapping: All items in the collection"""
196 # url('admin_settings_mapping')
197 c.active = 'mapping'
198 if request.POST:
199 rm_obsolete = request.POST.get('destroy', False)
200 install_git_hooks = request.POST.get('hooks', False)
201 invalidate_cache = request.POST.get('invalidate', False)
202 log.debug('rescanning repo location with destroy obsolete=%s and '
203 'install git hooks=%s' % (rm_obsolete,install_git_hooks))
204
205 if invalidate_cache:
206 log.debug('invalidating all repositories cache')
207 for repo in Repository.get_all():
208 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
209
210 filesystem_repos = ScmModel().repo_scan()
211 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete,
212 install_git_hook=install_git_hooks)
213 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
214 h.flash(_('Repositories successfully '
215 'rescanned added: %s ; removed: %s') %
216 (_repr(added), _repr(removed)),
217 category='success')
218 return redirect(url('admin_settings_mapping'))
219
220 defaults = RhodeCodeSetting.get_app_settings()
221 defaults.update(self._get_hg_ui_settings())
222
223 return htmlfill.render(
224 render('admin/settings/settings.html'),
225 defaults=defaults,
226 encoding="UTF-8",
227 force_defaults=False)
228
229 @HasPermissionAllDecorator('hg.admin')
230 def settings_global(self):
231 """GET /admin/settings/global: All items in the collection"""
232 # url('admin_settings_global')
233 c.active = 'global'
234 if request.POST:
235 application_form = ApplicationSettingsForm()()
236 try:
237 form_result = application_form.to_python(dict(request.POST))
238 except formencode.Invalid, errors:
239 return htmlfill.render(
240 render('admin/settings/settings.html'),
241 defaults=errors.value,
242 errors=errors.error_dict or {},
243 prefix_error=False,
244 encoding="UTF-8")
245
246 try:
247 sett1 = RhodeCodeSetting.create_or_update('title',
248 form_result['rhodecode_title'])
249 Session().add(sett1)
250
251 sett2 = RhodeCodeSetting.create_or_update('realm',
252 form_result['rhodecode_realm'])
253 Session().add(sett2)
254
255 sett3 = RhodeCodeSetting.create_or_update('ga_code',
256 form_result['rhodecode_ga_code'])
257 Session().add(sett3)
258
259 sett4 = RhodeCodeSetting.create_or_update('captcha_public_key',
260 form_result['rhodecode_captcha_public_key'])
261 Session().add(sett4)
262
263 sett5 = RhodeCodeSetting.create_or_update('captcha_private_key',
264 form_result['rhodecode_captcha_private_key'])
265 Session().add(sett5)
266
267 Session().commit()
268 set_rhodecode_config(config)
269 h.flash(_('Updated application settings'), category='success')
270
271 except Exception:
272 log.error(traceback.format_exc())
273 h.flash(_('Error occurred during updating '
274 'application settings'),
275 category='error')
276
277 return redirect(url('admin_settings_global'))
278
279 defaults = RhodeCodeSetting.get_app_settings()
280 defaults.update(self._get_hg_ui_settings())
281
282 return htmlfill.render(
283 render('admin/settings/settings.html'),
284 defaults=defaults,
285 encoding="UTF-8",
286 force_defaults=False)
287
288 @HasPermissionAllDecorator('hg.admin')
289 def settings_visual(self):
290 """GET /admin/settings/visual: All items in the collection"""
291 # url('admin_settings_visual')
292 c.active = 'visual'
293 if request.POST:
294 application_form = ApplicationVisualisationForm()()
295 try:
296 form_result = application_form.to_python(dict(request.POST))
297 except formencode.Invalid, errors:
298 return htmlfill.render(
299 render('admin/settings/settings.html'),
300 defaults=errors.value,
301 errors=errors.error_dict or {},
302 prefix_error=False,
303 encoding="UTF-8"
304 )
305
306 try:
307 settings = [
308 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
309 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
310 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
311 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
312 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
313 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
314 ('show_version', 'rhodecode_show_version', 'bool'),
315 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
316 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
317 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
318 ]
319 for setting, form_key, type_ in settings:
320 sett = RhodeCodeSetting.create_or_update(setting,
321 form_result[form_key], type_)
322 Session().add(sett)
323
324 Session().commit()
325 set_rhodecode_config(config)
326 h.flash(_('Updated visualisation settings'),
327 category='success')
328
329 except Exception:
330 log.error(traceback.format_exc())
331 h.flash(_('Error occurred during updating '
332 'visualisation settings'),
333 category='error')
334
335 return redirect(url('admin_settings_visual'))
336
337 defaults = RhodeCodeSetting.get_app_settings()
338 defaults.update(self._get_hg_ui_settings())
339
340 return htmlfill.render(
341 render('admin/settings/settings.html'),
342 defaults=defaults,
343 encoding="UTF-8",
344 force_defaults=False)
345
346 @HasPermissionAllDecorator('hg.admin')
347 def settings_email(self):
348 """GET /admin/settings/email: All items in the collection"""
349 # url('admin_settings_email')
350 c.active = 'email'
351 if request.POST:
352 test_email = request.POST.get('test_email')
353 test_email_subj = 'RhodeCode test email'
354 test_email_body = ('RhodeCode Email test, '
355 'RhodeCode version: %s' % c.rhodecode_version)
356 if not test_email:
357 h.flash(_('Please enter email address'), category='error')
358 return redirect(url('admin_settings_email'))
359
360 test_email_html_body = EmailNotificationModel()\
361 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
362 body=test_email_body)
363
364 recipients = [test_email] if test_email else None
365
366 run_task(tasks.send_email, recipients, test_email_subj,
367 test_email_body, test_email_html_body)
368
369 h.flash(_('Send email task created'), category='success')
370 return redirect(url('admin_settings_email'))
371
372 defaults = RhodeCodeSetting.get_app_settings()
373 defaults.update(self._get_hg_ui_settings())
374
375 import rhodecode
376 c.rhodecode_ini = rhodecode.CONFIG
377
378 return htmlfill.render(
379 render('admin/settings/settings.html'),
380 defaults=defaults,
381 encoding="UTF-8",
382 force_defaults=False)
383
384 @HasPermissionAllDecorator('hg.admin')
385 def settings_hooks(self):
386 """GET /admin/settings/hooks: All items in the collection"""
387 # url('admin_settings_hooks')
388 c.active = 'hooks'
389 if request.POST:
324 if c.visual.allow_custom_hooks_settings: 390 if c.visual.allow_custom_hooks_settings:
325 ui_key = request.POST.get('new_hook_ui_key') 391 ui_key = request.POST.get('new_hook_ui_key')
326 ui_value = request.POST.get('new_hook_ui_value') 392 ui_value = request.POST.get('new_hook_ui_value')
393
394 hook_id = request.POST.get('hook_id')
395
327 try: 396 try:
328
329 if ui_value and ui_key: 397 if ui_value and ui_key:
330 RhodeCodeUi.create_or_update_hook(ui_key, ui_value) 398 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
331 h.flash(_('Added new hook'), 399 h.flash(_('Added new hook'), category='success')
332 category='success') 400 elif hook_id:
401 RhodeCodeUi.delete(hook_id)
402 Session().commit()
333 403
334 # check for edits 404 # check for edits
335 update = False 405 update = False
336 _d = request.POST.dict_of_lists() 406 _d = request.POST.dict_of_lists()
337 for k, v in zip(_d.get('hook_ui_key', []), 407 for k, v in zip(_d.get('hook_ui_key', []),
345 except Exception: 415 except Exception:
346 log.error(traceback.format_exc()) 416 log.error(traceback.format_exc())
347 h.flash(_('Error occurred during hook creation'), 417 h.flash(_('Error occurred during hook creation'),
348 category='error') 418 category='error')
349 419
350 return redirect(url('admin_edit_setting', setting_id='hooks')) 420 return redirect(url('admin_settings_hooks'))
351 421
352 if setting_id == 'email': 422 defaults = RhodeCodeSetting.get_app_settings()
353 test_email = request.POST.get('test_email') 423 defaults.update(self._get_hg_ui_settings())
354 test_email_subj = 'RhodeCode TestEmail'
355 test_email_body = 'RhodeCode Email test'
356
357 test_email_html_body = EmailNotificationModel()\
358 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
359 body=test_email_body)
360
361 recipients = [test_email] if test_email else None
362
363 run_task(tasks.send_email, recipients, test_email_subj,
364 test_email_body, test_email_html_body)
365
366 h.flash(_('Email task created'), category='success')
367 return redirect(url('admin_settings'))
368
369 @HasPermissionAllDecorator('hg.admin')
370 def delete(self, setting_id):
371 """DELETE /admin/settings/setting_id: Delete an existing item"""
372 # Forms posted to this method should contain a hidden field:
373 # <input type="hidden" name="_method" value="DELETE" />
374 # Or using helpers:
375 # h.form(url('admin_setting', setting_id=ID),
376 # method='delete')
377 # url('admin_setting', setting_id=ID)
378 if setting_id == 'hooks':
379 hook_id = request.POST.get('hook_id')
380 RhodeCodeUi.delete(hook_id)
381 Session().commit()
382
383 @HasPermissionAllDecorator('hg.admin')
384 def show(self, setting_id, format='html'):
385 """
386 GET /admin/settings/setting_id: Show a specific item"""
387 # url('admin_setting', setting_id=ID)
388
389 @HasPermissionAllDecorator('hg.admin')
390 def edit(self, setting_id, format='html'):
391 """
392 GET /admin/settings/setting_id/edit: Form to
393 edit an existing item"""
394 # url('admin_edit_setting', setting_id=ID)
395 424
396 c.hooks = RhodeCodeUi.get_builtin_hooks() 425 c.hooks = RhodeCodeUi.get_builtin_hooks()
397 c.custom_hooks = RhodeCodeUi.get_custom_hooks() 426 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
398 427
399 return htmlfill.render( 428 return htmlfill.render(
400 render('admin/settings/hooks.html'), 429 render('admin/settings/settings.html'),
401 defaults={}, 430 defaults=defaults,
402 encoding="UTF-8", 431 encoding="UTF-8",
403 force_defaults=False 432 force_defaults=False)
404 ) 433
405 434 @HasPermissionAllDecorator('hg.admin')
406 def _load_my_repos_data(self): 435 def settings_search(self):
407 repos_list = Session().query(Repository)\ 436 """GET /admin/settings/search: All items in the collection"""
408 .filter(Repository.user_id == 437 # url('admin_settings_search')
409 self.rhodecode_user.user_id)\ 438 c.active = 'search'
410 .order_by(func.lower(Repository.repo_name)).all() 439 if request.POST:
411 440 repo_location = self._get_hg_ui_settings()['paths_root_path']
412 repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list, 441 full_index = request.POST.get('full_index', False)
413 admin=True) 442 run_task(tasks.whoosh_index, repo_location, full_index)
414 #json used to render the grid 443 h.flash(_('Whoosh reindex task scheduled'), category='success')
415 return json.dumps(repos_data) 444 return redirect(url('admin_settings_search'))
416 445
417 @NotAnonymous() 446 defaults = RhodeCodeSetting.get_app_settings()
418 def my_account(self): 447 defaults.update(self._get_hg_ui_settings())
419 """ 448
420 GET /_admin/my_account Displays info about my account 449 return htmlfill.render(
421 """ 450 render('admin/settings/settings.html'),
422 # url('admin_settings_my_account') 451 defaults=defaults,
423 452 encoding="UTF-8",
424 c.user = User.get(self.rhodecode_user.user_id) 453 force_defaults=False)
425 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id, 454
426 ip_addr=self.ip_addr) 455 @HasPermissionAllDecorator('hg.admin')
427 c.ldap_dn = c.user.ldap_dn 456 def settings_system(self):
428 457 """GET /admin/settings/system: All items in the collection"""
429 if c.user.username == 'default': 458 # url('admin_settings_system')
430 h.flash(_("You can't edit this user since it's" 459 c.active = 'system'
431 " crucial for entire application"), category='warning') 460
432 return redirect(url('users')) 461 defaults = RhodeCodeSetting.get_app_settings()
433 462 defaults.update(self._get_hg_ui_settings())
434 #json used to render the grid 463
435 c.data = self._load_my_repos_data() 464 import rhodecode
436 465 c.rhodecode_ini = rhodecode.CONFIG
437 defaults = c.user.get_dict() 466 c.rhodecode_update_url = defaults.get('rhodecode_update_url')
438 467 server_info = RhodeCodeSetting.get_server_info()
439 c.form = htmlfill.render( 468 for key, val in server_info.iteritems():
440 render('admin/users/user_edit_my_account_form.html'), 469 setattr(c, key, val)
441 defaults=defaults, 470
442 encoding="UTF-8", 471 return htmlfill.render(
443 force_defaults=False 472 render('admin/settings/settings.html'),
444 ) 473 defaults=defaults,
445 return render('admin/users/user_edit_my_account.html') 474 encoding="UTF-8",
446 475 force_defaults=False)
447 @NotAnonymous() 476
448 def my_account_update(self): 477 @HasPermissionAllDecorator('hg.admin')
449 """PUT /_admin/my_account_update: Update an existing item""" 478 def settings_system_update(self):
450 # Forms posted to this method should contain a hidden field: 479 """GET /admin/settings/system/updates: All items in the collection"""
451 # <input type="hidden" name="_method" value="PUT" /> 480 # url('admin_settings_system_update')
452 # Or using helpers: 481 import json
453 # h.form(url('admin_settings_my_account_update'), 482 import urllib2
454 # method='put') 483 from rhodecode.lib.verlib import NormalizedVersion
455 # url('admin_settings_my_account_update', id=ID) 484 from rhodecode import __version__
456 uid = self.rhodecode_user.user_id 485
457 c.user = User.get(self.rhodecode_user.user_id) 486 defaults = RhodeCodeSetting.get_app_settings()
458 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id, 487 defaults.update(self._get_hg_ui_settings())
459 ip_addr=self.ip_addr) 488 _update_url = defaults.get('rhodecode_update_url', '')
460 c.ldap_dn = c.user.ldap_dn 489
461 email = self.rhodecode_user.email 490 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s)
462 _form = UserForm(edit=True,
463 old_data={'user_id': uid, 'email': email})()
464 form_result = {}
465 try: 491 try:
466 form_result = _form.to_python(dict(request.POST)) 492 import rhodecode
467 skip_attrs = ['admin', 'active'] # skip attr for my account 493 ver = rhodecode.__version__
468 if c.ldap_dn: 494 log.debug('Checking for upgrade on `%s` server' % _update_url)
469 #forbid updating username for ldap accounts 495 opener = urllib2.build_opener()
470 skip_attrs.append('username') 496 opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)]
471 UserModel().update(uid, form_result, skip_attrs=skip_attrs) 497 response = opener.open(_update_url)
472 h.flash(_('Your account was updated successfully'), 498 response_data = response.read()
473 category='success') 499 data = json.loads(response_data)
474 Session().commit() 500 except urllib2.URLError, e:
475 except formencode.Invalid, errors:
476 #json used to render the grid
477 c.data = self._load_my_repos_data()
478 c.form = htmlfill.render(
479 render('admin/users/user_edit_my_account_form.html'),
480 defaults=errors.value,
481 errors=errors.error_dict or {},
482 prefix_error=False,
483 encoding="UTF-8")
484 return render('admin/users/user_edit_my_account.html')
485 except Exception:
486 log.error(traceback.format_exc()) 501 log.error(traceback.format_exc())
487 h.flash(_('Error occurred during update of user %s') \ 502 return _err('Failed to contact upgrade server: %r' % e)
488 % form_result.get('username'), category='error') 503 except ValueError, e:
489 504 log.error(traceback.format_exc())
490 return redirect(url('my_account')) 505 return _err('Bad data sent from update server')
491 506
492 @NotAnonymous() 507 latest = data['versions'][0]
493 def my_account_my_pullrequests(self): 508
494 c.show_closed = request.GET.get('pr_show_closed') 509 c.update_url = _update_url
495 510 c.latest_data = latest
496 def _filter(pr): 511 c.latest_ver = latest['version']
497 s = sorted(pr, key=lambda o: o.created_on, reverse=True) 512 c.cur_ver = __version__
498 if not c.show_closed: 513 c.should_upgrade = False
499 s = filter(lambda p: p.status != PullRequest.STATUS_CLOSED, s) 514
500 return s 515 if NormalizedVersion(c.latest_ver) > NormalizedVersion(c.cur_ver):
501 516 c.should_upgrade = True
502 c.my_pull_requests = _filter(PullRequest.query()\ 517 c.important_notices = latest['general']
503 .filter(PullRequest.user_id == 518
504 self.rhodecode_user.user_id)\ 519 return render('admin/settings/settings_system_update.html'),
505 .all()) 520
506 521 @HasPermissionAllDecorator('hg.admin')
507 c.participate_in_pull_requests = _filter([ 522 def settings_license(self):
508 x.pull_request for x in PullRequestReviewers.query()\ 523 """GET /admin/settings/hooks: All items in the collection"""
509 .filter(PullRequestReviewers.user_id == 524 # url('admin_settings_license')
510 self.rhodecode_user.user_id).all()]) 525 c.active = 'license'
511 526 if request.POST:
512 return render('admin/users/user_edit_my_account_pullrequests.html') 527 form_result = request.POST
513 528 try:
514 def _get_hg_ui_settings(self): 529 sett1 = RhodeCodeSetting.create_or_update('license_key',
515 ret = RhodeCodeUi.query().all() 530 form_result['rhodecode_license_key'],
516 531 'unicode')
517 if not ret: 532 Session().add(sett1)
518 raise Exception('Could not get application ui settings !') 533 Session().commit()
519 settings = {} 534 set_rhodecode_config(config)
520 for each in ret: 535 h.flash(_('Updated license information'),
521 k = each.ui_key 536 category='success')
522 v = each.ui_value 537
523 if k == '/': 538 except Exception:
524 k = 'root_path' 539 log.error(traceback.format_exc())
525 540 h.flash(_('Error occurred during updating license info'),
526 if k == 'push_ssl': 541 category='error')
527 v = str2bool(v) 542
528 543 return redirect(url('admin_settings_license'))
529 if k.find('.') != -1: 544
530 k = k.replace('.', '_') 545 defaults = RhodeCodeSetting.get_app_settings()
531 546 defaults.update(self._get_hg_ui_settings())
532 if each.ui_section in ['hooks', 'extensions']: 547
533 v = each.ui_active 548 import rhodecode
534 549 c.rhodecode_ini = rhodecode.CONFIG
535 settings[each.ui_section + '_' + k] = v 550 c.license_token = c.rhodecode_ini.get('license_token')
536 return settings 551 c.generated_license_token = LicenseModel.generate_license_token()
552 c.license_info = {}
553 c.license_loaded = False
554 # try to read info about license
555 try:
556 license_key = defaults.get('rhodecode_license_key')
557 if c.license_token and license_key:
558 c.license_info = json.loads(
559 LicenseModel(key=c.license_token).decrypt(license_key))
560 expires = h.fmt_date(h.time_to_datetime(c.license_info['valid_till']))
561 now = time.time()
562 if 0 < (c.license_info['valid_till'] - now) < 60*60*24*7:
563 h.flash(_('Your license will expire on %s, please contact '
564 'support to extend your license.' % expires), category='warning')
565 if c.license_info['valid_till'] - now < 0:
566 h.flash(_('Your license has expired on %s, please contact '
567 'support to extend your license.' % expires), category='error')
568 c.license_loaded = True
569 except Exception, e:
570 log.error(traceback.format_exc())
571 h.flash(_('Unexpected error while reading license key. Please '
572 'make sure your license token and key are correct'),
573 category='error')
574
575 return htmlfill.render(
576 render('admin/settings/settings.html'),
577 defaults=defaults,
578 encoding="UTF-8",
579 force_defaults=False)