##// END OF EJS Templates
fixes #732
marcink -
r3236:48b176df beta
parent child Browse files
Show More
@@ -1,175 +1,180
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.forks
3 rhodecode.controllers.forks
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 forks controller for rhodecode
6 forks controller for rhodecode
7
7
8 :created_on: Apr 23, 2011
8 :created_on: Apr 23, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2011-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 import logging
25 import logging
26 import formencode
26 import formencode
27 import traceback
27 import traceback
28 from formencode import htmlfill
28 from formencode import htmlfill
29
29
30 from pylons import tmpl_context as c, request, url
30 from pylons import tmpl_context as c, request, url
31 from pylons.controllers.util import redirect
31 from pylons.controllers.util import redirect
32 from pylons.i18n.translation import _
32 from pylons.i18n.translation import _
33
33
34 import rhodecode.lib.helpers as h
34 import rhodecode.lib.helpers as h
35
35
36 from rhodecode.lib.helpers import Page
36 from rhodecode.lib.helpers import Page
37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, \
37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, \
38 NotAnonymous, HasRepoPermissionAny, HasPermissionAllDecorator,\
38 NotAnonymous, HasRepoPermissionAny, HasPermissionAllDecorator,\
39 HasPermissionAnyDecorator
39 HasPermissionAnyDecorator
40 from rhodecode.lib.base import BaseRepoController, render
40 from rhodecode.lib.base import BaseRepoController, render
41 from rhodecode.model.db import Repository, RepoGroup, UserFollowing, User
41 from rhodecode.model.db import Repository, RepoGroup, UserFollowing, User
42 from rhodecode.model.repo import RepoModel
42 from rhodecode.model.repo import RepoModel
43 from rhodecode.model.forms import RepoForkForm
43 from rhodecode.model.forms import RepoForkForm
44 from rhodecode.model.scm import ScmModel
44 from rhodecode.model.scm import ScmModel
45 from rhodecode.lib.utils2 import safe_int
45 from rhodecode.lib.utils2 import safe_int
46
46
47 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
48
48
49
49
50 class ForksController(BaseRepoController):
50 class ForksController(BaseRepoController):
51
51
52 @LoginRequired()
52 @LoginRequired()
53 def __before__(self):
53 def __before__(self):
54 super(ForksController, self).__before__()
54 super(ForksController, self).__before__()
55
55
56 def __load_defaults(self):
56 def __load_defaults(self):
57 c.repo_groups = RepoGroup.groups_choices(check_perms=True)
57 c.repo_groups = RepoGroup.groups_choices(check_perms=True)
58 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
58 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
59 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
59 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
60 c.landing_revs_choices = choices
60 c.landing_revs_choices = choices
61
61
62 def __load_data(self, repo_name=None):
62 def __load_data(self, repo_name=None):
63 """
63 """
64 Load defaults settings for edit, and update
64 Load defaults settings for edit, and update
65
65
66 :param repo_name:
66 :param repo_name:
67 """
67 """
68 self.__load_defaults()
68 self.__load_defaults()
69
69
70 c.repo_info = db_repo = Repository.get_by_repo_name(repo_name)
70 c.repo_info = db_repo = Repository.get_by_repo_name(repo_name)
71 repo = db_repo.scm_instance
71 repo = db_repo.scm_instance
72
72
73 if c.repo_info is None:
73 if c.repo_info is None:
74 h.not_mapped_error(repo_name)
74 h.not_mapped_error(repo_name)
75 return redirect(url('repos'))
75 return redirect(url('repos'))
76
76
77 c.default_user_id = User.get_by_username('default').user_id
77 c.default_user_id = User.get_by_username('default').user_id
78 c.in_public_journal = UserFollowing.query()\
78 c.in_public_journal = UserFollowing.query()\
79 .filter(UserFollowing.user_id == c.default_user_id)\
79 .filter(UserFollowing.user_id == c.default_user_id)\
80 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
80 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
81
81
82 if c.repo_info.stats:
82 if c.repo_info.stats:
83 last_rev = c.repo_info.stats.stat_on_revision+1
83 last_rev = c.repo_info.stats.stat_on_revision+1
84 else:
84 else:
85 last_rev = 0
85 last_rev = 0
86 c.stats_revision = last_rev
86 c.stats_revision = last_rev
87
87
88 c.repo_last_rev = repo.count() if repo.revisions else 0
88 c.repo_last_rev = repo.count() if repo.revisions else 0
89
89
90 if last_rev == 0 or c.repo_last_rev == 0:
90 if last_rev == 0 or c.repo_last_rev == 0:
91 c.stats_percentage = 0
91 c.stats_percentage = 0
92 else:
92 else:
93 c.stats_percentage = '%.2f' % ((float((last_rev)) /
93 c.stats_percentage = '%.2f' % ((float((last_rev)) /
94 c.repo_last_rev) * 100)
94 c.repo_last_rev) * 100)
95
95
96 defaults = RepoModel()._get_defaults(repo_name)
96 defaults = RepoModel()._get_defaults(repo_name)
97 # alter the description to indicate a fork
98 defaults['description'] = ('fork of repository: %s \n%s'
99 % (defaults['repo_name'],
100 defaults['description']))
97 # add suffix to fork
101 # add suffix to fork
98 defaults['repo_name'] = '%s-fork' % defaults['repo_name']
102 defaults['repo_name'] = '%s-fork' % defaults['repo_name']
103
99 return defaults
104 return defaults
100
105
101 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
106 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
102 'repository.admin')
107 'repository.admin')
103 def forks(self, repo_name):
108 def forks(self, repo_name):
104 p = safe_int(request.params.get('page', 1), 1)
109 p = safe_int(request.params.get('page', 1), 1)
105 repo_id = c.rhodecode_db_repo.repo_id
110 repo_id = c.rhodecode_db_repo.repo_id
106 d = []
111 d = []
107 for r in Repository.get_repo_forks(repo_id):
112 for r in Repository.get_repo_forks(repo_id):
108 if not HasRepoPermissionAny(
113 if not HasRepoPermissionAny(
109 'repository.read', 'repository.write', 'repository.admin'
114 'repository.read', 'repository.write', 'repository.admin'
110 )(r.repo_name, 'get forks check'):
115 )(r.repo_name, 'get forks check'):
111 continue
116 continue
112 d.append(r)
117 d.append(r)
113 c.forks_pager = Page(d, page=p, items_per_page=20)
118 c.forks_pager = Page(d, page=p, items_per_page=20)
114
119
115 c.forks_data = render('/forks/forks_data.html')
120 c.forks_data = render('/forks/forks_data.html')
116
121
117 if request.environ.get('HTTP_X_PARTIAL_XHR'):
122 if request.environ.get('HTTP_X_PARTIAL_XHR'):
118 return c.forks_data
123 return c.forks_data
119
124
120 return render('/forks/forks.html')
125 return render('/forks/forks.html')
121
126
122 @NotAnonymous()
127 @NotAnonymous()
123 @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
128 @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
124 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
129 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
125 'repository.admin')
130 'repository.admin')
126 def fork(self, repo_name):
131 def fork(self, repo_name):
127 c.repo_info = Repository.get_by_repo_name(repo_name)
132 c.repo_info = Repository.get_by_repo_name(repo_name)
128 if not c.repo_info:
133 if not c.repo_info:
129 h.not_mapped_error(repo_name)
134 h.not_mapped_error(repo_name)
130 return redirect(url('home'))
135 return redirect(url('home'))
131
136
132 defaults = self.__load_data(repo_name)
137 defaults = self.__load_data(repo_name)
133
138
134 return htmlfill.render(
139 return htmlfill.render(
135 render('forks/fork.html'),
140 render('forks/fork.html'),
136 defaults=defaults,
141 defaults=defaults,
137 encoding="UTF-8",
142 encoding="UTF-8",
138 force_defaults=False
143 force_defaults=False
139 )
144 )
140
145
141 @NotAnonymous()
146 @NotAnonymous()
142 @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
147 @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
143 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
148 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
144 'repository.admin')
149 'repository.admin')
145 def fork_create(self, repo_name):
150 def fork_create(self, repo_name):
146 self.__load_defaults()
151 self.__load_defaults()
147 c.repo_info = Repository.get_by_repo_name(repo_name)
152 c.repo_info = Repository.get_by_repo_name(repo_name)
148 _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type},
153 _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type},
149 repo_groups=c.repo_groups_choices,
154 repo_groups=c.repo_groups_choices,
150 landing_revs=c.landing_revs_choices)()
155 landing_revs=c.landing_revs_choices)()
151 form_result = {}
156 form_result = {}
152 try:
157 try:
153 form_result = _form.to_python(dict(request.POST))
158 form_result = _form.to_python(dict(request.POST))
154
159
155 # create fork is done sometimes async on celery, db transaction
160 # create fork is done sometimes async on celery, db transaction
156 # management is handled there.
161 # management is handled there.
157 RepoModel().create_fork(form_result, self.rhodecode_user.user_id)
162 RepoModel().create_fork(form_result, self.rhodecode_user.user_id)
158 h.flash(_('forked %s repository as %s') \
163 h.flash(_('forked %s repository as %s') \
159 % (repo_name, form_result['repo_name']),
164 % (repo_name, form_result['repo_name']),
160 category='success')
165 category='success')
161 except formencode.Invalid, errors:
166 except formencode.Invalid, errors:
162 c.new_repo = errors.value['repo_name']
167 c.new_repo = errors.value['repo_name']
163
168
164 return htmlfill.render(
169 return htmlfill.render(
165 render('forks/fork.html'),
170 render('forks/fork.html'),
166 defaults=errors.value,
171 defaults=errors.value,
167 errors=errors.error_dict or {},
172 errors=errors.error_dict or {},
168 prefix_error=False,
173 prefix_error=False,
169 encoding="UTF-8")
174 encoding="UTF-8")
170 except Exception:
175 except Exception:
171 log.error(traceback.format_exc())
176 log.error(traceback.format_exc())
172 h.flash(_('An error occurred during repository forking %s') %
177 h.flash(_('An error occurred during repository forking %s') %
173 repo_name, category='error')
178 repo_name, category='error')
174
179
175 return redirect(url('home'))
180 return redirect(url('home'))
General Comments 0
You need to be logged in to leave comments. Login now