import tarfile import tempfile import os, sys import requests from requests.auth import HTTPBasicAuth from rich.console import Console from rich.prompt import Prompt console = Console() def publish(args): if not "@" in args.name: console.print(f"[b red]digpkg: failed to publish mineral: please include the version number in the package name. e.g: request@1.0.0") sys.exit(1) split_name = args.name.split("@") mineral_name = split_name[0] version = split_name[1] # sanity checks if not os.path.isdir(args.folder_path): console.print(f"[b red]digpkg: failed to publish mineral: \"{args.folder_path}\" is not a directory") sys.exit(1) if not os.path.isfile(os.path.join(args.folder_path, "mineral.ini")): console.print(f"[b red]digpkg: failed to publish mineral: mineral has no \"mineral.ini\" file") sys.exit(1) # ask for user and pass console.print("[b]Please authenticate.\n[/]") try: username = Prompt.ask("Username", console=console) password = Prompt.ask("Password (or PAT)", console=console, password=True) except KeyboardInterrupt: return console.print() with console.status("Authenticating...", spinner="bouncingBall", spinner_style="blue") as status: # check if we have permission to link the package to the repo repo_perms_request = requests.get( url=f"https://chookspace.com/api/v1/users/{username}/orgs/ground/permissions", auth=HTTPBasicAuth(username, password) ) if repo_perms_request.status_code == 401: console.print(f"[b red]digpkg: failed to publish mineral: checking authorization failed: invalid password[/b red]") sys.exit(1) elif not repo_perms_request.ok: console.print(f"[b red]digpkg: failed to publish mineral: checking authorization failed: {repo_perms_request.content.decode()}[/b red]") sys.exit(1) # compress to a tar file console.status("Compressing") f = tempfile.TemporaryFile(mode="wb+") with tarfile.open(fileobj=f, mode="w:gz") as tar_file: tar_file.add(args.folder_path, arcname=os.path.basename(args.folder_path)) f.flush() f.seek(0) console.print("[d][:white_check_mark:] Compressed![/]") # send the request status.update("Uploading...") response = requests.put( url=f"https://chookspace.com/api/packages/ground/generic/{mineral_name}/{version}/mineral.tar", data=f, auth=HTTPBasicAuth(username, password) ) f.close() match response.status_code: case 401: console.print("[b red]digpkg: failed to publish mineral: authentication failed[/]") sys.exit(1) case 400: console.print("[b red]digpkg: failed to publish mineral: the package name or version number are invalid[/]") sys.exit(1) case 409: console.print("[b red]digpkg: failed to publish mineral: that version number is already in use[/]") sys.exit(1) response.raise_for_status() console.print("[d][:white_check_mark:] Uploaded![/]") console.print("[:white_check_mark:] Done!")