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