Warning
This document is for an in-development version of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.
Source code for galaxy.util.streamball
"""
A simple wrapper for writing tarballs as a stream.
"""
from __future__ import absolute_import
import logging
import os
import tarfile
from galaxy.exceptions import ObjectNotFound
from .path import safe_walk
log = logging.getLogger(__name__)
[docs]class StreamBall(object):
[docs] def __init__(self, mode, members=None):
self.members = members
if members is None:
self.members = []
self.mode = mode
self.wsgi_status = None
self.wsgi_headeritems = None
[docs] def add(self, file, relpath, check_file=False):
if check_file and len(file) > 0:
if not os.path.isfile(file):
raise ObjectNotFound
else:
self.members.append((file, relpath))
else:
self.members.append((file, relpath))
[docs] def stream(self, environ, start_response):
response_write = start_response(self.wsgi_status, self.wsgi_headeritems)
class tarfileobj(object):
def write(self, *args, **kwargs):
response_write(*args, **kwargs)
tf = tarfile.open(mode=self.mode, fileobj=tarfileobj())
for (file, rel) in self.members:
tf.add(file, arcname=rel)
tf.close()
return []
[docs]class ZipBall(object):
[docs] def stream(self, environ, start_response):
response_write = start_response(self.wsgi_status, self.wsgi_headeritems)
tmpfh = open(self._tmpf)
response_write(tmpfh.read())
tmpfh.close()
try:
os.unlink(self._tmpf)
os.rmdir(self._tmpd)
except OSError:
log.exception("Unable to remove temporary library download archive and directory")
return []
[docs]def stream_archive(trans, path, upstream_gzip=False):
archive_type_string = 'w|gz'
archive_ext = 'tgz'
if upstream_gzip:
archive_type_string = 'w|'
archive_ext = 'tar'
archive = StreamBall(mode=archive_type_string)
for root, directories, files in safe_walk(path):
for filename in files:
p = os.path.join(root, filename)
relpath = os.path.relpath(p, os.path.join(path, os.pardir))
archive.add(file=os.path.join(path, p), relpath=relpath)
archive_name = "%s.%s" % (os.path.basename(path), archive_ext)
trans.response.set_content_type("application/x-tar")
trans.response.headers["Content-Disposition"] = 'attachment; filename="{}"'.format(archive_name)
archive.wsgi_status = trans.response.wsgi_status()
archive.wsgi_headeritems = trans.response.wsgi_headeritems()
return archive.stream