Skip to content

Commit

Permalink
(#197) updating .mount_file to use external.File
Browse files Browse the repository at this point in the history
  • Loading branch information
snake-biscuits committed Nov 11, 2024
1 parent b3f86d7 commit 5b08700
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 33 deletions.
19 changes: 11 additions & 8 deletions bsp_tool/archives/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import os
from typing import Dict, List, Tuple

from .. import external


def path_tuple(path: str) -> Tuple[str]:
out = tuple(path.replace("\\", "/").strip("/").split("/"))
Expand All @@ -15,7 +17,7 @@ def path_tuple(path: str) -> Tuple[str]:

class Archive:
ext = None
extras: Dict[str, io.BytesIO]
extras: Dict[str, external.File]

def __init__(self):
self.extras = dict()
Expand Down Expand Up @@ -67,11 +69,8 @@ def listdir(self, folder: str) -> List[str]:
folder_contents.append(subfolder)
return folder_contents

def mount_file(self, filename: str, archive=None):
if archive is None:
self.extras[filename] = open(filename, "rb")
else:
self.extras[filename] = io.BytesIO(archive.read(filename))
def mount_file(self, filename: str, external_file: external.File):
self.extras[filename] = external_file

def namelist(self) -> List[str]:
# NOTE: we assume namelist only contains filenames, no folders
Expand Down Expand Up @@ -110,7 +109,9 @@ def from_archive(cls, parent_archive: Archive, filename: str) -> Archive:
for pattern in archive.extra_patterns()
if fnmatch.fnmatch(filename.lower(), pattern.lower())]
for filename in extras:
archive.mount_file(os.path.join(folder, filename))
full_filename = os.path.join(folder, filename)
external_file = external.File.from_archive(full_filename, parent_archive)
archive.mount_file(filename, external_file)
return archive

@classmethod
Expand All @@ -127,7 +128,9 @@ def from_file(cls, filename: str) -> Archive:
for pattern in archive.extra_patterns()
if fnmatch.fnmatch(filename.lower(), pattern.lower())]
for filename in extras:
archive.mount_file(os.path.join(folder, filename))
full_filename = os.path.join(folder, filename)
external_file = external.File.from_file(full_filename)
archive.mount_file(filename, external_file)
return archive

@classmethod
Expand Down
50 changes: 25 additions & 25 deletions bsp_tool/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
from types import MethodType, ModuleType
from typing import Any, Dict, List

from . import external


class Bsp:
"""Bsp base class"""
branch: ModuleType # soft copy of "branch script"
endianness: str = "little"
extras: Dict[str, io.BytesIO] # file handles
extras: Dict[str, external.File]
file_magic: bytes = b"XBSP"
# NOTE: XBSP is not a real bsp variant! this is just a placeholder
filesize: int = 0 # size of .bsp in bytes
Expand All @@ -28,7 +30,6 @@ class Bsp:
def __init__(self, branch: ModuleType, filepath: str = "untitled.bsp"):
if not filepath.lower().endswith(".bsp"):
raise RuntimeError("Not a .bsp")
filepath = os.path.realpath(filepath)
self.folder, self.filename = os.path.split(filepath)
self.set_branch(branch)
self.headers = dict()
Expand Down Expand Up @@ -105,11 +106,8 @@ def lump_as_bytes(self, lump_name: str) -> bytes:
raw_lump = lump_entries.as_bytes()
return raw_lump

def mount_file(self, filename: str, archive=None):
if archive is None:
self.extras[filename] = open(filename, "rb")
else:
self.extras[filename] = io.BytesIO(archive.read(filename))
def mount_file(self, filename: str, external_file: external.File):
self.extras[filename] = external_file

def save_as(self, filename: str):
"""Expects outfile to be a file with write bytes capability"""
Expand Down Expand Up @@ -148,33 +146,35 @@ def unmount_file(self, filename: str):
self.extras.pop(filename)

@classmethod
def from_archive(cls, branch: ModuleType, filepath: str, parent_archive, mount_extras=False) -> Bsp:
def from_archive(cls, branch: ModuleType, filepath: str, parent_archive) -> Bsp:
bsp = cls.from_bytes(branch, filepath, parent_archive.read(filepath))
if mount_extras:
extras = [
filename
for filename in parent_archive.listdir(bsp.folder)
for pattern in bsp.extra_patterns()
if fnmatch.fnmatch(filename.lower(), pattern.lower())]
for filename in extras:
bsp.mount_file(os.path.join(bsp.folder, filename))
extras = [
filename
for filename in parent_archive.listdir(bsp.folder)
for pattern in bsp.extra_patterns()
if fnmatch.fnmatch(filename.lower(), pattern.lower())]
for filename in extras:
full_filename = os.path.join(bsp.folder, filename)
external_file = external.File.from_archive(full_filename, parent_archive)
bsp.mount_file(filename, external_file)
return bsp

@classmethod
def from_bytes(cls, branch: ModuleType, filepath: str, raw_bsp: bytes) -> Bsp:
return cls.from_stream(branch, filepath, io.BytesIO(raw_bsp))

@classmethod
def from_file(cls, branch: ModuleType, filepath: str, mount_extras=False) -> Bsp:
def from_file(cls, branch: ModuleType, filepath: str) -> Bsp:
bsp = cls.from_stream(branch, filepath, open(filepath, "rb"))
if mount_extras:
extras = [
filename
for filename in os.listdir(bsp.folder)
for pattern in bsp.extra_patterns()
if fnmatch.fnmatch(filename.lower(), pattern.lower())]
for filename in extras:
bsp.mount_file(os.path.join(bsp.folder, filename))
extras = [
filename
for filename in os.listdir(bsp.folder)
for pattern in bsp.extra_patterns()
if fnmatch.fnmatch(filename.lower(), pattern.lower())]
for filename in extras:
full_filename = os.path.join(bsp.folder, filename)
external_file = external.File.from_file(full_filename)
bsp.mount_file(filename, external_file)
return bsp

@classmethod
Expand Down

0 comments on commit 5b08700

Please sign in to comment.