##// END OF EJS Templates
fix flash link to repos that are in groups
marcink -
r3668:a3c1de44 beta
parent child Browse files
Show More
@@ -1,606 +1,606 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, HTTPForbidden
31 from webob.exc import HTTPInternalServerError, HTTPForbidden
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, NotAnonymous,\
40 HasPermissionAnyDecorator, HasRepoPermissionAllDecorator, NotAnonymous,\
41 HasPermissionAny, HasReposGroupPermissionAny, HasRepoPermissionAnyDecorator
41 HasPermissionAny, HasReposGroupPermissionAny, HasRepoPermissionAnyDecorator
42 from rhodecode.lib.base import BaseRepoController, render
42 from rhodecode.lib.base import BaseRepoController, render
43 from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug
43 from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug
44 from rhodecode.lib.helpers import get_token
44 from rhodecode.lib.helpers import get_token
45 from rhodecode.model.meta import Session
45 from rhodecode.model.meta import Session
46 from rhodecode.model.db import User, Repository, UserFollowing, RepoGroup,\
46 from rhodecode.model.db import User, Repository, UserFollowing, RepoGroup,\
47 RhodeCodeSetting, RepositoryField
47 RhodeCodeSetting, RepositoryField
48 from rhodecode.model.forms import RepoForm, RepoFieldForm, RepoPermsForm
48 from rhodecode.model.forms import RepoForm, RepoFieldForm, RepoPermsForm
49 from rhodecode.model.scm import ScmModel, GroupList
49 from rhodecode.model.scm import ScmModel, GroupList
50 from rhodecode.model.repo import RepoModel
50 from rhodecode.model.repo import RepoModel
51 from rhodecode.lib.compat import json
51 from rhodecode.lib.compat import json
52 from sqlalchemy.sql.expression import func
52 from sqlalchemy.sql.expression import func
53 from rhodecode.lib.exceptions import AttachedForksError
53 from rhodecode.lib.exceptions import AttachedForksError
54
54
55 log = logging.getLogger(__name__)
55 log = logging.getLogger(__name__)
56
56
57
57
58 class ReposController(BaseRepoController):
58 class ReposController(BaseRepoController):
59 """
59 """
60 REST Controller styled on the Atom Publishing Protocol"""
60 REST Controller styled on the Atom Publishing Protocol"""
61 # To properly map this controller, ensure your config/routing.py
61 # To properly map this controller, ensure your config/routing.py
62 # file has a resource setup:
62 # file has a resource setup:
63 # map.resource('repo', 'repos')
63 # map.resource('repo', 'repos')
64
64
65 @LoginRequired()
65 @LoginRequired()
66 def __before__(self):
66 def __before__(self):
67 c.admin_user = session.get('admin_user')
67 c.admin_user = session.get('admin_user')
68 c.admin_username = session.get('admin_username')
68 c.admin_username = session.get('admin_username')
69 super(ReposController, self).__before__()
69 super(ReposController, self).__before__()
70
70
71 def __load_defaults(self):
71 def __load_defaults(self):
72 acl_groups = GroupList(RepoGroup.query().all(),
72 acl_groups = GroupList(RepoGroup.query().all(),
73 perm_set=['group.write', 'group.admin'])
73 perm_set=['group.write', 'group.admin'])
74 c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
74 c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
75 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
75 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
76
76
77 repo_model = RepoModel()
77 repo_model = RepoModel()
78 c.users_array = repo_model.get_users_js()
78 c.users_array = repo_model.get_users_js()
79 c.users_groups_array = repo_model.get_users_groups_js()
79 c.users_groups_array = repo_model.get_users_groups_js()
80 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
80 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
81 c.landing_revs_choices = choices
81 c.landing_revs_choices = choices
82
82
83 def __load_data(self, repo_name=None):
83 def __load_data(self, repo_name=None):
84 """
84 """
85 Load defaults settings for edit, and update
85 Load defaults settings for edit, and update
86
86
87 :param repo_name:
87 :param repo_name:
88 """
88 """
89 self.__load_defaults()
89 self.__load_defaults()
90
90
91 c.repo_info = db_repo = Repository.get_by_repo_name(repo_name)
91 c.repo_info = db_repo = Repository.get_by_repo_name(repo_name)
92 repo = db_repo.scm_instance
92 repo = db_repo.scm_instance
93
93
94 if c.repo_info is None:
94 if c.repo_info is None:
95 h.not_mapped_error(repo_name)
95 h.not_mapped_error(repo_name)
96 return redirect(url('repos'))
96 return redirect(url('repos'))
97
97
98 ##override defaults for exact repo info here git/hg etc
98 ##override defaults for exact repo info here git/hg etc
99 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)
100 c.landing_revs_choices = choices
100 c.landing_revs_choices = choices
101
101
102 c.default_user_id = User.get_by_username('default').user_id
102 c.default_user_id = User.get_by_username('default').user_id
103 c.in_public_journal = UserFollowing.query()\
103 c.in_public_journal = UserFollowing.query()\
104 .filter(UserFollowing.user_id == c.default_user_id)\
104 .filter(UserFollowing.user_id == c.default_user_id)\
105 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
105 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
106
106
107 if c.repo_info.stats:
107 if c.repo_info.stats:
108 # 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
109 last_rev = c.repo_info.stats.stat_on_revision + 1
109 last_rev = c.repo_info.stats.stat_on_revision + 1
110 else:
110 else:
111 last_rev = 0
111 last_rev = 0
112 c.stats_revision = last_rev
112 c.stats_revision = last_rev
113
113
114 c.repo_last_rev = repo.count() if repo.revisions else 0
114 c.repo_last_rev = repo.count() if repo.revisions else 0
115
115
116 if last_rev == 0 or c.repo_last_rev == 0:
116 if last_rev == 0 or c.repo_last_rev == 0:
117 c.stats_percentage = 0
117 c.stats_percentage = 0
118 else:
118 else:
119 c.stats_percentage = '%.2f' % ((float((last_rev)) /
119 c.stats_percentage = '%.2f' % ((float((last_rev)) /
120 c.repo_last_rev) * 100)
120 c.repo_last_rev) * 100)
121
121
122 c.repo_fields = RepositoryField.query()\
122 c.repo_fields = RepositoryField.query()\
123 .filter(RepositoryField.repository == db_repo).all()
123 .filter(RepositoryField.repository == db_repo).all()
124
124
125 defaults = RepoModel()._get_defaults(repo_name)
125 defaults = RepoModel()._get_defaults(repo_name)
126
126
127 c.repos_list = [('', _('--REMOVE FORK--'))]
127 c.repos_list = [('', _('--REMOVE FORK--'))]
128 c.repos_list += [(x.repo_id, x.repo_name) for x in
128 c.repos_list += [(x.repo_id, x.repo_name) for x in
129 Repository.query().order_by(Repository.repo_name).all()
129 Repository.query().order_by(Repository.repo_name).all()
130 if x.repo_id != c.repo_info.repo_id]
130 if x.repo_id != c.repo_info.repo_id]
131
131
132 defaults['id_fork_of'] = db_repo.fork.repo_id if db_repo.fork else ''
132 defaults['id_fork_of'] = db_repo.fork.repo_id if db_repo.fork else ''
133 return defaults
133 return defaults
134
134
135 @HasPermissionAllDecorator('hg.admin')
135 @HasPermissionAllDecorator('hg.admin')
136 def index(self, format='html'):
136 def index(self, format='html'):
137 """GET /repos: All items in the collection"""
137 """GET /repos: All items in the collection"""
138 # url('repos')
138 # url('repos')
139
139
140 c.repos_list = Repository.query()\
140 c.repos_list = Repository.query()\
141 .order_by(func.lower(Repository.repo_name))\
141 .order_by(func.lower(Repository.repo_name))\
142 .all()
142 .all()
143
143
144 repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
144 repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
145 admin=True,
145 admin=True,
146 super_user_actions=True)
146 super_user_actions=True)
147 #json used to render the grid
147 #json used to render the grid
148 c.data = json.dumps(repos_data)
148 c.data = json.dumps(repos_data)
149
149
150 return render('admin/repos/repos.html')
150 return render('admin/repos/repos.html')
151
151
152 @NotAnonymous()
152 @NotAnonymous()
153 def create(self):
153 def create(self):
154 """
154 """
155 POST /repos: Create a new item"""
155 POST /repos: Create a new item"""
156 # url('repos')
156 # url('repos')
157
157
158 self.__load_defaults()
158 self.__load_defaults()
159 form_result = {}
159 form_result = {}
160 try:
160 try:
161 form_result = RepoForm(repo_groups=c.repo_groups_choices,
161 form_result = RepoForm(repo_groups=c.repo_groups_choices,
162 landing_revs=c.landing_revs_choices)()\
162 landing_revs=c.landing_revs_choices)()\
163 .to_python(dict(request.POST))
163 .to_python(dict(request.POST))
164
164
165 new_repo = RepoModel().create(form_result,
165 new_repo = RepoModel().create(form_result,
166 self.rhodecode_user.user_id)
166 self.rhodecode_user.user_id)
167 if form_result['clone_uri']:
167 if form_result['clone_uri']:
168 h.flash(_('Created repository %s from %s') \
168 h.flash(_('Created repository %s from %s') \
169 % (form_result['repo_name'], form_result['clone_uri']),
169 % (form_result['repo_name'], form_result['clone_uri']),
170 category='success')
170 category='success')
171 else:
171 else:
172 repo_url = h.link_to(form_result['repo_name'],
172 repo_url = h.link_to(form_result['repo_name'],
173 h.url('summary_home', repo_name=form_result['repo_name']))
173 h.url('summary_home', repo_name=form_result['repo_name_full']))
174 h.flash(h.literal(_('Created repository %s') % repo_url),
174 h.flash(h.literal(_('Created repository %s') % repo_url),
175 category='success')
175 category='success')
176
176
177 if request.POST.get('user_created'):
177 if request.POST.get('user_created'):
178 # created by regular non admin user
178 # created by regular non admin user
179 action_logger(self.rhodecode_user, 'user_created_repo',
179 action_logger(self.rhodecode_user, 'user_created_repo',
180 form_result['repo_name_full'], self.ip_addr,
180 form_result['repo_name_full'], self.ip_addr,
181 self.sa)
181 self.sa)
182 else:
182 else:
183 action_logger(self.rhodecode_user, 'admin_created_repo',
183 action_logger(self.rhodecode_user, 'admin_created_repo',
184 form_result['repo_name_full'], self.ip_addr,
184 form_result['repo_name_full'], self.ip_addr,
185 self.sa)
185 self.sa)
186 Session().commit()
186 Session().commit()
187 except formencode.Invalid, errors:
187 except formencode.Invalid, errors:
188 return htmlfill.render(
188 return htmlfill.render(
189 render('admin/repos/repo_add.html'),
189 render('admin/repos/repo_add.html'),
190 defaults=errors.value,
190 defaults=errors.value,
191 errors=errors.error_dict or {},
191 errors=errors.error_dict or {},
192 prefix_error=False,
192 prefix_error=False,
193 encoding="UTF-8")
193 encoding="UTF-8")
194
194
195 except Exception:
195 except Exception:
196 log.error(traceback.format_exc())
196 log.error(traceback.format_exc())
197 msg = _('Error creating repository %s') \
197 msg = _('Error creating repository %s') \
198 % form_result.get('repo_name')
198 % form_result.get('repo_name')
199 h.flash(msg, category='error')
199 h.flash(msg, category='error')
200 if c.rhodecode_user.is_admin:
200 if c.rhodecode_user.is_admin:
201 return redirect(url('repos'))
201 return redirect(url('repos'))
202 return redirect(url('home'))
202 return redirect(url('home'))
203 #redirect to our new repo !
203 #redirect to our new repo !
204 return redirect(url('summary_home', repo_name=new_repo.repo_name))
204 return redirect(url('summary_home', repo_name=new_repo.repo_name))
205
205
206 @NotAnonymous()
206 @NotAnonymous()
207 def create_repository(self):
207 def create_repository(self):
208 """GET /_admin/create_repository: Form to create a new item"""
208 """GET /_admin/create_repository: Form to create a new item"""
209 new_repo = request.GET.get('repo', '')
209 new_repo = request.GET.get('repo', '')
210 parent_group = request.GET.get('parent_group')
210 parent_group = request.GET.get('parent_group')
211 if not HasPermissionAny('hg.admin', 'hg.create.repository')():
211 if not HasPermissionAny('hg.admin', 'hg.create.repository')():
212 #you're not super admin nor have global create permissions,
212 #you're not super admin nor have global create permissions,
213 #but maybe you have at least write permission to a parent group ?
213 #but maybe you have at least write permission to a parent group ?
214 _gr = RepoGroup.get(parent_group)
214 _gr = RepoGroup.get(parent_group)
215 gr_name = _gr.group_name if _gr else None
215 gr_name = _gr.group_name if _gr else None
216 if not HasReposGroupPermissionAny('group.admin', 'group.write')(group_name=gr_name):
216 if not HasReposGroupPermissionAny('group.admin', 'group.write')(group_name=gr_name):
217 raise HTTPForbidden
217 raise HTTPForbidden
218
218
219 acl_groups = GroupList(RepoGroup.query().all(),
219 acl_groups = GroupList(RepoGroup.query().all(),
220 perm_set=['group.write', 'group.admin'])
220 perm_set=['group.write', 'group.admin'])
221 c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
221 c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
222 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
222 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
223 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
223 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
224
224
225 c.new_repo = repo_name_slug(new_repo)
225 c.new_repo = repo_name_slug(new_repo)
226
226
227 ## apply the defaults from defaults page
227 ## apply the defaults from defaults page
228 defaults = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
228 defaults = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
229 if parent_group:
229 if parent_group:
230 defaults.update({'repo_group': parent_group})
230 defaults.update({'repo_group': parent_group})
231
231
232 return htmlfill.render(
232 return htmlfill.render(
233 render('admin/repos/repo_add.html'),
233 render('admin/repos/repo_add.html'),
234 defaults=defaults,
234 defaults=defaults,
235 errors={},
235 errors={},
236 prefix_error=False,
236 prefix_error=False,
237 encoding="UTF-8"
237 encoding="UTF-8"
238 )
238 )
239
239
240 @HasRepoPermissionAllDecorator('repository.admin')
240 @HasRepoPermissionAllDecorator('repository.admin')
241 def update(self, repo_name):
241 def update(self, repo_name):
242 """
242 """
243 PUT /repos/repo_name: Update an existing item"""
243 PUT /repos/repo_name: Update an existing item"""
244 # Forms posted to this method should contain a hidden field:
244 # Forms posted to this method should contain a hidden field:
245 # <input type="hidden" name="_method" value="PUT" />
245 # <input type="hidden" name="_method" value="PUT" />
246 # Or using helpers:
246 # Or using helpers:
247 # h.form(url('repo', repo_name=ID),
247 # h.form(url('repo', repo_name=ID),
248 # method='put')
248 # method='put')
249 # url('repo', repo_name=ID)
249 # url('repo', repo_name=ID)
250 self.__load_defaults()
250 self.__load_defaults()
251 repo_model = RepoModel()
251 repo_model = RepoModel()
252 changed_name = repo_name
252 changed_name = repo_name
253 #override the choices with extracted revisions !
253 #override the choices with extracted revisions !
254 choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name)
254 choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name)
255 c.landing_revs_choices = choices
255 c.landing_revs_choices = choices
256 repo = Repository.get_by_repo_name(repo_name)
256 repo = Repository.get_by_repo_name(repo_name)
257 _form = RepoForm(edit=True, old_data={'repo_name': repo_name,
257 _form = RepoForm(edit=True, old_data={'repo_name': repo_name,
258 'repo_group': repo.group.get_dict() \
258 'repo_group': repo.group.get_dict() \
259 if repo.group else {}},
259 if repo.group else {}},
260 repo_groups=c.repo_groups_choices,
260 repo_groups=c.repo_groups_choices,
261 landing_revs=c.landing_revs_choices)()
261 landing_revs=c.landing_revs_choices)()
262 try:
262 try:
263 form_result = _form.to_python(dict(request.POST))
263 form_result = _form.to_python(dict(request.POST))
264 repo = repo_model.update(repo_name, **form_result)
264 repo = repo_model.update(repo_name, **form_result)
265 invalidate_cache('get_repo_cached_%s' % repo_name)
265 invalidate_cache('get_repo_cached_%s' % repo_name)
266 h.flash(_('Repository %s updated successfully') % repo_name,
266 h.flash(_('Repository %s updated successfully') % repo_name,
267 category='success')
267 category='success')
268 changed_name = repo.repo_name
268 changed_name = repo.repo_name
269 action_logger(self.rhodecode_user, 'admin_updated_repo',
269 action_logger(self.rhodecode_user, 'admin_updated_repo',
270 changed_name, self.ip_addr, self.sa)
270 changed_name, self.ip_addr, self.sa)
271 Session().commit()
271 Session().commit()
272 except formencode.Invalid, errors:
272 except formencode.Invalid, errors:
273 defaults = self.__load_data(repo_name)
273 defaults = self.__load_data(repo_name)
274 defaults.update(errors.value)
274 defaults.update(errors.value)
275 return htmlfill.render(
275 return htmlfill.render(
276 render('admin/repos/repo_edit.html'),
276 render('admin/repos/repo_edit.html'),
277 defaults=defaults,
277 defaults=defaults,
278 errors=errors.error_dict or {},
278 errors=errors.error_dict or {},
279 prefix_error=False,
279 prefix_error=False,
280 encoding="UTF-8")
280 encoding="UTF-8")
281
281
282 except Exception:
282 except Exception:
283 log.error(traceback.format_exc())
283 log.error(traceback.format_exc())
284 h.flash(_('Error occurred during update of repository %s') \
284 h.flash(_('Error occurred during update of repository %s') \
285 % repo_name, category='error')
285 % repo_name, category='error')
286 return redirect(url('edit_repo', repo_name=changed_name))
286 return redirect(url('edit_repo', repo_name=changed_name))
287
287
288 @HasRepoPermissionAllDecorator('repository.admin')
288 @HasRepoPermissionAllDecorator('repository.admin')
289 def delete(self, repo_name):
289 def delete(self, repo_name):
290 """
290 """
291 DELETE /repos/repo_name: Delete an existing item"""
291 DELETE /repos/repo_name: Delete an existing item"""
292 # Forms posted to this method should contain a hidden field:
292 # Forms posted to this method should contain a hidden field:
293 # <input type="hidden" name="_method" value="DELETE" />
293 # <input type="hidden" name="_method" value="DELETE" />
294 # Or using helpers:
294 # Or using helpers:
295 # h.form(url('repo', repo_name=ID),
295 # h.form(url('repo', repo_name=ID),
296 # method='delete')
296 # method='delete')
297 # url('repo', repo_name=ID)
297 # url('repo', repo_name=ID)
298
298
299 repo_model = RepoModel()
299 repo_model = RepoModel()
300 repo = repo_model.get_by_repo_name(repo_name)
300 repo = repo_model.get_by_repo_name(repo_name)
301 if not repo:
301 if not repo:
302 h.not_mapped_error(repo_name)
302 h.not_mapped_error(repo_name)
303 return redirect(url('repos'))
303 return redirect(url('repos'))
304 try:
304 try:
305 _forks = repo.forks.count()
305 _forks = repo.forks.count()
306 handle_forks = None
306 handle_forks = None
307 if _forks and request.POST.get('forks'):
307 if _forks and request.POST.get('forks'):
308 do = request.POST['forks']
308 do = request.POST['forks']
309 if do == 'detach_forks':
309 if do == 'detach_forks':
310 handle_forks = 'detach'
310 handle_forks = 'detach'
311 h.flash(_('Detached %s forks') % _forks, category='success')
311 h.flash(_('Detached %s forks') % _forks, category='success')
312 elif do == 'delete_forks':
312 elif do == 'delete_forks':
313 handle_forks = 'delete'
313 handle_forks = 'delete'
314 h.flash(_('Deleted %s forks') % _forks, category='success')
314 h.flash(_('Deleted %s forks') % _forks, category='success')
315 repo_model.delete(repo, forks=handle_forks)
315 repo_model.delete(repo, forks=handle_forks)
316 action_logger(self.rhodecode_user, 'admin_deleted_repo',
316 action_logger(self.rhodecode_user, 'admin_deleted_repo',
317 repo_name, self.ip_addr, self.sa)
317 repo_name, self.ip_addr, self.sa)
318 invalidate_cache('get_repo_cached_%s' % repo_name)
318 invalidate_cache('get_repo_cached_%s' % repo_name)
319 h.flash(_('Deleted repository %s') % repo_name, category='success')
319 h.flash(_('Deleted repository %s') % repo_name, category='success')
320 Session().commit()
320 Session().commit()
321 except AttachedForksError:
321 except AttachedForksError:
322 h.flash(_('Cannot delete %s it still contains attached forks')
322 h.flash(_('Cannot delete %s it still contains attached forks')
323 % repo_name, category='warning')
323 % repo_name, category='warning')
324
324
325 except Exception:
325 except Exception:
326 log.error(traceback.format_exc())
326 log.error(traceback.format_exc())
327 h.flash(_('An error occurred during deletion of %s') % repo_name,
327 h.flash(_('An error occurred during deletion of %s') % repo_name,
328 category='error')
328 category='error')
329
329
330 return redirect(url('repos'))
330 return redirect(url('repos'))
331
331
332 @HasRepoPermissionAllDecorator('repository.admin')
332 @HasRepoPermissionAllDecorator('repository.admin')
333 def set_repo_perm_member(self, repo_name):
333 def set_repo_perm_member(self, repo_name):
334 form = RepoPermsForm()().to_python(request.POST)
334 form = RepoPermsForm()().to_python(request.POST)
335
335
336 perms_new = form['perms_new']
336 perms_new = form['perms_new']
337 perms_updates = form['perms_updates']
337 perms_updates = form['perms_updates']
338 cur_repo = repo_name
338 cur_repo = repo_name
339
339
340 # update permissions
340 # update permissions
341 for member, perm, member_type in perms_updates:
341 for member, perm, member_type in perms_updates:
342 if member_type == 'user':
342 if member_type == 'user':
343 # this updates existing one
343 # this updates existing one
344 RepoModel().grant_user_permission(
344 RepoModel().grant_user_permission(
345 repo=cur_repo, user=member, perm=perm
345 repo=cur_repo, user=member, perm=perm
346 )
346 )
347 else:
347 else:
348 RepoModel().grant_users_group_permission(
348 RepoModel().grant_users_group_permission(
349 repo=cur_repo, group_name=member, perm=perm
349 repo=cur_repo, group_name=member, perm=perm
350 )
350 )
351 # set new permissions
351 # set new permissions
352 for member, perm, member_type in perms_new:
352 for member, perm, member_type in perms_new:
353 if member_type == 'user':
353 if member_type == 'user':
354 RepoModel().grant_user_permission(
354 RepoModel().grant_user_permission(
355 repo=cur_repo, user=member, perm=perm
355 repo=cur_repo, user=member, perm=perm
356 )
356 )
357 else:
357 else:
358 RepoModel().grant_users_group_permission(
358 RepoModel().grant_users_group_permission(
359 repo=cur_repo, group_name=member, perm=perm
359 repo=cur_repo, group_name=member, perm=perm
360 )
360 )
361 #TODO: implement this
361 #TODO: implement this
362 #action_logger(self.rhodecode_user, 'admin_changed_repo_permissions',
362 #action_logger(self.rhodecode_user, 'admin_changed_repo_permissions',
363 # repo_name, self.ip_addr, self.sa)
363 # repo_name, self.ip_addr, self.sa)
364 Session().commit()
364 Session().commit()
365 h.flash(_('Repository permissions updated'), category='success')
365 h.flash(_('Repository permissions updated'), category='success')
366 return redirect(url('edit_repo', repo_name=repo_name))
366 return redirect(url('edit_repo', repo_name=repo_name))
367
367
368 @HasRepoPermissionAllDecorator('repository.admin')
368 @HasRepoPermissionAllDecorator('repository.admin')
369 def delete_perm_user(self, repo_name):
369 def delete_perm_user(self, repo_name):
370 """
370 """
371 DELETE an existing repository permission user
371 DELETE an existing repository permission user
372
372
373 :param repo_name:
373 :param repo_name:
374 """
374 """
375 try:
375 try:
376 RepoModel().revoke_user_permission(repo=repo_name,
376 RepoModel().revoke_user_permission(repo=repo_name,
377 user=request.POST['user_id'])
377 user=request.POST['user_id'])
378 #TODO: implement this
378 #TODO: implement this
379 #action_logger(self.rhodecode_user, 'admin_revoked_repo_permissions',
379 #action_logger(self.rhodecode_user, 'admin_revoked_repo_permissions',
380 # repo_name, self.ip_addr, self.sa)
380 # repo_name, self.ip_addr, self.sa)
381 Session().commit()
381 Session().commit()
382 except Exception:
382 except Exception:
383 log.error(traceback.format_exc())
383 log.error(traceback.format_exc())
384 h.flash(_('An error occurred during deletion of repository user'),
384 h.flash(_('An error occurred during deletion of repository user'),
385 category='error')
385 category='error')
386 raise HTTPInternalServerError()
386 raise HTTPInternalServerError()
387
387
388 @HasRepoPermissionAllDecorator('repository.admin')
388 @HasRepoPermissionAllDecorator('repository.admin')
389 def delete_perm_users_group(self, repo_name):
389 def delete_perm_users_group(self, repo_name):
390 """
390 """
391 DELETE an existing repository permission user group
391 DELETE an existing repository permission user group
392
392
393 :param repo_name:
393 :param repo_name:
394 """
394 """
395
395
396 try:
396 try:
397 RepoModel().revoke_users_group_permission(
397 RepoModel().revoke_users_group_permission(
398 repo=repo_name, group_name=request.POST['users_group_id']
398 repo=repo_name, group_name=request.POST['users_group_id']
399 )
399 )
400 Session().commit()
400 Session().commit()
401 except Exception:
401 except Exception:
402 log.error(traceback.format_exc())
402 log.error(traceback.format_exc())
403 h.flash(_('An error occurred during deletion of repository'
403 h.flash(_('An error occurred during deletion of repository'
404 ' user groups'),
404 ' user groups'),
405 category='error')
405 category='error')
406 raise HTTPInternalServerError()
406 raise HTTPInternalServerError()
407
407
408 @HasRepoPermissionAllDecorator('repository.admin')
408 @HasRepoPermissionAllDecorator('repository.admin')
409 def repo_stats(self, repo_name):
409 def repo_stats(self, repo_name):
410 """
410 """
411 DELETE an existing repository statistics
411 DELETE an existing repository statistics
412
412
413 :param repo_name:
413 :param repo_name:
414 """
414 """
415
415
416 try:
416 try:
417 RepoModel().delete_stats(repo_name)
417 RepoModel().delete_stats(repo_name)
418 Session().commit()
418 Session().commit()
419 except Exception, e:
419 except Exception, e:
420 log.error(traceback.format_exc())
420 log.error(traceback.format_exc())
421 h.flash(_('An error occurred during deletion of repository stats'),
421 h.flash(_('An error occurred during deletion of repository stats'),
422 category='error')
422 category='error')
423 return redirect(url('edit_repo', repo_name=repo_name))
423 return redirect(url('edit_repo', repo_name=repo_name))
424
424
425 @HasRepoPermissionAllDecorator('repository.admin')
425 @HasRepoPermissionAllDecorator('repository.admin')
426 def repo_cache(self, repo_name):
426 def repo_cache(self, repo_name):
427 """
427 """
428 INVALIDATE existing repository cache
428 INVALIDATE existing repository cache
429
429
430 :param repo_name:
430 :param repo_name:
431 """
431 """
432
432
433 try:
433 try:
434 ScmModel().mark_for_invalidation(repo_name)
434 ScmModel().mark_for_invalidation(repo_name)
435 Session().commit()
435 Session().commit()
436 except Exception, e:
436 except Exception, e:
437 log.error(traceback.format_exc())
437 log.error(traceback.format_exc())
438 h.flash(_('An error occurred during cache invalidation'),
438 h.flash(_('An error occurred during cache invalidation'),
439 category='error')
439 category='error')
440 return redirect(url('edit_repo', repo_name=repo_name))
440 return redirect(url('edit_repo', repo_name=repo_name))
441
441
442 @HasRepoPermissionAllDecorator('repository.admin')
442 @HasRepoPermissionAllDecorator('repository.admin')
443 def repo_locking(self, repo_name):
443 def repo_locking(self, repo_name):
444 """
444 """
445 Unlock repository when it is locked !
445 Unlock repository when it is locked !
446
446
447 :param repo_name:
447 :param repo_name:
448 """
448 """
449
449
450 try:
450 try:
451 repo = Repository.get_by_repo_name(repo_name)
451 repo = Repository.get_by_repo_name(repo_name)
452 if request.POST.get('set_lock'):
452 if request.POST.get('set_lock'):
453 Repository.lock(repo, c.rhodecode_user.user_id)
453 Repository.lock(repo, c.rhodecode_user.user_id)
454 elif request.POST.get('set_unlock'):
454 elif request.POST.get('set_unlock'):
455 Repository.unlock(repo)
455 Repository.unlock(repo)
456 except Exception, e:
456 except Exception, e:
457 log.error(traceback.format_exc())
457 log.error(traceback.format_exc())
458 h.flash(_('An error occurred during unlocking'),
458 h.flash(_('An error occurred during unlocking'),
459 category='error')
459 category='error')
460 return redirect(url('edit_repo', repo_name=repo_name))
460 return redirect(url('edit_repo', repo_name=repo_name))
461
461
462 @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
462 @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
463 def toggle_locking(self, repo_name):
463 def toggle_locking(self, repo_name):
464 """
464 """
465 Toggle locking of repository by simple GET call to url
465 Toggle locking of repository by simple GET call to url
466
466
467 :param repo_name:
467 :param repo_name:
468 """
468 """
469
469
470 try:
470 try:
471 repo = Repository.get_by_repo_name(repo_name)
471 repo = Repository.get_by_repo_name(repo_name)
472
472
473 if repo.enable_locking:
473 if repo.enable_locking:
474 if repo.locked[0]:
474 if repo.locked[0]:
475 Repository.unlock(repo)
475 Repository.unlock(repo)
476 action = _('Unlocked')
476 action = _('Unlocked')
477 else:
477 else:
478 Repository.lock(repo, c.rhodecode_user.user_id)
478 Repository.lock(repo, c.rhodecode_user.user_id)
479 action = _('Locked')
479 action = _('Locked')
480
480
481 h.flash(_('Repository has been %s') % action,
481 h.flash(_('Repository has been %s') % action,
482 category='success')
482 category='success')
483 except Exception, e:
483 except Exception, e:
484 log.error(traceback.format_exc())
484 log.error(traceback.format_exc())
485 h.flash(_('An error occurred during unlocking'),
485 h.flash(_('An error occurred during unlocking'),
486 category='error')
486 category='error')
487 return redirect(url('summary_home', repo_name=repo_name))
487 return redirect(url('summary_home', repo_name=repo_name))
488
488
489 @HasRepoPermissionAllDecorator('repository.admin')
489 @HasRepoPermissionAllDecorator('repository.admin')
490 def repo_public_journal(self, repo_name):
490 def repo_public_journal(self, repo_name):
491 """
491 """
492 Set's this repository to be visible in public journal,
492 Set's this repository to be visible in public journal,
493 in other words assing default user to follow this repo
493 in other words assing default user to follow this repo
494
494
495 :param repo_name:
495 :param repo_name:
496 """
496 """
497
497
498 cur_token = request.POST.get('auth_token')
498 cur_token = request.POST.get('auth_token')
499 token = get_token()
499 token = get_token()
500 if cur_token == token:
500 if cur_token == token:
501 try:
501 try:
502 repo_id = Repository.get_by_repo_name(repo_name).repo_id
502 repo_id = Repository.get_by_repo_name(repo_name).repo_id
503 user_id = User.get_by_username('default').user_id
503 user_id = User.get_by_username('default').user_id
504 self.scm_model.toggle_following_repo(repo_id, user_id)
504 self.scm_model.toggle_following_repo(repo_id, user_id)
505 h.flash(_('Updated repository visibility in public journal'),
505 h.flash(_('Updated repository visibility in public journal'),
506 category='success')
506 category='success')
507 Session().commit()
507 Session().commit()
508 except Exception:
508 except Exception:
509 h.flash(_('An error occurred during setting this'
509 h.flash(_('An error occurred during setting this'
510 ' repository in public journal'),
510 ' repository in public journal'),
511 category='error')
511 category='error')
512
512
513 else:
513 else:
514 h.flash(_('Token mismatch'), category='error')
514 h.flash(_('Token mismatch'), category='error')
515 return redirect(url('edit_repo', repo_name=repo_name))
515 return redirect(url('edit_repo', repo_name=repo_name))
516
516
517 @HasRepoPermissionAllDecorator('repository.admin')
517 @HasRepoPermissionAllDecorator('repository.admin')
518 def repo_pull(self, repo_name):
518 def repo_pull(self, repo_name):
519 """
519 """
520 Runs task to update given repository with remote changes,
520 Runs task to update given repository with remote changes,
521 ie. make pull on remote location
521 ie. make pull on remote location
522
522
523 :param repo_name:
523 :param repo_name:
524 """
524 """
525 try:
525 try:
526 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
526 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
527 h.flash(_('Pulled from remote location'), category='success')
527 h.flash(_('Pulled from remote location'), category='success')
528 except Exception, e:
528 except Exception, e:
529 h.flash(_('An error occurred during pull from remote location'),
529 h.flash(_('An error occurred during pull from remote location'),
530 category='error')
530 category='error')
531
531
532 return redirect(url('edit_repo', repo_name=repo_name))
532 return redirect(url('edit_repo', repo_name=repo_name))
533
533
534 @HasRepoPermissionAllDecorator('repository.admin')
534 @HasRepoPermissionAllDecorator('repository.admin')
535 def repo_as_fork(self, repo_name):
535 def repo_as_fork(self, repo_name):
536 """
536 """
537 Mark given repository as a fork of another
537 Mark given repository as a fork of another
538
538
539 :param repo_name:
539 :param repo_name:
540 """
540 """
541 try:
541 try:
542 fork_id = request.POST.get('id_fork_of')
542 fork_id = request.POST.get('id_fork_of')
543 repo = ScmModel().mark_as_fork(repo_name, fork_id,
543 repo = ScmModel().mark_as_fork(repo_name, fork_id,
544 self.rhodecode_user.username)
544 self.rhodecode_user.username)
545 fork = repo.fork.repo_name if repo.fork else _('Nothing')
545 fork = repo.fork.repo_name if repo.fork else _('Nothing')
546 Session().commit()
546 Session().commit()
547 h.flash(_('Marked repo %s as fork of %s') % (repo_name, fork),
547 h.flash(_('Marked repo %s as fork of %s') % (repo_name, fork),
548 category='success')
548 category='success')
549 except Exception, e:
549 except Exception, e:
550 log.error(traceback.format_exc())
550 log.error(traceback.format_exc())
551 h.flash(_('An error occurred during this operation'),
551 h.flash(_('An error occurred during this operation'),
552 category='error')
552 category='error')
553
553
554 return redirect(url('edit_repo', repo_name=repo_name))
554 return redirect(url('edit_repo', repo_name=repo_name))
555
555
556 @HasPermissionAllDecorator('hg.admin')
556 @HasPermissionAllDecorator('hg.admin')
557 def show(self, repo_name, format='html'):
557 def show(self, repo_name, format='html'):
558 """GET /repos/repo_name: Show a specific item"""
558 """GET /repos/repo_name: Show a specific item"""
559 # url('repo', repo_name=ID)
559 # url('repo', repo_name=ID)
560
560
561 @HasRepoPermissionAllDecorator('repository.admin')
561 @HasRepoPermissionAllDecorator('repository.admin')
562 def edit(self, repo_name, format='html'):
562 def edit(self, repo_name, format='html'):
563 """GET /repos/repo_name/edit: Form to edit an existing item"""
563 """GET /repos/repo_name/edit: Form to edit an existing item"""
564 # url('edit_repo', repo_name=ID)
564 # url('edit_repo', repo_name=ID)
565 defaults = self.__load_data(repo_name)
565 defaults = self.__load_data(repo_name)
566
566
567 return htmlfill.render(
567 return htmlfill.render(
568 render('admin/repos/repo_edit.html'),
568 render('admin/repos/repo_edit.html'),
569 defaults=defaults,
569 defaults=defaults,
570 encoding="UTF-8",
570 encoding="UTF-8",
571 force_defaults=False
571 force_defaults=False
572 )
572 )
573
573
574 @HasPermissionAllDecorator('hg.admin')
574 @HasPermissionAllDecorator('hg.admin')
575 def create_repo_field(self, repo_name):
575 def create_repo_field(self, repo_name):
576 try:
576 try:
577 form_result = RepoFieldForm()().to_python(dict(request.POST))
577 form_result = RepoFieldForm()().to_python(dict(request.POST))
578 new_field = RepositoryField()
578 new_field = RepositoryField()
579 new_field.repository = Repository.get_by_repo_name(repo_name)
579 new_field.repository = Repository.get_by_repo_name(repo_name)
580 new_field.field_key = form_result['new_field_key']
580 new_field.field_key = form_result['new_field_key']
581 new_field.field_type = form_result['new_field_type'] # python type
581 new_field.field_type = form_result['new_field_type'] # python type
582 new_field.field_value = form_result['new_field_value'] # set initial blank value
582 new_field.field_value = form_result['new_field_value'] # set initial blank value
583 new_field.field_desc = form_result['new_field_desc']
583 new_field.field_desc = form_result['new_field_desc']
584 new_field.field_label = form_result['new_field_label']
584 new_field.field_label = form_result['new_field_label']
585 Session().add(new_field)
585 Session().add(new_field)
586 Session().commit()
586 Session().commit()
587
587
588 except Exception, e:
588 except Exception, e:
589 log.error(traceback.format_exc())
589 log.error(traceback.format_exc())
590 msg = _('An error occurred during creation of field')
590 msg = _('An error occurred during creation of field')
591 if isinstance(e, formencode.Invalid):
591 if isinstance(e, formencode.Invalid):
592 msg += ". " + e.msg
592 msg += ". " + e.msg
593 h.flash(msg, category='error')
593 h.flash(msg, category='error')
594 return redirect(url('edit_repo', repo_name=repo_name))
594 return redirect(url('edit_repo', repo_name=repo_name))
595
595
596 @HasPermissionAllDecorator('hg.admin')
596 @HasPermissionAllDecorator('hg.admin')
597 def delete_repo_field(self, repo_name, field_id):
597 def delete_repo_field(self, repo_name, field_id):
598 field = RepositoryField.get_or_404(field_id)
598 field = RepositoryField.get_or_404(field_id)
599 try:
599 try:
600 Session().delete(field)
600 Session().delete(field)
601 Session().commit()
601 Session().commit()
602 except Exception, e:
602 except Exception, e:
603 log.error(traceback.format_exc())
603 log.error(traceback.format_exc())
604 msg = _('An error occurred during removal of field')
604 msg = _('An error occurred during removal of field')
605 h.flash(msg, category='error')
605 h.flash(msg, category='error')
606 return redirect(url('edit_repo', repo_name=repo_name))
606 return redirect(url('edit_repo', repo_name=repo_name))
General Comments 0
You need to be logged in to leave comments. Login now