/paks-dl/pak_utils.py
Python | 126 lines | 93 code | 21 blank | 12 comment | 24 complexity | 63f69008206aa4f4e2ec055d96d106d3 MD5 | raw file
- #!/usr/bin/env python3
- import os
- import glob
- import subprocess
- import pathlib
- import hashlib
- PAKTOOL = os.environ['CLAW_ROOT'] + "/bin/claw-paktool"
- _pakCreatedCallback = None
- def onPakCreated(func):
- """Register callback which is called when pakTool creates pak file"""
- global _pakCreatedCallback
- _pakCreatedCallback = func
- def callCommand(args, stdin=""):
- """Launch given process with optional stdin input"""
- startupinfo = None
- if os.name == 'nt':
- startupinfo = subprocess.STARTUPINFO()
- startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
- p = subprocess.Popen(args,
- stdout=subprocess.PIPE,
- stdin=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- startupinfo=startupinfo)
- grep_stdout = p.communicate(input=bytes(stdin, 'ascii'))[0]
- print(grep_stdout.decode())
- def md5(fname):
- """Calculates md5 for given file"""
- hash_md5 = hashlib.md5()
- with open(fname, "rb") as f:
- for chunk in iter(lambda: f.read(4096*10), b""):
- hash_md5.update(chunk)
- return hash_md5.hexdigest()
- def listFilesExtended(path, fileFilterFunc=None, folderFilterFunc=None, maxdepth=None):
- """Recursively lists all files under path that match criteria"""
- files = []
- folder_stack = [(pathlib.Path(path), 0)]
- while folder_stack:
- current_dir, depth = folder_stack.pop(0)
- depth = depth + 1
- for file in current_dir.iterdir():
- if file.is_dir():
- if not folderFilterFunc or folderFilterFunc(file):
- if not maxdepth or depth < maxdepth:
- folder_stack.append((file, depth))
- else:
- if not fileFilterFunc or fileFilterFunc(file):
- files.append(file.as_posix())
- return files
- def listFiles(path, includedExtensions=[], excludedExtensions=[], excludedFolders=[], excludedSubfoldersOf=[], maxdepth=None):
- """Recursively lists all files under path that match criteria"""
- def _excludeExtension(file):
- if includedExtensions:
- return file.suffix in includedExtensions
- return not file.suffix in excludedExtensions
- def _excludeFolder(file):
- if file.stem in excludedFolders:
- return False
- if excludedSubfoldersOf and file.parent.stem in excludedSubfoldersOf:
- return False
- return True
- return listFilesExtended(path,
- fileFilterFunc=_excludeExtension,
- folderFilterFunc=_excludeFolder,
- maxdepth=maxdepth)
- def globFiles(path):
- """Return a possibly-empty list of posix styled path names that match pathname,
- which must be a string containing a path specification.
- path can contain shell-style wildcards."""
- files = pathlib.Path('.').glob(path)
- return [file.as_posix() for file in files]
- def pakTool(output, files, stripPath=None):
- """Calls pakTool to create output pak file from given files"""
- if stripPath:
- args = [PAKTOOL, "-s", str(stripPath), output]
- else:
- args = [PAKTOOL, output]
- filelist = "\n".join(files)
- callCommand(args, filelist)
- if _pakCreatedCallback:
- _pakCreatedCallback(output, files)
- def pakFolder(output, path, includedExtensions=[], excludedExtensions=[], excludedFolders=[], excludedSubfoldersOf=[], maxdepth=None, stripPath=None, skipIfEmpty=False):
- """Creates pak file from all files under path that match criteria"""
- files = listFiles(path,
- maxdepth=maxdepth,
- includedExtensions=includedExtensions,
- excludedExtensions=excludedExtensions,
- excludedFolders=excludedFolders,
- excludedSubfoldersOf=excludedSubfoldersOf)
- if not files and skipIfEmpty:
- return None
- return pakTool(output, files, stripPath=stripPath)
- def paksFromSubfolders(rootDir, stripPathFromPakName, stripPath, skipIfEmpty=False, includedExtensions=[], pakPrefix=""):
- """Create separate pak files from each folder under rootDir (includes rootDir)"""
- subfolders = [rootDir.as_posix()]
- subfolders.extend(glob.glob(rootDir.as_posix() + "/*/"))
- subfolders.extend(glob.glob(rootDir.as_posix() + "/**/*/", recursive=True))
- for subfolder in subfolders:
- subfolder = pathlib.Path(subfolder)
- pakName = pakPrefix + subfolder.relative_to(stripPathFromPakName).as_posix().replace("/", "_") + ".pak"
- pakFolder(pakName,
- subfolder.as_posix() + "/",
- stripPath=stripPath,
- maxdepth=1,
- skipIfEmpty=skipIfEmpty,
- includedExtensions=includedExtensions)