Skip to content

Commit 550fc10

Browse files
authored
Merge pull request #12 from Unity-Technologies/release/0.6.0
Release 0.6.0
2 parents 62c3e5a + 8e2ae25 commit 550fc10

File tree

8 files changed

+171
-77
lines changed

8 files changed

+171
-77
lines changed

CHANGELOG.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,20 @@ All notable changes to this package will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8-
## [0.5.0]
8+
## [0.6.0] - 2025-05-28
9+
10+
### Added
11+
- Assets containing only one audio file will automatically have their preview set as the same audio file.
12+
13+
### Fixed
14+
- Fix preview detection for `One file = one asset` strategy.
15+
- Section for Virtual Private Cloud Support in documentation
16+
17+
### Changed
18+
- Cleaned up documentation
19+
- Updated Python SDK dependency for bulk_upload to 0.10.7
20+
21+
## [0.5.0] - 2025-03-21
922

1023
### Added
1124
- Added the capacity to replicate assets' folder structure into collections.
@@ -65,4 +78,4 @@ Initial release
6578

6679
Features:
6780
- Source code of `bulk_upload_cli`
68-
- Source code of `bulk_download_script`
81+
- Source code of `bulk_download_script`

bulk_upload_cli/README.md

Lines changed: 92 additions & 61 deletions
Large diffs are not rendered by default.

bulk_upload_cli/bulk_upload/asset_mappers.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ def map_assets(self, config: ProjectUploaderConfig) -> [AssetInfo]:
153153

154154
@staticmethod
155155
def is_preview_file(file_path) -> bool:
156-
157156
file_suffix = file_path.suffix.lower()
158157
is_picture_file = file_suffix in [".png", ".jpg", ".jpeg", ".bmp", ".gif"]
159158

@@ -253,9 +252,8 @@ def map_assets(self, config: ProjectUploaderConfig) -> [AssetInfo]:
253252
continue
254253

255254
if self.is_preview_file(file):
256-
file_stem = file.stem.lower().replace("_preview", "")
257-
potential_previews[file_stem] = FileInfo(file,
258-
PurePosixPath(file.relative_to(config.assets_path)))
255+
file_stem = self.remove_preview_suffix(file)
256+
potential_previews[file_stem] = FileInfo(file, PurePosixPath(file.relative_to(config.assets_path)))
259257

260258
for file in files:
261259
if self.is_directory_path(file):
@@ -284,17 +282,32 @@ def map_assets(self, config: ProjectUploaderConfig) -> [AssetInfo]:
284282

285283
@staticmethod
286284
def is_preview_file(file_path) -> bool:
287-
file_suffix = file_path.suffix
288-
is_picture_file= file_suffix in [".png", ".jpg", ".jpeg", ".bmp", ".gif"]
285+
file_suffix = file_path.suffix.lower()
286+
is_picture_file = file_suffix in [".png", ".jpg", ".jpeg", ".bmp", ".gif"]
289287

290288
file_stem = file_path.stem.lower()
289+
file_name_is_preview = file_stem in ["preview", "previews", "thumbnail", "thumbnails"]
291290

292-
return file_stem.endswith("_preview") and is_picture_file
291+
file_parent_folder = file_path.parent.name.lower()
292+
parent_folder_is_preview = file_parent_folder in ["preview", "previews", "thumbnail", "thumbnails"]
293+
294+
return is_picture_file and file_name_is_preview or is_picture_file and parent_folder_is_preview
293295

294296
@staticmethod
295297
def is_directory_path(file_path) -> bool:
296298
return len(file_path.name.split("/")[-1].split(".")) == 1
297299

300+
@staticmethod
301+
def remove_preview_suffix(file_path) -> str:
302+
file_stem = file_path.stem.lower()
303+
304+
for suffix in ["preview", "previews", "thumbnail", "thumbnails"]:
305+
if file_stem.endswith(suffix):
306+
new_stem = file_stem.replace(suffix, "")
307+
break
308+
309+
return file_stem
310+
298311

299312
class CsvAssetMapper(AssetMapper):
300313

bulk_upload_cli/bulk_upload/assets_customization_providers.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ def get_collection(org_id, project_id) -> str:
8484
description=collection)
8585
uc.assets.create_collection(collection_creation, org_id, project_id)
8686

87-
return collection if collection != "No collection" else ""
87+
if collection == "No collection":
88+
return ""
89+
90+
return collection
8891

