3@file MaterialXDownloader.py
4@brief MaterialX release downloader utility for fetching releases and libraries from GitHub.
13 """Class to handle downloading MaterialX releases and libraries."""
16 """Initialize the MaterialX release downloader with default settings.
18 Sets up default configuration for downloading MaterialX releases including
19 version count, target file names, chunk size, and download directory.
34 self.
RELEASES_API_URL = f
"https://api.github.com/repos/{self.REPO_OWNER}/{self.REPO_NAME}/releases"
37 """Custom attribute setter with validation.
39 @param name: The name of the attribute to set
40 @param value: The value to set for the attribute
43 if name ==
'chunk_size':
45 raise ValueError(
"Chunk size must be a positive integer.")
47 elif name ==
'version_number':
48 if isinstance(value, list)
and len(value) == 3:
51 raise ValueError(
"Version number must be a list of three integers [major, minor, patch].")
52 elif name ==
'download_directory':
54 if hasattr(self,
'create_download_directory'):
56 elif name
in [
'version_count',
'target_file_names',
'folder_filter']:
62 """Custom attribute getter for private attributes.
64 @param name: The name of the attribute to get
65 @return: The value of the requested attribute
67 if name
in [
'version_count',
'version_number',
'download_directory',
'target_file_names',
'chunk_size',
'folder_filter']:
68 return getattr(self, f
'_{name}')
69 elif name ==
'version_string':
71 raise AttributeError(f
"'{self.__class__.__name__}' object has no attribute '{name}'")
74 """Create the download directory if it doesn't exist.
81 """Download a file from a given URL to the specified destination.
83 @param url: The URL to download the file from
84 @param dest_path: The local path where the file should be saved
87 headers = {
"Authorization": f
"token {self.GITHUB_TOKEN}"}
if self.
GITHUB_TOKEN else {}
88 response = requests.get(url, headers=headers, stream=
True)
89 response.raise_for_status()
92 with open(dest_path,
"wb")
as file:
93 for chunk
in response.iter_content(chunk_size=download_chunk_size):
95 print(
'*', end=
'', flush=
True)
99 """Download the assets of the latest N releases.
101 @param by_count: If True, download by count limit; if False, download specific version
104 headers = {
"Authorization": f
"token {self.GITHUB_TOKEN}"}
if self.
GITHUB_TOKEN else {}
106 response.raise_for_status()
108 releases = response.json()
110 version_string =
None
112 version_string = self.version_string
115 for release
in releases:
116 release_name = release[
"name"]
120 if version_string
in release_name:
123 print(f
"Skipping release: {release_name} (does not match version string {version_string})")
129 print(f
"Checking assets for release: {release_name}. Tag: {release['tag_name']}")
130 for asset
in release[
"assets"]:
131 asset_name = asset[
"name"]
134 print(
"- Found asset:", asset_name)
135 tag_names.append(release[
"tag_name"])
136 asset_url = asset[
"browser_download_url"]
137 asset_urls.append(asset_url)
141 asset_urls = list(asset_urls)
142 tag_names = list(tag_names)
144 for asset_url, tag_name
in zip(asset_urls, tag_names):
145 print(f
"- Downloading {asset_name} from {asset_url}")
148 print(f
"Saved to {dest_path}")
151 print(f
"Extracting {dest_path} to {os.path.join(self._download_directory, tag_name)}")
152 with zipfile.ZipFile(dest_path,
'r')
as zip_ref:
154 print(f
"Extracted to {os.path.join(self._download_directory, tag_name)}")
158 print(f
"Finished checking assets for release: {release_name}")
169 """Download the 'Source code (zip)' for the latest N releases and extract the standard 'libraries' folder.
171 @param by_count: If True, download by count limit; if False, download specific version
174 headers = {
"Authorization": f
"token {self.GITHUB_TOKEN}"}
if self.
GITHUB_TOKEN else {}
176 response.raise_for_status()
178 releases = response.json()
180 version_string =
None
182 version_string = self.version_string
185 for release
in releases:
186 tag_name = release[
"tag_name"]
187 release_name = release[
"name"]
189 if version_string
not in release_name:
190 print(f
"Skipping release: {release_name} (does not match version string {version_string})")
195 print(f
"Downloading 'Source code (zip)' for release: {release_name} (tag: {tag_name})")
197 source_zip_url = f
"https://github.com/{self.REPO_OWNER}/{self.REPO_NAME}/archive/refs/tags/{tag_name}.zip"
200 print(f
"\nSaved ZIP to {dest_path}")
203 print(f
"Extracing ZIP files from {dest_path} to {os.path.join(self._download_directory, tag_name)}")
204 with zipfile.ZipFile(dest_path,
'r')
as zip_ref:
205 for file
in zip_ref.namelist():
208 path_parts = file.split(
'/')
209 if len(path_parts) > 1:
212 relative_path =
'/'.join(path_parts[1:])
215 if any(relative_path.startswith(f
"{folder}/")
for folder
in self.
_folder_filter):
218 new_file_path = relative_path
221 info = zip_ref.getinfo(file)
222 info.filename = new_file_path
227 print(
'+', end=
'', flush=
True)
230 print(
"\nFinished extracting libraries folder from zip file.")
235 print(f
"Removed zip file: {dest_path}")
Class to handle downloading MaterialX releases and libraries.
int _remove_zip_after_extract
None download_libraries(self, bool by_count=True)
Download the 'Source code (zip)' for the latest N releases and extract the standard 'libraries' folde...
bool _remove_zip_after_extract
None __init__(self)
Initialize the MaterialX release downloader with default settings.
None __setattr__(self, str name, value)
Custom attribute setter with validation.
None download_releases(self, bool by_count=True)
Download the assets of the latest N releases.
None download_file(self, str url, str dest_path)
Download a file from a given URL to the specified destination.
__getattr__(self, str name)
Custom attribute getter for private attributes.
None create_download_directory(self)
Create the download directory if it doesn't exist.