Compare commits

...

37 Commits

Author SHA1 Message Date
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
Neocky
9b628498f1 Added new command/ examples & updated know problems 2021-03-21 18:19:44 +01:00
Neocky
d40ee52da1 Merge pull request #12 from Neocky/dev/eggcracking
Dev/eggcracking
2021-03-21 17:44:10 +01:00
Neocky
e66985054c Removed debug print & text formating
Changes:
- removed debug prints
- changed some text formating
2021-03-21 16:37:25 +01:00
Neocky
e1efcc4fc7 Added help for all commands & general better output
Changes:
- added help fo all/specific commands
- unified the output of check/update
- beautified the output of check/update
- a little code cleanup
2021-03-21 14:30:27 +01:00
Neocky
1147d4f29c Added better view counter 2021-03-19 19:16:02 +01:00
Neocky
ebb04085d3 Changed theme size 2021-03-19 19:03:42 +01:00
Neocky
e161d2c2f9 Added meme 2021-03-19 19:02:38 +01:00
Neocky
01465eb769 Added new progress bar and some formating
Changes:
- added simple progress bar when checking/updating plugins
- misc code cleanup
- changed logo
2021-03-18 23:42:02 +01:00
Neocky
d478432396 Added rich librarie 2021-03-18 18:46:19 +01:00
Neocky
d7fc68195b Added eggcracking method and first progress bar tests
Changes:
- added eggcracking method for plugins
- plugins will be unzipped when they don't have a version in their name and the version will be searched inside the `plugin.yml` file
- added progress bar tests
- changed default paths in config
2021-03-18 00:03:07 +01:00
Neocky
e87729f700 Merge pull request #9 from Neocky/dev/paper
Dev/paper to main
For new release
2021-03-16 21:50:49 +01:00
Neocky
01b9a52b40 Added server software parts and new usage parts 2021-03-16 21:45:37 +01:00
Neocky
76e1d7f5fd Fixed array was not created
Changes:
- fixed array would not be created for a plugin when plugin would throw a type- or valueerror
- deleted testing prints
- minor code cleanup
2021-03-16 21:10:09 +01:00
Neocky
430dbcd8d2 Finished paper support; Created independent paths
Changes:
- Created OS independent paths
- finished paper support
- created many catches for paper handling errors
2021-03-16 01:04:13 +01:00
Neocky
5e296e858f Added papermc support & fixing some issues
Changes:
- adding papermc support
- paper can be checked for an update
- can be updated to latest or specific version
- download specific paper version for different minecraft versions
2021-03-15 16:26:00 +01:00
Neocky
20261d110e Added catch for HTTPError and added papermc ground work
Changes:
- Added HTTPError catch when searching for a plugin
- Created first ground work for papermc server jar support
2021-03-15 01:20:18 +01:00
Neocky
932ae66827 Edited hit counter 2021-03-14 22:30:07 +01:00
Neocky
1e7de3ac5a FileNotFoundError will catch when using SFTP 2021-03-14 21:07:06 +01:00
Neocky
662f303935 Catched FileNotfoundError & Plugins updated will now display correctly
Changes:
- Catched file not found error
- Plugins updated
- Updated wrong index numbers when updating
2021-03-14 20:21:26 +01:00
Neocky
053a67e2d8 Update README.md 2021-03-14 19:38:47 +01:00
Neocky
e37840e665 Update README.md 2021-03-14 19:38:22 +01:00
Neocky
ac9b89de4f Edited license badge link 2021-03-14 19:15:06 +01:00
Neocky
f704b29ff9 Added latest release badge 2021-03-14 19:12:56 +01:00
Neocky
12f28107de Updated link 2021-03-14 18:55:39 +01:00
Neocky
b7e9673c80 Updated link 2021-03-14 18:51:43 +01:00
Neocky
0e4abad762 Update README.md 2021-03-14 18:02:09 +01:00
Neocky
972daf5687 Update README.md 2021-03-14 17:53:41 +01:00
Neocky
540a355d3d Added hit counter and removed star counter 2021-03-14 14:14:12 +01:00
Neocky
7e9b5850be Fixed big duplicate array issue for a plugin; Added seperate download path
Changes:
- Fixed big issue where two arrays would be created for a plugin and then everything else would fail
- added seperate location for downloaded files
2021-03-14 13:25:13 +01:00
14 changed files with 820 additions and 228 deletions

133
README.md
View File

