mirror of
https://github.com/blw1138/Zordon.git
synced 2026-02-05 13:46:10 +00:00
* Initial commit for settings window * More WIP for the Settings panel * Added Local Files section to Settings * More WIP on Settings * Add ability to ignore system builds * Improvements to Launch and Delete buttons * Fix issue where icons were not loading * Network password settings WIP * Update label * Import and naming fixes * Speed improvements to launch * Update requirements.txt * Update Windows CPU name lookup * Add missing default values to a few settings * More settings fixes * Fix Windows Path issue * Added hard types for getting settings values * More UI cleanup * Correctly refresh Engines list after downloading new engine * Improve downloader with UI progress * More download improvements * Add Settings Button to Toolbar
147 lines
5.6 KiB
Python
147 lines
5.6 KiB
Python
import logging
|
|
import re
|
|
import threading
|
|
|
|
import requests
|
|
|
|
from src.engines.blender.blender_engine import Blender
|
|
from src.engines.core.base_downloader import EngineDownloader
|
|
from src.utilities.misc_helper import current_system_os, current_system_cpu
|
|
|
|
url = "https://download.blender.org/release/"
|
|
|
|
logger = logging.getLogger()
|
|
supported_formats = ['.zip', '.tar.xz', '.dmg']
|
|
|
|
|
|
class BlenderDownloader(EngineDownloader):
|
|
|
|
engine = Blender
|
|
|
|
@staticmethod
|
|
def __get_major_versions():
|
|
try:
|
|
response = requests.get(url, timeout=5)
|
|
response.raise_for_status()
|
|
|
|
# Use regex to find all the <a> tags and extract the href attribute
|
|
link_pattern = r'<a href="([^"]+)">Blender(\d+[^<]+)</a>'
|
|
link_matches = re.findall(link_pattern, response.text)
|
|
|
|
major_versions = [link[-1].strip('/') for link in link_matches]
|
|
major_versions.sort(reverse=True)
|
|
return major_versions
|
|
except requests.exceptions.RequestException as e:
|
|
logger.error(f"Error: {e}")
|
|
return []
|
|
|
|
@staticmethod
|
|
def __get_minor_versions(major_version, system_os=None, cpu=None):
|
|
|
|
try:
|
|
base_url = url + 'Blender' + major_version
|
|
response = requests.get(base_url, timeout=5)
|
|
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)]
|
|
|
|
# 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 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]
|
|
versions_data = [x for x in versions_data if x['cpu'] == cpu]
|
|
|
|
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
|
|
except requests.exceptions.HTTPError as e:
|
|
logger.error(f"Invalid url: {e}")
|
|
except Exception as e:
|
|
logger.exception(e)
|
|
return []
|
|
|
|
@staticmethod
|
|
def __find_LTS_versions():
|
|
response = requests.get('https://www.blender.org/download/lts/')
|
|
response.raise_for_status()
|
|
|
|
lts_pattern = r'https://www.blender.org/download/lts/(\d+-\d+)/'
|
|
lts_matches = re.findall(lts_pattern, response.text)
|
|
lts_versions = [ver.replace('-', '.') for ver in list(set(lts_matches))]
|
|
lts_versions.sort(reverse=True)
|
|
|
|
return lts_versions
|
|
|
|
@classmethod
|
|
def all_versions(cls, system_os=None, cpu=None):
|
|
majors = cls.__get_major_versions()
|
|
all_versions = []
|
|
threads = []
|
|
results = [[] for _ in majors]
|
|
|
|
def thread_function(major_version, index, system_os_t, cpu_t):
|
|
results[index] = cls.__get_minor_versions(major_version, system_os_t, cpu_t)
|
|
|
|
for i, m in enumerate(majors):
|
|
thread = threading.Thread(target=thread_function, args=(m, i, system_os, cpu))
|
|
threads.append(thread)
|
|
thread.start()
|
|
|
|
# Wait for all threads to complete
|
|
for thread in threads:
|
|
thread.join()
|
|
|
|
# Extend all_versions with the results from each thread
|
|
for result in results:
|
|
all_versions.extend(result)
|
|
|
|
return all_versions
|
|
|
|
@classmethod
|
|
def find_most_recent_version(cls, system_os=None, cpu=None, lts_only=False):
|
|
try:
|
|
major_version = cls.__find_LTS_versions()[0] if lts_only else cls.__get_major_versions()[0]
|
|
most_recent = cls.__get_minor_versions(major_version=major_version, system_os=system_os, cpu=cpu)
|
|
return most_recent[0]
|
|
except (IndexError, requests.exceptions.RequestException):
|
|
logger.error(f"Cannot get most recent version of blender")
|
|
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
|
|
|
|
@classmethod
|
|
def download_engine(cls, version, download_location, system_os=None, cpu=None, timeout=120, progress_callback=None):
|
|
system_os = system_os or current_system_os()
|
|
cpu = cpu or current_system_cpu()
|
|
|
|
try:
|
|
logger.info(f"Requesting download of blender-{version}-{system_os}-{cpu}")
|
|
major_version = '.'.join(version.split('.')[:2])
|
|
minor_versions = [x for x in cls.__get_minor_versions(major_version, system_os, cpu) if
|
|
x['version'] == version]
|
|
cls.download_and_extract_app(remote_url=minor_versions[0]['url'], download_location=download_location,
|
|
timeout=timeout, progress_callback=progress_callback)
|
|
except IndexError:
|
|
logger.error("Cannot find requested engine")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
|
|
print(BlenderDownloader.find_most_recent_version())
|