15
15
# You should have received a copy of the GNU General Public License
16
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24
from breezy.errors import NoSuchId, NoSuchRevision
27
from breezy.transport import NoSuchFile
29
from breezy.errors import NoSuchFile
31
from breezy import osutils, urlutils
24
32
from paste import httpexceptions
25
33
from paste.request import path_info_pop
27
from loggerhead.controllers import TemplatedBranchView
35
from ..controllers import TemplatedBranchView
29
37
log = logging.getLogger("loggerhead.controllers")
32
40
class DownloadUI (TemplatedBranchView):
34
def __call__(self, environ, start_response):
35
# /download/<rev_id>/<file_id>/[filename]
42
def encode_filename(self, filename):
44
return urlutils.escape(filename)
46
def get_args(self, environ):
41
49
arg = path_info_pop(environ)
55
def __call__(self, environ, start_response):
56
# /download/<rev_id>/<filename>
58
args = self.get_args(environ)
47
60
raise httpexceptions.HTTPMovedPermanently(
48
61
self._branch.absolute_url('/changes'))
50
62
revid = h.fix_revid(args[0])
52
path, filename, content = h.get_file(file_id, revid)
64
path, filename, content = h.get_file("/".join(args[1:]), revid)
65
except (NoSuchFile, NoSuchRevision):
66
raise httpexceptions.HTTPNotFound()
53
67
mime_type, encoding = mimetypes.guess_type(filename)
54
68
if mime_type is None:
55
69
mime_type = 'application/octet-stream'
57
70
self.log.info('/download %s @ %s (%d bytes)',
59
72
h.get_revno(revid),
61
encoded_filename = urllib.quote(filename.encode('utf-8'))
74
encoded_filename = self.encode_filename(filename)
63
76
('Content-Type', mime_type),
64
77
('Content-Length', str(len(content))),
68
81
start_response('200 OK', headers)
85
class DownloadTarballUI(DownloadUI):
87
def __call__(self, environ, start_response):
88
"""Stream a tarball from a bazaar branch."""
89
# Tried to re-use code from downloadui, not very successful
90
if not self._branch.export_tarballs:
91
raise httpexceptions.HTTPForbidden(
92
"Tarball downloads are not allowed")
93
archive_format = "tgz"
94
history = self._history
95
self.args = self.get_args(environ)
97
revid = history.fix_revid(self.args[0])
98
version_part = '-r' + self.args[0]
100
revid = self.get_revid()
102
# XXX: Perhaps some better suggestion based on the URL or path?
104
# TODO: Perhaps set the tarball suggested mtime to the revision
106
root = self._branch.friendly_name or 'branch'
107
filename = root + version_part + '.' + archive_format
108
encoded_filename = self.encode_filename(filename)
110
('Content-Type', 'application/octet-stream'),
111
('Content-Disposition',
112
"attachment; filename*=utf-8''%s" % (encoded_filename,)),
114
start_response('200 OK', headers)
115
tree = history._branch.repository.revision_tree(revid)
116
return tree.archive(root=root, format=archive_format, name=filename)