##// END OF EJS Templates
user lowernames of repos for better sorting
marcink -
r2935:20c0af65 beta
parent child Browse files
Show More
@@ -1,509 +1,510 b''
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 Repositories controller for RhodeCode
6 Repositories 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) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28 import formencode
28 import formencode
29 from formencode import htmlfill
29 from formencode import htmlfill
30
30
31 from webob.exc import HTTPInternalServerError
31 from webob.exc import HTTPInternalServerError
32 from pylons import request, session, tmpl_context as c, url
32 from pylons import request, session, tmpl_context as c, url
33 from pylons.controllers.util import redirect
33 from pylons.controllers.util import redirect
34 from pylons.i18n.translation import _
34 from pylons.i18n.translation import _
35 from sqlalchemy.exc import IntegrityError
35 from sqlalchemy.exc import IntegrityError
36
36
37 import rhodecode
37 import rhodecode
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, HasRepoPermissionAllDecorator
40 HasPermissionAnyDecorator, HasRepoPermissionAllDecorator
41 from rhodecode.lib.base import BaseController, render
41 from rhodecode.lib.base import BaseController, render
42 from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug
42 from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug
43 from rhodecode.lib.helpers import get_token
43 from rhodecode.lib.helpers import get_token
44 from rhodecode.model.meta import Session
44 from rhodecode.model.meta import Session
45 from rhodecode.model.db import User, Repository, UserFollowing, RepoGroup
45 from rhodecode.model.db import User, Repository, UserFollowing, RepoGroup
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 from rhodecode.lib.compat import json
49 from rhodecode.lib.compat import json
50 from sqlalchemy.sql.expression import func
50
51
51 log = logging.getLogger(__name__)
52 log = logging.getLogger(__name__)
52
53
53
54
54 class ReposController(BaseController):
55 class ReposController(BaseController):
55 """
56 """
56 REST Controller styled on the Atom Publishing Protocol"""
57 REST Controller styled on the Atom Publishing Protocol"""
57 # To properly map this controller, ensure your config/routing.py
58 # To properly map this controller, ensure your config/routing.py
58 # file has a resource setup:
59 # file has a resource setup:
59 # map.resource('repo', 'repos')
60 # map.resource('repo', 'repos')
60
61
61 @LoginRequired()
62 @LoginRequired()
62 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
63 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
63 def __before__(self):
64 def __before__(self):
64 c.admin_user = session.get('admin_user')
65 c.admin_user = session.get('admin_user')
65 c.admin_username = session.get('admin_username')
66 c.admin_username = session.get('admin_username')
66 super(ReposController, self).__before__()
67 super(ReposController, self).__before__()
67
68
68 def __load_defaults(self):
69 def __load_defaults(self):
69 c.repo_groups = RepoGroup.groups_choices(check_perms=True)
70 c.repo_groups = RepoGroup.groups_choices(check_perms=True)
70 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
71 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
71
72
72 repo_model = RepoModel()
73 repo_model = RepoModel()
73 c.users_array = repo_model.get_users_js()
74 c.users_array = repo_model.get_users_js()
74 c.users_groups_array = repo_model.get_users_groups_js()
75 c.users_groups_array = repo_model.get_users_groups_js()
75 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
76 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
76 c.landing_revs_choices = choices
77 c.landing_revs_choices = choices
77
78
78 def __load_data(self, repo_name=None):
79 def __load_data(self, repo_name=None):
79 """
80 """
80 Load defaults settings for edit, and update
81 Load defaults settings for edit, and update
81
82
82 :param repo_name:
83 :param repo_name:
83 """
84 """
84 self.__load_defaults()
85 self.__load_defaults()
85
86
86 c.repo_info = db_repo = Repository.get_by_repo_name(repo_name)
87 c.repo_info = db_repo = Repository.get_by_repo_name(repo_name)
87 repo = db_repo.scm_instance
88 repo = db_repo.scm_instance
88
89
89 if c.repo_info is None:
90 if c.repo_info is None:
90 h.flash(_('%s repository is not mapped to db perhaps'
91 h.flash(_('%s repository is not mapped to db perhaps'
91 ' it was created or renamed from the filesystem'
92 ' it was created or renamed from the filesystem'
92 ' please run the application again'
93 ' please run the application again'
93 ' in order to rescan repositories') % repo_name,
94 ' in order to rescan repositories') % repo_name,
94 category='error')
95 category='error')
95
96
96 return redirect(url('repos'))
97 return redirect(url('repos'))
97
98
98 choices, c.landing_revs = ScmModel().get_repo_landing_revs(c.repo_info)
99 choices, c.landing_revs = ScmModel().get_repo_landing_revs(c.repo_info)
99 c.landing_revs_choices = choices
100 c.landing_revs_choices = choices
100
101
101 c.default_user_id = User.get_by_username('default').user_id
102 c.default_user_id = User.get_by_username('default').user_id
102 c.in_public_journal = UserFollowing.query()\
103 c.in_public_journal = UserFollowing.query()\
103 .filter(UserFollowing.user_id == c.default_user_id)\
104 .filter(UserFollowing.user_id == c.default_user_id)\
104 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
105 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
105
106
106 if c.repo_info.stats:
107 if c.repo_info.stats:
107 # this is on what revision we ended up so we add +1 for count
108 # this is on what revision we ended up so we add +1 for count
108 last_rev = c.repo_info.stats.stat_on_revision + 1
109 last_rev = c.repo_info.stats.stat_on_revision + 1
109 else:
110 else:
110 last_rev = 0
111 last_rev = 0
111 c.stats_revision = last_rev
112 c.stats_revision = last_rev
112
113
113 c.repo_last_rev = repo.count() if repo.revisions else 0
114 c.repo_last_rev = repo.count() if repo.revisions else 0
114
115
115 if last_rev == 0 or c.repo_last_rev == 0:
116 if last_rev == 0 or c.repo_last_rev == 0:
116 c.stats_percentage = 0
117 c.stats_percentage = 0
117 else:
118 else:
118 c.stats_percentage = '%.2f' % ((float((last_rev)) /
119 c.stats_percentage = '%.2f' % ((float((last_rev)) /
119 c.repo_last_rev) * 100)
120 c.repo_last_rev) * 100)
120
121
121 defaults = RepoModel()._get_defaults(repo_name)
122 defaults = RepoModel()._get_defaults(repo_name)
122
123
123 c.repos_list = [('', _('--REMOVE FORK--'))]
124 c.repos_list = [('', _('--REMOVE FORK--'))]
124 c.repos_list += [(x.repo_id, x.repo_name) for x in
125 c.repos_list += [(x.repo_id, x.repo_name) for x in
125 Repository.query().order_by(Repository.repo_name).all()
126 Repository.query().order_by(Repository.repo_name).all()
126 if x.repo_id != c.repo_info.repo_id]
127 if x.repo_id != c.repo_info.repo_id]
127
128
128 defaults['id_fork_of'] = db_repo.fork.repo_id if db_repo.fork else ''
129 defaults['id_fork_of'] = db_repo.fork.repo_id if db_repo.fork else ''
129 return defaults
130 return defaults
130
131
131 @HasPermissionAllDecorator('hg.admin')
132 @HasPermissionAllDecorator('hg.admin')
132 def index(self, format='html'):
133 def index(self, format='html'):
133 """GET /repos: All items in the collection"""
134 """GET /repos: All items in the collection"""
134 # url('repos')
135 # url('repos')
135
136
136 c.repos_list = Repository.query()\
137 c.repos_list = Repository.query()\
137 .order_by(Repository.repo_name)\
138 .order_by(func.lower(Repository.repo_name))\
138 .all()
139 .all()
139
140
140 repos_data = []
141 repos_data = []
141 total_records = len(c.repos_list)
142 total_records = len(c.repos_list)
142
143
143 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
144 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
144 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
145 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
145
146
146 quick_menu = lambda repo_name: (template.get_def("quick_menu")
147 quick_menu = lambda repo_name: (template.get_def("quick_menu")
147 .render(repo_name, _=_, h=h, c=c))
148 .render(repo_name, _=_, h=h, c=c))
148 repo_lnk = lambda name, rtype, private, fork_of: (
149 repo_lnk = lambda name, rtype, private, fork_of: (
149 template.get_def("repo_name")
150 template.get_def("repo_name")
150 .render(name, rtype, private, fork_of, short_name=False,
151 .render(name, rtype, private, fork_of, short_name=False,
151 admin=True, _=_, h=h, c=c))
152 admin=True, _=_, h=h, c=c))
152
153
153 repo_actions = lambda repo_name: (template.get_def("repo_actions")
154 repo_actions = lambda repo_name: (template.get_def("repo_actions")
154 .render(repo_name, _=_, h=h, c=c))
155 .render(repo_name, _=_, h=h, c=c))
155
156
156 for repo in c.repos_list:
157 for repo in c.repos_list:
157 repos_data.append({
158 repos_data.append({
158 "menu": quick_menu(repo.repo_name),
159 "menu": quick_menu(repo.repo_name),
159 "raw_name": repo.repo_name,
160 "raw_name": repo.repo_name.lower(),
160 "name": repo_lnk(repo.repo_name, repo.repo_type,
161 "name": repo_lnk(repo.repo_name, repo.repo_type,
161 repo.private, repo.fork),
162 repo.private, repo.fork),
162 "desc": repo.description,
163 "desc": repo.description,
163 "owner": repo.user.username,
164 "owner": repo.user.username,
164 "action": repo_actions(repo.repo_name),
165 "action": repo_actions(repo.repo_name),
165 })
166 })
166
167
167 c.data = json.dumps({
168 c.data = json.dumps({
168 "totalRecords": total_records,
169 "totalRecords": total_records,
169 "startIndex": 0,
170 "startIndex": 0,
170 "sort": "name",
171 "sort": "name",
171 "dir": "asc",
172 "dir": "asc",
172 "records": repos_data
173 "records": repos_data
173 })
174 })
174
175
175 return render('admin/repos/repos.html')
176 return render('admin/repos/repos.html')
176
177
177 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
178 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
178 def create(self):
179 def create(self):
179 """
180 """
180 POST /repos: Create a new item"""
181 POST /repos: Create a new item"""
181 # url('repos')
182 # url('repos')
182
183
183 self.__load_defaults()
184 self.__load_defaults()
184 form_result = {}
185 form_result = {}
185 try:
186 try:
186 form_result = RepoForm(repo_groups=c.repo_groups_choices,
187 form_result = RepoForm(repo_groups=c.repo_groups_choices,
187 landing_revs=c.landing_revs_choices)()\
188 landing_revs=c.landing_revs_choices)()\
188 .to_python(dict(request.POST))
189 .to_python(dict(request.POST))
189 new_repo = RepoModel().create(form_result,
190 new_repo = RepoModel().create(form_result,
190 self.rhodecode_user.user_id)
191 self.rhodecode_user.user_id)
191 if form_result['clone_uri']:
192 if form_result['clone_uri']:
192 h.flash(_('created repository %s from %s') \
193 h.flash(_('created repository %s from %s') \
193 % (form_result['repo_name'], form_result['clone_uri']),
194 % (form_result['repo_name'], form_result['clone_uri']),
194 category='success')
195 category='success')
195 else:
196 else:
196 h.flash(_('created repository %s') % form_result['repo_name'],
197 h.flash(_('created repository %s') % form_result['repo_name'],
197 category='success')
198 category='success')
198
199
199 if request.POST.get('user_created'):
200 if request.POST.get('user_created'):
200 # created by regular non admin user
201 # created by regular non admin user
201 action_logger(self.rhodecode_user, 'user_created_repo',
202 action_logger(self.rhodecode_user, 'user_created_repo',
202 form_result['repo_name_full'], self.ip_addr,
203 form_result['repo_name_full'], self.ip_addr,
203 self.sa)
204 self.sa)
204 else:
205 else:
205 action_logger(self.rhodecode_user, 'admin_created_repo',
206 action_logger(self.rhodecode_user, 'admin_created_repo',
206 form_result['repo_name_full'], self.ip_addr,
207 form_result['repo_name_full'], self.ip_addr,
207 self.sa)
208 self.sa)
208 Session().commit()
209 Session().commit()
209 except formencode.Invalid, errors:
210 except formencode.Invalid, errors:
210
211
211 c.new_repo = errors.value['repo_name']
212 c.new_repo = errors.value['repo_name']
212
213
213 if request.POST.get('user_created'):
214 if request.POST.get('user_created'):
214 r = render('admin/repos/repo_add_create_repository.html')
215 r = render('admin/repos/repo_add_create_repository.html')
215 else:
216 else:
216 r = render('admin/repos/repo_add.html')
217 r = render('admin/repos/repo_add.html')
217
218
218 return htmlfill.render(
219 return htmlfill.render(
219 r,
220 r,
220 defaults=errors.value,
221 defaults=errors.value,
221 errors=errors.error_dict or {},
222 errors=errors.error_dict or {},
222 prefix_error=False,
223 prefix_error=False,
223 encoding="UTF-8")
224 encoding="UTF-8")
224
225
225 except Exception:
226 except Exception:
226 log.error(traceback.format_exc())
227 log.error(traceback.format_exc())
227 msg = _('error occurred during creation of repository %s') \
228 msg = _('error occurred during creation of repository %s') \
228 % form_result.get('repo_name')
229 % form_result.get('repo_name')
229 h.flash(msg, category='error')
230 h.flash(msg, category='error')
230 return redirect(url('repos'))
231 return redirect(url('repos'))
231 #redirect to our new repo !
232 #redirect to our new repo !
232 return redirect(url('summary_home', repo_name=new_repo.repo_name))
233 return redirect(url('summary_home', repo_name=new_repo.repo_name))
233
234
234 @HasPermissionAllDecorator('hg.admin')
235 @HasPermissionAllDecorator('hg.admin')
235 def new(self, format='html'):
236 def new(self, format='html'):
236 """GET /repos/new: Form to create a new item"""
237 """GET /repos/new: Form to create a new item"""
237 new_repo = request.GET.get('repo', '')
238 new_repo = request.GET.get('repo', '')
238 c.new_repo = repo_name_slug(new_repo)
239 c.new_repo = repo_name_slug(new_repo)
239 self.__load_defaults()
240 self.__load_defaults()
240 return render('admin/repos/repo_add.html')
241 return render('admin/repos/repo_add.html')
241
242
242 @HasPermissionAllDecorator('hg.admin')
243 @HasPermissionAllDecorator('hg.admin')
243 def update(self, repo_name):
244 def update(self, repo_name):
244 """
245 """
245 PUT /repos/repo_name: Update an existing item"""
246 PUT /repos/repo_name: Update an existing item"""
246 # Forms posted to this method should contain a hidden field:
247 # Forms posted to this method should contain a hidden field:
247 # <input type="hidden" name="_method" value="PUT" />
248 # <input type="hidden" name="_method" value="PUT" />
248 # Or using helpers:
249 # Or using helpers:
249 # h.form(url('repo', repo_name=ID),
250 # h.form(url('repo', repo_name=ID),
250 # method='put')
251 # method='put')
251 # url('repo', repo_name=ID)
252 # url('repo', repo_name=ID)
252 self.__load_defaults()
253 self.__load_defaults()
253 repo_model = RepoModel()
254 repo_model = RepoModel()
254 changed_name = repo_name
255 changed_name = repo_name
255 #override the choices with extracted revisions !
256 #override the choices with extracted revisions !
256 choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name)
257 choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name)
257 c.landing_revs_choices = choices
258 c.landing_revs_choices = choices
258
259
259 _form = RepoForm(edit=True, old_data={'repo_name': repo_name},
260 _form = RepoForm(edit=True, old_data={'repo_name': repo_name},
260 repo_groups=c.repo_groups_choices,
261 repo_groups=c.repo_groups_choices,
261 landing_revs=c.landing_revs_choices)()
262 landing_revs=c.landing_revs_choices)()
262 try:
263 try:
263 form_result = _form.to_python(dict(request.POST))
264 form_result = _form.to_python(dict(request.POST))
264 repo = repo_model.update(repo_name, form_result)
265 repo = repo_model.update(repo_name, form_result)
265 invalidate_cache('get_repo_cached_%s' % repo_name)
266 invalidate_cache('get_repo_cached_%s' % repo_name)
266 h.flash(_('Repository %s updated successfully') % repo_name,
267 h.flash(_('Repository %s updated successfully') % repo_name,
267 category='success')
268 category='success')
268 changed_name = repo.repo_name
269 changed_name = repo.repo_name
269 action_logger(self.rhodecode_user, 'admin_updated_repo',
270 action_logger(self.rhodecode_user, 'admin_updated_repo',
270 changed_name, self.ip_addr, self.sa)
271 changed_name, self.ip_addr, self.sa)
271 Session().commit()
272 Session().commit()
272 except formencode.Invalid, errors:
273 except formencode.Invalid, errors:
273 defaults = self.__load_data(repo_name)
274 defaults = self.__load_data(repo_name)
274 defaults.update(errors.value)
275 defaults.update(errors.value)
275 return htmlfill.render(
276 return htmlfill.render(
276 render('admin/repos/repo_edit.html'),
277 render('admin/repos/repo_edit.html'),
277 defaults=defaults,
278 defaults=defaults,
278 errors=errors.error_dict or {},
279 errors=errors.error_dict or {},
279 prefix_error=False,
280 prefix_error=False,
280 encoding="UTF-8")
281 encoding="UTF-8")
281
282
282 except Exception:
283 except Exception:
283 log.error(traceback.format_exc())
284 log.error(traceback.format_exc())
284 h.flash(_('error occurred during update of repository %s') \
285 h.flash(_('error occurred during update of repository %s') \
285 % repo_name, category='error')
286 % repo_name, category='error')
286 return redirect(url('edit_repo', repo_name=changed_name))
287 return redirect(url('edit_repo', repo_name=changed_name))
287
288
288 @HasPermissionAllDecorator('hg.admin')
289 @HasPermissionAllDecorator('hg.admin')
289 def delete(self, repo_name):
290 def delete(self, repo_name):
290 """
291 """
291 DELETE /repos/repo_name: Delete an existing item"""
292 DELETE /repos/repo_name: Delete an existing item"""
292 # Forms posted to this method should contain a hidden field:
293 # Forms posted to this method should contain a hidden field:
293 # <input type="hidden" name="_method" value="DELETE" />
294 # <input type="hidden" name="_method" value="DELETE" />
294 # Or using helpers:
295 # Or using helpers:
295 # h.form(url('repo', repo_name=ID),
296 # h.form(url('repo', repo_name=ID),
296 # method='delete')
297 # method='delete')
297 # url('repo', repo_name=ID)
298 # url('repo', repo_name=ID)
298
299
299 repo_model = RepoModel()
300 repo_model = RepoModel()
300 repo = repo_model.get_by_repo_name(repo_name)
301 repo = repo_model.get_by_repo_name(repo_name)
301 if not repo:
302 if not repo:
302 h.flash(_('%s repository is not mapped to db perhaps'
303 h.flash(_('%s repository is not mapped to db perhaps'
303 ' it was moved or renamed from the filesystem'
304 ' it was moved or renamed from the filesystem'
304 ' please run the application again'
305 ' please run the application again'
305 ' in order to rescan repositories') % repo_name,
306 ' in order to rescan repositories') % repo_name,
306 category='error')
307 category='error')
307
308
308 return redirect(url('repos'))
309 return redirect(url('repos'))
309 try:
310 try:
310 action_logger(self.rhodecode_user, 'admin_deleted_repo',
311 action_logger(self.rhodecode_user, 'admin_deleted_repo',
311 repo_name, self.ip_addr, self.sa)
312 repo_name, self.ip_addr, self.sa)
312 repo_model.delete(repo)
313 repo_model.delete(repo)
313 invalidate_cache('get_repo_cached_%s' % repo_name)
314 invalidate_cache('get_repo_cached_%s' % repo_name)
314 h.flash(_('deleted repository %s') % repo_name, category='success')
315 h.flash(_('deleted repository %s') % repo_name, category='success')
315 Session().commit()
316 Session().commit()
316 except IntegrityError, e:
317 except IntegrityError, e:
317 if e.message.find('repositories_fork_id_fkey') != -1:
318 if e.message.find('repositories_fork_id_fkey') != -1:
318 log.error(traceback.format_exc())
319 log.error(traceback.format_exc())
319 h.flash(_('Cannot delete %s it still contains attached '
320 h.flash(_('Cannot delete %s it still contains attached '
320 'forks') % repo_name,
321 'forks') % repo_name,
321 category='warning')
322 category='warning')
322 else:
323 else:
323 log.error(traceback.format_exc())
324 log.error(traceback.format_exc())
324 h.flash(_('An error occurred during '
325 h.flash(_('An error occurred during '
325 'deletion of %s') % repo_name,
326 'deletion of %s') % repo_name,
326 category='error')
327 category='error')
327
328
328 except Exception, e:
329 except Exception, e:
329 log.error(traceback.format_exc())
330 log.error(traceback.format_exc())
330 h.flash(_('An error occurred during deletion of %s') % repo_name,
331 h.flash(_('An error occurred during deletion of %s') % repo_name,
331 category='error')
332 category='error')
332
333
333 return redirect(url('repos'))
334 return redirect(url('repos'))
334
335
335 @HasRepoPermissionAllDecorator('repository.admin')
336 @HasRepoPermissionAllDecorator('repository.admin')
336 def delete_perm_user(self, repo_name):
337 def delete_perm_user(self, repo_name):
337 """
338 """
338 DELETE an existing repository permission user
339 DELETE an existing repository permission user
339
340
340 :param repo_name:
341 :param repo_name:
341 """
342 """
342 try:
343 try:
343 RepoModel().revoke_user_permission(repo=repo_name,
344 RepoModel().revoke_user_permission(repo=repo_name,
344 user=request.POST['user_id'])
345 user=request.POST['user_id'])
345 Session().commit()
346 Session().commit()
346 except Exception:
347 except Exception:
347 log.error(traceback.format_exc())
348 log.error(traceback.format_exc())
348 h.flash(_('An error occurred during deletion of repository user'),
349 h.flash(_('An error occurred during deletion of repository user'),
349 category='error')
350 category='error')
350 raise HTTPInternalServerError()
351 raise HTTPInternalServerError()
351
352
352 @HasRepoPermissionAllDecorator('repository.admin')
353 @HasRepoPermissionAllDecorator('repository.admin')
353 def delete_perm_users_group(self, repo_name):
354 def delete_perm_users_group(self, repo_name):
354 """
355 """
355 DELETE an existing repository permission users group
356 DELETE an existing repository permission users group
356
357
357 :param repo_name:
358 :param repo_name:
358 """
359 """
359
360
360 try:
361 try:
361 RepoModel().revoke_users_group_permission(
362 RepoModel().revoke_users_group_permission(
362 repo=repo_name, group_name=request.POST['users_group_id']
363 repo=repo_name, group_name=request.POST['users_group_id']
363 )
364 )
364 Session().commit()
365 Session().commit()
365 except Exception:
366 except Exception:
366 log.error(traceback.format_exc())
367 log.error(traceback.format_exc())
367 h.flash(_('An error occurred during deletion of repository'
368 h.flash(_('An error occurred during deletion of repository'
368 ' users groups'),
369 ' users groups'),
369 category='error')
370 category='error')
370 raise HTTPInternalServerError()
371 raise HTTPInternalServerError()
371
372
372 @HasPermissionAllDecorator('hg.admin')
373 @HasPermissionAllDecorator('hg.admin')
373 def repo_stats(self, repo_name):
374 def repo_stats(self, repo_name):
374 """
375 """
375 DELETE an existing repository statistics
376 DELETE an existing repository statistics
376
377
377 :param repo_name:
378 :param repo_name:
378 """
379 """
379
380
380 try:
381 try:
381 RepoModel().delete_stats(repo_name)
382 RepoModel().delete_stats(repo_name)
382 Session().commit()
383 Session().commit()
383 except Exception, e:
384 except Exception, e:
384 log.error(traceback.format_exc())
385 log.error(traceback.format_exc())
385 h.flash(_('An error occurred during deletion of repository stats'),
386 h.flash(_('An error occurred during deletion of repository stats'),
386 category='error')
387 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_cache(self, repo_name):
391 def repo_cache(self, repo_name):
391 """
392 """
392 INVALIDATE existing repository cache
393 INVALIDATE existing repository cache
393
394
394 :param repo_name:
395 :param repo_name:
395 """
396 """
396
397
397 try:
398 try:
398 ScmModel().mark_for_invalidation(repo_name)
399 ScmModel().mark_for_invalidation(repo_name)
399 Session().commit()
400 Session().commit()
400 except Exception, e:
401 except Exception, e:
401 log.error(traceback.format_exc())
402 log.error(traceback.format_exc())
402 h.flash(_('An error occurred during cache invalidation'),
403 h.flash(_('An error occurred during cache invalidation'),
403 category='error')
404 category='error')
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 repo_locking(self, repo_name):
408 def repo_locking(self, repo_name):
408 """
409 """
409 Unlock repository when it is locked !
410 Unlock repository when it is locked !
410
411
411 :param repo_name:
412 :param repo_name:
412 """
413 """
413
414
414 try:
415 try:
415 repo = Repository.get_by_repo_name(repo_name)
416 repo = Repository.get_by_repo_name(repo_name)
416 if request.POST.get('set_lock'):
417 if request.POST.get('set_lock'):
417 Repository.lock(repo, c.rhodecode_user.user_id)
418 Repository.lock(repo, c.rhodecode_user.user_id)
418 elif request.POST.get('set_unlock'):
419 elif request.POST.get('set_unlock'):
419 Repository.unlock(repo)
420 Repository.unlock(repo)
420 except Exception, e:
421 except Exception, e:
421 log.error(traceback.format_exc())
422 log.error(traceback.format_exc())
422 h.flash(_('An error occurred during unlocking'),
423 h.flash(_('An error occurred during unlocking'),
423 category='error')
424 category='error')
424 return redirect(url('edit_repo', repo_name=repo_name))
425 return redirect(url('edit_repo', repo_name=repo_name))
425
426
426 @HasPermissionAllDecorator('hg.admin')
427 @HasPermissionAllDecorator('hg.admin')
427 def repo_public_journal(self, repo_name):
428 def repo_public_journal(self, repo_name):
428 """
429 """
429 Set's this repository to be visible in public journal,
430 Set's this repository to be visible in public journal,
430 in other words assing default user to follow this repo
431 in other words assing default user to follow this repo
431
432
432 :param repo_name:
433 :param repo_name:
433 """
434 """
434
435
435 cur_token = request.POST.get('auth_token')
436 cur_token = request.POST.get('auth_token')
436 token = get_token()
437 token = get_token()
437 if cur_token == token:
438 if cur_token == token:
438 try:
439 try:
439 repo_id = Repository.get_by_repo_name(repo_name).repo_id
440 repo_id = Repository.get_by_repo_name(repo_name).repo_id
440 user_id = User.get_by_username('default').user_id
441 user_id = User.get_by_username('default').user_id
441 self.scm_model.toggle_following_repo(repo_id, user_id)
442 self.scm_model.toggle_following_repo(repo_id, user_id)
442 h.flash(_('Updated repository visibility in public journal'),
443 h.flash(_('Updated repository visibility in public journal'),
443 category='success')
444 category='success')
444 Session().commit()
445 Session().commit()
445 except:
446 except:
446 h.flash(_('An error occurred during setting this'
447 h.flash(_('An error occurred during setting this'
447 ' repository in public journal'),
448 ' repository in public journal'),
448 category='error')
449 category='error')
449
450
450 else:
451 else:
451 h.flash(_('Token mismatch'), category='error')
452 h.flash(_('Token mismatch'), category='error')
452 return redirect(url('edit_repo', repo_name=repo_name))
453 return redirect(url('edit_repo', repo_name=repo_name))
453
454
454 @HasPermissionAllDecorator('hg.admin')
455 @HasPermissionAllDecorator('hg.admin')
455 def repo_pull(self, repo_name):
456 def repo_pull(self, repo_name):
456 """
457 """
457 Runs task to update given repository with remote changes,
458 Runs task to update given repository with remote changes,
458 ie. make pull on remote location
459 ie. make pull on remote location
459
460
460 :param repo_name:
461 :param repo_name:
461 """
462 """
462 try:
463 try:
463 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
464 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
464 h.flash(_('Pulled from remote location'), category='success')
465 h.flash(_('Pulled from remote location'), category='success')
465 except Exception, e:
466 except Exception, e:
466 h.flash(_('An error occurred during pull from remote location'),
467 h.flash(_('An error occurred during pull from remote location'),
467 category='error')
468 category='error')
468
469
469 return redirect(url('edit_repo', repo_name=repo_name))
470 return redirect(url('edit_repo', repo_name=repo_name))
470
471
471 @HasPermissionAllDecorator('hg.admin')
472 @HasPermissionAllDecorator('hg.admin')
472 def repo_as_fork(self, repo_name):
473 def repo_as_fork(self, repo_name):
473 """
474 """
474 Mark given repository as a fork of another
475 Mark given repository as a fork of another
475
476
476 :param repo_name:
477 :param repo_name:
477 """
478 """
478 try:
479 try:
479 fork_id = request.POST.get('id_fork_of')
480 fork_id = request.POST.get('id_fork_of')
480 repo = ScmModel().mark_as_fork(repo_name, fork_id,
481 repo = ScmModel().mark_as_fork(repo_name, fork_id,
481 self.rhodecode_user.username)
482 self.rhodecode_user.username)
482 fork = repo.fork.repo_name if repo.fork else _('Nothing')
483 fork = repo.fork.repo_name if repo.fork else _('Nothing')
483 Session().commit()
484 Session().commit()
484 h.flash(_('Marked repo %s as fork of %s') % (repo_name, fork),
485 h.flash(_('Marked repo %s as fork of %s') % (repo_name, fork),
485 category='success')
486 category='success')
486 except Exception, e:
487 except Exception, e:
487 log.error(traceback.format_exc())
488 log.error(traceback.format_exc())
488 h.flash(_('An error occurred during this operation'),
489 h.flash(_('An error occurred during this operation'),
489 category='error')
490 category='error')
490
491
491 return redirect(url('edit_repo', repo_name=repo_name))
492 return redirect(url('edit_repo', repo_name=repo_name))
492
493
493 @HasPermissionAllDecorator('hg.admin')
494 @HasPermissionAllDecorator('hg.admin')
494 def show(self, repo_name, format='html'):
495 def show(self, repo_name, format='html'):
495 """GET /repos/repo_name: Show a specific item"""
496 """GET /repos/repo_name: Show a specific item"""
496 # url('repo', repo_name=ID)
497 # url('repo', repo_name=ID)
497
498
498 @HasPermissionAllDecorator('hg.admin')
499 @HasPermissionAllDecorator('hg.admin')
499 def edit(self, repo_name, format='html'):
500 def edit(self, repo_name, format='html'):
500 """GET /repos/repo_name/edit: Form to edit an existing item"""
501 """GET /repos/repo_name/edit: Form to edit an existing item"""
501 # url('edit_repo', repo_name=ID)
502 # url('edit_repo', repo_name=ID)
502 defaults = self.__load_data(repo_name)
503 defaults = self.__load_data(repo_name)
503
504
504 return htmlfill.render(
505 return htmlfill.render(
505 render('admin/repos/repo_edit.html'),
506 render('admin/repos/repo_edit.html'),
506 defaults=defaults,
507 defaults=defaults,
507 encoding="UTF-8",
508 encoding="UTF-8",
508 force_defaults=False
509 force_defaults=False
509 )
510 )
General Comments 0
You need to be logged in to leave comments. Login now