diff --git a/mcUp.py b/mcUp.py index 763b647..4232f44 100755 --- a/mcUp.py +++ b/mcUp.py @@ -20,9 +20,42 @@ parser.add_argument('project', metavar='project', help='which project to query f 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=1) + 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": @@ -70,37 +103,19 @@ def modrinth(project, action, subAction): print(parsers.modrinth.getLatestStable(project)) if subAction == "get_URL": print(parsers.modrinth.getDownloadURL(project, parsers.modrinth.getLatestVersion(project))) - if action == "download": if subAction == "stable": - download(project, parsers.modrinth.getLatestStable(project)) + if version_for_minecraft() == True: + download(project, parsers.modrinth.getForMinecraftVersion(project, args.v, "stable")) + else: + download(project, parsers.modrinth.getLatestStable(project)) if subAction == "latest": - download(project, parsers.modrinth.getLatestVersion(project)) -def download(project, what): - versionToDownload = what - output = parsers.modrinth.getDownloadURL(project, what) - response = requests.get(output[0], stream=True, timeout=1) - 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 + 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)) # Determine which API parser to use: if args.api == "paperMC": diff --git a/parsers/modrinth.py b/parsers/modrinth.py index f27a060..b58dc8b 100644 --- a/parsers/modrinth.py +++ b/parsers/modrinth.py @@ -9,6 +9,7 @@ import datetime import iso8601 import pytz from urllib.parse import unquote +import re debug = True if debug == True: import logging @@ -19,6 +20,8 @@ if debug == True: requests_log.setLevel(logging.DEBUG) requests_log.propagate = True timeoutTime = 1 +#Setup re +#regex = re.compile(r'*') # Setup session, this lets the parser re-use the connection instead of establishing a new connection for EACH request, not only does this cause a HUGE performance boost, it's also nicer to the API. session = requests.Session() base_api_url = "https://api.modrinth.com:443/api/v1" @@ -101,7 +104,7 @@ def getLatestVersion(project, **kwargs): versions = targetted_versions else: versions = getVersions(project) - print(versions) + #print(versions) publishDates = determine(project, "date_published") #print(publishDates) # Get current date @@ -120,24 +123,53 @@ def getLatestVersion(project, **kwargs): latest = {key: val for key, val in sorted(shortestDate.items(), key = lambda ele: ele[1])} return list(latest.keys())[0] -def getLatestStable(project): - print("Calling getLatestStable()...") - versions = getVersions(project) - build_type = determine(project, "version_type") +def key_filter(project, dict_to_filter, key_to_grab, type_to_grab): + print("Calling key_filter()...") + versions = dict_to_filter + build_type = determine(project, key_to_grab) # Build a dictionary that ties the versions to the build type build_type_dict = {} number_of_versions = len(versions) for item in range(number_of_versions): build_type_dict[versions[item]] = build_type[item] - print(build_type_dict) + #print(build_type_dict) # Sort dictionary to filter out only the release builds stable = [] + print("Looking for "+str(type_to_grab)) for key, value in build_type_dict.items(): - if value == 'release': - print(key) + #print("looking at "+str(value)) + search = re.search(str(type_to_grab), str(value)) + if search != None: + print("Match!") + #print(key) stable.append(key) + # Call getLatestVersion, tell it to use our output - return getLatestVersion(project, targetted_versions=stable) + return stable + +def getForMinecraftVersion(project, version, stability): + print("Calling getForMinecraftVersion()...") + print("Downloading",stability,"for Minecraft version", version) + if stability == "stable": + #Filter Game versions + targetted_versions=key_filter(project, getVersions(project), "game_versions", version) + #Filter Stable versions + stable_versions=key_filter(project, targetted_versions, "version_type", "release") + result = getLatestVersion(project, targetted_versions=stable_versions) + elif stability == "latest": + #Filter Game versions + targetted_versions=key_filter(project, getVersions(project), "game_versions", version) + #print(targetted_versions) + #Filter Latest versions + stable_versions=key_filter(project, targetted_versions, "version_type", "release") + result = getLatestVersion(project, targetted_versions=stable_versions) + print("latest build for "+version+" is "+result) + return result + +def getLatestStable(project): + print("Calling getLatestStable()...") + return getLatestVersion(project, getVersions(project) ,targetted_versions=key_filter(project, "version_type", "release")) + def getDownloadURL(project, versionID): print("Calling getDownloadURL()...")