From b33ec7434738af99ecf41ca353acd605ff0d0ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 22 Jul 2016 16:39:35 +0200 Subject: [PATCH] Texture browser: Use node name as file name --- blender_cloud/pillar.py | 21 ++++++++++++++++----- blender_cloud/texture_browser.py | 22 ++++++++++++++++------ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/blender_cloud/pillar.py b/blender_cloud/pillar.py index 37ee360..38993a5 100644 --- a/blender_cloud/pillar.py +++ b/blender_cloud/pillar.py @@ -648,11 +648,17 @@ async def download_file_by_uuid(file_uuid, target_directory: str, metadata_directory: str, *, + filename: str = None, map_type: str = None, file_loading: callable = None, file_loaded: callable = None, file_loaded_sync: callable = None, future: asyncio.Future): + """Downloads a file from Pillar by its UUID. + + :param filename: overrules the filename in file_doc['filename'] if given. + The extension from file_doc['filename'] is still used, though. + """ if is_cancelled(future): log.debug('download_file_by_uuid(%r) cancelled.', file_uuid) return @@ -668,8 +674,10 @@ async def download_file_by_uuid(file_uuid, metadata_file = os.path.join(metadata_directory, 'files', '%s.json' % file_uuid) save_as_json(file_desc, metadata_file) - # TODO: base the file name on the node name, not the filename in the file_desc. + # Let the caller override the filename root. root, ext = os.path.splitext(file_desc['filename']) + if filename: + root, _ = os.path.splitext(filename) if not map_type or root.endswith(map_type): target_filename = '%s%s' % (root, ext) else: @@ -679,7 +687,7 @@ async def download_file_by_uuid(file_uuid, file_url = file_desc['link'] # log.debug('Texture %r:\n%s', file_uuid, pprint.pformat(file_desc.to_dict())) if file_loading is not None: - loop.call_soon_threadsafe(file_loading, file_path, file_desc) + loop.call_soon_threadsafe(file_loading, file_path, file_desc, map_type) # Cached headers are stored in the project space header_store = os.path.join(metadata_directory, 'files', @@ -688,9 +696,9 @@ async def download_file_by_uuid(file_uuid, await download_to_file(file_url, file_path, header_store=header_store, future=future) if file_loaded is not None: - loop.call_soon_threadsafe(file_loaded, file_path, file_desc) + loop.call_soon_threadsafe(file_loaded, file_path, file_desc, map_type) if file_loaded_sync is not None: - await file_loaded_sync(file_path, file_desc) + await file_loaded_sync(file_path, file_desc, map_type) async def download_texture(texture_node, @@ -705,13 +713,16 @@ async def download_texture(texture_node, raise TypeError("Node type should be in %r, not %r" % (TEXTURE_NODE_TYPES, node_type_name)) + filename = '%s.taken_from_file' % sanitize_filename(texture_node['name']) + # Download every file. Eve doesn't support embedding from a list-of-dicts. downloaders = [] for file_info in texture_node['properties']['files']: dlr = download_file_by_uuid(file_info['file'], target_directory, metadata_directory, - map_type=file_info.map_type, + filename=filename, + map_type=file_info.map_type or file_info.resolution, file_loading=texture_loading, file_loaded=texture_loaded, future=future) diff --git a/blender_cloud/texture_browser.py b/blender_cloud/texture_browser.py index 0f02ed8..b8700c4 100644 --- a/blender_cloud/texture_browser.py +++ b/blender_cloud/texture_browser.py @@ -811,10 +811,10 @@ class BlenderCloudBrowser(pillar.PillarOperatorMixin, file_paths = [] select_dblock = None - def texture_downloading(file_path, file_desc, *args): + def texture_downloading(file_path, *_): self.log.info('Texture downloading to %s', file_path) - def texture_downloaded(file_path, file_desc, *args): + def texture_downloaded(file_path, file_desc, map_type): nonlocal select_dblock self.log.info('Texture downloaded to %r.', file_path) @@ -833,6 +833,13 @@ class BlenderCloudBrowser(pillar.PillarOperatorMixin, image_dblock['bcloud_node_type'] = node['node_type'] image_dblock['bcloud_node'] = pillar.node_to_id(node) + if node['node_type'] == 'hdri': + # All HDRi variations should use the same image datablock, hence once name. + image_dblock.name = node['name'] + else: + # All texture variations are loaded at once, and thus need the map type in the name. + image_dblock.name = '%s-%s' % (node['name'], map_type) + # Select the image in the image editor (if the context is right). # Just set the first image we download, if context.area.type == 'IMAGE_EDITOR': @@ -941,13 +948,15 @@ class PILLAR_OT_switch_hdri(pillar.PillarOperatorMixin, self._state = 'QUIT' async def download_and_replace(self, context): + from .pillar import sanitize_filename + self._state = 'DOWNLOADING_TEXTURE' current_image = bpy.data.images[self.image_name] + node = current_image['bcloud_node'] + filename = '%s.taken_from_file' % sanitize_filename(node['name']) local_path = os.path.dirname(bpy.path.abspath(current_image.filepath)) - node = current_image['bcloud_node'] - top_texture_directory = bpy.path.abspath(context.scene.local_texture_dir) meta_path = os.path.join(top_texture_directory, '.blender_cloud') @@ -958,11 +967,11 @@ class PILLAR_OT_switch_hdri(pillar.PillarOperatorMixin, self.log.info('Downloading file %r-%s to %s', file_uuid, resolution, local_path) self.log.debug('Metadata will be stored at %s', meta_path) - def file_loading(file_path, file_desc): + def file_loading(file_path, file_desc, map_type): self.log.info('Texture downloading to %s (%s)', file_path, utils.sizeof_fmt(file_desc['length'])) - async def file_loaded(file_path, file_desc): + async def file_loaded(file_path, file_desc, map_type): if context.scene.local_texture_dir.startswith('//'): file_path = bpy.path.relpath(file_path) @@ -973,6 +982,7 @@ class PILLAR_OT_switch_hdri(pillar.PillarOperatorMixin, await pillar.download_file_by_uuid(file_uuid, local_path, meta_path, + filename=filename, map_type=resolution, file_loading=file_loading, file_loaded_sync=file_loaded,