Example 8: Recursive Unpacking
This example showcases the automatic recursive unpacking capabilities of OFRAK.
The input to this example is a nested tar.gz including a "Hello, world!" text file:
└── example_8.tar.gz
└── example_8_inner.tar.gz
└── hello_world.txt
The example automatically and recursively unpacks the input, and adds a new text file with an
obedience-demanding kitteh (😼(😼(😼))). The resulting output looks like:
└── example_8_meow.tar.gz
└── example_8_inner.tar.gz
├── hello_world.txt
└── meow.txt
Example OFRAK script:
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 | import argparse
import os
from ofrak import OFRAK, OFRAKContext
from ofrak.core.tar import TarArchive
ASSETS_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "assets"))
ARCHIVE = os.path.join(ASSETS_DIR, "example_8.tar.gz")
KITTEH = r"""
| | | | ___ | || | ___ | | / /(_) _ _
| |_| | / _ \ | || | / _ \ | |/ / _ _| |_ _| |_ _ _
| _ |/ /_\ \| || |/ / \ \ | / | |_ _|_ _|| |/ /
| | | |\ ,___/| || |\ \_/ / | |\ \ | | | |_ | |_ | / /
|_| |_| \___/ |_||_| \___/ |_| \_\|_| \___| \___|| /
_ _ / /
/ \_______ /|_\ \/
/ /_/ \__
/ \_/ /
_|_ |/|_
_|_ O _ O _|_
_|_ (_) _|_
\ /
_\_____________/_
/ \/ (___) \/ \
\__( o o )__/ kitteh! demands obedience..."""
async def main(ofrak_context: OFRAKContext, file_path: str, output_file_name: str):
# Load a root resource from the input file
root_resource = await ofrak_context.create_root_resource_from_file(file_path)
# Let OFRAK automatically unpack the file
await root_resource.unpack_recursively()
# Step through the filesystem hierarchy to the innermost TAR
outer_tar = await root_resource.get_only_child()
inner_gzip = await outer_tar.get_only_child()
inner_tar = await inner_gzip.get_only_child()
# View the innermost TAR as a TarArchive so that we can access TAR-specific methods
tar_view = await inner_tar.view_as(TarArchive)
# Add a file
await tar_view.add_file("meow.txt", KITTEH.encode("ascii"))
# Repack the file automagically and save the repacked file to disk
await root_resource.pack_recursively()
await root_resource.flush_data_to_disk(output_file_name)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--archive-file", default=ARCHIVE)
parser.add_argument("--output-file-name", default="./example_8_meow.tar.gz")
args = parser.parse_args()
ofrak = OFRAK()
ofrak.run(main, args.archive_file, args.output_file_name)
|