mirror of
https://github.com/mon/ifstools.git
synced 2024-11-30 19:54:27 +01:00
Allow fallback extraction of same-name-different-case collisions on Windows
This commit is contained in:
parent
cffe74d00a
commit
57e909572e
@ -1,3 +1,4 @@
|
||||
from collections import defaultdict
|
||||
from multiprocessing import Pool
|
||||
from os.path import basename, dirname, splitext, join, isdir, isfile, getmtime
|
||||
from os import utime, walk
|
||||
@ -128,7 +129,7 @@ class IFS:
|
||||
return str(self.tree)
|
||||
|
||||
def extract(self, progress = True, recurse = True, tex_only = False,
|
||||
extract_manifest = False, path = None, **kwargs):
|
||||
extract_manifest = False, path = None, rename_dupes = False, **kwargs):
|
||||
if path is None:
|
||||
path = self.folder_out
|
||||
if tex_only:
|
||||
@ -155,6 +156,27 @@ class IFS:
|
||||
utils.mkdir_silent(f_path)
|
||||
utime(f_path, (self.time, self.time))
|
||||
|
||||
# handle different-case-but-same-name for Windows
|
||||
same_name = defaultdict(list)
|
||||
for name, obj in folder.files.items():
|
||||
same_name[name.lower()].append(obj)
|
||||
|
||||
for files in same_name.values():
|
||||
# common base case of "sane ifs file"
|
||||
if len(files) == 1:
|
||||
continue
|
||||
|
||||
# make them 'a (1)', 'a (2)' etc
|
||||
if rename_dupes:
|
||||
for i, f in enumerate(files[1:]):
|
||||
base, ext = splitext(f.name)
|
||||
f.name = base + ' ({})'.format(i+1) + ext
|
||||
elif progress: # warn if not silenced
|
||||
all_names = ', '.join([f.name for f in files])
|
||||
tqdm.write('WARNING: Files with same name and differing case will overwrite on Windows ({}). '.format(all_names) +
|
||||
'Use --rename-dupes to extract without loss')
|
||||
# else just do nothing
|
||||
|
||||
# extract the files
|
||||
for f in tqdm(self.tree.all_files, disable = not progress):
|
||||
# allow recurse + tex_only to extract ifs files
|
||||
@ -167,7 +189,8 @@ class IFS:
|
||||
rpath = join(path, f.full_path)
|
||||
i = IFS(rpath)
|
||||
i.extract(progress=progress, recurse=recurse, tex_only=tex_only,
|
||||
extract_manifest=extract_manifest, path=rpath.replace('.ifs','_ifs'), **kwargs)
|
||||
extract_manifest=extract_manifest, path=rpath.replace('.ifs','_ifs'),
|
||||
rename_dupes=rename_dupes, **kwargs)
|
||||
|
||||
|
||||
# you can't pickle open files, so this won't work. Perhaps there is a way around it?
|
||||
|
@ -46,6 +46,8 @@ def main():
|
||||
parser.add_argument('--bounds', action='store_true', help='draw image bounds on the exported canvas in red', dest='draw_bbox')
|
||||
parser.add_argument('--uv', action='store_true', help='crop images to uvrect (usually 1px smaller than imgrect). Forces --tex-only', dest='crop_to_uvrect')
|
||||
parser.add_argument('--no-cache', action='store_false', help='ignore texture cache, recompress all', dest='use_cache')
|
||||
parser.add_argument('--rename-dupes', action='store_true', dest='rename_dupes',
|
||||
help='if two files have the same name but differing case (A.png vs a.png) rename the second as "a (1).png" to allow both to be extracted on Windows')
|
||||
parser.add_argument('-m', '--extract-manifest', action='store_true', help='extract the IFS manifest for inspection', dest='extract_manifest')
|
||||
parser.add_argument('-s', '--silent', action='store_false', dest='progress',
|
||||
help='don\'t display files as they are processed')
|
||||
|
Loading…
Reference in New Issue
Block a user