##// END OF EJS Templates
Opening pull request shouldn't be accessible by anonymous users
marcink -
r2627:6bd62617 beta
parent child Browse files
Show More
@@ -1,353 +1,356
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.pullrequests
3 rhodecode.controllers.pullrequests
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 pull requests controller for rhodecode for initializing pull requests
6 pull requests controller for rhodecode for initializing pull requests
7
7
8 :created_on: May 7, 2012
8 :created_on: May 7, 2012
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 import logging
25 import logging
26 import traceback
26 import traceback
27
27
28 from webob.exc import HTTPNotFound, HTTPForbidden
28 from webob.exc import HTTPNotFound, HTTPForbidden
29 from collections import defaultdict
29 from collections import defaultdict
30 from itertools import groupby
30 from itertools import groupby
31
31
32 from pylons import request, response, session, tmpl_context as c, url
32 from pylons import request, response, session, tmpl_context as c, url
33 from pylons.controllers.util import abort, redirect
33 from pylons.controllers.util import abort, redirect
34 from pylons.i18n.translation import _
34 from pylons.i18n.translation import _
35 from pylons.decorators import jsonify
35 from pylons.decorators import jsonify
36
36
37 from rhodecode.lib.compat import json
37 from rhodecode.lib.compat import json
38 from rhodecode.lib.base import BaseRepoController, render
38 from rhodecode.lib.base import BaseRepoController, render
39 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator,\
39 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator,\
40 NotAnonymous
40 NotAnonymous
41 from rhodecode.lib import helpers as h
41 from rhodecode.lib import helpers as h
42 from rhodecode.lib import diffs
42 from rhodecode.lib import diffs
43 from rhodecode.lib.utils import action_logger
43 from rhodecode.lib.utils import action_logger
44 from rhodecode.model.db import User, PullRequest, ChangesetStatus,\
44 from rhodecode.model.db import User, PullRequest, ChangesetStatus,\
45 ChangesetComment
45 ChangesetComment
46 from rhodecode.model.pull_request import PullRequestModel
46 from rhodecode.model.pull_request import PullRequestModel
47 from rhodecode.model.meta import Session
47 from rhodecode.model.meta import Session
48 from rhodecode.model.repo import RepoModel
48 from rhodecode.model.repo import RepoModel
49 from rhodecode.model.comment import ChangesetCommentsModel
49 from rhodecode.model.comment import ChangesetCommentsModel
50 from rhodecode.model.changeset_status import ChangesetStatusModel
50 from rhodecode.model.changeset_status import ChangesetStatusModel
51
51
52 log = logging.getLogger(__name__)
52 log = logging.getLogger(__name__)
53
53
54
54
55 class PullrequestsController(BaseRepoController):
55 class PullrequestsController(BaseRepoController):
56
56
57 @LoginRequired()
57 @LoginRequired()
58 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
58 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
59 'repository.admin')
59 'repository.admin')
60 def __before__(self):
60 def __before__(self):
61 super(PullrequestsController, self).__before__()
61 super(PullrequestsController, self).__before__()
62 repo_model = RepoModel()
62 repo_model = RepoModel()
63 c.users_array = repo_model.get_users_js()
63 c.users_array = repo_model.get_users_js()
64 c.users_groups_array = repo_model.get_users_groups_js()
64 c.users_groups_array = repo_model.get_users_groups_js()
65
65
66 def _get_repo_refs(self, repo):
66 def _get_repo_refs(self, repo):
67 hist_l = []
67 hist_l = []
68
68
69 branches_group = ([('branch:%s:%s' % (k, v), k) for
69 branches_group = ([('branch:%s:%s' % (k, v), k) for
70 k, v in repo.branches.iteritems()], _("Branches"))
70 k, v in repo.branches.iteritems()], _("Branches"))
71 bookmarks_group = ([('book:%s:%s' % (k, v), k) for
71 bookmarks_group = ([('book:%s:%s' % (k, v), k) for
72 k, v in repo.bookmarks.iteritems()], _("Bookmarks"))
72 k, v in repo.bookmarks.iteritems()], _("Bookmarks"))
73 tags_group = ([('tag:%s:%s' % (k, v), k) for
73 tags_group = ([('tag:%s:%s' % (k, v), k) for
74 k, v in repo.tags.iteritems()], _("Tags"))
74 k, v in repo.tags.iteritems()], _("Tags"))
75
75
76 hist_l.append(bookmarks_group)
76 hist_l.append(bookmarks_group)
77 hist_l.append(branches_group)
77 hist_l.append(branches_group)
78 hist_l.append(tags_group)
78 hist_l.append(tags_group)
79
79
80 return hist_l
80 return hist_l
81
81
82 def show_all(self, repo_name):
82 def show_all(self, repo_name):
83 c.pull_requests = PullRequestModel().get_all(repo_name)
83 c.pull_requests = PullRequestModel().get_all(repo_name)
84 c.repo_name = repo_name
84 c.repo_name = repo_name
85 return render('/pullrequests/pullrequest_show_all.html')
85 return render('/pullrequests/pullrequest_show_all.html')
86
86
87 @NotAnonymous()
87 def index(self):
88 def index(self):
88 org_repo = c.rhodecode_db_repo
89 org_repo = c.rhodecode_db_repo
89
90
90 if org_repo.scm_instance.alias != 'hg':
91 if org_repo.scm_instance.alias != 'hg':
91 log.error('Review not available for GIT REPOS')
92 log.error('Review not available for GIT REPOS')
92 raise HTTPNotFound
93 raise HTTPNotFound
93
94
94 other_repos_info = {}
95 other_repos_info = {}
95
96
96 c.org_refs = self._get_repo_refs(c.rhodecode_repo)
97 c.org_refs = self._get_repo_refs(c.rhodecode_repo)
97 c.org_repos = []
98 c.org_repos = []
98 c.other_repos = []
99 c.other_repos = []
99 c.org_repos.append((org_repo.repo_name, '%s/%s' % (
100 c.org_repos.append((org_repo.repo_name, '%s/%s' % (
100 org_repo.user.username, c.repo_name))
101 org_repo.user.username, c.repo_name))
101 )
102 )
102
103
103 c.other_refs = c.org_refs
104 c.other_refs = c.org_refs
104 c.other_repos.extend(c.org_repos)
105 c.other_repos.extend(c.org_repos)
105
106
106 #add orginal repo
107 #add orginal repo
107 other_repos_info[org_repo.repo_name] = {
108 other_repos_info[org_repo.repo_name] = {
108 'gravatar': h.gravatar_url(org_repo.user.email, 24),
109 'gravatar': h.gravatar_url(org_repo.user.email, 24),
109 'description': org_repo.description
110 'description': org_repo.description
110 }
111 }
111
112
112 c.default_pull_request = org_repo.repo_name
113 c.default_pull_request = org_repo.repo_name
113 #gather forks and add to this list
114 #gather forks and add to this list
114 for fork in org_repo.forks:
115 for fork in org_repo.forks:
115 c.other_repos.append((fork.repo_name, '%s/%s' % (
116 c.other_repos.append((fork.repo_name, '%s/%s' % (
116 fork.user.username, fork.repo_name))
117 fork.user.username, fork.repo_name))
117 )
118 )
118 other_repos_info[fork.repo_name] = {
119 other_repos_info[fork.repo_name] = {
119 'gravatar': h.gravatar_url(fork.user.email, 24),
120 'gravatar': h.gravatar_url(fork.user.email, 24),
120 'description': fork.description
121 'description': fork.description
121 }
122 }
122 #add parents of this fork also
123 #add parents of this fork also
123 if org_repo.parent:
124 if org_repo.parent:
124 c.default_pull_request = org_repo.parent.repo_name
125 c.default_pull_request = org_repo.parent.repo_name
125 c.other_repos.append((org_repo.parent.repo_name, '%s/%s' % (
126 c.other_repos.append((org_repo.parent.repo_name, '%s/%s' % (
126 org_repo.parent.user.username,
127 org_repo.parent.user.username,
127 org_repo.parent.repo_name))
128 org_repo.parent.repo_name))
128 )
129 )
129 other_repos_info[org_repo.parent.repo_name] = {
130 other_repos_info[org_repo.parent.repo_name] = {
130 'gravatar': h.gravatar_url(org_repo.parent.user.email, 24),
131 'gravatar': h.gravatar_url(org_repo.parent.user.email, 24),
131 'description': org_repo.parent.description
132 'description': org_repo.parent.description
132 }
133 }
133
134
134 c.other_repos_info = json.dumps(other_repos_info)
135 c.other_repos_info = json.dumps(other_repos_info)
135 c.review_members = [org_repo.user]
136 c.review_members = [org_repo.user]
136 return render('/pullrequests/pullrequest.html')
137 return render('/pullrequests/pullrequest.html')
137
138
138 @NotAnonymous()
139 @NotAnonymous()
139 def create(self, repo_name):
140 def create(self, repo_name):
140 req_p = request.POST
141 req_p = request.POST
141 org_repo = req_p['org_repo']
142 org_repo = req_p['org_repo']
142 org_ref = req_p['org_ref']
143 org_ref = req_p['org_ref']
143 other_repo = req_p['other_repo']
144 other_repo = req_p['other_repo']
144 other_ref = req_p['other_ref']
145 other_ref = req_p['other_ref']
145 revisions = req_p.getall('revisions')
146 revisions = req_p.getall('revisions')
146 reviewers = req_p.getall('review_members')
147 reviewers = req_p.getall('review_members')
147
148
148 #TODO: wrap this into a FORM !!!
149 #TODO: wrap this into a FORM !!!
149
150
150 title = req_p['pullrequest_title']
151 title = req_p['pullrequest_title']
151 description = req_p['pullrequest_desc']
152 description = req_p['pullrequest_desc']
152
153
153 try:
154 try:
154 pull_request = PullRequestModel().create(
155 pull_request = PullRequestModel().create(
155 self.rhodecode_user.user_id, org_repo, org_ref, other_repo,
156 self.rhodecode_user.user_id, org_repo, org_ref, other_repo,
156 other_ref, revisions, reviewers, title, description
157 other_ref, revisions, reviewers, title, description
157 )
158 )
158 Session().commit()
159 Session().commit()
159 h.flash(_('Successfully opened new pull request'),
160 h.flash(_('Successfully opened new pull request'),
160 category='success')
161 category='success')
161 except Exception:
162 except Exception:
162 h.flash(_('Error occurred during sending pull request'),
163 h.flash(_('Error occurred during sending pull request'),
163 category='error')
164 category='error')
164 log.error(traceback.format_exc())
165 log.error(traceback.format_exc())
165 return redirect(url('changelog_home', repo_name=org_repo,))
166 return redirect(url('changelog_home', repo_name=org_repo,))
166
167
167 return redirect(url('pullrequest_show', repo_name=other_repo,
168 return redirect(url('pullrequest_show', repo_name=other_repo,
168 pull_request_id=pull_request.pull_request_id))
169 pull_request_id=pull_request.pull_request_id))
169
170
170 @NotAnonymous()
171 @NotAnonymous()
171 @jsonify
172 @jsonify
172 def update(self, repo_name, pull_request_id):
173 def update(self, repo_name, pull_request_id):
173 pull_request = PullRequest.get_or_404(pull_request_id)
174 pull_request = PullRequest.get_or_404(pull_request_id)
174 if pull_request.is_closed():
175 if pull_request.is_closed():
175 raise HTTPForbidden()
176 raise HTTPForbidden()
176
177
177 reviewers_ids = map(int, filter(lambda v: v not in [None, ''],
178 reviewers_ids = map(int, filter(lambda v: v not in [None, ''],
178 request.POST.get('reviewers_ids', '').split(',')))
179 request.POST.get('reviewers_ids', '').split(',')))
179 PullRequestModel().update_reviewers(pull_request_id, reviewers_ids)
180 PullRequestModel().update_reviewers(pull_request_id, reviewers_ids)
180 Session.commit()
181 Session.commit()
181 return True
182 return True
182
183
183 def _load_compare_data(self, pull_request, enable_comments=True):
184 def _load_compare_data(self, pull_request, enable_comments=True):
184 """
185 """
185 Load context data needed for generating compare diff
186 Load context data needed for generating compare diff
186
187
187 :param pull_request:
188 :param pull_request:
188 :type pull_request:
189 :type pull_request:
189 """
190 """
190
191
191 org_repo = pull_request.org_repo
192 org_repo = pull_request.org_repo
192 org_ref_type, org_ref_, org_ref = pull_request.org_ref.split(':')
193 org_ref_type, org_ref_, org_ref = pull_request.org_ref.split(':')
193 other_repo = pull_request.other_repo
194 other_repo = pull_request.other_repo
194 other_ref_type, other_ref, other_ref_ = pull_request.other_ref.split(':')
195 other_ref_type, other_ref, other_ref_ = pull_request.other_ref.split(':')
195
196
196 org_ref = (org_ref_type, org_ref)
197 org_ref = (org_ref_type, org_ref)
197 other_ref = (other_ref_type, other_ref)
198 other_ref = (other_ref_type, other_ref)
198
199
199 c.org_repo = org_repo
200 c.org_repo = org_repo
200 c.other_repo = other_repo
201 c.other_repo = other_repo
201
202
202 c.cs_ranges, discovery_data = PullRequestModel().get_compare_data(
203 c.cs_ranges, discovery_data = PullRequestModel().get_compare_data(
203 org_repo, org_ref, other_repo, other_ref
204 org_repo, org_ref, other_repo, other_ref
204 )
205 )
205
206
206 c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
207 c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
207 c.cs_ranges])
208 c.cs_ranges])
208 # defines that we need hidden inputs with changesets
209 # defines that we need hidden inputs with changesets
209 c.as_form = request.GET.get('as_form', False)
210 c.as_form = request.GET.get('as_form', False)
210
211
211 c.org_ref = org_ref[1]
212 c.org_ref = org_ref[1]
212 c.other_ref = other_ref[1]
213 c.other_ref = other_ref[1]
213 # diff needs to have swapped org with other to generate proper diff
214 # diff needs to have swapped org with other to generate proper diff
214 _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref,
215 _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref,
215 discovery_data)
216 discovery_data)
216 diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
217 diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
217 _parsed = diff_processor.prepare()
218 _parsed = diff_processor.prepare()
218
219
219 c.files = []
220 c.files = []
220 c.changes = {}
221 c.changes = {}
221
222
222 for f in _parsed:
223 for f in _parsed:
223 fid = h.FID('', f['filename'])
224 fid = h.FID('', f['filename'])
224 c.files.append([fid, f['operation'], f['filename'], f['stats']])
225 c.files.append([fid, f['operation'], f['filename'], f['stats']])
225 diff = diff_processor.as_html(enable_comments=enable_comments,
226 diff = diff_processor.as_html(enable_comments=enable_comments,
226 diff_lines=[f])
227 diff_lines=[f])
227 c.changes[fid] = [f['operation'], f['filename'], diff]
228 c.changes[fid] = [f['operation'], f['filename'], diff]
228
229
229 def show(self, repo_name, pull_request_id):
230 def show(self, repo_name, pull_request_id):
230 repo_model = RepoModel()
231 repo_model = RepoModel()
231 c.users_array = repo_model.get_users_js()
232 c.users_array = repo_model.get_users_js()
232 c.users_groups_array = repo_model.get_users_groups_js()
233 c.users_groups_array = repo_model.get_users_groups_js()
233 c.pull_request = PullRequest.get_or_404(pull_request_id)
234 c.pull_request = PullRequest.get_or_404(pull_request_id)
234
235
235 cc_model = ChangesetCommentsModel()
236 cc_model = ChangesetCommentsModel()
236 cs_model = ChangesetStatusModel()
237 cs_model = ChangesetStatusModel()
237 _cs_statuses = cs_model.get_statuses(c.pull_request.org_repo,
238 _cs_statuses = cs_model.get_statuses(c.pull_request.org_repo,
238 pull_request=c.pull_request,
239 pull_request=c.pull_request,
239 with_revisions=True)
240 with_revisions=True)
240
241
241 cs_statuses = defaultdict(list)
242 cs_statuses = defaultdict(list)
242 for st in _cs_statuses:
243 for st in _cs_statuses:
243 cs_statuses[st.author.username] += [st]
244 cs_statuses[st.author.username] += [st]
244
245
245 c.pull_request_reviewers = []
246 c.pull_request_reviewers = []
246 for o in c.pull_request.reviewers:
247 for o in c.pull_request.reviewers:
247 st = cs_statuses.get(o.user.username, None)
248 st = cs_statuses.get(o.user.username, None)
248 if st:
249 if st:
249 sorter = lambda k: k.version
250 sorter = lambda k: k.version
250 st = [(x, list(y)[0])
251 st = [(x, list(y)[0])
251 for x, y in (groupby(sorted(st, key=sorter), sorter))]
252 for x, y in (groupby(sorted(st, key=sorter), sorter))]
252 c.pull_request_reviewers.append([o.user, st])
253 c.pull_request_reviewers.append([o.user, st])
253
254
254 # pull_requests repo_name we opened it against
255 # pull_requests repo_name we opened it against
255 # ie. other_repo must match
256 # ie. other_repo must match
256 if repo_name != c.pull_request.other_repo.repo_name:
257 if repo_name != c.pull_request.other_repo.repo_name:
257 raise HTTPNotFound
258 raise HTTPNotFound
258
259
259 # load compare data into template context
260 # load compare data into template context
260 enable_comments = not c.pull_request.is_closed()
261 enable_comments = not c.pull_request.is_closed()
261 self._load_compare_data(c.pull_request, enable_comments=enable_comments)
262 self._load_compare_data(c.pull_request, enable_comments=enable_comments)
262
263
263 # inline comments
264 # inline comments
264 c.inline_cnt = 0
265 c.inline_cnt = 0
265 c.inline_comments = cc_model.get_inline_comments(
266 c.inline_comments = cc_model.get_inline_comments(
266 c.rhodecode_db_repo.repo_id,
267 c.rhodecode_db_repo.repo_id,
267 pull_request=pull_request_id)
268 pull_request=pull_request_id)
268 # count inline comments
269 # count inline comments
269 for __, lines in c.inline_comments:
270 for __, lines in c.inline_comments:
270 for comments in lines.values():
271 for comments in lines.values():
271 c.inline_cnt += len(comments)
272 c.inline_cnt += len(comments)
272 # comments
273 # comments
273 c.comments = cc_model.get_comments(c.rhodecode_db_repo.repo_id,
274 c.comments = cc_model.get_comments(c.rhodecode_db_repo.repo_id,
274 pull_request=pull_request_id)
275 pull_request=pull_request_id)
275
276
276 # changeset(pull-request) status
277 # changeset(pull-request) status
277 c.current_changeset_status = cs_model.calculate_status(
278 c.current_changeset_status = cs_model.calculate_status(
278 c.pull_request_reviewers
279 c.pull_request_reviewers
279 )
280 )
280 c.changeset_statuses = ChangesetStatus.STATUSES
281 c.changeset_statuses = ChangesetStatus.STATUSES
281 c.target_repo = c.pull_request.org_repo.repo_name
282 c.target_repo = c.pull_request.org_repo.repo_name
282 return render('/pullrequests/pullrequest_show.html')
283 return render('/pullrequests/pullrequest_show.html')
283
284
285 @NotAnonymous()
284 @jsonify
286 @jsonify
285 def comment(self, repo_name, pull_request_id):
287 def comment(self, repo_name, pull_request_id):
286 pull_request = PullRequest.get_or_404(pull_request_id)
288 pull_request = PullRequest.get_or_404(pull_request_id)
287 if pull_request.is_closed():
289 if pull_request.is_closed():
288 raise HTTPForbidden()
290 raise HTTPForbidden()
289
291
290 status = request.POST.get('changeset_status')
292 status = request.POST.get('changeset_status')
291 change_status = request.POST.get('change_changeset_status')
293 change_status = request.POST.get('change_changeset_status')
292
294
293 comm = ChangesetCommentsModel().create(
295 comm = ChangesetCommentsModel().create(
294 text=request.POST.get('text'),
296 text=request.POST.get('text'),
295 repo=c.rhodecode_db_repo.repo_id,
297 repo=c.rhodecode_db_repo.repo_id,
296 user=c.rhodecode_user.user_id,
298 user=c.rhodecode_user.user_id,
297 pull_request=pull_request_id,
299 pull_request=pull_request_id,
298 f_path=request.POST.get('f_path'),
300 f_path=request.POST.get('f_path'),
299 line_no=request.POST.get('line'),
301 line_no=request.POST.get('line'),
300 status_change=(ChangesetStatus.get_status_lbl(status)
302 status_change=(ChangesetStatus.get_status_lbl(status)
301 if status and change_status else None)
303 if status and change_status else None)
302 )
304 )
303
305
304 # get status if set !
306 # get status if set !
305 if status and change_status:
307 if status and change_status:
306 ChangesetStatusModel().set_status(
308 ChangesetStatusModel().set_status(
307 c.rhodecode_db_repo.repo_id,
309 c.rhodecode_db_repo.repo_id,
308 status,
310 status,
309 c.rhodecode_user.user_id,
311 c.rhodecode_user.user_id,
310 comm,
312 comm,
311 pull_request=pull_request_id
313 pull_request=pull_request_id
312 )
314 )
313 action_logger(self.rhodecode_user,
315 action_logger(self.rhodecode_user,
314 'user_commented_pull_request:%s' % pull_request_id,
316 'user_commented_pull_request:%s' % pull_request_id,
315 c.rhodecode_db_repo, self.ip_addr, self.sa)
317 c.rhodecode_db_repo, self.ip_addr, self.sa)
316
318
317 if request.POST.get('save_close'):
319 if request.POST.get('save_close'):
318 PullRequestModel().close_pull_request(pull_request_id)
320 PullRequestModel().close_pull_request(pull_request_id)
319 action_logger(self.rhodecode_user,
321 action_logger(self.rhodecode_user,
320 'user_closed_pull_request:%s' % pull_request_id,
322 'user_closed_pull_request:%s' % pull_request_id,
321 c.rhodecode_db_repo, self.ip_addr, self.sa)
323 c.rhodecode_db_repo, self.ip_addr, self.sa)
322
324
323 Session().commit()
325 Session().commit()
324
326
325 if not request.environ.get('HTTP_X_PARTIAL_XHR'):
327 if not request.environ.get('HTTP_X_PARTIAL_XHR'):
326 return redirect(h.url('pullrequest_show', repo_name=repo_name,
328 return redirect(h.url('pullrequest_show', repo_name=repo_name,
327 pull_request_id=pull_request_id))
329 pull_request_id=pull_request_id))
328
330
329 data = {
331 data = {
330 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
332 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
331 }
333 }
332 if comm:
334 if comm:
333 c.co = comm
335 c.co = comm
334 data.update(comm.get_dict())
336 data.update(comm.get_dict())
335 data.update({'rendered_text':
337 data.update({'rendered_text':
336 render('changeset/changeset_comment_block.html')})
338 render('changeset/changeset_comment_block.html')})
337
339
338 return data
340 return data
339
341
342 @NotAnonymous()
340 @jsonify
343 @jsonify
341 def delete_comment(self, repo_name, comment_id):
344 def delete_comment(self, repo_name, comment_id):
342 co = ChangesetComment.get(comment_id)
345 co = ChangesetComment.get(comment_id)
343 if co.pull_request.is_closed():
346 if co.pull_request.is_closed():
344 #don't allow deleting comments on closed pull request
347 #don't allow deleting comments on closed pull request
345 raise HTTPForbidden()
348 raise HTTPForbidden()
346
349
347 owner = lambda: co.author.user_id == c.rhodecode_user.user_id
350 owner = lambda: co.author.user_id == c.rhodecode_user.user_id
348 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
351 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
349 ChangesetCommentsModel().delete(comment=co)
352 ChangesetCommentsModel().delete(comment=co)
350 Session().commit()
353 Session().commit()
351 return True
354 return True
352 else:
355 else:
353 raise HTTPForbidden()
356 raise HTTPForbidden()
General Comments 0
You need to be logged in to leave comments. Login now