示例#1
0
def get_stream_content(stream: IOBase,
                       seek: Optional[int] = None) -> (Optional[str], str):
    if seek is not None and stream.seekable():
        stream.seek(seek)

    content = stream.read(limits.STREAM_SIZE_LIMIT_BYTES + 1)
    default_ext = "txt" if isinstance(content, str) else "bin"
    if isinstance(content, str):
        content = content.encode("utf-8")

    if limits.stream_size_exceeds_limit(len(content)):
        return None, default_ext

    while True:
        chunk = stream.read(1024 * 1024)
        if chunk is None:
            continue
        elif not chunk:
            break
        else:
            if not isinstance(content, BytesIO):
                content = BytesIO(content)
                content.seek(0, 2)
            if isinstance(chunk, str):
                chunk = chunk.encode("utf-8")
            if limits.stream_size_exceeds_limit(content.tell() + len(chunk)):
                return None, default_ext
            content.write(chunk)
    if isinstance(content, BytesIO):
        content = content.getvalue()

    return content, default_ext
示例#2
0
def test_attributes_iobase(sio: io.IOBase) -> None:
    """Check basic attrs/descriptor functions related to being subclass of io.IOBase."""
    assert sio is not None
    assert isinstance(sio, io.IOBase)
    assert isinstance(sio, io.RawIOBase)
    assert not isinstance(sio, io.TextIOBase)
    assert sio.readable() is True
    assert sio.writable() is True
    assert sio.seekable() is False
    assert sio.isatty() is False
    assert sio.closed() is False
示例#3
0
def write_wav(f, channels, sample_width=SAMPLE_WIDTH, raw_samples=False, seekable=None):
	stream = wav_samples(channels, sample_width, raw_samples)
	channel_count = 1 if inspect.isgenerator(channels) else len(channels)

	output_seekable = IOBase.seekable(f) if seekable is None else seekable

	if not output_seekable:
		# protect the non-seekable file, since Wave_write will call tell
		f = NonSeekableFileProxy(f)

	w = wave.open(f)
	w.setparams((
		channel_count,
		sample_width,
		FRAME_RATE,
		0, # setting zero frames, should update automatically as more frames written
		COMPRESSION_TYPE,
		COMPRESSION_NAME
		))

	if not output_seekable:
		if wave_module_patched():
			# set nframes to make wave module write data size of 0xFFFFFFF
			w.setnframes((0xFFFFFFFF - 36) / w.getnchannels() / w.getsampwidth())
			logger.debug("Setting frames to: {0}, {1}".format((w.getnframes()), w._nframes))
		else:
			w.setnframes((0x7FFFFFFF - 36) / w.getnchannels() / w.getsampwidth())
			logger.debug("Setting frames to: {0}, {1}".format((w.getnframes()), w._nframes))

	for chunk in buffer(stream):
		logger.debug("Writing %d bytes..." % len(chunk))
		if output_seekable:
			w.writeframes(chunk)
		else:
			# tell wave module not to update nframes header field
			# if output stream not seekable, e.g. STDOUT to a pipe
			w.writeframesraw(chunk)
	w.close()
    async def create(
            cls, name: str, architecture: str, content: io.IOBase, *,
            title: str="",
            filetype: BootResourceFileType=BootResourceFileType.TGZ,
            chunk_size=(1 << 22), progress_callback=None):
        """Create a `BootResource`.

        Creates an uploaded boot resource with `content`. The `content` is
        uploaded in chunks of `chunk_size`. `content` must be seekable as the
        first pass through the `content` will calculate the size and sha256
        value then the second pass will perform the actual upload.

        :param name: Name of the boot resource. Must be in format 'os/release'.
        :type name: `str`
        :param architecture: Architecture of the boot resource. Must be in
            format 'arch/subarch'.
        :type architecture: `str`
        :param content: Content of the boot resource.
        :type content: `io.IOBase`
        :param title: Title of the boot resource.
        :type title: `str`
        :param filetype: Type of file in content.
        :type filetype: `str`
        :param chunk_size: Size in bytes to upload to MAAS in chunks.
            (Default is 4 MiB).
        :type chunk_size: `int`
        :param progress_callback: Called to inform the current progress of the
            upload. One argument is passed with the progress as a precentage.
            If the resource was already complete and no content
            needed to be uploaded then this callback will never be called.
        :type progress_callback: Callable
        :returns: Create boot resource.
        :rtype: `BootResource`.
        """
        if '/' not in name:
            raise ValueError(
                "name must be in format os/release; missing '/'")
        if '/' not in architecture:
            raise ValueError(
                "architecture must be in format arch/subarch; missing '/'")
        if not content.readable():
            raise ValueError("content must be readable")
        elif not content.seekable():
            raise ValueError("content must be seekable")
        if chunk_size <= 0:
            raise ValueError(
                "chunk_size must be greater than 0, not %d" % chunk_size)

        size, sha256 = calc_size_and_sha265(content, chunk_size)
        resource = cls._object(await cls._handler.create(
            name=name, architecture=architecture, title=title,
            filetype=filetype.value, size=str(size), sha256=sha256))
        newest_set = max(resource.sets, default=None)
        assert newest_set is not None
        resource_set = resource.sets[newest_set]
        assert len(resource_set.files) == 1
        rfile = list(resource_set.files.values())[0]
        if rfile.complete:
            # Already created and fully up-to-date.
            return resource
        else:
            # Upload in chunks and reload boot resource.
            await cls._upload_chunks(
                rfile, content, chunk_size, progress_callback)
            return cls._object.read(resource.id)
