Engine downloader API for #31 (#42)

* Add is_engine_available_to_download API call

* Fix issue with worker never throwing error if engine is not found

* Add API call to get most recent engine version

* Fix some minor import issues

* Fix web urls

* Fix default server log level

* Add progress bar for project download worker_factory downloads missing engine versions

* Better error handling when invalid version is given

* Add timeouts to engine downloaders
This commit is contained in:
2023-10-22 15:02:30 -07:00
committed by GitHub
parent 9603046432
commit e52682c8b9
9 changed files with 193 additions and 68 deletions

View File

@@ -4,7 +4,8 @@ import re
import requests
from ..core.downloader_core import download_and_extract_app
from src.engines.core.downloader_core import download_and_extract_app
from src.utilities.misc_helper import current_system_os, current_system_cpu
# url = "https://download.blender.org/release/"
url = "https://ftp.nluug.nl/pub/graphics/blender/release/" # much faster mirror for testing
@@ -35,27 +36,42 @@ class BlenderDownloader:
@staticmethod
def get_minor_versions(major_version, system_os=None, cpu=None):
base_url = url + 'Blender' + major_version
try:
base_url = url + 'Blender' + major_version
response = requests.get(base_url)
response.raise_for_status()
response = requests.get(base_url)
response.raise_for_status()
versions_pattern = r'<a href="(?P<file>[^"]+)">blender-(?P<version>[\d\.]+)-(?P<system_os>\w+)-(?P<cpu>\w+).*</a>'
versions_data = [match.groupdict() for match in re.finditer(versions_pattern, response.text)]
versions_pattern = r'<a href="(?P<file>[^"]+)">blender-(?P<version>[\d\.]+)-(?P<system_os>\w+)-(?P<cpu>\w+).*</a>'
versions_data = [match.groupdict() for match in re.finditer(versions_pattern, response.text)]
# Filter to just the supported formats
versions_data = [item for item in versions_data if any(item["file"].endswith(ext) for ext in supported_formats)]
# Filter to just the supported formats
versions_data = [item for item in versions_data if any(item["file"].endswith(ext) for ext in supported_formats)]
if system_os:
# Filter down OS and CPU
system_os = system_os or current_system_os()
cpu = cpu or current_system_cpu()
versions_data = [x for x in versions_data if x['system_os'] == system_os]
if cpu:
versions_data = [x for x in versions_data if x['cpu'] == cpu]
for v in versions_data:
v['url'] = base_url + '/' + v['file']
for v in versions_data:
v['url'] = base_url + '/' + v['file']
versions_data = sorted(versions_data, key=lambda x: x['version'], reverse=True)
return versions_data
versions_data = sorted(versions_data, key=lambda x: x['version'], reverse=True)
return versions_data
except requests.exceptions.HTTPError as e:
logger.error(f"Invalid url: {e}")
except Exception as e:
logger.exception(e)
return []
@classmethod
def version_is_available_to_download(cls, version, system_os=None, cpu=None):
requested_major_version = '.'.join(version.split('.')[:2])
minor_versions = cls.get_minor_versions(requested_major_version, system_os, cpu)
for minor in minor_versions:
if minor['version'] == version:
return minor
return None
@staticmethod
def find_LTS_versions():
@@ -79,7 +95,7 @@ class BlenderDownloader:
logger.error("Cannot find a most recent version")
@classmethod
def download_engine(cls, version, download_location, system_os=None, cpu=None):
def download_engine(cls, version, download_location, system_os=None, cpu=None, timeout=120):
system_os = system_os or platform.system().lower().replace('darwin', 'macos')
cpu = cpu or platform.machine().lower().replace('amd64', 'x64')
@@ -89,7 +105,8 @@ class BlenderDownloader:
minor_versions = [x for x in cls.get_minor_versions(major_version, system_os, cpu) if x['version'] == version]
# we get the URL instead of calculating it ourselves. May change this
download_and_extract_app(remote_url=minor_versions[0]['url'], download_location=download_location)
download_and_extract_app(remote_url=minor_versions[0]['url'], download_location=download_location,
timeout=timeout)
except IndexError:
logger.error("Cannot find requested engine")