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