238 lines
7.4 KiB
Python
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()
|