mirror of
https://github.com/Neocky/pluGET.git
synced 2024-04-29 16:12:30 +00:00
Compare commits
66 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6ea80b9c66 | ||
![]() |
3f4380acae | ||
![]() |
a9bac687c8 | ||
![]() |
1fda453bbd | ||
![]() |
30f0dd91ac | ||
![]() |
c8b026fb3a | ||
![]() |
b6b5b4dff7 | ||
![]() |
cd9479d8d5 | ||
![]() |
88b897716a | ||
![]() |
a7b528d25d | ||
![]() |
1c11b0df83 | ||
![]() |
653dac6c2c | ||
![]() |
a5eeca7d9a | ||
![]() |
1fc53d907d | ||
![]() |
32aabefdf1 | ||
![]() |
18ca3104a5 | ||
![]() |
8227c12bf1 | ||
![]() |
18e012540c | ||
![]() |
526ccf72cb | ||
![]() |
4250ab15df | ||
![]() |
03a117c4e8 | ||
![]() |
ede3557819 | ||
![]() |
0e09daae53 | ||
![]() |
6b926c9564 | ||
![]() |
b539d11f67 | ||
![]() |
744f2e5988 | ||
![]() |
119d44631f | ||
![]() |
626b7a3812 | ||
![]() |
1df6b36c5d | ||
![]() |
d7c09eb04a | ||
![]() |
bac69ae829 | ||
![]() |
badf6230bb | ||
![]() |
2e9973a24f | ||
![]() |
0bac45d478 | ||
![]() |
2ba9e6ddb7 | ||
![]() |
9e74d480dd | ||
![]() |
0b10a76a3b | ||
![]() |
9b2ff6e208 | ||
![]() |
e17be2c500 | ||
![]() |
fb52973cf6 | ||
![]() |
3219e32351 | ||
![]() |
041d7aa240 | ||
![]() |
96b4411020 | ||
![]() |
8620dfbe74 | ||
![]() |
84fcfc8922 | ||
![]() |
d427886c49 | ||
![]() |
e229324117 | ||
![]() |
7f2404f0cd | ||
![]() |
3943357569 | ||
![]() |
ac139ed048 | ||
![]() |
8e51b1976d | ||
![]() |
4920689f0e | ||
![]() |
993d438ff7 | ||
![]() |
3faf9785d7 | ||
![]() |
17e67e68ea | ||
![]() |
5075922674 | ||
![]() |
cf710088a9 | ||
![]() |
b1b5eeb992 | ||
![]() |
3bcb3de4cf | ||
![]() |
9a70733421 | ||
![]() |
449232e2ca | ||
![]() |
1c74d8501c | ||
![]() |
9289872831 | ||
![]() |
0c3bace49e | ||
![]() |
2e459cafe2 | ||
![]() |
1ff34a7372 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -1,3 +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']
|
||||
ko_fi: Neocky
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -133,3 +133,6 @@ dmypy.json
|
||||
|
||||
# PyCharm Settings
|
||||
.idea
|
||||
|
||||
# pluGET Files
|
||||
pluGET_config.yaml
|
||||
|
280
README.md
280
README.md
@ -1,7 +1,11 @@
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img src="https://i.ibb.co/JyCxnQn/logoreal.png" alt="pluGET" border="0"></a>
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./assets/branding/pluget-logo-white.png">
|
||||
<source media="(prefers-color-scheme: light)" srcset="./assets/branding/pluget-logo-black.png">
|
||||
<img src="./assets/branding/pluget-logo-black.png" alt="pluGET" border="0">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@ -17,12 +21,12 @@
|
||||
|
||||
|
||||
# pluGET
|
||||
#### A powerful package manager which updates [Plugins](https://www.spigotmc.org/resources/) and Server Software for minecraft servers.
|
||||
A powerful package manager which updates [Plugins](https://www.spigotmc.org/resources/) and Server Software for minecraft servers.
|
||||
|
||||
<img src="https://www.bildhost.com/images/2021/06/27/ezgif-1-28e102202188.gif" alt="pluGET.gif" border="0" />
|
||||
<img src="https://user-images.githubusercontent.com/13088544/177011216-1360d444-278a-475e-9863-966c48c60ba7.gif" alt="pluGET.gif" border="0" />
|
||||
|
||||
<details>
|
||||
<summary>Screenshots</summary>
|
||||
<summary>Old Screenshots</summary>
|
||||
|
||||
`check all` to check installed plugins for updates:
|
||||

|
||||
@ -35,43 +39,24 @@
|
||||
|
||||
</details>
|
||||
|
||||
# About
|
||||
pluGET is a standalone package manager written in python for minecraft [Spigot](https://www.spigotmc.org/) servers and its forks (e.g. [PaperMC](https://papermc.io/)). The program works with a locally installed servers 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 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 is the hard part of managing a minecraft server. The time it takes to manually check the [Spigot resources](https://www.spigotmc.org/resources/) page for updates and manually downloading all plugins is 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. The program input and the associated config file are pretty simple so every server owner and not only the most tech savy ones can use pluGET to ease their plugin handling.
|
||||
|
||||
<img src="https://i.ibb.co/82dnyrK/image.png" alt="meme" border="0" height="350" width="350"></a>
|
||||
|
||||
|
||||
## Issues? Found a bug?
|
||||
[Create an issue.](https://github.com/Neocky/pluGET/issues/new/choose)
|
||||
|
||||
|
||||
## 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/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 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.
|
||||
The program input and the associated config file are pretty simple so every server owner and not only the most tech savy ones can use pluGET to ease their plugin handling.
|
||||
|
||||
Follow the [Installation](https://github.com/Neocky/pluGET#installation) guide below for an easy and hassle free setup of pluGET.
|
||||
Read [Usage](https://github.com/Neocky/pluGET#usage) below to get some example inputs when using pluGET.
|
||||
If you still have questions [here](https://github.com/Neocky/pluGET#need-help) is the best place to ask for support.
|
||||
|
||||
So what can it do exactly?
|
||||
pluGET can:
|
||||
- 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/)
|
||||
# Features
|
||||
- Works locally or through SFTP/FTP
|
||||
- Runs directly from the console with command line arguments
|
||||
- Checks for updates and downloads the latest version of all/specific plugins
|
||||
- Checks for updates and downloads the latest version of your server software
|
||||
- [PaperMc](https://papermc.io/)
|
||||
- [Purpur](https://purpurmc.org/)
|
||||
- [Waterfall](https://papermc.io/downloads#Waterfall)
|
||||
- [Velocity](https://papermc.io/downloads#Velocity)
|
||||
|
||||
There are more features in the work. Check [Projects](https://github.com/Neocky/pluGET/projects) for a complete list.
|
||||
|
||||
@ -79,183 +64,160 @@ There are more features in the work. Check [Projects](https://github.com/Neocky/
|
||||
[Get the latest release here.](https://github.com/Neocky/pluGET/releases)
|
||||
|
||||
|
||||
## Donations
|
||||
If you feel like showing your love and/or appreciation for this project then how about buying me a coffee! :)
|
||||
|
||||
<a href="https://www.buymeacoffee.com/Neocky" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="76" width="272"></a>
|
||||
# Donations ☕
|
||||
If you feel like showing your love and/or appreciation for this project then how about buying me a coffee? ☕🤎
|
||||
|
||||
[<img src="https://ko-fi.com/img/githubbutton_sm.svg" alt="ko-fi" width="300"/>](https://ko-fi.com/Y8Y1CKZ43)
|
||||
|
||||
|
||||
## Need help?
|
||||
[<img src="https://i.ibb.co/CMKbT0L/rsz-1rsz-discord.png" alt="Discord" width="272"/>](https://discord.gg/475Uf4NBPF)
|
||||
|
||||
# Need help?
|
||||
[<img src="https://i.ibb.co/PQv3KtJ/Discord-Logo-Wordmark-Color.png" alt="Discord" width="300"/>](https://discord.gg/475Uf4NBPF)
|
||||
|
||||
|
||||
## Installation
|
||||
### 1. Python
|
||||
Python needs to be installed on your machine.
|
||||
Get it [here](https://www.python.org/downloads/).
|
||||
### 2. Dependencies
|
||||
Install the needed packages for this project.
|
||||
#### 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.
|
||||
# Installation
|
||||
## 1. Python 3.10.4
|
||||
Python needs to be installed on your machine. Get it [here](https://www.python.org/downloads/).
|
||||
|
||||
#### Manually
|
||||
Execute this command in the `\plugGET` folder:
|
||||
```python
|
||||
py -m pip install -r requirements.txt
|
||||
```
|
||||
## 2. Dependencies
|
||||
In order to install dependencies run the `install_requirements_WINDOWS/LINUX` file, of course depending on your system.
|
||||
|
||||
|
||||
### 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.
|
||||
## 3. Edit the config
|
||||
When run pluGET for the first time, the `pluGET_config.yaml` file will be created in the main 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.
|
||||
## 4. Running the program
|
||||
Execute the `pluget.py` file with python 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
|
||||
```python
|
||||
# Windows:
|
||||
py pluget.py
|
||||
# Linux
|
||||
python3 pluget.py
|
||||
```
|
||||
|
||||
> On both OS you can also launch the `src/__main__.py` file.
|
||||
|
||||
## Usage
|
||||
# Usage
|
||||
> As always, if you update plugins, shut down your server!
|
||||
|
||||
The following are examples of input for the general usage:
|
||||
(Hint: [thingsInBrackets] are optional & 'all' can always be exchanged through the plugin name or the plugin id and reverse)
|
||||
## Commands:
|
||||
|
||||
### General
|
||||
#### Command help:
|
||||
`help command [all/command]`
|
||||
```
|
||||
help command
|
||||
```
|
||||
<details>
|
||||
### • Show the information about all commands.
|
||||
<!-- <details>
|
||||
<summary>Output</summary>
|
||||
|
||||

|
||||

|
||||
|
||||
</details>
|
||||
</details> -->
|
||||
|
||||
### Manage Plugins
|
||||
#### Download the latest update of a specific package:
|
||||
`get [pluginID/pluginName]`
|
||||
```
|
||||
get 'pluginID'
|
||||
```
|
||||
or:
|
||||
help command [all/command]
|
||||
```
|
||||
get 'pluginName'
|
||||
```
|
||||
#### Check all plugins/one specific plugin for updates with optional changelog output:
|
||||
`check [all/pluginName] [changelog]`
|
||||
|
||||
### • Exit program:
|
||||
```
|
||||
check all
|
||||
```
|
||||
or:
|
||||
exit .
|
||||
```
|
||||
check 'pluginName' changelog
|
||||
|
||||
### • Get link to this page:
|
||||
```
|
||||
help .
|
||||
```
|
||||
|
||||
## Manage Plugins
|
||||
### • Download the latest update of a specific package:
|
||||
```
|
||||
get [pluginID/pluginName]
|
||||
```
|
||||
|
||||
<details>
|
||||
### • Check all plugins/one specific plugin for updates with optional changelog output:
|
||||
<!-- <details>
|
||||
<summary>Output</summary>
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
</details> -->
|
||||
|
||||
```
|
||||
check [all/pluginName] [changelog]
|
||||
```
|
||||
|
||||
#### Update all plugins/one specific plugin:
|
||||
`update [all/pluginName]`
|
||||
### • Update all plugins/one specific plugin:
|
||||
```
|
||||
update all
|
||||
update [all/pluginName]
|
||||
```
|
||||
or:
|
||||
|
||||
### • Remove a plugin with the ID/Name:
|
||||
```
|
||||
update 'pluginName'
|
||||
```
|
||||
#### Remove a plugin with the ID/Name:
|
||||
`remove [pluginID/pluginName]`
|
||||
remove [pluginID/pluginName]
|
||||
```
|
||||
remove 'pluginID'
|
||||
```
|
||||
or:
|
||||
|
||||
### • Search for a plugin:
|
||||
```
|
||||
remove 'pluginName'
|
||||
```
|
||||
#### Search for a plugin:
|
||||
`search [pluginName]`
|
||||
search [pluginName]
|
||||
```
|
||||
search 'pluginName'
|
||||
```
|
||||
#### Exit program:
|
||||
`exit [anything]`
|
||||
```
|
||||
exit .
|
||||
```
|
||||
#### Get link to here:
|
||||
`help [anything]`
|
||||
```
|
||||
help .
|
||||
```
|
||||
### Manage Server Software
|
||||
#### Check installed server software for updates:
|
||||
`check serverjar`
|
||||
|
||||
## Manage Server Software
|
||||
|
||||
### • Check installed server software for updates:
|
||||
```
|
||||
check serverjar
|
||||
```
|
||||
### Update installed server software to latest/specific version:
|
||||
`update serverjar [Version]`
|
||||
|
||||
### • Update installed server software to latest/specific version:
|
||||
```
|
||||
update serverjar 'PaperMCVersion'
|
||||
```
|
||||
### Download specific paper version:
|
||||
`get-paper [paperBuild] [minecraftVersion]`
|
||||
```
|
||||
get-paper 550 1.16.5
|
||||
```
|
||||
or:
|
||||
```
|
||||
get-paper 321
|
||||
update serverjar [Version]
|
||||
```
|
||||
|
||||
## Known problems
|
||||
### • Download specific paper version:
|
||||
```
|
||||
get-paper [paperBuild] [minecraftVersion]
|
||||
```
|
||||
|
||||
### Can't get latest version/Update available
|
||||
### • Download specific waterfall version:
|
||||
```
|
||||
get-waterfall [waterfallBuild] [minecraftVersion]
|
||||
```
|
||||
|
||||
#### Inconsistent Names and Versions
|
||||
For example:
|
||||
### • Download specific velocity version:
|
||||
```
|
||||
get-velocity [velocityBuild] [minecraftVersion]
|
||||
```
|
||||
|
||||
### • Download specific purpur version:
|
||||
```
|
||||
get-purpur [purpurBuild] [minecraftVersion]
|
||||
```
|
||||
|
||||
# Command line arguments
|
||||
pluGET supports all commands directly through the command line. Get the list of all available command line arguments with the `-h` argument.
|
||||
|
||||
Example direct command line call:
|
||||
```shell
|
||||
py pluget.py check all
|
||||
```
|
||||
|
||||
# Known problems
|
||||
|
||||
## Can't get latest version/Update available
|
||||
|
||||
### Inconsistent Names and Versions
|
||||
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
|
||||
### 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:
|
||||
### Bukkit plugins
|
||||
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.
|
||||
|
||||
|
BIN
assets/branding/pluget-logo-black.png
Normal file
BIN
assets/branding/pluget-logo-black.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
BIN
assets/branding/pluget-logo-white.png
Normal file
BIN
assets/branding/pluget-logo-white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
126
assets/branding/pluget-logo.svg
Normal file
126
assets/branding/pluget-logo.svg
Normal file
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
sodipodi:docname="pluget-logo.svg"
|
||||
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
|
||||
xml:space="preserve"
|
||||
id="svg5"
|
||||
version="1.1"
|
||||
viewBox="0 0 101.31679 30.525789"
|
||||
height="30.525789mm"
|
||||
width="101.31679mm"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.8284271"
|
||||
inkscape:cx="60.811183"
|
||||
inkscape:cy="81.31728"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1051"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" /><defs
|
||||
id="defs2"><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="66.717927,194.91922"
|
||||
end_point="66.717927,196.6932"
|
||||
center_point="66.717927,195.80621"
|
||||
id="path-effect2543"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="free"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /></defs><g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-244.05501,27.440776)"><path
|
||||
style="display:inline;fill:none;stroke:#ffffff;stroke-width:1.08823;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 269.92243,-15.41098 0.89279,-0.51545 c 2.31137,-1.33446 4.26969,-0.85065 3.74023,2.09491 -0.52947,2.94556 -2.57765,6.63243 0.19723,7.52795 1.17498,0.3792 3.00732,-0.24884 3.52934,-2.54794 0.70271,-3.09482 -0.37661,-6.7641 -1.62003,-10.38648 l -0.87139,-2.53855"
|
||||
id="path2515"
|
||||
sodipodi:nodetypes="cszsssc"
|
||||
inkscape:label="wire" /><g
|
||||
id="g2525"
|
||||
transform="matrix(1.5194714,-0.52157949,0.52157949,1.5194714,111.14245,-282.32695)"
|
||||
style="display:inline;stroke:none"
|
||||
inkscape:label="plug"><g
|
||||
id="g2521"
|
||||
transform="matrix(1.8835345,0,0,1.8835345,-81.40728,-180.76428)"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
inkscape:label="pins"><rect
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.744316;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2517"
|
||||
width="0.39793873"
|
||||
height="1.5362287"
|
||||
x="66.120705"
|
||||
y="193.25238"
|
||||
ry="0.19896936"
|
||||
inkscape:label="left" /><rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.744316;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2519"
|
||||
width="0.39793873"
|
||||
height="1.5362287"
|
||||
x="66.940681"
|
||||
y="193.25238"
|
||||
ry="0.19896936"
|
||||
inkscape:label="right" /></g><path
|
||||
id="path2523"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.439285;stroke-linecap:round"
|
||||
d="m 65.710577,195.23133 c 0,0.68804 0.25868,1.46187 1.00735,1.46187 v -1.77398 c -0.889087,0 -1.00735,0 -1.00735,0.31211 z m 2.0147,0 c 0,0.68804 -0.25868,1.46187 -1.00735,1.46187 v -1.77398 c 0.889087,0 1.00735,0 1.00735,0.31211 z"
|
||||
sodipodi:nodetypes="cccc"
|
||||
class="UnoptimicedTransforms"
|
||||
transform="matrix(1.8835345,0,0,1.8835345,-81.385177,-182.13354)"
|
||||
inkscape:label="body"
|
||||
inkscape:original-d="m 65.710577,195.23133 c 0,0.68804 0.25868,1.46187 1.00735,1.46187 v -1.77398 c -0.889087,0 -1.00735,0 -1.00735,0.31211 z"
|
||||
inkscape:path-effect="#path-effect2543" /></g><path
|
||||
id="path2531"
|
||||
style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.989574;stroke-linejoin:round"
|
||||
class="UnoptimicedTransforms"
|
||||
inkscape:label="top side"
|
||||
inkscape:transform-center-x="5.3509257"
|
||||
inkscape:transform-center-y="-7.3394763"
|
||||
transform="matrix(0.95451618,0,0,0.95451618,236.87111,-259.69297)"
|
||||
d="m 15.626149,255.26898 5.938704,3.42871 13.318093,-7.68921 -5.938698,-3.42871 z m -7.3793868,-4.26049 5.9804058,3.45279 13.318085,-7.68921 -5.980399,-3.45279 z"
|
||||
sodipodi:nodetypes="cccccccccc" /><path
|
||||
transform="matrix(-0.47725809,-0.82663525,0.82663525,-0.47725809,53.21073,137.01425)"
|
||||
style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.989574;stroke-linejoin:round"
|
||||
class="UnoptimicedTransforms"
|
||||
id="path2537"
|
||||
d="M 14.905808,254.85309 28.223899,262.5423 41.541992,254.85309 28.2239,247.16388 Z"
|
||||
inkscape:label="blank side" /><path
|
||||
id="path2533"
|
||||
style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.989574;stroke-linejoin:round"
|
||||
class="UnoptimicedTransforms"
|
||||
d="m 14.905755,254.85285 13.31825,7.68919 13.317866,-7.68907 -13.318249,-7.6892 z m 4.297769,-0.63465 2.921445,-1.6867 3.373173,1.94776 1.460956,-0.84349 -1.686685,-0.9735 4.381932,-2.52991 1.686685,0.97351 -1.460956,0.84348 3.373642,1.94748 1.460488,-0.84321 1.686685,0.97351 -4.381932,2.52991 -1.686686,-0.97351 -1.460487,0.84321 3.373173,1.94776 -2.921444,1.6867 -3.373174,-1.94776 2.921445,-1.6867 -3.373642,-1.94748 -2.921445,1.6867 z"
|
||||
transform="matrix(-0.47725809,0.82663526,-0.82663526,-0.47725809,488.59969,90.37568)"
|
||||
inkscape:label="creeper face side" /><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:17.0938px;line-height:1.25;font-family:Comfortaa;-inkscape-font-specification:'Comfortaa, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.427346"
|
||||
x="281.58862"
|
||||
y="-7.4172397"
|
||||
id="text2529"
|
||||
inkscape:label="text"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2527"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:17.0938px;font-family:Comfortaa;-inkscape-font-specification:'Comfortaa, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ffffff;fill-opacity:1;stroke-width:0.427346"
|
||||
x="281.58862"
|
||||
y="-7.4172397"
|
||||
dx="0 -0.51999998 -0.18000001 -0.69 -0.5 0.57999998">pluGET</tspan></text></g></svg>
|
After Width: | Height: | Size: 6.9 KiB |
4
install_requirements_LINUX.sh
Normal file
4
install_requirements_LINUX.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Installing Python packages and dependencies from requirements.txt... Please wait."
|
||||
pip install -r requirements.txt
|
4
install_requirements_WINDOWS.bat
Normal file
4
install_requirements_WINDOWS.bat
Normal file
@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
title Installing requirements...
|
||||
echo Installing Python packages and dependencies from requirements.txt... Please wait.
|
||||
py -m pip install -r requirements.txt
|
@ -1,34 +0,0 @@
|
||||
@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
|
@ -1,4 +0,0 @@
|
||||
@ECHO OFF
|
||||
cd "%~dp0"
|
||||
cd src
|
||||
py "__main__.py"
|
@ -1,2 +0,0 @@
|
||||
cd src/
|
||||
python3 "__main__.py"
|
45
pluget.py
Normal file
45
pluget.py
Normal file
@ -0,0 +1,45 @@
|
||||
"""
|
||||
Handles the main function and the argument passing for the whole pluGET program
|
||||
"""
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
# check if folder 'src' is accessible with all modules needed and if not exit
|
||||
try:
|
||||
from src.handlers.handle_config import check_config, validate_config
|
||||
from src.utils.console_output import rename_console_title, clear_console, print_logo, print_console_logo
|
||||
from src.utils.utilities import check_requirements, api_test_spiget, check_for_pluGET_update
|
||||
from src.handlers.handle_input import handle_input
|
||||
except TypeError:
|
||||
print("Folder 'src' not found in the directory or missing files or broken functions detected! \
|
||||
\nPlease redownload the files from here: https://www.github.com/Neocky/pluGET")
|
||||
sys.exit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Arguments for pluGET",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument("mode", help="Mode (install/update/etc.)", nargs='?', default=None)
|
||||
parser.add_argument("object", help="Object/Plugin Name", nargs='?', default=None)
|
||||
parser.add_argument("version", help="Version", nargs='?', default=None)
|
||||
parser.add_argument("--no-confirmation", action="store_true", help="Skip confirmation messages")
|
||||
args = vars(parser.parse_args())
|
||||
|
||||
rename_console_title()
|
||||
check_config()
|
||||
validate_config()
|
||||
api_test_spiget()
|
||||
check_requirements()
|
||||
|
||||
if args["mode"] is not None and args["object"] is not None:
|
||||
# arguments were used so call the handle_input function to get the right function call
|
||||
print_console_logo()
|
||||
check_for_pluGET_update()
|
||||
handle_input(args["mode"], args["object"], args["version"], args["no_confirmation"], arguments_from_console=True)
|
||||
else:
|
||||
# no arguments were used so start pluGET console
|
||||
clear_console()
|
||||
print_logo()
|
||||
check_for_pluGET_update()
|
||||
handle_input()
|
@ -11,4 +11,5 @@ pysftp >= 0.2.9
|
||||
rich >= 9.13.0
|
||||
commonmark >= 0.9.1
|
||||
Pygments >= 2.8.1
|
||||
typing_extensions >= 3.7.4.3
|
||||
typing_extensions >= 3.7.4.3
|
||||
ruamel.yaml >= 0.17.21
|
@ -1,16 +0,0 @@
|
||||
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
|
||||
|
||||
|
||||
def mainFunction():
|
||||
consoleTitle()
|
||||
clearConsole()
|
||||
checkConfig()
|
||||
check_requirements()
|
||||
createInputLists()
|
||||
printMainMenu()
|
||||
getInput()
|
||||
|
||||
mainFunction()
|
@ -1,87 +1,109 @@
|
||||
""""
|
||||
Handles the logic for the config validation, reading and creating
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import configparser
|
||||
import ruamel.yaml
|
||||
from pathlib import Path
|
||||
|
||||
from utils.consoleoutput import oColors
|
||||
from rich.console import Console
|
||||
|
||||
|
||||
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
|
||||
class config_value():
|
||||
"""
|
||||
Class which holds all the available configuration values from the config file and which will be used later in
|
||||
the process of updating plugins
|
||||
If bool in config can't be read it will default to 'False'
|
||||
"""
|
||||
def __init__(self):
|
||||
yaml = ruamel.yaml.YAML()
|
||||
with open("pluGET_config.yaml", "r") as config_file:
|
||||
data = yaml.load(config_file)
|
||||
self.connection = str(data["Connection"]).lower()
|
||||
self.path_to_plugin_folder = Path(data["Local"]["PathToPluginFolder"])
|
||||
self.local_seperate_download_path = True if data["Local"]["SeperateDownloadPath"] == True else False
|
||||
self.local_path_to_seperate_download_path = Path(data["Local"]["PathToSeperateDownloadPath"])
|
||||
self.server = data["Remote"]["Server"]
|
||||
self.username = data["Remote"]["Username"]
|
||||
self.password = data["Remote"]["Password"]
|
||||
self.sftp_port = int(data["Remote"]["SFTP_Port"])
|
||||
self.ftp_port = int(data["Remote"]["FTP_Port"])
|
||||
self.remote_seperate_download_path = True if data["Remote"]["SeperateDownloadPath"] == True else False
|
||||
self.remote_path_to_seperate_download_path = data["Remote"]["PathToSeperateDownloadPath"]
|
||||
self.remote_plugin_folder_on_server = data["Remote"]["PluginFolderOnServer"]
|
||||
|
||||
|
||||
def checkConfig():
|
||||
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()
|
||||
def check_config() -> None:
|
||||
"""
|
||||
Check if there is a pluGET_config.yml file in the same folder as pluget.py and if not create a new config
|
||||
and exit the programm
|
||||
"""
|
||||
if not os.path.isfile("pluGET_config.yaml"):
|
||||
create_config()
|
||||
return None
|
||||
|
||||
|
||||
def createConfig():
|
||||
config = configparser.ConfigParser(allow_no_value=True)
|
||||
config['General'] = {}
|
||||
config['General'][';'] = 'If a local plugin folder exists (True/False) (If False SFTP/FTP will be used):'
|
||||
config['General']['UseLocalPluginFolder'] = 'True'
|
||||
def create_config() -> None:
|
||||
"""
|
||||
Creates the yaml config in the current directory with the filename pluGET_config.yml
|
||||
"""
|
||||
# this is the whole yaml code because of weird formating indention is not possible
|
||||
configuration = """\
|
||||
#
|
||||
# Configuration File for pluGET
|
||||
# https://www.github.com/Neocky/pluGET
|
||||
#
|
||||
|
||||
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'
|
||||
# What should be used for the connection (local, sftp, ftp)
|
||||
Connection: local
|
||||
|
||||
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'][';'] = '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'
|
||||
Local:
|
||||
PathToPluginFolder: C:/Users/USER/Desktop/plugins
|
||||
# If a different folder should be used to store the updated plugins change to (True/False) and the path below
|
||||
SeperateDownloadPath : False
|
||||
PathToSeperateDownloadPath: C:/Users/USER/Desktop/plugins
|
||||
|
||||
Remote:
|
||||
Server: 0.0.0.0
|
||||
Username: user
|
||||
Password: password
|
||||
# If a different Port for SFTP/FTP will be used
|
||||
SFTP_Port: 22
|
||||
FTP_Port: 21
|
||||
# If a different folder should be used to store the updated plugins change to (True/False) and the path below
|
||||
SeperateDownloadPath : False
|
||||
PathToSeperateDownloadPath: /plugins/updated
|
||||
# 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)
|
||||
PluginFolderOnServer: /plugins
|
||||
"""
|
||||
# load ruamel.yaml to get the # commands right in the yaml code
|
||||
yaml = ruamel.yaml.YAML()
|
||||
code = yaml.load(configuration)
|
||||
with open("pluGET_config.yaml", "w") as config_file:
|
||||
yaml.dump(code, config_file)
|
||||
|
||||
config_file_path = os.path.abspath("pluGET_config.yaml")
|
||||
print(f"Path of config file: {config_file_path}")
|
||||
print("Config created. Edit config before executing again!")
|
||||
input("Press any key + enter to exit...")
|
||||
sys.exit()
|
||||
|
||||
|
||||
with open('config.ini', 'w') as configfile:
|
||||
config.write(configfile)
|
||||
def validate_config() -> None:
|
||||
"""
|
||||
Validates the config variables after config class is loaded and exit if error is detected and print error
|
||||
"""
|
||||
accepted_values = [
|
||||
("local", "sftp", "ftp")
|
||||
]
|
||||
# exit afterwards if there is an error in config
|
||||
exit_afterwards = False
|
||||
config = config_value()
|
||||
# rich console for nice colors
|
||||
console = Console()
|
||||
if config.connection not in accepted_values[0]:
|
||||
console.print(f"Error in Config! Accepted values for key 'Connection' are {accepted_values[0]}",
|
||||
style="bright_red")
|
||||
exit_afterwards = True
|
||||
if exit_afterwards:
|
||||
sys.exit()
|
||||
|
@ -1,110 +1,187 @@
|
||||
import os
|
||||
import sys
|
||||
import ftplib
|
||||
import stat
|
||||
import re
|
||||
|
||||
from utils.consoleoutput import oColors
|
||||
from handlers.handle_config import configurationValues
|
||||
from src.utils.console_output import rich_print_error
|
||||
from src.handlers.handle_config import config_value
|
||||
|
||||
|
||||
def createFTPConnection():
|
||||
configValues = configurationValues()
|
||||
ftp = ftplib.FTP(configValues.sftp_server, user=configValues.sftp_user, \
|
||||
passwd=configValues.sftp_password)
|
||||
def ftp_create_connection():
|
||||
"""
|
||||
Creates a connection to the ftp server with the given values in the config
|
||||
|
||||
:returns: ftp connection type
|
||||
"""
|
||||
config_values = config_value()
|
||||
try:
|
||||
ftp = ftplib.FTP()
|
||||
ftp.connect(config_values.server, config_values.ftp_port)
|
||||
ftp.login(config_values.username, config_values.password)
|
||||
return ftp
|
||||
except UnboundLocalError:
|
||||
print(oColors.brightRed + "[FTP]: Check your config.ini!" + oColors.standardWhite)
|
||||
print(oColors.brightRed + "Exiting program..." + oColors.standardWhite)
|
||||
rich_print_error("Error: [SFTP]: Check your config file!")
|
||||
rich_print_error("Exiting program...")
|
||||
sys.exit()
|
||||
|
||||
|
||||
def ftp_showPlugins(ftp):
|
||||
configValues = configurationValues()
|
||||
ftp.cwd(configValues.sftp_folderPath)
|
||||
def ftp_show_plugins(ftp) -> None:
|
||||
"""
|
||||
Prints all plugins in the plugin folder
|
||||
|
||||
:param ftp: ftp connection
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
config_values = config_value()
|
||||
ftp.cwd(config_values.remote_plugin_folder_on_server)
|
||||
for attr in ftp.dir():
|
||||
print(attr.filename, attr)
|
||||
return None
|
||||
|
||||
|
||||
def ftp_upload_file(ftp, itemPath):
|
||||
configValues = configurationValues()
|
||||
if configValues.sftp_seperateDownloadPath is True:
|
||||
uploadFolderPath = configValues.sftp_pathToSeperateDownloadPath
|
||||
def ftp_upload_file(ftp, path_item) -> None:
|
||||
"""
|
||||
Uploads a file to the ftp server
|
||||
|
||||
:param ftp: ftp connection
|
||||
:param path_item: Name of the item which should be uploaded
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
config_values = config_value()
|
||||
if config_values.remote_seperate_download_path is True:
|
||||
path_upload_folder = config_values.remote_path_to_seperate_download_path
|
||||
else:
|
||||
uploadFolderPath = configValues.sftp_folderPath
|
||||
path_upload_folder = config_values.remote_plugin_folder_on_server
|
||||
try:
|
||||
ftp.cwd(uploadFolderPath)
|
||||
itemPath = os.path.relpath(itemPath, 'TempSFTPFolder/')
|
||||
itemPath = str(itemPath)
|
||||
currentDirectory = os.getcwd()
|
||||
ftp.cwd(path_upload_folder)
|
||||
path_item = os.path.relpath(path_item, 'TempSFTPFolder/')
|
||||
path_item = str(path_item)
|
||||
current_directory = os.getcwd()
|
||||
os.chdir('TempSFTPFolder')
|
||||
with open (itemPath, 'rb') as plugin_file:
|
||||
ftp.storbinary('STOR '+ str(itemPath), plugin_file)
|
||||
with open (path_item, 'rb') as plugin_file:
|
||||
ftp.storbinary('STOR '+ str(path_item), 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)
|
||||
rich_print_error("Error: [FTP]: The 'plugins' folder couldn't be found on the remote host!")
|
||||
rich_print_error("Error: [FTP]: Aborting uploading.")
|
||||
os.chdir(current_directory)
|
||||
ftp.close()
|
||||
return None
|
||||
|
||||
|
||||
def ftp_upload_server_jar(ftp, itemPath):
|
||||
def ftp_upload_server_jar(ftp, path_item) -> None:
|
||||
"""
|
||||
Uploads a serverjar to the root folder of the ftp host
|
||||
|
||||
:param ftp: ftp connection
|
||||
:param path_item: Name of the file which should be uploaded
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
try:
|
||||
ftp.cwd('.')
|
||||
itemPath = os.path.relpath(itemPath, 'TempSFTPFolder/')
|
||||
itemPath = str(itemPath)
|
||||
currentDirectory = os.getcwd()
|
||||
path_item = os.path.relpath(path_item, 'TempSFTPFolder/')
|
||||
path_item = str(path_item)
|
||||
current_directory = os.getcwd()
|
||||
os.chdir('TempSFTPFolder')
|
||||
with open (itemPath, 'rb') as server_jar:
|
||||
ftp.storbinary('STOR '+ str(itemPath), server_jar)
|
||||
with open (path_item, 'rb') as server_jar:
|
||||
ftp.storbinary('STOR '+ str(path_item), 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)
|
||||
rich_print_error("Error: [FTP]: The 'root' folder couldn't be found on the remote host!")
|
||||
rich_print_error("Error: [FTP]: Aborting uploading.")
|
||||
os.chdir(current_directory)
|
||||
ftp.close()
|
||||
return None
|
||||
|
||||
|
||||
def ftp_listAll(ftp):
|
||||
configValues = configurationValues()
|
||||
def ftp_list_all(ftp):
|
||||
"""
|
||||
Returns a list with all installed plugins in the plugin folder of the ftp host
|
||||
|
||||
:param ftp: ftp connection
|
||||
|
||||
:returns: List of all plugins in plugin folder
|
||||
"""
|
||||
config_values = config_value()
|
||||
try:
|
||||
ftp.cwd(configValues.sftp_folderPath)
|
||||
installedPlugins = ftp.nlst()
|
||||
ftp.cwd(config_values.remote_plugin_folder_on_server)
|
||||
installed_plugins = ftp.nlst()
|
||||
except FileNotFoundError:
|
||||
print(oColors.brightRed + "[FTP]: The 'plugins' folder couldn*t be found on the remote host!" + oColors.standardWhite)
|
||||
rich_print_error("Error: [FTP]: The 'plugins' folder couldn't be found on the remote host!")
|
||||
|
||||
try:
|
||||
return installedPlugins
|
||||
return installed_plugins
|
||||
except UnboundLocalError:
|
||||
print(oColors.brightRed + "[FTP]: No plugins were found." + oColors.standardWhite)
|
||||
rich_print_error("Error: [FTP]: No plugins were found.")
|
||||
|
||||
|
||||
def ftp_listFilesInServerRoot(ftp):
|
||||
def ftp_list_files_in_server_root(ftp):
|
||||
"""
|
||||
Returns a list with all files in the root folder of the ftp host
|
||||
|
||||
:param ftp: ftp connection
|
||||
|
||||
:returns: List of all files in root folder
|
||||
"""
|
||||
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)
|
||||
rich_print_error("Error: [FTP]: The 'root' folder couldn't be found on the remote host!")
|
||||
|
||||
try:
|
||||
return filesInServerRoot
|
||||
except UnboundLocalError:
|
||||
print(oColors.brightRed + "[FTP]: No Serverjar was found." + oColors.standardWhite)
|
||||
rich_print_error("Error: [FTP]: No Serverjar was found.")
|
||||
|
||||
|
||||
def ftp_downloadFile(ftp, downloadPath, fileToDownload):
|
||||
configValues = configurationValues()
|
||||
ftp.cwd(configValues.sftp_folderPath)
|
||||
filedata = open(downloadPath,'wb')
|
||||
ftp.retrbinary('RETR '+fileToDownload, filedata.write)
|
||||
def ftp_download_file(ftp, path_download, file) -> None:
|
||||
"""
|
||||
Download a file of the ftp server
|
||||
|
||||
:param ftp: ftp connection
|
||||
:param path_download: Path to save downloaded file to
|
||||
:param file: File to download
|
||||
|
||||
:returns None
|
||||
"""
|
||||
config_values = config_value()
|
||||
ftp.cwd(config_values.remote_plugin_folder_on_server)
|
||||
filedata = open(path_download,'wb')
|
||||
ftp.retrbinary('RETR '+file, filedata.write)
|
||||
filedata.close()
|
||||
ftp.quit()
|
||||
return None
|
||||
|
||||
|
||||
def ftp_validateFileAttributes(ftp, pluginPath):
|
||||
pluginFTPAttribute = ftp.lstat(pluginPath)
|
||||
if stat.S_ISDIR(pluginFTPAttribute.st_mode):
|
||||
return False
|
||||
elif re.search(r'.jar$', pluginPath):
|
||||
def ftp_is_file(ftp, plugin_path) -> bool:
|
||||
"""
|
||||
Check if file on ftp host is a file and not a directory
|
||||
|
||||
:param ftp: ftp connection
|
||||
:param plugin_path
|
||||
|
||||
:returns: True if file is a file and not a directory
|
||||
"""
|
||||
if ftp.nlst(plugin_path) == [plugin_path]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def ftp_validate_file_attributes(ftp, plugin_path) -> bool:
|
||||
"""
|
||||
Check if a file is a legitimate plugin file
|
||||
|
||||
:param ftp: ftp connection
|
||||
:param plugin_path: Path of file to check
|
||||
|
||||
:returns: If file is a plugin file or not
|
||||
"""
|
||||
if ftp_is_file(ftp, plugin_path) is False:
|
||||
return False
|
||||
if re.search(r'.jar$', plugin_path):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
@ -1,105 +1,128 @@
|
||||
import sys
|
||||
""""
|
||||
Handles the input through the pluGET command line
|
||||
"""
|
||||
|
||||
from utils.consoleoutput import oColors
|
||||
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
|
||||
from src.utils.console_output import rich_print_error
|
||||
from src.utils.utilities import get_command_help
|
||||
from src.plugin.plugin_remover import delete_plugin
|
||||
from src.plugin.plugin_downloader import get_specific_plugin_spiget, search_specific_plugin_spiget
|
||||
from src.plugin.plugin_updatechecker import check_installed_plugins, update_installed_plugins
|
||||
from src.serverjar.serverjar_updatechecker import \
|
||||
check_update_available_installed_server_jar, update_installed_server_jar
|
||||
from src.serverjar.serverjar_paper_velocity_waterfall import serverjar_papermc_update
|
||||
from src.serverjar.serverjar_purpur import serverjar_purpur_update
|
||||
|
||||
|
||||
def createInputLists():
|
||||
global COMMANDLIST
|
||||
COMMANDLIST = [
|
||||
'get',
|
||||
'update',
|
||||
'check',
|
||||
'search',
|
||||
'exit',
|
||||
'help',
|
||||
'remove',
|
||||
'get-paper'
|
||||
]
|
||||
global INPUTSELECTEDOBJECT
|
||||
INPUTSELECTEDOBJECT = [
|
||||
'all',
|
||||
'*'
|
||||
]
|
||||
# check
|
||||
# update
|
||||
# get
|
||||
# get-paper
|
||||
# get-waterfall
|
||||
# get-velocity
|
||||
# get-purpur
|
||||
# exit
|
||||
# remove
|
||||
# search
|
||||
# help
|
||||
|
||||
|
||||
def handleInput(inputCommand, inputSelectedObject, inputParams):
|
||||
configValues = configurationValues()
|
||||
def handle_input(
|
||||
input_command : str=None,
|
||||
input_selected_object : str=None,
|
||||
input_parameter : str=None,
|
||||
no_confirmation : bool=False,
|
||||
arguments_from_console : bool=False
|
||||
) -> None:
|
||||
"""
|
||||
Manages the correct function calling from the given input
|
||||
|
||||
:param input_command: Command of main function
|
||||
:param input_selected_object: Name of plugin/serverjar
|
||||
:param: input_parameter: Optional parameters
|
||||
:param no_confirmation: If plugins should be updated without no confirmation message
|
||||
:param arguments_from_console: If arguments were given on script call
|
||||
|
||||
:returns None:
|
||||
"""
|
||||
while True:
|
||||
if inputCommand == 'get':
|
||||
if inputSelectedObject.isdigit():
|
||||
if not configValues.localPluginFolder:
|
||||
if configValues.sftp_seperateDownloadPath is True:
|
||||
pluginPath = configValues.sftp_pathToSeperateDownloadPath
|
||||
else:
|
||||
pluginPath = configValues.sftp_folderPath
|
||||
getSpecificPackage(inputSelectedObject, pluginPath, inputParams)
|
||||
break
|
||||
else:
|
||||
if configValues.seperateDownloadPath is True:
|
||||
pluginPath = configValues.pathToSeperateDownloadPath
|
||||
else:
|
||||
pluginPath = configValues.pathToPluginFolder
|
||||
getSpecificPackage(inputSelectedObject, pluginPath, inputParams)
|
||||
break
|
||||
else:
|
||||
searchPackage(inputSelectedObject)
|
||||
break
|
||||
if inputCommand == 'update':
|
||||
if inputSelectedObject == 'serverjar':
|
||||
updateServerjar(inputParams)
|
||||
else:
|
||||
updateInstalledPackage(inputSelectedObject)
|
||||
break
|
||||
if inputCommand == 'check':
|
||||
if inputSelectedObject == 'serverjar':
|
||||
checkInstalledServerjar()
|
||||
else:
|
||||
checkInstalledPackage(inputSelectedObject, inputParams)
|
||||
break
|
||||
if inputCommand == 'search':
|
||||
searchPackage(inputSelectedObject)
|
||||
break
|
||||
if inputCommand == 'exit':
|
||||
sys.exit()
|
||||
if inputCommand == 'help':
|
||||
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 + "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()
|
||||
# when arguemnts were not passed from console ask for input
|
||||
if arguments_from_console is False:
|
||||
try:
|
||||
input_command, input_selected_object, input_parameter = get_input()
|
||||
except TypeError:
|
||||
# KeyboardInterrupt was triggered and None was returned so exit
|
||||
return
|
||||
|
||||
match input_command:
|
||||
case "get":
|
||||
match input_selected_object.isdigit():
|
||||
case True:
|
||||
get_specific_plugin_spiget(input_selected_object, input_parameter)
|
||||
case _:
|
||||
search_specific_plugin_spiget(input_selected_object)
|
||||
|
||||
case "get-paper":
|
||||
serverjar_papermc_update(input_selected_object, input_parameter, None, "paper")
|
||||
case "get-velocity":
|
||||
serverjar_papermc_update(input_selected_object, input_parameter, None, "velocity")
|
||||
case "get-waterfall":
|
||||
serverjar_papermc_update(input_selected_object, input_parameter, None, "waterfall")
|
||||
case "get-purpur":
|
||||
serverjar_purpur_update(input_selected_object, input_parameter, None)
|
||||
|
||||
case "update":
|
||||
match input_selected_object:
|
||||
case "serverjar":
|
||||
update_installed_server_jar(input_parameter)
|
||||
case _:
|
||||
update_installed_plugins(input_selected_object, no_confirmation)
|
||||
|
||||
case "check":
|
||||
match input_selected_object:
|
||||
case "serverjar":
|
||||
check_update_available_installed_server_jar()
|
||||
case _:
|
||||
check_installed_plugins(input_selected_object, input_parameter)
|
||||
|
||||
case "search":
|
||||
search_specific_plugin_spiget(input_selected_object)
|
||||
case "remove":
|
||||
delete_plugin(input_selected_object)
|
||||
case "help":
|
||||
get_command_help(input_selected_object)
|
||||
case "exit":
|
||||
return
|
||||
case _:
|
||||
rich_print_error("Error: Command not found. Please try again. :(")
|
||||
rich_print_error("Use [bright_blue]'help all' [bright_red]to get a list of all available commands.")
|
||||
|
||||
# return to break out of while loop if pluGET was started with arguments from console
|
||||
if arguments_from_console:
|
||||
return None
|
||||
|
||||
|
||||
def getInput():
|
||||
inputCommand = None
|
||||
def get_input() -> str:
|
||||
"""
|
||||
Gets command line input and calls the handle input function
|
||||
|
||||
:returns: Main command to execute
|
||||
:returns: Selected Object to work with
|
||||
:returns: Optional parameter
|
||||
"""
|
||||
input_command = None
|
||||
print("\n'STRG + C' to exit")
|
||||
while True:
|
||||
try:
|
||||
inputCommand, inputSelectedObject, *inputParams = input("pluGET >> ").split()
|
||||
input_command, input_selected_object, *input_parameter = input("pluGET >> ").split()
|
||||
break
|
||||
except ValueError:
|
||||
if inputCommand == None:
|
||||
if input_command == None:
|
||||
# request input again if no input was given or not enough
|
||||
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)
|
||||
rich_print_error("Wrong input! Use: > 'command' 'selectedObject' [optionalParams]")
|
||||
rich_print_error("Use: [bright_blue]'help all' [bright_red]to get a list of all available commands.")
|
||||
except KeyboardInterrupt:
|
||||
sys.exit()
|
||||
inputParams = inputParams[0] if inputParams else None
|
||||
handleInput(inputCommand, inputSelectedObject, inputParams)
|
||||
return
|
||||
input_parameter = input_parameter[0] if input_parameter else None
|
||||
return input_command, input_selected_object, input_parameter
|
||||
|
@ -5,103 +5,164 @@ import paramiko
|
||||
import stat
|
||||
import re
|
||||
|
||||
from utils.consoleoutput import oColors
|
||||
from handlers.handle_config import configurationValues
|
||||
from src.utils.console_output import rich_print_error
|
||||
from src.handlers.handle_config import config_value
|
||||
|
||||
|
||||
def createSFTPConnection():
|
||||
configValues = configurationValues()
|
||||
def sftp_create_connection():
|
||||
"""
|
||||
Creates a sftp connection with the given values in the config file
|
||||
|
||||
:returns: SFTP connection type
|
||||
"""
|
||||
config_values = config_value()
|
||||
cnopts = pysftp.CnOpts()
|
||||
cnopts.hostkeys = None # TODO fix this
|
||||
try:
|
||||
sftp = pysftp.Connection(configValues.sftp_server, username=configValues.sftp_user, \
|
||||
password=configValues.sftp_password, port=configValues.sftp_port, cnopts=cnopts)
|
||||
sftp = pysftp.Connection(config_values.server, username=config_values.username, \
|
||||
password=config_values.password, port=config_values.sftp_port, cnopts=cnopts)
|
||||
except paramiko.ssh_exception.AuthenticationException:
|
||||
print(oColors.brightRed + "[SFTP]: Wrong Username/Password" + oColors.standardWhite)
|
||||
rich_print_error("Error: [SFTP]: Wrong Username/Password")
|
||||
except paramiko.ssh_exception.SSHException:
|
||||
print(oColors.brightRed + "[SFTP]: The SFTP server isn't available." + oColors.standardWhite)
|
||||
rich_print_error("Error: [SFTP]: The SFTP server isn't available.")
|
||||
try:
|
||||
return sftp
|
||||
except UnboundLocalError:
|
||||
print(oColors.brightRed + "[SFTP]: Check your config.ini!" + oColors.standardWhite)
|
||||
print(oColors.brightRed + "Exiting program..." + oColors.standardWhite)
|
||||
rich_print_error("Error: [SFTP]: Check your config file!")
|
||||
rich_print_error("Exiting program...")
|
||||
sys.exit()
|
||||
|
||||
|
||||
def sftp_showPlugins(sftp):
|
||||
configValues = configurationValues()
|
||||
sftp.cd(configValues.sftp_folderPath)
|
||||
def sftp_show_plugins(sftp) -> None:
|
||||
"""
|
||||
Prints all plugins in the sftp folder
|
||||
|
||||
:param sftp: sftp connection
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
config_values = config_value()
|
||||
sftp.cd(config_values.remote_plugin_folder_on_server)
|
||||
for attr in sftp.listdir_attr():
|
||||
print(attr.filename, attr)
|
||||
|
||||
|
||||
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(uploadFolderPath)
|
||||
sftp.put(itemPath)
|
||||
|
||||
except FileNotFoundError:
|
||||
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()
|
||||
return None
|
||||
|
||||
|
||||
def sftp_upload_server_jar(sftp, itemPath):
|
||||
def sftp_upload_file(sftp, path_item) -> None:
|
||||
"""
|
||||
Uploads a file to the set folder from the config file
|
||||
|
||||
:param sftp: sftp connection
|
||||
:param path_item: The upload path with the item name
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
config_values = config_value()
|
||||
if config_values.remote_seperate_download_path is True:
|
||||
path_upload_folder = config_values.remote_path_to_seperate_download_path
|
||||
else:
|
||||
path_upload_folder = config_values.remote_plugin_folder_on_server
|
||||
try:
|
||||
sftp.chdir(path_upload_folder)
|
||||
sftp.put(path_item)
|
||||
except FileNotFoundError:
|
||||
rich_print_error("Error: [SFTP]: The 'plugins' folder couldn't be found on the remote host!")
|
||||
rich_print_error("Error: [SFTP]: Aborting uploading.")
|
||||
sftp.close()
|
||||
return None
|
||||
|
||||
|
||||
def sftp_upload_server_jar(sftp, path_item) -> None:
|
||||
"""
|
||||
Uploads the server jar to the root folder
|
||||
|
||||
:param sftp: sftp connection
|
||||
:param path_item: The upload path with the item name
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
try:
|
||||
sftp.chdir('.')
|
||||
sftp.put(itemPath)
|
||||
sftp.put(path_item)
|
||||
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)
|
||||
rich_print_error("Error: [SFTP]: The 'root' folder couldn't be found on the remote host!")
|
||||
rich_print_error("Error: [SFTP]: Aborting uploading.")
|
||||
sftp.close()
|
||||
return None
|
||||
|
||||
|
||||
def sftp_listAll(sftp):
|
||||
configValues = configurationValues()
|
||||
def sftp_list_all(sftp):
|
||||
"""
|
||||
List all plugins in the 'plugins' folder on the sftp host
|
||||
|
||||
:param sftp: sftp connection
|
||||
|
||||
:return: List of plugins in plugin folder
|
||||
"""
|
||||
config_values = config_value()
|
||||
try:
|
||||
sftp.chdir(configValues.sftp_folderPath)
|
||||
installedPlugins = sftp.listdir()
|
||||
sftp.chdir(config_values.remote_plugin_folder_on_server)
|
||||
installed_plugins = sftp.listdir()
|
||||
except FileNotFoundError:
|
||||
print(oColors.brightRed + "[SFTP]: The 'plugins' folder couldn*t be found on the remote host!" + oColors.standardWhite)
|
||||
rich_print_error("Error: [SFTP]: The 'plugins' folder couldn't be found on the remote host!")
|
||||
|
||||
try:
|
||||
return installedPlugins
|
||||
return installed_plugins
|
||||
except UnboundLocalError:
|
||||
print(oColors.brightRed + "[SFTP]: No plugins were found." + oColors.standardWhite)
|
||||
rich_print_error("Error: [SFTP]: No plugins were found.")
|
||||
|
||||
|
||||
def sftp_listFilesInServerRoot(sftp):
|
||||
def sftp_list_files_in_server_root(sftp):
|
||||
"""
|
||||
List all files in the root folder on the sftp host
|
||||
|
||||
:param sftp: sftp connection
|
||||
|
||||
:returns: List of files in root folder
|
||||
"""
|
||||
try:
|
||||
filesInServerRoot = sftp.listdir()
|
||||
files_in_server_root = sftp.listdir()
|
||||
except FileNotFoundError:
|
||||
print(oColors.brightRed + "[SFTP]: The 'root' folder couldn*t be found on the remote host!" + oColors.standardWhite)
|
||||
|
||||
rich_print_error("Error: [SFTP]: The 'root' folder couldn't be found on the remote host!")
|
||||
try:
|
||||
return filesInServerRoot
|
||||
return files_in_server_root
|
||||
except UnboundLocalError:
|
||||
print(oColors.brightRed + "[SFTP]: No Serverjar was found." + oColors.standardWhite)
|
||||
rich_print_error("Error: [SFTP]: No Serverjar was found.")
|
||||
|
||||
|
||||
def sftp_downloadFile(sftp, downloadPath, fileToDownload):
|
||||
configValues = configurationValues()
|
||||
sftp.cwd(configValues.sftp_folderPath)
|
||||
currentDirectory = os.getcwd()
|
||||
def sftp_download_file(sftp, file) -> None:
|
||||
"""
|
||||
Downloads a plugin file from the sftp host to a temporary folder
|
||||
|
||||
:param sftp: sftp connection
|
||||
:param file: Filename of plugin
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
config_values = config_value()
|
||||
sftp.cwd(config_values.remote_plugin_folder_on_server)
|
||||
current_directory = os.getcwd()
|
||||
os.chdir('TempSFTPFolder')
|
||||
sftp.get(fileToDownload)
|
||||
sftp.get(file)
|
||||
sftp.close()
|
||||
os.chdir(currentDirectory)
|
||||
os.chdir(current_directory)
|
||||
return None
|
||||
|
||||
|
||||
def sftp_validateFileAttributes(sftp, pluginPath):
|
||||
pluginSFTPAttribute = sftp.lstat(pluginPath)
|
||||
if stat.S_ISDIR(pluginSFTPAttribute.st_mode):
|
||||
def sftp_validate_file_attributes(sftp, plugin_path) -> bool:
|
||||
"""
|
||||
Check if the file is a legitimate plugin file
|
||||
|
||||
:param sftp: sftp connection
|
||||
param plugin_path: Path of the single plugin file
|
||||
|
||||
:returns: If file is a plugin file or not
|
||||
"""
|
||||
plugin_sftp_attribute = sftp.lstat(plugin_path)
|
||||
if stat.S_ISDIR(plugin_sftp_attribute.st_mode):
|
||||
return False
|
||||
elif re.search(r'.jar$', pluginPath):
|
||||
elif re.search(r'.jar$', plugin_path):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
@ -1,148 +1,245 @@
|
||||
"""
|
||||
File and functions which handle the download of the specific plugins
|
||||
"""
|
||||
|
||||
import re
|
||||
import urllib.request
|
||||
from urllib.error import HTTPError
|
||||
from pathlib import Path
|
||||
import requests
|
||||
|
||||
from utils.consoleoutput import oColors
|
||||
from utils.web_request import doAPIRequest
|
||||
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
|
||||
from rich.table import Table
|
||||
from rich.console import Console
|
||||
from rich.progress import Progress
|
||||
|
||||
from src.utils.utilities import convert_file_size_down, remove_temp_plugin_folder, create_temp_plugin_folder
|
||||
from src.utils.utilities import api_do_request
|
||||
from src.utils.console_output import rich_print_error
|
||||
from src.handlers.handle_config import config_value
|
||||
from src.handlers.handle_sftp import sftp_create_connection, sftp_upload_file
|
||||
from src.handlers.handle_ftp import ftp_create_connection, ftp_upload_file
|
||||
|
||||
|
||||
def handleRegexPackageName(packageNameFull):
|
||||
packageNameFull2 = packageNameFull
|
||||
def handle_regex_plugin_name(full_plugin_name) -> str:
|
||||
"""
|
||||
Return the plugin name after trimming clutter from name with regex operations
|
||||
"""
|
||||
# trims the part of the package that has for example "[1.1 Off]" in it
|
||||
unwantedpackageName = re.search(r'(^\[+[a-zA-Z0-9\s\W*\.*\-*\+*\%*\,]*\]+)', packageNameFull)
|
||||
unwantedpackageNamematch = bool(unwantedpackageName)
|
||||
if unwantedpackageNamematch:
|
||||
unwantedpackageNameString = unwantedpackageName.group()
|
||||
packageNameFull2 = packageNameFull.replace(unwantedpackageNameString, '')
|
||||
# gets the real packagename "word1 & word2" is not supported only gets word 1
|
||||
packageName = re.search(r'([a-zA-Z]\d*)+(\s?\-*\_*[a-zA-Z]\d*\+*\-*\'*)+', packageNameFull2)
|
||||
packageNameFullString = packageName.group()
|
||||
packageNameOnly = packageNameFullString.replace(' ', '')
|
||||
return packageNameOnly
|
||||
unwanted_plugin_name = re.search(r'(^\[+[a-zA-Z0-9\s\W*\.*\-*\+*\%*\,]*\]+)', full_plugin_name)
|
||||
if bool(unwanted_plugin_name):
|
||||
unwanted_plugin_name_string = unwanted_plugin_name.group()
|
||||
full_plugin_name = full_plugin_name.replace(unwanted_plugin_name_string, '')
|
||||
|
||||
# gets the real plugin_name "word1 & word2" is not supported only gets word1
|
||||
plugin_name = re.search(r'([a-zA-Z]\d*)+(\s?\-*\_*[a-zA-Z]\d*\+*\-*\'*)+', full_plugin_name)
|
||||
try:
|
||||
plugin_name_full_string = plugin_name.group()
|
||||
found_plugin_name = plugin_name_full_string.replace(' ', '')
|
||||
except AttributeError:
|
||||
found_plugin_name = unwanted_plugin_name_string
|
||||
return found_plugin_name
|
||||
|
||||
|
||||
def getVersionID(packageId, packageVersion):
|
||||
if packageVersion == None or packageVersion == 'latest':
|
||||
url = f"https://api.spiget.org/v2/resources/{packageId}/versions/latest"
|
||||
response = doAPIRequest(url)
|
||||
versionId = response["id"]
|
||||
return versionId
|
||||
def get_version_id_spiget(plugin_id, plugin_version) -> str:
|
||||
"""
|
||||
Returns the version id of the plugin
|
||||
"""
|
||||
if plugin_version == None or plugin_version == 'latest':
|
||||
url = f"https://api.spiget.org/v2/resources/{plugin_id}/versions/latest"
|
||||
response = api_do_request(url)
|
||||
if response == None:
|
||||
return None
|
||||
version_id = response["id"]
|
||||
return version_id
|
||||
|
||||
url = f"https://api.spiget.org/v2/resources/{packageId}/versions?size=100&sort=-name"
|
||||
versionList = doAPIRequest(url)
|
||||
|
||||
for packages in versionList:
|
||||
packageUpdate = packages["name"]
|
||||
versionId = packages["id"]
|
||||
if packageUpdate == packageVersion:
|
||||
return versionId
|
||||
return versionList[0]["id"]
|
||||
url = f"https://api.spiget.org/v2/resources/{plugin_id}/versions?size=100&sort=-name"
|
||||
version_list = api_do_request(url)
|
||||
if version_list == None:
|
||||
return None
|
||||
for plugins in version_list:
|
||||
plugin_update = plugins["name"]
|
||||
version_id = plugins["id"]
|
||||
if plugin_update == plugin_version:
|
||||
return version_id
|
||||
return version_list[0]["id"]
|
||||
|
||||
|
||||
def getVersionName(packageId, versionId):
|
||||
url = f"https://api.spiget.org/v2/resources/{packageId}/versions/{versionId}"
|
||||
response = doAPIRequest(url)
|
||||
versionName = response["name"]
|
||||
return versionName
|
||||
def get_version_name_spiget(plugin_id, plugin_version_id) -> str:
|
||||
"""
|
||||
Returns the name of a specific version
|
||||
"""
|
||||
url = f"https://api.spiget.org/v2/resources/{plugin_id}/versions/{plugin_version_id}"
|
||||
response = api_do_request(url)
|
||||
if response == None:
|
||||
return None
|
||||
version_name = response["name"]
|
||||
return version_name
|
||||
|
||||
|
||||
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(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 = resource["tag"]
|
||||
pDownloads = resource["downloads"]
|
||||
print(f" [{i}]".rjust(6), end='')
|
||||
print(" ", end='')
|
||||
print(f"{newName}".ljust(30), end='')
|
||||
print(f"{pDownloads}".rjust(9), end='')
|
||||
print(" ", end='')
|
||||
print(f"{pTag}".ljust(120))
|
||||
i = i + 1
|
||||
def get_download_path(config_values) -> str:
|
||||
"""
|
||||
Reads the config and gets the path of the plugin folder
|
||||
"""
|
||||
match (config_values.connection):
|
||||
case "local":
|
||||
match (config_values.local_seperate_download_path):
|
||||
case True:
|
||||
return config_values.local_path_to_seperate_download_path
|
||||
case _:
|
||||
return config_values.path_to_plugin_folder
|
||||
case _:
|
||||
match (config_values.remote_seperate_download_path):
|
||||
case True:
|
||||
return config_values.remote_path_to_seperate_download_path
|
||||
case _:
|
||||
return config_values.remote_plugin_folder_on_server
|
||||
|
||||
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:
|
||||
if configValues.seperateDownloadPath is True:
|
||||
pluginDownloadPath = configValues.pathToSeperateDownloadPath
|
||||
else:
|
||||
pluginDownloadPath = configValues.pathToPluginFolder
|
||||
|
||||
def download_specific_plugin_version_spiget(plugin_id, download_path, version_id="latest") -> None:
|
||||
"""
|
||||
Download a specific plugin
|
||||
"""
|
||||
config_values = config_value()
|
||||
if version_id != "latest" and version_id != None:
|
||||
#url = f"https://spigotmc.org/resources/{plugin_id}/download?version={versionID}"
|
||||
rich_print_error("Sorry but specific version downloads aren't supported because of cloudflare protection. :(")
|
||||
rich_print_error("Reverting to latest version.")
|
||||
|
||||
#throws 403 forbidden error...cloudflare :(
|
||||
#url = f"https://api.spiget.org/v2/resources/{plugin_id}/versions/latest/download"
|
||||
|
||||
url = f"https://api.spiget.org/v2/resources/{plugin_id}/download"
|
||||
|
||||
# use rich Progress() to create progress bar
|
||||
with Progress(transient=True) as progress:
|
||||
header = {'user-agent': 'pluGET/1.0'}
|
||||
r = requests.get(url, headers=header, stream=True)
|
||||
try:
|
||||
getSpecificPackage(resourceId, pluginDownloadPath)
|
||||
except HTTPError as err:
|
||||
print(oColors.brightRed + f"Error: {err.code} - {err.reason}" + oColors.standardWhite)
|
||||
file_size = int(r.headers.get('content-length'))
|
||||
# create progress bar
|
||||
download_task = progress.add_task(" [cyan]Downloading...", total=file_size)
|
||||
except TypeError:
|
||||
# Content-lenght returned nothing
|
||||
file_size = 0
|
||||
with open(download_path, 'wb') as f:
|
||||
# split downloaded data in chunks of 32768
|
||||
for data in r.iter_content(chunk_size=32768):
|
||||
f.write(data)
|
||||
# don't show progress bar if no content-length was returned
|
||||
if file_size == 0:
|
||||
continue
|
||||
progress.update(download_task, advance=len(data))
|
||||
#f.flush()
|
||||
|
||||
|
||||
def downloadSpecificVersion(resourceId, downloadPath, versionID='latest'):
|
||||
configValues = configurationValues()
|
||||
if versionID != 'latest':
|
||||
#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/{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)
|
||||
filesize = int(filesize)
|
||||
print(" ", end='')
|
||||
if filesize >= 1000000:
|
||||
filesizeData = calculateFileSizeMb(filesize)
|
||||
print("Downloaded " + (str(filesizeData)).rjust(9) + f" MB here {downloadPath}")
|
||||
# use rich console for nice colors
|
||||
console = Console()
|
||||
if file_size == 0:
|
||||
console.print(
|
||||
f" [not bold][bright_green]Downloaded[bright_magenta] file [cyan]→ [white]{download_path}"
|
||||
)
|
||||
elif file_size >= 1000000:
|
||||
file_size_data = convert_file_size_down(convert_file_size_down(file_size))
|
||||
console.print(" [not bold][bright_green]Downloaded[bright_magenta] " + (str(file_size_data)).rjust(9) + \
|
||||
f" MB [cyan]→ [white]{download_path}")
|
||||
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)
|
||||
file_size_data = convert_file_size_down(file_size)
|
||||
console.print(" [not bold][bright_green]Downloaded[bright_magenta] " + (str(file_size_data)).rjust(9) + \
|
||||
f" KB [cyan]→ [white]{download_path}")
|
||||
|
||||
if config_values.connection == "sftp":
|
||||
sftp_session = sftp_create_connection()
|
||||
sftp_upload_file(sftp_session, download_path)
|
||||
elif config_values.connection == "ftp":
|
||||
ftp_session = ftp_create_connection()
|
||||
ftp_upload_file(ftp_session, download_path)
|
||||
return None
|
||||
|
||||
|
||||
def getSpecificPackage(resourceId, downloadPath, inputPackageVersion='latest'):
|
||||
configValues = configurationValues()
|
||||
if configValues.localPluginFolder == False:
|
||||
downloadPath = createTempPluginFolder()
|
||||
url = f"https://api.spiget.org/v2/resources/{resourceId}"
|
||||
packageDetails = doAPIRequest(url)
|
||||
packageName = packageDetails["name"]
|
||||
packageNameNew = handleRegexPackageName(packageName)
|
||||
versionId = getVersionID(resourceId, inputPackageVersion)
|
||||
packageVersion = getVersionName(resourceId, versionId)
|
||||
packageDownloadName = f"{packageNameNew}-{packageVersion}.jar"
|
||||
downloadPackagePath = Path(f"{downloadPath}/{packageDownloadName}")
|
||||
if inputPackageVersion is None or inputPackageVersion == 'latest':
|
||||
downloadSpecificVersion(resourceId=resourceId, downloadPath=downloadPackagePath)
|
||||
def get_specific_plugin_spiget(plugin_id, plugin_version="latest") -> None:
|
||||
"""
|
||||
Gets the specific plugin and calls the download function
|
||||
"""
|
||||
config_values = config_value()
|
||||
# use a temporary folder to store plugins until they are uploaded
|
||||
if config_values.connection != "local":
|
||||
download_path = create_temp_plugin_folder()
|
||||
else:
|
||||
downloadSpecificVersion(resourceId, downloadPackagePath, versionId)
|
||||
download_path = get_download_path(config_values)
|
||||
|
||||
if not configValues.localPluginFolder:
|
||||
deleteTempPluginFolder(downloadPath)
|
||||
url = f"https://api.spiget.org/v2/resources/{plugin_id}"
|
||||
plugin_details = api_do_request(url)
|
||||
if plugin_details == None:
|
||||
return None
|
||||
try:
|
||||
plugin_name = plugin_details["name"]
|
||||
except KeyError:
|
||||
# exit if plugin id couldn't be found
|
||||
rich_print_error("Error: Plugin ID couldn't be found")
|
||||
return None
|
||||
plugin_name = handle_regex_plugin_name(plugin_name)
|
||||
plugin_version_id = get_version_id_spiget(plugin_id, plugin_version)
|
||||
plugin_version_name = get_version_name_spiget(plugin_id, plugin_version_id)
|
||||
plugin_download_name = f"{plugin_name}-{plugin_version_name}.jar"
|
||||
download_plugin_path = Path(f"{download_path}/{plugin_download_name}")
|
||||
# if api requests weren't successfull stop function
|
||||
if plugin_version_id == None or plugin_version_name == None:
|
||||
rich_print_error("Error: Webrequest timed out")
|
||||
return None
|
||||
# set the plugin_version_id to None if a specific version wasn't given as parameter
|
||||
if plugin_version == "latest" or plugin_version is None:
|
||||
plugin_version_id = None
|
||||
download_specific_plugin_version_spiget(plugin_id, download_plugin_path, plugin_version_id)
|
||||
|
||||
if config_values.connection != "local":
|
||||
remove_temp_plugin_folder()
|
||||
return None
|
||||
|
||||
|
||||
def search_specific_plugin_spiget(plugin_name) -> None:
|
||||
"""
|
||||
Search for a name and return the top 10 results sorted for their download count
|
||||
Then ask for input and download that plugin
|
||||
"""
|
||||
url= f"https://api.spiget.org/v2/search/resources/{plugin_name}?field=name&sort=-downloads"
|
||||
plugin_search_results = api_do_request(url)
|
||||
if plugin_search_results == None:
|
||||
rich_print_error("Error: Webrequest wasn't successfull!")
|
||||
return None
|
||||
|
||||
print(f"Searching for {plugin_name}...")
|
||||
print(f"Found plugins:")
|
||||
# create table with rich
|
||||
rich_table = Table(box=None)
|
||||
rich_table.add_column("No.", justify="right", style="cyan", no_wrap=True)
|
||||
rich_table.add_column("Name", style="bright_magenta")
|
||||
rich_table.add_column("Downloads", justify="right", style="bright_green")
|
||||
rich_table.add_column("Description", justify="left", style="white")
|
||||
# start counting at 1 for all my non-programming friends :)
|
||||
i = 1
|
||||
for found_plugin in plugin_search_results:
|
||||
plugin_name = handle_regex_plugin_name(found_plugin["name"])
|
||||
plugin_downloads = found_plugin["downloads"]
|
||||
plugin_description = found_plugin["tag"]
|
||||
rich_table.add_row(str(i), plugin_name, str(plugin_downloads), plugin_description)
|
||||
i += 1
|
||||
|
||||
# print table from rich
|
||||
rich_console = Console()
|
||||
rich_console.print(rich_table)
|
||||
|
||||
try:
|
||||
plugin_selected = input("Select your wanted resource (No.)(0 to exit): ")
|
||||
except KeyboardInterrupt:
|
||||
return None
|
||||
if plugin_selected == "0":
|
||||
return None
|
||||
try:
|
||||
plugin_selected = int(plugin_selected) - 1
|
||||
plugin_selected_id = plugin_search_results[plugin_selected]["id"]
|
||||
except ValueError:
|
||||
rich_print_error("Error: Input wasn't a number! Please try again!")
|
||||
return None
|
||||
except IndexError:
|
||||
rich_print_error("Error: Number was out of range! Please try again!")
|
||||
return None
|
||||
selected_plugin_name = handle_regex_plugin_name(plugin_search_results[plugin_selected]["name"])
|
||||
rich_console.print(f"\n [not bold][bright_white]● [bright_magenta]{selected_plugin_name} [bright_green]latest")
|
||||
get_specific_plugin_spiget(plugin_selected_id)
|
||||
|
@ -1,59 +1,56 @@
|
||||
"""
|
||||
Removes the specified plugin file from the ./plugins folder
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
from rich.console import Console
|
||||
|
||||
from utils.consoleoutput import oColors
|
||||
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
|
||||
from src.handlers.handle_config import config_value
|
||||
from src.utils.console_output import rich_print_error
|
||||
from src.handlers.handle_sftp import sftp_create_connection, sftp_list_all
|
||||
from src.handlers.handle_ftp import ftp_create_connection, ftp_list_all
|
||||
|
||||
|
||||
def removePlugin(pluginToRemove):
|
||||
configValues = configurationValues()
|
||||
createPluginList()
|
||||
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(configValues.pathToPluginFolder)
|
||||
i = 0
|
||||
try:
|
||||
for plugin in pluginList:
|
||||
try:
|
||||
fileName = getFileName(plugin)
|
||||
fileVersion = getFileVersion(plugin)
|
||||
pluginId = getInstalledPlugin(fileName, fileVersion)
|
||||
except TypeError:
|
||||
continue
|
||||
pluginIdStr = str(pluginId)
|
||||
def delete_plugin(plugin_name: str) -> None:
|
||||
"""
|
||||
Deletes the specific plugin file
|
||||
|
||||
if pluginToRemove == pluginIdStr or re.search(pluginToRemove, fileName, re.IGNORECASE):
|
||||
print(f"Removing: {fileName}")
|
||||
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 = configValues.pathToPluginFolder
|
||||
pluginPath = Path(f"{pluginPath}/{plugin}")
|
||||
:param plugin_name: Name of plugin file to delete
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
config_values = config_value()
|
||||
rich_console = Console()
|
||||
match config_values.connection:
|
||||
case "sftp":
|
||||
connection = sftp_create_connection()
|
||||
plugin_list = sftp_list_all()
|
||||
case "ftp":
|
||||
connection = ftp_create_connection()
|
||||
plugin_list = ftp_list_all()
|
||||
case "local":
|
||||
plugin_list = os.listdir(config_values.path_to_plugin_folder)
|
||||
for plugin_file in plugin_list:
|
||||
# skip all other plugins
|
||||
if not re.search(plugin_name, plugin_file, re.IGNORECASE):
|
||||
continue
|
||||
|
||||
try:
|
||||
match config_values.connection:
|
||||
case "sftp":
|
||||
plugin_path = f"{config_values.remote_plugin_folder_on_server}/{plugin_file}"
|
||||
connection = sftp_create_connection()
|
||||
connection.remove(plugin_path)
|
||||
case "ftp":
|
||||
plugin_path = f"{config_values.remote_plugin_folder_on_server}/{plugin_file}"
|
||||
connection = ftp_create_connection()
|
||||
connection.delete(plugin_path)
|
||||
case "local":
|
||||
pluginPath = Path(f"{config_values.path_to_plugin_folder}/{plugin_file}")
|
||||
os.remove(pluginPath)
|
||||
print(f"Removed: {fileName}")
|
||||
i += 1
|
||||
break
|
||||
except TypeError:
|
||||
print(oColors.brightRed + f"Aborted removing of: {pluginToRemove}." + oColors.standardWhite)
|
||||
if i == 0:
|
||||
print(oColors.brightRed + f"Couldn't remove plugin: {pluginToRemove}" + oColors.standardWhite)
|
||||
rich_console.print(f"[not bold][bright_green]Successfully removed: [bright_magenta]{plugin_file}")
|
||||
except:
|
||||
rich_print_error(f"[not bold]Error: Couldn't remove [bright_magenta]{plugin_file}")
|
||||
return None
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,114 +0,0 @@
|
||||
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)
|
||||
|
@ -1,218 +0,0 @@
|
||||
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)
|
277
src/serverjar/serverjar_paper_velocity_waterfall.py
Normal file
277
src/serverjar/serverjar_paper_velocity_waterfall.py
Normal file
@ -0,0 +1,277 @@
|
||||
"""
|
||||
Handles the update checking and downloading of these serverjars:
|
||||
Paper, Velocity, Waterfall
|
||||
|
||||
All are from the PaperMC Team and use the same api structure which is the reason these are together
|
||||
"""
|
||||
|
||||
import re
|
||||
import requests
|
||||
from pathlib import Path
|
||||
from rich.table import Table
|
||||
from rich.console import Console
|
||||
from rich.progress import Progress
|
||||
|
||||
from src.handlers.handle_config import config_value
|
||||
from src.utils.console_output import rich_print_error
|
||||
from src.handlers.handle_sftp import sftp_create_connection, sftp_upload_server_jar
|
||||
from src.handlers.handle_ftp import ftp_create_connection, ftp_upload_server_jar
|
||||
from src.utils.utilities import \
|
||||
api_do_request, create_temp_plugin_folder, remove_temp_plugin_folder, convert_file_size_down
|
||||
|
||||
|
||||
def get_installed_serverjar_version(file_server_jar_full_name) -> str:
|
||||
"""
|
||||
Gets the installed version of the installed serverjar
|
||||
|
||||
:param file_server_jar_full_name: Full file name fo the installed serverjar
|
||||
|
||||
:returns: Used serverjar version
|
||||
"""
|
||||
serverjar_version_full = re.search(r"([\d]*.jar)", file_server_jar_full_name)
|
||||
try:
|
||||
serverjar_version = serverjar_version_full.group()
|
||||
except AttributeError:
|
||||
serverjar_version = serverjar_version_full
|
||||
serverjar_version = serverjar_version.replace('.jar', '')
|
||||
|
||||
return serverjar_version
|
||||
|
||||
|
||||
def get_version_group(file_server_jar_full_name) -> str:
|
||||
"""
|
||||
Gets the version group which is used for the papermc api
|
||||
|
||||
:param mc_version: Version of Minecraft in use
|
||||
|
||||
:returns: Version group of api
|
||||
"""
|
||||
version_group = re.sub(r"-\d*.jar$", "", file_server_jar_full_name)
|
||||
version_group = re.sub(r"^(\w*\-)", "", version_group)
|
||||
return version_group
|
||||
|
||||
|
||||
def find_latest_available_version(file_server_jar_full_name, version_group) -> int:
|
||||
"""
|
||||
Gets the latest available version of the installed serverjar version
|
||||
|
||||
:param version_group: Minecraft version group of the serverjar
|
||||
|
||||
:returns: Latest available version as int
|
||||
"""
|
||||
if "paper" in file_server_jar_full_name:
|
||||
url = f"https://papermc.io/api/v2/projects/paper/versions/{version_group}/builds"
|
||||
elif "waterfall" in file_server_jar_full_name:
|
||||
url = f"https://papermc.io/api/v2/projects/waterfall/versions/{version_group}/builds"
|
||||
elif "velocity" in file_server_jar_full_name:
|
||||
url = f"https://papermc.io/api/v2/projects/velocity/versions/{version_group}/builds"
|
||||
|
||||
versions = api_do_request(url)
|
||||
if "status" in versions: # Checks if the API returns a status. This means that there was an error.
|
||||
return None
|
||||
latest_version = versions["builds"][-1]["build"]
|
||||
return latest_version
|
||||
|
||||
|
||||
def get_versions_behind(serverjar_version, latest_version) -> int:
|
||||
"""
|
||||
Gets the number diffference between the two versions
|
||||
|
||||
:param serverjar_version: Installed serverjar version
|
||||
:param latest_version: Latest avaialable serverjar version
|
||||
|
||||
:returns: Number difference between the two versions
|
||||
"""
|
||||
versions_behind = int(latest_version) - int(serverjar_version)
|
||||
return versions_behind
|
||||
|
||||
|
||||
def get_papermc_download_file_name(mc_version, serverjar_version, file_server_jar_full_name) -> str:
|
||||
"""
|
||||
Gets the download name from the papermc api
|
||||
|
||||
:param mc_version: Minecraft version
|
||||
:param serverjar_version: Version of the serverjar
|
||||
:param file_server_jar_full_name: Serverjar name
|
||||
|
||||
:returns: Download name of the file
|
||||
"""
|
||||
if "paper" in file_server_jar_full_name:
|
||||
url = f"https://papermc.io/api/v2/projects/paper/versions/{mc_version}/builds/{serverjar_version}"
|
||||
elif "waterfall" in file_server_jar_full_name:
|
||||
url = f"https://papermc.io/api/v2/projects/waterfall/versions/{mc_version}/builds/{serverjar_version}"
|
||||
elif "velocity" in file_server_jar_full_name:
|
||||
url = f"https://papermc.io/api/v2/projects/velocity/versions/{mc_version}/builds/{serverjar_version}"
|
||||
build_details = api_do_request(url)
|
||||
download_name = build_details["downloads"]["application"]["name"]
|
||||
return download_name
|
||||
|
||||
|
||||
def serverjar_papermc_check_update(file_server_jar_full_name) -> None:
|
||||
"""
|
||||
Checks the installed paper serverjar if an update is available
|
||||
|
||||
:param file_server_jar_full_name: Full name of the paper server jar file name
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
serverjar_version = get_installed_serverjar_version(file_server_jar_full_name)
|
||||
if serverjar_version == None:
|
||||
rich_print_error("Error: An error occured while checking the installed serverjar version")
|
||||
return None
|
||||
|
||||
version_group = get_version_group(file_server_jar_full_name)
|
||||
if version_group == None:
|
||||
rich_print_error(
|
||||
"Error: An error occured while checking the installed version group of the installed serverjar"
|
||||
)
|
||||
return None
|
||||
|
||||
latest_version = find_latest_available_version(file_server_jar_full_name, version_group)
|
||||
if latest_version == None:
|
||||
rich_print_error("Error: An error occured while checking for the latest available version of the serverjar")
|
||||
return None
|
||||
|
||||
versions_behind = get_versions_behind(serverjar_version, latest_version)
|
||||
|
||||
rich_table = Table(box=None)
|
||||
rich_table.add_column("Name", style="bright_magenta")
|
||||
rich_table.add_column("Installed V.", justify="right", style="green")
|
||||
rich_table.add_column("Latest V.", justify="right", style="bright_green")
|
||||
rich_table.add_column("Versions behind", justify="right", style="cyan")
|
||||
|
||||
rich_table.add_row(
|
||||
file_server_jar_full_name,
|
||||
serverjar_version,
|
||||
str(latest_version),
|
||||
str(versions_behind)
|
||||
)
|
||||
rich_console = Console()
|
||||
rich_console.print(rich_table)
|
||||
return None
|
||||
|
||||
|
||||
def serverjar_papermc_update(
|
||||
server_jar_version: str="latest",
|
||||
mc_version: str=None,
|
||||
file_server_jar_full_name: str=None,
|
||||
serverjar_to_download: str=None
|
||||
) -> bool:
|
||||
"""
|
||||
Handles the downloading of the papermc serverjar
|
||||
|
||||
:param server_jar_version: Version of the serverjar which should get downloaded
|
||||
:param mc_version: Minecraft version
|
||||
:param no_confirmation: If no confirmation message should pop up
|
||||
:param file_server_jar_full_name: The old serverjar file
|
||||
:param serverjar_to_download: The serverjar to download because it supports: paper, velocity, waterfall
|
||||
This is used in the handle_input function
|
||||
|
||||
:returns: True/False if the serverjar was downloaded successfully
|
||||
"""
|
||||
config_values = config_value()
|
||||
match config_values.connection:
|
||||
case "local":
|
||||
path_server_root = config_values.path_to_plugin_folder
|
||||
# need help_path or else TypeError will be thrown
|
||||
help_path = Path('/plugins')
|
||||
help_path_str = str(help_path)
|
||||
path_server_root = Path(str(path_server_root).replace(help_path_str, ''))
|
||||
case _:
|
||||
path_server_root = create_temp_plugin_folder()
|
||||
|
||||
# exit if the mc version can't be found
|
||||
if file_server_jar_full_name == None and mc_version == None:
|
||||
rich_print_error("Error: Please specifiy the minecraft version as third argument!")
|
||||
return False
|
||||
|
||||
# if both the file name and the serverjar_to_download are emtpy then exit
|
||||
if file_server_jar_full_name == None and serverjar_to_download == None:
|
||||
rich_print_error("Error: Couldn't get serverjar name to download")
|
||||
return False
|
||||
|
||||
if mc_version == None:
|
||||
mc_version = get_version_group(file_server_jar_full_name)
|
||||
|
||||
if file_server_jar_full_name == None:
|
||||
papermc_serverjar = serverjar_to_download
|
||||
else:
|
||||
papermc_serverjar = file_server_jar_full_name
|
||||
|
||||
if server_jar_version == "latest" or server_jar_version == None:
|
||||
server_jar_version = find_latest_available_version(papermc_serverjar, mc_version)
|
||||
|
||||
# use rich console for nice colors
|
||||
rich_console = Console()
|
||||
rich_console.print(
|
||||
f"\n [not bold][bright_white]● [bright_magenta]{papermc_serverjar.capitalize()}" + \
|
||||
f" [cyan]→ [bright_green]{server_jar_version}"
|
||||
)
|
||||
|
||||
if file_server_jar_full_name != None:
|
||||
serverjar_version = get_installed_serverjar_version(file_server_jar_full_name)
|
||||
if get_versions_behind(serverjar_version, server_jar_version) == 0:
|
||||
rich_console.print(" [not bold][bright_green]No updates currently available!")
|
||||
return False
|
||||
|
||||
try:
|
||||
download_file_name = get_papermc_download_file_name(mc_version, server_jar_version, papermc_serverjar)
|
||||
except KeyError:
|
||||
rich_print_error(f" Error: This version wasn't found for {mc_version}")
|
||||
rich_print_error(f" Reverting to latest version for {mc_version}")
|
||||
try:
|
||||
server_jar_version = find_latest_available_version(papermc_serverjar, mc_version)
|
||||
download_file_name = get_papermc_download_file_name(mc_version, server_jar_version, papermc_serverjar)
|
||||
except KeyError:
|
||||
rich_print_error(
|
||||
f" Error: Version {mc_version} wasn't found for {papermc_serverjar.capitalize()} in the papermc api"
|
||||
)
|
||||
return False
|
||||
|
||||
if "paper" in papermc_serverjar:
|
||||
url = f"https://papermc.io/api/v2/projects/paper/versions/{mc_version}" + \
|
||||
f"/builds/{server_jar_version}/downloads/{download_file_name}"
|
||||
elif "waterfall" in papermc_serverjar:
|
||||
url = f"https://papermc.io/api/v2/projects/waterfall/versions/{mc_version}" + \
|
||||
f"/builds/{server_jar_version}/downloads/{download_file_name}"
|
||||
elif "velocity" in papermc_serverjar:
|
||||
url = f"https://papermc.io/api/v2/projects/velocity/versions/{mc_version}" + \
|
||||
f"/builds/{server_jar_version}/downloads/{download_file_name}"
|
||||
|
||||
download_path = Path(f"{path_server_root}/{download_file_name}")
|
||||
|
||||
with Progress(transient=True) as progress:
|
||||
header = {'user-agent': 'pluGET/1.0'}
|
||||
r = requests.get(url, headers=header, stream=True)
|
||||
try:
|
||||
file_size = int(r.headers.get('Content-Length'))
|
||||
# create progress bar
|
||||
download_task = progress.add_task(" [cyan]Downloading...", total=file_size)
|
||||
except TypeError:
|
||||
# Content-lenght returned nothing
|
||||
file_size = 0
|
||||
with open(download_path, 'wb') as f:
|
||||
# split downloaded data in chunks of 65536
|
||||
for data in r.iter_content(chunk_size=65536):
|
||||
f.write(data)
|
||||
# don't show progress bar if no content-length was returned
|
||||
if file_size == 0:
|
||||
continue
|
||||
progress.update(download_task, advance=len(data))
|
||||
#f.flush()
|
||||
|
||||
|
||||
file_size_data = convert_file_size_down(convert_file_size_down(file_size))
|
||||
rich_console.print(" [not bold][bright_green]Downloaded[bright_magenta] " + (str(file_size_data)).rjust(9) + \
|
||||
f" MB [cyan]→ [white]{download_path}")
|
||||
|
||||
if config_values.connection == "sftp":
|
||||
sftp_session = sftp_create_connection()
|
||||
sftp_upload_server_jar(sftp_session, download_path)
|
||||
remove_temp_plugin_folder()
|
||||
elif config_values.connection == "ftp":
|
||||
ftp_session = ftp_create_connection()
|
||||
ftp_upload_server_jar(ftp_session, download_path)
|
||||
remove_temp_plugin_folder()
|
||||
|
||||
return True
|
208
src/serverjar/serverjar_purpur.py
Normal file
208
src/serverjar/serverjar_purpur.py
Normal file
@ -0,0 +1,208 @@
|
||||
"""
|
||||
Handles the update checking and downloading of these serverjars:
|
||||
Purpur
|
||||
"""
|
||||
|
||||
import re
|
||||
import requests
|
||||
from pathlib import Path
|
||||
from rich.table import Table
|
||||
from rich.console import Console
|
||||
from rich.progress import Progress
|
||||
|
||||
from src.handlers.handle_config import config_value
|
||||
from src.utils.console_output import rich_print_error
|
||||
from src.handlers.handle_sftp import sftp_create_connection, sftp_upload_server_jar
|
||||
from src.handlers.handle_ftp import ftp_create_connection, ftp_upload_server_jar
|
||||
from src.utils.utilities import \
|
||||
api_do_request, create_temp_plugin_folder, remove_temp_plugin_folder, convert_file_size_down
|
||||
from src.serverjar.serverjar_paper_velocity_waterfall import \
|
||||
get_installed_serverjar_version, get_version_group, get_versions_behind
|
||||
|
||||
|
||||
def find_latest_available_version(version_group) -> int:
|
||||
"""
|
||||
Gets the latest available version of the installed serverjar version
|
||||
|
||||
:param version_group: Minecraft version group of the serverjar
|
||||
|
||||
:returns: Latest available version as int
|
||||
"""
|
||||
url = f"https://api.purpurmc.org/v2/purpur/{version_group}/"
|
||||
versions = api_do_request(url)
|
||||
if "status" in versions: # Checks if the API returns a status. This means that there was an error.
|
||||
return None
|
||||
latest_version = versions["builds"]["all"][-1]
|
||||
return latest_version
|
||||
|
||||
|
||||
def get_purpur_download_file_name(mc_version, serverjar_version) -> str:
|
||||
"""
|
||||
Gets the download name from the purpur api and merge it together in the right format
|
||||
|
||||
:param mc_version: Minecraft version
|
||||
:param serverjar_version: Version of the serverjar
|
||||
:param file_server_jar_full_name: Serverjar name
|
||||
|
||||
:returns: Download name of the file
|
||||
"""
|
||||
url = f"https://api.purpurmc.org/v2/purpur/{mc_version}/{serverjar_version}/"
|
||||
build_details = api_do_request(url)
|
||||
purpur_build_version = build_details["build"]
|
||||
purpur_project_name = build_details["project"]
|
||||
purpur_mc_version = build_details["version"]
|
||||
download_name = f"{purpur_project_name}-{purpur_mc_version}-{purpur_build_version}.jar"
|
||||
return download_name
|
||||
|
||||
|
||||
def serverjar_purpur_check_update(file_server_jar_full_name) -> None:
|
||||
"""
|
||||
Checks the installed purpur serverjar if an update is available
|
||||
|
||||
:param file_server_jar_full_name: Full name of the purpu server jar file name
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
serverjar_version = get_installed_serverjar_version(file_server_jar_full_name)
|
||||
if serverjar_version == None:
|
||||
rich_print_error("Error: An error occured while checking the installed serverjar version")
|
||||
return None
|
||||
|
||||
version_group = get_version_group(file_server_jar_full_name)
|
||||
if version_group == None:
|
||||
rich_print_error(
|
||||
"Error: An error occured while checking the installed version group of the installed serverjar"
|
||||
)
|
||||
return None
|
||||
|
||||
latest_version = find_latest_available_version(version_group)
|
||||
if latest_version == None:
|
||||
rich_print_error("Error: An error occured while checking for the latest available version of the serverjar")
|
||||
return None
|
||||
|
||||
versions_behind = get_versions_behind(serverjar_version, latest_version)
|
||||
|
||||
rich_table = Table(box=None)
|
||||
rich_table.add_column("Name", style="bright_magenta")
|
||||
rich_table.add_column("Installed V.", justify="right", style="green")
|
||||
rich_table.add_column("Latest V.", justify="right", style="bright_green")
|
||||
rich_table.add_column("Versions behind", justify="right", style="cyan")
|
||||
|
||||
rich_table.add_row(
|
||||
file_server_jar_full_name,
|
||||
serverjar_version,
|
||||
str(latest_version),
|
||||
str(versions_behind)
|
||||
)
|
||||
rich_console = Console()
|
||||
rich_console.print(rich_table)
|
||||
return None
|
||||
|
||||
|
||||
def serverjar_purpur_update(
|
||||
server_jar_version: str="latest",
|
||||
mc_version: str=None,
|
||||
file_server_jar_full_name: str=None
|
||||
) -> bool:
|
||||
"""
|
||||
Handles the downloading of the papermc serverjar
|
||||
|
||||
:param server_jar_version: Version of the serverjar which should get downloaded
|
||||
:param mc_version: Minecraft version
|
||||
:param no_confirmation: If no confirmation message should pop up
|
||||
:param file_server_jar_full_name: The old serverjar file
|
||||
|
||||
:returns: True/False if the serverjar was downloaded successfully
|
||||
"""
|
||||
config_values = config_value()
|
||||
match config_values.connection:
|
||||
case "local":
|
||||
path_server_root = config_values.path_to_plugin_folder
|
||||
# need help_path or else TypeError will be thrown
|
||||
help_path = Path('/plugins')
|
||||
help_path_str = str(help_path)
|
||||
path_server_root = Path(str(path_server_root).replace(help_path_str, ''))
|
||||
case _:
|
||||
path_server_root = create_temp_plugin_folder()
|
||||
|
||||
# exit if the mc version can't be found
|
||||
if file_server_jar_full_name == None and mc_version == None:
|
||||
rich_print_error("Error: Please specifiy the minecraft version as third argument!")
|
||||
return False
|
||||
|
||||
if mc_version == None:
|
||||
mc_version = get_version_group(file_server_jar_full_name)
|
||||
|
||||
if server_jar_version == "latest" or server_jar_version == None:
|
||||
server_jar_version = find_latest_available_version(mc_version)
|
||||
|
||||
if file_server_jar_full_name == None:
|
||||
serverjar_name = "purpur"
|
||||
else:
|
||||
serverjar_name = file_server_jar_full_name
|
||||
|
||||
# use rich console for nice colors
|
||||
rich_console = Console()
|
||||
rich_console.print(
|
||||
f"\n [not bold][bright_white]● [bright_magenta]{serverjar_name.capitalize()}" + \
|
||||
f" [cyan]→ [bright_green]{server_jar_version}"
|
||||
)
|
||||
|
||||
if file_server_jar_full_name != None:
|
||||
serverjar_version = get_installed_serverjar_version(file_server_jar_full_name)
|
||||
if get_versions_behind(serverjar_version, server_jar_version) == 0:
|
||||
rich_console.print(" [not bold][bright_green]No updates currently available!")
|
||||
return False
|
||||
|
||||
try:
|
||||
download_file_name = get_purpur_download_file_name(mc_version, server_jar_version)
|
||||
except KeyError:
|
||||
rich_print_error(f" Error: This version wasn't found for {mc_version}")
|
||||
rich_print_error(f" Reverting to latest version for {mc_version}")
|
||||
try:
|
||||
server_jar_version = find_latest_available_version(mc_version)
|
||||
download_file_name = get_purpur_download_file_name(mc_version, server_jar_version)
|
||||
except KeyError:
|
||||
rich_print_error(
|
||||
f" Error: Version {mc_version} wasn't found for {serverjar_name.capitalize()} in the purpur api"
|
||||
)
|
||||
return False
|
||||
|
||||
url = f"https://api.purpurmc.org/v2/purpur/{mc_version}/{server_jar_version}/download/"
|
||||
download_path = Path(f"{path_server_root}/{download_file_name}")
|
||||
|
||||
with Progress(transient=True) as progress:
|
||||
header = {'user-agent': 'pluGET/1.0'}
|
||||
r = requests.get(url, headers=header, stream=True)
|
||||
try:
|
||||
file_size = int(r.headers.get('Content-Length'))
|
||||
# create progress bar
|
||||
download_task = progress.add_task(" [cyan]Downloading...", total=file_size)
|
||||
except TypeError:
|
||||
# Content-lenght returned nothing
|
||||
file_size = 0
|
||||
with open(download_path, 'wb') as f:
|
||||
# split downloaded data in chunks of 65536
|
||||
for data in r.iter_content(chunk_size=65536):
|
||||
f.write(data)
|
||||
# don't show progress bar if no content-length was returned
|
||||
if file_size == 0:
|
||||
continue
|
||||
progress.update(download_task, advance=len(data))
|
||||
#f.flush()
|
||||
|
||||
|
||||
file_size_data = convert_file_size_down(convert_file_size_down(file_size))
|
||||
rich_console.print(" [not bold][bright_green]Downloaded[bright_magenta] " + (str(file_size_data)).rjust(9) + \
|
||||
f" MB [cyan]→ [white]{download_path}")
|
||||
|
||||
if config_values.connection == "sftp":
|
||||
sftp_session = sftp_create_connection()
|
||||
sftp_upload_server_jar(sftp_session, download_path)
|
||||
remove_temp_plugin_folder()
|
||||
elif config_values.connection == "ftp":
|
||||
ftp_session = ftp_create_connection()
|
||||
ftp_upload_server_jar(ftp_session, download_path)
|
||||
remove_temp_plugin_folder()
|
||||
|
||||
return True
|
139
src/serverjar/serverjar_updatechecker.py
Normal file
139
src/serverjar/serverjar_updatechecker.py
Normal file
@ -0,0 +1,139 @@
|
||||
"""
|
||||
Checks the installed serverjar for updates
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from rich.console import Console
|
||||
|
||||
from src.handlers.handle_config import config_value
|
||||
from src.utils.console_output import rich_print_error
|
||||
from src.handlers.handle_sftp import sftp_create_connection, sftp_list_files_in_server_root
|
||||
from src.handlers.handle_ftp import ftp_create_connection, ftp_list_files_in_server_root
|
||||
from src.serverjar.serverjar_paper_velocity_waterfall import serverjar_papermc_check_update, serverjar_papermc_update
|
||||
from src.serverjar.serverjar_purpur import serverjar_purpur_check_update, serverjar_purpur_update
|
||||
|
||||
|
||||
def get_installed_server_jar_file(config_values) -> str:
|
||||
"""
|
||||
Gets the file name of the installed server jar
|
||||
|
||||
:param config_values: Configuration values from pluGET config
|
||||
|
||||
:returns: Full file name of installed server jar
|
||||
"""
|
||||
match config_values.connection:
|
||||
case "sftp":
|
||||
connection = sftp_create_connection()
|
||||
file_list_server_root = sftp_list_files_in_server_root(connection)
|
||||
case "ftp":
|
||||
connection = ftp_create_connection()
|
||||
file_list_server_root = ftp_list_files_in_server_root(connection)
|
||||
case _:
|
||||
file_list_server_root = os.path.dirname(config_values.path_to_plugin_folder)
|
||||
file_list_server_root = os.listdir(file_list_server_root)
|
||||
|
||||
file_server_jar_full_name = None
|
||||
try:
|
||||
for file in file_list_server_root:
|
||||
try:
|
||||
if ".jar" in file:
|
||||
file_server_jar_full_name = file
|
||||
break
|
||||
except TypeError:
|
||||
continue
|
||||
except TypeError:
|
||||
rich_print_error("Error: Serverjar couldn't be found")
|
||||
return None
|
||||
return file_server_jar_full_name
|
||||
|
||||
|
||||
def check_update_available_installed_server_jar() -> None:
|
||||
"""
|
||||
Handles the checking of available updates of the installed server jar
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
config_values = config_value()
|
||||
file_server_jar_full_name = get_installed_server_jar_file(config_values)
|
||||
if file_server_jar_full_name == None:
|
||||
# print error and exit function
|
||||
rich_print_error("Error: Serverjar couldn't be found")
|
||||
return None
|
||||
|
||||
# TODO: Add other serverjars here
|
||||
# Paper / Velocity / Waterfall
|
||||
if "paper" in file_server_jar_full_name or \
|
||||
"waterfall" in file_server_jar_full_name or \
|
||||
"velocity" in file_server_jar_full_name:
|
||||
serverjar_papermc_check_update(file_server_jar_full_name)
|
||||
|
||||
# Purpur
|
||||
elif "purpur" in file_server_jar_full_name:
|
||||
serverjar_purpur_check_update(file_server_jar_full_name)
|
||||
|
||||
else:
|
||||
rich_print_error(f"[not bold]Error: [bright_magenta]{file_server_jar_full_name} [bright_red]isn't supported")
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def update_installed_server_jar(server_jar_version: str="latest") -> None:
|
||||
"""
|
||||
Handles the updating of the installed server jar
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
config_values = config_value()
|
||||
file_server_jar_full_name = get_installed_server_jar_file(config_values)
|
||||
if file_server_jar_full_name == None:
|
||||
# print error and exit function
|
||||
rich_print_error("Error: Serverjar couldn't be found")
|
||||
return None
|
||||
|
||||
# finding path which is used for deleting old server jar
|
||||
match config_values.connection:
|
||||
case "local":
|
||||
path_server_root = config_values.path_to_plugin_folder
|
||||
# need help_path or else TypeError will be thrown
|
||||
help_path = Path('/plugins')
|
||||
help_path_str = str(help_path)
|
||||
path_server_root = Path(str(path_server_root).replace(help_path_str, ''))
|
||||
case _:
|
||||
path_server_root = config_values.remote_plugin_folder_on_server
|
||||
path_server_root = str(path_server_root).replace(r'/plugins', '')
|
||||
|
||||
server_jar_path = f"{path_server_root}/{file_server_jar_full_name}"
|
||||
rich_console = Console()
|
||||
download_successfull = False
|
||||
# TODO: Add other serverjars here
|
||||
# Paper / Velocity / Waterfall
|
||||
if "paper" in file_server_jar_full_name or \
|
||||
"waterfall" in file_server_jar_full_name or \
|
||||
"velocity" in file_server_jar_full_name:
|
||||
download_successfull = serverjar_papermc_update(server_jar_version, None, file_server_jar_full_name, None)
|
||||
|
||||
# Purpur
|
||||
elif "purpur" in file_server_jar_full_name:
|
||||
download_successfull = serverjar_purpur_update(server_jar_version, None, file_server_jar_full_name)
|
||||
|
||||
else:
|
||||
rich_print_error(f"[not bold]Error: [bright_magenta]{file_server_jar_full_name} [bright_red]isn't supported")
|
||||
|
||||
# remove old serverjar when the serverjar was sucessfully updated
|
||||
if download_successfull is True:
|
||||
match config_values.connection:
|
||||
case "local":
|
||||
os.remove(Path(server_jar_path))
|
||||
case "sftp":
|
||||
connection = sftp_create_connection()
|
||||
connection.remove(server_jar_path)
|
||||
case "ftp":
|
||||
connection = ftp_create_connection()
|
||||
connection.delete(server_jar_path)
|
||||
rich_console.print(
|
||||
" [not bold][bright_green]Deleted old server file [cyan]→ [white]" +
|
||||
f"{file_server_jar_full_name}"
|
||||
)
|
||||
|
||||
return None
|
8
src/settings.py
Normal file
8
src/settings.py
Normal file
@ -0,0 +1,8 @@
|
||||
"""
|
||||
Constant values
|
||||
|
||||
PLUGETVERSION = current version of pluGET
|
||||
"""
|
||||
|
||||
# constant values
|
||||
PLUGETVERSION = "1.7.2"
|
0
src/tests/__init__.py
Normal file
0
src/tests/__init__.py
Normal file
31
src/tests/test_plugin_updatechecker.py
Normal file
31
src/tests/test_plugin_updatechecker.py
Normal file
@ -0,0 +1,31 @@
|
||||
import unittest
|
||||
|
||||
from src.plugin import plugin_updatechecker
|
||||
|
||||
|
||||
class TestCases(unittest.TestCase):
|
||||
def test_get_plugin_file_name(self):
|
||||
plugin_file_name = "LuckPerms-5.4.30.jar"
|
||||
plugin_file_name_cropped = "LuckPerms"
|
||||
result = plugin_updatechecker.get_plugin_file_name(plugin_file_name)
|
||||
self.assertEqual(result, plugin_file_name_cropped)
|
||||
|
||||
def test_get_plugin_file_version(self):
|
||||
plugin_file_name = "LuckPerms-5.4.30.jar"
|
||||
plugin_version_cropped = "5.4.30"
|
||||
result = plugin_updatechecker.get_plugin_file_version(plugin_file_name)
|
||||
self.assertEqual(result, plugin_version_cropped)
|
||||
|
||||
def test_get_plugin_version_without_letters(self):
|
||||
plugin_version = "VERSIONv5.4.30"
|
||||
plugin_version_cropped = "5.4.30"
|
||||
result = plugin_updatechecker.get_plugin_version_without_letters(plugin_version)
|
||||
self.assertEqual(result, plugin_version_cropped)
|
||||
|
||||
def test_compare_plugin_version(self):
|
||||
result = plugin_updatechecker.compare_plugin_version("5.4.30", "5.4.0")
|
||||
result2 = plugin_updatechecker.compare_plugin_version("5.4.30", "8.7.60")
|
||||
result3 = plugin_updatechecker.compare_plugin_version("5.4.30", "5.4.30")
|
||||
self.assertEqual(result, True)
|
||||
self.assertEqual(result2, False)
|
||||
self.assertEqual(result3, False)
|
61
src/tests/test_plugin_utils.py
Normal file
61
src/tests/test_plugin_utils.py
Normal file
@ -0,0 +1,61 @@
|
||||
import unittest
|
||||
|
||||
from src.plugin import plugin_downloader
|
||||
from src.utils import utilities
|
||||
|
||||
|
||||
class TestCases(unittest.TestCase):
|
||||
def test_handle_regex_plugin_name(self):
|
||||
# Cropped name -> 'SUPERBPlugin'
|
||||
plugin_name = "[1.13-5.49 ❤] >|> SUPERB Plugin <<💥| Now 150% OFF IN WINTER SALE IN SUMMER???"
|
||||
plugin_name_cropped = "SUPERBPlugin"
|
||||
result = plugin_downloader.handle_regex_plugin_name(plugin_name)
|
||||
self.assertEqual(result, plugin_name_cropped)
|
||||
|
||||
|
||||
def test_get_version_id_spiget(self):
|
||||
# 21840 -> "Luckperms" in Version 5.4.30
|
||||
result = plugin_downloader.get_version_id_spiget("28140", "5.4.30")
|
||||
self.assertEqual(result, 455966)
|
||||
|
||||
|
||||
def test_get_version_name_spiget(self):
|
||||
# 455966 -> "5.4.30" from Luckperms
|
||||
result = plugin_downloader.get_version_name_spiget("28140", 455966)
|
||||
self.assertEqual(result, "5.4.30")
|
||||
|
||||
|
||||
def test_get_download_path(self):
|
||||
# local plugin folder
|
||||
class config_values_local:
|
||||
connection = "local"
|
||||
local_seperate_download_path = True
|
||||
local_path_to_seperate_download_path = "/local/path/plugins"
|
||||
result=plugin_downloader.get_download_path(config_values_local)
|
||||
self.assertEqual(result, config_values_local.local_path_to_seperate_download_path)
|
||||
|
||||
# plugin folder over sftp
|
||||
class config_values_sftp:
|
||||
connection = "sftp"
|
||||
remote_seperate_download_path = True
|
||||
remote_path_to_seperate_download_path = "/sftp/path/plugins"
|
||||
result=plugin_downloader.get_download_path(config_values_sftp)
|
||||
self.assertEqual(result, config_values_sftp.remote_path_to_seperate_download_path)
|
||||
|
||||
# plugin folder over ftp
|
||||
class config_values_ftp:
|
||||
connection = "ftp"
|
||||
remote_seperate_download_path = True
|
||||
remote_path_to_seperate_download_path = "/ftp/path/plugins"
|
||||
result=plugin_downloader.get_download_path(config_values_ftp)
|
||||
self.assertEqual(result, config_values_ftp.remote_path_to_seperate_download_path)
|
||||
|
||||
|
||||
def test_convert_file_size_down(self):
|
||||
# 100000 / 1024 = 97.66
|
||||
result= utilities.convert_file_size_down(100000)
|
||||
self.assertEqual(result, 97.66)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
42
src/tests/test_serverjar_paper_velocity_waterfall.py
Normal file
42
src/tests/test_serverjar_paper_velocity_waterfall.py
Normal file
@ -0,0 +1,42 @@
|
||||
import unittest
|
||||
|
||||
from src.serverjar import serverjar_paper_velocity_waterfall
|
||||
|
||||
class TestCases(unittest.TestCase):
|
||||
def test_get_installed_serverjar_version(self):
|
||||
# paper-1.19-40.jar -> 40
|
||||
serverjar_file_name = "paper-1.19-40.jar"
|
||||
serverjar_version = "40"
|
||||
result = serverjar_paper_velocity_waterfall.get_installed_serverjar_version(serverjar_file_name)
|
||||
self.assertEqual(result, serverjar_version)
|
||||
|
||||
|
||||
def test_get_version_group(self):
|
||||
# 1.18.2 -> 1.18
|
||||
mc_version = "1.18.2"
|
||||
mc_version_group = "1.18.2"
|
||||
result = serverjar_paper_velocity_waterfall.get_version_group(mc_version)
|
||||
self.assertEqual(result, mc_version_group)
|
||||
|
||||
|
||||
def test_find_latest_available_version(self):
|
||||
# Get latest available paper version for 1.15.2 which should be 393
|
||||
file_server_jar_full_name = "paper-1.15.2-40.jar"
|
||||
version_group = "1.15.2"
|
||||
result = serverjar_paper_velocity_waterfall.find_latest_available_version(
|
||||
file_server_jar_full_name,
|
||||
version_group
|
||||
)
|
||||
self.assertEqual(result, 393)
|
||||
|
||||
|
||||
def test_get_versions_behind(self):
|
||||
# 161 - 157 = 4
|
||||
serverjar_version = 157
|
||||
latest_version = 161
|
||||
result = serverjar_paper_velocity_waterfall.get_versions_behind(serverjar_version, latest_version)
|
||||
self.assertEqual(result, 4)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
40
src/tests/test_serverjar_purpur.py
Normal file
40
src/tests/test_serverjar_purpur.py
Normal file
@ -0,0 +1,40 @@
|
||||
import unittest
|
||||
|
||||
from src.serverjar import serverjar_purpur
|
||||
from src.serverjar import serverjar_paper_velocity_waterfall
|
||||
|
||||
class TestCases(unittest.TestCase):
|
||||
def test_get_installed_serverjar_version(self):
|
||||
# purpur-1.19-40.jar -> 40
|
||||
serverjar_file_name = "purpur-1.19-40.jar"
|
||||
serverjar_version = "40"
|
||||
result = serverjar_paper_velocity_waterfall.get_installed_serverjar_version(serverjar_file_name)
|
||||
self.assertEqual(result, serverjar_version)
|
||||
|
||||
|
||||
def test_get_version_group(self):
|
||||
# 1.18.2 -> 1.18
|
||||
mc_version = "1.18.2"
|
||||
mc_version_group = "1.18.2"
|
||||
result = serverjar_paper_velocity_waterfall.get_version_group(mc_version)
|
||||
self.assertEqual(result, mc_version_group)
|
||||
|
||||
|
||||
def test_find_latest_available_version(self):
|
||||
# Get latest available purpur version for 1.15.2 which should be '606'
|
||||
file_server_jar_full_name = "purpur-1.15.2-40.jar"
|
||||
version_group = "1.15.2"
|
||||
result = serverjar_purpur.find_latest_available_version(version_group)
|
||||
self.assertEqual(result, str(606))
|
||||
|
||||
|
||||
def test_get_versions_behind(self):
|
||||
# 161 - 157 = 4
|
||||
serverjar_version = 157
|
||||
latest_version = 161
|
||||
result = serverjar_paper_velocity_waterfall.get_versions_behind(serverjar_version, latest_version)
|
||||
self.assertEqual(result, 4)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
152
src/utils/console_output.py
Normal file
152
src/utils/console_output.py
Normal file
@ -0,0 +1,152 @@
|
||||
"""
|
||||
Handles the console on first startup of pluGET and prints logo and sets title
|
||||
"""
|
||||
|
||||
import os
|
||||
from rich.console import Console
|
||||
|
||||
from src.settings import PLUGETVERSION
|
||||
|
||||
|
||||
def rich_print_error(error_message) -> None:
|
||||
"""
|
||||
Prints a formatted error message from rich
|
||||
"""
|
||||
console = Console()
|
||||
console.print(error_message, style="bright_red")
|
||||
return None
|
||||
|
||||
|
||||
def rename_console_title() -> None:
|
||||
"""
|
||||
Renames the console title on first startup
|
||||
"""
|
||||
if os.name == "nt":
|
||||
os.system("title " + "pluGET │ By Neocky")
|
||||
return None
|
||||
|
||||
|
||||
def clear_console() -> None:
|
||||
"""
|
||||
Clears the console on first startup
|
||||
"""
|
||||
os.system('cls' if os.name=='nt' else 'clear')
|
||||
return None
|
||||
|
||||
|
||||
def print_logo() -> None:
|
||||
"""
|
||||
Prints the logo of pluGET and the link to the github repo
|
||||
"""
|
||||
# use rich console
|
||||
console = Console()
|
||||
# line 1
|
||||
console.print()
|
||||
# line 2
|
||||
console.print(" ██████",style="bright_magenta", end='')
|
||||
console.print("╗ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("╗ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("╗ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("╗ ", style="bright_yellow", end='')
|
||||
console.print("██████", style="bright_magenta", end='')
|
||||
console.print("╗ ", style="bright_yellow", end='')
|
||||
console.print("███████", style="bright_magenta", end='')
|
||||
console.print("╗", style="bright_yellow", end='')
|
||||
console.print("████████", style="bright_magenta", end='')
|
||||
console.print("╗", style="bright_yellow")
|
||||
# line 3
|
||||
console.print(" ██", style="bright_magenta", end='')
|
||||
console.print("╔══", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("╗", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("╔════╝ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("╔════╝╚══", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("╔══╝", style="bright_yellow")
|
||||
# line 4
|
||||
console.print(" ██████", style="bright_magenta", end='')
|
||||
console.print("╔╝", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow", end='')
|
||||
console.print("███", style="bright_magenta", end='')
|
||||
console.print("╗", style="bright_yellow", end='')
|
||||
console.print("█████", style="bright_magenta", end='')
|
||||
console.print("╗ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow")
|
||||
# line 5
|
||||
console.print(" ██", style="bright_magenta", end='')
|
||||
console.print("╔═══╝ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("╔══╝ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow")
|
||||
# line 6
|
||||
console.print(" ██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow", end='')
|
||||
console.print("███████", style="bright_magenta", end='')
|
||||
console.print("╗╚", style="bright_yellow", end='')
|
||||
console.print("██████", style="bright_magenta", end='')
|
||||
console.print("╔╝╚", style="bright_yellow", end='')
|
||||
console.print("██████", style="bright_magenta", end='')
|
||||
console.print("╔╝", style="bright_yellow", end='')
|
||||
console.print("███████", style="bright_magenta", end='')
|
||||
console.print("╗ ", style="bright_yellow", end='')
|
||||
console.print("██", style="bright_magenta", end='')
|
||||
console.print("║ ", style="bright_yellow")
|
||||
# line 7
|
||||
console.print(" ╚═╝ ╚══════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ", style="bright_yellow")
|
||||
# line 8
|
||||
console.print()
|
||||
# line 9
|
||||
console.print(" ┌────────────────────────────────────┐", style="bright_black")
|
||||
# line 10
|
||||
console.print(" │ [", style="bright_black", end='')
|
||||
console.print("By Neocky", style="bright_magenta", end='')
|
||||
console.print("] │ ", style="bright_black")
|
||||
# line 11
|
||||
console.print(" │ ", style="bright_black", end='')
|
||||
console.print("https://github.com/Neocky/pluGET", style="link https://github.com/Neocky/pluGET", end='')
|
||||
console.print(" │ ", style="bright_black")
|
||||
# line 12
|
||||
console.print(" └────────────────────────────────────┘", style="bright_black")
|
||||
console.print(" ───────────────────────────────────────────────────")
|
||||
return None
|
||||
|
||||
|
||||
def print_console_logo() -> None:
|
||||
"""
|
||||
Prints the logo of pluGET if it is called from console
|
||||
"""
|
||||
console = Console()
|
||||
console.print(f"[not bold][bright_magenta]pluGET [bright_green]{PLUGETVERSION} ", end='')
|
||||
console.print("created by Neocky → ", end='')
|
||||
console.print("https://github.com/Neocky/pluGET", style="link https://github.com/Neocky/pluGET")
|
||||
return None
|
@ -1,89 +0,0 @@
|
||||
from os import system
|
||||
from os import name
|
||||
|
||||
|
||||
def consoleTitle():
|
||||
system("title " + "pluGET │ By Neocky")
|
||||
|
||||
|
||||
def clearConsole():
|
||||
system('cls' if name=='nt' else 'clear')
|
||||
|
||||
|
||||
# https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
|
||||
class oColors:
|
||||
standardWhite = "\033[0m"
|
||||
brightBlack = "\033[90m"
|
||||
brightRed = "\033[91m"
|
||||
brightGreen = "\033[92m"
|
||||
brightYellow = "\033[93m"
|
||||
brightMagenta = "\033[95m"
|
||||
|
||||
|
||||
def printLogo():
|
||||
print()
|
||||
print(oColors.brightYellow + r" ___ ___ ___ ___ ___ ___ ")
|
||||
print(oColors.brightMagenta + r" /\ " + oColors.brightYellow + r"\ " + oColors.brightMagenta + r"/"'\\' +
|
||||
oColors.brightYellow + r"__\ " + oColors.brightMagenta + r"/"'\\' + oColors.brightYellow + r"__\ " +
|
||||
oColors.brightMagenta + r"/\ "+ oColors.brightYellow + r"\ " + oColors.brightMagenta + r"/\ "+
|
||||
oColors.brightYellow + r"\ " + oColors.brightMagenta + r"/\ "+ oColors.brightYellow + r""'\\ ')
|
||||
print(oColors.brightMagenta + r" /::\ "+ oColors.brightYellow + r"\ " + oColors.brightMagenta + r"/:/ " +
|
||||
oColors.brightYellow + r"/ " + oColors.brightMagenta + r"/:/ "+ oColors.brightYellow + r"/ " +
|
||||
oColors.brightMagenta + r"/::\ "+ oColors.brightYellow + r"\ " + oColors.brightMagenta + r"/::\ "+
|
||||
oColors.brightYellow + r"\ " + oColors.brightMagenta + r"\:\ "+ oColors.brightYellow + r""'\\ ')
|
||||
print(oColors.brightMagenta + r" /:/\:\ "+ oColors.brightYellow + r"\ " + oColors.brightMagenta + r"/:/ "+
|
||||
oColors.brightYellow + r"/ " + oColors.brightMagenta + r"/:/ "+ oColors.brightYellow + r"/ " +
|
||||
oColors.brightMagenta + r"/:/\:\ "+ oColors.brightYellow + r"\ " + oColors.brightMagenta + r"/:/\:\ "+
|
||||
oColors.brightYellow + r"\ " + oColors.brightMagenta + r"\:\ "+ oColors.brightYellow + r""'\\ ')
|
||||
print(oColors.brightMagenta + r" /::"'\\' + oColors.brightYellow + r"~" + oColors.brightMagenta + r"\:\ "+
|
||||
oColors.brightYellow + r"\ " + oColors.brightMagenta + r"/:/ "+ oColors.brightYellow + r"/ " +
|
||||
oColors.brightMagenta + r"/:/ "+ oColors.brightYellow + r"/ ___ " + oColors.brightMagenta + r"/:/ \:\ "+
|
||||
oColors.brightYellow + r"\ " + oColors.brightMagenta + r"/::"'\\'+ oColors.brightYellow + r"~" +
|
||||
oColors.brightMagenta + r"\:\ "+ oColors.brightYellow + r"\ " + oColors.brightMagenta + r"/::\ "+
|
||||
oColors.brightYellow + r""'\\')
|
||||
print(oColors.brightMagenta + r" /:/\:\ \:"'\\'+ oColors.brightYellow + r"__\ " + oColors.brightMagenta + r"/:/"+
|
||||
oColors.brightYellow + r"__/ " + oColors.brightMagenta + r"/:/"+ oColors.brightYellow + r"__/ " +
|
||||
oColors.brightMagenta + r"/"'\\'+ oColors.brightYellow + r"__\ " + oColors.brightMagenta + r"/:/"+
|
||||
oColors.brightYellow + r"__/_" + oColors.brightMagenta + r"\:"'\\'+ oColors.brightYellow + r"__\ " +
|
||||
oColors.brightMagenta + r"/:/\:\ \:"'\\' + oColors.brightYellow + r"__\ " +
|
||||
oColors.brightMagenta + r"/:/\:"'\\'+ oColors.brightYellow + r"__\ ")
|
||||
print(oColors.brightMagenta + r" " + oColors.brightMagenta + r"\/"+ oColors.brightYellow + r"__" +
|
||||
oColors.brightMagenta + r"\:\/:/"+ oColors.brightYellow + r" / " + oColors.brightMagenta + r"\:"'\\'+
|
||||
oColors.brightYellow + r" \ " + oColors.brightMagenta + r"\:"'\\' + oColors.brightYellow + r" \ " +
|
||||
oColors.brightMagenta + r"/:/ "+ oColors.brightYellow + r"/ " + oColors.brightMagenta + r"\:\ /\ \/" +
|
||||
oColors.brightYellow + r"__/ " + oColors.brightMagenta + r"\:"'\\' + oColors.brightYellow + r"~" +
|
||||
oColors.brightMagenta + r"\:\ \/" + oColors.brightYellow + r"__/ " + oColors.brightMagenta + r"/:/ \/"+
|
||||
oColors.brightYellow + r"__/")
|
||||
print(oColors.brightMagenta + r" \::/ "+ oColors.brightYellow + r"/ " + oColors.brightMagenta + r"\:\ "+
|
||||
oColors.brightYellow + r"\ " + oColors.brightMagenta + r"\:\ /:/ "+ oColors.brightYellow + r"/ " +
|
||||
oColors.brightMagenta + r"\:\ \:"'\\'+ oColors.brightYellow + r"__\ " + oColors.brightMagenta + r"\:\ \:"'\\'+
|
||||
oColors.brightYellow + r"__\ " + oColors.brightMagenta + r"/:/ "+ oColors.brightYellow + r"/ ")
|
||||
print(oColors.brightMagenta + r" \/"+ oColors.brightYellow + r"__/ " +
|
||||
oColors.brightMagenta + r"\:\ " + oColors.brightYellow + r"\ " + oColors.brightMagenta + r"\:\/:/ "+
|
||||
oColors.brightYellow + r"/ " + oColors.brightMagenta + r"\:\/:/ "+ oColors.brightYellow + r"/ " +
|
||||
oColors.brightMagenta + r"\:\ \/"+ oColors.brightYellow + r"__/ " + oColors.brightMagenta + r"\/"+
|
||||
oColors.brightYellow + r"__/ ")
|
||||
print(oColors.brightMagenta + r" \:"'\\' + oColors.brightYellow + r"__\ " +
|
||||
oColors.brightMagenta + r"\::/ " + oColors.brightYellow + r"/ " + oColors.brightMagenta + r"\::/ " +
|
||||
oColors.brightYellow + r"/ " + oColors.brightMagenta + r"\:"'\\' + oColors.brightYellow + r"__\ ")
|
||||
print(oColors.brightMagenta + r" \/" + oColors.brightYellow + r"__/ " +
|
||||
oColors.brightMagenta + r"\/" + oColors.brightYellow + r"__/ " + oColors.brightMagenta + r"\/" +
|
||||
oColors.brightYellow + r"__/ " + oColors.brightMagenta + r"\/" + oColors.brightYellow + r"__/ " +
|
||||
oColors.standardWhite)
|
||||
print()
|
||||
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():
|
||||
print(" ─────────────────────────────────────────────────────────────────────────────────")
|
||||
|
||||
|
||||
def printMainMenu():
|
||||
printLogo()
|
||||
printHorizontalLine()
|
@ -1,175 +1,210 @@
|
||||
# misc functions
|
||||
"""
|
||||
Holds all the utilitie code for pluGET and the webrequests function
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import requests
|
||||
import shutil
|
||||
import re
|
||||
from pathlib import Path
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
from src.handlers.handle_sftp import sftp_create_connection
|
||||
from src.handlers.handle_ftp import ftp_create_connection
|
||||
|
||||
from utils.consoleoutput import oColors
|
||||
from handlers.handle_config import configurationValues
|
||||
from handlers.handle_sftp import createSFTPConnection
|
||||
from handlers.handle_ftp import createFTPConnection
|
||||
from src.utils.console_output import rich_print_error
|
||||
from src.handlers.handle_config import config_value
|
||||
from src.settings import PLUGETVERSION
|
||||
|
||||
|
||||
def getHelp():
|
||||
print(oColors.brightYellow+ "Need help?" + oColors.standardWhite)
|
||||
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 get_command_help(command: str) -> None:
|
||||
"""
|
||||
Prints the help page for all commands and individual commands
|
||||
|
||||
:param command: Console command which the help page should show
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
rich_console = Console()
|
||||
rich_table = Table(box=None)
|
||||
rich_table.add_column("Command", justify="left", style="bright_blue", no_wrap=True)
|
||||
rich_table.add_column("Object", style="bright_magenta")
|
||||
rich_table.add_column("Params", justify="left", style="cyan")
|
||||
rich_table.add_column("Description", justify="left", style="white")
|
||||
match command:
|
||||
case "all":
|
||||
rich_table.add_row("check", "Name/all", None, "Check for an update of an installed plugin")
|
||||
rich_table.add_row("check", "serverjar", None, "Check for an update for the installed serverjar")
|
||||
rich_table.add_row("exit", "./anything", None, "Exit pluGET")
|
||||
rich_table.add_row("get", "Name/ID", None, "Downloads the latest version of a plugin")
|
||||
rich_table.add_row("get-paper", "PaperVersion", "McVersion", "Downloads a specific PaperMc version")
|
||||
rich_table.add_row("get-purpur", "PurpurVersion", "McVersion", "Downloads a specific Purpur version")
|
||||
rich_table.add_row("get-velocity", "VelocityVersion", "McVersion", "Downloads a specific Velocity version")
|
||||
rich_table.add_row(
|
||||
"get-waterfall", "WaterfallVersion", "McVersion", "Downloads a specific waterfall version"
|
||||
)
|
||||
rich_table.add_row("help", "./anything", None, "Get specific help to the commands of pluGET")
|
||||
rich_table.add_row("remove", "Name", None, "Delete an installed plugin from the plugin folder")
|
||||
rich_table.add_row("search", "Name/all", None, "Search for a plugin and download the latest version")
|
||||
rich_table.add_row("update", "Name/all", None, "Update installed plugins to the latest version")
|
||||
rich_table.add_row("update", "serverjar", None, "Update the installed serverjar to the latest version")
|
||||
case "check":
|
||||
rich_table.add_row("check", "Name/all", None, "Check for an update of an installed plugin")
|
||||
rich_table.add_row("check", "serverjar", None, "Check for an update for the installed serverjar")
|
||||
case "exit":
|
||||
rich_table.add_row("exit", "./anything", None, "Exit pluGET")
|
||||
case "get":
|
||||
rich_table.add_row("get", "Name/ID", None, "Downloads the latest version of a plugin")
|
||||
case "get-paper":
|
||||
rich_table.add_row("get-paper", "PaperVersion", "McVersion", "Downloads a specific PaperMc version")
|
||||
case "get-purpur":
|
||||
rich_table.add_row("get-purpur", "PurpurVersion", "McVersion", "Downloads a specific Purpur version")
|
||||
case "get-velocity":
|
||||
rich_table.add_row("get-velocity", "VelocityVersion", "McVersion", "Downloads a specific Velocity version")
|
||||
case "get-waterfall":
|
||||
rich_table.add_row(
|
||||
"get-waterfall", "WaterfallVersion", "McVersion", "Downloads a specific Waterfall version"
|
||||
)
|
||||
case "help" | "all":
|
||||
rich_table.add_row("help", "./anything", None, "Get specific help to the commands of pluGET")
|
||||
case "remove":
|
||||
rich_table.add_row("remove", "Name", None, "Delete an installed plugin from the plugin folder")
|
||||
case "search":
|
||||
rich_table.add_row("search", "Name/all", None, "Search for a plugin and download the latest version")
|
||||
case "update":
|
||||
rich_table.add_row("update", "Name/all", None, "Update installed plugins to the latest version")
|
||||
rich_table.add_row("update", "serverjar", None, "Update the installed serverjar to the latest version")
|
||||
case _:
|
||||
rich_print_error(f"[not bold]Error: Help for command [bright_magenta]'{command}' [bright_red]not found!")
|
||||
rich_print_error("Use [bright_blue]'help all' [bright_red]to get a list of all commands.")
|
||||
return None
|
||||
|
||||
rich_console.print(rich_table)
|
||||
|
||||
|
||||
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:
|
||||
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)
|
||||
try:
|
||||
os.mkdir(pluginFolderPath)
|
||||
except OSError:
|
||||
print(oColors.brightRed + "Creation of directory %s failed" % pluginFolderPath)
|
||||
print(oColors.brightRed + "Please check the config file!" + oColors.standardWhite)
|
||||
input("Press any key + enter to exit...")
|
||||
sys.exit()
|
||||
else:
|
||||
print("Created directory %s" % pluginFolderPath)
|
||||
|
||||
|
||||
def apiTest():
|
||||
apiStatusUrl = 'https://api.spiget.org/v2/status'
|
||||
def check_for_pluGET_update() -> None:
|
||||
"""
|
||||
Check with the github api if there is a new version for pluGET available and print download message if this is
|
||||
the case
|
||||
"""
|
||||
response = api_do_request("https://api.github.com/repos/Neocky/pluGET/releases/latest")
|
||||
# get '.1.6.10' as output
|
||||
full_version_string = re.search(r"[\.?\d]*$", response["name"])
|
||||
# remove '.' to get '1.6.10' as output
|
||||
version = re.sub(r"^\.*", "", full_version_string.group())
|
||||
console = Console()
|
||||
try:
|
||||
r = requests.get(apiStatusUrl)
|
||||
pluget_installed_version_tuple = tuple(map(int, (PLUGETVERSION.split("."))))
|
||||
plugin_latest_version_tuple = tuple(map(int, (version.split("."))))
|
||||
except ValueError:
|
||||
console.print("Couldn't check if new version of pluGET is available")
|
||||
return None
|
||||
if pluget_installed_version_tuple < plugin_latest_version_tuple:
|
||||
print(f"A new version of pluGET is available: {version}")
|
||||
console.print("Download it here: ", end='')
|
||||
console.print("https://github.com/Neocky/pluGET", style="link https://github.com/Neocky/pluGET")
|
||||
return None
|
||||
|
||||
|
||||
def api_do_request(url) -> list:
|
||||
"""
|
||||
Handles the webrequest and returns a json list
|
||||
"""
|
||||
webrequest_header = {'user-agent': 'pluGET/1.0'}
|
||||
try:
|
||||
response = requests.get(url, headers=webrequest_header)
|
||||
except:
|
||||
rich_print_error("Error: Couldn't create webrequest")
|
||||
# return None to make functions quit
|
||||
return None
|
||||
try:
|
||||
api_json_data = response.json()
|
||||
except:
|
||||
rich_print_error("Error: Couldn't parse json of webrequest")
|
||||
return None
|
||||
return api_json_data
|
||||
|
||||
|
||||
def api_test_spiget() -> None:
|
||||
"""
|
||||
Test if the Spiget api sends a 200 status code back
|
||||
"""
|
||||
try:
|
||||
r = requests.get('https://api.spiget.org/v2/status')
|
||||
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...")
|
||||
rich_print_error("Error: Couldn't make a connection to the API. Check you connection to the internet!")
|
||||
sys.exit()
|
||||
if r.status_code != 200:
|
||||
print(oColors.brightRed + "Problems with the API detected. Plese try it again later!" + oColors.standardWhite)
|
||||
input("Press any key + enter to exit...")
|
||||
rich_print_error("Error: Problems with the API detected. Plese try it again later!")
|
||||
sys.exit()
|
||||
return None
|
||||
|
||||
|
||||
def check_requirements():
|
||||
configValues = configurationValues()
|
||||
apiTest()
|
||||
check_local_plugin_folder()
|
||||
if not configValues.localPluginFolder:
|
||||
if configValues.sftp_useSftp:
|
||||
createSFTPConnection()
|
||||
else:
|
||||
createFTPConnection()
|
||||
def create_temp_plugin_folder() -> Path:
|
||||
"""
|
||||
Creates a temporary folder to store plugins inside
|
||||
Returns full path of temporary folder
|
||||
"""
|
||||
path_temp_plugin_folder = Path("./TempSFTPFolder")
|
||||
if os.path.isdir(path_temp_plugin_folder):
|
||||
return path_temp_plugin_folder
|
||||
|
||||
|
||||
def createTempPluginFolder():
|
||||
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" % configValues.pathToPluginFolder)
|
||||
print(oColors.brightRed + "Please check the config file!" + oColors.standardWhite)
|
||||
input("Press any key + enter to exit...")
|
||||
sys.exit()
|
||||
return tempPluginFolder
|
||||
|
||||
|
||||
def deleteTempPluginFolder(tempPluginFolder):
|
||||
try:
|
||||
shutil.rmtree(tempPluginFolder)
|
||||
os.mkdir(path_temp_plugin_folder)
|
||||
except OSError:
|
||||
rich_print_error(f"Error: Creation of directory {path_temp_plugin_folder} failed")
|
||||
rich_print_error(" Please check for missing permissions in folder tree!")
|
||||
sys.exit()
|
||||
return path_temp_plugin_folder
|
||||
|
||||
|
||||
def remove_temp_plugin_folder() -> None:
|
||||
"""
|
||||
Removes the temporary plugin folder and all content inside it
|
||||
"""
|
||||
try:
|
||||
shutil.rmtree(Path("./TempSFTPFolder"))
|
||||
except OSError as e:
|
||||
print ("Error: %s - %s." % (e.filename, e.strerror))
|
||||
rich_print_error(f"Error: {e.filename} - {e.strerror}")
|
||||
return
|
||||
|
||||
|
||||
def calculateFileSizeMb(downloadFileSize):
|
||||
fileSizeDownload = int(downloadFileSize)
|
||||
fileSizeMb = fileSizeDownload / 1024 / 1024
|
||||
roundedFileSize = round(fileSizeMb, 2)
|
||||
return roundedFileSize
|
||||
def convert_file_size_down(file_size) -> float:
|
||||
"""
|
||||
Convert the size of the number one down. E.g. MB -> KB through division with 1024
|
||||
"""
|
||||
converted_file_size = (int(file_size)) / 1024
|
||||
converted_file_size = round(converted_file_size, 2)
|
||||
return converted_file_size
|
||||
|
||||
def calculateFileSizeKb(downloadFileSize):
|
||||
fileSizeDownload = int(downloadFileSize)
|
||||
fileSizeKb = fileSizeDownload / 1024
|
||||
roundedFileSize = round(fileSizeKb, 2)
|
||||
return roundedFileSize
|
||||
|
||||
def check_local_plugin_folder(config_values) -> None:
|
||||
"""
|
||||
Check if a local plugin folder exists and if not exit the programm
|
||||
"""
|
||||
if config_values.local_seperate_download_path:
|
||||
plugin_folder_path = config_values.local_path_to_seperate_download_path
|
||||
else:
|
||||
plugin_folder_path = config_values.path_to_plugin_folder
|
||||
if not os.path.isdir(plugin_folder_path):
|
||||
rich_print_error(f"Error: Local plugin folder '{plugin_folder_path}' couldn't be found! \
|
||||
\n Check the config and try again!")
|
||||
sys.exit()
|
||||
return None
|
||||
|
||||
|
||||
def check_requirements() -> None:
|
||||
"""
|
||||
Check if the plugin folders are available
|
||||
"""
|
||||
config_values = config_value()
|
||||
match config_values.connection:
|
||||
case "local":
|
||||
check_local_plugin_folder(config_values)
|
||||
case "sftp":
|
||||
sftp_create_connection()
|
||||
case "ftp":
|
||||
ftp_create_connection()
|
||||
return None
|
||||
|
@ -1,9 +0,0 @@
|
||||
# Handles the web requests
|
||||
import requests
|
||||
|
||||
|
||||
def doAPIRequest(url):
|
||||
headers = {'user-agent': 'pluGET/1.0'}
|
||||
response = requests.get(url, headers=headers)
|
||||
packageDetails = response.json()
|
||||
return packageDetails
|
Loading…
x
Reference in New Issue
Block a user