diff --git a/src/handlers/handle_ftp.py b/src/handlers/handle_ftp.py index 774b07d..27fbebb 100644 --- a/src/handlers/handle_ftp.py +++ b/src/handlers/handle_ftp.py @@ -101,8 +101,7 @@ def ftp_validateFileAttributes(ftp, pluginPath): pluginFTPAttribute = ftp.lstat(pluginPath) if stat.S_ISDIR(pluginFTPAttribute.st_mode): return False - if stat.S_ISDIR(pluginFTPAttribute.st_mode): - if re.search(r'.jar$', pluginFTPAttribute.filename): - return True - else: - return False + elif re.search(r'.jar$', pluginPath): + return True + else: + return False diff --git a/src/handlers/handle_input.py b/src/handlers/handle_input.py index b192111..3dc5af3 100644 --- a/src/handlers/handle_input.py +++ b/src/handlers/handle_input.py @@ -61,7 +61,7 @@ def handleInput(inputCommand, inputSelectedObject, inputParams): if inputSelectedObject == 'serverjar': checkInstalledServerjar() else: - checkInstalledPackage(inputSelectedObject) + checkInstalledPackage(inputSelectedObject, inputParams) break if inputCommand == 'search': searchPackage(inputSelectedObject) diff --git a/src/handlers/handle_sftp.py b/src/handlers/handle_sftp.py index 7b15380..df5e71a 100644 --- a/src/handlers/handle_sftp.py +++ b/src/handlers/handle_sftp.py @@ -97,8 +97,7 @@ def sftp_validateFileAttributes(sftp, pluginPath): pluginSFTPAttribute = sftp.lstat(pluginPath) if stat.S_ISDIR(pluginSFTPAttribute.st_mode): return False - if stat.S_ISDIR(pluginSFTPAttribute.st_mode): - if re.search(r'.jar$', pluginSFTPAttribute.filename): - return True - else: - return False + elif re.search(r'.jar$', pluginPath): + return True + else: + return False diff --git a/src/plugin/plugin_updatechecker.py b/src/plugin/plugin_updatechecker.py index 12874bd..194944e 100644 --- a/src/plugin/plugin_updatechecker.py +++ b/src/plugin/plugin_updatechecker.py @@ -1,8 +1,7 @@ import os import re import io -import stat -import pysftp +import base64 from zipfile import ZipFile from urllib.error import HTTPError from pathlib import Path @@ -23,8 +22,8 @@ def createPluginList(): return INSTALLEDPLUGINLIST -def addToPluginList(pluginId, versionId, plugin_latest_version, plugin_is_outdated): - INSTALLEDPLUGINLIST.append([pluginId, versionId, plugin_latest_version, plugin_is_outdated]) +def addToPluginList(localFileName, pluginId, versionId, plugin_latest_version, plugin_is_outdated): + INSTALLEDPLUGINLIST.append([localFileName, pluginId, versionId, plugin_latest_version, plugin_is_outdated]) def getFileName(pluginName): @@ -59,6 +58,23 @@ def getLatestPluginVersion(pluginId): return versionLatestUpdate +def getUpdateDescription(pluginId): + url = f"https://api.spiget.org/v2/resources/{pluginId}/updates?size=1&sort=-date" + latestDescriptionSearch = doAPIRequest(url) + versionLatestDescription = latestDescriptionSearch[0]["description"] + versionLatestDescription = base64.b64decode(versionLatestDescription) + versionLatestDescriptionText =versionLatestDescription.decode('utf-8') + htmlRegex = re.compile('<.*?>') + versionLatestDescriptionText = re.sub(htmlRegex, '', versionLatestDescriptionText) + linesChangelogDescription = versionLatestDescriptionText.split("\n") + nonEmptyLines = [line for line in linesChangelogDescription if line.strip() != ""] + stringnonEmptyLines = "" + for line in nonEmptyLines: + stringnonEmptyLines += line + "\n" + stringnonEmptyLines = stringnonEmptyLines[:-1] + return stringnonEmptyLines + + def compareVersions(plugin_latest_version, pluginVersion): if pluginVersion < plugin_latest_version: plugin_is_outdated = True @@ -114,7 +130,7 @@ def eggCrackingJar(localJarFileName, searchMode): return pluginName -def checkInstalledPackage(inputSelectedObject="all"): +def checkInstalledPackage(inputSelectedObject="all", inputOptionalParam=None): configValues = configurationValues() createPluginList() pluginFolderPath = configValues.pathToPluginFolder @@ -127,9 +143,12 @@ def checkInstalledPackage(inputSelectedObject="all"): pluginList = ftp_listAll(connection) else: pluginList = os.listdir(pluginFolderPath) + i = 0 oldPlugins = 0 print(oColors.brightBlack + f"Checking: {inputSelectedObject}" + oColors.standardWhite) + if inputOptionalParam != "changelog": + print(oColors.brightBlack + f"Use 'check {inputSelectedObject} changelog' to get the latest changelog from plugins" + oColors.standardWhite) print("┌─────┬────────────────────────────────┬──────────────┬──────────────┬───────────────────┐") print("│ No. │ Name │ Installed V. │ Latest V. │ Update available │") print("└─────┴────────────────────────────────┴──────────────┴──────────────┴───────────────────┘") @@ -154,7 +173,6 @@ def checkInstalledPackage(inputSelectedObject="all"): continue if not re.search(r'.jar$', plugin): continue - try: fileName = getFileName(plugin) fileVersion = getFileVersion(plugin) @@ -166,7 +184,7 @@ def checkInstalledPackage(inputSelectedObject="all"): if fileVersion == '': fileVersion = 'N/A' try: - pluginLatestVersion = INSTALLEDPLUGINLIST[i][2] + pluginLatestVersion = INSTALLEDPLUGINLIST[i][3] except IndexError: pluginLatestVersion = 'N/A' @@ -174,7 +192,7 @@ def checkInstalledPackage(inputSelectedObject="all"): pluginLatestVersion = 'N/A' try: - pluginIsOutdated = INSTALLEDPLUGINLIST[i][3] + pluginIsOutdated = INSTALLEDPLUGINLIST[i][4] except IndexError: pluginIsOutdated = 'N/A' @@ -187,28 +205,37 @@ def checkInstalledPackage(inputSelectedObject="all"): if re.search(r'.jar$', fileName): fileName = eggCrackingJar(plugin, "name") - if inputSelectedObject != "*" and inputSelectedObject != "all": + if inputSelectedObject != "all" and inputSelectedObject != "*": + if inputSelectedObject != pluginIdStr or not re.search(inputSelectedObject, fileName, re.IGNORECASE): + i += 1 + continue + + if inputSelectedObject == "all" or inputSelectedObject != "*" or inputSelectedObject != "all": if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE): if pluginLatestVersion == 'N/A': print(oColors.brightBlack + f" [{1}]".rjust(6), end='') else: print(f" [{1}]".rjust(6), end='') - print(" ", end='') - print(f"{fileName}".ljust(33), end='') - print(f"{fileVersion}".ljust(15), end='') - print(f"{pluginLatestVersion}".ljust(15), end='') - print(f"{pluginIsOutdated}".ljust(5) + oColors.standardWhite) - break - else: - if pluginLatestVersion == 'N/A': - print(oColors.brightBlack + f" [{i+1}]".rjust(6), end='') else: - print(f" [{i+1}]".rjust(6), end='') + if pluginLatestVersion == 'N/A': + print(oColors.brightBlack + f" [{i+1}]".rjust(6), end='') + else: + print(f" [{i+1}]".rjust(6), end='') print(" ", end='') print(f"{fileName}".ljust(33), end='') print(f"{fileVersion}".ljust(15), end='') print(f"{pluginLatestVersion}".ljust(15), end='') print(f"{pluginIsOutdated}".ljust(5) + oColors.standardWhite) + if (inputOptionalParam == "changelog" and pluginLatestVersion != 'N/A'): + print(oColors.brightYellow + f"CHANGELOG {fileName}:" + oColors.standardWhite) + description = getUpdateDescription(pluginId) + print(description) + print() + if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE): + break + else: + print(oColors.brightRed + "Wrong input! Use 'check all' to check every plugin for updates!" + oColors.standardWhite) + break i += 1 except TypeError: @@ -218,17 +245,33 @@ def checkInstalledPackage(inputSelectedObject="all"): def updateInstalledPackage(inputSelectedObject='all'): configValues = configurationValues() - createPluginList() - pluginFolderPath = configValues.pathToPluginFolder if not configValues.localPluginFolder: if configValues.sftp_useSftp: connection = createSFTPConnection() - pluginList = sftp_listAll(connection) else: connection = createFTPConnection() - pluginList = ftp_listAll(connection) - else: - pluginList = os.listdir(pluginFolderPath) + + try: + print(oColors.brightBlack + "Selected plugins:" + oColors.standardWhite) + if inputSelectedObject == "all" or inputSelectedObject == "*": + for pluginIndex in range(len(INSTALLEDPLUGINLIST)): + fileName = getFileName(INSTALLEDPLUGINLIST[pluginIndex][0]) + print(fileName, end=' ') + else: + print(inputSelectedObject, end=' ') + + print() + updateConfirmation = input("Update these plugins [y/n] ? ") + if updateConfirmation != "y": + print(oColors.brightRed + "Aborting the update process."+ oColors.standardWhite) + return False + + except NameError: + print(oColors.brightRed + "Check for updates before updating plugins with: 'check all'" + oColors.standardWhite) + print(oColors.brightRed + "Started checking for updates..." + oColors.standardWhite) + checkInstalledPackage() + print(oColors.brightRed + f"Please input 'update {inputSelectedObject}' again!" + oColors.standardWhite) + return False i = 0 pluginsUpdated = 0 @@ -238,7 +281,8 @@ def updateInstalledPackage(inputSelectedObject='all'): print("│ No. │ Name │ Old V. │ New V. │") print("└─────┴────────────────────────────────┴────────────┴──────────┘") try: - for plugin in track(pluginList, description="Updating" ,transient=True, complete_style="bright_magenta"): + for pluginArray in track(INSTALLEDPLUGINLIST, description="Updating" ,transient=True, complete_style="bright_magenta", ): + plugin = INSTALLEDPLUGINLIST[i][0] if not configValues.localPluginFolder: if configValues.sftp_seperateDownloadPath is True: pluginFile = f"{configValues.sftp_pathToSeperateDownloadPath}/{plugin}" @@ -248,25 +292,29 @@ def updateInstalledPackage(inputSelectedObject='all'): if configValues.sftp_useSftp: pluginAttributes = sftp_validateFileAttributes(connection, pluginFile) if pluginAttributes == False: + i += 1 continue else: pluginAttributes = ftp_validateFileAttributes(connection, pluginFile) if pluginAttributes == False: + i += 1 continue else: + pluginFolderPath = configValues.pathToPluginFolder if not os.path.isfile(Path(f"{pluginFolderPath}/{plugin}")): + i += 1 continue if not re.search(r'.jar$', plugin): + i += 1 continue try: fileName = getFileName(plugin) fileVersion = getFileVersion(plugin) - pluginId = getInstalledPlugin(fileName, fileVersion, plugin) - latestVersion = getLatestPluginVersion(pluginId) - except TypeError: - continue - except ValueError: + pluginId = INSTALLEDPLUGINLIST[i][1] + latestVersion = INSTALLEDPLUGINLIST[i][3] + except (TypeError, ValueError): + i += 1 continue if re.search(r'.jar$', fileName): @@ -274,66 +322,16 @@ def updateInstalledPackage(inputSelectedObject='all'): pluginIdStr = str(pluginId) if pluginId == None or pluginId == '': - print(oColors.brightRed + "Couldn't find plugin id. Sorry :(" + oColors.standardWhite) + i += 1 continue - if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE): - if INSTALLEDPLUGINLIST[i][3] == True: + if inputSelectedObject == 'all' or inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE): + if INSTALLEDPLUGINLIST[i][4] == True: print(f" [{indexNumberUpdated+1}]".rjust(6), end='') print(" ", end='') print(f"{fileName}".ljust(33), end='') print(f"{fileVersion}".ljust(13), end='') print(f"{latestVersion}".ljust(13)) - - if not configValues.localPluginFolder: - if configValues.sftp_seperateDownloadPath is True: - pluginPath = configValues.sftp_pathToSeperateDownloadPath - else: - pluginPath = configValues.sftp_folderPath - pluginPath = Path(f"{pluginPath}/{plugin}") - sftp = createSFTPConnection() - indexNumberUpdated += 1 - pluginsUpdated += 1 - try: - getSpecificPackage(pluginId, configValues.sftp_folderPath) - if configValues.sftp_seperateDownloadPath is False: - sftp.remove(pluginPath) - except HTTPError as err: - print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite) - pluginsUpdated -= 1 - except FileNotFoundError: - print(oColors.brightRed + "Error: Old plugin file coulnd't be deleted" + oColors.standardWhite) - else: - if configValues.seperateDownloadPath is True: - pluginPath = configValues.pathToSeperateDownloadPath - else: - pluginPath = pluginFolderPath - pluginPath = Path(f"{pluginPath}/{plugin}") - indexNumberUpdated += 1 - pluginsUpdated += 1 - try: - getSpecificPackage(pluginId, pluginFolderPath) - if configValues.seperateDownloadPath is False: - os.remove(pluginPath) - except HTTPError as err: - print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite) - pluginsUpdated -= 1 - except FileNotFoundError: - print(oColors.brightRed + f"Error: Old plugin file coulnd't be deleted" + oColors.standardWhite) - break - else: - print(f"{fileName} is already on {latestVersion}") - print(oColors.brightRed + "Aborting the update process."+ oColors.standardWhite) - break - - if inputSelectedObject == 'all': - if INSTALLEDPLUGINLIST[i][3] == True: - print(f" [{indexNumberUpdated+1}]".rjust(6), end='') - print(" ", end='') - print(f"{fileName}".ljust(33), end='') - print(f"{fileVersion}".ljust(13), end='') - print(f"{latestVersion}".ljust(13)) - if not configValues.localPluginFolder: if configValues.sftp_useSftp: if configValues.sftp_seperateDownloadPath is True: @@ -389,12 +387,27 @@ def updateInstalledPackage(inputSelectedObject='all'): pluginsUpdated -= 1 except FileNotFoundError: print(oColors.brightRed + f"FileNotFoundError: Old plugin file coulnd't be deleted" + oColors.standardWhite) + if inputSelectedObject != 'all': + break + elif inputSelectedObject != 'all': + print(oColors.brightGreen + f"{fileName} is already on {latestVersion}" + oColors.standardWhite) + print(oColors.brightRed + "Aborting the update process."+ oColors.standardWhite) + break + else: + i += 1 + continue i += 1 except TypeError: - print(oColors.brightRed + "Error occured: Aborted updating for plugins." + oColors.standardWhite) - print(oColors.brightYellow + f"Plugins updated: [{pluginsUpdated}/{i}]" + oColors.standardWhite) - if inputSelectedObject =='all' and pluginsUpdated == 0: + print(oColors.brightRed + "Error occured: Aborted updating plugins." + oColors.standardWhite) + except NameError: + print(oColors.brightRed + "Check for updates before updating plugins with: 'check all'" + oColors.standardWhite) + print(oColors.brightRed + "Started checking for updates..." + oColors.standardWhite) + checkInstalledPackage() + print(oColors.brightRed + f"Please input 'update {inputSelectedObject}' again!" + oColors.standardWhite) + if i != 0: + print(oColors.brightYellow + f"Plugins updated: [{pluginsUpdated}/{i}]" + oColors.standardWhite) + if inputSelectedObject =='all' and pluginsUpdated == 0 and i != 0: print(oColors.brightGreen + "All found plugins are on the latest version!" + oColors.standardWhite) @@ -425,7 +438,6 @@ def getInstalledPlugin(localFileName, localFileVersion, localPluginFullName): continue pID = ressource["id"] url2 = f"https://api.spiget.org/v2/resources/{pID}/versions?size=100&sort=-name" - try: packageVersions = doAPIRequest(url2) except ValueError: @@ -438,7 +450,7 @@ def getInstalledPlugin(localFileName, localFileVersion, localPluginFullName): updateId = updates["id"] plugin_latest_version = getLatestPluginVersion(pID) plugin_is_outdated = compareVersions(plugin_latest_version, updateVersion) - addToPluginList(pID, updateId, plugin_latest_version , plugin_is_outdated) + addToPluginList(localPluginFullName, pID, updateId, plugin_latest_version , plugin_is_outdated) return pluginID else: @@ -447,6 +459,6 @@ def getInstalledPlugin(localFileName, localFileVersion, localPluginFullName): updateId = None plugin_latest_version = None plugin_is_outdated = None - addToPluginList(pID, updateId, plugin_latest_version , plugin_is_outdated) + addToPluginList(localPluginFullName, pID, updateId, plugin_latest_version , plugin_is_outdated) return pluginID diff --git a/src/serverjar/serverjar_paper.py b/src/serverjar/serverjar_paper.py index 16658e6..a33b3ec 100644 --- a/src/serverjar/serverjar_paper.py +++ b/src/serverjar/serverjar_paper.py @@ -1,5 +1,3 @@ -import os -import sys import re import urllib.request from pathlib import Path @@ -13,7 +11,6 @@ from handlers.handle_config import configurationValues from utils.utilities import createTempPluginFolder, deleteTempPluginFolder, calculateFileSizeMb -# = 1.16.5 def getInstalledPaperMinecraftVersion(localPaperName): if localPaperName is None: return False @@ -25,7 +22,6 @@ def getInstalledPaperMinecraftVersion(localPaperName): return mcVersion -# = 550 def getInstalledPaperVersion(localPaperName): if localPaperName is None: return False @@ -39,7 +35,7 @@ def getInstalledPaperVersion(localPaperName): def findVersionGroup(mcVersion): - versionGroups = ['1.16', '1.15'] + versionGroups = ['1.17', '1.16', '1.15'] if mcVersion is None: return False for versionGroup in versionGroups: @@ -57,7 +53,7 @@ def findVersionGroup(mcVersion): def findBuildVersion(wantedPaperBuild): - versionGroups = ['1.16', '1.15'] + versionGroups = ['1.17', '1.16', '1.15'] if wantedPaperBuild is None: return False for versionGroup in versionGroups: @@ -93,7 +89,7 @@ def findLatestBuildForVersion(mcVersion): def versionBehind(installedPaperBuild, latestPaperBuild): - if installedPaperBuild or latestPaperBuild is None: + if installedPaperBuild is None or latestPaperBuild is None: return False installedPaperBuildint = int(installedPaperBuild) latestPaperBuildint = int(latestPaperBuild) @@ -102,7 +98,7 @@ def versionBehind(installedPaperBuild, latestPaperBuild): def getDownloadFileName(paperMcVersion, paperBuild): - if paperMcVersion or paperBuild is None: + if paperMcVersion is None or paperBuild is None: return False url = f"https://papermc.io/api/v2/projects/paper/versions/{paperMcVersion}/builds/{paperBuild}" buildDetails = doAPIRequest(url) @@ -120,7 +116,6 @@ def paperCheckForUpdate(installedServerjarFullName): return False paperInstalledBuild = getInstalledPaperVersion(installedServerjarFullName) - # Report an error if getInstalledPaperVersion encountered an issue. if not paperInstalledBuild: print(oColors.brightRed + f"ERR: An error was encountered while detecting the server's Paper version." + @@ -128,7 +123,6 @@ def paperCheckForUpdate(installedServerjarFullName): return False versionGroup = findVersionGroup(mcVersion) - # Report an error if findVersionGroup encountered an issue. if not versionGroup: print(oColors.brightRed + f"ERR: An error was encountered while fetching the server's version group." + @@ -136,7 +130,6 @@ def paperCheckForUpdate(installedServerjarFullName): return False paperLatestBuild = findLatestBuild(versionGroup) - # Report an error if findLatestBuild encountered an issue. if not paperLatestBuild: print(oColors.brightRed + f"ERR: An error was encountered while fetching the latest version of PaperMC." + @@ -145,17 +138,16 @@ def paperCheckForUpdate(installedServerjarFullName): # being printed. paperVersionBehind = versionBehind(paperInstalledBuild, paperLatestBuild) - # Report an error if getInstalledPaperVersion encountered an issue. if not paperVersionBehind: print(oColors.brightRed + f"ERR: An error was encountered while detecting how many versions behind you are. " f"Will display as 'N/A'." + oColors.standardWhite) + print(paperVersionBehind) paperVersionBehind = "N/A" # Sets paperVersionBehind to N/A while still letting the versionBehind check return - # # False for error-handing reasons. + # False for error-handing reasons. # Does not return false as versions behind doesn't break things. It is just helpful information. # paperVersionBehind will just display as "N/A" - print("┌─────┬────────────────────────────────┬──────────────┬──────────────┬───────────────────┐") print("│ No. │ Name │ Installed V. │ Latest V. │ Versions behind │") print("└─────┴────────────────────────────────┴──────────────┴──────────────┴───────────────────┘") @@ -181,7 +173,7 @@ def papermc_downloader(paperBuild='latest', installedServerjarName=None, mcVersi if mcVersion == None: if paperBuild == 'latest': - mcVersion = '1.16.5' + mcVersion = '1.17' else: mcVersion = findBuildVersion(paperBuild) @@ -199,11 +191,11 @@ def papermc_downloader(paperBuild='latest', installedServerjarName=None, mcVersi downloadFileName = getDownloadFileName(mcVersion, paperBuild) downloadPackagePath = Path(f"{downloadPath}/{downloadFileName}") - if configValues.localPluginFolder == False: downloadPath = createTempPluginFolder() url = f"https://papermc.io/api/v2/projects/paper/versions/{mcVersion}/builds/{paperBuild}/downloads/{downloadFileName}" + print(url) remotefile = urllib.request.urlopen(url) filesize = remotefile.info()['Content-Length'] print(f"Getting Paper {paperBuild} for {mcVersion}") diff --git a/src/utils/utilities.py b/src/utils/utilities.py index 38f5772..52eb6f6 100644 --- a/src/utils/utilities.py +++ b/src/utils/utilities.py @@ -35,7 +35,7 @@ def getCommandHelp(optionalParams): print(" help command all/command Get specific help to the commands of pluGET") print(oColors.brightBlack + " PLUGIN MANAGEMENT:" + oColors.standardWhite) print(" get Name/ID Version Downloads the latest version of a plugin") - print(" check Name/ID/all Check for an update of an installed plugin") + print(" check Name/ID/all changelog Check for an update of an installed plugin") print(" update Name/ID/all Update installed plugins to the latest version") print(" search Name Search for a plugin and download the latest version") print(" remove Name/ID Delete an installed plugin") @@ -120,7 +120,7 @@ def apiTest(): apiStatusUrl = 'https://api.spiget.org/v2/status' try: r = requests.get(apiStatusUrl) - except requests.exceptions.HTTPError: + except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError): print(oColors.brightRed + "Couldn't make a connection to the API. Check you connection to the internet!" + oColors.standardWhite) input("Press any key + enter to exit...") sys.exit()