##// END OF EJS Templates
added proper groups names in add repo from settings
marcink -
r1161:f3c25bbd beta
parent child Browse files
Show More
@@ -1,422 +1,423
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.repos
3 rhodecode.controllers.admin.repos
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Admin controller for RhodeCode
6 Admin controller for RhodeCode
7
7
8 :created_on: Apr 7, 2010
8 :created_on: Apr 7, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 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
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
16 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
27
27
28 import logging
28 import logging
29 import traceback
29 import traceback
30 import formencode
30 import formencode
31 from operator import itemgetter
31 from operator import itemgetter
32 from formencode import htmlfill
32 from formencode import htmlfill
33
33
34 from paste.httpexceptions import HTTPInternalServerError
34 from paste.httpexceptions import HTTPInternalServerError
35 from pylons import request, response, session, tmpl_context as c, url
35 from pylons import request, response, session, tmpl_context as c, url
36 from pylons.controllers.util import abort, redirect
36 from pylons.controllers.util import abort, redirect
37 from pylons.i18n.translation import _
37 from pylons.i18n.translation import _
38
38
39 from rhodecode.lib import helpers as h
39 from rhodecode.lib import helpers as h
40 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
40 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
41 HasPermissionAnyDecorator
41 HasPermissionAnyDecorator
42 from rhodecode.lib.base import BaseController, render
42 from rhodecode.lib.base import BaseController, render
43 from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug
43 from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug
44 from rhodecode.lib.helpers import get_token
44 from rhodecode.lib.helpers import get_token
45 from rhodecode.model.db import User, Repository, UserFollowing, Group
45 from rhodecode.model.db import User, Repository, UserFollowing, Group
46 from rhodecode.model.forms import RepoForm
46 from rhodecode.model.forms import RepoForm
47 from rhodecode.model.scm import ScmModel
47 from rhodecode.model.scm import ScmModel
48 from rhodecode.model.repo import RepoModel
48 from rhodecode.model.repo import RepoModel
49
49
50 log = logging.getLogger(__name__)
50 log = logging.getLogger(__name__)
51
51
52 class ReposController(BaseController):
52 class ReposController(BaseController):
53 """
53 """
54 REST Controller styled on the Atom Publishing Protocol"""
54 REST Controller styled on the Atom Publishing Protocol"""
55 # To properly map this controller, ensure your config/routing.py
55 # To properly map this controller, ensure your config/routing.py
56 # file has a resource setup:
56 # file has a resource setup:
57 # map.resource('repo', 'repos')
57 # map.resource('repo', 'repos')
58
58
59 @LoginRequired()
59 @LoginRequired()
60 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
60 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
61 def __before__(self):
61 def __before__(self):
62 c.admin_user = session.get('admin_user')
62 c.admin_user = session.get('admin_user')
63 c.admin_username = session.get('admin_username')
63 c.admin_username = session.get('admin_username')
64 super(ReposController, self).__before__()
64 super(ReposController, self).__before__()
65
65
66 def __load_defaults(self):
66 def __load_defaults(self):
67 repo_model = RepoModel()
67 repo_model = RepoModel()
68
68
69 c.repo_groups = [('', '')]
69 c.repo_groups = [('', '')]
70 parents_link = lambda k:h.literal('&raquo;'.join(
70 parents_link = lambda k:h.literal('&raquo;'.join(
71 map(lambda k:k.group_name,
71 map(lambda k:k.group_name,
72 k.parents + [k])
72 k.parents + [k])
73 )
73 )
74 )
74 )
75
75
76 c.repo_groups.extend([(x.group_id, parents_link(x)) for \
76 c.repo_groups.extend([(x.group_id, parents_link(x)) for \
77 x in self.sa.query(Group).all()])
77 x in self.sa.query(Group).all()])
78 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
78 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
79 c.users_array = repo_model.get_users_js()
79 c.users_array = repo_model.get_users_js()
80 c.users_groups_array = repo_model.get_users_groups_js()
80 c.users_groups_array = repo_model.get_users_groups_js()
81
81
82 def __load_data(self, repo_name=None):
82 def __load_data(self, repo_name=None):
83 """
83 """
84 Load defaults settings for edit, and update
84 Load defaults settings for edit, and update
85
85
86 :param repo_name:
86 :param repo_name:
87 """
87 """
88 self.__load_defaults()
88 self.__load_defaults()
89
89
90 repo, dbrepo = ScmModel().get(repo_name, retval='repo')
90 repo, dbrepo = ScmModel().get(repo_name, retval='repo')
91
91
92 repo_model = RepoModel()
92 repo_model = RepoModel()
93 c.repo_info = repo_model.get_by_repo_name(repo_name)
93 c.repo_info = repo_model.get_by_repo_name(repo_name)
94
94
95
95
96 if c.repo_info is None:
96 if c.repo_info is None:
97 h.flash(_('%s repository is not mapped to db perhaps'
97 h.flash(_('%s repository is not mapped to db perhaps'
98 ' it was created or renamed from the filesystem'
98 ' it was created or renamed from the filesystem'
99 ' please run the application again'
99 ' please run the application again'
100 ' in order to rescan repositories') % repo_name,
100 ' in order to rescan repositories') % repo_name,
101 category='error')
101 category='error')
102
102
103 return redirect(url('repos'))
103 return redirect(url('repos'))
104
104
105
105
106 c.default_user_id = User.by_username('default').user_id
106 c.default_user_id = User.by_username('default').user_id
107 c.in_public_journal = self.sa.query(UserFollowing)\
107 c.in_public_journal = self.sa.query(UserFollowing)\
108 .filter(UserFollowing.user_id == c.default_user_id)\
108 .filter(UserFollowing.user_id == c.default_user_id)\
109 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
109 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
110
110
111 if c.repo_info.stats:
111 if c.repo_info.stats:
112 last_rev = c.repo_info.stats.stat_on_revision
112 last_rev = c.repo_info.stats.stat_on_revision
113 else:
113 else:
114 last_rev = 0
114 last_rev = 0
115 c.stats_revision = last_rev
115 c.stats_revision = last_rev
116
116
117 c.repo_last_rev = repo.count() - 1 if repo.revisions else 0
117 c.repo_last_rev = repo.count() - 1 if repo.revisions else 0
118
118
119 if last_rev == 0 or c.repo_last_rev == 0:
119 if last_rev == 0 or c.repo_last_rev == 0:
120 c.stats_percentage = 0
120 c.stats_percentage = 0
121 else:
121 else:
122 c.stats_percentage = '%.2f' % ((float((last_rev)) /
122 c.stats_percentage = '%.2f' % ((float((last_rev)) /
123 c.repo_last_rev) * 100)
123 c.repo_last_rev) * 100)
124
124
125
125
126
126
127 defaults = c.repo_info.get_dict()
127 defaults = c.repo_info.get_dict()
128 group, repo_name = c.repo_info.groups_and_repo
128 group, repo_name = c.repo_info.groups_and_repo
129 defaults['repo_name'] = repo_name
129 defaults['repo_name'] = repo_name
130 defaults['repo_group'] = getattr(group[-1] if group else None, 'group_id', None)
130 defaults['repo_group'] = getattr(group[-1] if group else None,
131 'group_id', None)
131
132
132 #fill owner
133 #fill owner
133 if c.repo_info.user:
134 if c.repo_info.user:
134 defaults.update({'user':c.repo_info.user.username})
135 defaults.update({'user':c.repo_info.user.username})
135 else:
136 else:
136 replacement_user = self.sa.query(User)\
137 replacement_user = self.sa.query(User)\
137 .filter(User.admin == True).first().username
138 .filter(User.admin == True).first().username
138 defaults.update({'user':replacement_user})
139 defaults.update({'user':replacement_user})
139
140
140
141
141 #fill repository users
142 #fill repository users
142 for p in c.repo_info.repo_to_perm:
143 for p in c.repo_info.repo_to_perm:
143 defaults.update({'u_perm_%s' % p.user.username:
144 defaults.update({'u_perm_%s' % p.user.username:
144 p.permission.permission_name})
145 p.permission.permission_name})
145
146
146 #fill repository groups
147 #fill repository groups
147 for p in c.repo_info.users_group_to_perm:
148 for p in c.repo_info.users_group_to_perm:
148 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
149 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
149 p.permission.permission_name})
150 p.permission.permission_name})
150
151
151
152
152 return defaults
153 return defaults
153
154
154
155
155 @HasPermissionAllDecorator('hg.admin')
156 @HasPermissionAllDecorator('hg.admin')
156 def index(self, format='html'):
157 def index(self, format='html'):
157 """GET /repos: All items in the collection"""
158 """GET /repos: All items in the collection"""
158 # url('repos')
159 # url('repos')
159 cached_repo_list = ScmModel().get_repos()
160 cached_repo_list = ScmModel().get_repos()
160 c.repos_list = sorted(cached_repo_list, key=itemgetter('name_sort'))
161 c.repos_list = sorted(cached_repo_list, key=itemgetter('name_sort'))
161 return render('admin/repos/repos.html')
162 return render('admin/repos/repos.html')
162
163
163 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
164 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
164 def create(self):
165 def create(self):
165 """
166 """
166 POST /repos: Create a new item"""
167 POST /repos: Create a new item"""
167 # url('repos')
168 # url('repos')
168 repo_model = RepoModel()
169 repo_model = RepoModel()
169 self.__load_defaults()
170 self.__load_defaults()
170 form_result = {}
171 form_result = {}
171 try:
172 try:
172 form_result = RepoForm(repo_groups=c.repo_groups_choices)()\
173 form_result = RepoForm(repo_groups=c.repo_groups_choices)()\
173 .to_python(dict(request.POST))
174 .to_python(dict(request.POST))
174 repo_model.create(form_result, self.rhodecode_user)
175 repo_model.create(form_result, self.rhodecode_user)
175 if form_result['clone_uri']:
176 if form_result['clone_uri']:
176 h.flash(_('created repository %s from %s') \
177 h.flash(_('created repository %s from %s') \
177 % (form_result['repo_name'], form_result['clone_uri']),
178 % (form_result['repo_name'], form_result['clone_uri']),
178 category='success')
179 category='success')
179 else:
180 else:
180 h.flash(_('created repository %s') % form_result['repo_name'],
181 h.flash(_('created repository %s') % form_result['repo_name'],
181 category='success')
182 category='success')
182
183
183 if request.POST.get('user_created'):
184 if request.POST.get('user_created'):
184 action_logger(self.rhodecode_user, 'user_created_repo',
185 action_logger(self.rhodecode_user, 'user_created_repo',
185 form_result['repo_name'], '', self.sa)
186 form_result['repo_name'], '', self.sa)
186 else:
187 else:
187 action_logger(self.rhodecode_user, 'admin_created_repo',
188 action_logger(self.rhodecode_user, 'admin_created_repo',
188 form_result['repo_name'], '', self.sa)
189 form_result['repo_name'], '', self.sa)
189
190
190 except formencode.Invalid, errors:
191 except formencode.Invalid, errors:
191
192
192 c.new_repo = errors.value['repo_name']
193 c.new_repo = errors.value['repo_name']
193
194
194 if request.POST.get('user_created'):
195 if request.POST.get('user_created'):
195 r = render('admin/repos/repo_add_create_repository.html')
196 r = render('admin/repos/repo_add_create_repository.html')
196 else:
197 else:
197 r = render('admin/repos/repo_add.html')
198 r = render('admin/repos/repo_add.html')
198
199
199 return htmlfill.render(
200 return htmlfill.render(
200 r,
201 r,
201 defaults=errors.value,
202 defaults=errors.value,
202 errors=errors.error_dict or {},
203 errors=errors.error_dict or {},
203 prefix_error=False,
204 prefix_error=False,
204 encoding="UTF-8")
205 encoding="UTF-8")
205
206
206 except Exception:
207 except Exception:
207 log.error(traceback.format_exc())
208 log.error(traceback.format_exc())
208 msg = _('error occurred during creation of repository %s') \
209 msg = _('error occurred during creation of repository %s') \
209 % form_result.get('repo_name')
210 % form_result.get('repo_name')
210 h.flash(msg, category='error')
211 h.flash(msg, category='error')
211 if request.POST.get('user_created'):
212 if request.POST.get('user_created'):
212 return redirect(url('home'))
213 return redirect(url('home'))
213 return redirect(url('repos'))
214 return redirect(url('repos'))
214
215
215 @HasPermissionAllDecorator('hg.admin')
216 @HasPermissionAllDecorator('hg.admin')
216 def new(self, format='html'):
217 def new(self, format='html'):
217 """GET /repos/new: Form to create a new item"""
218 """GET /repos/new: Form to create a new item"""
218 new_repo = request.GET.get('repo', '')
219 new_repo = request.GET.get('repo', '')
219 c.new_repo = repo_name_slug(new_repo)
220 c.new_repo = repo_name_slug(new_repo)
220 self.__load_defaults()
221 self.__load_defaults()
221 return render('admin/repos/repo_add.html')
222 return render('admin/repos/repo_add.html')
222
223
223 @HasPermissionAllDecorator('hg.admin')
224 @HasPermissionAllDecorator('hg.admin')
224 def update(self, repo_name):
225 def update(self, repo_name):
225 """
226 """
226 PUT /repos/repo_name: Update an existing item"""
227 PUT /repos/repo_name: Update an existing item"""
227 # Forms posted to this method should contain a hidden field:
228 # Forms posted to this method should contain a hidden field:
228 # <input type="hidden" name="_method" value="PUT" />
229 # <input type="hidden" name="_method" value="PUT" />
229 # Or using helpers:
230 # Or using helpers:
230 # h.form(url('repo', repo_name=ID),
231 # h.form(url('repo', repo_name=ID),
231 # method='put')
232 # method='put')
232 # url('repo', repo_name=ID)
233 # url('repo', repo_name=ID)
233 self.__load_defaults()
234 self.__load_defaults()
234 repo_model = RepoModel()
235 repo_model = RepoModel()
235 changed_name = repo_name
236 changed_name = repo_name
236 _form = RepoForm(edit=True, old_data={'repo_name':repo_name},
237 _form = RepoForm(edit=True, old_data={'repo_name':repo_name},
237 repo_groups=c.repo_groups_choices)()
238 repo_groups=c.repo_groups_choices)()
238 try:
239 try:
239 form_result = _form.to_python(dict(request.POST))
240 form_result = _form.to_python(dict(request.POST))
240 repo_model.update(repo_name, form_result)
241 repo_model.update(repo_name, form_result)
241 invalidate_cache('get_repo_cached_%s' % repo_name)
242 invalidate_cache('get_repo_cached_%s' % repo_name)
242 h.flash(_('Repository %s updated successfully' % repo_name),
243 h.flash(_('Repository %s updated successfully' % repo_name),
243 category='success')
244 category='success')
244 changed_name = form_result['repo_name']
245 changed_name = form_result['repo_name']
245 action_logger(self.rhodecode_user, 'admin_updated_repo',
246 action_logger(self.rhodecode_user, 'admin_updated_repo',
246 changed_name, '', self.sa)
247 changed_name, '', self.sa)
247
248
248 except formencode.Invalid, errors:
249 except formencode.Invalid, errors:
249 defaults = self.__load_data(repo_name)
250 defaults = self.__load_data(repo_name)
250 defaults.update(errors.value)
251 defaults.update(errors.value)
251 return htmlfill.render(
252 return htmlfill.render(
252 render('admin/repos/repo_edit.html'),
253 render('admin/repos/repo_edit.html'),
253 defaults=defaults,
254 defaults=defaults,
254 errors=errors.error_dict or {},
255 errors=errors.error_dict or {},
255 prefix_error=False,
256 prefix_error=False,
256 encoding="UTF-8")
257 encoding="UTF-8")
257
258
258 except Exception:
259 except Exception:
259 log.error(traceback.format_exc())
260 log.error(traceback.format_exc())
260 h.flash(_('error occurred during update of repository %s') \
261 h.flash(_('error occurred during update of repository %s') \
261 % repo_name, category='error')
262 % repo_name, category='error')
262 return redirect(url('edit_repo', repo_name=changed_name))
263 return redirect(url('edit_repo', repo_name=changed_name))
263
264
264 @HasPermissionAllDecorator('hg.admin')
265 @HasPermissionAllDecorator('hg.admin')
265 def delete(self, repo_name):
266 def delete(self, repo_name):
266 """
267 """
267 DELETE /repos/repo_name: Delete an existing item"""
268 DELETE /repos/repo_name: Delete an existing item"""
268 # Forms posted to this method should contain a hidden field:
269 # Forms posted to this method should contain a hidden field:
269 # <input type="hidden" name="_method" value="DELETE" />
270 # <input type="hidden" name="_method" value="DELETE" />
270 # Or using helpers:
271 # Or using helpers:
271 # h.form(url('repo', repo_name=ID),
272 # h.form(url('repo', repo_name=ID),
272 # method='delete')
273 # method='delete')
273 # url('repo', repo_name=ID)
274 # url('repo', repo_name=ID)
274
275
275 repo_model = RepoModel()
276 repo_model = RepoModel()
276 repo = repo_model.get_by_repo_name(repo_name)
277 repo = repo_model.get_by_repo_name(repo_name)
277 if not repo:
278 if not repo:
278 h.flash(_('%s repository is not mapped to db perhaps'
279 h.flash(_('%s repository is not mapped to db perhaps'
279 ' it was moved or renamed from the filesystem'
280 ' it was moved or renamed from the filesystem'
280 ' please run the application again'
281 ' please run the application again'
281 ' in order to rescan repositories') % repo_name,
282 ' in order to rescan repositories') % repo_name,
282 category='error')
283 category='error')
283
284
284 return redirect(url('repos'))
285 return redirect(url('repos'))
285 try:
286 try:
286 action_logger(self.rhodecode_user, 'admin_deleted_repo',
287 action_logger(self.rhodecode_user, 'admin_deleted_repo',
287 repo_name, '', self.sa)
288 repo_name, '', self.sa)
288 repo_model.delete(repo)
289 repo_model.delete(repo)
289 invalidate_cache('get_repo_cached_%s' % repo_name)
290 invalidate_cache('get_repo_cached_%s' % repo_name)
290 h.flash(_('deleted repository %s') % repo_name, category='success')
291 h.flash(_('deleted repository %s') % repo_name, category='success')
291
292
292 except Exception, e:
293 except Exception, e:
293 log.error(traceback.format_exc())
294 log.error(traceback.format_exc())
294 h.flash(_('An error occurred during deletion of %s') % repo_name,
295 h.flash(_('An error occurred during deletion of %s') % repo_name,
295 category='error')
296 category='error')
296
297
297 return redirect(url('repos'))
298 return redirect(url('repos'))
298
299
299 @HasPermissionAllDecorator('hg.admin')
300 @HasPermissionAllDecorator('hg.admin')
300 def delete_perm_user(self, repo_name):
301 def delete_perm_user(self, repo_name):
301 """
302 """
302 DELETE an existing repository permission user
303 DELETE an existing repository permission user
303
304
304 :param repo_name:
305 :param repo_name:
305 """
306 """
306
307
307 try:
308 try:
308 repo_model = RepoModel()
309 repo_model = RepoModel()
309 repo_model.delete_perm_user(request.POST, repo_name)
310 repo_model.delete_perm_user(request.POST, repo_name)
310 except Exception, e:
311 except Exception, e:
311 h.flash(_('An error occurred during deletion of repository user'),
312 h.flash(_('An error occurred during deletion of repository user'),
312 category='error')
313 category='error')
313 raise HTTPInternalServerError()
314 raise HTTPInternalServerError()
314
315
315 @HasPermissionAllDecorator('hg.admin')
316 @HasPermissionAllDecorator('hg.admin')
316 def delete_perm_users_group(self, repo_name):
317 def delete_perm_users_group(self, repo_name):
317 """
318 """
318 DELETE an existing repository permission users group
319 DELETE an existing repository permission users group
319
320
320 :param repo_name:
321 :param repo_name:
321 """
322 """
322 try:
323 try:
323 repo_model = RepoModel()
324 repo_model = RepoModel()
324 repo_model.delete_perm_users_group(request.POST, repo_name)
325 repo_model.delete_perm_users_group(request.POST, repo_name)
325 except Exception, e:
326 except Exception, e:
326 h.flash(_('An error occurred during deletion of repository'
327 h.flash(_('An error occurred during deletion of repository'
327 ' users groups'),
328 ' users groups'),
328 category='error')
329 category='error')
329 raise HTTPInternalServerError()
330 raise HTTPInternalServerError()
330
331
331 @HasPermissionAllDecorator('hg.admin')
332 @HasPermissionAllDecorator('hg.admin')
332 def repo_stats(self, repo_name):
333 def repo_stats(self, repo_name):
333 """
334 """
334 DELETE an existing repository statistics
335 DELETE an existing repository statistics
335
336
336 :param repo_name:
337 :param repo_name:
337 """
338 """
338
339
339 try:
340 try:
340 repo_model = RepoModel()
341 repo_model = RepoModel()
341 repo_model.delete_stats(repo_name)
342 repo_model.delete_stats(repo_name)
342 except Exception, e:
343 except Exception, e:
343 h.flash(_('An error occurred during deletion of repository stats'),
344 h.flash(_('An error occurred during deletion of repository stats'),
344 category='error')
345 category='error')
345 return redirect(url('edit_repo', repo_name=repo_name))
346 return redirect(url('edit_repo', repo_name=repo_name))
346
347
347 @HasPermissionAllDecorator('hg.admin')
348 @HasPermissionAllDecorator('hg.admin')
348 def repo_cache(self, repo_name):
349 def repo_cache(self, repo_name):
349 """
350 """
350 INVALIDATE existing repository cache
351 INVALIDATE existing repository cache
351
352
352 :param repo_name:
353 :param repo_name:
353 """
354 """
354
355
355 try:
356 try:
356 ScmModel().mark_for_invalidation(repo_name)
357 ScmModel().mark_for_invalidation(repo_name)
357 except Exception, e:
358 except Exception, e:
358 h.flash(_('An error occurred during cache invalidation'),
359 h.flash(_('An error occurred during cache invalidation'),
359 category='error')
360 category='error')
360 return redirect(url('edit_repo', repo_name=repo_name))
361 return redirect(url('edit_repo', repo_name=repo_name))
361
362
362 @HasPermissionAllDecorator('hg.admin')
363 @HasPermissionAllDecorator('hg.admin')
363 def repo_public_journal(self, repo_name):
364 def repo_public_journal(self, repo_name):
364 """
365 """
365 Set's this repository to be visible in public journal,
366 Set's this repository to be visible in public journal,
366 in other words assing default user to follow this repo
367 in other words assing default user to follow this repo
367
368
368 :param repo_name:
369 :param repo_name:
369 """
370 """
370
371
371 cur_token = request.POST.get('auth_token')
372 cur_token = request.POST.get('auth_token')
372 token = get_token()
373 token = get_token()
373 if cur_token == token:
374 if cur_token == token:
374 try:
375 try:
375 repo_id = Repository.by_repo_name(repo_name).repo_id
376 repo_id = Repository.by_repo_name(repo_name).repo_id
376 user_id = User.by_username('default').user_id
377 user_id = User.by_username('default').user_id
377 self.scm_model.toggle_following_repo(repo_id, user_id)
378 self.scm_model.toggle_following_repo(repo_id, user_id)
378 h.flash(_('Updated repository visibility in public journal'),
379 h.flash(_('Updated repository visibility in public journal'),
379 category='success')
380 category='success')
380 except:
381 except:
381 h.flash(_('An error occurred during setting this'
382 h.flash(_('An error occurred during setting this'
382 ' repository in public journal'),
383 ' repository in public journal'),
383 category='error')
384 category='error')
384
385
385 else:
386 else:
386 h.flash(_('Token mismatch'), category='error')
387 h.flash(_('Token mismatch'), category='error')
387 return redirect(url('edit_repo', repo_name=repo_name))
388 return redirect(url('edit_repo', repo_name=repo_name))
388
389
389 @HasPermissionAllDecorator('hg.admin')
390 @HasPermissionAllDecorator('hg.admin')
390 def repo_pull(self, repo_name):
391 def repo_pull(self, repo_name):
391 """
392 """
392 Runs task to update given repository with remote changes,
393 Runs task to update given repository with remote changes,
393 ie. make pull on remote location
394 ie. make pull on remote location
394
395
395 :param repo_name:
396 :param repo_name:
396 """
397 """
397 try:
398 try:
398 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
399 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
399 h.flash(_('Pulled from remote location'), category='success')
400 h.flash(_('Pulled from remote location'), category='success')
400 except Exception, e:
401 except Exception, e:
401 h.flash(_('An error occurred during pull from remote location'),
402 h.flash(_('An error occurred during pull from remote location'),
402 category='error')
403 category='error')
403
404
404 return redirect(url('edit_repo', repo_name=repo_name))
405 return redirect(url('edit_repo', repo_name=repo_name))
405
406
406 @HasPermissionAllDecorator('hg.admin')
407 @HasPermissionAllDecorator('hg.admin')
407 def show(self, repo_name, format='html'):
408 def show(self, repo_name, format='html'):
408 """GET /repos/repo_name: Show a specific item"""
409 """GET /repos/repo_name: Show a specific item"""
409 # url('repo', repo_name=ID)
410 # url('repo', repo_name=ID)
410
411
411 @HasPermissionAllDecorator('hg.admin')
412 @HasPermissionAllDecorator('hg.admin')
412 def edit(self, repo_name, format='html'):
413 def edit(self, repo_name, format='html'):
413 """GET /repos/repo_name/edit: Form to edit an existing item"""
414 """GET /repos/repo_name/edit: Form to edit an existing item"""
414 # url('edit_repo', repo_name=ID)
415 # url('edit_repo', repo_name=ID)
415 defaults = self.__load_data(repo_name)
416 defaults = self.__load_data(repo_name)
416
417
417 return htmlfill.render(
418 return htmlfill.render(
418 render('admin/repos/repo_edit.html'),
419 render('admin/repos/repo_edit.html'),
419 defaults=defaults,
420 defaults=defaults,
420 encoding="UTF-8",
421 encoding="UTF-8",
421 force_defaults=False
422 force_defaults=False
422 )
423 )
@@ -1,348 +1,359
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) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 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
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
16 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
27
27
28 import logging
28 import logging
29 import traceback
29 import traceback
30 import formencode
30 import formencode
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
40 HasPermissionAnyDecorator, NotAnonymous
41 from rhodecode.lib.base import BaseController, render
41 from rhodecode.lib.base import BaseController, render
42 from rhodecode.lib.celerylib import tasks, run_task
42 from rhodecode.lib.celerylib import tasks, run_task
43 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
43 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
44 set_rhodecode_config, repo_name_slug
44 set_rhodecode_config, repo_name_slug
45 from rhodecode.model.db import RhodeCodeUi, Repository, Group
45 from rhodecode.model.db import RhodeCodeUi, Repository, Group
46 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
46 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
47 ApplicationUiSettingsForm
47 ApplicationUiSettingsForm
48 from rhodecode.model.scm import ScmModel
48 from rhodecode.model.scm import ScmModel
49 from rhodecode.model.settings import SettingsModel
49 from rhodecode.model.settings import SettingsModel
50 from rhodecode.model.user import UserModel
50 from rhodecode.model.user import UserModel
51
51
52 log = logging.getLogger(__name__)
52 log = logging.getLogger(__name__)
53
53
54
54
55 class SettingsController(BaseController):
55 class SettingsController(BaseController):
56 """REST Controller styled on the Atom Publishing Protocol"""
56 """REST Controller styled on the Atom Publishing Protocol"""
57 # To properly map this controller, ensure your config/routing.py
57 # To properly map this controller, ensure your config/routing.py
58 # file has a resource setup:
58 # file has a resource setup:
59 # map.resource('setting', 'settings', controller='admin/settings',
59 # map.resource('setting', 'settings', controller='admin/settings',
60 # path_prefix='/admin', name_prefix='admin_')
60 # path_prefix='/admin', name_prefix='admin_')
61
61
62
62
63 @LoginRequired()
63 @LoginRequired()
64 def __before__(self):
64 def __before__(self):
65 c.admin_user = session.get('admin_user')
65 c.admin_user = session.get('admin_user')
66 c.admin_username = session.get('admin_username')
66 c.admin_username = session.get('admin_username')
67 super(SettingsController, self).__before__()
67 super(SettingsController, self).__before__()
68
68
69
69
70 @HasPermissionAllDecorator('hg.admin')
70 @HasPermissionAllDecorator('hg.admin')
71 def index(self, format='html'):
71 def index(self, format='html'):
72 """GET /admin/settings: All items in the collection"""
72 """GET /admin/settings: All items in the collection"""
73 # url('admin_settings')
73 # url('admin_settings')
74
74
75 defaults = SettingsModel().get_app_settings()
75 defaults = SettingsModel().get_app_settings()
76 defaults.update(self.get_hg_ui_settings())
76 defaults.update(self.get_hg_ui_settings())
77 return htmlfill.render(
77 return htmlfill.render(
78 render('admin/settings/settings.html'),
78 render('admin/settings/settings.html'),
79 defaults=defaults,
79 defaults=defaults,
80 encoding="UTF-8",
80 encoding="UTF-8",
81 force_defaults=False
81 force_defaults=False
82 )
82 )
83
83
84 @HasPermissionAllDecorator('hg.admin')
84 @HasPermissionAllDecorator('hg.admin')
85 def create(self):
85 def create(self):
86 """POST /admin/settings: Create a new item"""
86 """POST /admin/settings: Create a new item"""
87 # url('admin_settings')
87 # url('admin_settings')
88
88
89 @HasPermissionAllDecorator('hg.admin')
89 @HasPermissionAllDecorator('hg.admin')
90 def new(self, format='html'):
90 def new(self, format='html'):
91 """GET /admin/settings/new: Form to create a new item"""
91 """GET /admin/settings/new: Form to create a new item"""
92 # url('admin_new_setting')
92 # url('admin_new_setting')
93
93
94 @HasPermissionAllDecorator('hg.admin')
94 @HasPermissionAllDecorator('hg.admin')
95 def update(self, setting_id):
95 def update(self, setting_id):
96 """PUT /admin/settings/setting_id: Update an existing item"""
96 """PUT /admin/settings/setting_id: Update an existing item"""
97 # Forms posted to this method should contain a hidden field:
97 # Forms posted to this method should contain a hidden field:
98 # <input type="hidden" name="_method" value="PUT" />
98 # <input type="hidden" name="_method" value="PUT" />
99 # Or using helpers:
99 # Or using helpers:
100 # h.form(url('admin_setting', setting_id=ID),
100 # h.form(url('admin_setting', setting_id=ID),
101 # method='put')
101 # method='put')
102 # url('admin_setting', setting_id=ID)
102 # url('admin_setting', setting_id=ID)
103 if setting_id == 'mapping':
103 if setting_id == 'mapping':
104 rm_obsolete = request.POST.get('destroy', False)
104 rm_obsolete = request.POST.get('destroy', False)
105 log.debug('Rescanning directories with destroy=%s', rm_obsolete)
105 log.debug('Rescanning directories with destroy=%s', rm_obsolete)
106 initial = ScmModel().repo_scan()
106 initial = ScmModel().repo_scan()
107 log.debug('invalidating all repositories')
107 log.debug('invalidating all repositories')
108 for repo_name in initial.keys():
108 for repo_name in initial.keys():
109 invalidate_cache('get_repo_cached_%s' % repo_name)
109 invalidate_cache('get_repo_cached_%s' % repo_name)
110
110
111 added, removed = repo2db_mapper(initial, rm_obsolete)
111 added, removed = repo2db_mapper(initial, rm_obsolete)
112
112
113 h.flash(_('Repositories successfully'
113 h.flash(_('Repositories successfully'
114 ' rescanned added: %s,removed: %s') % (added, removed)
114 ' rescanned added: %s,removed: %s') % (added, removed)
115 , category='success')
115 , category='success')
116
116
117 if setting_id == 'whoosh':
117 if setting_id == 'whoosh':
118 repo_location = self.get_hg_ui_settings()['paths_root_path']
118 repo_location = self.get_hg_ui_settings()['paths_root_path']
119 full_index = request.POST.get('full_index', False)
119 full_index = request.POST.get('full_index', False)
120 task = run_task(tasks.whoosh_index, repo_location, full_index)
120 task = run_task(tasks.whoosh_index, repo_location, full_index)
121
121
122 h.flash(_('Whoosh reindex task scheduled'), category='success')
122 h.flash(_('Whoosh reindex task scheduled'), category='success')
123 if setting_id == 'global':
123 if setting_id == 'global':
124
124
125 application_form = ApplicationSettingsForm()()
125 application_form = ApplicationSettingsForm()()
126 try:
126 try:
127 form_result = application_form.to_python(dict(request.POST))
127 form_result = application_form.to_python(dict(request.POST))
128 settings_model = SettingsModel()
128 settings_model = SettingsModel()
129
129
130 try:
130 try:
131 hgsettings1 = settings_model.get('title')
131 hgsettings1 = settings_model.get('title')
132 hgsettings1.app_settings_value = form_result['rhodecode_title']
132 hgsettings1.app_settings_value = form_result['rhodecode_title']
133
133
134 hgsettings2 = settings_model.get('realm')
134 hgsettings2 = settings_model.get('realm')
135 hgsettings2.app_settings_value = form_result['rhodecode_realm']
135 hgsettings2.app_settings_value = form_result['rhodecode_realm']
136
136
137 hgsettings3 = settings_model.get('ga_code')
137 hgsettings3 = settings_model.get('ga_code')
138 hgsettings3.app_settings_value = form_result['rhodecode_ga_code']
138 hgsettings3.app_settings_value = form_result['rhodecode_ga_code']
139
139
140
140
141
141
142 self.sa.add(hgsettings1)
142 self.sa.add(hgsettings1)
143 self.sa.add(hgsettings2)
143 self.sa.add(hgsettings2)
144 self.sa.add(hgsettings3)
144 self.sa.add(hgsettings3)
145 self.sa.commit()
145 self.sa.commit()
146 set_rhodecode_config(config)
146 set_rhodecode_config(config)
147 h.flash(_('Updated application settings'),
147 h.flash(_('Updated application settings'),
148 category='success')
148 category='success')
149
149
150 except:
150 except:
151 log.error(traceback.format_exc())
151 log.error(traceback.format_exc())
152 h.flash(_('error occurred during updating application settings'),
152 h.flash(_('error occurred during updating application settings'),
153 category='error')
153 category='error')
154
154
155 self.sa.rollback()
155 self.sa.rollback()
156
156
157
157
158 except formencode.Invalid, errors:
158 except formencode.Invalid, errors:
159 return htmlfill.render(
159 return htmlfill.render(
160 render('admin/settings/settings.html'),
160 render('admin/settings/settings.html'),
161 defaults=errors.value,
161 defaults=errors.value,
162 errors=errors.error_dict or {},
162 errors=errors.error_dict or {},
163 prefix_error=False,
163 prefix_error=False,
164 encoding="UTF-8")
164 encoding="UTF-8")
165
165
166 if setting_id == 'mercurial':
166 if setting_id == 'mercurial':
167 application_form = ApplicationUiSettingsForm()()
167 application_form = ApplicationUiSettingsForm()()
168 try:
168 try:
169 form_result = application_form.to_python(dict(request.POST))
169 form_result = application_form.to_python(dict(request.POST))
170
170
171 try:
171 try:
172
172
173 hgsettings1 = self.sa.query(RhodeCodeUi)\
173 hgsettings1 = self.sa.query(RhodeCodeUi)\
174 .filter(RhodeCodeUi.ui_key == 'push_ssl').one()
174 .filter(RhodeCodeUi.ui_key == 'push_ssl').one()
175 hgsettings1.ui_value = form_result['web_push_ssl']
175 hgsettings1.ui_value = form_result['web_push_ssl']
176
176
177 hgsettings2 = self.sa.query(RhodeCodeUi)\
177 hgsettings2 = self.sa.query(RhodeCodeUi)\
178 .filter(RhodeCodeUi.ui_key == '/').one()
178 .filter(RhodeCodeUi.ui_key == '/').one()
179 hgsettings2.ui_value = form_result['paths_root_path']
179 hgsettings2.ui_value = form_result['paths_root_path']
180
180
181
181
182 #HOOKS
182 #HOOKS
183 hgsettings3 = self.sa.query(RhodeCodeUi)\
183 hgsettings3 = self.sa.query(RhodeCodeUi)\
184 .filter(RhodeCodeUi.ui_key == 'changegroup.update').one()
184 .filter(RhodeCodeUi.ui_key == 'changegroup.update').one()
185 hgsettings3.ui_active = bool(form_result['hooks_changegroup_update'])
185 hgsettings3.ui_active = bool(form_result['hooks_changegroup_update'])
186
186
187 hgsettings4 = self.sa.query(RhodeCodeUi)\
187 hgsettings4 = self.sa.query(RhodeCodeUi)\
188 .filter(RhodeCodeUi.ui_key == 'changegroup.repo_size').one()
188 .filter(RhodeCodeUi.ui_key == 'changegroup.repo_size').one()
189 hgsettings4.ui_active = bool(form_result['hooks_changegroup_repo_size'])
189 hgsettings4.ui_active = bool(form_result['hooks_changegroup_repo_size'])
190
190
191 hgsettings5 = self.sa.query(RhodeCodeUi)\
191 hgsettings5 = self.sa.query(RhodeCodeUi)\
192 .filter(RhodeCodeUi.ui_key == 'pretxnchangegroup.push_logger').one()
192 .filter(RhodeCodeUi.ui_key == 'pretxnchangegroup.push_logger').one()
193 hgsettings5.ui_active = bool(form_result['hooks_pretxnchangegroup_push_logger'])
193 hgsettings5.ui_active = bool(form_result['hooks_pretxnchangegroup_push_logger'])
194
194
195 hgsettings6 = self.sa.query(RhodeCodeUi)\
195 hgsettings6 = self.sa.query(RhodeCodeUi)\
196 .filter(RhodeCodeUi.ui_key == 'preoutgoing.pull_logger').one()
196 .filter(RhodeCodeUi.ui_key == 'preoutgoing.pull_logger').one()
197 hgsettings6.ui_active = bool(form_result['hooks_preoutgoing_pull_logger'])
197 hgsettings6.ui_active = bool(form_result['hooks_preoutgoing_pull_logger'])
198
198
199
199
200 self.sa.add(hgsettings1)
200 self.sa.add(hgsettings1)
201 self.sa.add(hgsettings2)
201 self.sa.add(hgsettings2)
202 self.sa.add(hgsettings3)
202 self.sa.add(hgsettings3)
203 self.sa.add(hgsettings4)
203 self.sa.add(hgsettings4)
204 self.sa.add(hgsettings5)
204 self.sa.add(hgsettings5)
205 self.sa.add(hgsettings6)
205 self.sa.add(hgsettings6)
206 self.sa.commit()
206 self.sa.commit()
207
207
208 h.flash(_('Updated mercurial settings'),
208 h.flash(_('Updated mercurial settings'),
209 category='success')
209 category='success')
210
210
211 except:
211 except:
212 log.error(traceback.format_exc())
212 log.error(traceback.format_exc())
213 h.flash(_('error occurred during updating application settings'),
213 h.flash(_('error occurred during updating application settings'),
214 category='error')
214 category='error')
215
215
216 self.sa.rollback()
216 self.sa.rollback()
217
217
218
218
219 except formencode.Invalid, errors:
219 except formencode.Invalid, errors:
220 return htmlfill.render(
220 return htmlfill.render(
221 render('admin/settings/settings.html'),
221 render('admin/settings/settings.html'),
222 defaults=errors.value,
222 defaults=errors.value,
223 errors=errors.error_dict or {},
223 errors=errors.error_dict or {},
224 prefix_error=False,
224 prefix_error=False,
225 encoding="UTF-8")
225 encoding="UTF-8")
226
226
227
227
228
228
229 return redirect(url('admin_settings'))
229 return redirect(url('admin_settings'))
230
230
231 @HasPermissionAllDecorator('hg.admin')
231 @HasPermissionAllDecorator('hg.admin')
232 def delete(self, setting_id):
232 def delete(self, setting_id):
233 """DELETE /admin/settings/setting_id: Delete an existing item"""
233 """DELETE /admin/settings/setting_id: Delete an existing item"""
234 # Forms posted to this method should contain a hidden field:
234 # Forms posted to this method should contain a hidden field:
235 # <input type="hidden" name="_method" value="DELETE" />
235 # <input type="hidden" name="_method" value="DELETE" />
236 # Or using helpers:
236 # Or using helpers:
237 # h.form(url('admin_setting', setting_id=ID),
237 # h.form(url('admin_setting', setting_id=ID),
238 # method='delete')
238 # method='delete')
239 # url('admin_setting', setting_id=ID)
239 # url('admin_setting', setting_id=ID)
240
240
241 @HasPermissionAllDecorator('hg.admin')
241 @HasPermissionAllDecorator('hg.admin')
242 def show(self, setting_id, format='html'):
242 def show(self, setting_id, format='html'):
243 """GET /admin/settings/setting_id: Show a specific item"""
243 """GET /admin/settings/setting_id: Show a specific item"""
244 # url('admin_setting', setting_id=ID)
244 # url('admin_setting', setting_id=ID)
245
245
246 @HasPermissionAllDecorator('hg.admin')
246 @HasPermissionAllDecorator('hg.admin')
247 def edit(self, setting_id, format='html'):
247 def edit(self, setting_id, format='html'):
248 """GET /admin/settings/setting_id/edit: Form to edit an existing item"""
248 """GET /admin/settings/setting_id/edit: Form to edit an existing item"""
249 # url('admin_edit_setting', setting_id=ID)
249 # url('admin_edit_setting', setting_id=ID)
250
250
251 @NotAnonymous()
251 @NotAnonymous()
252 def my_account(self):
252 def my_account(self):
253 """
253 """
254 GET /_admin/my_account Displays info about my account
254 GET /_admin/my_account Displays info about my account
255 """
255 """
256 # url('admin_settings_my_account')
256 # url('admin_settings_my_account')
257
257
258 c.user = UserModel().get(self.rhodecode_user.user_id, cache=False)
258 c.user = UserModel().get(self.rhodecode_user.user_id, cache=False)
259 all_repos = [r.repo_name for r in self.sa.query(Repository)\
259 all_repos = [r.repo_name for r in self.sa.query(Repository)\
260 .filter(Repository.user_id == c.user.user_id)\
260 .filter(Repository.user_id == c.user.user_id)\
261 .order_by(func.lower(Repository.repo_name)).all()]
261 .order_by(func.lower(Repository.repo_name)).all()]
262 c.user_repos = ScmModel().get_repos(all_repos)
262 c.user_repos = ScmModel().get_repos(all_repos)
263
263
264 if c.user.username == 'default':
264 if c.user.username == 'default':
265 h.flash(_("You can't edit this user since it's"
265 h.flash(_("You can't edit this user since it's"
266 " crucial for entire application"), category='warning')
266 " crucial for entire application"), category='warning')
267 return redirect(url('users'))
267 return redirect(url('users'))
268
268
269 defaults = c.user.get_dict()
269 defaults = c.user.get_dict()
270 return htmlfill.render(
270 return htmlfill.render(
271 render('admin/users/user_edit_my_account.html'),
271 render('admin/users/user_edit_my_account.html'),
272 defaults=defaults,
272 defaults=defaults,
273 encoding="UTF-8",
273 encoding="UTF-8",
274 force_defaults=False
274 force_defaults=False
275 )
275 )
276
276
277 def my_account_update(self):
277 def my_account_update(self):
278 """PUT /_admin/my_account_update: Update an existing item"""
278 """PUT /_admin/my_account_update: Update an existing item"""
279 # Forms posted to this method should contain a hidden field:
279 # Forms posted to this method should contain a hidden field:
280 # <input type="hidden" name="_method" value="PUT" />
280 # <input type="hidden" name="_method" value="PUT" />
281 # Or using helpers:
281 # Or using helpers:
282 # h.form(url('admin_settings_my_account_update'),
282 # h.form(url('admin_settings_my_account_update'),
283 # method='put')
283 # method='put')
284 # url('admin_settings_my_account_update', id=ID)
284 # url('admin_settings_my_account_update', id=ID)
285 user_model = UserModel()
285 user_model = UserModel()
286 uid = self.rhodecode_user.user_id
286 uid = self.rhodecode_user.user_id
287 _form = UserForm(edit=True, old_data={'user_id':uid,
287 _form = UserForm(edit=True, old_data={'user_id':uid,
288 'email':self.rhodecode_user.email})()
288 'email':self.rhodecode_user.email})()
289 form_result = {}
289 form_result = {}
290 try:
290 try:
291 form_result = _form.to_python(dict(request.POST))
291 form_result = _form.to_python(dict(request.POST))
292 user_model.update_my_account(uid, form_result)
292 user_model.update_my_account(uid, form_result)
293 h.flash(_('Your account was updated successfully'),
293 h.flash(_('Your account was updated successfully'),
294 category='success')
294 category='success')
295
295
296 except formencode.Invalid, errors:
296 except formencode.Invalid, errors:
297 c.user = user_model.get(self.rhodecode_user.user_id, cache=False)
297 c.user = user_model.get(self.rhodecode_user.user_id, cache=False)
298 c.user = UserModel().get(self.rhodecode_user.user_id, cache=False)
298 c.user = UserModel().get(self.rhodecode_user.user_id, cache=False)
299 all_repos = self.sa.query(Repository)\
299 all_repos = self.sa.query(Repository)\
300 .filter(Repository.user_id == c.user.user_id)\
300 .filter(Repository.user_id == c.user.user_id)\
301 .order_by(func.lower(Repository.repo_name))\
301 .order_by(func.lower(Repository.repo_name))\
302 .all()
302 .all()
303 c.user_repos = ScmModel().get_repos(all_repos)
303 c.user_repos = ScmModel().get_repos(all_repos)
304
304
305 return htmlfill.render(
305 return htmlfill.render(
306 render('admin/users/user_edit_my_account.html'),
306 render('admin/users/user_edit_my_account.html'),
307 defaults=errors.value,
307 defaults=errors.value,
308 errors=errors.error_dict or {},
308 errors=errors.error_dict or {},
309 prefix_error=False,
309 prefix_error=False,
310 encoding="UTF-8")
310 encoding="UTF-8")
311 except Exception:
311 except Exception:
312 log.error(traceback.format_exc())
312 log.error(traceback.format_exc())
313 h.flash(_('error occurred during update of user %s') \
313 h.flash(_('error occurred during update of user %s') \
314 % form_result.get('username'), category='error')
314 % form_result.get('username'), category='error')
315
315
316 return redirect(url('my_account'))
316 return redirect(url('my_account'))
317
317
318 @NotAnonymous()
318 @NotAnonymous()
319 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
319 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
320 def create_repository(self):
320 def create_repository(self):
321 """GET /_admin/create_repository: Form to create a new item"""
321 """GET /_admin/create_repository: Form to create a new item"""
322
323 c.repo_groups = [('', '')]
324 parents_link = lambda k:h.literal('&raquo;'.join(
325 map(lambda k:k.group_name,
326 k.parents + [k])
327 )
328 )
329
330 c.repo_groups.extend([(x.group_id, parents_link(x)) for \
331 x in self.sa.query(Group).all()])
332 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
333
322 new_repo = request.GET.get('repo', '')
334 new_repo = request.GET.get('repo', '')
323 c.new_repo = repo_name_slug(new_repo)
335 c.new_repo = repo_name_slug(new_repo)
324 c.repo_groups = [('', '')]
336
325 c.repo_groups.extend([(x.group_id, x.group_name) for x in self.sa.query(Group).all()])
326 return render('admin/repos/repo_add_create_repository.html')
337 return render('admin/repos/repo_add_create_repository.html')
327
338
328 def get_hg_ui_settings(self):
339 def get_hg_ui_settings(self):
329 ret = self.sa.query(RhodeCodeUi).all()
340 ret = self.sa.query(RhodeCodeUi).all()
330
341
331 if not ret:
342 if not ret:
332 raise Exception('Could not get application ui settings !')
343 raise Exception('Could not get application ui settings !')
333 settings = {}
344 settings = {}
334 for each in ret:
345 for each in ret:
335 k = each.ui_key
346 k = each.ui_key
336 v = each.ui_value
347 v = each.ui_value
337 if k == '/':
348 if k == '/':
338 k = 'root_path'
349 k = 'root_path'
339
350
340 if k.find('.') != -1:
351 if k.find('.') != -1:
341 k = k.replace('.', '_')
352 k = k.replace('.', '_')
342
353
343 if each.ui_section == 'hooks':
354 if each.ui_section == 'hooks':
344 v = each.ui_active
355 v = each.ui_active
345
356
346 settings[each.ui_section + '_' + k] = v
357 settings[each.ui_section + '_' + k] = v
347
358
348 return settings
359 return settings
General Comments 0
You need to be logged in to leave comments. Login now