@@ -1,4 +1,5 @@
<p align="center"> <p align="center">
<img src="https://i.ibb.co/JyCxnQn/logoreal.png" alt="pluGET" border="0"></a> <img src="https://i.ibb.co/JyCxnQn/logoreal.png" alt="pluGET" border="0"></a>
</p> </p>
@@ -8,15 +9,35 @@
</p> </p>
<p align="center"> <p align="center">
<a href="https://github.com/Neocky/pluGET/blob/main/LICENSE"> <img src="https://img.shields.io/badge/license-Apache--2.0-blue" alt="Apache-2.0" border="0"></a> <a href="https://github.com/Neocky/pluGET/blob/main/LICENSE"> <img src="https://img.shields.io/github/license/Neocky/pluGET" alt="Apache-2.0" border="0"></a>
<a href="https://github.com/Neocky/pluGET/stargazers"> <img src="https://img.shields.io/github/stars/Neocky/pluGET?color=yellow" alt="stars" border="0"></a> <a href="https://github.com/Neocky/pluGET/releases"> <img src="https://img.shields.io/github/v/release/Neocky/pluGET?include_prereleases" alt"latestrelease"></a>
<a href="https://github.com/Neocky/pluGET/releases"> <img src="https://img.shields.io/github/downloads/Neocky/pluGET/total" alt="downloads" border="0"></a> <a href="https://github.com/Neocky/pluGET/releases"> <img src="https://img.shields.io/github/downloads/Neocky/pluGET/total" alt="downloads" border="0"></a>
<a href="https://hits.seeyoufarm.com"><img src="https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FNeocky%2FpluGET&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false"/></a>
</p> </p>
# pluGET
A powerfull package manager which handles [Plugins](https://www.spigotmc.org/resources/) for minecraft servers. # pluGET
#### A powerfull 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? ## Issues? Found a bug?
@@ -28,8 +49,9 @@ This is a package manager for minecraft [Spigot](https://www.spigotmc.org/) serv
This is a standalone program written in python. 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, 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 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/)).
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 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 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. 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. This program is suited for minecraft server owners who want to save time and stay on top of their plugin versions.
@@ -42,10 +64,16 @@ If you still have questions [here](https://github.com/Neocky/pluGET#need-help) i
So what can it do exactly? So what can it do exactly?
pluGET can: pluGET can:
- work locally or through sftp - work locally or through sftp
- download the latest version of a plugin - manage plugins:
- update every installed/one specific plugin - download the latest version of a plugin
- check for an update of every installed/one specific plugin - update every installed/one specific plugin
- remove a plugin from the plugin folder - check for an update of every installed/one specific plugin
- remove a plugin from the plugin folder
- manager server software:
- download a specific server software version
- check instlalled server software for update
- update installed server software to a specific version
- supported server software: [PaperMc](https://papermc.io/)
There are more features in the work. Check [Projects](https://github.com/Neocky/pluGET/projects) for a complete list. There are more features in the work. Check [Projects](https://github.com/Neocky/pluGET/projects) for a complete list.
@@ -71,7 +99,7 @@ Get it [here](https://www.python.org/downloads/).
Install the needed packages for this project. Install the needed packages for this project.
Execute this command in the ```\plugGET``` folder: Execute this command in the ```\plugGET``` folder:
```python ```python
pip install -r requirements.txt py -m pip install -r requirements.txt
``` ```
@@ -82,10 +110,27 @@ Edit the config to your needs and relaunch pluGET.
## Usage ## Usage
> As always, if you update plugins, shut down your server!
Execute the `launcher.bat` in the `\pluGET` folder. This will launch pluGET correctly. Execute the `launcher.bat` in the `\pluGET` folder. This will launch pluGET correctly.
Another way is to launch the `src\__main__.py` file. Another way is to launch the `src\__main__.py` file.
The following are examples of input for the general usage: The following are examples of input for the general usage:
(Hint: 'all' can always be exchanged through the plugin name or the plugin id and reverse) (Hint: [thingsInBrackets] are optional & 'all' can always be exchanged through the plugin name or the plugin id and reverse)
### General
#### Command help:
`help command [all/command]`
```
help command
```
<details>
<summary>Output</summary>
![Output](https://i.ibb.co/9VZCjD6/pluget-help2.png)
</details>
### Manage Plugins
#### Download the latest update of a specific package: #### Download the latest update of a specific package:
`get [pluginID/pluginName]` `get [pluginID/pluginName]`
``` ```
@@ -104,6 +149,15 @@ or:
``` ```
check 'pluginName' check 'pluginName'
``` ```
<details>
<summary>Output</summary>
![Output](https://i.ibb.co/VmSNh6K/pluget-checkall.png)
</details>
#### Update all plugins/one specific plugin: #### Update all plugins/one specific plugin:
`update [all/pluginName]` `update [all/pluginName]`
``` ```
@@ -137,37 +191,34 @@ exit .
``` ```
help . help .
``` ```
### Manage Server Software
#### Check installed server software for updates:
`check serverjar`
```
check serverjar
```
### Update installed server software to latest/specific version:
`update serverjar [Version]`
```
update serverjar 'PaperMCVersion'
```
### Download specific paper version:
`get-paper [paperBuild] [minecraftVersion]`
```
get-paper 550 1.16.5
```
or:
```
get-paper 321
```
## Known problems ## Known problems
### Can't get installed version
### Can't get latest version/Update available
For example: For example:
``` ![worldguard](https://i.ibb.co/7NJ9HRG/pluget-checkallonlyone.png)
pluGET >> check all As you can see the installed version was found but not the latest version for this plugin.
Checking: all This is because this is a plugin which is not available on [Spigot](https://www.spigotmc.org/resources/).
Index | Name | Installed V. | Latest V. | Update available pluGET supports currently only plugins from [Spigot](https://www.spigotmc.org/resources/).
[1] Vault N/A 1.7.3 False In this example this is a bukkit plugin.
```
This is a known issue because the filename in the `\plugin` folder doesn't include a version.
This is the plugin file in the `\plugin` folder right now: `Vault.jar`
How it should be: `Vault-1.7.3.jar`
Many plugins which get download from Spigot won't have a file version in the name.
#### How to solve:
Delete the `Vault.jar` file and download the newest version with the `get` command:
```
pluGET >> get vault
Index | Name | Description | Downloads
[1] Vault Vault is a Permissions, Chat, & Economy API to give plugins easy hooks into these systems. 989046
Select your wanted Ressource (Index)(0 to exit): 1
Downloadsize: 267.31 KB
File downloaded here: C:\Users\USER\Desktop\plugins\Vault-1.7.3.jar
```
Now you got the plugin with the correct name inside your `\plugin` folder: `Vault-1.7.3.jar`
And pluGET will tell you the installed version and check if an update is available when checking again:
```
pluGET >> check all
Checking: all
Index | Name | Installed V. | Latest V. | Update available
[1] Vault 1.7.3 1.7.3 False
```

View File

@@ -8,3 +8,7 @@ cffi >= 1.14.5
six >= 1.15.0 six >= 1.15.0
pycparser >= 2.20 pycparser >= 2.20
pysftp >= 0.2.9 pysftp >= 0.2.9
rich >= 9.13.0
commonmark >= 0.9.1
Pygments >= 2.8.1
typing_extensions >= 3.7.4.3

View File

@@ -1,10 +1,7 @@
from utils.consoleoutput import consoleTitle, clearConsole, printMainMenu, oColors from utils.consoleoutput import consoleTitle, clearConsole, printMainMenu
from utils.utilities import getHelp, check_requirements from utils.utilities import check_requirements
from handlers.handle_input import createInputLists, getInput from handlers.handle_input import createInputLists, getInput
from handlers.handle_config import checkConfig from handlers.handle_config import checkConfig
from plugin.plugin_downloader import searchPackage, getSpecificPackage
from plugin.plugin_updatechecker import updateInstalledPackage, checkInstalledPackage
from plugin.plugin_remover import removePlugin
def mainFunction(): def mainFunction():

View File

@@ -1,57 +1,76 @@
import os import os
import sys import sys
import configparser import configparser
from pathlib import Path
from utils.consoleoutput import oColors from utils.consoleoutput import oColors
def checkConfig(): class configurationValues:
currentFolder = os.getcwd() def __init__(self):
os.chdir('..') config = configparser.ConfigParser()
configAvailable = os.path.isfile("config.ini") config.sections()
config.read("config.ini")
localPluginFolder = config['General']['LocalPluginFolder']
self.pathToPluginFolder = Path(config['General']['PathToPluginFolder'])
seperateDownloadPath = config['General']['SeperateDownloadPath']
self.pathToSeperateDownloadPath = Path(config['General']['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']['Port']
self.sftp_folderPath = config['SFTP - Remote Server']['PluginFolderOnServer']
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
def checkConfig():
configAvailable = os.path.isfile("config.ini")
if not configAvailable: if not configAvailable:
createConfig() createConfig()
print(oColors.brightRed + "Config created. Edit config before executing again!" + oColors.standardWhite) print(oColors.brightRed + "Config created. Edit config before executing again!" + oColors.standardWhite)
input("Press any key + enter to exit...") input("Press any key + enter to exit...")
sys.exit() sys.exit()
class configValues:
config = configparser.ConfigParser()
config.sections()
config.read("config.ini")
localPluginFolder = config['General']['LocalPluginFolder']
pathToPluginFolder = config['General']['PathToPluginFolder']
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']['PluginFolderForUpload']
sftp_port = int(sftp_port)
if localPluginFolder == 'True':
localPluginFolder = True
else:
localPluginFolder = False
os.chdir(currentFolder)
return configValues
def createConfig(): def createConfig():
config = configparser.ConfigParser(allow_no_value=True) config = configparser.ConfigParser(allow_no_value=True)
config['General'] = {} config['General'] = {}
config['General'][';'] = 'If a local plugin folder exists (True/False): (If False SFTP will be used)' config['General'][';'] = 'If a local plugin folder exists (True/False): (If False SFTP will be used)'
config['General']['LocalPluginFolder'] = 'True' config['General']['LocalPluginFolder'] = 'True'
config['General']['PathToPluginFolder'] = 'C:\\Users\\USER\\Desktop\\plugins' 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['SFTP - Remote Server'] = {} config['SFTP - Remote Server'] = {}
config['SFTP - Remote Server']['Server'] = '0.0.0.0' config['SFTP - Remote Server']['Server'] = '0.0.0.0'
config['SFTP - Remote Server']['Username'] = 'user' config['SFTP - Remote Server']['Username'] = 'user'
config['SFTP - Remote Server']['Password'] = 'password' 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'][';'] = 'Normally you won*t need to change anything below this line'
config['SFTP - Remote Server']['Port'] = '22' config['SFTP - Remote Server']['Port'] = '22'
config['SFTP - Remote Server']['PluginFolderForUpload'] = '.\\plugins' 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']['SeperateDownloadPath'] = 'False'
config['SFTP - Remote Server']['PathToSeperateDownloadPath'] = '.\\plugins'
with open('./config.ini', 'w') as configfile:
with open('config.ini', 'w') as configfile:
config.write(configfile) config.write(configfile)

View File

@@ -1,11 +1,14 @@
import sys import sys
from utils.consoleoutput import oColors from utils.consoleoutput import oColors
from utils.utilities import getHelp 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_downloader import searchPackage, getSpecificPackage
from plugin.plugin_updatechecker import updateInstalledPackage, checkInstalledPackage from plugin.plugin_updatechecker import updateInstalledPackage, checkInstalledPackage
from plugin.plugin_remover import removePlugin from plugin.plugin_remover import removePlugin
from serverjar.serverjar_checker import checkInstalledServerjar, updateServerjar
from serverjar.serverjar_paper import papermc_downloader
def createInputLists(): def createInputLists():
global COMMANDLIST global COMMANDLIST
@@ -16,7 +19,8 @@ def createInputLists():
'search', 'search',
'exit', 'exit',
'help', 'help',
'remove' 'remove',
'get-paper'
] ]
global INPUTSELECTEDOBJECT global INPUTSELECTEDOBJECT
INPUTSELECTEDOBJECT = [ INPUTSELECTEDOBJECT = [
@@ -26,23 +30,38 @@ def createInputLists():
def handleInput(inputCommand, inputSelectedObject, inputParams): def handleInput(inputCommand, inputSelectedObject, inputParams):
configValues = configurationValues()
while True: while True:
if inputCommand == 'get': if inputCommand == 'get':
if inputSelectedObject.isdigit(): if inputSelectedObject.isdigit():
if not checkConfig().localPluginFolder: if not configValues.localPluginFolder:
getSpecificPackage(inputSelectedObject, checkConfig().sftp_folderPath, inputParams) if configValues.sftp_seperateDownloadPath is True:
pluginPath = configValues.sftp_pathToSeperateDownloadPath
else:
pluginPath = configValues.sftp_folderPath
getSpecificPackage(inputSelectedObject, pluginPath, inputParams)
break break
else: else:
getSpecificPackage(inputSelectedObject, checkConfig().pathToPluginFolder, inputParams) if configValues.seperateDownloadPath is True:
pluginPath = configValues.pathToSeperateDownloadPath
else:
pluginPath = configValues.pathToPluginFolder
getSpecificPackage(inputSelectedObject, pluginPath, inputParams)
break break
else: else:
searchPackage(inputSelectedObject) searchPackage(inputSelectedObject)
break break
if inputCommand == 'update': if inputCommand == 'update':
updateInstalledPackage(inputSelectedObject) if inputSelectedObject == 'serverjar':
updateServerjar(inputParams)
else:
updateInstalledPackage(inputSelectedObject)
break break
if inputCommand == 'check': if inputCommand == 'check':
checkInstalledPackage(inputSelectedObject) if inputSelectedObject == 'serverjar':
checkInstalledServerjar()
else:
checkInstalledPackage(inputSelectedObject)
break break
if inputCommand == 'search': if inputCommand == 'search':
searchPackage(inputSelectedObject) searchPackage(inputSelectedObject)
@@ -50,13 +69,19 @@ def handleInput(inputCommand, inputSelectedObject, inputParams):
if inputCommand == 'exit': if inputCommand == 'exit':
sys.exit() sys.exit()
if inputCommand == 'help': if inputCommand == 'help':
getHelp() if inputSelectedObject == 'command' or inputSelectedObject == 'commands':
getCommandHelp(inputParams)
else:
getHelp()
break break
if inputCommand == 'remove': if inputCommand == 'remove':
removePlugin(inputSelectedObject) removePlugin(inputSelectedObject)
break break
if inputCommand == 'get-paper':
papermc_downloader(inputSelectedObject, inputParams)
break
else: else:
print(oColors.brightRed + "Command not found. Please try again." + oColors.standardWhite) print(oColors.brightRed + "Error: Command not found. Please try again. :(" + oColors.standardWhite)
getInput() getInput()
getInput() getInput()
@@ -67,7 +92,8 @@ def getInput():
inputCommand, inputSelectedObject, *inputParams = input("pluGET >> ").split() inputCommand, inputSelectedObject, *inputParams = input("pluGET >> ").split()
break break
except ValueError: except ValueError:
print(oColors.brightRed + "Wrong input! Use: > *command* *selectedObject* *optionalParams*" + oColors.standardWhite) 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)
inputParams = inputParams[0] if inputParams else None inputParams = inputParams[0] if inputParams else None
handleInput(inputCommand, inputSelectedObject, inputParams) handleInput(inputCommand, inputSelectedObject, inputParams)

View File

@@ -45,6 +45,17 @@ def sftp_upload_file(sftp, itemPath):
sftp.close() sftp.close()
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)
sftp.close()
def sftp_listAll(sftp): def sftp_listAll(sftp):
try: try:
sftp.chdir('plugins') sftp.chdir('plugins')
@@ -57,3 +68,17 @@ def sftp_listAll(sftp):
return installedPlugins return installedPlugins
except UnboundLocalError: except UnboundLocalError:
print(oColors.brightRed + "No plugins were found." + oColors.standardWhite) print(oColors.brightRed + "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)
try:
return filesInServerRoot
except UnboundLocalError:
print(oColors.brightRed + "No Serverjar was found." + oColors.standardWhite)

View File

@@ -1,21 +1,15 @@
import re import re
import urllib.request import urllib.request
from urllib.error import HTTPError from urllib.error import HTTPError
from pathlib import Path
from utils.consoleoutput import oColors from utils.consoleoutput import oColors
from utils.web_request import doAPIRequest from utils.web_request import doAPIRequest
from utils.utilities import createTempPluginFolder, deleteTempPluginFolder from utils.utilities import createTempPluginFolder, deleteTempPluginFolder, calculateFileSizeKb, calculateFileSizeMb
from handlers.handle_config import checkConfig from handlers.handle_config import configurationValues
from handlers.handle_sftp import sftp_upload_file, sftp_cdPluginDir, createSFTPConnection 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
def handleRegexPackageName(packageNameFull): def handleRegexPackageName(packageNameFull):
packageNameFull2 = packageNameFull packageNameFull2 = packageNameFull
# trims the part of the package that has for example "[1.1 Off]" in it # trims the part of the package that has for example "[1.1 Off]" in it
@@ -57,10 +51,11 @@ def getVersionName(packageId, versionId):
def searchPackage(ressourceName): def searchPackage(ressourceName):
configValues = configurationValues()
url = f"https://api.spiget.org/v2/search/resources/{ressourceName}?field=name&sort=-downloads" url = f"https://api.spiget.org/v2/search/resources/{ressourceName}?field=name&sort=-downloads"
packageName = doAPIRequest(url) packageName = doAPIRequest(url)
i = 1 i = 1
print(f"Searching: {ressourceName}") print(oColors.brightBlack + f"Searching: {ressourceName}" + oColors.standardWhite)
print("Index | Name | Description | Downloads") print("Index | Name | Description | Downloads")
for ressource in packageName: for ressource in packageName:
pName = ressource["name"] pName = ressource["name"]
@@ -77,13 +72,20 @@ def searchPackage(ressourceName):
if ressourceSelected != 0: if ressourceSelected != 0:
ressourceSelected = ressourceSelected - 1 ressourceSelected = ressourceSelected - 1
ressourceId = packageName[ressourceSelected]["id"] ressourceId = packageName[ressourceSelected]["id"]
if not checkConfig().localPluginFolder: if not configValues.localPluginFolder:
getSpecificPackage(ressourceId, checkConfig().sftp_folderPath) try:
getSpecificPackage(ressourceId, configValues.sftp_folderPath)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
else: else:
getSpecificPackage(ressourceId, checkConfig().pathToPluginFolder) try:
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'): def downloadSpecificVersion(ressourceId, downloadPath, versionID='latest'):
configValues = configurationValues()
if versionID != 'latest': if versionID != 'latest':
#url = f"https://spigotmc.org/resources/{ressourceId}/download?version={versionID}" #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) print(oColors.brightRed + "Sorry but specific version downloads aren't supported because of cloudflare protection. :(" + oColors.standardWhite)
@@ -95,16 +97,22 @@ def downloadSpecificVersion(ressourceId, downloadPath, versionID='latest'):
remotefile = urllib.request.urlopen(url) remotefile = urllib.request.urlopen(url)
filesize = remotefile.info()['Content-Length'] filesize = remotefile.info()['Content-Length']
urllib.request.urlretrieve(url, downloadPath) urllib.request.urlretrieve(url, downloadPath)
filesizeData = calculateFileSize(filesize) filesize = int(filesize)
print(f"Downloadsize: {filesizeData} KB") print(" ", end='')
print(f"File downloaded here: {downloadPath}") if filesize >= 1000000:
if not checkConfig().localPluginFolder: 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:
sftpSession = createSFTPConnection() sftpSession = createSFTPConnection()
sftp_upload_file(sftpSession, downloadPath) sftp_upload_file(sftpSession, downloadPath)
def getSpecificPackage(ressourceId, downloadPath, inputPackageVersion='latest'): def getSpecificPackage(ressourceId, downloadPath, inputPackageVersion='latest'):
if checkConfig().localPluginFolder == False: configValues = configurationValues()
if configValues.localPluginFolder == False:
downloadPath = createTempPluginFolder() downloadPath = createTempPluginFolder()
url = f"https://api.spiget.org/v2/resources/{ressourceId}" url = f"https://api.spiget.org/v2/resources/{ressourceId}"
packageDetails = doAPIRequest(url) packageDetails = doAPIRequest(url)
@@ -113,30 +121,17 @@ def getSpecificPackage(ressourceId, downloadPath, inputPackageVersion='latest'):
versionId = getVersionID(ressourceId, inputPackageVersion) versionId = getVersionID(ressourceId, inputPackageVersion)
packageVersion = getVersionName(ressourceId, versionId) packageVersion = getVersionName(ressourceId, versionId)
packageDownloadName = f"{packageNameNew}-{packageVersion}.jar" packageDownloadName = f"{packageNameNew}-{packageVersion}.jar"
downloadPackagePath = f"{downloadPath}\\{packageDownloadName}" downloadPackagePath = Path(f"{downloadPath}/{packageDownloadName}")
if checkConfig().localPluginFolder: if configValues.localPluginFolder:
if inputPackageVersion is None or inputPackageVersion == 'latest': if inputPackageVersion is None or inputPackageVersion == 'latest':
try: downloadSpecificVersion(ressourceId=ressourceId, downloadPath=downloadPackagePath)
downloadSpecificVersion(ressourceId=ressourceId, downloadPath=downloadPackagePath)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
else: else:
try: downloadSpecificVersion(ressourceId, downloadPackagePath, versionId)
downloadSpecificVersion(ressourceId, downloadPackagePath, versionId)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
if not checkConfig().localPluginFolder: if not configValues.localPluginFolder:
if inputPackageVersion is None or inputPackageVersion == 'latest': if inputPackageVersion is None or inputPackageVersion == 'latest':
try: downloadSpecificVersion(ressourceId=ressourceId, downloadPath=downloadPackagePath)
downloadSpecificVersion(ressourceId=ressourceId, downloadPath=downloadPackagePath) deleteTempPluginFolder(downloadPath)
deleteTempPluginFolder(downloadPath)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
else: else:
try: downloadSpecificVersion(ressourceId, downloadPackagePath, versionId)
downloadSpecificVersion(ressourceId, downloadPackagePath, versionId) deleteTempPluginFolder(downloadPath)
deleteTempPluginFolder(downloadPath)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)

View File

@@ -1,19 +1,21 @@
import os import os
import re import re
from pathlib import Path
from utils.consoleoutput import oColors 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_sftp import createSFTPConnection, sftp_listAll
from plugin.plugin_updatechecker import getFileName, getFileVersion, getInstalledPlugin, createPluginList from plugin.plugin_updatechecker import getFileName, getFileVersion, getInstalledPlugin, createPluginList
def removePlugin(pluginToRemove): def removePlugin(pluginToRemove):
configValues = configurationValues()
createPluginList() createPluginList()
if not checkConfig().localPluginFolder: if not configValues.localPluginFolder:
sftp = createSFTPConnection() sftp = createSFTPConnection()
pluginList = sftp_listAll(sftp) pluginList = sftp_listAll(sftp)
else: else:
pluginList = os.listdir(checkConfig().pathToPluginFolder) pluginList = os.listdir(configValues.pathToPluginFolder)
i = 0 i = 0
try: try:
for plugin in pluginList: for plugin in pluginList:
@@ -27,17 +29,17 @@ def removePlugin(pluginToRemove):
if pluginToRemove == pluginIdStr or re.search(pluginToRemove, fileName, re.IGNORECASE): if pluginToRemove == pluginIdStr or re.search(pluginToRemove, fileName, re.IGNORECASE):
print(f"Removing: {fileName}") print(f"Removing: {fileName}")
if not checkConfig().localPluginFolder: if not configValues.localPluginFolder:
pluginPath = checkConfig().sftp_folderPath pluginPath = configValues.sftp_folderPath
pluginPath = f"{pluginPath}\\{plugin}" pluginPath = f"{pluginPath}/{plugin}"
sftp = createSFTPConnection() sftp = createSFTPConnection()
sftp.remove(pluginPath) sftp.remove(pluginPath)
print(f"Removed: {fileName}") print(f"Removed: {fileName}")
i += 1 i += 1
break break
else: else:
pluginPath = checkConfig().pathToPluginFolder pluginPath = configValues.pathToPluginFolder
pluginPath = f"{pluginPath}\\{plugin}" pluginPath = Path(f"{pluginPath}/{plugin}")
os.remove(pluginPath) os.remove(pluginPath)
print(f"Removed: {fileName}") print(f"Removed: {fileName}")
i += 1 i += 1

View File

@@ -1,9 +1,14 @@
import os import os
import re import re
import io
from zipfile import ZipFile
from urllib.error import HTTPError
from pathlib import Path
from rich.progress import track
from utils.consoleoutput import oColors from utils.consoleoutput import oColors
from utils.web_request import doAPIRequest from utils.web_request import doAPIRequest
from handlers.handle_config import checkConfig from handlers.handle_config import configurationValues
from handlers.handle_sftp import createSFTPConnection, sftp_listAll from handlers.handle_sftp import createSFTPConnection, sftp_listAll
from plugin.plugin_downloader import getSpecificPackage from plugin.plugin_downloader import getSpecificPackage
@@ -36,6 +41,10 @@ def getFileVersion(pluginName):
pluginVersion = re.search(r'([\d.]+[.jar]+)', pluginNameFull) pluginVersion = re.search(r'([\d.]+[.jar]+)', pluginNameFull)
pluginVersionFull = pluginVersion.group() pluginVersionFull = pluginVersion.group()
pluginVersionString = pluginVersionFull.replace('.jar', '') pluginVersionString = pluginVersionFull.replace('.jar', '')
if pluginVersionString.endswith('.'):
pluginVersionString = ''
if pluginVersionString == '':
pluginVersionString = eggCrackingJar(pluginNameFull)
return pluginVersionString return pluginVersionString
@@ -54,30 +63,55 @@ def compareVersions(plugin_latest_version, pluginVersion):
return plugin_is_outdated return plugin_is_outdated
def eggCrackingJar(localJarFileName):
configValues = configurationValues()
if not configValues.localPluginFolder:
pluginPath = configValues.sftp_folderPath
else:
pluginPath = configValues.pathToPluginFolder
pathToPluginJar = Path(f"{pluginPath}/{localJarFileName}")
pluginVersion = ''
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
except FileNotFoundError:
pluginVersion = ''
return pluginVersion
def checkInstalledPackage(inputSelectedObject="all"): def checkInstalledPackage(inputSelectedObject="all"):
configValues = configurationValues()
createPluginList() createPluginList()
if not checkConfig().localPluginFolder: if not configValues.localPluginFolder:
sftp = createSFTPConnection() sftp = createSFTPConnection()
pluginList = sftp_listAll(sftp) pluginList = sftp_listAll(sftp)
else: else:
pluginList = os.listdir(checkConfig().pathToPluginFolder) pluginList = os.listdir(configValues.pathToPluginFolder)
i = 0 i = 0
oldPackages = 0 oldPlugins = 0
print(f"Checking: {inputSelectedObject}") print(oColors.brightBlack + f"Checking: {inputSelectedObject}" + oColors.standardWhite)
print("Index | Name | Installed V. | Latest V. | Update available") print("┌─────┬────────────────────────────────┬──────────────┬──────────────┬───────────────────┐")
print("│ No. │ Name │ Installed V. │ Latest V. │ Update available │")
print("└─────┴────────────────────────────────┴──────────────┴──────────────┴───────────────────┘")
try: try:
for plugin in pluginList: for plugin in track(pluginList, description="Checking for updates" ,transient=True, complete_style="bright_yellow"):
try: try:
fileName = getFileName(plugin) fileName = getFileName(plugin)
fileVersion = getFileVersion(plugin) fileVersion = getFileVersion(plugin)
pluginId = getInstalledPlugin(fileName, fileVersion) pluginId = getInstalledPlugin(fileName, fileVersion)
except TypeError: except TypeError:
i += 1
continue continue
pluginIdStr = str(pluginId) pluginIdStr = str(pluginId)
if fileVersion == '': if fileVersion == '':
fileVersion = 'N/A' fileVersion = 'N/A'
try: try:
pluginLatestVersion = INSTALLEDPLUGINLIST[i][2] pluginLatestVersion = INSTALLEDPLUGINLIST[i][2]
except IndexError: except IndexError:
@@ -95,78 +129,113 @@ def checkInstalledPackage(inputSelectedObject="all"):
pluginIsOutdated = 'N/A' pluginIsOutdated = 'N/A'
if pluginIsOutdated == True: if pluginIsOutdated == True:
oldPackages = oldPackages + 1 oldPlugins = oldPlugins + 1
if inputSelectedObject != "*" and inputSelectedObject != "all": if inputSelectedObject != "*" and inputSelectedObject != "all":
if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE): if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE):
print(f" [{1}]".ljust(8), end='') 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"{fileName}".ljust(33), end='')
print(f"{fileVersion}".ljust(15), end='') print(f"{fileVersion}".ljust(15), end='')
print(f"{pluginLatestVersion}".ljust(12), end='') print(f"{pluginLatestVersion}".ljust(15), end='')
print(f" {pluginIsOutdated}".ljust(5)) print(f"{pluginIsOutdated}".ljust(5) + oColors.standardWhite)
break break
else: else:
print(f" [{i+1}]".ljust(8), 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"{fileName}".ljust(33), end='')
print(f"{fileVersion}".ljust(15), end='') print(f"{fileVersion}".ljust(15), end='')
print(f"{pluginLatestVersion}".ljust(12), end='') print(f"{pluginLatestVersion}".ljust(15), end='')
print(f" {pluginIsOutdated}".ljust(5)) print(f"{pluginIsOutdated}".ljust(5) + oColors.standardWhite)
i = i + 1 i += 1
except TypeError: except TypeError:
print(oColors.brightRed + "Aborted checking for plugins." + oColors.standardWhite) 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'): def updateInstalledPackage(inputSelectedObject='all'):
configValues = configurationValues()
createPluginList() createPluginList()
if not checkConfig().localPluginFolder: if not configValues.localPluginFolder:
sftp = createSFTPConnection() sftp = createSFTPConnection()
pluginList = sftp_listAll(sftp) pluginList = sftp_listAll(sftp)
else: else:
pluginList = os.listdir(checkConfig().pathToPluginFolder) pluginList = os.listdir(configValues.pathToPluginFolder)
i = 0 i = 0
pluginsUpdated = 0 pluginsUpdated = 0
print(f"Updating: {inputSelectedObject}") indexNumberUpdated = 0
print("Index | Name | Old V. | New V.") print(oColors.brightBlack + f"Updating: {inputSelectedObject}" + oColors.standardWhite)
print("┌─────┬────────────────────────────────┬────────────┬──────────┐")
print("│ No. │ Name │ Old V. │ New V. │")
print("└─────┴────────────────────────────────┴────────────┴──────────┘")
try: try:
for plugin in pluginList: for plugin in track(pluginList, description="Updating" ,transient=True, complete_style="bright_magenta"):
try: try:
fileName = getFileName(plugin) fileName = getFileName(plugin)
fileVersion = getFileVersion(plugin) fileVersion = getFileVersion(plugin)
pluginId = getInstalledPlugin(fileName, fileVersion) pluginId = getInstalledPlugin(fileName, fileVersion)
latestVersion = getLatestPluginVersion(pluginId) latestVersion = getLatestPluginVersion(pluginId)
except TypeError: except TypeError:
i += 1
continue continue
except ValueError: except ValueError:
i += 1
continue continue
pluginIdStr = str(pluginId) pluginIdStr = str(pluginId)
if pluginId == None or pluginId == '':
if pluginId == None:
print(oColors.brightRed + "Couldn't find plugin id. Sorry :(" + oColors.standardWhite) print(oColors.brightRed + "Couldn't find plugin id. Sorry :(" + oColors.standardWhite)
continue continue
if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE): if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE):
if INSTALLEDPLUGINLIST[i][3] == True: if INSTALLEDPLUGINLIST[i][3] == True:
print(f" [{pluginsUpdated+1}]".ljust(8), end='') print(f" [{indexNumberUpdated+1}]".rjust(6), end='')
print(f"{fileName}".ljust(30), end='') print(" ", end='')
print(f"{fileVersion}".ljust(8), end='') print(f"{fileName}".ljust(33), end='')
print(" ", end='') print(f"{fileVersion}".ljust(13), end='')
print(f"{latestVersion}".ljust(8)) #print(" ", end='')
print(f"{latestVersion}".ljust(13))
if not checkConfig().localPluginFolder: if not configValues.localPluginFolder:
pluginPath = checkConfig().sftp_folderPath if configValues.sftp_seperateDownloadPath is True:
pluginPath = f"{pluginPath}\\{plugin}" pluginPath = configValues.sftp_pathToSeperateDownloadPath
else:
pluginPath = configValues.sftp_folderPath
pluginPath = Path(f"{pluginPath}/{plugin}")
sftp = createSFTPConnection() sftp = createSFTPConnection()
sftp.remove(pluginPath) indexNumberUpdated += 1
getSpecificPackage(pluginId, checkConfig().sftp_folderPath)
pluginsUpdated += 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: else:
pluginPath = checkConfig().pathToPluginFolder if configValues.seperateDownloadPath is True:
pluginPath = f"{pluginPath}\\{plugin}" pluginPath = configValues.pathToSeperateDownloadPath
os.remove(pluginPath) else:
getSpecificPackage(pluginId, checkConfig().pathToPluginFolder) pluginPath = configValues.pathToPluginFolder
pluginPath = Path(f"{pluginPath}/{plugin}")
indexNumberUpdated += 1
pluginsUpdated += 1 pluginsUpdated += 1
try:
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)
pluginsUpdated -= 1
except FileNotFoundError:
print(oColors.brightRed + f"Error: Old plugin file coulnd't be deleted" + oColors.standardWhite)
break break
else: else:
print(f"{fileName} is already on {latestVersion}") print(f"{fileName} is already on {latestVersion}")
@@ -175,44 +244,66 @@ def updateInstalledPackage(inputSelectedObject='all'):
if inputSelectedObject == 'all': if inputSelectedObject == 'all':
if INSTALLEDPLUGINLIST[i][3] == True: if INSTALLEDPLUGINLIST[i][3] == True:
print(f" [{pluginsUpdated+1}]".ljust(8), end='') print(f" [{indexNumberUpdated+1}]".rjust(6), end='')
print(f"{fileName}".ljust(30), end='') print(" ", end='')
print(f"{fileVersion}".ljust(8), end='') print(f"{fileName}".ljust(33), end='')
print(" ", end='') print(f"{fileVersion}".ljust(13), end='')
print(f"{latestVersion}".ljust(8)) #print(" ", end='')
print(f"{latestVersion}".ljust(13))
if not checkConfig().localPluginFolder: if not configValues.localPluginFolder:
pluginPath = checkConfig().sftp_folderPath if configValues.sftp_seperateDownloadPath is True:
pluginPath = f"{pluginPath}\\{plugin}" pluginPath = configValues.sftp_pathToSeperateDownloadPath
else:
pluginPath = configValues.sftp_folderPath
pluginPath = f"{pluginPath}/{plugin}"
sftp = createSFTPConnection() sftp = createSFTPConnection()
sftp.remove(pluginPath) indexNumberUpdated += 1
getSpecificPackage(pluginId, checkConfig().sftp_folderPath)
pluginsUpdated += 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 + f"Error: Old plugin file coulnd't be deleted" + oColors.standardWhite)
else: else:
pluginPath = checkConfig().pathToPluginFolder if configValues.seperateDownloadPath is True:
pluginPath = f"{pluginPath}\\{plugin}" pluginPath = configValues.pathToSeperateDownloadPath
os.remove(pluginPath) else:
getSpecificPackage(pluginId, checkConfig().pathToPluginFolder) pluginPath = configValues.pathToPluginFolder
pluginPath = Path(f"{pluginPath}/{plugin}")
indexNumberUpdated += 1
pluginsUpdated += 1 pluginsUpdated += 1
try:
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)
pluginsUpdated -= 1
except FileNotFoundError:
print(oColors.brightRed + f"Error: Old plugin file coulnd't be deleted" + oColors.standardWhite)
i = i + 1 i = i + 1
except TypeError: except TypeError:
print(oColors.brightRed + "Aborted updating for plugins." + oColors.standardWhite) print(oColors.brightRed + "Error occured: Aborted updating for plugins." + oColors.standardWhite)
print(f"[{pluginsUpdated}/{i}] Plugins updated") print(oColors.brightYellow + f"Plugins updated: [{pluginsUpdated}/{i}]" + oColors.standardWhite)
if inputSelectedObject =='all' and pluginsUpdated == 0: if inputSelectedObject =='all' and pluginsUpdated == 0:
print(oColors.brightGreen + "All plugins are on the latest version!" + oColors.standardWhite) print(oColors.brightGreen + "All found plugins are on the latest version!" + oColors.standardWhite)
def getInstalledPlugin(localFileName, localFileVersion): def getInstalledPlugin(localFileName, localFileVersion):
url = "https://api.spiget.org/v2/search/resources/" + localFileName + "?field=name&sort=-downloads" url = "https://api.spiget.org/v2/search/resources/" + localFileName + "?field=name&sort=-downloads"
packageName = doAPIRequest(url) packageName = doAPIRequest(url)
i = 1
plugin_match_found = False plugin_match_found = False
pluginID = None pluginID = None
for ressource in packageName: for ressource in packageName:
if plugin_match_found == True: if plugin_match_found == True:
break break
pID = ressource["id"] pID = ressource["id"]
url2 = f"https://api.spiget.org/v2/resources/{pID}/versions?size=100&sort=-name" url2 = f"https://api.spiget.org/v2/resources/{pID}/versions?size=100&sort=-name"
packageVersions = doAPIRequest(url2) packageVersions = doAPIRequest(url2)
@@ -225,22 +316,14 @@ def getInstalledPlugin(localFileName, localFileVersion):
plugin_latest_version = getLatestPluginVersion(pID) plugin_latest_version = getLatestPluginVersion(pID)
plugin_is_outdated = compareVersions(plugin_latest_version, updateVersion) plugin_is_outdated = compareVersions(plugin_latest_version, updateVersion)
addToPluginList(pID, updateId, plugin_latest_version , plugin_is_outdated) addToPluginList(pID, updateId, plugin_latest_version , plugin_is_outdated)
break return pluginID
i = i + 1
else: else:
pID = None if plugin_match_found != True:
updateId = None pID = None
plugin_latest_version = None updateId = None
plugin_is_outdated = None plugin_latest_version = None
addToPluginList(pID, updateId, plugin_latest_version , plugin_is_outdated) plugin_is_outdated = None
addToPluginList(pID, updateId, plugin_latest_version , plugin_is_outdated)
return pluginID return pluginID
# start query
# get id
# search with id for all version upates
# get version that matches installed version
# if match then download latest update
# else get second query

