##// END OF EJS Templates
fixed files diffs to use gitdiff enabled diffs
marcink -
r1132:c4b59dcf beta
parent child Browse files
Show More
@@ -1,293 +1,297 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.files
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Files controller for RhodeCode
7 7
8 8 :created_on: Apr 21, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software; you can redistribute it and/or
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program; if not, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27 import logging
28 28 import rhodecode.lib.helpers as h
29 29
30 30 from pylons import request, response, session, tmpl_context as c, url
31 31 from pylons.i18n.translation import _
32 32 from pylons.controllers.util import redirect
33 33
34 34 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
35 35 from rhodecode.lib.base import BaseRepoController, render
36 36 from rhodecode.lib.utils import EmptyChangeset
37 37 from rhodecode.model.repo import RepoModel
38 38
39 39 from vcs.backends import ARCHIVE_SPECS
40 40 from vcs.exceptions import RepositoryError, ChangesetError, \
41 41 ChangesetDoesNotExistError, EmptyRepositoryError, ImproperArchiveTypeError, \
42 42 VCSError
43 43 from vcs.nodes import FileNode, NodeKind
44 44 from vcs.utils import diffs as differ
45 45
46 46 log = logging.getLogger(__name__)
47 47
48 48 class FilesController(BaseRepoController):
49 49
50 50 @LoginRequired()
51 51 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
52 52 'repository.admin')
53 53 def __before__(self):
54 54 super(FilesController, self).__before__()
55 55 c.cut_off_limit = self.cut_off_limit
56 56
57 57 def __get_cs(self, rev, repo_name):
58 58 """
59 59 Safe way to get changeset if error ucure it redirects to given
60 60 :param rev: revision to fetch
61 61 :param repo_name: repo name to redirect after
62 62 """
63 63
64 64 try:
65 65 return c.rhodecode_repo.get_changeset(rev)
66 66 except EmptyRepositoryError, e:
67 67 h.flash(_('There are no files yet'), category='warning')
68 68 redirect(h.url('summary_home', repo_name=repo_name))
69 69
70 70 except RepositoryError, e:
71 71 h.flash(str(e), category='warning')
72 72 redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
73 73
74 74 def index(self, repo_name, revision, f_path):
75 75
76 76 try:
77 77 #reditect to given revision from form
78 78 post_revision = request.POST.get('at_rev', None)
79 79 if post_revision:
80 80 post_revision = c.rhodecode_repo.get_changeset(post_revision).raw_id
81 81 redirect(url('files_home', repo_name=c.repo_name,
82 82 revision=post_revision, f_path=f_path))
83 83
84 84 c.branch = request.GET.get('branch', None)
85 85
86 86 c.f_path = f_path
87 87
88 88 c.changeset = c.rhodecode_repo.get_changeset(revision)
89 89 cur_rev = c.changeset.revision
90 90
91 91 #prev link
92 92 try:
93 93 prev_rev = c.rhodecode_repo.get_changeset(cur_rev).prev(c.branch).raw_id
94 94 c.url_prev = url('files_home', repo_name=c.repo_name,
95 95 revision=prev_rev, f_path=f_path)
96 96 if c.branch:
97 97 c.url_prev += '?branch=%s' % c.branch
98 98 except (ChangesetDoesNotExistError, VCSError):
99 99 c.url_prev = '#'
100 100
101 101 #next link
102 102 try:
103 103 next_rev = c.rhodecode_repo.get_changeset(cur_rev).next(c.branch).raw_id
104 104 c.url_next = url('files_home', repo_name=c.repo_name,
105 105 revision=next_rev, f_path=f_path)
106 106 if c.branch:
107 107 c.url_next += '?branch=%s' % c.branch
108 108 except (ChangesetDoesNotExistError, VCSError):
109 109 c.url_next = '#'
110 110
111 111 #files
112 112 try:
113 113 c.files_list = c.changeset.get_node(f_path)
114 114 c.file_history = self._get_history(c.rhodecode_repo, c.files_list, f_path)
115 115 except RepositoryError, e:
116 116 h.flash(str(e), category='warning')
117 117 redirect(h.url('files_home', repo_name=repo_name, revision=revision))
118 118
119 119 except EmptyRepositoryError, e:
120 120 h.flash(_('There are no files yet'), category='warning')
121 121 redirect(h.url('summary_home', repo_name=repo_name))
122 122
123 123 except RepositoryError, e:
124 124 h.flash(str(e), category='warning')
125 125 redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
126 126
127 127
128 128
129 129 return render('files/files.html')
130 130
131 131 def rawfile(self, repo_name, revision, f_path):
132 132 cs = self.__get_cs(revision, repo_name)
133 133 try:
134 134 file_node = cs.get_node(f_path)
135 135 except RepositoryError, e:
136 136 h.flash(str(e), category='warning')
137 137 redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id))
138 138
139 139 fname = f_path.split('/')[-1].encode('utf8', 'replace')
140 140 response.content_type = file_node.mimetype
141 141 response.content_disposition = 'attachment; filename=%s' % fname
142 142 return file_node.content
143 143
144 144 def raw(self, repo_name, revision, f_path):
145 145 cs = self.__get_cs(revision, repo_name)
146 146 try:
147 147 file_node = cs.get_node(f_path)
148 148 except RepositoryError, e:
149 149 h.flash(str(e), category='warning')
150 150 redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id))
151 151
152 152 response.content_type = 'text/plain'
153 153
154 154 return file_node.content
155 155
156 156 def annotate(self, repo_name, revision, f_path):
157 157 cs = self.__get_cs(revision, repo_name)
158 158 try:
159 159 c.file = cs.get_node(f_path)
160 160 except RepositoryError, e:
161 161 h.flash(str(e), category='warning')
162 162 redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id))
163 163
164 164 c.file_history = self._get_history(c.rhodecode_repo, c.file, f_path)
165 165 c.cs = cs
166 166 c.f_path = f_path
167 167
168 168 return render('files/files_annotate.html')
169 169
170 170 def archivefile(self, repo_name, fname):
171 171
172 172 fileformat = None
173 173 revision = None
174 174 ext = None
175 175
176 176 for a_type, ext_data in ARCHIVE_SPECS.items():
177 177 archive_spec = fname.split(ext_data[1])
178 178 if len(archive_spec) == 2 and archive_spec[1] == '':
179 179 fileformat = a_type or ext_data[1]
180 180 revision = archive_spec[0]
181 181 ext = ext_data[1]
182 182
183 183 try:
184 184 dbrepo = RepoModel().get_by_repo_name(repo_name)
185 185 if dbrepo.enable_downloads is False:
186 186 return _('downloads disabled')
187 187
188 188 cs = c.rhodecode_repo.get_changeset(revision)
189 189 content_type = ARCHIVE_SPECS[fileformat][0]
190 190 except ChangesetDoesNotExistError:
191 191 return _('Unknown revision %s') % revision
192 192 except EmptyRepositoryError:
193 193 return _('Empty repository')
194 194 except (ImproperArchiveTypeError, KeyError):
195 195 return _('Unknown archive type')
196 196
197 197 response.content_type = content_type
198 198 response.content_disposition = 'attachment; filename=%s-%s%s' \
199 199 % (repo_name, revision, ext)
200 200
201 201 return cs.get_chunked_archive(kind=fileformat)
202 202
203 203
204 204 def diff(self, repo_name, f_path):
205 205 diff1 = request.GET.get('diff1')
206 206 diff2 = request.GET.get('diff2')
207 207 c.action = request.GET.get('diff')
208 208 c.no_changes = diff1 == diff2
209 209 c.f_path = f_path
210 210
211 211 try:
212 212 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
213 213 c.changeset_1 = c.rhodecode_repo.get_changeset(diff1)
214 214 node1 = c.changeset_1.get_node(f_path)
215 215 else:
216 216 c.changeset_1 = EmptyChangeset()
217 217 node1 = FileNode('.', '', changeset=c.changeset_1)
218 218
219 219 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
220 220 c.changeset_2 = c.rhodecode_repo.get_changeset(diff2)
221 221 node2 = c.changeset_2.get_node(f_path)
222 222 else:
223 223 c.changeset_2 = EmptyChangeset()
224 224 node2 = FileNode('.', '', changeset=c.changeset_2)
225 225 except RepositoryError:
226 226 return redirect(url('files_home',
227 227 repo_name=c.repo_name, f_path=f_path))
228 228
229 229
230 230 if c.action == 'download':
231 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2))
231 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
232 format='gitdiff')
232 233
233 234 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
234 235 response.content_type = 'text/plain'
235 236 response.content_disposition = 'attachment; filename=%s' \
236 237 % diff_name
237 238 return diff.raw_diff()
238 239
239 240 elif c.action == 'raw':
240 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2))
241 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
242 format='gitdiff')
241 243 response.content_type = 'text/plain'
242 244 return diff.raw_diff()
243 245
244 246 elif c.action == 'diff':
245 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2))
247 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
248 format='gitdiff')
246 249
247 250 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
248 251 c.cur_diff = _('Diff is to big to display')
249 252 elif node1.is_binary or node2.is_binary:
250 253 c.cur_diff = _('Binary file')
251 254 else:
252 255 c.cur_diff = diff.as_html()
253 256 else:
254 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2))
257 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
258 format='gitdiff')
255 259 #default option
256 260 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
257 261 c.cur_diff = _('Diff is to big to display')
258 262 elif node1.is_binary or node2.is_binary:
259 263 c.cur_diff = _('Binary file')
260 264 else:
261 265 c.cur_diff = diff.as_html()
262 266
263 267 if not c.cur_diff: c.no_changes = True
264 268 return render('files/file_diff.html')
265 269
266 270 def _get_history(self, repo, node, f_path):
267 271 if not node.kind is NodeKind.FILE:
268 272 return []
269 273 changesets = node.history
270 274 hist_l = []
271 275
272 276 changesets_group = ([], _("Changesets"))
273 277 branches_group = ([], _("Branches"))
274 278 tags_group = ([], _("Tags"))
275 279
276 280 for chs in changesets:
277 281 n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
278 282 changesets_group[0].append((chs.raw_id, n_desc,))
279 283
280 284 hist_l.append(changesets_group)
281 285
282 286 for name, chs in c.rhodecode_repo.branches.items():
283 287 #chs = chs.split(':')[-1]
284 288 branches_group[0].append((chs, name),)
285 289 hist_l.append(branches_group)
286 290
287 291 for name, chs in c.rhodecode_repo.tags.items():
288 292 #chs = chs.split(':')[-1]
289 293 tags_group[0].append((chs, name),)
290 294 hist_l.append(tags_group)
291 295
292 296 return hist_l
293 297
General Comments 0
You need to be logged in to leave comments. Login now