mirror of
https://github.com/Neocky/pluGET.git
synced 2024-04-29 16:12:30 +00:00
Compare commits
69 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2e459cafe2 | ||
![]() |
1ff34a7372 | ||
![]() |
367ee5be42 | ||
![]() |
abf07e8301 | ||
![]() |
c551c6bd66 | ||
![]() |
572a7de68a | ||
![]() |
2b00942749 | ||
![]() |
50038c4474 | ||
![]() |
2eb4940574 | ||
![]() |
496334a2fa | ||
![]() |
42be836928 | ||
![]() |
1e7b30a1be | ||
![]() |
a4b1b7acf9 | ||
![]() |
8344ed0afc | ||
![]() |
2a416bbbc2 | ||
![]() |
456a0e185a | ||
![]() |
f4361ad137 | ||
![]() |
41527926b2 | ||
![]() |
93818b90d7 | ||
![]() |
2712bd5be6 | ||
![]() |
3ad7753674 | ||
![]() |
38edfc73d6 | ||
![]() |
a4636153c0 | ||
![]() |
764e8bcb81 | ||
![]() |
26d7965422 | ||
![]() |
78f38f36cd | ||
![]() |
afbc3e8029 | ||
![]() |
a08aab7ae4 | ||
![]() |
b31cca5e31 | ||
![]() |
cd4a66002c | ||
![]() |
0d709cfb6f | ||
![]() |
edc300a33d | ||
![]() |
11b4fdcbeb | ||
![]() |
716227eafa | ||
![]() |
6e980a1580 | ||
![]() |
cb0282e676 | ||
![]() |
1dad1c62cd | ||
![]() |
91a5e84028 | ||
![]() |
60a41015e6 | ||
![]() |
706b8049c3 | ||
![]() |
927767b0aa | ||
![]() |
2a7372dae1 | ||
![]() |
31a2a4aa89 | ||
![]() |
aceca0dec3 | ||
![]() |
205a13ee94 | ||
![]() |
fddc0c252c | ||
![]() |
17611c741e | ||
![]() |
e8e46bb014 | ||
![]() |
5086b36aa3 | ||
![]() |
2a481acbef | ||
![]() |
5b68181661 | ||
![]() |
9b628498f1 | ||
![]() |
d40ee52da1 | ||
![]() |
e66985054c | ||
![]() |
e1efcc4fc7 | ||
![]() |
1147d4f29c | ||
![]() |
ebb04085d3 | ||
![]() |
e161d2c2f9 | ||
![]() |
01465eb769 | ||
![]() |
d478432396 | ||
![]() |
d7fc68195b | ||
![]() |
e87729f700 | ||
![]() |
01b9a52b40 | ||
![]() |
76e1d7f5fd | ||
![]() |
430dbcd8d2 | ||
![]() |
5e296e858f | ||
![]() |
20261d110e | ||
![]() |
932ae66827 | ||
![]() |
1e7de3ac5a |
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
custom: https://www.buymeacoffee.com/Neocky # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
6
.gitignore
vendored
6
.gitignore
vendored
@@ -127,3 +127,9 @@ dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# VSCode Settings
|
||||
.vscode
|
||||
|
||||
# PyCharm Settings
|
||||
.idea
|
||||
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"python.linting.pylintEnabled": true,
|
||||
"python.linting.enabled": true
|
||||
}
|
200
README.md
200
README.md
@@ -5,20 +5,37 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.python.org/"> <img src="https://forthebadge.com/images/badges/made-with-python.svg" alt="madewithpython" border="0"></a>
|
||||
<a href="https://www.python.org/"> <img src="https://img.shields.io/badge/made%20with-python%20%F0%9F%90%8D-brightgreen" alt="madewithpython" border="0"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<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/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/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://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>
|
||||
|
||||
|
||||
# pluGET
|
||||
[](http://hits.dwyl.com/Neocky/pluGET)
|
||||
A powerfull package manager which handles [Plugins](https://www.spigotmc.org/resources/) for minecraft servers.
|
||||
# pluGET
|
||||
#### 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/06/27/ezgif-1-28e102202188.gif" alt="pluGET.gif" border="0" />
|
||||
|
||||
<details>
|
||||
<summary>Screenshots</summary>
|
||||
|
||||
`check all` to check installed plugins for updates:
|
||||

|
||||
|
||||
`check all` with more plugins:
|
||||

|
||||
|
||||
`help command` list all available commands:
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
<img src="https://i.ibb.co/82dnyrK/image.png" alt="meme" border="0" height="350" width="350"></a>
|
||||
|
||||
|
||||
## Issues? Found a bug?
|
||||
@@ -28,10 +45,11 @@ A powerfull package manager which handles [Plugins](https://www.spigotmc.org/res
|
||||
## 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 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 resource](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.
|
||||
@@ -43,11 +61,17 @@ 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
|
||||
- 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
|
||||
- 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
|
||||
- manage server software:
|
||||
- download a specific server software version
|
||||
- check installed 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.
|
||||
|
||||
@@ -62,32 +86,73 @@ 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
|
||||
Execute the `launcher.bat` in the `\pluGET` folder. This will launch pluGET correctly.
|
||||
Another way is to launch the `src\__main__.py` file.
|
||||
> As always, if you update plugins, shut down your server!
|
||||
|
||||
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>
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
### Manage Plugins
|
||||
#### Download the latest update of a specific package:
|
||||
`get [pluginID/pluginName]`
|
||||
```
|
||||
@@ -97,15 +162,24 @@ or:
|
||||
```
|
||||
get 'pluginName'
|
||||
```
|
||||
#### Check all plugins/one specific plugin for updates:
|
||||
`check [all/pluginName]`
|
||||
#### Check all plugins/one specific plugin for updates with optional changelog output:
|
||||
`check [all/pluginName] [changelog]`
|
||||
```
|
||||
check all
|
||||
```
|
||||
or:
|
||||
```
|
||||
check 'pluginName'
|
||||
check 'pluginName' changelog
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Output</summary>
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
|
||||
#### Update all plugins/one specific plugin:
|
||||
`update [all/pluginName]`
|
||||
```
|
||||
@@ -139,37 +213,49 @@ exit .
|
||||
```
|
||||
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
|
||||
### Can't get installed version
|
||||
For example:
|
||||
```
|
||||
pluGET >> check all
|
||||
Checking: all
|
||||
Index | Name | Installed V. | Latest V. | Update available
|
||||
[1] Vault N/A 1.7.3 False
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
### Can't get latest version/Update available
|
||||
|
||||
#### Inconsistent Names and Versions
|
||||
For example:
|
||||

|
||||
EssentialsX is a prominent example of inconsisten version naming. The installed version is `2.18.2.0` but on [Spigot](https://www.spigotmc.org/resources/essentialsx.9089/update?update=371379) the version is only described as `2.18.2`.
|
||||
That's the reason pluGET can't detect it automatically.
|
||||
> There are of course many more plugins which have some sort of inconsistency which makes it sadly impossible for pluGET to detect them all. EssentialsX is used only as an example.
|
||||
|
||||
#### Solution
|
||||
Download the plugins with the `get [pluginName]` command to make them detectable for pluGET.
|
||||
After downloading EssentialsX with `get EssentialsX` and using `check all`:
|
||||

|
||||
EssentialsX is now detected from pluGET and can update automatically when a new version comes out.
|
||||
|
||||
#### Bukkit plugins
|
||||
For example:
|
||||

|
||||
As you can see the installed version was found but not the latest version for this plugin.
|
||||
This is because this is a plugin which is not available on [Spigot](https://www.spigotmc.org/resources/).
|
||||
pluGET supports currently only plugins from [Spigot](https://www.spigotmc.org/resources/).
|
||||
In this example this is a bukkit plugin.
|
||||
|
||||
|
34
installer.bat
Normal file
34
installer.bat
Normal 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 [93mInstalling Python packages and dependencies...[0m
|
||||
|
||||
py -m pip install -r requirements.txt
|
||||
|
||||
Echo `
|
||||
Echo [92mLaunching pluGET...[0m
|
||||
|
||||
launcher.bat
|
||||
|
||||
exit
|
2
launcher.sh
Normal file
2
launcher.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
cd src/
|
||||
python3 "__main__.py"
|
@@ -7,4 +7,8 @@ pynacl >= 1.4.0
|
||||
cffi >= 1.14.5
|
||||
six >= 1.15.0
|
||||
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
|
@@ -1,10 +1,7 @@
|
||||
from utils.consoleoutput import consoleTitle, clearConsole, printMainMenu, oColors
|
||||
from utils.utilities import getHelp, check_requirements
|
||||
from utils.consoleoutput import consoleTitle, clearConsole, printMainMenu
|
||||
from utils.utilities import check_requirements
|
||||
from handlers.handle_input import createInputLists, getInput
|
||||
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():
|
||||
|
@@ -1,79 +1,87 @@
|
||||
import os
|
||||
import sys
|
||||
import configparser
|
||||
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()
|
||||
os.chdir('..')
|
||||
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 = config['General']['PathToPluginFolder']
|
||||
seperateDownloadPath = config['General']['SeperateDownloadPath']
|
||||
pathToSeperateDownloadPath = 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:
|
||||
with open('config.ini', 'w') as configfile:
|
||||
config.write(configfile)
|
||||
|
116
src/handlers/handle_ftp.py
Normal file
116
src/handlers/handle_ftp.py
Normal file
@@ -0,0 +1,116 @@
|
||||
import os
|
||||
import sys
|
||||
import ftplib
|
||||
import stat
|
||||
import re
|
||||
|
||||
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()
|
||||
if configValues.sftp_seperateDownloadPath is True:
|
||||
uploadFolderPath = configValues.sftp_pathToSeperateDownloadPath
|
||||
else:
|
||||
uploadFolderPath = configValues.sftp_folderPath
|
||||
try:
|
||||
ftp.cwd(uploadFolderPath)
|
||||
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:
|
||||
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()
|
||||
|
||||
|
||||
def ftp_is_file(ftp, pluginPath):
|
||||
if ftp.nlst(pluginPath) == [pluginPath]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def ftp_validateFileAttributes(ftp, pluginPath):
|
||||
if ftp_is_file(ftp, pluginPath) is False:
|
||||
return False
|
||||
if re.search(r'.jar$', pluginPath):
|
||||
return True
|
||||
else:
|
||||
return False
|
@@ -1,11 +1,14 @@
|
||||
import sys
|
||||
|
||||
from utils.consoleoutput import oColors
|
||||
from utils.utilities import getHelp
|
||||
from handlers.handle_config import checkConfig
|
||||
from utils.utilities import getHelp, getCommandHelp
|
||||
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
|
||||
from serverjar.serverjar_checker import checkInstalledServerjar, updateServerjar
|
||||
from serverjar.serverjar_paper import papermc_downloader
|
||||
|
||||
|
||||
def createInputLists():
|
||||
global COMMANDLIST
|
||||
@@ -16,7 +19,8 @@ def createInputLists():
|
||||
'search',
|
||||
'exit',
|
||||
'help',
|
||||
'remove'
|
||||
'remove',
|
||||
'get-paper'
|
||||
]
|
||||
global INPUTSELECTEDOBJECT
|
||||
INPUTSELECTEDOBJECT = [
|
||||
@@ -26,31 +30,38 @@ 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:
|
||||
searchPackage(inputSelectedObject)
|
||||
break
|
||||
if inputCommand == 'update':
|
||||
updateInstalledPackage(inputSelectedObject)
|
||||
if inputSelectedObject == 'serverjar':
|
||||
updateServerjar(inputParams)
|
||||
else:
|
||||
updateInstalledPackage(inputSelectedObject)
|
||||
break
|
||||
if inputCommand == 'check':
|
||||
checkInstalledPackage(inputSelectedObject)
|
||||
if inputSelectedObject == 'serverjar':
|
||||
checkInstalledServerjar()
|
||||
else:
|
||||
checkInstalledPackage(inputSelectedObject, inputParams)
|
||||
break
|
||||
if inputCommand == 'search':
|
||||
searchPackage(inputSelectedObject)
|
||||
@@ -58,24 +69,37 @@ def handleInput(inputCommand, inputSelectedObject, inputParams):
|
||||
if inputCommand == 'exit':
|
||||
sys.exit()
|
||||
if inputCommand == 'help':
|
||||
getHelp()
|
||||
if inputSelectedObject == 'command' or inputSelectedObject == 'commands':
|
||||
getCommandHelp(inputParams)
|
||||
else:
|
||||
getHelp()
|
||||
break
|
||||
if inputCommand == 'remove':
|
||||
removePlugin(inputSelectedObject)
|
||||
break
|
||||
if inputCommand == 'get-paper':
|
||||
papermc_downloader(inputSelectedObject, inputParams)
|
||||
break
|
||||
else:
|
||||
print(oColors.brightRed + "Command not found. Please try again." + oColors.standardWhite)
|
||||
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)
|
||||
|
||||
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)
|
||||
|
@@ -1,17 +1,21 @@
|
||||
import sys
|
||||
import os
|
||||
import pysftp
|
||||
import paramiko
|
||||
import stat
|
||||
import re
|
||||
|
||||
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:
|
||||
@@ -25,35 +29,79 @@ def createSFTPConnection():
|
||||
|
||||
|
||||
def sftp_showPlugins(sftp):
|
||||
sftp.cd('plugins')
|
||||
configValues = configurationValues()
|
||||
sftp.cd(configValues.sftp_folderPath)
|
||||
for attr in sftp.listdir_attr():
|
||||
print(attr.filename, attr)
|
||||
|
||||
|
||||
def sftp_cdPluginDir(sftp):
|
||||
sftp.cd('plugins')
|
||||
|
||||
|
||||
def sftp_upload_file(sftp, itemPath):
|
||||
configValues = configurationValues()
|
||||
if configValues.sftp_seperateDownloadPath is True:
|
||||
uploadFolderPath = configValues.sftp_pathToSeperateDownloadPath
|
||||
else:
|
||||
uploadFolderPath = configValues.sftp_folderPath
|
||||
try:
|
||||
sftp.chdir('plugins')
|
||||
sftp.chdir(uploadFolderPath)
|
||||
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()
|
||||
|
||||
|
||||
def sftp_upload_server_jar(sftp, itemPath):
|
||||
try:
|
||||
sftp.chdir('.')
|
||||
sftp.put(itemPath)
|
||||
except FileNotFoundError:
|
||||
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()
|
||||
|
||||
|
||||
def sftp_listAll(sftp):
|
||||
configValues = configurationValues()
|
||||
try:
|
||||
sftp.chdir('plugins')
|
||||
sftp.chdir(configValues.sftp_folderPath)
|
||||
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:
|
||||
filesInServerRoot = sftp.listdir()
|
||||
except FileNotFoundError:
|
||||
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 + "[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)
|
||||
|
||||
|
||||
def sftp_validateFileAttributes(sftp, pluginPath):
|
||||
pluginSFTPAttribute = sftp.lstat(pluginPath)
|
||||
if stat.S_ISDIR(pluginSFTPAttribute.st_mode):
|
||||
return False
|
||||
elif re.search(r'.jar$', pluginPath):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
@@ -1,19 +1,14 @@
|
||||
import re
|
||||
import urllib.request
|
||||
from urllib.error import HTTPError
|
||||
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):
|
||||
@@ -56,81 +51,98 @@ def getVersionName(packageId, versionId):
|
||||
return versionName
|
||||
|
||||
|
||||
def searchPackage(ressourceName):
|
||||
url = f"https://api.spiget.org/v2/search/resources/{ressourceName}?field=name&sort=-downloads"
|
||||
def searchPackage(resourceName):
|
||||
configValues = configurationValues()
|
||||
url = f"https://api.spiget.org/v2/search/resources/{resourceName}?field=name&sort=-downloads"
|
||||
packageName = doAPIRequest(url)
|
||||
i = 1
|
||||
print(f"Searching: {ressourceName}")
|
||||
print("Index | Name | Description | Downloads")
|
||||
for ressource in packageName:
|
||||
pName = ressource["name"]
|
||||
print(oColors.brightBlack + f"Searching: {resourceName}" + oColors.standardWhite)
|
||||
print("┌─────┬─────────────────────────────┬───────────┬──────────────────────────────────────────────────────────────────────┐")
|
||||
print("│ No. │ Name │ Downloads │ Description │")
|
||||
print("└─────┴─────────────────────────────┴───────────┴──────────────────────────────────────────────────────────────────────┘")
|
||||
for resource in packageName:
|
||||
pName = resource["name"]
|
||||
newName = handleRegexPackageName(pName)
|
||||
pTag = ressource["tag"]
|
||||
pDownloads = ressource["downloads"]
|
||||
print(f" [{i}]".ljust(8), end='')
|
||||
pTag = resource["tag"]
|
||||
pDownloads = resource["downloads"]
|
||||
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): "))
|
||||
if ressourceSelected != 0:
|
||||
ressourceSelected = ressourceSelected - 1
|
||||
ressourceId = packageName[ressourceSelected]["id"]
|
||||
if not checkConfig().localPluginFolder:
|
||||
getSpecificPackage(ressourceId, checkConfig().sftp_folderPath)
|
||||
resourceSelected = int(input("Select your wanted resource (No.)(0 to exit): "))
|
||||
if resourceSelected != 0:
|
||||
resourceSelected = resourceSelected - 1
|
||||
resourceId = packageName[resourceSelected]["id"]
|
||||
if not configValues.localPluginFolder:
|
||||
if configValues.sftp_seperateDownloadPath is True:
|
||||
pluginDownloadPath = configValues.sftp_pathToSeperateDownloadPath
|
||||
else:
|
||||
pluginDownloadPath = configValues.sftp_folderPath
|
||||
else:
|
||||
getSpecificPackage(ressourceId, checkConfig().pathToPluginFolder)
|
||||
if configValues.seperateDownloadPath is True:
|
||||
pluginDownloadPath = configValues.pathToSeperateDownloadPath
|
||||
else:
|
||||
pluginDownloadPath = configValues.pathToPluginFolder
|
||||
try:
|
||||
getSpecificPackage(resourceId, pluginDownloadPath)
|
||||
except HTTPError as err:
|
||||
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
|
||||
|
||||
|
||||
def downloadSpecificVersion(ressourceId, downloadPath, versionID='latest'):
|
||||
def downloadSpecificVersion(resourceId, downloadPath, versionID='latest'):
|
||||
configValues = configurationValues()
|
||||
if versionID != 'latest':
|
||||
#url = f"https://spigotmc.org/resources/{ressourceId}/download?version={versionID}"
|
||||
#url = f"https://spigotmc.org/resources/{resourceId}/download?version={versionID}"
|
||||
print(oColors.brightRed + "Sorry but specific version downloads aren't supported because of cloudflare protection. :(" + oColors.standardWhite)
|
||||
print(oColors.brightRed + "Reverting to latest version." + oColors.standardWhite)
|
||||
|
||||
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 :(
|
||||
url = f"https://api.spiget.org/v2/resources/{resourceId}/download"
|
||||
#url = f"https://api.spiget.org/v2/resources/{resourceId}/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:
|
||||
def getSpecificPackage(resourceId, downloadPath, inputPackageVersion='latest'):
|
||||
configValues = configurationValues()
|
||||
if configValues.localPluginFolder == False:
|
||||
downloadPath = createTempPluginFolder()
|
||||
url = f"https://api.spiget.org/v2/resources/{ressourceId}"
|
||||
url = f"https://api.spiget.org/v2/resources/{resourceId}"
|
||||
packageDetails = doAPIRequest(url)
|
||||
packageName = packageDetails["name"]
|
||||
packageNameNew = handleRegexPackageName(packageName)
|
||||
versionId = getVersionID(ressourceId, inputPackageVersion)
|
||||
packageVersion = getVersionName(ressourceId, versionId)
|
||||
versionId = getVersionID(resourceId, inputPackageVersion)
|
||||
packageVersion = getVersionName(resourceId, versionId)
|
||||
packageDownloadName = f"{packageNameNew}-{packageVersion}.jar"
|
||||
downloadPackagePath = f"{downloadPath}\\{packageDownloadName}"
|
||||
if checkConfig().localPluginFolder:
|
||||
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':
|
||||
try:
|
||||
downloadSpecificVersion(ressourceId=ressourceId, downloadPath=downloadPackagePath)
|
||||
deleteTempPluginFolder(downloadPath)
|
||||
except HTTPError as err:
|
||||
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
|
||||
else:
|
||||
try:
|
||||
downloadSpecificVersion(ressourceId, downloadPackagePath, versionId)
|
||||
deleteTempPluginFolder(downloadPath)
|
||||
except HTTPError as err:
|
||||
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
|
||||
downloadPackagePath = Path(f"{downloadPath}/{packageDownloadName}")
|
||||
if inputPackageVersion is None or inputPackageVersion == 'latest':
|
||||
downloadSpecificVersion(resourceId=resourceId, downloadPath=downloadPackagePath)
|
||||
else:
|
||||
downloadSpecificVersion(resourceId, downloadPackagePath, versionId)
|
||||
|
||||
if not configValues.localPluginFolder:
|
||||
deleteTempPluginFolder(downloadPath)
|
||||
|
@@ -1,19 +1,26 @@
|
||||
import os
|
||||
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:
|
||||
@@ -27,17 +34,21 @@ 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
|
||||
pluginPath = f"{pluginPath}\\{plugin}"
|
||||
sftp = createSFTPConnection()
|
||||
sftp.remove(pluginPath)
|
||||
if not configValues.localPluginFolder:
|
||||
pluginPath = configValues.sftp_folderPath
|
||||
pluginPath = f"{pluginPath}/{plugin}"
|
||||
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 = f"{pluginPath}\\{plugin}"
|
||||
pluginPath = configValues.pathToPluginFolder
|
||||
pluginPath = Path(f"{pluginPath}/{plugin}")
|
||||
os.remove(pluginPath)
|
||||
print(f"Removed: {fileName}")
|
||||
i += 1
|
||||
|
@@ -1,12 +1,19 @@
|
||||
import os
|
||||
import re
|
||||
import io
|
||||
import base64
|
||||
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.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, sftp_validateFileAttributes
|
||||
from handlers.handle_ftp import createFTPConnection, ftp_listAll, ftp_downloadFile, ftp_validateFileAttributes
|
||||
from plugin.plugin_downloader import getSpecificPackage
|
||||
from utils.utilities import createTempPluginFolder, deleteTempPluginFolder
|
||||
|
||||
|
||||
def createPluginList():
|
||||
@@ -15,8 +22,8 @@ def createPluginList():
|
||||
return INSTALLEDPLUGINLIST
|
||||
|
||||
|
||||
def addToPluginList(pluginId, versionId, plugin_latest_version, plugin_is_outdated):
|
||||
INSTALLEDPLUGINLIST.append([pluginId, versionId, plugin_latest_version, plugin_is_outdated])
|
||||
def addToPluginList(localFileName, pluginId, versionId, plugin_latest_version, plugin_is_outdated):
|
||||
INSTALLEDPLUGINLIST.append([localFileName, pluginId, versionId, plugin_latest_version, plugin_is_outdated])
|
||||
|
||||
|
||||
def getFileName(pluginName):
|
||||
@@ -37,6 +44,10 @@ def getFileVersion(pluginName):
|
||||
pluginVersion = re.search(r'([\d.]+[.jar]+)', pluginNameFull)
|
||||
pluginVersionFull = pluginVersion.group()
|
||||
pluginVersionString = pluginVersionFull.replace('.jar', '')
|
||||
if pluginVersionString.endswith('.'):
|
||||
pluginVersionString = ''
|
||||
if pluginVersionString == '':
|
||||
pluginVersionString = eggCrackingJar(pluginNameFull, 'version')
|
||||
return pluginVersionString
|
||||
|
||||
|
||||
@@ -47,48 +58,151 @@ def getLatestPluginVersion(pluginId):
|
||||
return versionLatestUpdate
|
||||
|
||||
|
||||
def getUpdateDescription(pluginId):
|
||||
url = f"https://api.spiget.org/v2/resources/{pluginId}/updates?size=1&sort=-date"
|
||||
latestDescriptionSearch = doAPIRequest(url)
|
||||
versionLatestDescription = latestDescriptionSearch[0]["description"]
|
||||
versionLatestDescription = base64.b64decode(versionLatestDescription)
|
||||
versionLatestDescriptionText =versionLatestDescription.decode('utf-8')
|
||||
htmlRegex = re.compile('<.*?>')
|
||||
versionLatestDescriptionText = re.sub(htmlRegex, '', versionLatestDescriptionText)
|
||||
linesChangelogDescription = versionLatestDescriptionText.split("\n")
|
||||
nonEmptyLines = [line for line in linesChangelogDescription if line.strip() != ""]
|
||||
stringnonEmptyLines = ""
|
||||
for line in nonEmptyLines:
|
||||
stringnonEmptyLines += line + "\n"
|
||||
stringnonEmptyLines = stringnonEmptyLines[:-1]
|
||||
return stringnonEmptyLines
|
||||
|
||||
|
||||
def versionTuple(versionString):
|
||||
return tuple(map(int, (versionString.split("."))))
|
||||
|
||||
|
||||
def getVersionWithoutLetters(versionString):
|
||||
return re.sub(r'([A-Za-z]*)', '', versionString)
|
||||
|
||||
|
||||
def compareVersions(plugin_latest_version, pluginVersion):
|
||||
if pluginVersion < plugin_latest_version:
|
||||
plugin_is_outdated = True
|
||||
else:
|
||||
plugin_is_outdated = False
|
||||
return plugin_is_outdated
|
||||
|
||||
|
||||
def checkInstalledPackage(inputSelectedObject="all"):
|
||||
createPluginList()
|
||||
if not checkConfig().localPluginFolder:
|
||||
sftp = createSFTPConnection()
|
||||
pluginList = sftp_listAll(sftp)
|
||||
else:
|
||||
pluginList = os.listdir(checkConfig().pathToPluginFolder)
|
||||
i = 0
|
||||
oldPackages = 0
|
||||
print(f"Checking: {inputSelectedObject}")
|
||||
print("Index | Name | Installed V. | Latest V. | Update available")
|
||||
try:
|
||||
for plugin in pluginList:
|
||||
pluginVersionTuple = versionTuple(getVersionWithoutLetters(pluginVersion))
|
||||
plugin_latest_versionTuple = versionTuple(getVersionWithoutLetters(plugin_latest_version))
|
||||
except ValueError:
|
||||
return False
|
||||
if pluginVersionTuple < plugin_latest_versionTuple:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def eggCrackingJar(localJarFileName, searchMode):
|
||||
configValues = configurationValues()
|
||||
if not configValues.localPluginFolder:
|
||||
tempPluginFolderPath = createTempPluginFolder()
|
||||
if configValues.sftp_useSftp:
|
||||
sftp = createSFTPConnection()
|
||||
pathToPluginJar = Path(f"{tempPluginFolderPath}/{localJarFileName}")
|
||||
sftp_downloadFile(sftp, pathToPluginJar, localJarFileName)
|
||||
else:
|
||||
ftp = createFTPConnection()
|
||||
pathToPluginJar = Path(f"{tempPluginFolderPath}/{localJarFileName}")
|
||||
ftp_downloadFile(ftp, pathToPluginJar, localJarFileName)
|
||||
else:
|
||||
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 searchMode == 'version':
|
||||
if re.match(r'^\s*?version: ', line):
|
||||
pluginVersion = re.sub(r'^\s*?version: ', '', line)
|
||||
pluginVersion = pluginVersion.replace('\n', '')
|
||||
pluginVersion = pluginVersion.replace("'", '')
|
||||
pluginVersion = pluginVersion.replace('"', '')
|
||||
elif searchMode == 'name':
|
||||
if re.match(r'^\s*?name: ', line):
|
||||
pluginName = re.sub(r'^\s*?name: ', '', line)
|
||||
pluginName = pluginName.replace('\n', '')
|
||||
pluginName = pluginName.replace("'", '')
|
||||
pluginName = pluginName.replace('"', '')
|
||||
|
||||
except FileNotFoundError:
|
||||
pluginVersion = ''
|
||||
pluginName = ''
|
||||
except KeyError:
|
||||
pluginVersion = ''
|
||||
pluginName = ''
|
||||
if not configValues.localPluginFolder:
|
||||
deleteTempPluginFolder(tempPluginFolderPath)
|
||||
if searchMode == 'version':
|
||||
return pluginVersion
|
||||
if searchMode == 'name':
|
||||
return pluginName
|
||||
|
||||
|
||||
def checkInstalledPackage(inputSelectedObject="all", inputOptionalParam=None):
|
||||
configValues = configurationValues()
|
||||
createPluginList()
|
||||
pluginFolderPath = configValues.pathToPluginFolder
|
||||
if not configValues.localPluginFolder:
|
||||
if configValues.sftp_useSftp:
|
||||
connection = createSFTPConnection()
|
||||
pluginList = sftp_listAll(connection)
|
||||
else:
|
||||
connection = createFTPConnection()
|
||||
pluginList = ftp_listAll(connection)
|
||||
else:
|
||||
pluginList = os.listdir(pluginFolderPath)
|
||||
|
||||
i = 0
|
||||
oldPlugins = 0
|
||||
print(oColors.brightBlack + f"Checking: {inputSelectedObject}" + oColors.standardWhite)
|
||||
if inputOptionalParam != "changelog":
|
||||
print(oColors.brightBlack + f"Use 'check {inputSelectedObject} changelog' to get the latest changelog from plugins" + oColors.standardWhite)
|
||||
print("┌─────┬────────────────────────────────┬──────────────┬──────────────┐")
|
||||
print("│ No. │ Name │ Installed V. │ Latest V. │")
|
||||
print("└─────┴────────────────────────────────┴──────────────┴──────────────┘")
|
||||
try:
|
||||
for plugin in track(pluginList, description="Checking for updates" ,transient=True, complete_style="bright_yellow"):
|
||||
if not configValues.localPluginFolder:
|
||||
pluginFile = f"{configValues.sftp_folderPath}/{plugin}"
|
||||
if configValues.sftp_useSftp:
|
||||
pluginAttributes = sftp_validateFileAttributes(connection, pluginFile)
|
||||
if pluginAttributes == False:
|
||||
continue
|
||||
else:
|
||||
pluginAttributes = ftp_validateFileAttributes(connection, pluginFile)
|
||||
if pluginAttributes == False:
|
||||
continue
|
||||
else:
|
||||
if not os.path.isfile(Path(f"{pluginFolderPath}/{plugin}")):
|
||||
continue
|
||||
if not re.search(r'.jar$', plugin):
|
||||
continue
|
||||
try:
|
||||
fileName = getFileName(plugin)
|
||||
fileVersion = getFileVersion(plugin)
|
||||
pluginId = getInstalledPlugin(fileName, fileVersion)
|
||||
pluginId = getInstalledPlugin(fileName, fileVersion, plugin)
|
||||
except TypeError:
|
||||
continue
|
||||
pluginIdStr = str(pluginId)
|
||||
|
||||
pluginIdStr = str(pluginId)
|
||||
if fileVersion == '':
|
||||
fileVersion = 'N/A'
|
||||
|
||||
try:
|
||||
pluginLatestVersion = INSTALLEDPLUGINLIST[i][2]
|
||||
pluginLatestVersion = INSTALLEDPLUGINLIST[i][3]
|
||||
except IndexError:
|
||||
pluginLatestVersion = 'N/A'
|
||||
|
||||
|
||||
if pluginLatestVersion == None:
|
||||
pluginLatestVersion = 'N/A'
|
||||
|
||||
try:
|
||||
pluginIsOutdated = INSTALLEDPLUGINLIST[i][3]
|
||||
pluginIsOutdated = INSTALLEDPLUGINLIST[i][4]
|
||||
except IndexError:
|
||||
pluginIsOutdated = 'N/A'
|
||||
|
||||
@@ -96,200 +210,273 @@ def checkInstalledPackage(inputSelectedObject="all"):
|
||||
pluginIsOutdated = 'N/A'
|
||||
|
||||
if pluginIsOutdated == True:
|
||||
oldPackages = oldPackages + 1
|
||||
oldPlugins = oldPlugins + 1
|
||||
|
||||
if inputSelectedObject != "*" and inputSelectedObject != "all":
|
||||
if re.search(r'.jar$', fileName):
|
||||
fileName = eggCrackingJar(plugin, "name")
|
||||
|
||||
if inputSelectedObject != "all" and inputSelectedObject != "*":
|
||||
if inputSelectedObject != pluginIdStr or not re.search(inputSelectedObject, fileName, re.IGNORECASE):
|
||||
i += 1
|
||||
continue
|
||||
|
||||
if inputSelectedObject == "all" or inputSelectedObject != "*" or inputSelectedObject != "all":
|
||||
if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE):
|
||||
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='')
|
||||
else:
|
||||
if pluginLatestVersion == 'N/A':
|
||||
print(oColors.brightBlack + f" [{i+1}]".rjust(6), end='')
|
||||
else:
|
||||
print(f" [{i+1}]".rjust(6), end='')
|
||||
print(" ", end='')
|
||||
if pluginIsOutdated == True:
|
||||
print(oColors.brightRed + f"{fileName}".ljust(33) + oColors.standardWhite, end='')
|
||||
elif pluginIsOutdated == False:
|
||||
print(oColors.brightGreen + f"{fileName}".ljust(33) + oColors.standardWhite, end='')
|
||||
else:
|
||||
print(f"{fileName}".ljust(33), end='')
|
||||
print(f"{fileVersion}".ljust(15), end='')
|
||||
print(f"{pluginLatestVersion}".ljust(12), end='')
|
||||
print(f" {pluginIsOutdated}".ljust(5))
|
||||
|
||||
print(f"{fileVersion}".ljust(15), end='')
|
||||
print(f"{pluginLatestVersion}".ljust(15))
|
||||
if (inputOptionalParam == "changelog" and pluginLatestVersion != 'N/A'):
|
||||
print(oColors.brightYellow + f"CHANGELOG {fileName}:" + oColors.standardWhite)
|
||||
description = getUpdateDescription(pluginId)
|
||||
print(description)
|
||||
print()
|
||||
if inputSelectedObject == pluginIdStr or re.search(inputSelectedObject, fileName, re.IGNORECASE):
|
||||
break
|
||||
else:
|
||||
print(f" [{i+1}]".ljust(8), end='')
|
||||
print(f"{fileName}".ljust(33), end='')
|
||||
print(f"{fileVersion}".ljust(15), end='')
|
||||
print(f"{pluginLatestVersion}".ljust(12), end='')
|
||||
print(f" {pluginIsOutdated}".ljust(5))
|
||||
print(oColors.brightRed + "Wrong input! Use 'check all' to check every plugin for updates!" + oColors.standardWhite)
|
||||
break
|
||||
|
||||
i = i + 1
|
||||
i += 1
|
||||
except TypeError:
|
||||
print(oColors.brightRed + "Aborted checking for plugins." + oColors.standardWhite)
|
||||
print(oColors.brightYellow + f"Old packages: [{oldPackages}/{i}]" + oColors.standardWhite)
|
||||
print(oColors.brightRed + "Error occured: Aborted checking for updates." + oColors.standardWhite)
|
||||
print(oColors.brightYellow + f"Outdated plugins: [{oldPlugins}/{i}]" + oColors.standardWhite)
|
||||
|
||||
|
||||
def updateInstalledPackage(inputSelectedObject='all'):
|
||||
createPluginList()
|
||||
if not checkConfig().localPluginFolder:
|
||||
sftp = createSFTPConnection()
|
||||
pluginList = sftp_listAll(sftp)
|
||||
else:
|
||||
pluginList = os.listdir(checkConfig().pathToPluginFolder)
|
||||
configValues = configurationValues()
|
||||
if not configValues.localPluginFolder:
|
||||
if configValues.sftp_useSftp:
|
||||
connection = createSFTPConnection()
|
||||
else:
|
||||
connection = createFTPConnection()
|
||||
|
||||
try:
|
||||
print(oColors.brightBlack + "Selected plugins with available Updates:" + oColors.standardWhite)
|
||||
if inputSelectedObject == "all" or inputSelectedObject == "*":
|
||||
for pluginIndex in range(len(INSTALLEDPLUGINLIST)):
|
||||
if INSTALLEDPLUGINLIST[pluginIndex][4] == True:
|
||||
fileName = getFileName(INSTALLEDPLUGINLIST[pluginIndex][0])
|
||||
print(fileName, end=' ')
|
||||
else:
|
||||
print(inputSelectedObject, end=' ')
|
||||
|
||||
print()
|
||||
updateConfirmation = input("Update these plugins [y/n] ? ")
|
||||
if str.lower(updateConfirmation) != "y":
|
||||
print(oColors.brightRed + "Aborting the update process."+ oColors.standardWhite)
|
||||
return False
|
||||
|
||||
except NameError:
|
||||
print(oColors.brightRed + "Check for updates before updating plugins with: 'check all'" + oColors.standardWhite)
|
||||
print(oColors.brightRed + "Started checking for updates..." + oColors.standardWhite)
|
||||
checkInstalledPackage()
|
||||
print(oColors.brightRed + f"Please input 'update {inputSelectedObject}' again!" + oColors.standardWhite)
|
||||
return False
|
||||
|
||||
i = 0
|
||||
pluginsUpdated = 0
|
||||
indexNumberUpdated = 0
|
||||
print(f"Updating: {inputSelectedObject}")
|
||||
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:
|
||||
for plugin in pluginList:
|
||||
for pluginArray in track(INSTALLEDPLUGINLIST, description="Updating" ,transient=True, complete_style="bright_magenta", ):
|
||||
plugin = INSTALLEDPLUGINLIST[i][0]
|
||||
if not configValues.localPluginFolder:
|
||||
pluginFile = f"{configValues.sftp_folderPath}/{plugin}"
|
||||
if configValues.sftp_useSftp:
|
||||
pluginAttributes = sftp_validateFileAttributes(connection, pluginFile)
|
||||
if pluginAttributes == False:
|
||||
i += 1
|
||||
continue
|
||||
else:
|
||||
pluginAttributes = ftp_validateFileAttributes(connection, pluginFile)
|
||||
if pluginAttributes == False:
|
||||
i += 1
|
||||
continue
|
||||
else:
|
||||
pluginFolderPath = configValues.pathToPluginFolder
|
||||
if not os.path.isfile(Path(f"{pluginFolderPath}/{plugin}")):
|
||||
i += 1
|
||||
continue
|
||||
if not re.search(r'.jar$', plugin):
|
||||
i += 1
|
||||
continue
|
||||
|
||||
try:
|
||||
fileName = getFileName(plugin)
|
||||
fileVersion = getFileVersion(plugin)
|
||||
pluginId = getInstalledPlugin(fileName, fileVersion)
|
||||
latestVersion = getLatestPluginVersion(pluginId)
|
||||
except TypeError:
|
||||
continue
|
||||
except ValueError:
|
||||
pluginId = INSTALLEDPLUGINLIST[i][1]
|
||||
latestVersion = INSTALLEDPLUGINLIST[i][3]
|
||||
except (TypeError, ValueError):
|
||||
i += 1
|
||||
continue
|
||||
|
||||
if re.search(r'.jar$', fileName):
|
||||
fileName = eggCrackingJar(plugin, "name")
|
||||
|
||||
pluginIdStr = str(pluginId)
|
||||
|
||||
if pluginId == None:
|
||||
print(oColors.brightRed + "Couldn't find plugin id. Sorry :(" + oColors.standardWhite)
|
||||
if pluginId == None or pluginId == '':
|
||||
i += 1
|
||||
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"{fileName}".ljust(30), end='')
|
||||
print(f"{fileVersion}".ljust(8), end='')
|
||||
print(" ", end='')
|
||||
print(f"{latestVersion}".ljust(8))
|
||||
|
||||
if not checkConfig().localPluginFolder:
|
||||
if checkConfig().sftp_pathToSeperateDownloadPath is True:
|
||||
pluginPath = checkConfig().sftp_pathToSeperateDownloadPath
|
||||
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)
|
||||
else:
|
||||
if checkConfig().seperateDownloadPath is True:
|
||||
pluginPath = checkConfig().pathToSeperateDownloadPath
|
||||
else:
|
||||
pluginPath = checkConfig().pathToPluginFolder
|
||||
pluginPath = f"{pluginPath}\\{plugin}"
|
||||
indexNumberUpdated += 1
|
||||
pluginsUpdated += 1
|
||||
try:
|
||||
getSpecificPackage(pluginId, checkConfig().pathToPluginFolder)
|
||||
if checkConfig().seperateDownloadPath is False:
|
||||
os.remove(pluginPath)
|
||||
except HTTPError as err:
|
||||
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
|
||||
pluginsUpdated -= 1
|
||||
except FileNotFoundError:
|
||||
print(oColors.brightRed + f"Error: Old plugin file coulnd't be deleted" + oColors.standardWhite)
|
||||
break
|
||||
else:
|
||||
print(f"{fileName} is already on {latestVersion}")
|
||||
print(oColors.brightRed + "Aborting the update process."+ oColors.standardWhite)
|
||||
break
|
||||
|
||||
if inputSelectedObject == 'all':
|
||||
if INSTALLEDPLUGINLIST[i][3] == True:
|
||||
print(f" [{indexNumberUpdated+1}]".ljust(8), end='')
|
||||
print(f"{fileName}".ljust(30), end='')
|
||||
print(f"{fileVersion}".ljust(8), end='')
|
||||
print(" ", end='')
|
||||
print(f"{latestVersion}".ljust(8))
|
||||
|
||||
if not checkConfig().localPluginFolder:
|
||||
if checkConfig().sftp_seperateDownloadPath is True:
|
||||
pluginPath = checkConfig().sftp_pathToSeperateDownloadPath
|
||||
else:
|
||||
pluginPath = checkConfig().sftp_folderPath
|
||||
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)
|
||||
|
||||
else:
|
||||
if checkConfig().seperateDownloadPath is True:
|
||||
pluginPath = checkConfig().pathToSeperateDownloadPath
|
||||
else:
|
||||
pluginPath = checkConfig().pathToPluginFolder
|
||||
pluginPath = f"{pluginPath}\\{plugin}"
|
||||
indexNumberUpdated += 1
|
||||
pluginsUpdated += 1
|
||||
try:
|
||||
getSpecificPackage(pluginId, checkConfig().pathToPluginFolder)
|
||||
if checkConfig().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
|
||||
except TypeError:
|
||||
print(oColors.brightRed + "Aborted updating for plugins." + oColors.standardWhite)
|
||||
print(f"[{pluginsUpdated}/{i}] Plugins updated")
|
||||
if inputSelectedObject =='all' and pluginsUpdated == 0:
|
||||
print(oColors.brightGreen + "All plugins are on the latest version!" + oColors.standardWhite)
|
||||
|
||||
|
||||
def getInstalledPlugin(localFileName, localFileVersion):
|
||||
url = "https://api.spiget.org/v2/search/resources/" + localFileName + "?field=name&sort=-downloads"
|
||||
packageName = doAPIRequest(url)
|
||||
i = 1
|
||||
plugin_match_found = False
|
||||
pluginID = None
|
||||
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 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)
|
||||
if inputSelectedObject != 'all' and inputSelectedObject != pluginIdStr and not re.search(inputSelectedObject, fileName, re.IGNORECASE):
|
||||
i += 1
|
||||
continue
|
||||
if INSTALLEDPLUGINLIST[i][4] != True:
|
||||
i += 1
|
||||
continue
|
||||
if INSTALLEDPLUGINLIST[i][4] == False and inputSelectedObject != 'all':
|
||||
print(oColors.brightGreen + f"{fileName} is already on {latestVersion}" + oColors.standardWhite)
|
||||
print(oColors.brightRed + "Aborting the update process."+ oColors.standardWhite)
|
||||
break
|
||||
|
||||
i = i + 1
|
||||
print(f" [{indexNumberUpdated+1}]".rjust(6), end='')
|
||||
print(" ", end='')
|
||||
print(f"{fileName}".ljust(33), end='')
|
||||
print(f"{fileVersion}".ljust(13), end='')
|
||||
print(f"{latestVersion}".ljust(13))
|
||||
if not configValues.localPluginFolder:
|
||||
if configValues.sftp_seperateDownloadPath is True:
|
||||
pluginPath = configValues.sftp_pathToSeperateDownloadPath
|
||||
else:
|
||||
pluginPath = configValues.sftp_folderPath
|
||||
pluginPath = f"{pluginPath}/{plugin}"
|
||||
indexNumberUpdated += 1
|
||||
pluginsUpdated += 1
|
||||
if configValues.sftp_useSftp:
|
||||
sftp = createSFTPConnection()
|
||||
try:
|
||||
getSpecificPackage(pluginId, pluginPath)
|
||||
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 TypeError:
|
||||
print(oColors.brightRed + f"TypeError: Couldn't download new version. Is the file available on spigotmc?" + oColors.standardWhite)
|
||||
pluginsUpdated -= 1
|
||||
except FileNotFoundError:
|
||||
print(oColors.brightRed + f"FileNotFoundError: Old plugin file coulnd't be deleted" + oColors.standardWhite)
|
||||
|
||||
else:
|
||||
ftp = createFTPConnection()
|
||||
try:
|
||||
getSpecificPackage(pluginId, pluginPath)
|
||||
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 TypeError:
|
||||
print(oColors.brightRed + f"TypeError: Couldn't download new version. Is the file available on spigotmc?" + oColors.standardWhite)
|
||||
pluginsUpdated -= 1
|
||||
except FileNotFoundError:
|
||||
print(oColors.brightRed + f"FileNotFoundError: Old plugin file coulnd't be deleted" + oColors.standardWhite)
|
||||
|
||||
else:
|
||||
if configValues.seperateDownloadPath is True:
|
||||
pluginPath = configValues.pathToSeperateDownloadPath
|
||||
else:
|
||||
pluginPath = configValues.pathToPluginFolder
|
||||
indexNumberUpdated += 1
|
||||
pluginsUpdated += 1
|
||||
try:
|
||||
getSpecificPackage(pluginId, pluginPath)
|
||||
if configValues.seperateDownloadPath is False:
|
||||
pluginPath = f"{pluginPath}/{plugin}"
|
||||
os.remove(pluginPath)
|
||||
except HTTPError as err:
|
||||
print(oColors.brightRed + f"HTTPError: {err.code} - {err.reason}" + oColors.standardWhite)
|
||||
pluginsUpdated -= 1
|
||||
except TypeError:
|
||||
print(oColors.brightRed + f"TypeError: Couldn't download new version. Is the file available on spigotmc?" + oColors.standardWhite)
|
||||
pluginsUpdated -= 1
|
||||
except FileNotFoundError:
|
||||
print(oColors.brightRed + f"FileNotFoundError: Old plugin file coulnd't be deleted" + oColors.standardWhite)
|
||||
if inputSelectedObject != 'all':
|
||||
break
|
||||
elif inputSelectedObject != 'all':
|
||||
print(oColors.brightGreen + f"{fileName} is already on {latestVersion}" + oColors.standardWhite)
|
||||
print(oColors.brightRed + "Aborting the update process."+ oColors.standardWhite)
|
||||
break
|
||||
|
||||
i += 1
|
||||
except TypeError:
|
||||
print(oColors.brightRed + "Error occured: Aborted updating plugins." + oColors.standardWhite)
|
||||
except NameError:
|
||||
print(oColors.brightRed + "Check for updates before updating plugins with: 'check all'" + oColors.standardWhite)
|
||||
print(oColors.brightRed + "Started checking for updates..." + oColors.standardWhite)
|
||||
checkInstalledPackage()
|
||||
print(oColors.brightRed + f"Please input 'update {inputSelectedObject}' again!" + oColors.standardWhite)
|
||||
if i != 0:
|
||||
print(oColors.brightYellow + f"Plugins updated: [{pluginsUpdated}/{i}]" + oColors.standardWhite)
|
||||
if inputSelectedObject =='all' and pluginsUpdated == 0 and i != 0:
|
||||
print(oColors.brightGreen + "All found plugins are on the latest version!" + oColors.standardWhite)
|
||||
|
||||
|
||||
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
|
||||
localFileVersionNew = localFileVersion
|
||||
i = 0
|
||||
for i in range(0, 3):
|
||||
if plugin_match_found == True:
|
||||
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"
|
||||
try:
|
||||
packageName = doAPIRequest(url)
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
localFileVersion = localFileVersionNew
|
||||
|
||||
for resource in packageName:
|
||||
if plugin_match_found == True:
|
||||
continue
|
||||
pID = resource["id"]
|
||||
url2 = f"https://api.spiget.org/v2/resources/{pID}/versions?size=100&sort=-name"
|
||||
try:
|
||||
packageVersions = doAPIRequest(url2)
|
||||
except ValueError:
|
||||
continue
|
||||
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(localPluginFullName, pID, updateId, plugin_latest_version , plugin_is_outdated)
|
||||
return pluginID
|
||||
|
||||
else:
|
||||
if plugin_match_found != True:
|
||||
pID = None
|
||||
updateId = None
|
||||
plugin_latest_version = None
|
||||
plugin_is_outdated = None
|
||||
addToPluginList(pID, updateId, plugin_latest_version , plugin_is_outdated)
|
||||
pID = updateId = plugin_latest_version = plugin_is_outdated = None
|
||||
addToPluginList(localPluginFullName, pID, updateId, plugin_latest_version , plugin_is_outdated)
|
||||
|
||||
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
|
||||
|
0
src/serverjar/__init__.py
Normal file
0
src/serverjar/__init__.py
Normal file
114
src/serverjar/serverjar_checker.py
Normal file
114
src/serverjar/serverjar_checker.py
Normal file
@@ -0,0 +1,114 @@
|
||||
import os
|
||||
import sys
|
||||
from urllib.error import HTTPError
|
||||
from pathlib import Path
|
||||
|
||||
from handlers.handle_sftp import createSFTPConnection, sftp_listFilesInServerRoot
|
||||
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():
|
||||
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(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)
|
||||
try:
|
||||
papermc_downloader(serverJarBuild, None, installedServerjarFullName)
|
||||
if not configValues.localPluginFolder:
|
||||
sftp.remove(serverJarPath)
|
||||
else:
|
||||
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)
|
||||
|
218
src/serverjar/serverjar_paper.py
Normal file
218
src/serverjar/serverjar_paper.py
Normal file
@@ -0,0 +1,218 @@
|
||||
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 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
|
||||
|
||||
|
||||
def getInstalledPaperMinecraftVersion(localPaperName):
|
||||
if localPaperName is None:
|
||||
return False
|
||||
mcVersionFull = re.search(r'(\d*\.*\d)+', localPaperName)
|
||||
try:
|
||||
mcVersion = mcVersionFull.group()
|
||||
except AttributeError:
|
||||
mcVersion = mcVersionFull
|
||||
return mcVersion
|
||||
|
||||
|
||||
def getInstalledPaperVersion(localPaperName):
|
||||
if localPaperName is None:
|
||||
return False
|
||||
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.17', '1.16', '1.15']
|
||||
if mcVersion is None:
|
||||
return False
|
||||
for versionGroup in versionGroups:
|
||||
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:
|
||||
paperVersionGroup = versionGroup
|
||||
return paperVersionGroup
|
||||
if versionGroup == mcVersion:
|
||||
paperVersionGroup = versionGroup
|
||||
return paperVersionGroup
|
||||
return False # Not found
|
||||
|
||||
|
||||
def findBuildVersion(wantedPaperBuild):
|
||||
versionGroups = ['1.17', '1.16', '1.15']
|
||||
if wantedPaperBuild is None:
|
||||
return False
|
||||
for versionGroup in versionGroups:
|
||||
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:
|
||||
paperVersionGroup = build["version"]
|
||||
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]
|
||||
return latestPaperBuild
|
||||
|
||||
|
||||
def versionBehind(installedPaperBuild, latestPaperBuild):
|
||||
if installedPaperBuild is None or latestPaperBuild is None:
|
||||
return False
|
||||
installedPaperBuildint = int(installedPaperBuild)
|
||||
latestPaperBuildint = int(latestPaperBuild)
|
||||
versionsBehind = latestPaperBuildint - installedPaperBuildint
|
||||
return versionsBehind
|
||||
|
||||
|
||||
def getDownloadFileName(paperMcVersion, paperBuild):
|
||||
if paperMcVersion is None or paperBuild is None:
|
||||
return False
|
||||
url = f"https://papermc.io/api/v2/projects/paper/versions/{paperMcVersion}/builds/{paperBuild}"
|
||||
buildDetails = doAPIRequest(url)
|
||||
downloadName = buildDetails["downloads"]["application"]["name"]
|
||||
return downloadName
|
||||
|
||||
|
||||
def paperCheckForUpdate(installedServerjarFullName):
|
||||
mcVersion = getInstalledPaperMinecraftVersion(installedServerjarFullName)
|
||||
|
||||
# Report an error if getInstalledPaperMinecraftVersion encountered an issue.
|
||||
if not mcVersion:
|
||||
print(oColors.brightRed + "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 + "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 + "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 + "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)
|
||||
# Report an error if getInstalledPaperVersion encountered an issue.
|
||||
if not paperVersionBehind:
|
||||
print(oColors.brightRed + "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. │")
|
||||
print("└─────┴────────────────────────────────┴──────────────┴──────────────┘")
|
||||
print(" [1]".rjust(6), end='')
|
||||
print(" ", end='')
|
||||
if paperVersionBehind != 0:
|
||||
print(oColors.brightRed + "paper".ljust(33) + oColors.standardWhite, end='')
|
||||
else:
|
||||
print(oColors.brightGreen + "paper".ljust(33) + oColors.standardWhite, end='')
|
||||
print(f"{paperInstalledBuild}".ljust(15), end='')
|
||||
print(f"{paperLatestBuild}".ljust(15))
|
||||
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', mcVersion=None, installedServerjarName=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.17.1'
|
||||
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:
|
||||
if not configValues.sftp_useSftp:
|
||||
ftpSession = createFTPConnection()
|
||||
ftp_upload_server_jar(ftpSession, downloadPackagePath)
|
||||
else:
|
||||
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)
|
@@ -13,11 +13,11 @@ def clearConsole():
|
||||
# https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
|
||||
class oColors:
|
||||
standardWhite = "\033[0m"
|
||||
brightYellow = "\033[93m"
|
||||
brightMagenta = "\033[95m"
|
||||
brightBlack = "\033[90m"
|
||||
brightRed = "\033[91m"
|
||||
brightGreen = "\033[92m"
|
||||
darkMagenta = "\033[35m"
|
||||
brightYellow = "\033[93m"
|
||||
brightMagenta = "\033[95m"
|
||||
|
||||
|
||||
def printLogo():
|
||||
@@ -72,9 +72,12 @@ def printLogo():
|
||||
oColors.standardWhite)
|
||||
print()
|
||||
print()
|
||||
print(oColors.brightYellow + " [" + oColors.darkMagenta + "By Neocky" +
|
||||
oColors.brightYellow + "] " + oColors.standardWhite)
|
||||
print()
|
||||
print(oColors.brightBlack + " ┌────────────────────────────────────┐" + oColors.standardWhite)
|
||||
print(oColors.brightBlack + " │ [" + oColors.brightMagenta + "By Neocky" +oColors.brightBlack +
|
||||
"] │ " + oColors.standardWhite)
|
||||
print(oColors.brightBlack + " │ " + oColors.brightMagenta + "https://github.com/Neocky/pluGET" + oColors.brightBlack +
|
||||
" │ " + oColors.standardWhite)
|
||||
print(oColors.brightBlack + " └────────────────────────────────────┘" + oColors.standardWhite)
|
||||
|
||||
|
||||
def printHorizontalLine():
|
||||
|
@@ -3,26 +3,105 @@ import os
|
||||
import sys
|
||||
import shutil
|
||||
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():
|
||||
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("Or go to the official discord.")
|
||||
print("The link for discord can also be found on Github!")
|
||||
|
||||
|
||||
def check_local_plugin_folder():
|
||||
if checkConfig().localPluginFolder:
|
||||
if checkConfig().seperateDownloadPath:
|
||||
pluginFolderPath = checkConfig().pathToSeperateDownloadPath
|
||||
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 changelog Check for an update of an installed plugin")
|
||||
print(" update Name/ID/all Update installed plugins to the latest version")
|
||||
print(" search Name Search for a plugin and download the latest version")
|
||||
print(" remove Name/ID Delete an installed plugin")
|
||||
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:
|
||||
pluginFolderPath = checkConfig().pathToPluginFolder
|
||||
print(oColors.brightRed + "Error: Help for Command not found. Please try again. :(" + oColors.standardWhite)
|
||||
break
|
||||
|
||||
|
||||
def check_local_plugin_folder():
|
||||
configValues = configurationValues()
|
||||
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)
|
||||
@@ -41,7 +120,7 @@ def apiTest():
|
||||
apiStatusUrl = 'https://api.spiget.org/v2/status'
|
||||
try:
|
||||
r = requests.get(apiStatusUrl)
|
||||
except requests.exceptions.HTTPError:
|
||||
except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError):
|
||||
print(oColors.brightRed + "Couldn't make a connection to the API. Check you connection to the internet!" + oColors.standardWhite)
|
||||
input("Press any key + enter to exit...")
|
||||
sys.exit()
|
||||
@@ -52,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 = ".\\plugins"
|
||||
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()
|
||||
@@ -76,3 +160,16 @@ def deleteTempPluginFolder(tempPluginFolder):
|
||||
shutil.rmtree(tempPluginFolder)
|
||||
except OSError as e:
|
||||
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
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user