25
24
from paste import httpexceptions
26
25
from paste.request import path_info_pop
28
27
from loggerhead.controllers import TemplatedBranchView
29
from loggerhead.exporter import export_archive
31
29
log = logging.getLogger("loggerhead.controllers")
34
32
class DownloadUI (TemplatedBranchView):
36
def encode_filename(self, filename):
38
return urllib.quote(filename.encode('utf-8'))
40
def get_args(self, environ):
34
def __call__(self, environ, start_response):
35
# /download/<rev_id>/<file_id>/[filename]
43
41
arg = path_info_pop(environ)
49
def __call__(self, environ, start_response):
50
# /download/<rev_id>/<file_id>/[filename]
52
args = self.get_args(environ)
54
47
raise httpexceptions.HTTPMovedPermanently(
55
48
self._branch.absolute_url('/changes'))
56
50
revid = h.fix_revid(args[0])
58
52
path, filename, content = h.get_file(file_id, revid)
59
53
mime_type, encoding = mimetypes.guess_type(filename)
60
54
if mime_type is None:
61
55
mime_type = 'application/octet-stream'
62
57
self.log.info('/download %s @ %s (%d bytes)',
64
59
h.get_revno(revid),
66
encoded_filename = self.encode_filename(filename)
61
encoded_filename = urllib.quote(filename.encode('utf-8'))
68
63
('Content-Type', mime_type),
69
64
('Content-Length', str(len(content))),
73
68
start_response('200 OK', headers)
77
class DownloadTarballUI(DownloadUI):
79
def __call__(self, environ, start_response):
80
"""Stream a tarball from a bazaar branch."""
81
# Tried to re-use code from downloadui, not very successful
82
if not self._branch.export_tarballs:
83
raise httpexceptions.HTTPForbidden(
84
"Tarball downloads are not allowed")
85
archive_format = "tgz"
86
history = self._history
87
self.args = self.get_args(environ)
89
revid = history.fix_revid(self.args[0])
90
version_part = '-r' + self.args[0]
92
revid = self.get_revid()
94
# XXX: Perhaps some better suggestion based on the URL or path?
96
# TODO: Perhaps set the tarball suggested mtime to the revision
98
root = self._branch.friendly_name or 'branch'
99
encoded_filename = self.encode_filename(
100
root + version_part + '.' + archive_format)
102
('Content-Type', 'application/octet-stream'),
103
('Content-Disposition',
104
"attachment; filename*=utf-8''%s" % (encoded_filename,)),
106
start_response('200 OK', headers)
107
return export_archive(history, root, revid, archive_format)