#!/bin/python # Setup Parser from ssl import HAS_ECDH import requests #import socket #from request_wrapper import requests_wrapper as requests from re import sub import parsers.paperMC import parsers.modrinth import parsers.curseforge import argparse import shutil import hashlib from os import error # Define Errors: class MismatchSHA1Error(Exception): pass parser = argparse.ArgumentParser(description='A command-line tool to update a Minecraft Server.') parser.add_argument('api', metavar='api', help='which API to use') parser.add_argument('project', metavar='project', help='which project to query for') parser.add_argument('action', metavar='action', help='what action to execute') parser.add_argument('subAction', metavar='subAction', help='what sub action to execute') parser.add_argument('-o', nargs="?", help='Optional: Specify output filepath') parser.add_argument('-v', nargs="?", help='Specify Minecraft Version to target') args = parser.parse_args() print("mcUp.py, written by Caleb Fontenot") print(args.o) #Downloader function def download(project, what): versionToDownload = what output = parsers.modrinth.getDownloadURL(project, what) response = requests.get(output[0], stream=True, timeout=10) if args.o != None: # Check if user set an output filepath output_file = args.o else: output_file = output[2] with response as raw: with open(output_file, 'wb') as file_object: shutil.copyfileobj(raw.raw, file_object) print("Downloaded "+versionToDownload+" to "+output_file) #Calculate hash, compare with API given hash h_sha1 = hashlib.sha1() with open(output_file, 'rb') as file_object: chunk = 0 while chunk != b'': chunk = file_object.read(1024) h_sha1.update(chunk) print("API SHA 1: "+str(output[1])) print("Our calculated SHA 1: "+str(h_sha1.hexdigest())) if h_sha1.hexdigest() == output[1]: print("sha1sum of downloaded file matches the sum that the API gave, jar is safe to use") else: raise MismatchSHA1Error # determine if args.v has a value def version_for_minecraft(): if args.v != None: return True else: return False # PaperMC command functions def paperMC(project, action, subAction): if action == "get": if subAction == "versions": print(parsers.paperMC.getVersions(project)) elif subAction == "latest": latestVersion = parsers.paperMC.getLatest(project) buildNumber = parsers.paperMC.getBuildNumber(project, latestVersion) print("Latest version of "+project+" is "+latestVersion+" build #"+str(buildNumber[-1])) if action == "download": if subAction == "latest": latestVersion = parsers.paperMC.getLatest(project) output = parsers.paperMC.getJarInfo(project, latestVersion) if args.o != None: # Check if user set an output filepath output_file = args.o else: output_file = output["name"] with parsers.paperMC.downloadVersion(project, latestVersion) as raw: with open(output_file, 'wb') as file_object: shutil.copyfileobj(raw.raw, file_object) print("Downloaded "+latestVersion+" to "+output_file) #Calculate hash, compare with API given hash h_sha256 = hashlib.sha256() with open(output_file, 'rb') as file_object: chunk = 0 while chunk != b'': chunk = file_object.read(1024) h_sha256.update(chunk) if h_sha256.hexdigest() == output["sha256"]: print("sha256sum of downloaded file matches the sum that the API gave, jar is safe to use") else: raise error # modrinth command functions def modrinth(project, action, subAction): if action == "get": if subAction == "info": print(parsers.modrinth.modInfo(project)) if subAction == "version_info": print(parsers.modrinth.getAllModVersionInfo(project)) if subAction == "versions": print(parsers.modrinth.determine(project, "version_number")) if subAction == "latest": print(parsers.modrinth.getLatestVersion_by_number(project, args.v)) if subAction == "stable": print(parsers.modrinth.getLatestStable(project)) if subAction == "get_URL": print(parsers.modrinth.getDownloadURL(project, parsers.modrinth.getLatestVersion(project))) if action == "download": if subAction == "stable": if version_for_minecraft() == True: download(project, parsers.modrinth.getForMinecraftVersion(project, args.v, "stable")) else: download(project, parsers.modrinth.getLatestStable(project)) if subAction == "latest": if version_for_minecraft() == True: download(project, parsers.modrinth.getForMinecraftVersion(project, args.v, "latest")) else: download(project, parsers.modrinth.getLatestVersion(project)) #print(parsers.modrinth.getForMinecraftVersion(project, args.v)) # CurseForge command functions def curseforge(project, action, subAction): import json if action == "get": if subAction == "games": print(parsers.curseforge.get_games()) if subAction == "mod": print(json.dumps(parsers.curseforge.get_mod(project), indent=4)) if action == "search": if subAction == "mod": print(json.dumps(parsers.curseforge.search_mods(project), indent=4)) if action == "download": if subAction == "latest": print(parsers.curseforge.download(project)) # Determine which API parser to use: if args.api == "paperMC": paperMC(args.project, args.action, args.subAction) elif args.api == "modrinth": modrinth(args.project, args.action, args.subAction) elif args.api == "curseforge": curseforge(args.project, args.action, args.subAction) else: print("Error: Unknown API: "+args.api)