##// END OF EJS Templates
clean and fixes in files controller
marcink -
r1137:82344ce0 beta
parent child Browse files
Show More
@@ -1,300 +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
28 28 import logging
29 29 import tempfile
30 30 import rhodecode.lib.helpers as h
31 31
32 32 from pylons import request, response, session, tmpl_context as c, url
33 33 from pylons.i18n.translation import _
34 34 from pylons.controllers.util import redirect
35 35
36 36 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
37 37 from rhodecode.lib.base import BaseRepoController, render
38 38 from rhodecode.lib.utils import EmptyChangeset
39 39 from rhodecode.model.repo import RepoModel
40 40
41 41 from vcs.backends import ARCHIVE_SPECS
42 42 from vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \
43 43 EmptyRepositoryError, ImproperArchiveTypeError, VCSError
44 44 from vcs.nodes import FileNode, NodeKind
45 45 from vcs.utils import diffs as differ
46 46
47 47 log = logging.getLogger(__name__)
48 48
49 49
50 50 class FilesController(BaseRepoController):
51 51
52 52 @LoginRequired()
53 53 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
54 54 'repository.admin')
55 55 def __before__(self):
56 56 super(FilesController, self).__before__()
57 57 c.cut_off_limit = self.cut_off_limit
58 58
59 def __get_cs(self, rev, repo_name):
59 def __get_cs_or_redirect(self, rev, repo_name):
60 60 """
61 Safe way to get changeset if error ucure it redirects to given
61 Safe way to get changeset if error occur it redirects to tip with
62 proper message
63
62 64 :param rev: revision to fetch
63 65 :param repo_name: repo name to redirect after
64 66 """
65 67
66 68 try:
67 69 return c.rhodecode_repo.get_changeset(rev)
68 70 except EmptyRepositoryError, e:
69 71 h.flash(_('There are no files yet'), category='warning')
70 72 redirect(h.url('summary_home', repo_name=repo_name))
71 73
72 74 except RepositoryError, e:
73 75 h.flash(str(e), category='warning')
74 76 redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
75 77
76 78 def index(self, repo_name, revision, f_path):
77
78 try:
79 #reditect to given revision from form
79 #reditect to given revision from form if given
80 80 post_revision = request.POST.get('at_rev', None)
81 81 if post_revision:
82 post_revision = c.rhodecode_repo.get_changeset(post_revision).raw_id
82 cs = self.__get_cs_or_redirect(revision, repo_name)
83 83 redirect(url('files_home', repo_name=c.repo_name,
84 revision=post_revision, f_path=f_path))
84 revision=cs.raw_id, f_path=f_path))
85
85 86
87 c.changeset = self.__get_cs_or_redirect(revision, repo_name)
86 88 c.branch = request.GET.get('branch', None)
87
88 89 c.f_path = f_path
89 90
90 c.changeset = c.rhodecode_repo.get_changeset(revision)
91 91 cur_rev = c.changeset.revision
92 92
93 93 #prev link
94 94 try:
95 prev_rev = c.rhodecode_repo.get_changeset(cur_rev).prev(c.branch).raw_id
95 prev_rev = c.rhodecode_repo.get_changeset(cur_rev).prev(c.branch)
96 96 c.url_prev = url('files_home', repo_name=c.repo_name,
97 revision=prev_rev, f_path=f_path)
97 revision=prev_rev.raw_id, f_path=f_path)
98 98 if c.branch:
99 99 c.url_prev += '?branch=%s' % c.branch
100 100 except (ChangesetDoesNotExistError, VCSError):
101 101 c.url_prev = '#'
102 102
103 103 #next link
104 104 try:
105 next_rev = c.rhodecode_repo.get_changeset(cur_rev).next(c.branch).raw_id
105 next_rev = c.rhodecode_repo.get_changeset(cur_rev).next(c.branch)
106 106 c.url_next = url('files_home', repo_name=c.repo_name,
107 revision=next_rev, f_path=f_path)
107 revision=next_rev.raw_id, f_path=f_path)
108 108 if c.branch:
109 109 c.url_next += '?branch=%s' % c.branch
110 110 except (ChangesetDoesNotExistError, VCSError):
111 111 c.url_next = '#'
112 112
113 113 #files
114 114 try:
115 115 c.files_list = c.changeset.get_node(f_path)
116 c.file_history = self._get_history(c.rhodecode_repo, c.files_list, f_path)
116 c.file_history = self._get_history(c.rhodecode_repo,
117 c.files_list, f_path)
117 118 except RepositoryError, e:
118 119 h.flash(str(e), category='warning')
119 redirect(h.url('files_home', repo_name=repo_name, revision=revision))
120
121 except EmptyRepositoryError, e:
122 h.flash(_('There are no files yet'), category='warning')
123 redirect(h.url('summary_home', repo_name=repo_name))
124
125 except RepositoryError, e:
126 h.flash(str(e), category='warning')
127 redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
128
120 redirect(h.url('files_home', repo_name=repo_name,
121 revision=revision))
129 122
130 123
131 124 return render('files/files.html')
132 125
133 126 def rawfile(self, repo_name, revision, f_path):
134 cs = self.__get_cs(revision, repo_name)
127 cs = self.__get_cs_or_redirect(revision, repo_name)
135 128 try:
136 129 file_node = cs.get_node(f_path)
137 130 except RepositoryError, e:
138 131 h.flash(str(e), category='warning')
139 redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id))
132 redirect(h.url('files_home', repo_name=repo_name,
133 revision=cs.raw_id))
140 134
141 135 fname = f_path.split('/')[-1].encode('utf8', 'replace')
142 136 response.content_type = file_node.mimetype
143 137 response.content_disposition = 'attachment; filename=%s' % fname
144 138 return file_node.content
145 139
146 140 def raw(self, repo_name, revision, f_path):
147 cs = self.__get_cs(revision, repo_name)
141 cs = self.__get_cs_or_redirect(revision, repo_name)
148 142 try:
149 143 file_node = cs.get_node(f_path)
150 144 except RepositoryError, e:
151 145 h.flash(str(e), category='warning')
152 redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id))
146 redirect(h.url('files_home', repo_name=repo_name,
147 revision=cs.raw_id))
153 148
154 149 response.content_type = 'text/plain'
155 150
156 151 return file_node.content
157 152
158 153 def annotate(self, repo_name, revision, f_path):
159 cs = self.__get_cs(revision, repo_name)
154 cs = self.__get_cs_or_redirect(revision, repo_name)
160 155 try:
161 156 c.file = cs.get_node(f_path)
162 157 except RepositoryError, e:
163 158 h.flash(str(e), category='warning')
164 redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id))
159 redirect(h.url('files_home', repo_name=repo_name,
160 revision=cs.raw_id))
165 161
166 c.file_history = self._get_history(c.rhodecode_repo, c.file, f_path)
162 c.file_history = self._get_history(c.rhodecode_repo,
163 c.file, f_path)
167 164 c.cs = cs
168 165 c.f_path = f_path
169 166
170 167 return render('files/files_annotate.html')
171 168
172 169 def archivefile(self, repo_name, fname):
173 170
174 171 fileformat = None
175 172 revision = None
176 173 ext = None
177 174
178 175 for a_type, ext_data in ARCHIVE_SPECS.items():
179 176 archive_spec = fname.split(ext_data[1])
180 177 if len(archive_spec) == 2 and archive_spec[1] == '':
181 178 fileformat = a_type or ext_data[1]
182 179 revision = archive_spec[0]
183 180 ext = ext_data[1]
184 181
185 182 try:
186 183 dbrepo = RepoModel().get_by_repo_name(repo_name)
187 184 if dbrepo.enable_downloads is False:
188 185 return _('downloads disabled')
189 186
190 187 cs = c.rhodecode_repo.get_changeset(revision)
191 188 content_type = ARCHIVE_SPECS[fileformat][0]
192 189 except ChangesetDoesNotExistError:
193 190 return _('Unknown revision %s') % revision
194 191 except EmptyRepositoryError:
195 192 return _('Empty repository')
196 193 except (ImproperArchiveTypeError, KeyError):
197 194 return _('Unknown archive type')
198 195
199 196 response.content_type = content_type
200 197 response.content_disposition = 'attachment; filename=%s-%s%s' \
201 198 % (repo_name, revision, ext)
202 199
203 200 return cs.get_chunked_archive(stream=tempfile.TemporaryFile(),
204 201 kind=fileformat)
205 202
206 203
207 204 def diff(self, repo_name, f_path):
208 205 diff1 = request.GET.get('diff1')
209 206 diff2 = request.GET.get('diff2')
210 207 c.action = request.GET.get('diff')
211 208 c.no_changes = diff1 == diff2
212 209 c.f_path = f_path
213 210
214 211 try:
215 212 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
216 213 c.changeset_1 = c.rhodecode_repo.get_changeset(diff1)
217 214 node1 = c.changeset_1.get_node(f_path)
218 215 else:
219 216 c.changeset_1 = EmptyChangeset()
220 217 node1 = FileNode('.', '', changeset=c.changeset_1)
221 218
222 219 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
223 220 c.changeset_2 = c.rhodecode_repo.get_changeset(diff2)
224 221 node2 = c.changeset_2.get_node(f_path)
225 222 else:
226 223 c.changeset_2 = EmptyChangeset()
227 224 node2 = FileNode('.', '', changeset=c.changeset_2)
228 225 except RepositoryError:
229 226 return redirect(url('files_home',
230 227 repo_name=c.repo_name, f_path=f_path))
231 228
232 229
233 230 if c.action == 'download':
234 231 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
235 232 format='gitdiff')
236 233
237 234 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
238 235 response.content_type = 'text/plain'
239 236 response.content_disposition = 'attachment; filename=%s' \
240 237 % diff_name
241 238 return diff.raw_diff()
242 239
243 240 elif c.action == 'raw':
244 241 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
245 242 format='gitdiff')
246 243 response.content_type = 'text/plain'
247 244 return diff.raw_diff()
248 245
249 246 elif c.action == 'diff':
250 247 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
251 248 format='gitdiff')
252 249
253 250 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
254 251 c.cur_diff = _('Diff is to big to display')
255 252 elif node1.is_binary or node2.is_binary:
256 253 c.cur_diff = _('Binary file')
257 254 else:
258 255 c.cur_diff = diff.as_html()
259 256 else:
260 257 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
261 258 format='gitdiff')
262 259 #default option
263 260 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
264 261 c.cur_diff = _('Diff is to big to display')
265 262 elif node1.is_binary or node2.is_binary:
266 263 c.cur_diff = _('Binary file')
267 264 else:
268 265 c.cur_diff = diff.as_html()
269 266
270 267 if not c.cur_diff: c.no_changes = True
271 268 return render('files/file_diff.html')
272 269
273 270 def _get_history(self, repo, node, f_path):
274 271 if not node.kind is NodeKind.FILE:
275 272 return []
276 273 changesets = node.history
277 274 hist_l = []
278 275
279 276 changesets_group = ([], _("Changesets"))
280 277 branches_group = ([], _("Branches"))
281 278 tags_group = ([], _("Tags"))
282 279
283 280 for chs in changesets:
284 281 n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
285 282 changesets_group[0].append((chs.raw_id, n_desc,))
286 283
287 284 hist_l.append(changesets_group)
288 285
289 286 for name, chs in c.rhodecode_repo.branches.items():
290 287 #chs = chs.split(':')[-1]
291 288 branches_group[0].append((chs, name),)
292 289 hist_l.append(branches_group)
293 290
294 291 for name, chs in c.rhodecode_repo.tags.items():
295 292 #chs = chs.split(':')[-1]
296 293 tags_group[0].append((chs, name),)
297 294 hist_l.append(tags_group)
298 295
299 296 return hist_l
300 297
General Comments 0
You need to be logged in to leave comments. Login now