Added new spiget downloader

Added new spiget downloader for plugins with progress bar and error handling for Issue #46
This commit is contained in:
Jan-Luca Bogdan | BEL NET GmbH 2022-06-17 12:51:32 +02:00
parent d427886c49
commit 84fcfc8922
4 changed files with 48 additions and 29 deletions

View File

@ -18,11 +18,11 @@ except:
if __name__ == "__main__": if __name__ == "__main__":
check_config()
rename_console_title() rename_console_title()
check_config()
validate_config()
api_test_spiget() api_test_spiget()
check_requirements() check_requirements()
validate_config()
parser = argparse.ArgumentParser(description="Arguments for pluGET", parser = argparse.ArgumentParser(description="Arguments for pluGET",
formatter_class=argparse.ArgumentDefaultsHelpFormatter) formatter_class=argparse.ArgumentDefaultsHelpFormatter)
#parser.add_argument("-a", "--archive", action="store_true", help="archive mode") #parser.add_argument("-a", "--archive", action="store_true", help="archive mode")

View File

@ -40,6 +40,7 @@ def check_config() -> None:
""" """
if not os.path.isfile("pluGET_config.yaml"): if not os.path.isfile("pluGET_config.yaml"):
create_config() create_config()
return None
def create_config() -> None: def create_config() -> None:

View File

