##// END OF EJS Templates
white space cleanup
marcink -
r2188:56e96d4e beta
parent child Browse files
Show More
@@ -1,391 +1,392 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.changeset
3 rhodecode.controllers.changeset
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 changeset controller for pylons showoing changes beetween
6 changeset controller for pylons showoing changes beetween
7 revisions
7 revisions
8
8
9 :created_on: Apr 25, 2010
9 :created_on: Apr 25, 2010
10 :author: marcink
10 :author: marcink
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software: you can redistribute it and/or modify
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 import logging
26 import logging
27 import traceback
27 import traceback
28 from collections import defaultdict
28 from collections import defaultdict
29 from webob.exc import HTTPForbidden
29 from webob.exc import HTTPForbidden
30
30
31 from pylons import tmpl_context as c, url, request, response
31 from pylons import tmpl_context as c, url, request, response
32 from pylons.i18n.translation import _
32 from pylons.i18n.translation import _
33 from pylons.controllers.util import redirect
33 from pylons.controllers.util import redirect
34 from pylons.decorators import jsonify
34 from pylons.decorators import jsonify
35
35
36 from rhodecode.lib.vcs.exceptions import RepositoryError, ChangesetError, \
36 from rhodecode.lib.vcs.exceptions import RepositoryError, ChangesetError, \
37 ChangesetDoesNotExistError
37 ChangesetDoesNotExistError
38 from rhodecode.lib.vcs.nodes import FileNode
38 from rhodecode.lib.vcs.nodes import FileNode
39
39
40 import rhodecode.lib.helpers as h
40 import rhodecode.lib.helpers as h
41 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
41 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
42 from rhodecode.lib.base import BaseRepoController, render
42 from rhodecode.lib.base import BaseRepoController, render
43 from rhodecode.lib.utils import EmptyChangeset
43 from rhodecode.lib.utils import EmptyChangeset
44 from rhodecode.lib.compat import OrderedDict
44 from rhodecode.lib.compat import OrderedDict
45 from rhodecode.lib import diffs
45 from rhodecode.lib import diffs
46 from rhodecode.model.db import ChangesetComment
46 from rhodecode.model.db import ChangesetComment
47 from rhodecode.model.comment import ChangesetCommentsModel
47 from rhodecode.model.comment import ChangesetCommentsModel
48 from rhodecode.model.meta import Session
48 from rhodecode.model.meta import Session
49 from rhodecode.lib.diffs import wrapped_diff
49 from rhodecode.lib.diffs import wrapped_diff
50
50
51 log = logging.getLogger(__name__)
51 log = logging.getLogger(__name__)
52
52
53
53
54 def _update_with_GET(params, GET):
54 def _update_with_GET(params, GET):
55 for k in ['diff1', 'diff2', 'diff']:
55 for k in ['diff1', 'diff2', 'diff']:
56 params[k] += GET.getall(k)
56 params[k] += GET.getall(k)
57
57
58
58
59 def anchor_url(revision, path, GET):
59 def anchor_url(revision, path, GET):
60 fid = h.FID(revision, path)
60 fid = h.FID(revision, path)
61 return h.url.current(anchor=fid, **dict(GET))
61 return h.url.current(anchor=fid, **dict(GET))
62
62
63
63
64 def get_ignore_ws(fid, GET):
64 def get_ignore_ws(fid, GET):
65 ig_ws_global = GET.get('ignorews')
65 ig_ws_global = GET.get('ignorews')
66 ig_ws = filter(lambda k: k.startswith('WS'), GET.getall(fid))
66 ig_ws = filter(lambda k: k.startswith('WS'), GET.getall(fid))
67 if ig_ws:
67 if ig_ws:
68 try:
68 try:
69 return int(ig_ws[0].split(':')[-1])
69 return int(ig_ws[0].split(':')[-1])
70 except:
70 except:
71 pass
71 pass
72 return ig_ws_global
72 return ig_ws_global
73
73
74
74
75 def _ignorews_url(GET, fileid=None):
75 def _ignorews_url(GET, fileid=None):
76 fileid = str(fileid) if fileid else None
76 fileid = str(fileid) if fileid else None
77 params = defaultdict(list)
77 params = defaultdict(list)
78 _update_with_GET(params, GET)
78 _update_with_GET(params, GET)
79 lbl = _('show white space')
79 lbl = _('show white space')
80 ig_ws = get_ignore_ws(fileid, GET)
80 ig_ws = get_ignore_ws(fileid, GET)
81 ln_ctx = get_line_ctx(fileid, GET)
81 ln_ctx = get_line_ctx(fileid, GET)
82 # global option
82 # global option
83 if fileid is None:
83 if fileid is None:
84 if ig_ws is None:
84 if ig_ws is None:
85 params['ignorews'] += [1]
85 params['ignorews'] += [1]
86 lbl = _('ignore white space')
86 lbl = _('ignore white space')
87 ctx_key = 'context'
87 ctx_key = 'context'
88 ctx_val = ln_ctx
88 ctx_val = ln_ctx
89 # per file options
89 # per file options
90 else:
90 else:
91 if ig_ws is None:
91 if ig_ws is None:
92 params[fileid] += ['WS:1']
92 params[fileid] += ['WS:1']
93 lbl = _('ignore white space')
93 lbl = _('ignore white space')
94
94
95 ctx_key = fileid
95 ctx_key = fileid
96 ctx_val = 'C:%s' % ln_ctx
96 ctx_val = 'C:%s' % ln_ctx
97 # if we have passed in ln_ctx pass it along to our params
97 # if we have passed in ln_ctx pass it along to our params
98 if ln_ctx:
98 if ln_ctx:
99 params[ctx_key] += [ctx_val]
99 params[ctx_key] += [ctx_val]
100
100
101 params['anchor'] = fileid
101 params['anchor'] = fileid
102 img = h.image(h.url('/images/icons/text_strikethrough.png'), lbl, class_='icon')
102 img = h.image(h.url('/images/icons/text_strikethrough.png'), lbl, class_='icon')
103 return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip')
103 return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip')
104
104
105
105
106 def get_line_ctx(fid, GET):
106 def get_line_ctx(fid, GET):
107 ln_ctx_global = GET.get('context')
107 ln_ctx_global = GET.get('context')
108 ln_ctx = filter(lambda k: k.startswith('C'), GET.getall(fid))
108 ln_ctx = filter(lambda k: k.startswith('C'), GET.getall(fid))
109
109
110 if ln_ctx:
110 if ln_ctx:
111 retval = ln_ctx[0].split(':')[-1]
111 retval = ln_ctx[0].split(':')[-1]
112 else:
112 else:
113 retval = ln_ctx_global
113 retval = ln_ctx_global
114
114
115 try:
115 try:
116 return int(retval)
116 return int(retval)
117 except:
117 except:
118 return
118 return
119
119
120
120
121 def _context_url(GET, fileid=None):
121 def _context_url(GET, fileid=None):
122 """
122 """
123 Generates url for context lines
123 Generates url for context lines
124
124
125 :param fileid:
125 :param fileid:
126 """
126 """
127
127
128 fileid = str(fileid) if fileid else None
128 fileid = str(fileid) if fileid else None
129 ig_ws = get_ignore_ws(fileid, GET)
129 ig_ws = get_ignore_ws(fileid, GET)
130 ln_ctx = (get_line_ctx(fileid, GET) or 3) * 2
130 ln_ctx = (get_line_ctx(fileid, GET) or 3) * 2
131
131
132 params = defaultdict(list)
132 params = defaultdict(list)
133 _update_with_GET(params, GET)
133 _update_with_GET(params, GET)
134
134
135 # global option
135 # global option
136 if fileid is None:
136 if fileid is None:
137 if ln_ctx > 0:
137 if ln_ctx > 0:
138 params['context'] += [ln_ctx]
138 params['context'] += [ln_ctx]
139
139
140 if ig_ws:
140 if ig_ws:
141 ig_ws_key = 'ignorews'
141 ig_ws_key = 'ignorews'
142 ig_ws_val = 1
142 ig_ws_val = 1
143
143
144 # per file option
144 # per file option
145 else:
145 else:
146 params[fileid] += ['C:%s' % ln_ctx]
146 params[fileid] += ['C:%s' % ln_ctx]
147 ig_ws_key = fileid
147 ig_ws_key = fileid
148 ig_ws_val = 'WS:%s' % 1
148 ig_ws_val = 'WS:%s' % 1
149
149
150 if ig_ws:
150 if ig_ws:
151 params[ig_ws_key] += [ig_ws_val]
151 params[ig_ws_key] += [ig_ws_val]
152
152
153 lbl = _('%s line context') % ln_ctx
153 lbl = _('%s line context') % ln_ctx
154
154
155 params['anchor'] = fileid
155 params['anchor'] = fileid
156 img = h.image(h.url('/images/icons/table_add.png'), lbl, class_='icon')
156 img = h.image(h.url('/images/icons/table_add.png'), lbl, class_='icon')
157 return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip')
157 return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip')
158
158
159
159
160 class ChangesetController(BaseRepoController):
160 class ChangesetController(BaseRepoController):
161
161
162 @LoginRequired()
162 @LoginRequired()
163 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
163 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
164 'repository.admin')
164 'repository.admin')
165 def __before__(self):
165 def __before__(self):
166 super(ChangesetController, self).__before__()
166 super(ChangesetController, self).__before__()
167 c.affected_files_cut_off = 60
167 c.affected_files_cut_off = 60
168
168
169 def index(self, revision):
169 def index(self, revision):
170
170
171 c.anchor_url = anchor_url
171 c.anchor_url = anchor_url
172 c.ignorews_url = _ignorews_url
172 c.ignorews_url = _ignorews_url
173 c.context_url = _context_url
173 c.context_url = _context_url
174 limit_off = request.GET.get('fulldiff')
174 limit_off = request.GET.get('fulldiff')
175 #get ranges of revisions if preset
175 #get ranges of revisions if preset
176 rev_range = revision.split('...')[:2]
176 rev_range = revision.split('...')[:2]
177 enable_comments = True
177 enable_comments = True
178 try:
178 try:
179 if len(rev_range) == 2:
179 if len(rev_range) == 2:
180 enable_comments = False
180 enable_comments = False
181 rev_start = rev_range[0]
181 rev_start = rev_range[0]
182 rev_end = rev_range[1]
182 rev_end = rev_range[1]
183 rev_ranges = c.rhodecode_repo.get_changesets(start=rev_start,
183 rev_ranges = c.rhodecode_repo.get_changesets(start=rev_start,
184 end=rev_end)
184 end=rev_end)
185 else:
185 else:
186 rev_ranges = [c.rhodecode_repo.get_changeset(revision)]
186 rev_ranges = [c.rhodecode_repo.get_changeset(revision)]
187
187
188 c.cs_ranges = list(rev_ranges)
188 c.cs_ranges = list(rev_ranges)
189 if not c.cs_ranges:
189 if not c.cs_ranges:
190 raise RepositoryError('Changeset range returned empty result')
190 raise RepositoryError('Changeset range returned empty result')
191
191
192 except (RepositoryError, ChangesetDoesNotExistError, Exception), e:
192 except (RepositoryError, ChangesetDoesNotExistError, Exception), e:
193 log.error(traceback.format_exc())
193 log.error(traceback.format_exc())
194 h.flash(str(e), category='warning')
194 h.flash(str(e), category='warning')
195 return redirect(url('home'))
195 return redirect(url('home'))
196
196
197 c.changes = OrderedDict()
197 c.changes = OrderedDict()
198
198
199 c.lines_added = 0 # count of lines added
199 c.lines_added = 0 # count of lines added
200 c.lines_deleted = 0 # count of lines removes
200 c.lines_deleted = 0 # count of lines removes
201
201
202 cumulative_diff = 0
202 cumulative_diff = 0
203 c.cut_off = False # defines if cut off limit is reached
203 c.cut_off = False # defines if cut off limit is reached
204
204
205 c.comments = []
205 c.comments = []
206 c.inline_comments = []
206 c.inline_comments = []
207 c.inline_cnt = 0
207 c.inline_cnt = 0
208 # Iterate over ranges (default changeset view is always one changeset)
208 # Iterate over ranges (default changeset view is always one changeset)
209 for changeset in c.cs_ranges:
209 for changeset in c.cs_ranges:
210 c.comments.extend(ChangesetCommentsModel()\
210 c.comments.extend(ChangesetCommentsModel()\
211 .get_comments(c.rhodecode_db_repo.repo_id,
211 .get_comments(c.rhodecode_db_repo.repo_id,
212 changeset.raw_id))
212 changeset.raw_id))
213 inlines = ChangesetCommentsModel()\
213 inlines = ChangesetCommentsModel()\
214 .get_inline_comments(c.rhodecode_db_repo.repo_id,
214 .get_inline_comments(c.rhodecode_db_repo.repo_id,
215 changeset.raw_id)
215 changeset.raw_id)
216 c.inline_comments.extend(inlines)
216 c.inline_comments.extend(inlines)
217 c.changes[changeset.raw_id] = []
217 c.changes[changeset.raw_id] = []
218 try:
218 try:
219 changeset_parent = changeset.parents[0]
219 changeset_parent = changeset.parents[0]
220 except IndexError:
220 except IndexError:
221 changeset_parent = None
221 changeset_parent = None
222
222
223 #==================================================================
223 #==================================================================
224 # ADDED FILES
224 # ADDED FILES
225 #==================================================================
225 #==================================================================
226 for node in changeset.added:
226 for node in changeset.added:
227 fid = h.FID(revision, node.path)
227 fid = h.FID(revision, node.path)
228 line_context_lcl = get_line_ctx(fid, request.GET)
228 line_context_lcl = get_line_ctx(fid, request.GET)
229 ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
229 ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
230 lim = self.cut_off_limit
230 lim = self.cut_off_limit
231 if cumulative_diff > self.cut_off_limit:
231 if cumulative_diff > self.cut_off_limit:
232 lim = -1 if limit_off is None else None
232 lim = -1 if limit_off is None else None
233 size, cs1, cs2, diff, st = wrapped_diff(
233 size, cs1, cs2, diff, st = wrapped_diff(
234 filenode_old=None,
234 filenode_old=None,
235 filenode_new=node,
235 filenode_new=node,
236 cut_off_limit=lim,
236 cut_off_limit=lim,
237 ignore_whitespace=ign_whitespace_lcl,
237 ignore_whitespace=ign_whitespace_lcl,
238 line_context=line_context_lcl,
238 line_context=line_context_lcl,
239 enable_comments=enable_comments
239 enable_comments=enable_comments
240 )
240 )
241 cumulative_diff += size
241 cumulative_diff += size
242 c.lines_added += st[0]
242 c.lines_added += st[0]
243 c.lines_deleted += st[1]
243 c.lines_deleted += st[1]
244 c.changes[changeset.raw_id].append(
244 c.changes[changeset.raw_id].append(
245 ('added', node, diff, cs1, cs2, st)
245 ('added', node, diff, cs1, cs2, st)
246 )
246 )
247
247
248 #==================================================================
248 #==================================================================
249 # CHANGED FILES
249 # CHANGED FILES
250 #==================================================================
250 #==================================================================
251 for node in changeset.changed:
251 for node in changeset.changed:
252 try:
252 try:
253 filenode_old = changeset_parent.get_node(node.path)
253 filenode_old = changeset_parent.get_node(node.path)
254 except ChangesetError:
254 except ChangesetError:
255 log.warning('Unable to fetch parent node for diff')
255 log.warning('Unable to fetch parent node for diff')
256 filenode_old = FileNode(node.path, '', EmptyChangeset())
256 filenode_old = FileNode(node.path, '', EmptyChangeset())
257
257
258 fid = h.FID(revision, node.path)
258 fid = h.FID(revision, node.path)
259 line_context_lcl = get_line_ctx(fid, request.GET)
259 line_context_lcl = get_line_ctx(fid, request.GET)
260 ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
260 ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
261 lim = self.cut_off_limit
261 lim = self.cut_off_limit
262 if cumulative_diff > self.cut_off_limit:
262 if cumulative_diff > self.cut_off_limit:
263 lim = -1 if limit_off is None else None
263 lim = -1 if limit_off is None else None
264 size, cs1, cs2, diff, st = wrapped_diff(
264 size, cs1, cs2, diff, st = wrapped_diff(
265 filenode_old=filenode_old,
265 filenode_old=filenode_old,
266 filenode_new=node,
266 filenode_new=node,
267 cut_off_limit=lim,
267 cut_off_limit=lim,
268 ignore_whitespace=ign_whitespace_lcl,
268 ignore_whitespace=ign_whitespace_lcl,
269 line_context=line_context_lcl,
269 line_context=line_context_lcl,
270 enable_comments=enable_comments
270 enable_comments=enable_comments
271 )
271 )
272 cumulative_diff += size
272 cumulative_diff += size
273 c.lines_added += st[0]
273 c.lines_added += st[0]
274 c.lines_deleted += st[1]
274 c.lines_deleted += st[1]
275 c.changes[changeset.raw_id].append(
275 c.changes[changeset.raw_id].append(
276 ('changed', node, diff, cs1, cs2, st)
276 ('changed', node, diff, cs1, cs2, st)
277 )
277 )
278 #==================================================================
278 #==================================================================
279 # REMOVED FILES
279 # REMOVED FILES
280 #==================================================================
280 #==================================================================
281 for node in changeset.removed:
281 for node in changeset.removed:
282 c.changes[changeset.raw_id].append(
282 c.changes[changeset.raw_id].append(
283 ('removed', node, None, None, None, (0, 0))
283 ('removed', node, None, None, None, (0, 0))
284 )
284 )
285
285
286 # count inline comments
286 # count inline comments
287 for path, lines in c.inline_comments:
287 for path, lines in c.inline_comments:
288 for comments in lines.values():
288 for comments in lines.values():
289 c.inline_cnt += len(comments)
289 c.inline_cnt += len(comments)
290
290
291 if len(c.cs_ranges) == 1:
291 if len(c.cs_ranges) == 1:
292 c.changeset = c.cs_ranges[0]
292 c.changeset = c.cs_ranges[0]
293 c.changes = c.changes[c.changeset.raw_id]
293 c.changes = c.changes[c.changeset.raw_id]
294
294
295 return render('changeset/changeset.html')
295 return render('changeset/changeset.html')
296 else:
296 else:
297 return render('changeset/changeset_range.html')
297 return render('changeset/changeset_range.html')
298
298
299 def raw_changeset(self, revision):
299 def raw_changeset(self, revision):
300
300
301 method = request.GET.get('diff', 'show')
301 method = request.GET.get('diff', 'show')
302 ignore_whitespace = request.GET.get('ignorews') == '1'
302 ignore_whitespace = request.GET.get('ignorews') == '1'
303 line_context = request.GET.get('context', 3)
303 line_context = request.GET.get('context', 3)
304 try:
304 try:
305 c.scm_type = c.rhodecode_repo.alias
305 c.scm_type = c.rhodecode_repo.alias
306 c.changeset = c.rhodecode_repo.get_changeset(revision)
306 c.changeset = c.rhodecode_repo.get_changeset(revision)
307 except RepositoryError:
307 except RepositoryError:
308 log.error(traceback.format_exc())
308 log.error(traceback.format_exc())
309 return redirect(url('home'))
309 return redirect(url('home'))
310 else:
310 else:
311 try:
311 try:
312 c.changeset_parent = c.changeset.parents[0]
312 c.changeset_parent = c.changeset.parents[0]
313 except IndexError:
313 except IndexError:
314 c.changeset_parent = None
314 c.changeset_parent = None
315 c.changes = []
315 c.changes = []
316
316
317 for node in c.changeset.added:
317 for node in c.changeset.added:
318 filenode_old = FileNode(node.path, '')
318 filenode_old = FileNode(node.path, '')
319 if filenode_old.is_binary or node.is_binary:
319 if filenode_old.is_binary or node.is_binary:
320 diff = _('binary file') + '\n'
320 diff = _('binary file') + '\n'
321 else:
321 else:
322 f_gitdiff = diffs.get_gitdiff(filenode_old, node,
322 f_gitdiff = diffs.get_gitdiff(filenode_old, node,
323 ignore_whitespace=ignore_whitespace,
323 ignore_whitespace=ignore_whitespace,
324 context=line_context)
324 context=line_context)
325 diff = diffs.DiffProcessor(f_gitdiff,
325 diff = diffs.DiffProcessor(f_gitdiff,
326 format='gitdiff').raw_diff()
326 format='gitdiff').raw_diff()
327
327
328 cs1 = None
328 cs1 = None
329 cs2 = node.changeset.raw_id
329 cs2 = node.changeset.raw_id
330 c.changes.append(('added', node, diff, cs1, cs2))
330 c.changes.append(('added', node, diff, cs1, cs2))
331
331
332 for node in c.changeset.changed:
332 for node in c.changeset.changed:
333 filenode_old = c.changeset_parent.get_node(node.path)
333 filenode_old = c.changeset_parent.get_node(node.path)
334 if filenode_old.is_binary or node.is_binary:
334 if filenode_old.is_binary or node.is_binary:
335 diff = _('binary file')
335 diff = _('binary file')
336 else:
336 else:
337 f_gitdiff = diffs.get_gitdiff(filenode_old, node,
337 f_gitdiff = diffs.get_gitdiff(filenode_old, node,
338 ignore_whitespace=ignore_whitespace,
338 ignore_whitespace=ignore_whitespace,
339 context=line_context)
339 context=line_context)
340 diff = diffs.DiffProcessor(f_gitdiff,
340 diff = diffs.DiffProcessor(f_gitdiff,
341 format='gitdiff').raw_diff()
341 format='gitdiff').raw_diff()
342
342
343 cs1 = filenode_old.changeset.raw_id
343 cs1 = filenode_old.changeset.raw_id
344 cs2 = node.changeset.raw_id
344 cs2 = node.changeset.raw_id
345 c.changes.append(('changed', node, diff, cs1, cs2))
345 c.changes.append(('changed', node, diff, cs1, cs2))
346
346
347 response.content_type = 'text/plain'
347 response.content_type = 'text/plain'
348
348
349 if method == 'download':
349 if method == 'download':
350 response.content_disposition = 'attachment; filename=%s.patch' \
350 response.content_disposition = 'attachment; filename=%s.patch' \
351 % revision
351 % revision
352
352
353 c.parent_tmpl = ''.join(['# Parent %s\n' % x.raw_id
353 c.parent_tmpl = ''.join(['# Parent %s\n' % x.raw_id
354 for x in c.changeset.parents])
354 for x in c.changeset.parents])
355
355
356 c.diffs = ''
356 c.diffs = ''
357 for x in c.changes:
357 for x in c.changes:
358 c.diffs += x[2]
358 c.diffs += x[2]
359
359
360 return render('changeset/raw_changeset.html')
360 return render('changeset/raw_changeset.html')
361
361
362 @jsonify
362 @jsonify
363 def comment(self, repo_name, revision):
363 def comment(self, repo_name, revision):
364 comm = ChangesetCommentsModel().create(
364 comm = ChangesetCommentsModel().create(
365 text=request.POST.get('text'),
365 text=request.POST.get('text'),
366 repo_id=c.rhodecode_db_repo.repo_id,
366 repo_id=c.rhodecode_db_repo.repo_id,
367 user_id=c.rhodecode_user.user_id,
367 user_id=c.rhodecode_user.user_id,
368 revision=revision,
368 revision=revision,
369 f_path=request.POST.get('f_path'),
369 f_path=request.POST.get('f_path'),
370 line_no=request.POST.get('line')
370 line_no=request.POST.get('line')
371 )
371 )
372 Session.commit()
372 Session.commit()
373 data = {
373 data = {
374 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
374 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
375 }
375 }
376 if comm:
376 if comm:
377 c.co = comm
377 c.co = comm
378 data.update(comm.get_dict())
378 data.update(comm.get_dict())
379 data.update({'rendered_text': render('changeset/changeset_comment_block.html')})
379 data.update({'rendered_text':
380 render('changeset/changeset_comment_block.html')})
380 return data
381 return data
381
382
382 @jsonify
383 @jsonify
383 def delete_comment(self, repo_name, comment_id):
384 def delete_comment(self, repo_name, comment_id):
384 co = ChangesetComment.get(comment_id)
385 co = ChangesetComment.get(comment_id)
385 owner = lambda: co.author.user_id == c.rhodecode_user.user_id
386 owner = lambda: co.author.user_id == c.rhodecode_user.user_id
386 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
387 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
387 ChangesetCommentsModel().delete(comment=co)
388 ChangesetCommentsModel().delete(comment=co)
388 Session.commit()
389 Session.commit()
389 return True
390 return True
390 else:
391 else:
391 raise HTTPForbidden()
392 raise HTTPForbidden()
@@ -1,2 +1,2 b''
1 <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
1 <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
2 ${comment.comment_block(c.co)} No newline at end of file
2 ${comment.comment_block(c.co)}
General Comments 0
You need to be logged in to leave comments. Login now