diff --git a/bin/sm-song-package b/bin/sm-song-package new file mode 100755 index 0000000..834f239 --- /dev/null +++ b/bin/sm-song-package @@ -0,0 +1,109 @@ +#!/usr/bin/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.") diff --git a/bin/stayawake b/bin/stayawake new file mode 100755 index 0000000..059882e --- /dev/null +++ b/bin/stayawake @@ -0,0 +1,66 @@ +#!/usr/bin/python +# Sleep Timer for Aufio Books, inspired by some of the nice Android audiobook players +# (c) 2015 by Taeyeon Mori + + +from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia + +import sys +import subprocess + + +cmd = ["audacious", "--pause"] +beep = "/usr/share/sounds/freedesktop/stereo/complete.oga" + + +def run_task(): + print("Rnunning ", cmd) + subprocess.check_call(cmd) + + + +def main(app): + icon = QtGui.QIcon.fromTheme("caffeine", QtGui.QIcon.fromTheme("kalarm")) + tray = QtWidgets.QSystemTrayIcon(icon) + + def wakeup(): + print("Checking Human") + dialog = QtWidgets.QMessageBox(QtWidgets.QMessageBox.NoIcon, "Wake up", "Click OK or press return to reset timer") + dialog.addButton(QtWidgets.QMessageBox.Ok) + dialog.addButton(QtWidgets.QMessageBox.Close) + timeout = QtCore.QTimer() + timeout.setInterval(60000) + timeout.setSingleShot(True) + timeout.timeout.connect(dialog.reject) + + QtMultimedia.QSound.play(beep) + + timeout.start() + if dialog.exec() != QtWidgets.QMessageBox.Ok: + timeout.stop() + run_task() + app.quit() + else: + timer.start() + + timer = QtCore.QTimer() + timer.setInterval(600000) + timer.setSingleShot(True) + timer.timeout.connect(wakeup) + + menu = QtWidgets.QMenu() + areset = menu.addAction("Reset") + areset.triggered.connect(lambda x: (timer.stop(), timer.start())) + aquit = menu.addAction("Quit") + aquit.triggered.connect(app.quit) + tray.setContextMenu(menu) + + tray.show() + timer.start() + return app.exec() + + +if __name__ == "__main__": + app = QtWidgets.QApplication(sys.argv) + sys.exit(main(app)) +