##// END OF EJS Templates
replaced all global calls to template context (rhodecode_user), into instance attributes
marcink -
r1121:f3f84771 beta
parent child Browse files
Show More
@@ -1,410 +1,410 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.admin.repos
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Admin controller for RhodeCode
7 7
8 8 :created_on: Apr 7, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2011 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
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27
28 28 import logging
29 29 import traceback
30 30 import formencode
31 31 from operator import itemgetter
32 32 from formencode import htmlfill
33 33
34 34 from paste.httpexceptions import HTTPInternalServerError
35 35 from pylons import request, response, session, tmpl_context as c, url
36 36 from pylons.controllers.util import abort, redirect
37 37 from pylons.i18n.translation import _
38 38
39 39 from rhodecode.lib import helpers as h
40 40 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
41 41 HasPermissionAnyDecorator
42 42 from rhodecode.lib.base import BaseController, render
43 43 from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug
44 44 from rhodecode.lib.helpers import get_token
45 45 from rhodecode.model.db import User, Repository, UserFollowing, Group
46 46 from rhodecode.model.forms import RepoForm
47 47 from rhodecode.model.scm import ScmModel
48 48 from rhodecode.model.repo import RepoModel
49 49
50 50 log = logging.getLogger(__name__)
51 51
52 52 class ReposController(BaseController):
53 53 """
54 54 REST Controller styled on the Atom Publishing Protocol"""
55 55 # To properly map this controller, ensure your config/routing.py
56 56 # file has a resource setup:
57 57 # map.resource('repo', 'repos')
58 58
59 59 @LoginRequired()
60 60 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
61 61 def __before__(self):
62 62 c.admin_user = session.get('admin_user')
63 63 c.admin_username = session.get('admin_username')
64 64 super(ReposController, self).__before__()
65 65
66 66
67 67
68 68 def __load_data(self, repo_name):
69 69 """
70 70 Load defaults settings for edit, and update
71 71
72 72 :param repo_name:
73 73 """
74 74 repo, dbrepo = ScmModel().get(repo_name, retval='repo')
75 75
76 76 repo_model = RepoModel()
77 77 c.repo_info = repo_model.get_by_repo_name(repo_name)
78 78
79 79 if c.repo_info is None:
80 80 h.flash(_('%s repository is not mapped to db perhaps'
81 81 ' it was created or renamed from the filesystem'
82 82 ' please run the application again'
83 83 ' in order to rescan repositories') % repo_name,
84 84 category='error')
85 85
86 86 return redirect(url('repos'))
87 87
88 88
89 89
90 90 c.repo_groups = [('', '')]
91 91 c.repo_groups.extend([(x.group_id, x.group_name) for x in self.sa.query(Group).all()])
92 92
93 93 c.default_user_id = User.by_username('default').user_id
94 94 c.in_public_journal = self.sa.query(UserFollowing)\
95 95 .filter(UserFollowing.user_id == c.default_user_id)\
96 96 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
97 97
98 98 if c.repo_info.stats:
99 99 last_rev = c.repo_info.stats.stat_on_revision
100 100 else:
101 101 last_rev = 0
102 102 c.stats_revision = last_rev
103 103
104 104 c.repo_last_rev = repo.count() - 1 if repo.revisions else 0
105 105
106 106 if last_rev == 0 or c.repo_last_rev == 0:
107 107 c.stats_percentage = 0
108 108 else:
109 109 c.stats_percentage = '%.2f' % ((float((last_rev)) /
110 110 c.repo_last_rev) * 100)
111 111
112 112 c.users_array = repo_model.get_users_js()
113 113 c.users_groups_array = repo_model.get_users_groups_js()
114 114
115 115 defaults = c.repo_info.get_dict()
116 116 group, repo_name = c.repo_info.groups_and_repo
117 117 defaults['repo_name'] = repo_name
118 118 defaults['repo_group'] = getattr(group, 'group_id', None)
119 119 #fill owner
120 120 if c.repo_info.user:
121 121 defaults.update({'user':c.repo_info.user.username})
122 122 else:
123 123 replacement_user = self.sa.query(User)\
124 124 .filter(User.admin == True).first().username
125 125 defaults.update({'user':replacement_user})
126 126
127 127
128 128 #fill repository users
129 129 for p in c.repo_info.repo_to_perm:
130 130 defaults.update({'u_perm_%s' % p.user.username:
131 131 p.permission.permission_name})
132 132
133 133 #fill repository groups
134 134 for p in c.repo_info.users_group_to_perm:
135 135 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
136 136 p.permission.permission_name})
137 137
138 138
139 139 return defaults
140 140
141 141
142 142 @HasPermissionAllDecorator('hg.admin')
143 143 def index(self, format='html'):
144 144 """GET /repos: All items in the collection"""
145 145 # url('repos')
146 146 cached_repo_list = ScmModel().get_repos()
147 147 c.repos_list = sorted(cached_repo_list, key=itemgetter('name_sort'))
148 148 return render('admin/repos/repos.html')
149 149
150 150 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
151 151 def create(self):
152 152 """
153 153 POST /repos: Create a new item"""
154 154 # url('repos')
155 155 repo_model = RepoModel()
156 156 c.repo_groups = [('', '')]
157 157 c.repo_groups.extend([(x.group_id, x.group_name) for x in self.sa.query(Group).all()])
158 158 form_result = {}
159 159 try:
160 160 form_result = RepoForm()(repo_groups=c.repo_groups).to_python(dict(request.POST))
161 repo_model.create(form_result, c.rhodecode_user)
161 repo_model.create(form_result, self.rhodecode_user)
162 162 if form_result['clone_uri']:
163 163 h.flash(_('created repository %s from %s') \
164 164 % (form_result['repo_name'], form_result['clone_uri']),
165 165 category='success')
166 166 else:
167 167 h.flash(_('created repository %s') % form_result['repo_name'],
168 168 category='success')
169 169
170 170 if request.POST.get('user_created'):
171 171 action_logger(self.rhodecode_user, 'user_created_repo',
172 172 form_result['repo_name'], '', self.sa)
173 173 else:
174 174 action_logger(self.rhodecode_user, 'admin_created_repo',
175 175 form_result['repo_name'], '', self.sa)
176 176
177 177 except formencode.Invalid, errors:
178 178
179 179 c.new_repo = errors.value['repo_name']
180 180 c.repo_groups = [('', '')]
181 181 c.repo_groups.extend([(x.group_id, x.group_name) for x in self.sa.query(Group).all()])
182 182
183 183 if request.POST.get('user_created'):
184 184 r = render('admin/repos/repo_add_create_repository.html')
185 185 else:
186 186 r = render('admin/repos/repo_add.html')
187 187
188 188 return htmlfill.render(
189 189 r,
190 190 defaults=errors.value,
191 191 errors=errors.error_dict or {},
192 192 prefix_error=False,
193 193 encoding="UTF-8")
194 194
195 195 except Exception:
196 196 log.error(traceback.format_exc())
197 197 msg = _('error occurred during creation of repository %s') \
198 198 % form_result.get('repo_name')
199 199 h.flash(msg, category='error')
200 200 if request.POST.get('user_created'):
201 201 return redirect(url('home'))
202 202 return redirect(url('repos'))
203 203
204 204 @HasPermissionAllDecorator('hg.admin')
205 205 def new(self, format='html'):
206 206 """GET /repos/new: Form to create a new item"""
207 207 new_repo = request.GET.get('repo', '')
208 208 c.new_repo = repo_name_slug(new_repo)
209 209 c.repo_groups = [('', '')]
210 210 c.repo_groups.extend([(x.group_id, x.group_name) for x in self.sa.query(Group).all()])
211 211 return render('admin/repos/repo_add.html')
212 212
213 213 @HasPermissionAllDecorator('hg.admin')
214 214 def update(self, repo_name):
215 215 """
216 216 PUT /repos/repo_name: Update an existing item"""
217 217 # Forms posted to this method should contain a hidden field:
218 218 # <input type="hidden" name="_method" value="PUT" />
219 219 # Or using helpers:
220 220 # h.form(url('repo', repo_name=ID),
221 221 # method='put')
222 222 # url('repo', repo_name=ID)
223 223 repo_model = RepoModel()
224 224 changed_name = repo_name
225 225 _form = RepoForm(edit=True, old_data={'repo_name':repo_name})()
226 226 try:
227 227 form_result = _form.to_python(dict(request.POST))
228 228 repo_model.update(repo_name, form_result)
229 229 invalidate_cache('get_repo_cached_%s' % repo_name)
230 230 h.flash(_('Repository %s updated successfully' % repo_name),
231 231 category='success')
232 232 changed_name = form_result['repo_name']
233 233 action_logger(self.rhodecode_user, 'admin_updated_repo',
234 234 changed_name, '', self.sa)
235 235
236 236 except formencode.Invalid, errors:
237 237 defaults = self.__load_data(repo_name)
238 238 defaults.update(errors.value)
239 239 return htmlfill.render(
240 240 render('admin/repos/repo_edit.html'),
241 241 defaults=defaults,
242 242 errors=errors.error_dict or {},
243 243 prefix_error=False,
244 244 encoding="UTF-8")
245 245
246 246 except Exception:
247 247 log.error(traceback.format_exc())
248 248 h.flash(_('error occurred during update of repository %s') \
249 249 % repo_name, category='error')
250 250 return redirect(url('edit_repo', repo_name=changed_name))
251 251
252 252 @HasPermissionAllDecorator('hg.admin')
253 253 def delete(self, repo_name):
254 254 """
255 255 DELETE /repos/repo_name: Delete an existing item"""
256 256 # Forms posted to this method should contain a hidden field:
257 257 # <input type="hidden" name="_method" value="DELETE" />
258 258 # Or using helpers:
259 259 # h.form(url('repo', repo_name=ID),
260 260 # method='delete')
261 261 # url('repo', repo_name=ID)
262 262
263 263 repo_model = RepoModel()
264 264 repo = repo_model.get_by_repo_name(repo_name)
265 265 if not repo:
266 266 h.flash(_('%s repository is not mapped to db perhaps'
267 267 ' it was moved or renamed from the filesystem'
268 268 ' please run the application again'
269 269 ' in order to rescan repositories') % repo_name,
270 270 category='error')
271 271
272 272 return redirect(url('repos'))
273 273 try:
274 274 action_logger(self.rhodecode_user, 'admin_deleted_repo',
275 275 repo_name, '', self.sa)
276 276 repo_model.delete(repo)
277 277 invalidate_cache('get_repo_cached_%s' % repo_name)
278 278 h.flash(_('deleted repository %s') % repo_name, category='success')
279 279
280 280 except Exception, e:
281 281 log.error(traceback.format_exc())
282 282 h.flash(_('An error occurred during deletion of %s') % repo_name,
283 283 category='error')
284 284
285 285 return redirect(url('repos'))
286 286
287 287 @HasPermissionAllDecorator('hg.admin')
288 288 def delete_perm_user(self, repo_name):
289 289 """
290 290 DELETE an existing repository permission user
291 291
292 292 :param repo_name:
293 293 """
294 294
295 295 try:
296 296 repo_model = RepoModel()
297 297 repo_model.delete_perm_user(request.POST, repo_name)
298 298 except Exception, e:
299 299 h.flash(_('An error occurred during deletion of repository user'),
300 300 category='error')
301 301 raise HTTPInternalServerError()
302 302
303 303 @HasPermissionAllDecorator('hg.admin')
304 304 def delete_perm_users_group(self, repo_name):
305 305 """
306 306 DELETE an existing repository permission users group
307 307
308 308 :param repo_name:
309 309 """
310 310 try:
311 311 repo_model = RepoModel()
312 312 repo_model.delete_perm_users_group(request.POST, repo_name)
313 313 except Exception, e:
314 314 h.flash(_('An error occurred during deletion of repository'
315 315 ' users groups'),
316 316 category='error')
317 317 raise HTTPInternalServerError()
318 318
319 319 @HasPermissionAllDecorator('hg.admin')
320 320 def repo_stats(self, repo_name):
321 321 """
322 322 DELETE an existing repository statistics
323 323
324 324 :param repo_name:
325 325 """
326 326
327 327 try:
328 328 repo_model = RepoModel()
329 329 repo_model.delete_stats(repo_name)
330 330 except Exception, e:
331 331 h.flash(_('An error occurred during deletion of repository stats'),
332 332 category='error')
333 333 return redirect(url('edit_repo', repo_name=repo_name))
334 334
335 335 @HasPermissionAllDecorator('hg.admin')
336 336 def repo_cache(self, repo_name):
337 337 """
338 338 INVALIDATE existing repository cache
339 339
340 340 :param repo_name:
341 341 """
342 342
343 343 try:
344 344 ScmModel().mark_for_invalidation(repo_name)
345 345 except Exception, e:
346 346 h.flash(_('An error occurred during cache invalidation'),
347 347 category='error')
348 348 return redirect(url('edit_repo', repo_name=repo_name))
349 349
350 350 @HasPermissionAllDecorator('hg.admin')
351 351 def repo_public_journal(self, repo_name):
352 352 """
353 353 Set's this repository to be visible in public journal,
354 354 in other words assing default user to follow this repo
355 355
356 356 :param repo_name:
357 357 """
358 358
359 359 cur_token = request.POST.get('auth_token')
360 360 token = get_token()
361 361 if cur_token == token:
362 362 try:
363 363 repo_id = Repository.by_repo_name(repo_name).repo_id
364 364 user_id = User.by_username('default').user_id
365 365 self.scm_model.toggle_following_repo(repo_id, user_id)
366 366 h.flash(_('Updated repository visibility in public journal'),
367 367 category='success')
368 368 except:
369 369 h.flash(_('An error occurred during setting this'
370 370 ' repository in public journal'),
371 371 category='error')
372 372
373 373 else:
374 374 h.flash(_('Token mismatch'), category='error')
375 375 return redirect(url('edit_repo', repo_name=repo_name))
376 376
377 377 @HasPermissionAllDecorator('hg.admin')
378 378 def repo_pull(self, repo_name):
379 379 """
380 380 Runs task to update given repository with remote changes,
381 381 ie. make pull on remote location
382 382
383 383 :param repo_name:
384 384 """
385 385 try:
386 ScmModel().pull_changes(repo_name, c.rhodecode_user.username)
386 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
387 387 h.flash(_('Pulled from remote location'), category='success')
388 388 except Exception, e:
389 389 h.flash(_('An error occurred during pull from remote location'),
390 390 category='error')
391 391
392 392 return redirect(url('edit_repo', repo_name=repo_name))
393 393
394 394 @HasPermissionAllDecorator('hg.admin')
395 395 def show(self, repo_name, format='html'):
396 396 """GET /repos/repo_name: Show a specific item"""
397 397 # url('repo', repo_name=ID)
398 398
399 399 @HasPermissionAllDecorator('hg.admin')
400 400 def edit(self, repo_name, format='html'):
401 401 """GET /repos/repo_name/edit: Form to edit an existing item"""
402 402 # url('edit_repo', repo_name=ID)
403 403 defaults = self.__load_data(repo_name)
404 404
405 405 return htmlfill.render(
406 406 render('admin/repos/repo_edit.html'),
407 407 defaults=defaults,
408 408 encoding="UTF-8",
409 409 force_defaults=False
410 410 )
@@ -1,348 +1,348 b''
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) 2009-2011 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
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27
28 28 import logging
29 29 import traceback
30 30 import formencode
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, Group
46 46 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
47 47 ApplicationUiSettingsForm
48 48 from rhodecode.model.scm import ScmModel
49 49 from rhodecode.model.settings import SettingsModel
50 50 from rhodecode.model.user import UserModel
51 51
52 52 log = logging.getLogger(__name__)
53 53
54 54
55 55 class SettingsController(BaseController):
56 56 """REST Controller styled on the Atom Publishing Protocol"""
57 57 # To properly map this controller, ensure your config/routing.py
58 58 # file has a resource setup:
59 59 # map.resource('setting', 'settings', controller='admin/settings',
60 60 # path_prefix='/admin', name_prefix='admin_')
61 61
62 62
63 63 @LoginRequired()
64 64 def __before__(self):
65 65 c.admin_user = session.get('admin_user')
66 66 c.admin_username = session.get('admin_username')
67 67 super(SettingsController, self).__before__()
68 68
69 69
70 70 @HasPermissionAllDecorator('hg.admin')
71 71 def index(self, format='html'):
72 72 """GET /admin/settings: All items in the collection"""
73 73 # url('admin_settings')
74 74
75 75 defaults = SettingsModel().get_app_settings()
76 76 defaults.update(self.get_hg_ui_settings())
77 77 return htmlfill.render(
78 78 render('admin/settings/settings.html'),
79 79 defaults=defaults,
80 80 encoding="UTF-8",
81 81 force_defaults=False
82 82 )
83 83
84 84 @HasPermissionAllDecorator('hg.admin')
85 85 def create(self):
86 86 """POST /admin/settings: Create a new item"""
87 87 # url('admin_settings')
88 88
89 89 @HasPermissionAllDecorator('hg.admin')
90 90 def new(self, format='html'):
91 91 """GET /admin/settings/new: Form to create a new item"""
92 92 # url('admin_new_setting')
93 93
94 94 @HasPermissionAllDecorator('hg.admin')
95 95 def update(self, setting_id):
96 96 """PUT /admin/settings/setting_id: Update an existing item"""
97 97 # Forms posted to this method should contain a hidden field:
98 98 # <input type="hidden" name="_method" value="PUT" />
99 99 # Or using helpers:
100 100 # h.form(url('admin_setting', setting_id=ID),
101 101 # method='put')
102 102 # url('admin_setting', setting_id=ID)
103 103 if setting_id == 'mapping':
104 104 rm_obsolete = request.POST.get('destroy', False)
105 105 log.debug('Rescanning directories with destroy=%s', rm_obsolete)
106 106 initial = ScmModel().repo_scan()
107 107 log.debug('invalidating all repositories')
108 108 for repo_name in initial.keys():
109 109 invalidate_cache('get_repo_cached_%s' % repo_name)
110 110
111 111 added, removed = repo2db_mapper(initial, rm_obsolete)
112 112
113 113 h.flash(_('Repositories successfully'
114 114 ' rescanned added: %s,removed: %s') % (added, removed)
115 115 , category='success')
116 116
117 117 if setting_id == 'whoosh':
118 118 repo_location = self.get_hg_ui_settings()['paths_root_path']
119 119 full_index = request.POST.get('full_index', False)
120 120 task = run_task(tasks.whoosh_index, repo_location, full_index)
121 121
122 122 h.flash(_('Whoosh reindex task scheduled'), category='success')
123 123 if setting_id == 'global':
124 124
125 125 application_form = ApplicationSettingsForm()()
126 126 try:
127 127 form_result = application_form.to_python(dict(request.POST))
128 128 settings_model = SettingsModel()
129 129
130 130 try:
131 131 hgsettings1 = settings_model.get('title')
132 132 hgsettings1.app_settings_value = form_result['rhodecode_title']
133 133
134 134 hgsettings2 = settings_model.get('realm')
135 135 hgsettings2.app_settings_value = form_result['rhodecode_realm']
136 136
137 137 hgsettings3 = settings_model.get('ga_code')
138 138 hgsettings3.app_settings_value = form_result['rhodecode_ga_code']
139 139
140 140
141 141
142 142 self.sa.add(hgsettings1)
143 143 self.sa.add(hgsettings2)
144 144 self.sa.add(hgsettings3)
145 145 self.sa.commit()
146 146 set_rhodecode_config(config)
147 147 h.flash(_('Updated application settings'),
148 148 category='success')
149 149
150 150 except:
151 151 log.error(traceback.format_exc())
152 152 h.flash(_('error occurred during updating application settings'),
153 153 category='error')
154 154
155 155 self.sa.rollback()
156 156
157 157
158 158 except formencode.Invalid, errors:
159 159 return htmlfill.render(
160 160 render('admin/settings/settings.html'),
161 161 defaults=errors.value,
162 162 errors=errors.error_dict or {},
163 163 prefix_error=False,
164 164 encoding="UTF-8")
165 165
166 166 if setting_id == 'mercurial':
167 167 application_form = ApplicationUiSettingsForm()()
168 168 try:
169 169 form_result = application_form.to_python(dict(request.POST))
170 170
171 171 try:
172 172
173 173 hgsettings1 = self.sa.query(RhodeCodeUi)\
174 174 .filter(RhodeCodeUi.ui_key == 'push_ssl').one()
175 175 hgsettings1.ui_value = form_result['web_push_ssl']
176 176
177 177 hgsettings2 = self.sa.query(RhodeCodeUi)\
178 178 .filter(RhodeCodeUi.ui_key == '/').one()
179 179 hgsettings2.ui_value = form_result['paths_root_path']
180 180
181 181
182 182 #HOOKS
183 183 hgsettings3 = self.sa.query(RhodeCodeUi)\
184 184 .filter(RhodeCodeUi.ui_key == 'changegroup.update').one()
185 185 hgsettings3.ui_active = bool(form_result['hooks_changegroup_update'])
186 186
187 187 hgsettings4 = self.sa.query(RhodeCodeUi)\
188 188 .filter(RhodeCodeUi.ui_key == 'changegroup.repo_size').one()
189 189 hgsettings4.ui_active = bool(form_result['hooks_changegroup_repo_size'])
190 190
191 191 hgsettings5 = self.sa.query(RhodeCodeUi)\
192 192 .filter(RhodeCodeUi.ui_key == 'pretxnchangegroup.push_logger').one()
193 193 hgsettings5.ui_active = bool(form_result['hooks_pretxnchangegroup_push_logger'])
194 194
195 195 hgsettings6 = self.sa.query(RhodeCodeUi)\
196 196 .filter(RhodeCodeUi.ui_key == 'preoutgoing.pull_logger').one()
197 197 hgsettings6.ui_active = bool(form_result['hooks_preoutgoing_pull_logger'])
198 198
199 199
200 200 self.sa.add(hgsettings1)
201 201 self.sa.add(hgsettings2)
202 202 self.sa.add(hgsettings3)
203 203 self.sa.add(hgsettings4)
204 204 self.sa.add(hgsettings5)
205 205 self.sa.add(hgsettings6)
206 206 self.sa.commit()
207 207
208 208 h.flash(_('Updated mercurial settings'),
209 209 category='success')
210 210
211 211 except:
212 212 log.error(traceback.format_exc())
213 213 h.flash(_('error occurred during updating application settings'),
214 214 category='error')
215 215
216 216 self.sa.rollback()
217 217
218 218
219 219 except formencode.Invalid, errors:
220 220 return htmlfill.render(
221 221 render('admin/settings/settings.html'),
222 222 defaults=errors.value,
223 223 errors=errors.error_dict or {},
224 224 prefix_error=False,
225 225 encoding="UTF-8")
226 226
227 227
228 228
229 229 return redirect(url('admin_settings'))
230 230
231 231 @HasPermissionAllDecorator('hg.admin')
232 232 def delete(self, setting_id):
233 233 """DELETE /admin/settings/setting_id: Delete an existing item"""
234 234 # Forms posted to this method should contain a hidden field:
235 235 # <input type="hidden" name="_method" value="DELETE" />
236 236 # Or using helpers:
237 237 # h.form(url('admin_setting', setting_id=ID),
238 238 # method='delete')
239 239 # url('admin_setting', setting_id=ID)
240 240
241 241 @HasPermissionAllDecorator('hg.admin')
242 242 def show(self, setting_id, format='html'):
243 243 """GET /admin/settings/setting_id: Show a specific item"""
244 244 # url('admin_setting', setting_id=ID)
245 245
246 246 @HasPermissionAllDecorator('hg.admin')
247 247 def edit(self, setting_id, format='html'):
248 248 """GET /admin/settings/setting_id/edit: Form to edit an existing item"""
249 249 # url('admin_edit_setting', setting_id=ID)
250 250
251 251 @NotAnonymous()
252 252 def my_account(self):
253 253 """
254 254 GET /_admin/my_account Displays info about my account
255 255 """
256 256 # url('admin_settings_my_account')
257 257
258 c.user = UserModel().get(c.rhodecode_user.user_id, cache=False)
258 c.user = UserModel().get(self.rhodecode_user.user_id, cache=False)
259 259 all_repos = [r.repo_name for r in self.sa.query(Repository)\
260 260 .filter(Repository.user_id == c.user.user_id)\
261 261 .order_by(func.lower(Repository.repo_name)).all()]
262 262 c.user_repos = ScmModel().get_repos(all_repos)
263 263
264 264 if c.user.username == 'default':
265 265 h.flash(_("You can't edit this user since it's"
266 266 " crucial for entire application"), category='warning')
267 267 return redirect(url('users'))
268 268
269 269 defaults = c.user.get_dict()
270 270 return htmlfill.render(
271 271 render('admin/users/user_edit_my_account.html'),
272 272 defaults=defaults,
273 273 encoding="UTF-8",
274 274 force_defaults=False
275 275 )
276 276
277 277 def my_account_update(self):
278 278 """PUT /_admin/my_account_update: Update an existing item"""
279 279 # Forms posted to this method should contain a hidden field:
280 280 # <input type="hidden" name="_method" value="PUT" />
281 281 # Or using helpers:
282 282 # h.form(url('admin_settings_my_account_update'),
283 283 # method='put')
284 284 # url('admin_settings_my_account_update', id=ID)
285 285 user_model = UserModel()
286 uid = c.rhodecode_user.user_id
286 uid = self.rhodecode_user.user_id
287 287 _form = UserForm(edit=True, old_data={'user_id':uid,
288 'email':c.rhodecode_user.email})()
288 'email':self.rhodecode_user.email})()
289 289 form_result = {}
290 290 try:
291 291 form_result = _form.to_python(dict(request.POST))
292 292 user_model.update_my_account(uid, form_result)
293 293 h.flash(_('Your account was updated successfully'),
294 294 category='success')
295 295
296 296 except formencode.Invalid, errors:
297 c.user = user_model.get(c.rhodecode_user.user_id, cache=False)
298 c.user = UserModel().get(c.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)
299 299 all_repos = self.sa.query(Repository)\
300 300 .filter(Repository.user_id == c.user.user_id)\
301 301 .order_by(func.lower(Repository.repo_name))\
302 302 .all()
303 303 c.user_repos = ScmModel().get_repos(all_repos)
304 304
305 305 return htmlfill.render(
306 306 render('admin/users/user_edit_my_account.html'),
307 307 defaults=errors.value,
308 308 errors=errors.error_dict or {},
309 309 prefix_error=False,
310 310 encoding="UTF-8")
311 311 except Exception:
312 312 log.error(traceback.format_exc())
313 313 h.flash(_('error occurred during update of user %s') \
314 314 % form_result.get('username'), category='error')
315 315
316 316 return redirect(url('my_account'))
317 317
318 318 @NotAnonymous()
319 319 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
320 320 def create_repository(self):
321 321 """GET /_admin/create_repository: Form to create a new item"""
322 322 new_repo = request.GET.get('repo', '')
323 323 c.new_repo = repo_name_slug(new_repo)
324 324 c.repo_groups = [('', '')]
325 325 c.repo_groups.extend([(x.group_id, x.group_name) for x in self.sa.query(Group).all()])
326 326 return render('admin/repos/repo_add_create_repository.html')
327 327
328 328 def get_hg_ui_settings(self):
329 329 ret = self.sa.query(RhodeCodeUi).all()
330 330
331 331 if not ret:
332 332 raise Exception('Could not get application ui settings !')
333 333 settings = {}
334 334 for each in ret:
335 335 k = each.ui_key
336 336 v = each.ui_value
337 337 if k == '/':
338 338 k = 'root_path'
339 339
340 340 if k.find('.') != -1:
341 341 k = k.replace('.', '_')
342 342
343 343 if each.ui_section == 'hooks':
344 344 v = each.ui_active
345 345
346 346 settings[each.ui_section + '_' + k] = v
347 347
348 348 return settings
@@ -1,248 +1,248 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.journal
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Journal controller for pylons
7 7
8 8 :created_on: Nov 21, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2011 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
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27 import logging
28 28
29 29 from sqlalchemy import or_
30 30 from sqlalchemy.orm import joinedload, make_transient
31 31 from webhelpers.paginate import Page
32 32 from itertools import groupby
33 33
34 34 from paste.httpexceptions import HTTPInternalServerError
35 35 from pylons import request, tmpl_context as c, response, url
36 36 from pylons.i18n.translation import _
37 37 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
38 38
39 39 import rhodecode.lib.helpers as h
40 40 from rhodecode.lib.auth import LoginRequired, NotAnonymous
41 41 from rhodecode.lib.base import BaseController, render
42 42 from rhodecode.model.db import UserLog, UserFollowing
43 43
44 44 log = logging.getLogger(__name__)
45 45
46 46 class JournalController(BaseController):
47 47
48 48
49 49
50 50 def __before__(self):
51 51 super(JournalController, self).__before__()
52 c.rhodecode_user = self.rhodecode_user
52 self.rhodecode_user = self.rhodecode_user
53 53 self.title = _('%s public journal %s feed') % (c.rhodecode_name, '%s')
54 54 self.language = 'en-us'
55 55 self.ttl = "5"
56 56 self.feed_nr = 20
57 57
58 58 @LoginRequired()
59 59 @NotAnonymous()
60 60 def index(self):
61 61 # Return a rendered template
62 62 p = int(request.params.get('page', 1))
63 63
64 64 c.following = self.sa.query(UserFollowing)\
65 65 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
66 66 .options(joinedload(UserFollowing.follows_repository))\
67 67 .all()
68 68
69 69 journal = self._get_journal_data(c.following)
70 70
71 71 c.journal_pager = Page(journal, page=p, items_per_page=20)
72 72
73 73 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
74 74
75 75 c.journal_data = render('journal/journal_data.html')
76 76 if request.params.get('partial'):
77 77 return c.journal_data
78 78 return render('journal/journal.html')
79 79
80 80
81 81 def _get_daily_aggregate(self, journal):
82 82 groups = []
83 83 for k, g in groupby(journal, lambda x:x.action_as_day):
84 84 user_group = []
85 85 for k2, g2 in groupby(list(g), lambda x:x.user.email):
86 86 l = list(g2)
87 87 user_group.append((l[0].user, l))
88 88
89 89 groups.append((k, user_group,))
90 90
91 91 return groups
92 92
93 93
94 94 def _get_journal_data(self, following_repos):
95 95 repo_ids = [x.follows_repository.repo_id for x in following_repos
96 96 if x.follows_repository is not None]
97 97 user_ids = [x.follows_user.user_id for x in following_repos
98 98 if x.follows_user is not None]
99 99
100 100 filtering_criterion = None
101 101
102 102 if repo_ids and user_ids:
103 103 filtering_criterion = or_(UserLog.repository_id.in_(repo_ids),
104 104 UserLog.user_id.in_(user_ids))
105 105 if repo_ids and not user_ids:
106 106 filtering_criterion = UserLog.repository_id.in_(repo_ids)
107 107 if not repo_ids and user_ids:
108 108 filtering_criterion = UserLog.user_id.in_(user_ids)
109 109 if filtering_criterion is not None:
110 110 journal = self.sa.query(UserLog)\
111 111 .options(joinedload(UserLog.user))\
112 112 .options(joinedload(UserLog.repository))\
113 113 .filter(filtering_criterion)\
114 114 .order_by(UserLog.action_date.desc())
115 115 else:
116 116 journal = []
117 117
118 118
119 119 return journal
120 120
121 121 @LoginRequired()
122 122 @NotAnonymous()
123 123 def toggle_following(self):
124 124 cur_token = request.POST.get('auth_token')
125 125 token = h.get_token()
126 126 if cur_token == token:
127 127
128 128 user_id = request.POST.get('follows_user_id')
129 129 if user_id:
130 130 try:
131 131 self.scm_model.toggle_following_user(user_id,
132 132 self.rhodecode_user.user_id)
133 133 return 'ok'
134 134 except:
135 135 raise HTTPInternalServerError()
136 136
137 137 repo_id = request.POST.get('follows_repo_id')
138 138 if repo_id:
139 139 try:
140 140 self.scm_model.toggle_following_repo(repo_id,
141 141 self.rhodecode_user.user_id)
142 142 return 'ok'
143 143 except:
144 144 raise HTTPInternalServerError()
145 145
146 146
147 147 log.debug('token mismatch %s vs %s', cur_token, token)
148 148 raise HTTPInternalServerError()
149 149
150 150
151 151
152 152 @LoginRequired()
153 153 def public_journal(self):
154 154 # Return a rendered template
155 155 p = int(request.params.get('page', 1))
156 156
157 157 c.following = self.sa.query(UserFollowing)\
158 158 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
159 159 .options(joinedload(UserFollowing.follows_repository))\
160 160 .all()
161 161
162 162 journal = self._get_journal_data(c.following)
163 163
164 164 c.journal_pager = Page(journal, page=p, items_per_page=20)
165 165
166 166 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
167 167
168 168 c.journal_data = render('journal/journal_data.html')
169 169 if request.params.get('partial'):
170 170 return c.journal_data
171 171 return render('journal/public_journal.html')
172 172
173 173
174 174 @LoginRequired(api_access=True)
175 175 def public_journal_atom(self):
176 176 """
177 177 Produce an atom-1.0 feed via feedgenerator module
178 178 """
179 179 c.following = self.sa.query(UserFollowing)\
180 180 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
181 181 .options(joinedload(UserFollowing.follows_repository))\
182 182 .all()
183 183
184 184 journal = self._get_journal_data(c.following)
185 185
186 186 feed = Atom1Feed(title=self.title % 'atom',
187 187 link=url('public_journal_atom', qualified=True),
188 188 description=_('Public journal'),
189 189 language=self.language,
190 190 ttl=self.ttl)
191 191
192 192 for entry in journal[:self.feed_nr]:
193 193 #tmpl = h.action_parser(entry)[0]
194 194 action, action_extra = h.action_parser(entry, feed=True)
195 195 title = "%s - %s %s" % (entry.user.short_contact, action,
196 196 entry.repository.repo_name)
197 197 desc = action_extra()
198 198 feed.add_item(title=title,
199 199 pubdate=entry.action_date,
200 200 link=url('', qualified=True),
201 201 author_email=entry.user.email,
202 202 author_name=entry.user.full_contact,
203 203 description=desc)
204 204
205 205 response.content_type = feed.mime_type
206 206 return feed.writeString('utf-8')
207 207
208 208 @LoginRequired(api_access=True)
209 209 def public_journal_rss(self):
210 210 """
211 211 Produce an rss2 feed via feedgenerator module
212 212 """
213 213 c.following = self.sa.query(UserFollowing)\
214 214 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
215 215 .options(joinedload(UserFollowing.follows_repository))\
216 216 .all()
217 217
218 218 journal = self._get_journal_data(c.following)
219 219
220 220 feed = Rss201rev2Feed(title=self.title % 'rss',
221 221 link=url('public_journal_rss', qualified=True),
222 222 description=_('Public journal'),
223 223 language=self.language,
224 224 ttl=self.ttl)
225 225
226 226 for entry in journal[:self.feed_nr]:
227 227 #tmpl = h.action_parser(entry)[0]
228 228 action, action_extra = h.action_parser(entry, feed=True)
229 229 title = "%s - %s %s" % (entry.user.short_contact, action,
230 230 entry.repository.repo_name)
231 231 desc = action_extra()
232 232 feed.add_item(title=title,
233 233 pubdate=entry.action_date,
234 234 link=url('', qualified=True),
235 235 author_email=entry.user.email,
236 236 author_name=entry.user.full_contact,
237 237 description=desc)
238 238
239 239 response.content_type = feed.mime_type
240 240 return feed.writeString('utf-8')
241 241
242 242
243 243
244 244
245 245
246 246
247 247
248 248
@@ -1,150 +1,150 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.login
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Login controller for rhodeocode
7 7
8 8 :created_on: Apr 22, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2011 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
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27
28 28 import logging
29 29 import formencode
30 30
31 31 from formencode import htmlfill
32 32
33 33 from pylons.i18n.translation import _
34 34 from pylons.controllers.util import abort, redirect
35 35 from pylons import request, response, session, tmpl_context as c, url
36 36
37 37 import rhodecode.lib.helpers as h
38 38 from rhodecode.lib.auth import AuthUser, HasPermissionAnyDecorator
39 39 from rhodecode.lib.base import BaseController, render
40 40 from rhodecode.model.forms import LoginForm, RegisterForm, PasswordResetForm
41 41 from rhodecode.model.user import UserModel
42 42
43 43
44 44 log = logging.getLogger(__name__)
45 45
46 46 class LoginController(BaseController):
47 47
48 48 def __before__(self):
49 49 super(LoginController, self).__before__()
50 50
51 51 def index(self):
52 52 #redirect if already logged in
53 53 c.came_from = request.GET.get('came_from', None)
54 54
55 if c.rhodecode_user.is_authenticated \
56 and c.rhodecode_user.username != 'default':
55 if self.rhodecode_user.is_authenticated \
56 and self.rhodecode_user.username != 'default':
57 57
58 58 return redirect(url('home'))
59 59
60 60 if request.POST:
61 61 #import Login Form validator class
62 62 login_form = LoginForm()
63 63 try:
64 64 c.form_result = login_form.to_python(dict(request.POST))
65 65 #form checks for username/password, now we're authenticated
66 66 username = c.form_result['username']
67 67 user = UserModel().get_by_username(username,
68 68 case_insensitive=True)
69 69 auth_user = AuthUser(user.user_id)
70 70 auth_user.set_authenticated()
71 71 session['rhodecode_user'] = auth_user
72 72 session.save()
73 73
74 74 log.info('user %s is now authenticated and stored in session',
75 75 username)
76 76 user.update_lastlogin()
77 77
78 78 if c.came_from:
79 79 return redirect(c.came_from)
80 80 else:
81 81 return redirect(url('home'))
82 82
83 83 except formencode.Invalid, errors:
84 84 return htmlfill.render(
85 85 render('/login.html'),
86 86 defaults=errors.value,
87 87 errors=errors.error_dict or {},
88 88 prefix_error=False,
89 89 encoding="UTF-8")
90 90
91 91 return render('/login.html')
92 92
93 93 @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
94 94 'hg.register.manual_activate')
95 95 def register(self):
96 96 user_model = UserModel()
97 97 c.auto_active = False
98 98 for perm in user_model.get_by_username('default', cache=False).user_perms:
99 99 if perm.permission.permission_name == 'hg.register.auto_activate':
100 100 c.auto_active = True
101 101 break
102 102
103 103 if request.POST:
104 104
105 105 register_form = RegisterForm()()
106 106 try:
107 107 form_result = register_form.to_python(dict(request.POST))
108 108 form_result['active'] = c.auto_active
109 109 user_model.create_registration(form_result)
110 110 h.flash(_('You have successfully registered into rhodecode'),
111 111 category='success')
112 112 return redirect(url('login_home'))
113 113
114 114 except formencode.Invalid, errors:
115 115 return htmlfill.render(
116 116 render('/register.html'),
117 117 defaults=errors.value,
118 118 errors=errors.error_dict or {},
119 119 prefix_error=False,
120 120 encoding="UTF-8")
121 121
122 122 return render('/register.html')
123 123
124 124 def password_reset(self):
125 125 user_model = UserModel()
126 126 if request.POST:
127 127
128 128 password_reset_form = PasswordResetForm()()
129 129 try:
130 130 form_result = password_reset_form.to_python(dict(request.POST))
131 131 user_model.reset_password(form_result)
132 132 h.flash(_('Your new password was sent'),
133 133 category='success')
134 134 return redirect(url('login_home'))
135 135
136 136 except formencode.Invalid, errors:
137 137 return htmlfill.render(
138 138 render('/password_reset.html'),
139 139 defaults=errors.value,
140 140 errors=errors.error_dict or {},
141 141 prefix_error=False,
142 142 encoding="UTF-8")
143 143
144 144 return render('/password_reset.html')
145 145
146 146 def logout(self):
147 147 del session['rhodecode_user']
148 148 session.save()
149 149 log.info('Logging out and setting user as Empty')
150 150 redirect(url('home'))
@@ -1,209 +1,209 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.settings
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Settings controller for rhodecode
7 7
8 8 :created_on: Jun 30, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2011 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
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27
28 28 import logging
29 29 import traceback
30 30 import formencode
31 31
32 32 from formencode import htmlfill
33 33
34 34 from pylons import tmpl_context as c, request, url
35 35 from pylons.controllers.util import redirect
36 36 from pylons.i18n.translation import _
37 37
38 38 import rhodecode.lib.helpers as h
39 39
40 40 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator, \
41 41 HasRepoPermissionAnyDecorator, NotAnonymous
42 42 from rhodecode.lib.base import BaseRepoController, render
43 43 from rhodecode.lib.utils import invalidate_cache, action_logger
44 44
45 45 from rhodecode.model.forms import RepoSettingsForm, RepoForkForm
46 46 from rhodecode.model.repo import RepoModel
47 47 from rhodecode.model.db import User
48 48
49 49 log = logging.getLogger(__name__)
50 50
51 51 class SettingsController(BaseRepoController):
52 52
53 53 @LoginRequired()
54 54 def __before__(self):
55 55 super(SettingsController, self).__before__()
56 56
57 57 @HasRepoPermissionAllDecorator('repository.admin')
58 58 def index(self, repo_name):
59 59 repo_model = RepoModel()
60 60 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
61 61 if not repo:
62 62 h.flash(_('%s repository is not mapped to db perhaps'
63 63 ' it was created or renamed from the file system'
64 64 ' please run the application again'
65 65 ' in order to rescan repositories') % repo_name,
66 66 category='error')
67 67
68 68 return redirect(url('home'))
69 69
70 70 c.users_array = repo_model.get_users_js()
71 71 c.users_groups_array = repo_model.get_users_groups_js()
72 72
73 73 defaults = c.repo_info.get_dict()
74 74
75 75 #fill owner
76 76 if c.repo_info.user:
77 77 defaults.update({'user':c.repo_info.user.username})
78 78 else:
79 79 replacement_user = self.sa.query(User)\
80 80 .filter(User.admin == True).first().username
81 81 defaults.update({'user':replacement_user})
82 82
83 83 #fill repository users
84 84 for p in c.repo_info.repo_to_perm:
85 85 defaults.update({'u_perm_%s' % p.user.username:
86 86 p.permission.permission_name})
87 87
88 88 #fill repository groups
89 89 for p in c.repo_info.users_group_to_perm:
90 90 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
91 91 p.permission.permission_name})
92 92
93 93 return htmlfill.render(
94 94 render('settings/repo_settings.html'),
95 95 defaults=defaults,
96 96 encoding="UTF-8",
97 97 force_defaults=False
98 98 )
99 99
100 100 @HasRepoPermissionAllDecorator('repository.admin')
101 101 def update(self, repo_name):
102 102 repo_model = RepoModel()
103 103 changed_name = repo_name
104 104 _form = RepoSettingsForm(edit=True, old_data={'repo_name':repo_name})()
105 105 try:
106 106 form_result = _form.to_python(dict(request.POST))
107 107 repo_model.update(repo_name, form_result)
108 108 invalidate_cache('get_repo_cached_%s' % repo_name)
109 109 h.flash(_('Repository %s updated successfully' % repo_name),
110 110 category='success')
111 111 changed_name = form_result['repo_name']
112 112 action_logger(self.rhodecode_user, 'user_updated_repo',
113 113 changed_name, '', self.sa)
114 114 except formencode.Invalid, errors:
115 115 c.repo_info = repo_model.get_by_repo_name(repo_name)
116 116 c.users_array = repo_model.get_users_js()
117 117 errors.value.update({'user':c.repo_info.user.username})
118 118 return htmlfill.render(
119 119 render('settings/repo_settings.html'),
120 120 defaults=errors.value,
121 121 errors=errors.error_dict or {},
122 122 prefix_error=False,
123 123 encoding="UTF-8")
124 124 except Exception:
125 125 log.error(traceback.format_exc())
126 126 h.flash(_('error occurred during update of repository %s') \
127 127 % repo_name, category='error')
128 128
129 129 return redirect(url('repo_settings_home', repo_name=changed_name))
130 130
131 131
132 132 @HasRepoPermissionAllDecorator('repository.admin')
133 133 def delete(self, repo_name):
134 134 """DELETE /repos/repo_name: Delete an existing item"""
135 135 # Forms posted to this method should contain a hidden field:
136 136 # <input type="hidden" name="_method" value="DELETE" />
137 137 # Or using helpers:
138 138 # h.form(url('repo_settings_delete', repo_name=ID),
139 139 # method='delete')
140 140 # url('repo_settings_delete', repo_name=ID)
141 141
142 142 repo_model = RepoModel()
143 143 repo = repo_model.get_by_repo_name(repo_name)
144 144 if not repo:
145 145 h.flash(_('%s repository is not mapped to db perhaps'
146 146 ' it was moved or renamed from the filesystem'
147 147 ' please run the application again'
148 148 ' in order to rescan repositories') % repo_name,
149 149 category='error')
150 150
151 151 return redirect(url('home'))
152 152 try:
153 153 action_logger(self.rhodecode_user, 'user_deleted_repo',
154 154 repo_name, '', self.sa)
155 155 repo_model.delete(repo)
156 156 invalidate_cache('get_repo_cached_%s' % repo_name)
157 157 h.flash(_('deleted repository %s') % repo_name, category='success')
158 158 except Exception:
159 159 h.flash(_('An error occurred during deletion of %s') % repo_name,
160 160 category='error')
161 161
162 162 return redirect(url('home'))
163 163
164 164 @NotAnonymous()
165 165 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
166 166 'repository.admin')
167 167 def fork(self, repo_name):
168 168 repo_model = RepoModel()
169 169 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
170 170 if not repo:
171 171 h.flash(_('%s repository is not mapped to db perhaps'
172 172 ' it was created or renamed from the file system'
173 173 ' please run the application again'
174 174 ' in order to rescan repositories') % repo_name,
175 175 category='error')
176 176
177 177 return redirect(url('home'))
178 178
179 179 return render('settings/repo_fork.html')
180 180
181 181 @NotAnonymous()
182 182 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
183 183 'repository.admin')
184 184 def fork_create(self, repo_name):
185 185 repo_model = RepoModel()
186 186 c.repo_info = repo_model.get_by_repo_name(repo_name)
187 187 _form = RepoForkForm(old_data={'repo_type':c.repo_info.repo_type})()
188 188 form_result = {}
189 189 try:
190 190 form_result = _form.to_python(dict(request.POST))
191 191 form_result.update({'repo_name':repo_name})
192 repo_model.create_fork(form_result, c.rhodecode_user)
192 repo_model.create_fork(form_result, self.rhodecode_user)
193 193 h.flash(_('forked %s repository as %s') \
194 194 % (repo_name, form_result['fork_name']),
195 195 category='success')
196 196 action_logger(self.rhodecode_user,
197 197 'user_forked_repo:%s' % form_result['fork_name'],
198 198 repo_name, '', self.sa)
199 199 except formencode.Invalid, errors:
200 200 c.new_repo = errors.value['fork_name']
201 201 r = render('settings/repo_fork.html')
202 202
203 203 return htmlfill.render(
204 204 r,
205 205 defaults=errors.value,
206 206 errors=errors.error_dict or {},
207 207 prefix_error=False,
208 208 encoding="UTF-8")
209 209 return redirect(url('home'))
@@ -1,169 +1,169 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.summary
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Summary controller for Rhodecode
7 7
8 8 :created_on: Apr 18, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2011 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
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27
28 28 import calendar
29 29 import logging
30 30 from time import mktime
31 31 from datetime import datetime, timedelta, date
32 32
33 33 from vcs.exceptions import ChangesetError
34 34
35 35 from pylons import tmpl_context as c, request, url
36 36 from pylons.i18n.translation import _
37 37
38 38 from rhodecode.model.db import Statistics
39 39
40 40 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
41 41 from rhodecode.lib.base import BaseRepoController, render
42 42 from rhodecode.lib.utils import OrderedDict, EmptyChangeset
43 43
44 44 from rhodecode.lib.celerylib import run_task
45 45 from rhodecode.lib.celerylib.tasks import get_commits_stats
46 46 from rhodecode.lib.helpers import RepoPage
47 47
48 48 try:
49 49 import json
50 50 except ImportError:
51 51 #python 2.5 compatibility
52 52 import simplejson as json
53 53 log = logging.getLogger(__name__)
54 54
55 55 class SummaryController(BaseRepoController):
56 56
57 57 @LoginRequired()
58 58 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
59 59 'repository.admin')
60 60 def __before__(self):
61 61 super(SummaryController, self).__before__()
62 62
63 63 def index(self):
64 64 c.repo, dbrepo = self.scm_model.get(c.repo_name)
65 65 c.dbrepo = dbrepo
66 66
67 67 c.following = self.scm_model.is_following_repo(c.repo_name,
68 c.rhodecode_user.user_id)
68 self.rhodecode_user.user_id)
69 69 def url_generator(**kw):
70 70 return url('shortlog_home', repo_name=c.repo_name, **kw)
71 71
72 72 c.repo_changesets = RepoPage(c.repo, page=1, items_per_page=10,
73 73 url=url_generator)
74 74
75 75 e = request.environ
76 76
77 77 if self.rhodecode_user.username == 'default':
78 78 #for default(anonymous) user we don't need to pass credentials
79 79 username = ''
80 80 password = ''
81 81 else:
82 username = str(c.rhodecode_user.username)
82 username = str(self.rhodecode_user.username)
83 83 password = '@'
84 84
85 85 uri = u'%(protocol)s://%(user)s%(password)s%(host)s%(prefix)s/%(repo_name)s' % {
86 86 'protocol': e.get('wsgi.url_scheme'),
87 87 'user':username,
88 88 'password':password,
89 89 'host':e.get('HTTP_HOST'),
90 90 'prefix':e.get('SCRIPT_NAME'),
91 91 'repo_name':c.repo_name, }
92 92 c.clone_repo_url = uri
93 93 c.repo_tags = OrderedDict()
94 94 for name, hash in c.repo.tags.items()[:10]:
95 95 try:
96 96 c.repo_tags[name] = c.repo.get_changeset(hash)
97 97 except ChangesetError:
98 98 c.repo_tags[name] = EmptyChangeset(hash)
99 99
100 100 c.repo_branches = OrderedDict()
101 101 for name, hash in c.repo.branches.items()[:10]:
102 102 try:
103 103 c.repo_branches[name] = c.repo.get_changeset(hash)
104 104 except ChangesetError:
105 105 c.repo_branches[name] = EmptyChangeset(hash)
106 106
107 107 td = date.today() + timedelta(days=1)
108 108 td_1m = td - timedelta(days=calendar.mdays[td.month])
109 109 td_1y = td - timedelta(days=365)
110 110
111 111 ts_min_m = mktime(td_1m.timetuple())
112 112 ts_min_y = mktime(td_1y.timetuple())
113 113 ts_max_y = mktime(td.timetuple())
114 114
115 115 if dbrepo.enable_statistics:
116 116 c.no_data_msg = _('No data loaded yet')
117 117 run_task(get_commits_stats, c.repo.name, ts_min_y, ts_max_y)
118 118 else:
119 119 c.no_data_msg = _('Statistics are disabled for this repository')
120 120 c.ts_min = ts_min_m
121 121 c.ts_max = ts_max_y
122 122
123 123 stats = self.sa.query(Statistics)\
124 124 .filter(Statistics.repository == dbrepo)\
125 125 .scalar()
126 126
127 127
128 128 if stats and stats.languages:
129 129 c.no_data = False is dbrepo.enable_statistics
130 130 lang_stats = json.loads(stats.languages)
131 131 c.commit_data = stats.commit_activity
132 132 c.overview_data = stats.commit_activity_combined
133 133 c.trending_languages = json.dumps(OrderedDict(
134 134 sorted(lang_stats.items(), reverse=True,
135 135 key=lambda k: k[1])[:10]
136 136 )
137 137 )
138 138 else:
139 139 c.commit_data = json.dumps({})
140 140 c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10] ])
141 141 c.trending_languages = json.dumps({})
142 142 c.no_data = True
143 143
144 144 c.enable_downloads = dbrepo.enable_downloads
145 145 if c.enable_downloads:
146 146 c.download_options = self._get_download_links(c.repo)
147 147
148 148 return render('summary/summary.html')
149 149
150 150
151 151
152 152 def _get_download_links(self, repo):
153 153
154 154 download_l = []
155 155
156 156 branches_group = ([], _("Branches"))
157 157 tags_group = ([], _("Tags"))
158 158
159 159 for name, chs in c.rhodecode_repo.branches.items():
160 160 #chs = chs.split(':')[-1]
161 161 branches_group[0].append((chs, name),)
162 162 download_l.append(branches_group)
163 163
164 164 for name, chs in c.rhodecode_repo.tags.items():
165 165 #chs = chs.split(':')[-1]
166 166 tags_group[0].append((chs, name),)
167 167 download_l.append(tags_group)
168 168
169 169 return download_l
General Comments 0
You need to be logged in to leave comments. Login now