import requests import os import sys import tempfile import tarfile from rich.console import Console from rich.progress import SpinnerColumn from util import check_ground_libs_path, check_sudo console = Console() def install_package(package_name, version, args): retries_left = args.max_retries with console.status("Downloading tarball...", spinner="bouncingBall", spinner_style="blue") as status: while retries_left > 0: # grab the tar ball response = requests.get(f"https://chookspace.com/api/packages/ground/generic/{package_name}/{version}/mineral.tar") # check response code for errors if response.status_code == 404: # package doesn't exist console.print(f"[b red]digpkg: mineral \"{package_name}\" was not found. Check to make sure the name and version number are correct.[/]") sys.exit(1) elif response.status_code != 200: retries_left -= 1 console.print(f"[b yellow]digpkg: failed to download mineral \"{package_name}\": {response.content.decode()} ({retries_left} retries left)[/]") if retries_left == 0: console.print(f"[b red]digpkg: exceeded max retries while downloading mineral \"{package_name}\"[/]") sys.exit(1) continue response.raise_for_status() break # create temporary file for tarball try: f = tempfile.TemporaryFile("wb+") f.write(response.content) f.flush() f.seek(0) console.print("[d][:white_check_mark:] Tarball downloaded![/]") except KeyboardInterrupt: console.print("[b yellow]digpkg: operation cancelled by user[/]") return # extract the tarball to the GROUND_LIBS folder status.update("Extracting...") extract_dir = os.getenv("GROUND_LIBS") if not os.path.isdir(extract_dir): # gotta ensure the folder exists os.mkdir(extract_dir) tar_file = tarfile.open(fileobj=f) tar_file.extractall(extract_dir) f.close() console.print(f"[d][:white_check_mark:] Extracted to {extract_dir}.") console.status("Finishing up...") # create a symlink from the main.so file to the ground libs folder so ground can find it symlink_path = os.path.join(extract_dir, f"{package_name}.so") # the path where the symlink is if not os.path.isfile(symlink_path): os.symlink(os.path.join(extract_dir, package_name, "main.so"), symlink_path) console.print("[:white_check_mark:] Done!") def install(args): check_sudo() check_ground_libs_path() for package in args.names: # figure out which version to install package_name = package version = "1.0.0" if "@" in package: split = package.split("@") package_name = split[0] version = split[1] else: console.print(f"[b red]digpkg: failed to install package: please specify version to install for {package_name}[/]") sys.exit(1) install_package(package_name, version, args)