Skip to content

Instantly share code, notes, and snippets.

@einsteinx2
Created August 30, 2020 01:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save einsteinx2/b1310ab056be44ceccac79c8d640c77f to your computer and use it in GitHub Desktop.
Save einsteinx2/b1310ab056be44ceccac79c8d640c77f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# Requires: Python 3.7 (might work on 3.6, but I haven't tested)
# Purpose: Rename files such as "Some Game (USA) (En, Fr).gbx" to "Some Game.gbx"
# File Names: This script will operate on any file with the gb, gbc, and gba extension
# Note: Supports both copy and move
import os
import glob
import collections
import array
import shutil
import argparse
import re
from pprint import pprint
from pathlib import Path
from operator import attrgetter
# Constants
ROM_EXT = '.gb*'
SUB_REGEX = '( \(.+?)\.gb.?'
# Named tuple representing each game ROM
RomFile = collections.namedtuple('RomFile', 'in_path, in_filename, out_filename')
# Find all game roms in the input path and calculate their new file names
def process_roms(in_path):
# Array of processed roms so we can do all the processing first before modifying the filesystem
roms = []
# Process the list of roms
glob_str = os.path.join(in_path, F'*{ROM_EXT}')
for in_path in glob.iglob(glob_str):
# Get the original rom file name
in_filename = os.path.basename(in_path)
# Get the file extension
file_ext = os.path.splitext(in_path)[1]
# Get the file name with extra stuff removed
out_filename = re.sub(SUB_REGEX, '', in_filename) + file_ext
# Create the RomFile named tuple and add it to the list of roms
roms.append(RomFile(in_path = in_path, in_filename = in_filename, out_filename = out_filename))
# Sort by file name
roms.sort(key = attrgetter('in_filename'))
# Return the list of RomFile named tuples
return roms
# Copy (or move) the files to their new locations
def copy_roms(roms, out_path, move = False, dry_run = True):
# Create the output directory
if dry_run is False:
Path(out_path).mkdir(parents = True, exist_ok = True)
# Process the ROMs
for rom in roms:
# Determine the output path
out_file_path = os.path.join(out_path, rom.out_filename)
if move is True:
# Move the file
print(F'Moving "{rom.in_path}" to "{out_file_path}".....')
if dry_run is False:
shutil.move(rom.in_path, out_file_path)
else:
# Copy the file
print(F'Copying "{rom.in_path}" to "{out_file_path}".....')
if dry_run is False:
shutil.copy2(rom.in_path, out_file_path)
def parse_args():
parser = argparse.ArgumentParser()
# Positional arguments
parser.add_argument('in_path', help = 'Path to the input directory that contains *.gb* files that are in the format "Some Game (USA) (En, Fr).gbx"')
parser.add_argument('out_path', help = 'Path to the output directory where the renamed files will be placed (if recursive, directory structure will be preserved)')
# Optional arguments
parser.add_argument('-m', '--move', help='Move the disc images instead of copying them (WARNING! Make sure you have a backup copy first!)', action='store_true')
parser.add_argument('-d', '--dry-run', help='Just print out what would happen, but do not copy or move any files', action='store_true')
return parser.parse_args()
def main():
args = parse_args()
if args.dry_run is True:
print("Performing dry run...\n")
roms = process_roms(args.in_path)
copy_roms(roms, args.out_path, args.move, args.dry_run)
# Execute only if run as a script
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment