Skip to content

Instantly share code, notes, and snippets.

@smiley
Created June 23, 2018 16:50
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 smiley/5472ffad2f9d92f94b6bf7bd192ef321 to your computer and use it in GitHub Desktop.
Save smiley/5472ffad2f9d92f94b6bf7bd192ef321 to your computer and use it in GitHub Desktop.
Install osu! beatmaps (.osz) without launching osu! (but requiring a refresh), by plainly extracting them into the songs folder.
from collections import namedtuple
import json
import os
import sys
import zipfile
import winreg
from winreg import HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER, KEY_READ, KEY_WOW64_32KEY, KEY_WOW64_64KEY
RegistryKeyMetadata = namedtuple('RegistryKeyMetadata', ['root', 'path', 'value_name'])
OSU_USER_KEY = RegistryKeyMetadata(HKEY_CURRENT_USER, '\\'.join([
'SOFTWARE',
'osu!'
]), 'UninstallId')
OSU_UNINSTALL_KEY = RegistryKeyMetadata(HKEY_LOCAL_MACHINE, '\\'.join([
'SOFTWARE',
'Microsoft',
'Windows',
'CurrentVersion',
'Uninstall',
'{{{osuid}}}'
]), 'DisplayIcon')
OSU_PATH_END = '\\osu!.exe'
SCRIPT_SETTINGS_FILE = os.path.expanduser("~/.osuimport")
def get_osu_uninstall_id():
with winreg.OpenKey(OSU_USER_KEY.root, OSU_USER_KEY.path, access=KEY_READ) as user_key:
return winreg.QueryValueEx(user_key, OSU_USER_KEY.value_name)[0]
def get_osu_path(uninstall_id=None):
if os.path.exists(SCRIPT_SETTINGS_FILE):
try:
with open(SCRIPT_SETTINGS_FILE, 'r') as f:
settings = json.load(f)
return settings.get("path")
except:
# Continue normal flow
pass
if uninstall_id is None:
uninstall_id = get_osu_uninstall_id()
with winreg.OpenKey(OSU_UNINSTALL_KEY.root, OSU_UNINSTALL_KEY.os.path.format(osuid=uninstall_id), access=KEY_READ) as uninstall_key:
osu_exe = winreg.QueryValueEx(uninstall_key, OSU_UNINSTALL_KEY.value_name)[0]
if osu_exe.endswith(OSU_PATH_END):
return osu_exe[0:len(osu_exe) - len(OSU_PATH_END)]
return osu_exe
def get_songs_path(osu_path):
songs_default = os.path.join(osu_path, 'Songs')
if os.path.exists(songs_default):
return songs_default
raise FileNotFoundError("Could not find songs folder inside the given osu! os.path.")
def validate_osu_path(osu_path):
return os.path.exists(os.path.join(osu_path, 'osu!.exe')) and \
os.path.exists(os.path.join(osu_path, 'Songs')) and \
os.path.exists(os.path.join(osu_path, 'osu!.cfg'))
def save_osu_path(osu_path):
if validate_osu_path(osu_path):
with open(SCRIPT_SETTINGS_FILE, 'w') as f:
json.dump({'path': osu_path}, f)
def main(zip_path):
try:
OSU_PATH = get_osu_path()
if not validate_osu_path(OSU_PATH):
raise FileNotFoundError()
except FileNotFoundError as ex:
print("I can't find Osu! installed. Type the path below; it'll be saved for future reference.")
OSU_PATH = input("osu! installation path: ")
if validate_osu_path(OSU_PATH):
save_osu_path(OSU_PATH)
print("Processing: {0}".format(zip_path))
with zipfile.ZipFile(zip_path) as zf:
zip_dst = os.path.join(get_songs_path(OSU_PATH), os.path.basename(zip_path).split(os.path.extsep)[0])
print("Extracting to: {0}".format(zip_dst))
if os.path.exists(zip_dst):
print("Already exists/installed; skipping...")
else:
os.mkdir(zip_dst)
zf.extractall(zip_dst)
print("Done.")
if __name__ == '__main__':
main(sys.argv[1])
input("Press ENTER to exit...")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment