Dotfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
3.8 KiB

#!/usr/bin/env python3
# StepMania 5 Song package generator
# (c) 2015 Taeyeon Mori
#
# This program tries to create a .smzip ready to drop into SM5/Packages from downloaded .zips containing songs
import zipfile
import os
import tempfile
import posixpath
def zip_has_file(f, filename):
try:
f.getinfo(filename)
except KeyError:
return False
return True
def colorful(text, color):
return "\033[%sm%s\033[0m" % (color, text)
def run(filename, *, delete_orig=False, replace=False, rename_bak=False):
with zipfile.ZipFile(filename) as f:
if zip_has_file(f, "Songs/"):
print("==> '%s' already a valid StepMania song package" % colorful(filename, 36))
return True
else:
print("==> '%s' is not a valid StepMania song package" % colorful(filename, 36))
if any((
zip_has_file(f, "Announcers/"),
zip_has_file(f, "Characters/"),
zip_has_file(f, "Data/"),
zip_has_file(f, "Noteskins/"),
zip_has_file(f, "Themes/"))):
print("===> However, it seems to be a different type of SM Package.")
return False
if replace:
newname = filename
oldname = ".".join(filename, "bak")
os.rename(filename, oldname)
print("===> Original was renamed to '%s'" % colorful(oldname, 35))
else:
newname = ".".join((os.path.splitext(filename)[0], "smzip"))
if newname == filename:
newname = ".".join((os.path.splitext(filename)[0], "new", "smzip"))
oldname = filename
if os.path.exists(newname):
print("===> Target filename exists: '%s'" % colorful(newname, 35))
return False
print("===> Repacking into StepMania Package: '%s'" % colorful(newname, 35))
with tempfile.TemporaryDirectory() as tmp:
with zipfile.ZipFile(newname, "w", zipfile.ZIP_DEFLATE) as out:
dirs = []
for info in f.infolist():
print("\r====> Processing '%s'" % colorful(info.filename, 32), end="\033[0K")
file = f.extract(info, path=tmp)
out.write(file, posixpath.join("Songs", info.filename))
if os.path.isfile(file):
os.unlink(file)
else:
dirs.append(file)
for directory in reversed(dirs):
os.rmdir(directory)
print("\r\033[2K", end="")
if delete_orig:
print("===> Deleting Original Archive.")
os.unlink(oldname)
elif rename_bak and not replace:
xoldname = ".".join((oldname, "bak"))
os.rename(oldname, xoldname)
print("===> Original was renamed to '%s'" % colorful(xoldname, 35))
print("===> Done.")
return True
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-delete", action="store_true", help="Delete original files")
parser.add_argument("-replace", action="store_true", help="Use the original filename for the new archive and add .bak to the original one")
parser.add_argument("-rename", action="store_true", help="Rename original files to *.bak")
parser.add_argument("files", nargs="+", help="The files to process")
args = parser.parse_args()
print("=> Running sm-song-package")
print("=> (c) 2015 Taeyeon Mori")
for file in args.files:
run(file, delete_orig=args.delete, replace=args.replace, rename_bak=args.rename)
print("=> Done.")