1
0
mirror of https://github.com/mon/ifstools.git synced 2025-02-26 14:11:43 +01:00
ifstools/ifs/handlers/GenericFile.py

69 lines
2.2 KiB
Python
Raw Normal View History

2017-12-30 15:03:50 +10:00
import os
from kbinxml import KBinXML
import lxml.etree as etree
from .Node import Node
from .. import utils
class GenericFile(Node):
def from_xml(self, element):
self.start, self.size, self.time = self._split_ints(element.text)
def from_filesystem(self, folder):
self.base_path = self.parent.base_path
self.time = int(os.path.getmtime(self.disk_path))
self.start = self.size = None
def extract(self, base, use_cache = True):
data = self.load()
path = os.path.join(base, self.full_path)
utils.save_with_timestamp(path, data, self.time)
def load(self, convert_kbin = True):
if self.from_ifs:
return self._load_from_ifs(convert_kbin)
else:
return self._load_from_filesystem()
def _load_from_ifs(self, convert_kbin = True):
end = self.start + self.size
assert self.start <= len(self.ifs_data) and end <= len(self.ifs_data)
data = self.ifs_data[self.start:end]
if convert_kbin and self.name.endswith('.xml') and KBinXML.is_binary_xml(data):
data = KBinXML(data).to_text().encode('utf8')
return data
def _load_from_filesystem(self):
with open(self.disk_path, 'rb') as f:
ret = f.read()
self.size = len(ret)
return ret
@property
def needs_preload(self):
return False
def preload(self, use_cache):
pass
def repack(self, manifest, data_blob, tqdm_progress):
if tqdm_progress:
tqdm_progress.write(self.full_path)
tqdm_progress.update(1)
elem = etree.SubElement(manifest, self.packed_name)
elem.attrib['__type'] = '3s32'
data = self.load(convert_kbin = False)
if self.name.endswith('.xml') and not KBinXML.is_binary_xml(data):
data = KBinXML(data).to_binary()
# offset, size, timestamp
elem.text = '{} {} {}'.format(len(data_blob.getvalue()), len(data), self.time)
data_blob.write(data)
@property
def disk_path(self):
if self.from_ifs:
raise Exception('disk_path invalid for IFS file')
return os.path.join(self.base_path, self.full_path)