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