@ -3,11 +3,12 @@ File and functions which handle the download of the specific plugins
""" """
import re import re
import urllib.request
from pathlib import Path from pathlib import Path
import requests
from rich.table import Table from rich.table import Table
from rich.console import Console 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 convert_file_size_down, remove_temp_plugin_folder, create_temp_plugin_folder
from src.utils.utilities import api_do_request from src.utils.utilities import api_do_request
@ -15,7 +16,7 @@ from src.utils.console_output import rich_print_error
from src.handlers.handle_config import config_value from src.handlers.handle_config import config_value
def handle_regex_package_name(full_plugin_name) -> str: def handle_regex_plugin_name(full_plugin_name) -> str:
""" """
Return the plugin name after trimming clutter from name with regex operations Return the plugin name after trimming clutter from name with regex operations
""" """
@ -90,7 +91,7 @@ def get_download_path(config_values) -> str:
return config_values.remote_plugin_folder_on_server return config_values.remote_plugin_folder_on_server
def download_specific_plugin_version(plugin_id, download_path, version_id="latest") -> None: def download_specific_plugin_version_spiget(plugin_id, download_path, version_id="latest") -> None:
""" """
Download a specific plugin Download a specific plugin
""" """
@ -103,26 +104,41 @@ def download_specific_plugin_version(plugin_id, download_path, version_id="lates
#url = f"https://api.spiget.org/v2/resources/{plugin_id}/versions/latest/download" #throws 403 forbidden error...cloudflare :( #url = f"https://api.spiget.org/v2/resources/{plugin_id}/versions/latest/download" #throws 403 forbidden error...cloudflare :(
url = f"https://api.spiget.org/v2/resources/{plugin_id}/download" url = f"https://api.spiget.org/v2/resources/{plugin_id}/download"
urrlib_opener = urllib.request.build_opener() # use rich Progress() to create progress bar
urrlib_opener.addheaders = [('User-agent', 'pluGET/1.0')] with Progress() as progress:
urllib.request.install_opener(urrlib_opener) 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(" [bright_red]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()
remote_file = urllib.request.urlopen(url) # use rich console for nice colors
try: console = Console()
file_size = int(remote_file.info()['Content-Length']) if file_size == 0:
except TypeError: console.print(
# if api won't return file size set it to 0 to avoid throwing an error f" [not bold][bright_green]Downloaded[bright_magenta] file [cyan]→ [white]{download_path}"
file_size = 0 )
urllib.request.urlretrieve(url, download_path) elif file_size >= 1000000:
print(" ", end='')
if file_size >= 1000000 and file_size != 0:
file_size_data = convert_file_size_down(convert_file_size_down(file_size)) file_size_data = convert_file_size_down(convert_file_size_down(file_size))
print("Downloaded " + (str(file_size_data)).rjust(9) + f" MB here {download_path}") console.print(" [not bold][bright_green]Downloaded[bright_magenta] " + (str(file_size_data)).rjust(9) + \
elif file_size != 0: f" MB [cyan]→ [white]{download_path}")
elif file_size < 1000000:
file_size_data = convert_file_size_down(file_size) file_size_data = convert_file_size_down(file_size)
print("Downloaded " + (str(file_size_data)).rjust(9) + f" KB here {download_path}") console.print(" [not bold][bright_green]Downloaded[bright_magenta] " + (str(file_size_data)).rjust(9) + \
else: f" KB [cyan]→ [white]{download_path}")
print(f"Downloaded file here {download_path}")
# TODO add sftp and ftp support # TODO add sftp and ftp support
#if config_values.connection == "sftp": #if config_values.connection == "sftp":
# sftp_session = createSFTPConnection() # sftp_session = createSFTPConnection()
@ -151,10 +167,10 @@ def get_specific_plugin(plugin_id, plugin_version="latest") -> None:
try: try:
plugin_name = plugin_details["name"] plugin_name = plugin_details["name"]
except KeyError: except KeyError:
# exit if plugin id coudn't be found # exit if plugin id couldn't be found
rich_print_error("Error: Plugin ID couldn't be found") rich_print_error("Error: Plugin ID couldn't be found")
return None return None
plugin_name = handle_regex_package_name(plugin_name) plugin_name = handle_regex_plugin_name(plugin_name)
plugin_version_id = get_version_id(plugin_id, plugin_version) plugin_version_id = get_version_id(plugin_id, plugin_version)
plugin_version_name = get_version_name(plugin_id, plugin_version_id) plugin_version_name = get_version_name(plugin_id, plugin_version_id)
plugin_download_name = f"{plugin_name}-{plugin_version_name}.jar" plugin_download_name = f"{plugin_name}-{plugin_version_name}.jar"
@ -162,7 +178,7 @@ def get_specific_plugin(plugin_id, plugin_version="latest") -> None:
# set the plugin_version_id to None if a specific version wasn't given as parameter # 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: if plugin_version == "latest" or plugin_version is None:
plugin_version_id = None plugin_version_id = None
download_specific_plugin_version(plugin_id, download_plugin_path, plugin_version_id) download_specific_plugin_version_spiget(plugin_id, download_plugin_path, plugin_version_id)
if config_values.connection != "local": if config_values.connection != "local":
remove_temp_plugin_folder() remove_temp_plugin_folder()
@ -190,7 +206,7 @@ def search_specific_plugin(plugin_name) -> None:
# start counting at 1 for all my non-programming friends :) # start counting at 1 for all my non-programming friends :)
i = 1 i = 1
for found_plugin in plugin_search_results: for found_plugin in plugin_search_results:
plugin_name = handle_regex_package_name(found_plugin["name"]) plugin_name = handle_regex_plugin_name(found_plugin["name"])
plugin_downloads = found_plugin["downloads"] plugin_downloads = found_plugin["downloads"]
plugin_description = found_plugin["tag"] plugin_description = found_plugin["tag"]
rich_table.add_row(str(i), plugin_name, str(plugin_downloads), plugin_description) rich_table.add_row(str(i), plugin_name, str(plugin_downloads), plugin_description)
@ -215,5 +231,7 @@ def search_specific_plugin(plugin_name) -> None:
except IndexError: except IndexError:
rich_print_error("Error: Number was out of range! Please try again!") rich_print_error("Error: Number was out of range! Please try again!")
return None 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) get_specific_plugin(plugin_selected_id)

View File

@ -49,12 +49,12 @@ class TestCases(unittest.TestCase):
result=plugin_downloader.get_download_path(config_values_ftp) result=plugin_downloader.get_download_path(config_values_ftp)
self.assertEqual(result, config_values_ftp.remote_path_to_seperate_download_path) self.assertEqual(result, config_values_ftp.remote_path_to_seperate_download_path)
def test_convert_file_size_down(self): def test_convert_file_size_down(self):
# 100000 / 1024 = 97.66 # 100000 / 1024 = 97.66
result= utilities.convert_file_size_down(100000) result= utilities.convert_file_size_down(100000)
self.assertEqual(result, 97.66) self.assertEqual(result, 97.66)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()