View File

View File

@@ -0,0 +1,117 @@
import os
import sys
from urllib.error import HTTPError
from pathlib import Path
from handlers.handle_sftp import createSFTPConnection, sftp_listFilesInServerRoot
from handlers.handle_config import configurationValues
from utils.consoleoutput import oColors
from serverjar.serverjar_paper import paperCheckForUpdate, papermc_downloader
def checkInstalledServerjar():
configValues = configurationValues()
if not configValues.localPluginFolder:
sftp = createSFTPConnection()
serverRootList = sftp_listFilesInServerRoot(sftp)
else:
serverRootList = os.path.dirname(configValues.pathToPluginFolder)
serverRootList = os.listdir(serverRootList)
installedServerjarFullName = None
try:
for files in serverRootList:
try:
if '.jar' in files:
installedServerjarFullName = files
break
except TypeError:
continue
except TypeError:
print(oColors.brightRed + "Serverjar couldn't be found." + oColors.standardWhite)
print(oColors.brightRed + "Aborting the process." + oColors.standardWhite)
if installedServerjarFullName == None:
print(oColors.brightRed + "Serverjar couldn't be found." + oColors.standardWhite)
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)
else:
print(oColors.brightRed + f"{installedServerjarFullName} isn't supported.")
print(oColors.brightRed + "Aborting the process." + oColors.standardWhite)
def updateServerjar(serverJarBuild='latest'):
configValues = configurationValues()
try:
if serverJarBuild == None:
serverJarBuild = 'latest'
if not configValues.localPluginFolder:
sftp = createSFTPConnection()
serverRootPath = configValues.sftp_folderPath
serverRootPath = Path(str(serverRootPath).replace(r'/plugins', ''))
serverRootList = sftp_listFilesInServerRoot(sftp)
else:
serverRoot = os.path.dirname(configValues.pathToPluginFolder)
serverRootList = os.listdir(serverRoot)
serverRootPath = configValues.pathToPluginFolder
helpPath = Path('/plugins')
helpPathstr = str(helpPath)
serverRootPath = Path(str(serverRootPath).replace(helpPathstr, ''))
installedServerjarFullName = None
except FileNotFoundError:
print(oColors.brightRed + "Path couldn't be found!" + oColors.standardWhite)
print(oColors.brightRed + "Check your config!" + oColors.standardWhite)
print(oColors.brightRed + "Aborting the process." + oColors.standardWhite)
input("Press any key + enter to exit...")
sys.exit()
try:
for files in serverRootList:
try:
if '.jar' in files:
installedServerjarFullName = files
break
except TypeError:
continue
except TypeError:
print(oColors.brightRed + "Serverjar couldn't be found." + oColors.standardWhite)
print(oColors.brightRed + "Aborting the process." + oColors.standardWhite)
if installedServerjarFullName == None:
print(oColors.brightRed + "Serverjar couldn't be found." + oColors.standardWhite)
print(oColors.brightRed + "Aborting the process." + oColors.standardWhite)
input("Press any key + enter to exit...")
sys.exit()
serverJarPath = Path(f"{serverRootPath}/{installedServerjarFullName}")
if 'paper' in installedServerjarFullName:
print(oColors.brightBlack + f"Updating Paper to build: {serverJarBuild}" + oColors.standardWhite)
if not configValues.localPluginFolder:
try:
papermc_downloader(serverJarBuild, installedServerjarFullName)
sftp.remove(serverJarPath)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
except FileNotFoundError:
print(oColors.brightRed + "Error: Old serverjar file coulnd't be deleted" + oColors.standardWhite)
else:
try:
papermc_downloader(serverJarBuild, installedServerjarFullName)
os.remove(serverJarPath)
except HTTPError as err:
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
except FileNotFoundError:
print(oColors.brightRed + "Error: Old serverjar file coulnd't be deleted" + oColors.standardWhite)
else:
print(oColors.brightRed + f"{installedServerjarFullName} isn't supported.")
print(oColors.brightRed + "Aborting the process." + oColors.standardWhite)

