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