From e350811b055dd2309a93b0020e381f8c02581869 Mon Sep 17 00:00:00 2001 From: Caleb Fontenot Date: Sun, 19 Dec 2021 23:42:31 -0600 Subject: [PATCH] Add support for modrinth --- mcUp.py | 37 +++++++++++++++++++++++++--- parsers/modrinth.py | 59 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 87 insertions(+), 9 deletions(-) diff --git a/mcUp.py b/mcUp.py index f75682c..d625337 100755 --- a/mcUp.py +++ b/mcUp.py @@ -1,5 +1,7 @@ #!/bin/python # Setup Parser +import requests +from re import sub import parsers.paperMC import parsers.modrinth import argparse @@ -49,13 +51,42 @@ def paperMC(project, action, subAction): raise error # modrinth command functions def modrinth(project, action, subAction): - if action == "list": + if action == "get": if subAction == "info": print(parsers.modrinth.modInfo(project)) - if subAction == "versions": + 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(project)) + if subAction == "get_URL": + print(parsers.modrinth.getDownloadURL(project, parsers.modrinth.getLatestVersion(project))) + if action == "download": + if subAction == "latest": + latestVersion = parsers.modrinth.getLatestVersion(project) + output = parsers.modrinth.getDownloadURL(project, parsers.modrinth.getLatestVersion(project)) + 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 "+latestVersion+" 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) + 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 error # Determine which API parser to use: if args.api == "paperMC": diff --git a/parsers/modrinth.py b/parsers/modrinth.py index b7b6cf7..27ef098 100644 --- a/parsers/modrinth.py +++ b/parsers/modrinth.py @@ -1,6 +1,10 @@ from os import error +from pytz.tzinfo import memorized_timedelta import requests -debug = True +import datetime +import iso8601 +import pytz +debug = False if debug == True: import logging from requests import api @@ -37,7 +41,7 @@ def getVersions(project): return dataCache["getVersions"] workingDict = modInfo(project) versions = workingDict["versions"] - print(versions) + cacheData("getVersions", versions) return versions def getAllModVersionInfo(project): @@ -54,10 +58,53 @@ def getAllModVersionInfo(project): cacheData("getAllMinecraftVersionInfo", responseList) return responseList -def determineLatestMinecraftVersion(project): +def determine(project, whatToDetermine): modInfo = getAllModVersionInfo(project) numberOfVersions = len(modInfo) - gameVersions = {} - #for item in range(numberOfVersions): - #gameVersions = + determine = [] + for item in range(numberOfVersions): + workingDict = modInfo[item] + determine.append(workingDict[whatToDetermine]) + #print(str(item)+" "+str(determine[item])) + return determine +def getLatestVersion(project): + versions = getVersions(project) + publishDates = determine(project, "date_published") + #print(publishDates) + # Get current date + currentDate = pytz.utc.localize(datetime.datetime.utcnow()) + #print(currentDate) + convertedDates = {} + numberOfDates = len(publishDates) + for item in range(numberOfDates): + convertTime = iso8601.parse_date(publishDates[item]) + convertedDates[versions[item]] = convertTime + shortestDate = {} + for item in range(numberOfDates): + shortestDate[versions[item]] = currentDate - convertedDates[versions[item]] + #print(shortestDate) + # Sort the dictionary to find the most recent version + latest = {key: val for key, val in sorted(shortestDate.items(), key = lambda ele: ele[1])} + return list(latest.keys())[0] + +def getDownloadURL(project, versionID): + versions = getVersions(project) + versionInfo = getAllModVersionInfo(project) + downloadURLs = {} + downloadSHA1 = {} + downloadFilenames = {} + # Iterate through the nested lists/dicts + for item in range(len(versions)): + workingDict = versionInfo[item] + #print("workingDict: "+str(workingDict)) + workingList = workingDict["files"] + #print("workingList: "+str(workingList)) + workingDict2 = workingList[0] + workingDict3 = workingDict2["hashes"] + #print(workingDict3) + downloadURLs[versions[item]] = workingDict2["url"] + downloadSHA1[versions[item]] = workingDict3["sha1"] + downloadFilenames[versions[item]] = workingDict2["filename"] + #print(downloadURLs) + return [downloadURLs[versionID], downloadSHA1[versionID], downloadFilenames[versionID]]