##// END OF EJS Templates
fixed #96 redirect loop on files
marcink -
r915:35e701dc beta
parent child Browse files
Show More
@@ -1,268 +1,273 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 tempfile
28 28 import logging
29 29 import rhodecode.lib.helpers as h
30 30
31 31 from mercurial import archival
32 32
33 33 from pylons import request, response, session, tmpl_context as c, url
34 34 from pylons.i18n.translation import _
35 35 from pylons.controllers.util import redirect
36 36
37 37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
38 38 from rhodecode.lib.base import BaseController, render
39 39 from rhodecode.lib.utils import EmptyChangeset
40 40 from rhodecode.model.scm import ScmModel
41 41
42 from vcs.exceptions import RepositoryError, ChangesetError, ChangesetDoesNotExistError
42 from vcs.exceptions import RepositoryError, ChangesetError, \
43 ChangesetDoesNotExistError, EmptyRepositoryError
43 44 from vcs.nodes import FileNode
44 45 from vcs.utils import diffs as differ
45 46
46 47 log = logging.getLogger(__name__)
47 48
48 49 class FilesController(BaseController):
49 50
50 51 @LoginRequired()
51 52 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
52 53 'repository.admin')
53 54 def __before__(self):
54 55 super(FilesController, self).__before__()
55 56 c.cut_off_limit = self.cut_off_limit
56 57
57 58 def index(self, repo_name, revision, f_path):
58 59 hg_model = ScmModel()
59 60 c.repo = hg_model.get_repo(c.repo_name)
60 61
61 62 try:
62 63 #reditect to given revision from form
63 64 post_revision = request.POST.get('at_rev', None)
64 65 if post_revision:
65 66 post_revision = c.repo.get_changeset(post_revision).raw_id
66 67 redirect(url('files_home', repo_name=c.repo_name,
67 68 revision=post_revision, f_path=f_path))
68 69
69 70 c.branch = request.GET.get('branch', None)
70 71
71 72 c.f_path = f_path
72 73
73 74 c.changeset = c.repo.get_changeset(revision)
74 75 cur_rev = c.changeset.revision
75 76
76 77 #prev link
77 78 try:
78 79 prev_rev = c.repo.get_changeset(cur_rev).prev(c.branch).raw_id
79 80 c.url_prev = url('files_home', repo_name=c.repo_name,
80 81 revision=prev_rev, f_path=f_path)
81 82 if c.branch:
82 83 c.url_prev += '?branch=%s' % c.branch
83 84 except ChangesetDoesNotExistError:
84 85 c.url_prev = '#'
85 86
86 87 #next link
87 88 try:
88 89 next_rev = c.repo.get_changeset(cur_rev).next(c.branch).raw_id
89 90 c.url_next = url('files_home', repo_name=c.repo_name,
90 91 revision=next_rev, f_path=f_path)
91 92 if c.branch:
92 93 c.url_next += '?branch=%s' % c.branch
93 94 except ChangesetDoesNotExistError:
94 95 c.url_next = '#'
95 96
96 97 #files
97 98 try:
98 99 c.files_list = c.changeset.get_node(f_path)
99 100 c.file_history = self._get_history(c.repo, c.files_list, f_path)
100 101 except RepositoryError, e:
101 102 h.flash(str(e), category='warning')
102 103 redirect(h.url('files_home', repo_name=repo_name, revision=revision))
103 104
105 except EmptyRepositoryError, e:
106 h.flash(_('There are no files yet'), category='warning')
107 redirect(h.url('summary_home', repo_name=repo_name))
108
104 109 except RepositoryError, e:
105 110 h.flash(str(e), category='warning')
106 111 redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
107 112
108 113
109 114
110 115 return render('files/files.html')
111 116
112 117 def rawfile(self, repo_name, revision, f_path):
113 118 hg_model = ScmModel()
114 119 c.repo = hg_model.get_repo(c.repo_name)
115 120 file_node = c.repo.get_changeset(revision).get_node(f_path)
116 121 response.content_type = file_node.mimetype
117 122 response.content_disposition = 'attachment; filename=%s' \
118 123 % f_path.split('/')[-1]
119 124 return file_node.content
120 125
121 126 def raw(self, repo_name, revision, f_path):
122 127 hg_model = ScmModel()
123 128 c.repo = hg_model.get_repo(c.repo_name)
124 129 file_node = c.repo.get_changeset(revision).get_node(f_path)
125 130 response.content_type = 'text/plain'
126 131
127 132 return file_node.content
128 133
129 134 def annotate(self, repo_name, revision, f_path):
130 135 hg_model = ScmModel()
131 136 c.repo = hg_model.get_repo(c.repo_name)
132 137
133 138 try:
134 139 c.cs = c.repo.get_changeset(revision)
135 140 c.file = c.cs.get_node(f_path)
136 141 except RepositoryError, e:
137 142 h.flash(str(e), category='warning')
138 143 redirect(h.url('files_home', repo_name=repo_name, revision=revision))
139 144
140 145 c.file_history = self._get_history(c.repo, c.file, f_path)
141 146
142 147 c.f_path = f_path
143 148
144 149 return render('files/files_annotate.html')
145 150
146 151 def archivefile(self, repo_name, fname):
147 152 info = fname.split('.')
148 153 revision, fileformat = info[0], '.' + '.'.join(info[1:])
149 154 archive_specs = {
150 155 '.tar.bz2': ('application/x-tar', 'tbz2'),
151 156 '.tar.gz': ('application/x-tar', 'tgz'),
152 157 '.zip': ('application/zip', 'zip'),
153 158 }
154 159 if not archive_specs.has_key(fileformat):
155 160 return _('Unknown archive type %s') % fileformat
156 161
157 162 repo = ScmModel().get_repo(repo_name)
158 163
159 164 try:
160 165 repo.get_changeset(revision)
161 166 except ChangesetDoesNotExistError:
162 167 return _('Unknown revision %s') % revision
163 168
164 169 archive = tempfile.TemporaryFile()
165 170 localrepo = repo.repo
166 171 fname = '%s-%s%s' % (repo_name, revision, fileformat)
167 172 archival.archive(localrepo, archive, revision, archive_specs[fileformat][1],
168 173 prefix='%s-%s' % (repo_name, revision))
169 174 response.content_type = archive_specs[fileformat][0]
170 175 response.content_disposition = 'attachment; filename=%s' % fname
171 176 archive.seek(0)
172 177
173 178 def read_in_chunks(file_object, chunk_size=1024 * 40):
174 179 """Lazy function (generator) to read a file piece by piece.
175 180 Default chunk size: 40k."""
176 181 while True:
177 182 data = file_object.read(chunk_size)
178 183 if not data:
179 184 break
180 185 yield data
181 186
182 187 return read_in_chunks(archive)
183 188
184 189 def diff(self, repo_name, f_path):
185 190 hg_model = ScmModel()
186 191 diff1 = request.GET.get('diff1')
187 192 diff2 = request.GET.get('diff2')
188 193 c.action = request.GET.get('diff')
189 194 c.no_changes = diff1 == diff2
190 195 c.f_path = f_path
191 196 c.repo = hg_model.get_repo(c.repo_name)
192 197
193 198 try:
194 199 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
195 200 c.changeset_1 = c.repo.get_changeset(diff1)
196 201 node1 = c.changeset_1.get_node(f_path)
197 202 else:
198 203 c.changeset_1 = EmptyChangeset()
199 204 node1 = FileNode('.', '', changeset=c.changeset_1)
200 205
201 206 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
202 207 c.changeset_2 = c.repo.get_changeset(diff2)
203 208 node2 = c.changeset_2.get_node(f_path)
204 209 else:
205 210 c.changeset_2 = EmptyChangeset()
206 211 node2 = FileNode('.', '', changeset=c.changeset_2)
207 212 except RepositoryError:
208 213 return redirect(url('files_home',
209 214 repo_name=c.repo_name, f_path=f_path))
210 215
211 216 f_udiff = differ.get_udiff(node1, node2)
212 217 diff = differ.DiffProcessor(f_udiff)
213 218
214 219 if c.action == 'download':
215 220 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
216 221 response.content_type = 'text/plain'
217 222 response.content_disposition = 'attachment; filename=%s' \
218 223 % diff_name
219 224 return diff.raw_diff()
220 225
221 226 elif c.action == 'raw':
222 227 response.content_type = 'text/plain'
223 228 return diff.raw_diff()
224 229
225 230 elif c.action == 'diff':
226 231 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
227 232 c.cur_diff = _('Diff is to big to display')
228 233 else:
229 234 c.cur_diff = diff.as_html()
230 235 else:
231 236 #default option
232 237 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
233 238 c.cur_diff = _('Diff is to big to display')
234 239 else:
235 240 c.cur_diff = diff.as_html()
236 241
237 242 if not c.cur_diff: c.no_changes = True
238 243 return render('files/file_diff.html')
239 244
240 245 def _get_history(self, repo, node, f_path):
241 246 from vcs.nodes import NodeKind
242 247 if not node.kind is NodeKind.FILE:
243 248 return []
244 249 changesets = node.history
245 250 hist_l = []
246 251
247 252 changesets_group = ([], _("Changesets"))
248 253 branches_group = ([], _("Branches"))
249 254 tags_group = ([], _("Tags"))
250 255
251 256 for chs in changesets:
252 257 n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
253 258 changesets_group[0].append((chs.raw_id, n_desc,))
254 259
255 260 hist_l.append(changesets_group)
256 261
257 262 for name, chs in c.repository_branches.items():
258 263 #chs = chs.split(':')[-1]
259 264 branches_group[0].append((chs, name),)
260 265 hist_l.append(branches_group)
261 266
262 267 for name, chs in c.repository_tags.items():
263 268 #chs = chs.split(':')[-1]
264 269 tags_group[0].append((chs, name),)
265 270 hist_l.append(tags_group)
266 271
267 272 return hist_l
268 273
General Comments 0
You need to be logged in to leave comments. Login now