def fill_archive(self, stream=None, kind='tgz', prefix=None): """ Fills up given stream. :param stream: file like object. :param kind: one of following: ``zip``, ``tgz`` or ``tbz2``. Default: ``tgz``. :param prefix: name of root directory in archive. Default is repository name and changeset's raw_id joined with dash (``repo-tip.<KIND>``). :raise ImproperArchiveTypeError: If given kind is wrong. :raise VcsError: If given stream is None """ allowed_kinds = ARCHIVE_SPECS.keys() if kind not in allowed_kinds: raise ImproperArchiveTypeError('Archive kind not supported use one' 'of %s', allowed_kinds) if prefix is None: prefix = '%s-%s' % (self.repository.name, self.short_id) elif prefix.startswith('/'): raise VCSError("Prefix cannot start with leading slash") elif prefix.strip() == '': raise VCSError("Prefix cannot be empty") if kind == 'zip': frmt = 'zip' else: frmt = 'tar' cmd = 'git archive --format=%s --prefix=%s/ %s' % (frmt, prefix, self.raw_id) if kind == 'tgz': cmd += ' | gzip -9' elif kind == 'tbz2': cmd += ' | bzip2 -9' if stream is None: raise VCSError('You need to pass in a valid stream for filling' ' with archival data') else: arch_path = None popen = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True, cwd=self.repository.path) buffer_size = 1024 * 8 chunk = popen.stdout.read(buffer_size) while chunk: stream.write(chunk) chunk = popen.stdout.read(buffer_size) # Make sure all descriptors would be read popen.communicate()
def archivefile(self, repo_name, fname): fileformat = None revision = None ext = None subrepos = request.GET.get('subrepos') == 'true' for a_type, ext_data in ARCHIVE_SPECS.items(): archive_spec = fname.split(ext_data[1]) if len(archive_spec) == 2 and archive_spec[1] == '': fileformat = a_type or ext_data[1] revision = archive_spec[0] ext = ext_data[1] try: dbrepo = RepoModel().get_by_repo_name(repo_name) if dbrepo.enable_downloads is False: return _('downloads disabled') cs = c.rhodecode_repo.get_changeset(revision) content_type = ARCHIVE_SPECS[fileformat][0] except ChangesetDoesNotExistError: return _('Unknown revision %s') % revision except EmptyRepositoryError: return _('Empty repository') except (ImproperArchiveTypeError, KeyError): return _('Unknown archive type') response.content_type = content_type response.content_disposition = 'attachment; filename=%s-%s%s' \ % (repo_name, revision, ext) import tempfile archive = tempfile.mkstemp()[1] t = open(archive, 'wb') cs.fill_archive(stream=t, kind=fileformat, subrepos=subrepos) def get_chunked_archive(archive): stream = open(archive, 'rb') while True: data = stream.read(4096) if not data: os.remove(archive) break yield data return get_chunked_archive(archive)
def fill_archive(self, stream=None, kind="tgz", prefix=None): """ Fills up given stream. :param stream: file like object. :param kind: one of following: ``zip``, ``tgz`` or ``tbz2``. Default: ``tgz``. :param prefix: name of root directory in archive. Default is repository name and changeset's raw_id joined with dash (``repo-tip.<KIND>``). :raise ImproperArchiveTypeError: If given kind is wrong. :raise VcsError: If given stream is None """ allowed_kinds = ARCHIVE_SPECS.keys() if kind not in allowed_kinds: raise ImproperArchiveTypeError("Archive kind not supported use one" "of %s", allowed_kinds) if stream is None: raise VCSError("You need to pass in a valid stream for filling" " with archival data") if prefix is None: prefix = "%s-%s" % (self.repository.name, self.short_id) elif prefix.startswith("/"): raise VCSError("Prefix cannot start with leading slash") elif prefix.strip() == "": raise VCSError("Prefix cannot be empty") archival.archive(self.repository._repo, stream, self.raw_id, kind, prefix=prefix) # stream.close() if stream.closed and hasattr(stream, "name"): stream = open(stream.name, "rb") elif hasattr(stream, "mode") and "r" not in stream.mode: stream = open(stream.name, "rb") else: stream.seek(0)