seven_zip.py
ofrak.core.seven_zip
SevenZFilesystem (GenericBinary, FilesystemRoot)
dataclass
Filesystem stored in a 7z archive.
SevenZUnpacker (Unpacker)
Unpack (decompress) a 7z file.
unpack(self, resource, config=None)
async
Unpack the given resource.
Users should not call this method directly; rather, they should run Resource.run or Resource.unpack.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
resource |
Resource |
The resource that is being unpacked |
required |
config |
Optional config for unpacking. If an implementation provides a default, this default will always be used when config would otherwise be None. Note that a copy of the default config will be passed, so the default config values cannot be modified persistently by a component run. |
None |
Source code in ofrak/core/seven_zip.py
async def unpack(self, resource: Resource, config=None):
seven_zip_v = await resource.view_as(SevenZFilesystem)
resource_data = await seven_zip_v.resource.get_data()
with tempfile.NamedTemporaryFile() as temp_file:
temp_file.write(resource_data)
temp_file.flush()
with tempfile.TemporaryDirectory() as temp_flush_dir:
cmd = [
"7zz",
"x",
f"-o{temp_flush_dir}",
temp_file.name,
]
proc = await asyncio.create_subprocess_exec(
*cmd,
)
returncode = await proc.wait()
if proc.returncode:
raise CalledProcessError(returncode=returncode, cmd=cmd)
await seven_zip_v.initialize_from_disk(temp_flush_dir)
SevenzPacker (Packer)
Pack files into a compressed 7z archive.
pack(self, resource, config=None)
async
Pack the given resource.
Users should not call this method directly; rather, they should run Resource.run or Resource.pack.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
resource |
Resource |
required | |
config |
Optional config for packing. If an implementation provides a default, this default will always be used when config would otherwise be None. Note that a copy of the default config will be passed, so the default config values cannot be modified persistently by a component run. |
None |
Source code in ofrak/core/seven_zip.py
async def pack(self, resource: Resource, config=None):
seven_zip_v: SevenZFilesystem = await resource.view_as(SevenZFilesystem)
temp_flush_dir = await seven_zip_v.flush_to_disk()
temp_flush_dir = os.path.join(temp_flush_dir, ".")
with tempfile.TemporaryDirectory() as temp_dir:
temp_name = os.path.join(temp_dir, "temp.7z")
cmd = [
"7zz",
"a",
temp_name,
temp_flush_dir,
]
proc = await asyncio.create_subprocess_exec(
*cmd,
)
returncode = await proc.wait()
if proc.returncode:
raise CalledProcessError(returncode=returncode, cmd=cmd)
with open(temp_name, "rb") as f:
new_data = f.read()
# Passing in the original range effectively replaces the original data with the new data
resource.queue_patch(Range(0, await resource.get_data_length()), new_data)