View File

@@ -0,0 +1,173 @@
import os
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 configurationValues
from utils.utilities import createTempPluginFolder, deleteTempPluginFolder, calculateFileSizeMb
# = 1.16.5
def getInstalledPaperMinecraftVersion(localPaperName):
mcVersionFull = re.search(r'(\d*\.*\d)+', localPaperName)
try:
mcVersion = mcVersionFull.group()
except AttributeError:
mcVersion = mcVersionFull
return mcVersion
# = 550
def getInstalledPaperVersion(localPaperName):
paperBuildFull = re.search(r'([\d]*.jar)', localPaperName)
try:
paperBuild = paperBuildFull.group()
except AttributeError:
paperBuild = paperBuildFull
paperBuild = paperBuild.replace('.jar', '')
return paperBuild
def findVersionGroup(mcVersion):
versionGroups = ['1.16', '1.15']
versionGroupFound = 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
if versionGroup == mcVersion:
versionGroupFound = True
paperVersionGroup = versionGroup
break
return paperVersionGroup
def findBuildVersion(wantedPaperBuild):
versionGroups = ['1.16', '1.15']
paperBuildFound = 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
def findLatestBuild(paperVersionGroup):
url = f"https://papermc.io/api/v2/projects/paper/version_group/{paperVersionGroup}/builds"
papermcbuilds = doAPIRequest(url)
latestPaperBuild = papermcbuilds["builds"][-1]["build"]
return latestPaperBuild
def findLatestBuildForVersion(mcVersion):
url = f"https://papermc.io/api/v2/projects/paper/versions/{mcVersion}"
papermcbuilds = doAPIRequest(url)
latestPaperBuild = papermcbuilds["builds"][-1]
return latestPaperBuild
def versionBehind(installedPaperBuild, latestPaperBuild):
installedPaperBuildint = int(installedPaperBuild)
latestPaperBuildint = int(latestPaperBuild)
versionsBehind = latestPaperBuildint - installedPaperBuildint
return versionsBehind
def getDownloadFileName(paperMcVersion, paperBuild):
url = f"https://papermc.io/api/v2/projects/paper/versions/{paperMcVersion}/builds/{paperBuild}"
buildDetails = doAPIRequest(url)
downloadName = buildDetails["downloads"]["application"]["name"]
return downloadName
def paperCheckForUpdate(installedServerjarFullName):
mcVersion = getInstalledPaperMinecraftVersion(installedServerjarFullName)
paperInstalledBuild = getInstalledPaperVersion(installedServerjarFullName)
versionGroup = findVersionGroup(mcVersion)
paperLatestBuild = findLatestBuild(versionGroup)
paperVersionBehind = versionBehind(paperInstalledBuild, paperLatestBuild)
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):
configValues = configurationValues()
if configValues.localPluginFolder == False:
downloadPath = createTempPluginFolder()
else:
downloadPath = configValues.pathToPluginFolder
helpPath = Path('/plugins')
helpPathstr = str(helpPath)
downloadPath = Path(str(downloadPath).replace(helpPathstr, ''))
if mcVersion == None:
if paperBuild == 'latest':
mcVersion = '1.16.5'
else:
mcVersion = findBuildVersion(paperBuild)
if installedServerjarName != None:
mcVersion = getInstalledPaperMinecraftVersion(installedServerjarName)
if paperBuild == 'latest':
paperBuild = findLatestBuildForVersion(mcVersion)
try:
downloadFileName = getDownloadFileName(mcVersion, paperBuild)
except KeyError:
print(oColors.brightRed + f"This version wasn't found for {mcVersion}" + oColors.standardWhite)
print(oColors.brightRed + f"Reverting to latest version for {mcVersion}" + oColors.standardWhite)
paperBuild = findLatestBuildForVersion(mcVersion)
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}"
remotefile = urllib.request.urlopen(url)
filesize = remotefile.info()['Content-Length']
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:
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)

