Compare commits

...

27 Commits

Author SHA1 Message Date
Neocky
26d7965422 Added installer.bat
Changes:
- added installer.bat file which automaticcally will install the needed python packages to run pluGET
2021-05-26 20:57:25 +02:00
Neocky
78f38f36cd Added installer.bat help
Changes:
- added installer.bat help
- changed formating of windows security message
2021-05-26 20:54:12 +02:00
Neocky
afbc3e8029 Merge pull request #18 from ZandercraftGames/main
Error Handling To Address Paper Check Crashes
2021-05-19 21:08:45 +02:00
Zander
a08aab7ae4 Made paperVersionBehind display "N/A" instead of "False" for more clarity. 2021-05-15 19:05:29 -04:00
Zander
b31cca5e31 Fix findLatestBuild check returning false on a successful API response. 2021-05-15 19:02:09 -04:00
Neocky
cd4a66002c Added new discord picture 2021-05-15 01:30:22 +02:00
Neocky
0d709cfb6f Fixed typo 2021-05-15 00:47:06 +02:00
Neocky
edc300a33d Eggcracking for better name finding & added better version digging
Added:
- eggcracking to get plugin name
- better version find mechanism
2021-05-15 00:46:29 +02:00
Zander
11b4fdcbeb Add error handling to "check serverjar" command on paper servers. Fixes use assignment issues when detection doesn't work. 2021-05-09 01:33:05 -04:00
Zander
716227eafa Add PyCharm configurations to .gitignore 2021-05-09 00:23:11 -04:00
Neocky
6e980a1580 Fixed typo & added part about security warning 2021-04-12 23:26:12 +02:00
Neocky
cb0282e676 Fixed array index out of range
Changes:
- fixed array index out of range error when checking/updating
2021-04-07 20:38:29 +02:00
Neocky
1dad1c62cd Removed typos 2021-04-03 20:36:33 +02:00
Neocky
91a5e84028 Added FTP to feature list 2021-04-03 20:33:58 +02:00
Neocky
60a41015e6 Merge pull request #16 from Neocky/dev/ftp
For Version 1.5.0
2021-03-31 18:19:39 +02:00
Neocky
706b8049c3 Added custom header to download & better ftp error messages
Changes:
- added custom header to plugin download
- added better sftp/ftp error messages
- removed unnecessary sftp/ftp functions
2021-03-31 18:11:41 +02:00
Neocky
927767b0aa Added FTP support
Changes:
- added ftp support
- added ftp to every function which had already sftp interaction
- edited config
- added handle_ftp.py
fixed old configcheck() bugs
- added sftp/ftp to eggcrackingjar mechanism
- added new line input with enter
2021-03-30 23:55:04 +02:00
Neocky
2a7372dae1 Added new start pluGET topic
Changes:
- added docs to launch pluGET on linux
2021-03-28 17:41:55 +02:00
Neocky
31a2a4aa89 Added full linux support & better output when searching
Changes:
- added launcher.sh file to launch pluGET on linux
- beautified output when searching for a ressource
- deleted .vscode folder & added it to the .gitignore list
2021-03-28 16:15:03 +02:00
Neocky
aceca0dec3 Merge pull request #14 from Neocky/dev/v1.3.2
Dev/v1.3.2
2021-03-27 19:02:21 +01:00
Neocky
205a13ee94 Optimized config handling & beautified output
Changes:
- optimized config handling
- added spinner to paper download
- changed progress bar colors
- better output for updating paper version
- misc code cleanup
2021-03-27 18:58:16 +01:00
Neocky
fddc0c252c Better config handling & better output for serverjar
Changes:
- better config handling
- better output for serverjar checking
2021-03-27 12:07:19 +01:00
Neocky
17611c741e Better output & first part of new config handling
Changes:
- better output when downloading files
- optimization when getting values from the config
2021-03-26 20:24:15 +01:00
Neocky
e8e46bb014 Changed command & misc 2021-03-24 23:06:27 +01:00
Neocky
5086b36aa3 Added gif 2021-03-23 18:45:14 +01:00
Neocky
2a481acbef Fixed formating issues
Changes:
- fixed some formating issues
2021-03-23 18:32:20 +01:00
Neocky
5b68181661 Added screenshots 2021-03-21 18:58:02 +01:00
16 changed files with 667 additions and 310 deletions

6
.gitignore vendored
View File

@@ -127,3 +127,9 @@ dmypy.json
# Pyre type checker
.pyre/
# VSCode Settings
.vscode
# PyCharm Settings
.idea

View File

@@ -1,4 +0,0 @@
{
"python.linting.pylintEnabled": true,
"python.linting.enabled": true
}

View File