8992
@staticmethod
9093
def get_assets_organization() -> bool:
@@ -157,7 +160,13 @@ def apply_asset_customization(self, assets: [AssetInfo], config: ProjectUploader
157160

158161
def get_cloud_collections(org_id: str, project_id: str):
159162
collections = uc.assets.list_collections(org_id, project_id)
160-
return [collection.name for collection in collections]
163+
collections_choices = []
164+
for collection in collections:
165+
if collection.parent_path == "":
166+
collections_choices.append(collection.name)
167+
else:
168+
collections_choices.append(f"{collection.parent_path}/{collection.name}")
169+
return collections_choices
161170

162171

163172
def sanitize_tags(tags: str) -> list[str]:

bulk_upload_cli/bulk_upload/assets_uploaders.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,15 @@ def __init__(self):
2727
def upload_assets(self, asset_infos: [AssetInfo], config: ProjectUploaderConfig, app_settings: AppSettings):
2828
self.config = config
2929

30-
cloud_assets = [] if config.strategy == Strategy.CLOUD_ASSET else uc.assets.get_asset_list(self.config.org_id, self.config.project_id)
30+
cloud_assets = []
31+
if config.strategy != Strategy.CLOUD_ASSET:
32+
try:
33+
cloud_assets = uc.assets.get_asset_list(self.config.org_id, self.config.project_id)
34+
except Exception as e:
35+
logger.exception(f"Failed to get cloud assets: {e}")
36+
logger.warning("====== WARNING ====")
37+
logger.warning("Upload will continue, but no update can be made, only creation. /n")
38+
3139

3240
if asset_infos is None:
3341
return
@@ -222,6 +230,9 @@ def set_asset_decorations(self, asset: AssetInfo, skip_freeze: bool = False):
222230
print(asset.customization.description)
223231
asset_update.description = asset.customization.description
224232

233+
if len(asset.preview_files) == 0 and asset.is_audio_asset():
234+
asset_update = AssetUpdate(name=asset.name, preview_file=asset.files[0].cloud_path)
235+
225236
try:
226237
uc.assets.update_asset(asset_update, self.config.org_id, self.config.project_id, asset.am_id, asset.version)
227238
except Exception as e:
@@ -238,6 +249,8 @@ def create_collections(self, collections: [CollectionInfo]):
238249
if not collection.exists_in_cloud:
239250
collection_creation = CollectionCreation(name=collection.get_name(), parent_path=collection.get_parent(), description=collection.get_name())
240251
uc.assets.create_collection(collection_creation, self.config.org_id, self.config.project_id)
252+
# wait for the collection to be created since this can cause unauthorized errors if the collection is not ready
253+
time.sleep(0.5)
241254
collection.exists_in_cloud = True
242255

243256
except Exception as e:
@@ -248,8 +261,9 @@ def set_collections(self, collections: [CollectionInfo]):
248261
for collection in collections:
249262
try:
250263
if len(collection.assets) > 0:
251-
uc.assets.link_assets_to_collection(self.config.org_id, self.config.project_id, collection.path.__str__(), [asset.am_id for asset in collection.assets])
252-
264+
uc.assets.link_assets_to_collection(self.config.org_id, self.config.project_id,
265+
collection.path.__str__(),
266+
[asset.am_id for asset in collection.assets])
253267
except Exception as e:
254268
print(f'Failed to set assets to collection : {collection.path.__str__()}', flush=True)
255269
print(e, flush=True)

bulk_upload_cli/bulk_upload/config_providers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ def get_folder_config(self, strategy: Strategy) -> ProjectUploaderConfig:
178178
self.config.hierarchical_level = self.execute_prompt_auto(inquirer.number(
179179
message="Enter the depth of directory grouping (for example, 1 to group by top folders in your asset directory)"),
180180
self.config.hierarchical_level)
181+
182+
if strategy == Strategy.SINGLE_FILE_ASSET or strategy == Strategy.FOLDER_GROUPING:
181183
self.config.preview_detection = self.execute_prompt_auto(inquirer.confirm(
182184
message="Would you like to enable automatic preview detection (see documentation to see how it is detected)?"),
183185
self.config.preview_detection)

bulk_upload_cli/bulk_upload/models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,18 @@ def from_csv(self, csv_row: {}):
265265
def get_files_size(self):
266266
return sum([os.stat(f.path.__str__()).st_size for f in self.files])
267267

268+
def is_audio_asset(self):
269+
if len(self.files) == 1:
270+
return self.is_audio_extension(self.files[0].path.suffix)
271+
elif len(self.files) == 2:
272+
return any(self.is_audio_extension(f.path.suffix) for f in self.files) \
273+
and any(f.path.suffix in [".meta"] for f in self.files)
274+
return False
275+
276+
@staticmethod
277+
def is_audio_extension(extension: str):
278+
return extension.lower() in [".wav", ".mp3", ".ogg", ".aiff", ".aif"]
279+
268280

269281
class AssetCustomization(object):
270282
def __init__(self):

bulk_upload_cli/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This file lists all pip dependencies
22

33
--extra-index-url https://unity3ddist.jfrog.io/artifactory/api/pypi/am-pypi-prod-local/simple
4-
unity_cloud == 0.10.6
4+
unity_cloud == 0.10.7
55

6-
InquirerPy
6+
InquirerPy

0 commit comments

Comments
 (0)