mirror of
https://github.com/Neocky/pluGET.git
synced 2024-04-29 16:12:30 +00:00
245 lines
9.7 KiB
Python
245 lines
9.7 KiB
Python
"""
|
|
File and functions which handle the download of the specific plugins
|
|
"""
|
|
|
|
import re
|
|
from pathlib import Path
|
|
import requests
|
|
|
|
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
|
|
|
|
|
|
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
|
|
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 get_version_id(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/{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 get_version_name(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 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
|
|
|
|
|
|
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:
|
|
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()
|
|
|
|
# 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}")
|
|
elif file_size < 1000000:
|
|
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}")
|
|
# TODO add sftp and ftp support
|
|
#if config_values.connection == "sftp":
|
|
# sftp_session = createSFTPConnection()
|
|
# sftp_upload_file(sftp_session, download_path)
|
|
#elif config_values.connection == "ftp":
|
|
# ftp_session = createFTPConnection()
|
|
# ftp_upload_file(ftp_session, download_path)
|
|
return None
|
|
|
|
|
|
def get_specific_plugin(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:
|
|
download_path = get_download_path(config_values)
|
|
|
|
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(plugin_id, plugin_version)
|
|
plugin_version_name = get_version_name(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(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
|
|
console = Console()
|
|
selected_plugin_name = handle_regex_plugin_name(plugin_search_results[plugin_selected]["name"])
|
|
console.print(f"\n [bright_white]● [bright_magenta]{selected_plugin_name} [bright_green]latest")
|
|
get_specific_plugin(plugin_selected_id)
|