def create_compressed_fs(progress, source, target, block_size=65536, preamble=PREAMBLE, level=9): size = os.path.getsize(source) num_blocks = int(math.ceil(size / block_size)) header = HEADER.pack(preamble, block_size, num_blocks) with open(target, 'wb') as target: target.write(header) current = len(header) + OFFSET.size * (num_blocks + 1) target.seek(current) offsets = [current] progress.update(0) with open(source, 'rb') as source: for i in range(1, num_blocks + 1): if progress.condition('cancel'): return progress.update(i / num_blocks * 100) uncompressed = source.read(block_size) if len(uncompressed) < block_size: uncompressed += '\x00' * (block_size - len(uncompressed)) assert len(uncompressed) == block_size compressed = zlib.compress(uncompressed, level) target.write(compressed) current += len(compressed) offsets.append(current) target.seek(len(header)) for offset in offsets: target.write(OFFSET.pack(offset))
def extract_compressed_fs(progress, source, target): with open(source, 'rb') as source: num_blocks = HEADER.unpack(source.read(HEADER.size))[2] offsets = [OFFSET.unpack(source.read(OFFSET.size))[0] for i in range(num_blocks + 1)] progress.update(0) with open(target, 'wb') as target: for i, offset in enumerate(offsets[:-1]): if progress.condition('cancel'): return progress.update((i + 1) / num_blocks * 100) target.write(zlib.decompress(source.read(offsets[i + 1] - offset)))
def mkisofs(progress, *arguments): process = subprocess.Popen([_mkisofs] + list(arguments), stderr=subprocess.PIPE) while process.poll() is None: if progress.condition('cancel'): process.kill() return else: line = process.stderr.readline() match = _MKISOFS_PERCENTAGE.search(line) if match: progress.update(float(match.group(1))) progress.update(100) if process.returncode != 0: progress.condition('error').activate()