View File

@@ -13,11 +13,11 @@ def clearConsole():
# https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences # https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
class oColors: class oColors:
standardWhite = "\033[0m" standardWhite = "\033[0m"
brightYellow = "\033[93m" brightBlack = "\033[90m"
brightMagenta = "\033[95m"
brightRed = "\033[91m" brightRed = "\033[91m"
brightGreen = "\033[92m" brightGreen = "\033[92m"
darkMagenta = "\033[35m" brightYellow = "\033[93m"
brightMagenta = "\033[95m"
def printLogo(): def printLogo():
@@ -72,9 +72,12 @@ def printLogo():
oColors.standardWhite) oColors.standardWhite)
print() print()
print() print()
print(oColors.brightYellow + " [" + oColors.darkMagenta + "By Neocky" + print(oColors.brightBlack + " ┌────────────────────────────────────┐" + oColors.standardWhite)
oColors.brightYellow + "] " + oColors.standardWhite) print(oColors.brightBlack + " [" + oColors.brightMagenta + "By Neocky" +oColors.brightBlack +
print() "] │ " + oColors.standardWhite)
print(oColors.brightBlack + "" + oColors.brightMagenta + "https://github.com/Neocky/pluGET" + oColors.brightBlack +
"" + oColors.standardWhite)
print(oColors.brightBlack + " └────────────────────────────────────┘" + oColors.standardWhite)
def printHorizontalLine(): def printHorizontalLine():

