##// END OF EJS Templates
fixed problem with rawfile content_disposition attachment,...
marcink -
r1102:8d085837 beta
parent child Browse files
Show More
@@ -1,293 +1,293 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 fname = f_path.split('/')[-1].encode('utf8', 'replace')
139 140 response.content_type = file_node.mimetype
140 response.content_disposition = 'attachment; filename=%s' \
141 % f_path.split('/')[-1]
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 231 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2))
232 232
233 233 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
234 234 response.content_type = 'text/plain'
235 235 response.content_disposition = 'attachment; filename=%s' \
236 236 % diff_name
237 237 return diff.raw_diff()
238 238
239 239 elif c.action == 'raw':
240 240 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2))
241 241 response.content_type = 'text/plain'
242 242 return diff.raw_diff()
243 243
244 244 elif c.action == 'diff':
245 245 diff = differ.DiffProcessor(differ.get_udiff(node1, node2))
246 246
247 247 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
248 248 c.cur_diff = _('Diff is to big to display')
249 249 elif node1.is_binary or node2.is_binary:
250 250 c.cur_diff = _('Binary file')
251 251 else:
252 252 c.cur_diff = diff.as_html()
253 253 else:
254 254 diff = differ.DiffProcessor(differ.get_udiff(node1, node2))
255 255 #default option
256 256 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
257 257 c.cur_diff = _('Diff is to big to display')
258 258 elif node1.is_binary or node2.is_binary:
259 259 c.cur_diff = _('Binary file')
260 260 else:
261 261 c.cur_diff = diff.as_html()
262 262
263 263 if not c.cur_diff: c.no_changes = True
264 264 return render('files/file_diff.html')
265 265
266 266 def _get_history(self, repo, node, f_path):
267 267 if not node.kind is NodeKind.FILE:
268 268 return []
269 269 changesets = node.history
270 270 hist_l = []
271 271
272 272 changesets_group = ([], _("Changesets"))
273 273 branches_group = ([], _("Branches"))
274 274 tags_group = ([], _("Tags"))
275 275
276 276 for chs in changesets:
277 277 n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
278 278 changesets_group[0].append((chs.raw_id, n_desc,))
279 279
280 280 hist_l.append(changesets_group)
281 281
282 282 for name, chs in c.rhodecode_repo.branches.items():
283 283 #chs = chs.split(':')[-1]
284 284 branches_group[0].append((chs, name),)
285 285 hist_l.append(branches_group)
286 286
287 287 for name, chs in c.rhodecode_repo.tags.items():
288 288 #chs = chs.split(':')[-1]
289 289 tags_group[0].append((chs, name),)
290 290 hist_l.append(tags_group)
291 291
292 292 return hist_l
293 293
General Comments 0
You need to be logged in to leave comments. Login now