示例#5
0
    async def create(cls,
                     name: str,
                     architecture: str,
                     content: io.IOBase,
                     *,
                     title: str = "",
                     filetype: BootResourceFileType = BootResourceFileType.TGZ,
                     chunk_size=(1 << 22),
                     progress_callback=None):
        """Create a `BootResource`.

        Creates an uploaded boot resource with `content`. The `content` is
        uploaded in chunks of `chunk_size`. `content` must be seekable as the
        first pass through the `content` will calculate the size and sha256
        value then the second pass will perform the actual upload.

        :param name: Name of the boot resource. Must be in format 'os/release'.
        :type name: `str`
        :param architecture: Architecture of the boot resource. Must be in
            format 'arch/subarch'.
        :type architecture: `str`
        :param content: Content of the boot resource.
        :type content: `io.IOBase`
        :param title: Title of the boot resource.
        :type title: `str`
        :param filetype: Type of file in content.
        :type filetype: `str`
        :param chunk_size: Size in bytes to upload to MAAS in chunks.
            (Default is 4 MiB).
        :type chunk_size: `int`
        :param progress_callback: Called to inform the current progress of the
            upload. One argument is passed with the progress as a precentage.
            If the resource was already complete and no content
            needed to be uploaded then this callback will never be called.
        :type progress_callback: Callable
        :returns: Create boot resource.
        :rtype: `BootResource`.
        """
        if '/' not in name:
            raise ValueError("name must be in format os/release; missing '/'")
        if '/' not in architecture:
            raise ValueError(
                "architecture must be in format arch/subarch; missing '/'")
        if not content.readable():
            raise ValueError("content must be readable")
        elif not content.seekable():
            raise ValueError("content must be seekable")
        if chunk_size <= 0:
            raise ValueError("chunk_size must be greater than 0, not %d" %
                             chunk_size)

        size, sha256 = calc_size_and_sha265(content, chunk_size)
        resource = cls._object(await
                               cls._handler.create(name=name,
                                                   architecture=architecture,
                                                   title=title,
                                                   filetype=filetype.value,
                                                   size=str(size),
                                                   sha256=sha256))
        newest_set = max(resource.sets, default=None)
        assert newest_set is not None
        resource_set = resource.sets[newest_set]
        assert len(resource_set.files) == 1
        rfile = list(resource_set.files.values())[0]
        if rfile.complete:
            # Already created and fully up-to-date.
            return resource
        else:
            # Upload in chunks and reload boot resource.
            await cls._upload_chunks(rfile, content, chunk_size,
                                     progress_callback)
            return cls._object.read(resource.id)
示例#6
0
 def __init__(self, raw: io.IOBase):
     assert raw.seekable()
     self.raw = raw
     assert self.check_is_block_gzip()