Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- """ Utility script to convert PPP animation files.
- This script is for parsing PPP animation filenames, filtering, renaming, and
- restructuring files.
- Example uses:
- # Clone files from orig_directory into all_files.
- python ponka.py --input "C:/orig_directory"
- --output "C:/new_directory"
- --keep-structure
- # Copy all files from orig_directory into new_directory without copying the
- # directory structure.
- python ponka.py --input "C:/orig_directory"
- --output "C:/new_directory"
- # Move all files from orig_directory into new_directory without copying the
- # directory structure.
- python ponka.py --input "C:/orig_directory"
- --output "C:/new_directory"
- --migrate
- # Move all files with "char" in the path or filename (case-insensitive) into
- # new_directory.
- python ponka.py --input "C:/orig_directory"
- --output "C:/new_directory"
- --filter char
- --migrate
- # Copy files from orig_directory to new_directory and rename them so their
- # corresponding FLA filename comes first, followed by their symbol id, and set the
- # extension to .png.
- python ponka.py --input "C:/orig_directory" --output "C:/new_directory" --rename "{symbol}_{fla}.png"
- # Move files with "char" in their filename from orig_directory to a chars/ directory,
- # and rename them so they're prefixed with "clean_". Don't actually make the changes,
- # just show which changes would be made.
- python ponka.py --input "C:/orig_directory"
- --output "C:/chars"
- --filter char
- --rename "clean_{fla}_{symbol}.png"
- --migrate
- --dry-run
- Run "python ponka.py --help" from the command line or Powershell for the short version.
- """
- import argparse
- import os
- import re
- import shutil
- _EXPLICIT_FLA = re.compile(r'f-(.*)\.fla', re.IGNORECASE)
- _IMPLICIT_FLA = re.compile(r'(.*)\.fla', re.IGNORECASE)
- _EXPLICIT_SYM = re.compile(r's-(.*)\.sym', re.IGNORECASE)
- _IMPLICIT_SYM = re.compile(r'(.*_f[0-9]{0,4})\.png', re.IGNORECASE)
- class SymbolFile:
- def __init__(self, full_path, rel_path):
- self.full_path = full_path
- self.rel_path = rel_path
- self._rel_dir = None
- self._fla_name = None
- self._symbol_name = None
- self._full_name = None
- self._base_name = None
- self._ext = None
- @property
- def rel_dir(self):
- if not self._rel_dir:
- self._rel_dir = os.path.dirname(self.rel_path)
- return self._rel_dir
- @property
- def fla_name(self):
- if self._fla_name:
- return self.fla_name
- for file_part in self.full_path.split(os.sep)[::-1]:
- matches = _EXPLICIT_FLA.search(file_part)
- if matches:
- self._fla_name = matches.group(1)
- return self._fla_name
- for file_part in self.full_path.split(os.sep)[::-1]:
- matches = _IMPLICIT_FLA.search(file_part)
- if matches:
- self._fla_name = matches.group(1)
- return self._fla_name
- raise Exception("Missing FLA file in path: %s" % (self.full_path,))
- @property
- def symbol_name(self):
- if self._symbol_name:
- return self._symbol_name
- for file_part in self.full_path.split(os.sep)[::-1]:
- matches = _EXPLICIT_SYM.search(file_part)
- if matches:
- self._symbol_name = matches.group(1)
- return self._symbol_name
- for file_part in self.full_path.split(os.sep)[::-1]:
- matches = _IMPLICIT_SYM.search(file_part)
- if matches:
- self._symbol_name = matches.group(1)
- return self._symbol_name
- raise Exception("Missing symbol name in path: %s" % (self.full_path,))
- @property
- def full_name(self):
- if not self._full_name:
- self._full_name = os.path.basename(self.rel_path)
- return self._full_name
- def _parse_base_ext(self):
- base_name, ext = os.path.splitext(self.full_name)
- self._base_name = base_name
- self._ext = ext[1:]
- @property
- def base_name(self):
- if self._base_name:
- return self._base_name
- self._parse_base_ext()
- return self._base_name
- @property
- def extension(self):
- if self._ext:
- return self._ext
- self._parse_base_ext()
- return self._ext
- class SymbolFileCopier:
- def __init__(self, output_dir, keep_structure=False, rename_pattern=None, migrate=False, dry_run=False):
- self.output_dir = output_dir
- self.keep_structure = keep_structure
- self.rename_pattern = rename_pattern
- self.migrate = migrate
- self.dry_run = dry_run
- def copy(self, pppfile):
- if self.rename_pattern:
- output_filename = (
- self.rename_pattern.replace("{file}", pppfile.full_name)
- .replace("{base}", pppfile.base_name)
- .replace("{ext}", pppfile.extension)
- .replace("{fla}", f"f-{pppfile.fla_name}.fla")
- .replace("{symbol}", f"s-{pppfile.symbol_name}.sym")
- )
- else:
- output_filename = pppfile.full_name
- if self.keep_structure:
- output_path = os.path.join(self.output_dir, pppfile.rel_dir, output_filename)
- else:
- output_path = os.path.join(self.output_dir, output_filename)
- if self.dry_run:
- op = 'moving' if self.migrate else 'copying'
- print(op, pppfile.full_path, "to", output_path)
- return
- output_dir = os.path.dirname(output_path)
- os.makedirs(output_dir, exist_ok=True)
- try:
- op = os.rename if self.migrate else shutil.copyfile
- op(pppfile.full_path, output_path)
- except:
- print('duplicate file:', pppfile.full_path)
- def _allow_all(x):
- return True
- def collect_files(input_path, filter_regex=None):
- if not filter_regex:
- filter_regex = _allow_all
- else:
- filter_regex = re.compile(filter_regex, re.IGNORECASE).search
- for root, dirs, files in os.walk(input_path):
- for fn in files:
- full_path = os.path.join(root, fn)
- rel_path = os.path.relpath(full_path, start=input_path)
- if not filter_regex(rel_path):
- continue
- yield SymbolFile(full_path, rel_path)
- class SmartFormatter(argparse.HelpFormatter):
- def _split_lines(self, text, width):
- if text.startswith("R|"):
- return text[2:].splitlines()
- return argparse.HelpFormatter._split_lines(self, text, width)
- def _main():
- parser = argparse.ArgumentParser(
- formatter_class=SmartFormatter,
- description='File conversion tool for PPP animation data.')
- parser.add_argument(
- "-i",
- "--input",
- metavar="folder",
- required=True,
- help="Input folder containing the animation data.",
- )
- parser.add_argument(
- "-o",
- "--output",
- metavar="folder",
- required=True,
- help="Output folder for dumping the results.",
- )
- parser.add_argument(
- "--migrate",
- default=False,
- action="store_true",
- help="Include this flag to move files rather than copy them.",
- )
- parser.add_argument(
- "--keep-structure",
- default=False,
- action="store_true",
- help="Replicate the input folder structure in the output folder.",
- )
- parser.add_argument(
- "-f",
- "--filter",
- metavar="pattern",
- required=False,
- help="Filter to include files by filename (regex).",
- )
- parser.add_argument(
- "-r",
- "--rename",
- metavar="template",
- required=False,
- help="""R|Rename files based on the existing name. You can use the following
- template variables:
- {file}: The full filename including the extension.
- {base}: The file name without the extension.
- {ext}: The file extension.
- {fla}: The FLA base name associated with a file.
- {symbol}: The symbol name associated with a file.""",
- )
- parser.add_argument(
- "--dry-run",
- default=False,
- action="store_true",
- help="Dump of the list of changes to be made without actually making them.",
- )
- args = parser.parse_args()
- filter_pattern = args.filter
- rename_template = args.rename
- input_files = collect_files(args.input, filter_pattern)
- copier = SymbolFileCopier(args.output, args.keep_structure, args.rename, args.migrate, args.dry_run)
- for pppfile in input_files:
- copier.copy(pppfile)
- if __name__ == "__main__":
- _main()
Advertisement
Add Comment
Please, Sign In to add comment