Skip to content

Commit

Permalink
(#156)(#197) automatically mounting extras to `archives.base.Archiv…
Browse files Browse the repository at this point in the history
…e` (`.from_archive` & `.from_file`)
  • Loading branch information
snake-biscuits committed Nov 7, 2024
1 parent 34ae341 commit 1fab057
Showing 1 changed file with 24 additions and 6 deletions.
30 changes: 24 additions & 6 deletions bsp_tool/archives/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class Archive:
def __init__(self):
self.extras = dict()

def extra_patterns(self) -> List[str]:
"""filename patterns for files to mount (e.g. '*.bin')"""
return list()

def extract(self, filename, to_path=None):
if filename not in self.namelist():
raise FileNotFoundError(f"Couldn't find {filename!r} to extract")
Expand Down Expand Up @@ -98,19 +102,33 @@ def unmount_file(self, filename: str):
@classmethod
def from_archive(cls, parent_archive: Archive, filename: str) -> Archive:
"""for ArchiveClasses composed of multiple files"""
# TODO: mount extra files
# e.g. sega.Gdi tracks or respawn.Vpk data vpks
return cls.from_bytes(parent_archive.read(filename))
archive = cls.from_bytes(parent_archive.read(filename))
folder = os.path.dirname(filename)
extras = [
filename
for filename in parent_archive.listdir(folder)
for pattern in archive.extra_patterns()
if fnmatch.fnmatch(filename, pattern)]
for filename in extras:
archive.mount_file(filename)
return archive

@classmethod
def from_bytes(cls, raw_archive: bytes) -> Archive:
return cls.from_stream(io.BytesIO(raw_archive))

@classmethod
def from_file(cls, filename: str) -> Archive:
# NOTE: don't use "with" if you want to keep the stream open
archive_file = open(filename, "rb")
return cls.from_stream(archive_file)
archive = cls.from_stream(open(filename, "rb"))
folder = os.path.dirname(filename)
extras = [
filename
for filename in os.listdir(folder)
for pattern in archive.extra_patterns()
if fnmatch.fnmatch(filename, pattern)]
for filename in extras:
archive.mount_file(filename)
return archive

@classmethod
def from_stream(cls, stream: io.BytesIO) -> Archive:
Expand Down

0 comments on commit 1fab057

Please sign in to comment.