View File

@@ -3,33 +3,116 @@ import os
import sys import sys
import shutil import shutil
import requests import requests
from pathlib import Path
from utils.consoleoutput import oColors 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_sftp import createSFTPConnection
def getHelp(): def getHelp():
print(oColors.brightYellow+ "Need help?" + oColors.standardWhite) print(oColors.brightYellow+ "Need help?" + oColors.standardWhite)
print("Check the docs here:") print("For a list of all commands: 'help command'")
print("Or check the docs here:")
print("https://github.com/Neocky/pluGET") print("https://github.com/Neocky/pluGET")
print("Or go to the official discord.") print("Or go to the official discord.")
print("The link for discord can also be found on Github!") print("The link for discord can also be found on Github!")
def getCommandHelp(optionalParams):
if optionalParams == None:
optionalParams = 'all'
print(oColors.brightBlack + f"Help for command: {optionalParams}" +oColors.standardWhite)
print("┌────────────────┬─────────────────┬─────────────────┬────────────────────────────────────────────────────────┐")
print("│ Command │ Selected Object │ Optional Params │ Function │")
print("└────────────────┴─────────────────┴─────────────────┴────────────────────────────────────────────────────────┘")
while True:
if optionalParams == 'all':
print(oColors.brightBlack + " GENERAL:" + oColors.standardWhite)
print(" exit ./anything Exit pluGET")
print(" help ./anything Get general help")
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(" 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")
print(oColors.brightBlack + " SERVER SOFTWARE MANAGEMENT:" + oColors.standardWhite)
print(" check serverjar Check installed server software for an update")
print(" update serverjar Version/Latest Update installed server software to a specific version")
print(" get-paper PaperVersion McVersion Downloads a specific PaperMc version")
break
if optionalParams == 'exit':
print(oColors.brightBlack + " GENERAL:" + oColors.standardWhite)
print(" exit ./anything Exit pluGET")
break
if optionalParams == 'help':
print(oColors.brightBlack + " GENERAL:" + oColors.standardWhite)
print(" help ./anything Get general help")
print(" help command all/command Get specific help to the commands of pluGET")
break
if optionalParams == 'get':
print(oColors.brightBlack + " PLUGIN MANAGEMENT:" + oColors.standardWhite)
print(print(" get Name/ID Version Downloads the latest version of a plugin"))
break
if optionalParams == 'check':
print(oColors.brightBlack + " PLUGIN MANAGEMENT:" + oColors.standardWhite)
print(" check Name/ID/all Check for an update of an installed plugin")
print(oColors.brightBlack + " SERVER SOFTWARE MANAGEMENT:" + oColors.standardWhite)
print(" check serverjar Check installed server software for an update")
break
if optionalParams == 'update':
print(oColors.brightBlack + " PLUGIN MANAGEMENT:" + oColors.standardWhite)
print(" update Name/ID/all Update installed plugins to the latest version")
print(oColors.brightBlack + " SERVER SOFTWARE MANAGEMENT:" + oColors.standardWhite)
print(" update serverjar Version/Latest Update installed server software to a specific version")
break
if optionalParams == 'search':
print(oColors.brightBlack + " PLUGIN MANAGEMENT:" + oColors.standardWhite)
print(" search Name Search for a plugin and download the latest version")
break
if optionalParams == 'remove':
print(oColors.brightBlack + " PLUGIN MANAGEMENT:" + oColors.standardWhite)
print(" remove Name/ID Delete an installed plugin")
break
if optionalParams == 'get-paper':
print(oColors.brightBlack + " SERVER SOFTWARE MANAGEMENT:" + oColors.standardWhite)
print(" get-paper PaperVersion McVersion Downloads a specific PaperMc version")
break
else:
print(oColors.brightRed + "Error: Help for Command not found. Please try again. :(" + oColors.standardWhite)
break
def check_local_plugin_folder(): def check_local_plugin_folder():
if checkConfig().localPluginFolder: configValues = configurationValues()
if not os.path.isdir(checkConfig().pathToPluginFolder): if configValues.localPluginFolder:
if configValues.seperateDownloadPath:
pluginFolderPath = configValues.pathToSeperateDownloadPath
else:
pluginFolderPath = configValues.pathToPluginFolder
if not os.path.isdir(pluginFolderPath):
print(oColors.brightRed + "Plugin folder coulnd*t be found. Creating one..." + oColors.standardWhite) print(oColors.brightRed + "Plugin folder coulnd*t be found. Creating one..." + oColors.standardWhite)
try: try:
os.mkdir(checkConfig().pathToPluginFolder) os.mkdir(pluginFolderPath)
except OSError: except OSError:
print(oColors.brightRed + "Creation of directory %s failed" % checkConfig().pathToPluginFolder) print(oColors.brightRed + "Creation of directory %s failed" % pluginFolderPath)
print(oColors.brightRed + "Please check the config file!" + oColors.standardWhite) print(oColors.brightRed + "Please check the config file!" + oColors.standardWhite)
input("Press any key + enter to exit...") input("Press any key + enter to exit...")
sys.exit() sys.exit()
else: else:
print("Created directory %s" % checkConfig().pathToPluginFolder) print("Created directory %s" % pluginFolderPath)
def apiTest(): def apiTest():
@@ -47,14 +130,15 @@ def apiTest():
def check_requirements(): def check_requirements():
configValues = configurationValues()
apiTest() apiTest()
check_local_plugin_folder() check_local_plugin_folder()
if not checkConfig().localPluginFolder: if not configValues.localPluginFolder:
createSFTPConnection() createSFTPConnection()
def createTempPluginFolder(): def createTempPluginFolder():
tempPluginFolder = ".\\plugins" tempPluginFolder = Path("./TempSFTPUploadFolder")
if not os.path.isdir(tempPluginFolder): if not os.path.isdir(tempPluginFolder):
try: try:
os.mkdir(tempPluginFolder) os.mkdir(tempPluginFolder)
@@ -71,3 +155,16 @@ def deleteTempPluginFolder(tempPluginFolder):
shutil.rmtree(tempPluginFolder) shutil.rmtree(tempPluginFolder)
except OSError as e: except OSError as e:
print ("Error: %s - %s." % (e.filename, e.strerror)) print ("Error: %s - %s." % (e.filename, e.strerror))
def calculateFileSizeMb(downloadFileSize):
fileSizeDownload = int(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