@@ -19,12 +19,27 @@
# pluGET
#### A powerfull package manager which handles [Plugins](https://www.spigotmc.org/resources/) and Server Software for minecraft servers.
#### A powerful package manager which updates [Plugins](https://www.spigotmc.org/resources/) and Server Software for minecraft servers.
<img src="https://www.bildhost.com/images/2021/03/23/pluGET.gif" alt="pluGET.gif" border="0" />
<details>
<summary>Screenshots</summary>
`check all` to check installed plugins for updates:
![screenshot1](https://i.ibb.co/QM7xh7w/pluget-checkall-small.png)
`check all` with more plugins:
![screenshot2](https://i.ibb.co/VmSNh6K/pluget-checkall.png)
`help command` list all available commands:
![screenshot3](https://i.ibb.co/9VZCjD6/pluget-help2.png)
</details>
<img src="https://i.ibb.co/82dnyrK/image.png" alt="meme" border="0" height="350" width="350"></a>
## Issues? Found a bug?
[Create an issue.](https://github.com/Neocky/pluGET/issues/new/choose)
@@ -32,11 +47,11 @@
## About
This is a package manager for minecraft [Spigot](https://www.spigotmc.org/) servers and its forks (e.g. [PaperMC](https://papermc.io/)).
This is a standalone program written in python.
The program works with a locally installed server or with a remote host through SFTP, when configured in the config.
The program works with a locally installed server or with a remote host through SFTP/FTP, when configured in the config.
It uses the [Spiget](https://spiget.org/) API to download and compare plugin versions and can download the latest version of plugins from the [Spigot](https://www.spigotmc.org/) site.
It can also compare and download the latest update of specifif server software (e.g. [PaperMC](https://papermc.io/)).
It can also compare and download the latest update of specific server software (e.g. [PaperMC](https://papermc.io/)).
Plugin management was the hard part of mangaging a minecraft server. The time it took to check the [Spigot ressource](https://www.spigotmc.org/resources/) page for updates for the installed plugins and updating all plugins manually which have available updates was too long and shocking.
Plugin management was the hard part of managing a minecraft server. The time it took to check the [Spigot ressource](https://www.spigotmc.org/resources/) page for updates for the installed plugins and updating all plugins manually which have available updates was too long and daunting.
So I built pluGET to automate and ease the plugin handling of a minecraft server and to turn the most time consuming part of managing a minecraft server to an easy one.
This program is suited for minecraft server owners who want to save time and stay on top of their plugin versions.
@@ -48,15 +63,15 @@ If you still have questions [here](https://github.com/Neocky/pluGET#need-help) i
So what can it do exactly?
pluGET can:
- work locally or through sftp
- work locally or through SFTP/FTP
- manage plugins:
- download the latest version of a plugin
- update every installed/one specific plugin
- check for an update of every installed/one specific plugin
- remove a plugin from the plugin folder
- manager server software:
- manage server software:
- download a specific server software version
- check instlalled server software for update
- check installed server software for update
- update installed server software to a specific version
- supported server software: [PaperMc](https://papermc.io/)
@@ -73,32 +88,56 @@ If you feel like showing your love and/or appreciation for this project then how
## Need help?
[<img src="https://i.imgur.com/D5vyVzC.png" alt="Discord" width="272"/>](https://discord.gg/475Uf4NBPF)
[<img src="https://i.ibb.co/CMKbT0L/rsz-1rsz-discord.png" alt="Discord" width="272"/>](https://discord.gg/475Uf4NBPF)
## Installation
### Python
### 1. Python
Python needs to be installed on your machine.
Get it [here](https://www.python.org/downloads/).
### Dependencies
### 2. Dependencies
Install the needed packages for this project.
Execute this command in the ```\plugGET``` folder:
#### Automatically (Windows only)
Execute the `installer.bat` file to automaticcally install the needed packages for this project.
> Sometimes the security warning `Windows protected your PC` comes when launching the `installer.bat` file.
> This is a normal behaviour from the windows defender because this is a unknown `.bat` file.
> To run the `installer.bat` anyway, click `More Info` and then `Run anyway` when the message pops up.
##### Manually
Execute this command in the `\plugGET` folder:
```python
pip install -r requirements.txt
py -m pip install -r requirements.txt
```
### Edit the Config
When run the first time, the `config.ini` file will be created in the root package folder and the program will close.
### 3. Edit the Config
When run the first time, the `config.ini` file will be created in the `\src` folder and the program will close.
Edit the config to your needs and relaunch pluGET.
**Now you are good to go!**
## Start pluGET
### Windows:
Execute the `launcher.bat` in the `\pluGET` folder.
This will launch pluGET correctly.
> Sometimes the security warning `Windows protected your PC` comes when launching the `launcher.bat` file.
> This is a normal behaviour from the windows defender because this is a unknown `.bat` file.
> To run the `launcher.bat` anyway, click `More Info` and then `Run anyway` when the message pops up.
### Linux:
Use `cd` to change into the `/pluGET` directory and change the permission of the `launcher.sh` to make it executeable:
```
$ chmod +x launcher.sh
```
Execute the `launcher.sh` file:
```
$ ./launcher.sh
```
> On both OS you can also launch the `src/__main__.py` file.
## Usage
> As always, if you update plugins, shut down your server!
Execute the `launcher.bat` in the `\pluGET` folder. This will launch pluGET correctly.
Another way is to launch the `src\__main__.py` file.
The following are examples of input for the general usage:
(Hint: [thingsInBrackets] are optional & 'all' can always be exchanged through the plugin name or the plugin id and reverse)

34
installer.bat Normal file
View File

@@ -0,0 +1,34 @@
@ECHO OFF
cd /d %~dp0
Echo ___ ___ ___ ___ ___ ___
Echo /\ \ /\__\ /\__\ /\ \ /\ \ /\ \
Echo /::\ \ /:/ / /:/ / /::\ \ /::\ \ \:\ \
Echo /:/\:\ \ /:/ / /:/ / /:/\:\ \ /:/\:\ \ \:\ \
Echo /::\~\:\ \ /:/ / /:/ / ___ /:/ \:\ \ /::\~\:\ \ /::\ \
Echo /:/\:\ \:\__\ /:/__/ /:/__/ /\__\ /:/__/_\:\__\ /:/\:\ \:\__\ /:/\:\__\
Echo \/__\:\/:/ / \:\ \ \:\ \ /:/ / \:\ /\ \/__/ \:\~\:\ \/__/ /:/ \/__/
Echo \::/ / \:\ \ \:\ /:/ / \:\ \:\__\ \:\ \:\__\ /:/ /
Echo \/__/ \:\ \ \:\/:/ / \:\/:/ / \:\ \/__/ \/__/
Echo \:\__\ \::/ / \::/ / \:\__\
Echo \/__/ \/__/ \/__/ \/__/
Echo `
Echo `
Echo ------------------------------------
Echo [By Neocky]
Echo https://github.com/Neocky/pluGET
Echo pluGET-Installer
Echo ------------------------------------
Echo `
Echo ----------------------------------------------------------------------------------
Echo Installing Python packages and dependencies...
py -m pip install -r requirements.txt
Echo `
Echo Launching pluGET...
launcher.bat
exit

2
launcher.sh Normal file
View File

@@ -0,0 +1,2 @@
cd src/
python3 "__main__.py"

View File

@@ -6,73 +6,81 @@ from pathlib import Path
from utils.consoleoutput import oColors
class configurationValues:
def __init__(self):
config = configparser.ConfigParser()
config.sections()
config.read("config.ini")
localPluginFolder = config['General']['UseLocalPluginFolder']
self.pathToPluginFolder = Path(config['Local - This Machine']['PathToPluginFolder'])
seperateDownloadPath = config['Local - This Machine']['SeperateDownloadPath']
self.pathToSeperateDownloadPath = Path(config['Local - This Machine']['PathToSeperateDownloadPath'])
self.sftp_server = config['SFTP - Remote Server']['Server']
self.sftp_user = config['SFTP - Remote Server']['Username']
self.sftp_password = config['SFTP - Remote Server']['Password']
sftp_port = config['SFTP - Remote Server']['SFTPPort']
self.sftp_folderPath = config['SFTP - Remote Server']['PluginFolderOnServer']
sftp_useSftp = config['SFTP - Remote Server']['USE_SFTP']
sftp_seperateDownloadPath = config['SFTP - Remote Server']['SeperateDownloadPath']
self.sftp_pathToSeperateDownloadPath = config['SFTP - Remote Server']['PathToSeperateDownloadPath']
self.sftp_port = int(sftp_port)
if localPluginFolder == 'True':
self.localPluginFolder = True
else:
self.localPluginFolder = False
if seperateDownloadPath == 'True':
self.seperateDownloadPath = True
else:
self.seperateDownloadPath = False
if sftp_seperateDownloadPath == 'True':
self.sftp_seperateDownloadPath = True
else:
self.sftp_seperateDownloadPath = False
if sftp_useSftp == 'True':
self.sftp_useSftp = True
else:
self.sftp_useSftp = False
def checkConfig():
currentFolder = os.getcwd()
configAvailable = os.path.isfile("config.ini")
if not configAvailable:
createConfig()
print(oColors.brightRed + "Config created. Edit config before executing again!" + oColors.standardWhite)
input("Press any key + enter to exit...")
sys.exit()
class configValues:
config = configparser.ConfigParser()
config.sections()
config.read("config.ini")
localPluginFolder = config['General']['LocalPluginFolder']
pathToPluginFolder = Path(config['General']['PathToPluginFolder'])
seperateDownloadPath = config['General']['SeperateDownloadPath']
pathToSeperateDownloadPath = Path(config['General']['PathToSeperateDownloadPath'])
sftp_server = config['SFTP - Remote Server']['Server']
sftp_user = config['SFTP - Remote Server']['Username']
sftp_password = config['SFTP - Remote Server']['Password']
sftp_port = config['SFTP - Remote Server']['Port']
sftp_folderPath = config['SFTP - Remote Server']['PluginFolderOnServer']
sftp_seperateDownloadPath = config['SFTP - Remote Server']['SeperateDownloadPath']
sftp_pathToSeperateDownloadPath = config['SFTP - Remote Server']['PathToSeperateDownloadPath']
sftp_port = int(sftp_port)
if localPluginFolder == 'True':
localPluginFolder = True
else:
localPluginFolder = False
if seperateDownloadPath == 'True':
seperateDownloadPath = True
else:
seperateDownloadPath = False
if sftp_seperateDownloadPath == 'True':
sftp_seperateDownloadPath = True
else:
sftp_seperateDownloadPath = False
os.chdir(currentFolder)
return configValues
def createConfig():
config = configparser.ConfigParser(allow_no_value=True)
config['General'] = {}
config['General'][';'] = 'If a local plugin folder exists (True/False): (If False SFTP will be used)'
config['General']['LocalPluginFolder'] = 'True'
config['General']['PathToPluginFolder'] = 'C:/Users/USER/Desktop/plugins'
config['General'][';_'] = 'If you want a different folder to store the updated plugins change to (True/False) and the path below'
config['General']['SeperateDownloadPath'] = 'False'
config['General']['PathToSeperateDownloadPath'] = 'C:/Users/USER/Desktop/plugins'
config['General'][';'] = 'If a local plugin folder exists (True/False) (If False SFTP/FTP will be used):'
config['General']['UseLocalPluginFolder'] = 'True'
config['Local - This Machine'] = {}
config['Local - This Machine']['PathToPluginFolder'] = 'C:/Users/USER/Desktop/plugins'
config['Local - This Machine'][';'] = 'For a different folder to store the updated plugins change to (True/False) and the path below'
config['Local - This Machine']['SeperateDownloadPath'] = 'False'
config['Local - This Machine']['PathToSeperateDownloadPath'] = 'C:/Users/USER/Desktop/plugins'
config['SFTP - Remote Server'] = {}
config['SFTP - Remote Server']['Server'] = '0.0.0.0'
config['SFTP - Remote Server']['Username'] = 'user'
config['SFTP - Remote Server']['Password'] = 'password'
config['SFTP - Remote Server'][';'] = 'Normally you won*t need to change anything below this line'
config['SFTP - Remote Server']['Port'] = '22'
config['SFTP - Remote Server']['PluginFolderOnServer'] = '.\\plugins'
config['SFTP - Remote Server'][';_'] = 'If you want a different folder to store the updated plugins change to (True/False) and the path below'
config['SFTP - Remote Server'][';'] = 'If a different Port for SFTP needs to be used (Works only for SFTP)'
config['SFTP - Remote Server']['SFTPPort'] = '22'
config['SFTP - Remote Server'][';_'] = 'Change the path below if the plugin folder path is different on the SFTP/FTP server (Change only if you know what you are doing)'
config['SFTP - Remote Server']['PluginFolderOnServer'] = './plugins'
config['SFTP - Remote Server'][';__'] = 'If you want to use FTP instead of SFTP change to (False) else use (True)'
config['SFTP - Remote Server']['USE_SFTP'] = 'True'
config['SFTP - Remote Server'][';___'] = 'For a different folder to store the updated plugins (Only with the update command!) change to (True/False) and the path below'
config['SFTP - Remote Server']['SeperateDownloadPath'] = 'False'
config['SFTP - Remote Server']['PathToSeperateDownloadPath'] = '.\\plugins'
config['SFTP - Remote Server']['PathToSeperateDownloadPath'] = './plugins'
with open('config.ini', 'w') as configfile:

View File

@@ -0,0 +1,95 @@
import os
import sys
import ftplib
from utils.consoleoutput import oColors
from handlers.handle_config import configurationValues
def createFTPConnection():
configValues = configurationValues()
ftp = ftplib.FTP(configValues.sftp_server, user=configValues.sftp_user, \
passwd=configValues.sftp_password)
try:
return ftp
except UnboundLocalError:
print(oColors.brightRed + "[FTP]: Check your config.ini!" + oColors.standardWhite)
print(oColors.brightRed + "Exiting program..." + oColors.standardWhite)
sys.exit()
def ftp_showPlugins(ftp):
configValues = configurationValues()
ftp.cwd(configValues.sftp_folderPath)
for attr in ftp.dir():
print(attr.filename, attr)
def ftp_upload_file(ftp, itemPath):
configValues = configurationValues()
try:
ftp.cwd(configValues.sftp_folderPath)
itemPath = os.path.relpath(itemPath, 'TempSFTPFolder/')
itemPath = str(itemPath)
currentDirectory = os.getcwd()
os.chdir('TempSFTPFolder')
with open (itemPath, 'rb') as plugin_file:
ftp.storbinary('STOR '+ str(itemPath), plugin_file)
except FileNotFoundError:
print(oColors.brightRed + "[FTP]: The 'plugins' folder couldn*t be found on the remote host!" + oColors.standardWhite)
print(oColors.brightRed + "[FTP]: Aborting uploading." + oColors.standardWhite)
os.chdir(currentDirectory)
ftp.close()
def ftp_upload_server_jar(ftp, itemPath):
try:
print(f"itempath: {itemPath}")
ftp.cwd('.')
itemPath = os.path.relpath(itemPath, 'TempSFTPFolder/')
itemPath = str(itemPath)
currentDirectory = os.getcwd()
os.chdir('TempSFTPFolder')
with open (itemPath, 'rb') as server_jar:
ftp.storbinary('STOR '+ str(itemPath), server_jar)
except FileNotFoundError:
print(oColors.brightRed + "[FTP]: The 'root' folder couldn*t be found on the remote host!" + oColors.standardWhite)
print(oColors.brightRed + "[FTP]: Aborting uploading." + oColors.standardWhite)
os.chdir(currentDirectory)
ftp.close()
def ftp_listAll(ftp):
configValues = configurationValues()
try:
ftp.cwd(configValues.sftp_folderPath)
installedPlugins = ftp.nlst()
except FileNotFoundError:
print(oColors.brightRed + "[FTP]: The 'plugins' folder couldn*t be found on the remote host!" + oColors.standardWhite)
try:
return installedPlugins
except UnboundLocalError:
print(oColors.brightRed + "[FTP]: No plugins were found." + oColors.standardWhite)
def ftp_listFilesInServerRoot(ftp):
try:
ftp.cwd('.')
filesInServerRoot = ftp.nlst()
except FileNotFoundError:
print(oColors.brightRed + "[FTP]: The 'root' folder couldn*t be found on the remote host!" + oColors.standardWhite)
try:
return filesInServerRoot
except UnboundLocalError:
print(oColors.brightRed + "[FTP]: No Serverjar was found." + oColors.standardWhite)
def ftp_downloadFile(ftp, downloadPath, fileToDownload):
configValues = configurationValues()
ftp.cwd(configValues.sftp_folderPath)
filedata = open(downloadPath,'wb')
ftp.retrbinary('RETR '+fileToDownload, filedata.write)
filedata.close()
ftp.quit()

View File

@@ -2,7 +2,7 @@ import sys
from utils.consoleoutput import oColors
from utils.utilities import getHelp, getCommandHelp
from handlers.handle_config import checkConfig
from handlers.handle_config import configurationValues
from plugin.plugin_downloader import searchPackage, getSpecificPackage
from plugin.plugin_updatechecker import updateInstalledPackage, checkInstalledPackage
from plugin.plugin_remover import removePlugin
@@ -30,21 +30,22 @@ def createInputLists():
def handleInput(inputCommand, inputSelectedObject, inputParams):
configValues = configurationValues()
while True:
if inputCommand == 'get':
if inputSelectedObject.isdigit():
if not checkConfig().localPluginFolder:
if checkConfig().sftp_seperateDownloadPath is True:
pluginPath = checkConfig().sftp_pathToSeperateDownloadPath
if not configValues.localPluginFolder:
if configValues.sftp_seperateDownloadPath is True:
pluginPath = configValues.sftp_pathToSeperateDownloadPath
else:
pluginPath = checkConfig().sftp_folderPath
pluginPath = configValues.sftp_folderPath
getSpecificPackage(inputSelectedObject, pluginPath, inputParams)
break
else:
if checkConfig().seperateDownloadPath is True:
pluginPath = checkConfig().pathToSeperateDownloadPath
if configValues.seperateDownloadPath is True:
pluginPath = configValues.pathToSeperateDownloadPath
else:
pluginPath = checkConfig().pathToPluginFolder
pluginPath = configValues.pathToPluginFolder
getSpecificPackage(inputSelectedObject, pluginPath, inputParams)
break
else:
@@ -81,18 +82,24 @@ def handleInput(inputCommand, inputSelectedObject, inputParams):
break
else:
print(oColors.brightRed + "Error: Command not found. Please try again. :(" + oColors.standardWhite)
print(oColors.brightRed + "Use: '" + oColors.standardWhite +"help command" + oColors.brightRed +"' to get all available commands" + oColors.standardWhite)
getInput()
getInput()
def getInput():
inputCommand = None
while True:
try:
inputCommand, inputSelectedObject, *inputParams = input("pluGET >> ").split()
break
except ValueError:
print(oColors.brightRed + "Wrong input! Use: > 'command' 'selectedObject' [optionalParams]" + oColors.standardWhite)
print(oColors.brightRed + "Use: '" + oColors.standardWhite +"help command" + oColors.brightRed +"' to get all available commands" + oColors.standardWhite)
if inputCommand == None:
continue
else:
print(oColors.brightRed + "Wrong input! Use: > 'command' 'selectedObject' [optionalParams]" + oColors.standardWhite)
print(oColors.brightRed + "Use: '" + oColors.standardWhite +"help command" + oColors.brightRed +"' to get all available commands" + oColors.standardWhite)
except KeyboardInterrupt:
sys.exit()
inputParams = inputParams[0] if inputParams else None
handleInput(inputCommand, inputSelectedObject, inputParams)

View File

@@ -1,17 +1,19 @@
import sys
import os
import pysftp
import paramiko
from utils.consoleoutput import oColors
from handlers.handle_config import checkConfig
from handlers.handle_config import configurationValues
def createSFTPConnection():
configValues = configurationValues()
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None # TODO fix this
try:
sftp = pysftp.Connection(checkConfig().sftp_server, username=checkConfig().sftp_user, \
password=checkConfig().sftp_password, port=checkConfig().sftp_port, cnopts=cnopts)
sftp = pysftp.Connection(configValues.sftp_server, username=configValues.sftp_user, \
password=configValues.sftp_password, port=configValues.sftp_port, cnopts=cnopts)
except paramiko.ssh_exception.AuthenticationException:
print(oColors.brightRed + "[SFTP]: Wrong Username/Password" + oColors.standardWhite)
except paramiko.ssh_exception.SSHException:
@@ -30,18 +32,14 @@ def sftp_showPlugins(sftp):
print(attr.filename, attr)
def sftp_cdPluginDir(sftp):
sftp.cd('plugins')
def sftp_upload_file(sftp, itemPath):
try:
sftp.chdir('plugins')
sftp.put(itemPath)
except FileNotFoundError:
print(oColors.brightRed + "The 'plugins' folder couldn*t be found on the remote host!" + oColors.standardWhite)
print(oColors.brightRed + "Aborting installation." + oColors.standardWhite)
print(oColors.brightRed + "[SFTP]: The 'plugins' folder couldn*t be found on the remote host!" + oColors.standardWhite)
print(oColors.brightRed + "[SFTP]: Aborting uploading." + oColors.standardWhite)
sftp.close()
@@ -49,10 +47,9 @@ def sftp_upload_server_jar(sftp, itemPath):
try:
sftp.chdir('.')
sftp.put(itemPath)
except FileNotFoundError:
print(oColors.brightRed + "The 'plugins' folder couldn*t be found on the remote host!" + oColors.standardWhite)
print(oColors.brightRed + "Aborting installation." + oColors.standardWhite)
print(oColors.brightRed + "[SFTP]: The 'root' folder couldn*t be found on the remote host!" + oColors.standardWhite)
print(oColors.brightRed + "[SFTP]: Aborting uploading." + oColors.standardWhite)
sftp.close()
@@ -60,25 +57,33 @@ def sftp_listAll(sftp):
try:
sftp.chdir('plugins')
installedPlugins = sftp.listdir()
except FileNotFoundError:
print(oColors.brightRed + "The 'plugins' folder couldn*t be found on the remote host!" + oColors.standardWhite)
print(oColors.brightRed + "[SFTP]: The 'plugins' folder couldn*t be found on the remote host!" + oColors.standardWhite)
try:
return installedPlugins
except UnboundLocalError:
print(oColors.brightRed + "No plugins were found." + oColors.standardWhite)
print(oColors.brightRed + "[SFTP]: No plugins were found." + oColors.standardWhite)
def sftp_listFilesInServerRoot(sftp):
try:
#sftp.chdir('plugins')
filesInServerRoot = sftp.listdir()
except FileNotFoundError:
print(oColors.brightRed + "The 'root' folder couldn*t be found on the remote host!" + oColors.standardWhite)
print(oColors.brightRed + "[SFTP]: The 'root' folder couldn*t be found on the remote host!" + oColors.standardWhite)
try:
return filesInServerRoot
except UnboundLocalError:
print(oColors.brightRed + "No Serverjar was found." + oColors.standardWhite)
print(oColors.brightRed + "[SFTP]: No Serverjar was found." + oColors.standardWhite)
def sftp_downloadFile(sftp, downloadPath, fileToDownload):
configValues = configurationValues()
sftp.cwd(configValues.sftp_folderPath)
currentDirectory = os.getcwd()
os.chdir('TempSFTPFolder')
sftp.get(fileToDownload)
sftp.close()
os.chdir(currentDirectory)

View File

@@ -5,16 +5,10 @@ from pathlib import Path
from utils.consoleoutput import oColors
from utils.web_request import doAPIRequest
from utils.utilities import createTempPluginFolder, deleteTempPluginFolder
from handlers.handle_config import checkConfig
from handlers.handle_sftp import sftp_upload_file, sftp_cdPluginDir, createSFTPConnection
def calculateFileSize(downloadFileSize):
fileSizeDownload = int(downloadFileSize)
fileSizeKb = fileSizeDownload / 1024
roundedFileSize = round(fileSizeKb, 2)
return roundedFileSize
from utils.utilities import createTempPluginFolder, deleteTempPluginFolder, calculateFileSizeKb, calculateFileSizeMb
from handlers.handle_config import configurationValues
from handlers.handle_sftp import sftp_upload_file, createSFTPConnection
from handlers.handle_ftp import ftp_upload_file, createFTPConnection
def handleRegexPackageName(packageNameFull):
@@ -58,39 +52,45 @@ def getVersionName(packageId, versionId):
def searchPackage(ressourceName):
configValues = configurationValues()
url = f"https://api.spiget.org/v2/search/resources/{ressourceName}?field=name&sort=-downloads"
packageName = doAPIRequest(url)
i = 1
print(oColors.brightBlack + f"Searching: {ressourceName}" + oColors.standardWhite)
print("Index | Name | Description | Downloads")
print("┌─────┬─────────────────────────────┬───────────┬──────────────────────────────────────────────────────────────────────┐")
print("│ No. │ Name │ Downloads │ Description │")
print("└─────┴─────────────────────────────┴───────────┴──────────────────────────────────────────────────────────────────────┘")
for ressource in packageName:
pName = ressource["name"]
newName = handleRegexPackageName(pName)
pTag = ressource["tag"]
pDownloads = ressource["downloads"]
print(f" [{i}]".ljust(8), end='')
print(f" [{i}]".rjust(6), end='')
print(" ", end='')
print(f"{newName}".ljust(30), end='')
print(f"{pTag}".ljust(120), end='')
print(f"{pDownloads}".ljust(7))
print(f"{pDownloads}".rjust(9), end='')
print(" ", end='')
print(f"{pTag}".ljust(120))
i = i + 1
ressourceSelected = int(input("Select your wanted Ressource (Index)(0 to exit): "))
ressourceSelected = int(input("Select your wanted Ressource (No.)(0 to exit): "))
if ressourceSelected != 0:
ressourceSelected = ressourceSelected - 1
ressourceId = packageName[ressourceSelected]["id"]
if not checkConfig().localPluginFolder:
if not configValues.localPluginFolder:
try:
getSpecificPackage(ressourceId, checkConfig().sftp_folderPath)
getSpecificPackage(ressourceId, configValues.sftp_folderPath)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
else:
try:
getSpecificPackage(ressourceId, checkConfig().pathToPluginFolder)
getSpecificPackage(ressourceId, configValues.pathToPluginFolder)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
def downloadSpecificVersion(ressourceId, downloadPath, versionID='latest'):
configValues = configurationValues()
if versionID != 'latest':
#url = f"https://spigotmc.org/resources/{ressourceId}/download?version={versionID}"
print(oColors.brightRed + "Sorry but specific version downloads aren't supported because of cloudflare protection. :(" + oColors.standardWhite)
@@ -99,19 +99,33 @@ def downloadSpecificVersion(ressourceId, downloadPath, versionID='latest'):
url = f"https://api.spiget.org/v2/resources/{ressourceId}/download"
#url = f"https://api.spiget.org/v2/resources/{ressourceId}/versions/latest/download" #throws 403 forbidden error...cloudflare :(
urrlib_opener = urllib.request.build_opener()
urrlib_opener.addheaders = [('User-agent', 'pluGET/1.0')]
urllib.request.install_opener(urrlib_opener)
remotefile = urllib.request.urlopen(url)
filesize = remotefile.info()['Content-Length']
urllib.request.urlretrieve(url, downloadPath)
filesizeData = calculateFileSize(filesize)
print(f"Downloadsize: {filesizeData} KB")
print(f"File downloaded here: {downloadPath}")
if not checkConfig().localPluginFolder:
sftpSession = createSFTPConnection()
sftp_upload_file(sftpSession, downloadPath)
filesize = int(filesize)
print(" ", end='')
if filesize >= 1000000:
filesizeData = calculateFileSizeMb(filesize)
print("Downloaded " + (str(filesizeData)).rjust(9) + f" MB here {downloadPath}")
else:
filesizeData = calculateFileSizeKb(filesize)
print("Downloaded " + (str(filesizeData)).rjust(9) + f" KB here {downloadPath}")
if not configValues.localPluginFolder:
if configValues.sftp_useSftp:
sftpSession = createSFTPConnection()
sftp_upload_file(sftpSession, downloadPath)
else:
ftpSession = createFTPConnection()
ftp_upload_file(ftpSession, downloadPath)
def getSpecificPackage(ressourceId, downloadPath, inputPackageVersion='latest'):
if checkConfig().localPluginFolder == False:
configValues = configurationValues()
if configValues.localPluginFolder == False:
downloadPath = createTempPluginFolder()
url = f"https://api.spiget.org/v2/resources/{ressourceId}"
packageDetails = doAPIRequest(url)
@@ -120,17 +134,14 @@ def getSpecificPackage(ressourceId, downloadPath, inputPackageVersion='latest'):
versionId = getVersionID(ressourceId, inputPackageVersion)
packageVersion = getVersionName(ressourceId, versionId)
packageDownloadName = f"{packageNameNew}-{packageVersion}.jar"
#if not configValues.localPluginFolder:
#downloadPackagePath = f"{downloadPath}/{packageDownloadName}"
#else:
downloadPackagePath = Path(f"{downloadPath}/{packageDownloadName}")
if checkConfig().localPluginFolder:
if inputPackageVersion is None or inputPackageVersion == 'latest':
downloadSpecificVersion(ressourceId=ressourceId, downloadPath=downloadPackagePath)
else:
downloadSpecificVersion(ressourceId, downloadPackagePath, versionId)
if inputPackageVersion is None or inputPackageVersion == 'latest':
downloadSpecificVersion(ressourceId=ressourceId, downloadPath=downloadPackagePath)
else:
downloadSpecificVersion(ressourceId, downloadPackagePath, versionId)
if not checkConfig().localPluginFolder:
if inputPackageVersion is None or inputPackageVersion == 'latest':
downloadSpecificVersion(ressourceId=ressourceId, downloadPath=downloadPackagePath)
deleteTempPluginFolder(downloadPath)
else:
downloadSpecificVersion(ressourceId, downloadPackagePath, versionId)
deleteTempPluginFolder(downloadPath)
if not configValues.localPluginFolder:
deleteTempPluginFolder(downloadPath)

View File

@@ -3,18 +3,24 @@ import re
from pathlib import Path
from utils.consoleoutput import oColors
from handlers.handle_config import checkConfig
from handlers.handle_config import configurationValues
from handlers.handle_sftp import createSFTPConnection, sftp_listAll
from handlers.handle_ftp import createFTPConnection, ftp_listAll
from plugin.plugin_updatechecker import getFileName, getFileVersion, getInstalledPlugin, createPluginList
def removePlugin(pluginToRemove):
configValues = configurationValues()
createPluginList()
if not checkConfig().localPluginFolder:
sftp = createSFTPConnection()
pluginList = sftp_listAll(sftp)
if not configValues.localPluginFolder:
if not configValues.sftp_useSftp:
ftp = createFTPConnection()
pluginList = ftp_listAll(ftp)
else:
sftp = createSFTPConnection()
pluginList = sftp_listAll(sftp)
else:
pluginList = os.listdir(checkConfig().pathToPluginFolder)
pluginList = os.listdir(configValues.pathToPluginFolder)
i = 0
try:
for plugin in pluginList:
@@ -28,16 +34,20 @@ def removePlugin(pluginToRemove):
if pluginToRemove == pluginIdStr or re.search(pluginToRemove, fileName, re.IGNORECASE):
print(f"Removing: {fileName}")
if not checkConfig().localPluginFolder:
pluginPath = checkConfig().sftp_folderPath
if not configValues.localPluginFolder:
pluginPath = configValues.sftp_folderPath
pluginPath = f"{pluginPath}/{plugin}"
sftp = createSFTPConnection()
sftp.remove(pluginPath)
if not configValues.sftp_useSftp:
ftp = createFTPConnection()
ftp.delete(pluginPath)
else:
sftp = createSFTPConnection()
sftp.remove(pluginPath)
print(f"Removed: {fileName}")
i += 1
break
else:
pluginPath = checkConfig().pathToPluginFolder
pluginPath = configValues.pathToPluginFolder
pluginPath = Path(f"{pluginPath}/{plugin}")
os.remove(pluginPath)
print(f"Removed: {fileName}")

View File

@@ -8,9 +8,11 @@ from rich.progress import track
from utils.consoleoutput import oColors
from utils.web_request import doAPIRequest
from handlers.handle_config import checkConfig
from handlers.handle_sftp import createSFTPConnection, sftp_listAll
from handlers.handle_config import configurationValues
from handlers.handle_sftp import createSFTPConnection, sftp_listAll, sftp_downloadFile
from handlers.handle_ftp import createFTPConnection, ftp_listAll, ftp_downloadFile
from plugin.plugin_downloader import getSpecificPackage
from utils.utilities import createTempPluginFolder, deleteTempPluginFolder
def createPluginList():
@@ -44,7 +46,7 @@ def getFileVersion(pluginName):
if pluginVersionString.endswith('.'):
pluginVersionString = ''
if pluginVersionString == '':
pluginVersionString = eggCrackingJar(pluginNameFull)
pluginVersionString = eggCrackingJar(pluginNameFull, 'version')
return pluginVersionString
@@ -63,49 +65,78 @@ def compareVersions(plugin_latest_version, pluginVersion):
return plugin_is_outdated
def eggCrackingJar(localJarFileName):
if not checkConfig().localPluginFolder:
pluginPath = checkConfig().sftp_folderPath
def eggCrackingJar(localJarFileName, searchMode):
configValues = configurationValues()
if not configValues.localPluginFolder:
if configValues.sftp_useSftp:
tempPluginFolderPath = createTempPluginFolder()
sftp = createSFTPConnection()
pathToPluginJar = Path(f"{tempPluginFolderPath}/{localJarFileName}")
sftp_downloadFile(sftp, pathToPluginJar, localJarFileName)
else:
tempPluginFolderPath = createTempPluginFolder()
ftp = createFTPConnection()
pathToPluginJar = Path(f"{tempPluginFolderPath}/{localJarFileName}")
ftp_downloadFile(ftp, pathToPluginJar, localJarFileName)
else:
pluginPath = checkConfig().pathToPluginFolder
pathToPluginJar = Path(f"{pluginPath}/{localJarFileName}")
pluginPath = configValues.pathToPluginFolder
pathToPluginJar = Path(f"{pluginPath}/{localJarFileName}")
pluginVersion = ''
pluginName = ''
with ZipFile(pathToPluginJar, 'r') as pluginJar:
try:
with io.TextIOWrapper(pluginJar.open('plugin.yml', 'r'), encoding="utf-8") as pluginYml:
pluginYmlContentLine = pluginYml.readlines()
for line in pluginYmlContentLine:
if "version: " in line:
pluginVersion = line.replace('version: ', '')
pluginVersion = pluginVersion.replace('\n', '')
break
if searchMode == 'version':
if re.match(r'^version: ', line):
pluginVersion = line.replace('version: ', '')
pluginVersion = pluginVersion.replace('\n', '')
pluginVersion = pluginVersion.replace("'", '')
pluginVersion = pluginVersion.replace('"', '')
elif searchMode == 'name':
if re.match(r'^name: ', line):
pluginName = line.replace('name: ', '')
pluginName = pluginName.replace('\n', '')
pluginName = pluginName.replace("'", '')
pluginName = pluginName.replace('"', '')
except FileNotFoundError:
pluginVersion = ''
return pluginVersion
pluginName = ''
if not configValues.localPluginFolder:
deleteTempPluginFolder(tempPluginFolderPath)
if searchMode == 'version':
return pluginVersion
if searchMode == 'name':
return pluginName
def checkInstalledPackage(inputSelectedObject="all"):
configValues = configurationValues()
createPluginList()
if not checkConfig().localPluginFolder:
sftp = createSFTPConnection()
pluginList = sftp_listAll(sftp)
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(checkConfig().pathToPluginFolder)
pluginList = os.listdir(configValues.pathToPluginFolder)
i = 0
oldPackages = 0
oldPlugins = 0
print(oColors.brightBlack + f"Checking: {inputSelectedObject}" + oColors.standardWhite)
print("┌─────┬────────────────────────────────┬──────────────┬───────────┬───────────────────┐")
print("│ No. │ Name │ Installed V. │ Latest V. │ Update available │")
print("└─────┴────────────────────────────────┴──────────────┴───────────┴───────────────────┘")
print("┌─────┬────────────────────────────────┬──────────────┬──────────────┬───────────────────┐")
print("│ No. │ Name │ Installed V. │ Latest V. │ Update available ")
print("└─────┴────────────────────────────────┴──────────────┴──────────────┴───────────────────┘")
try:
for plugin in track(pluginList, description="Checking for updates" ,transient=True, complete_style="cyan"):
for plugin in track(pluginList, description="Checking for updates" ,transient=True, complete_style="bright_yellow"):
try:
fileName = getFileName(plugin)
fileVersion = getFileVersion(plugin)
pluginId = getInstalledPlugin(fileName, fileVersion)
pluginId = getInstalledPlugin(fileName, fileVersion, plugin)
except TypeError:
i += 1
continue
pluginIdStr = str(pluginId)
if fileVersion == '':
@@ -127,61 +158,66 @@ def checkInstalledPackage(inputSelectedObject="all"):
pluginIsOutdated = 'N/A'
if pluginIsOutdated == True:
oldPackages = oldPackages + 1
oldPlugins = oldPlugins + 1
if inputSelectedObject != "*" and inputSelectedObject != "all":
if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE):
if pluginLatestVersion == 'N/A':
print(oColors.brightBlack + f" [{1}]".ljust(8), end='')
print(oColors.brightBlack + f" [{1}]".rjust(6), end='')
else:
print(f" [{1}]".ljust(8), end='')
print(f" [{1}]".rjust(6), end='')
print(" ", end='')
print(f"{fileName}".ljust(33), end='')
print(f"{fileVersion}".ljust(15), end='')
print(f"{pluginLatestVersion}".ljust(12), end='')
print(f" {pluginIsOutdated}".ljust(5) + oColors.standardWhite)
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}]".ljust(8), end='')
print(oColors.brightBlack + f" [{i+1}]".rjust(6), end='')
else:
print(f" [{i+1}]".ljust(8), end='')
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(12), end='')
print(f" {pluginIsOutdated}".ljust(5) + oColors.standardWhite)
print(f"{pluginLatestVersion}".ljust(15), end='')
print(f"{pluginIsOutdated}".ljust(5) + oColors.standardWhite)
i += 1
except TypeError:
print(oColors.brightRed + "Error occured: Aborted checking for updates." + oColors.standardWhite)
print(oColors.brightYellow + f"Old packages: [{oldPackages}/{i}]" + oColors.standardWhite)
print(oColors.brightYellow + f"Outdated plugins: [{oldPlugins}/{i}]" + oColors.standardWhite)
def updateInstalledPackage(inputSelectedObject='all'):
configValues = configurationValues()
createPluginList()
if not checkConfig().localPluginFolder:
sftp = createSFTPConnection()
pluginList = sftp_listAll(sftp)
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(checkConfig().pathToPluginFolder)
pluginList = os.listdir(configValues.pathToPluginFolder)
i = 0
pluginsUpdated = 0
indexNumberUpdated = 0
print(oColors.brightBlack + f"Updating: {inputSelectedObject}" + oColors.standardWhite)
print("┌─────┬────────────────────────────────┬────────────┬──────────┐")
print("│ No. │ Name │ Old V. New V. │")
print("│ No. │ Name │ Old V. New V. ")
print("└─────┴────────────────────────────────┴────────────┴──────────┘")
try:
for plugin in track(pluginList, description="Updating" ,transient=True, complete_style="red"):
for plugin in track(pluginList, description="Updating" ,transient=True, complete_style="bright_magenta"):
try:
fileName = getFileName(plugin)
fileVersion = getFileVersion(plugin)
pluginId = getInstalledPlugin(fileName, fileVersion)
pluginId = getInstalledPlugin(fileName, fileVersion, plugin)
latestVersion = getLatestPluginVersion(pluginId)
except TypeError:
i += 1
continue
except ValueError:
i += 1
continue
pluginIdStr = str(pluginId)
if pluginId == None or pluginId == '':
@@ -189,24 +225,24 @@ def updateInstalledPackage(inputSelectedObject='all'):
continue
if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE):
if INSTALLEDPLUGINLIST[i][3] == True:
print(f" [{indexNumberUpdated+1}]".ljust(8), end='')
print(f" [{indexNumberUpdated+1}]".rjust(6), end='')
print(" ", end='')
print(f"{fileName}".ljust(33), end='')
print(f"{fileVersion}".ljust(8), end='')
print(" ", end='')
print(f"{latestVersion}".ljust(8))
print(f"{fileVersion}".ljust(13), end='')
print(f"{latestVersion}".ljust(13))
if not checkConfig().localPluginFolder:
if checkConfig().sftp_seperateDownloadPath is True:
pluginPath = checkConfig().sftp_pathToSeperateDownloadPath
if not configValues.localPluginFolder:
if configValues.sftp_seperateDownloadPath is True:
pluginPath = configValues.sftp_pathToSeperateDownloadPath
else:
pluginPath = checkConfig().sftp_folderPath
pluginPath = configValues.sftp_folderPath
pluginPath = Path(f"{pluginPath}/{plugin}")
sftp = createSFTPConnection()
indexNumberUpdated += 1
pluginsUpdated += 1
try:
getSpecificPackage(pluginId, checkConfig().sftp_folderPath)
if checkConfig().sftp_seperateDownloadPath is False:
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)
@@ -214,16 +250,16 @@ def updateInstalledPackage(inputSelectedObject='all'):
except FileNotFoundError:
print(oColors.brightRed + "Error: Old plugin file coulnd't be deleted" + oColors.standardWhite)
else:
if checkConfig().seperateDownloadPath is True:
pluginPath = checkConfig().pathToSeperateDownloadPath
if configValues.seperateDownloadPath is True:
pluginPath = configValues.pathToSeperateDownloadPath
else:
pluginPath = checkConfig().pathToPluginFolder
pluginPath = configValues.pathToPluginFolder
pluginPath = Path(f"{pluginPath}/{plugin}")
indexNumberUpdated += 1
pluginsUpdated += 1
try:
getSpecificPackage(pluginId, checkConfig().pathToPluginFolder)
if checkConfig().seperateDownloadPath is False:
getSpecificPackage(pluginId, configValues.pathToPluginFolder)
if configValues.seperateDownloadPath is False:
os.remove(pluginPath)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
@@ -238,78 +274,110 @@ def updateInstalledPackage(inputSelectedObject='all'):
if inputSelectedObject == 'all':
if INSTALLEDPLUGINLIST[i][3] == True:
print(f" [{indexNumberUpdated+1}]".ljust(8), end='')
print(f" [{indexNumberUpdated+1}]".rjust(6), end='')
print(" ", end='')
print(f"{fileName}".ljust(33), end='')
print(f"{fileVersion}".ljust(8), end='')
print(" ", end='')
print(f"{latestVersion}".ljust(8))
print(f"{fileVersion}".ljust(13), end='')
print(f"{latestVersion}".ljust(13))
if not checkConfig().localPluginFolder:
if checkConfig().sftp_seperateDownloadPath is True:
pluginPath = checkConfig().sftp_pathToSeperateDownloadPath
if not configValues.localPluginFolder:
if configValues.sftp_useSftp:
if configValues.sftp_seperateDownloadPath is True:
pluginPath = configValues.sftp_pathToSeperateDownloadPath
else:
pluginPath = configValues.sftp_folderPath
pluginPath = 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"HTTPError: {err.code} - {err.reason}" + oColors.standardWhite)
pluginsUpdated -= 1
except FileNotFoundError:
print(oColors.brightRed + f"FileNotFoundError: Old plugin file coulnd't be deleted" + oColors.standardWhite)
else:
pluginPath = checkConfig().sftp_folderPath
pluginPath = f"{pluginPath}/{plugin}"
sftp = createSFTPConnection()
indexNumberUpdated += 1
pluginsUpdated += 1
try:
getSpecificPackage(pluginId, checkConfig().sftp_folderPath)
if checkConfig().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 + f"Error: Old plugin file coulnd't be deleted" + oColors.standardWhite)
if configValues.sftp_seperateDownloadPath is True:
pluginPath = configValues.sftp_pathToSeperateDownloadPath
else:
pluginPath = configValues.sftp_folderPath
pluginPath = f"{pluginPath}/{plugin}"
ftp = createFTPConnection()
indexNumberUpdated += 1
pluginsUpdated += 1
try:
getSpecificPackage(pluginId, configValues.sftp_folderPath)
if configValues.sftp_seperateDownloadPath is False:
ftp.delete(pluginPath)
except HTTPError as err:
print(oColors.brightRed + f"HTTPError: {err.code} - {err.reason}" + oColors.standardWhite)
pluginsUpdated -= 1
except FileNotFoundError:
print(oColors.brightRed + f"FileNotFoundError: Old plugin file coulnd't be deleted" + oColors.standardWhite)
else:
if checkConfig().seperateDownloadPath is True:
pluginPath = checkConfig().pathToSeperateDownloadPath
if configValues.seperateDownloadPath is True:
pluginPath = configValues.pathToSeperateDownloadPath
else:
pluginPath = checkConfig().pathToPluginFolder
pluginPath = configValues.pathToPluginFolder
pluginPath = Path(f"{pluginPath}/{plugin}")
indexNumberUpdated += 1
pluginsUpdated += 1
try:
getSpecificPackage(pluginId, checkConfig().pathToPluginFolder)
if checkConfig().seperateDownloadPath is False:
getSpecificPackage(pluginId, configValues.pathToPluginFolder)
if configValues.seperateDownloadPath is False:
os.remove(pluginPath)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
print(oColors.brightRed + f"HTTPError: {err.code} - {err.reason}" + oColors.standardWhite)
pluginsUpdated -= 1
except FileNotFoundError:
print(oColors.brightRed + f"Error: Old plugin file coulnd't be deleted" + oColors.standardWhite)
print(oColors.brightRed + f"FileNotFoundError: Old plugin file coulnd't be deleted" + oColors.standardWhite)
i = i + 1
i += 1
except TypeError:
print(oColors.brightRed + "Error occured: Aborted updating for plugins." + oColors.standardWhite)
print(oColors.brightYellow + f"[{pluginsUpdated}/{i}] Plugins updated" + oColors.standardWhite)
print(oColors.brightYellow + f"Plugins updated: [{pluginsUpdated}/{i}]" + oColors.standardWhite)
if inputSelectedObject =='all' and pluginsUpdated == 0:
print(oColors.brightGreen + "All found plugins are on the latest version!" + oColors.standardWhite)
def getInstalledPlugin(localFileName, localFileVersion):
def getInstalledPlugin(localFileName, localFileVersion, localPluginFullName):
url = "https://api.spiget.org/v2/search/resources/" + localFileName + "?field=name&sort=-downloads"
packageName = doAPIRequest(url)
plugin_match_found = False
pluginID = None
for ressource in packageName:
localFileVersionNew = localFileVersion
i = 0
for i in range(0, 3):
if plugin_match_found == True:
break
pID = ressource["id"]
url2 = f"https://api.spiget.org/v2/resources/{pID}/versions?size=100&sort=-name"
packageVersions = doAPIRequest(url2)
for updates in packageVersions:
updateVersion = updates["name"]
if localFileVersion in updateVersion:
plugin_match_found = True
pluginID = pID
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)
return pluginID
break
if i == 1:
localFileVersionNew = re.sub(r'(\-\w*)', '', localFileVersion)
if i == 2:
pluginNameinYML = eggCrackingJar(localPluginFullName, 'name')
url = "https://api.spiget.org/v2/search/resources/" + pluginNameinYML + "?field=name&sort=-downloads"
packageName = doAPIRequest(url)
localFileVersion = localFileVersionNew
for ressource in packageName:
if plugin_match_found == True:
break
pID = ressource["id"]
url2 = f"https://api.spiget.org/v2/resources/{pID}/versions?size=100&sort=-name"
packageVersions = doAPIRequest(url2)
for updates in packageVersions:
updateVersion = updates["name"]
if localFileVersionNew in updateVersion:
plugin_match_found = True
pluginID = pID
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)
return pluginID
else:
if plugin_match_found != True:

View File

@@ -4,17 +4,23 @@ from urllib.error import HTTPError
from pathlib import Path
from handlers.handle_sftp import createSFTPConnection, sftp_listFilesInServerRoot
from handlers.handle_config import checkConfig
from handlers.handle_ftp import createFTPConnection, ftp_listFilesInServerRoot
from handlers.handle_config import configurationValues
from utils.consoleoutput import oColors
from serverjar.serverjar_paper import paperCheckForUpdate, papermc_downloader
def checkInstalledServerjar():
if not checkConfig().localPluginFolder:
sftp = createSFTPConnection()
serverRootList = sftp_listFilesInServerRoot(sftp)
configValues = configurationValues()
if not configValues.localPluginFolder:
if not configValues.sftp_useSftp:
ftp = createFTPConnection()
serverRootList = ftp_listFilesInServerRoot(ftp)
else:
sftp = createSFTPConnection()
serverRootList = sftp_listFilesInServerRoot(sftp)
else:
serverRootList = os.path.dirname(checkConfig().pathToPluginFolder)
serverRootList = os.path.dirname(configValues.pathToPluginFolder)
serverRootList = os.listdir(serverRootList)
installedServerjarFullName = None
try:
@@ -34,7 +40,7 @@ def checkInstalledServerjar():
print(oColors.brightRed + "Aborting the process." + oColors.standardWhite)
input("Press any key + enter to exit...")
sys.exit()
print(oColors.brightBlack + f"Checking: {installedServerjarFullName}" + oColors.standardWhite)
if 'paper' in installedServerjarFullName:
paperCheckForUpdate(installedServerjarFullName)
@@ -44,19 +50,20 @@ def checkInstalledServerjar():
def updateServerjar(serverJarBuild='latest'):
configValues = configurationValues()
try:
if serverJarBuild == None:
serverJarBuild = 'latest'
if not checkConfig().localPluginFolder:
if not configValues.localPluginFolder:
sftp = createSFTPConnection()
serverRootPath = checkConfig().sftp_folderPath
serverRootPath = configValues.sftp_folderPath
serverRootPath = Path(str(serverRootPath).replace(r'/plugins', ''))
serverRootList = sftp_listFilesInServerRoot(sftp)
else:
serverRoot = os.path.dirname(checkConfig().pathToPluginFolder)
serverRoot = os.path.dirname(configValues.pathToPluginFolder)
serverRootList = os.listdir(serverRoot)
serverRootPath = checkConfig().pathToPluginFolder
serverRootPath = configValues.pathToPluginFolder
helpPath = Path('/plugins')
helpPathstr = str(helpPath)
serverRootPath = Path(str(serverRootPath).replace(helpPathstr, ''))
@@ -90,8 +97,8 @@ def updateServerjar(serverJarBuild='latest'):
serverJarPath = Path(f"{serverRootPath}/{installedServerjarFullName}")
if 'paper' in installedServerjarFullName:
print(f"Updating Paper to build: {serverJarBuild}")
if not checkConfig().localPluginFolder:
print(oColors.brightBlack + f"Updating Paper to build: {serverJarBuild}" + oColors.standardWhite)
if not configValues.localPluginFolder:
try:
papermc_downloader(serverJarBuild, installedServerjarFullName)
sftp.remove(serverJarPath)

View File

@@ -3,16 +3,20 @@ import sys
import re
import urllib.request
from pathlib import Path
from rich.console import Console
from utils.consoleoutput import oColors
from utils.web_request import doAPIRequest
from handlers.handle_sftp import sftp_upload_server_jar, sftp_cdPluginDir, createSFTPConnection
from handlers.handle_config import checkConfig
from handlers.handle_sftp import createSFTPConnection, sftp_upload_server_jar
from handlers.handle_ftp import createFTPConnection, ftp_upload_server_jar
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
mcVersionFull = re.search(r'(\d*\.*\d)+', localPaperName)
try:
mcVersion = mcVersionFull.group()
@@ -23,6 +27,8 @@ def getInstalledPaperMinecraftVersion(localPaperName):
# = 550
def getInstalledPaperVersion(localPaperName):
if localPaperName is None:
return False
paperBuildFull = re.search(r'([\d]*.jar)', localPaperName)
try:
paperBuild = paperBuildFull.group()
@@ -34,52 +40,52 @@ def getInstalledPaperVersion(localPaperName):
def findVersionGroup(mcVersion):
versionGroups = ['1.16', '1.15']
versionGroupFound = False
if mcVersion is None:
return False
for versionGroup in versionGroups:
if versionGroupFound == True:
break
url = f"https://papermc.io/api/v2/projects/paper/version_group/{versionGroup}/builds"
papermcdetails = doAPIRequest(url)
papermcVersionForMc = papermcdetails["versions"]
for versions in papermcVersionForMc:
if versions == mcVersion:
versionGroupFound = True
paperVersionGroup = versionGroup
break
return paperVersionGroup
if versionGroup == mcVersion:
versionGroupFound = True
paperVersionGroup = versionGroup
break
return paperVersionGroup
return paperVersionGroup
return False # Not found
def findBuildVersion(wantedPaperBuild):
versionGroups = ['1.16', '1.15']
paperBuildFound = False
if wantedPaperBuild is None:
return False
for versionGroup in versionGroups:
if paperBuildFound is True:
break
url = f"https://papermc.io/api/v2/projects/paper/version_group/{versionGroup}/builds"
papermcdetails = doAPIRequest(url)
paperMcBuilds = papermcdetails["builds"]
for build in paperMcBuilds:
paperBuild = str(build["build"])
if paperBuild == wantedPaperBuild:
paperBuildFound = True
paperVersionGroup = build["version"]
break
return paperVersionGroup
return paperVersionGroup
return False # Not found
def findLatestBuild(paperVersionGroup):
if paperVersionGroup is None:
return False
url = f"https://papermc.io/api/v2/projects/paper/version_group/{paperVersionGroup}/builds"
papermcbuilds = doAPIRequest(url)
if "status" in papermcbuilds: # Checks if the API returns a status. This means that there was an error.
return False
latestPaperBuild = papermcbuilds["builds"][-1]["build"]
return latestPaperBuild
def findLatestBuildForVersion(mcVersion):
if mcVersion is None:
return False
url = f"https://papermc.io/api/v2/projects/paper/versions/{mcVersion}"
papermcbuilds = doAPIRequest(url)
latestPaperBuild = papermcbuilds["builds"][-1]
@@ -87,6 +93,8 @@ def findLatestBuildForVersion(mcVersion):
def versionBehind(installedPaperBuild, latestPaperBuild):
if installedPaperBuild or latestPaperBuild is None:
return False
installedPaperBuildint = int(installedPaperBuild)
latestPaperBuildint = int(latestPaperBuild)
versionsBehind = latestPaperBuildint - installedPaperBuildint
@@ -94,6 +102,8 @@ def versionBehind(installedPaperBuild, latestPaperBuild):
def getDownloadFileName(paperMcVersion, paperBuild):
if paperMcVersion or paperBuild is None:
return False
url = f"https://papermc.io/api/v2/projects/paper/versions/{paperMcVersion}/builds/{paperBuild}"
buildDetails = doAPIRequest(url)
downloadName = buildDetails["downloads"]["application"]["name"]
@@ -102,28 +112,69 @@ def getDownloadFileName(paperMcVersion, paperBuild):
def paperCheckForUpdate(installedServerjarFullName):
mcVersion = getInstalledPaperMinecraftVersion(installedServerjarFullName)
# Report an error if getInstalledPaperMinecraftVersion encountered an issue.
if not mcVersion:
print(oColors.brightRed + f"ERR: An error was encountered while detecting the server's Minecraft version." +
oColors.standardWhite)
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." +
oColors.standardWhite)
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." +
oColors.standardWhite)
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." +
oColors.standardWhite)
return False # Not currently handled, but can be at a later date. Currently just stops the following from
# being printed.
paperVersionBehind = versionBehind(paperInstalledBuild, paperLatestBuild)
print(f"Paper for {mcVersion}")
print("Index | Name | Installed V. | Latest V. | Versions behind ")
print(f" [1]".ljust(8), end='')
print(f"paper".ljust(21), end='')
print(f"{paperInstalledBuild}".ljust(8), end='')
print(" ", end='')
print(f"{paperLatestBuild}".ljust(8), end='')
print(" ", end='')
# 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)
paperVersionBehind = "N/A" # Sets paperVersionBehind to N/A while still letting the versionBehind check return
# # 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("└─────┴────────────────────────────────┴──────────────┴──────────────┴───────────────────┘")
print(" [1]".rjust(6), end='')
print(" ", end='')
print("paper".ljust(33), end='')
print(f"{paperInstalledBuild}".ljust(15), end='')
print(f"{paperLatestBuild}".ljust(15), end='')
print(f"{paperVersionBehind}".ljust(8))
print(oColors.brightYellow + f"Versions behind: [{paperVersionBehind}]" + oColors.standardWhite)
# https://papermc.io/api/docs/swagger-ui/index.html?configUrl=/api/openapi/swagger-config#/
def papermc_downloader(paperBuild='latest', installedServerjarName=None, mcVersion=None):
if checkConfig().localPluginFolder == False:
configValues = configurationValues()
if configValues.localPluginFolder == False:
downloadPath = createTempPluginFolder()
else:
downloadPath = checkConfig().pathToPluginFolder
downloadPath = configValues.pathToPluginFolder
helpPath = Path('/plugins')
helpPathstr = str(helpPath)
downloadPath = Path(str(downloadPath).replace(helpPathstr, ''))
@@ -149,22 +200,27 @@ def papermc_downloader(paperBuild='latest', installedServerjarName=None, mcVersi
downloadPackagePath = Path(f"{downloadPath}/{downloadFileName}")
if checkConfig().localPluginFolder == False:
if configValues.localPluginFolder == False:
downloadPath = createTempPluginFolder()
url = f"https://papermc.io/api/v2/projects/paper/versions/{mcVersion}/builds/{paperBuild}/downloads/{downloadFileName}"
remotefile = urllib.request.urlopen(url)
filesize = remotefile.info()['Content-Length']
print(f"Starting Paper-{paperBuild} download for {mcVersion}...")
urllib.request.urlretrieve(url, downloadPackagePath)
print(f"Getting Paper {paperBuild} for {mcVersion}")
console = Console()
with console.status("Downloading...", spinner='line', spinner_style='bright_magenta') as status:
urllib.request.urlretrieve(url, downloadPackagePath)
filesizeData = calculateFileSizeMb(filesize)
print("Downloaded " + (str(filesizeData)).rjust(9) + f" MB here {downloadPackagePath}")
if not configValues.localPluginFolder:
if not configValues.sftp_useSftp:
ftpSession = createFTPConnection()
ftp_upload_server_jar(ftpSession, downloadPackagePath)
else:
sftpSession = createSFTPConnection()
sftp_upload_server_jar(sftpSession, downloadPackagePath)
print(f"Downloadsize: {filesizeData} MB")
print(f"File downloaded here: {downloadPackagePath}")
if not checkConfig().localPluginFolder:
sftpSession = createSFTPConnection()
sftp_upload_server_jar(sftpSession, downloadPackagePath)
deleteTempPluginFolder(downloadPath)
print(oColors.brightGreen + "Downloaded successfully " + oColors.standardWhite + f"Paper-{paperBuild}" + \
oColors.brightGreen + " for " + oColors.standardWhite + f"{mcVersion}" + oColors.standardWhite)
print(oColors.brightGreen + "Downloaded successfully " + oColors.standardWhite + f"Paper {paperBuild}" + \
oColors.brightGreen + " for " + oColors.standardWhite + f"{mcVersion}" + oColors.standardWhite)

View File

@@ -6,8 +6,9 @@ import requests
from pathlib import Path
from utils.consoleoutput import oColors
from handlers.handle_config import checkConfig
from handlers.handle_config import configurationValues
from handlers.handle_sftp import createSFTPConnection
from handlers.handle_ftp import createFTPConnection
def getHelp():
@@ -95,11 +96,12 @@ def getCommandHelp(optionalParams):
def check_local_plugin_folder():
if checkConfig().localPluginFolder:
if checkConfig().seperateDownloadPath:
pluginFolderPath = checkConfig().pathToSeperateDownloadPath
configValues = configurationValues()
if configValues.localPluginFolder:
if configValues.seperateDownloadPath:
pluginFolderPath = configValues.pathToSeperateDownloadPath
else:
pluginFolderPath = checkConfig().pathToPluginFolder
pluginFolderPath = configValues.pathToPluginFolder
if not os.path.isdir(pluginFolderPath):
print(oColors.brightRed + "Plugin folder coulnd*t be found. Creating one..." + oColors.standardWhite)
@@ -129,19 +131,24 @@ def apiTest():
def check_requirements():
configValues = configurationValues()
apiTest()
check_local_plugin_folder()
if not checkConfig().localPluginFolder:
createSFTPConnection()
if not configValues.localPluginFolder:
if configValues.sftp_useSftp:
createSFTPConnection()
else:
createFTPConnection()
def createTempPluginFolder():
tempPluginFolder = Path("./TempSFTPUploadFolder")
configValues = configurationValues()
tempPluginFolder = Path("./TempSFTPFolder")
if not os.path.isdir(tempPluginFolder):
try:
os.mkdir(tempPluginFolder)
except OSError:
print(oColors.brightRed + "Creation of directory %s failed" % checkConfig().pathToPluginFolder)
print(oColors.brightRed + "Creation of directory %s failed" % configValues.pathToPluginFolder)
print(oColors.brightRed + "Please check the config file!" + oColors.standardWhite)
input("Press any key + enter to exit...")
sys.exit()
@@ -160,3 +167,9 @@ def calculateFileSizeMb(downloadFileSize):
fileSizeMb = fileSizeDownload / 1024 / 1024
roundedFileSize = round(fileSizeMb, 2)
return roundedFileSize
def calculateFileSizeKb(downloadFileSize):
fileSizeDownload = int(downloadFileSize)
fileSizeKb = fileSizeDownload / 1024
roundedFileSize = round(fileSizeKb, 2)
return roundedFileSize

View File

@@ -3,7 +3,7 @@ import requests
def doAPIRequest(url):
headers = {'user-agent': 'pluGET'}
headers = {'user-agent': 'pluGET/1.0'}
response = requests.get(url, headers=headers)
packageDetails = response.json()
return packageDetails