Files
QuestAppLauncher_Assets/QuestAssetGenerator.py
oxmc7769 3d86f19c0f
Some checks failed
build-pack / build (push) Has been cancelled
Modernize
2026-03-18 09:16:56 -07:00

238 lines
7.4 KiB
Python

import argparse, datetime, os, requests, shutil, subprocess, sys, zipfile
from QuestAssetDL import main as QuestAssetDL
from github import Github, Auth
# Temporary directory for scratch space
TEMP_DIR = "__temp__"
LATEST_RELASE_DIR = "latest_release"
QALAG_OUTPUT_DIR = "qalag"
WINDIFF_EXE_PATH = "bin\\WinDiff.exe"
QUEST_DIR = "quest"
ICONPACK_QUEST = "iconpack_quest.zip"
APPNAMES_QUEST = "appnames_quest.json"
ICONPACK_OTHER = "iconpack_others.zip"
APPNAMES_OTHER = "appnames_other.json"
APPNAMES_GALAG_NAME = "appnames_quest_en_US.json"
def main():
parser = argparse.ArgumentParser(description="Quest Asset Generator")
parser.add_argument(
"-a", "--access-token", required=True, help="GitHub acess token"
)
parser.add_argument(
"-dr",
"--download-release",
action="store_true",
help="Download latest asset release from github",
)
parser.add_argument(
"-da",
"--download-assets",
action="store_true",
help="Download assets from Oculus",
)
parser.add_argument("-c", "--compare", action="store_true", help="Compare assets")
parser.add_argument(
"-r", "--release", action="store_true", help="Draft a github release"
)
args = parser.parse_args()
# If nothing is specified, perform all actions
if (
not args.download_release
and not args.download_assets
and not args.compare
and not args.release
):
args.download_release = True
args.download_assets = True
args.compare = True
args.release = True
# Instantiate github client
ga = Auth.Token(args.access_token)
g = Github(auth=ga)
repo = g.get_user("HooverHigh").get_repo("QuestAppLauncher_Assets")
# Set up temp dir
folder_path_temp = os.path.abspath(TEMP_DIR)
if not os.path.isdir(folder_path_temp):
os.mkdir(folder_path_temp)
# Download latest assets
if args.download_assets:
download_latest_assets()
# Download latest release
if args.download_release:
download_release_assets(repo)
if args.compare:
compare()
if args.release:
create_release(repo)
def get_release_download_path():
return os.path.join(os.path.abspath(TEMP_DIR), LATEST_RELASE_DIR)
def get_galag_download_path():
return os.path.abspath(os.path.join(os.path.abspath(TEMP_DIR), QALAG_OUTPUT_DIR))
# Download latest Github release
def download_release_assets(repo):
try:
release = repo.get_latest_release()
except Exception:
print("No published releases found, skipping download")
return
print("Downloading release: '%s'" % (release.title))
download_release_path = get_release_download_path()
if os.path.isdir(download_release_path):
shutil.rmtree(download_release_path)
os.mkdir(download_release_path)
assets = release.get_assets()
for asset in assets:
print("\tAsset: %s [%s]" % (asset.name, asset.url))
r = requests.get(
asset.url,
allow_redirects=True,
headers={"Accept": "application/octet-stream"},
)
file_path = os.path.join(download_release_path, asset.name)
open(file_path, "wb").write(r.content)
# Extract quest icons
iconpack_quest_release_zip = os.path.join(download_release_path, ICONPACK_QUEST)
iconpack_quest_release_ext_path = os.path.join(download_release_path, QUEST_DIR)
with zipfile.ZipFile(iconpack_quest_release_zip) as zip:
zip.extractall(iconpack_quest_release_ext_path)
# Download latest assets
def download_latest_assets():
galag_output_dir = get_galag_download_path()
if os.path.isdir(galag_output_dir):
shutil.rmtree(galag_output_dir)
os.mkdir(galag_output_dir)
QuestAssetDL(
platform="quest",
locale="en_US",
action="assets",
output_dir_param=galag_output_dir,
)
# Rename file
for f in os.listdir(galag_output_dir):
if f.startswith("appnames_quest") and f.endswith(".json"):
os.rename(
os.path.join(galag_output_dir, f),
os.path.join(galag_output_dir, APPNAMES_QUEST),
)
break
else:
raise FileNotFoundError("No appnames_quest JSON found")
# Compare
def compare():
# Check if we have a release to compare against
release_path = get_release_download_path()
if not os.path.isdir(release_path) or not os.path.exists(
os.path.join(release_path, ICONPACK_QUEST)
):
print("No previous release assets found, skipping comparison")
return
# Proceed with comparison
iconpack_quest_release_ext_path = os.path.join(release_path, QUEST_DIR)
iconpack_quest_generated_ext_path = os.path.join(
get_galag_download_path(), QUEST_DIR
)
launch_executable(
["-t", iconpack_quest_release_ext_path, iconpack_quest_generated_ext_path],
bin_path=WINDIFF_EXE_PATH,
)
appnames_quest_release_path = os.path.join(release_path, APPNAMES_QUEST)
appnames_quest_generated_path = os.path.join(
get_galag_download_path(), APPNAMES_QUEST
)
launch_executable(
[appnames_quest_release_path, appnames_quest_generated_path],
bin_path=WINDIFF_EXE_PATH,
)
# Create release
def create_release(repo):
tag = "v" + datetime.date.today().strftime("%m.%d.%Y")
name = tag + ": Update quest assets"
print(f"Creating release: tag: {tag}, name: {name}")
release = repo.create_git_release(
tag=tag, name=name, message="Updating quest assets", draft=True
)
# Paths for "other" assets (from previous release)
other_appnames = os.path.join(get_release_download_path(), APPNAMES_OTHER)
other_iconpack = os.path.join(get_release_download_path(), ICONPACK_OTHER)
# Upload other assets only if they exist (first release will skip)
if os.path.exists(other_appnames):
release.upload_asset(other_appnames)
print(f"Uploaded {APPNAMES_OTHER}")
else:
print(f"Warning: {APPNAMES_OTHER} not found, skipping upload")
if os.path.exists(other_iconpack):
release.upload_asset(other_iconpack)
print(f"Uploaded {ICONPACK_OTHER}")
else:
print(f"Warning: {ICONPACK_OTHER} not found, skipping upload")
# Quest assets are always uploaded from the freshly downloaded data
quest_appnames = os.path.join(get_galag_download_path(), APPNAMES_QUEST)
quest_iconpack = os.path.join(get_galag_download_path(), ICONPACK_QUEST)
# Ensure these files exist (they should, from download_latest_assets)
if os.path.exists(quest_appnames):
release.upload_asset(quest_appnames)
else:
raise FileNotFoundError(f"Missing generated Quest appnames: {quest_appnames}")
if os.path.exists(quest_iconpack):
release.upload_asset(quest_iconpack)
else:
raise FileNotFoundError(f"Missing generated Quest iconpack: {quest_iconpack}")
# Launch executable and return output
def launch_executable(args, bin_path):
try:
output = subprocess.check_output([bin_path] + args, stderr=subprocess.STDOUT)
return output.decode(sys.stdout.encoding)
except subprocess.CalledProcessError as e:
raise Exception(
str.format(
str(e)
+ ". Output: '%s'" % (e.output.decode(sys.stdout.encoding).rstrip())
)
) from e
except Exception as e:
raise type(e)(str.format(str(e) + " when calling '%s'" % (bin_path)))
main()