Gracefully handle download errors in texture browser
This commit is contained in:
parent
0a99b9e22e
commit
79dc5c91f7
BIN
blender_cloud/icons/error.png
Normal file
BIN
blender_cloud/icons/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
@ -632,7 +632,11 @@ async def download_texture_thumbnail(texture_node, desired_size: str,
|
||||
# Cached headers are stored next to thumbnails in sidecar files.
|
||||
header_store = '%s.headers' % thumb_path
|
||||
|
||||
try:
|
||||
await download_to_file(thumb_url, thumb_path, header_store=header_store, future=future)
|
||||
except requests.exceptions.HTTPError as ex:
|
||||
log.error('Unable to download %s: %s', thumb_url, ex)
|
||||
thumb_path = 'ERROR'
|
||||
|
||||
loop.call_soon_threadsafe(thumbnail_loaded, texture_node, file_desc, thumb_path)
|
||||
|
||||
|
@ -82,6 +82,7 @@ class MenuItem:
|
||||
DEFAULT_ICONS = {
|
||||
'FOLDER': os.path.join(library_icons_path, 'folder.png'),
|
||||
'SPINNER': os.path.join(library_icons_path, 'spinner.png'),
|
||||
'ERROR': os.path.join(library_icons_path, 'error.png'),
|
||||
}
|
||||
|
||||
FOLDER_NODE_TYPES = {'group_texture', 'group_hdri', UpNode.NODE_TYPE, ProjectNode.NODE_TYPE}
|
||||
@ -99,6 +100,7 @@ class MenuItem:
|
||||
self.node = node # pillarsdk.Node, contains 'node_type' key to indicate type
|
||||
self.file_desc = file_desc # pillarsdk.File object, or None if a 'folder' node.
|
||||
self.label_text = label_text
|
||||
self.small_text = self._small_text_from_node()
|
||||
self._thumb_path = ''
|
||||
self.icon = None
|
||||
self._is_folder = node['node_type'] in self.FOLDER_NODE_TYPES
|
||||
@ -118,6 +120,26 @@ class MenuItem:
|
||||
self.width = 0
|
||||
self.height = 0
|
||||
|
||||
def _small_text_from_node(self) -> str:
|
||||
"""Return the components of the texture (i.e. which map types are available)."""
|
||||
|
||||
if not self.node:
|
||||
return ''
|
||||
|
||||
try:
|
||||
node_files = self.node.properties.files
|
||||
except AttributeError:
|
||||
# Happens for nodes that don't have .properties.files.
|
||||
return ''
|
||||
if not node_files:
|
||||
return ''
|
||||
|
||||
map_types = {f.map_type for f in node_files if f.map_type}
|
||||
map_types.discard('color') # all textures have colour
|
||||
if not map_types:
|
||||
return ''
|
||||
return ', '.join(sorted(map_types))
|
||||
|
||||
def sort_key(self):
|
||||
"""Key for sorting lists of MenuItems."""
|
||||
return self._order, self.label_text
|
||||
@ -159,6 +181,11 @@ class MenuItem:
|
||||
if label_text is not None:
|
||||
self.label_text = label_text
|
||||
|
||||
if thumb_path == 'ERROR':
|
||||
self.small_text = 'This open is broken'
|
||||
else:
|
||||
self.small_text = self._small_text_from_node()
|
||||
|
||||
@property
|
||||
def is_folder(self) -> bool:
|
||||
return self._is_folder
|
||||
@ -185,6 +212,7 @@ class MenuItem:
|
||||
bgl.glRectf(self.x, self.y, self.x + self.width, self.y + self.height)
|
||||
|
||||
texture = self.icon
|
||||
if texture:
|
||||
err = texture.gl_load(filter=bgl.GL_NEAREST, mag=bgl.GL_NEAREST)
|
||||
assert not err, 'OpenGL error: %i' % err
|
||||
|
||||
@ -192,6 +220,7 @@ class MenuItem:
|
||||
# bgl.glLineWidth(1.5)
|
||||
|
||||
# ------ TEXTURE ---------#
|
||||
if texture:
|
||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture.bindcode[0])
|
||||
bgl.glEnable(bgl.GL_TEXTURE_2D)
|
||||
bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
@ -210,6 +239,7 @@ class MenuItem:
|
||||
bgl.glDisable(bgl.GL_TEXTURE_2D)
|
||||
bgl.glDisable(bgl.GL_BLEND)
|
||||
|
||||
if texture:
|
||||
texture.gl_free()
|
||||
|
||||
# draw some text
|
||||
@ -221,24 +251,11 @@ class MenuItem:
|
||||
blf.size(font_id, self.text_size, text_dpi)
|
||||
blf.draw(font_id, self.label_text)
|
||||
|
||||
# Draw the components of the texture (i.e. which map types are available)
|
||||
try:
|
||||
node_files = self.node.properties.files
|
||||
except AttributeError:
|
||||
# Happens for nodes that don't have .properties.files.
|
||||
node_files = None
|
||||
if not node_files:
|
||||
return
|
||||
|
||||
map_types = {f.map_type for f in node_files if f.map_type}
|
||||
map_types.discard('color') # all textures have colour
|
||||
if not map_types:
|
||||
return
|
||||
|
||||
# draw the small text
|
||||
bgl.glColor4f(1.0, 1.0, 1.0, 0.5)
|
||||
blf.size(font_id, self.text_size_small, text_dpi)
|
||||
blf.position(font_id, text_x, self.y + 0.5 * self.text_size_small, 0)
|
||||
blf.draw(font_id, ', '.join(sorted(map_types)))
|
||||
blf.draw(font_id, self.small_text)
|
||||
|
||||
def hits(self, mouse_x: int, mouse_y: int) -> bool:
|
||||
return self.x < mouse_x < self.x + self.width and self.y < mouse_y < self.y + self.height
|
||||
|
Reference in New Issue
Block a user