Integrate Thumbnails for use in Loaders.
This thumbnail is different from 'thumbnail' representation which could be uploaded to Ftrack, or used as any other representation in Loaders to pull into a scene.
This one is used only as image describing content of published item and shows up only in Loader or WebUI.
Instance must have 'published_representations' to be able to integrate thumbnail. Possible sources of thumbnail paths: - instance.data["thumbnailPath"] - representation with 'thumbnail' name in 'published_representations' - context.data["thumbnailPath"]
Notes
Issue with 'thumbnail' representation is that we most likely don't want to integrate it as representation. Integrated representation is polluting Loader and database without real usage. That's why they usually have 'delete' tag to skip the integration.
IntegrateThumbnailsAYON
Bases: ContextPlugin
Integrate Thumbnails for use in Loaders.
Source code in client/ayon_core/plugins/publish/integrate_thumbnail.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 | class IntegrateThumbnailsAYON(pyblish.api.ContextPlugin):
"""Integrate Thumbnails for use in Loaders."""
label = "Integrate Thumbnails to AYON"
order = pyblish.api.IntegratorOrder + 0.01
def process(self, context):
# Filter instances which can be used for integration
filtered_instance_items = self._prepare_instances(context)
if not filtered_instance_items:
self.log.debug(
"All instances were filtered. Thumbnail integration skipped."
)
return
project_name = context.data["projectName"]
# Collect version ids from all filtered instance
version_ids = {
instance_items.version_id
for instance_items in filtered_instance_items
}
# Query versions
version_entities = ayon_api.get_versions(
project_name,
version_ids=version_ids,
hero=True,
fields={"id", "version"}
)
# Store version by their id (converted to string)
version_entities_by_id = {
version_entity["id"]: version_entity
for version_entity in version_entities
}
self._integrate_thumbnails(
filtered_instance_items,
version_entities_by_id,
project_name
)
def _prepare_instances(self, context):
context_thumbnail_path = context.data.get("thumbnailPath")
valid_context_thumbnail = bool(
context_thumbnail_path
and os.path.exists(context_thumbnail_path)
)
filtered_instances = []
anatomy = context.data["anatomy"]
for instance in context:
instance_label = self._get_instance_label(instance)
# Skip instances without published representations
# - there is no place where to put the thumbnail
published_repres = instance.data.get("published_representations")
if not published_repres:
self.log.debug((
"There are no published representations"
" on the instance {}."
).format(instance_label))
continue
# Find thumbnail path on instance
thumbnail_path = (
instance.data.get("thumbnailPath")
or self._get_instance_thumbnail_path(
published_repres, anatomy
)
)
if thumbnail_path:
self.log.debug((
"Found thumbnail path for instance \"{}\"."
" Thumbnail path: {}"
).format(instance_label, thumbnail_path))
elif valid_context_thumbnail:
# Use context thumbnail path if is available
thumbnail_path = context_thumbnail_path
self.log.debug((
"Using context thumbnail path for instance \"{}\"."
" Thumbnail path: {}"
).format(instance_label, thumbnail_path))
# Skip instance if thumbnail path is not available for it
if not thumbnail_path:
self.log.debug((
"Skipping thumbnail integration for instance \"{}\"."
" Instance and context"
" thumbnail paths are not available."
).format(instance_label))
continue
version_id = str(self._get_version_id(published_repres))
filtered_instances.append(
InstanceFilterResult(instance, thumbnail_path, version_id)
)
return filtered_instances
def _get_version_id(self, published_representations):
for repre_info in published_representations.values():
return repre_info["representation"]["versionId"]
def _get_instance_thumbnail_path(
self, published_representations, anatomy
):
thumb_repre_entity = None
for repre_info in published_representations.values():
repre_entity = repre_info["representation"]
if "thumbnail" in repre_entity["name"].lower():
thumb_repre_entity = repre_entity
break
if thumb_repre_entity is None:
self.log.debug(
"There is no representation with name \"thumbnail\""
)
return None
path = thumb_repre_entity["attrib"]["path"]
filled_path = anatomy.fill_root(path)
if not os.path.exists(filled_path):
self.log.warning(
"Thumbnail file cannot be found. Path: {}".format(filled_path)
)
return None
return os.path.normpath(filled_path)
def _integrate_thumbnails(
self,
filtered_instance_items,
version_entities_by_id,
project_name
):
# Make sure each entity id has defined only one thumbnail id
thumbnail_info_by_entity_id = {}
for instance_item in filtered_instance_items:
instance, thumbnail_path, version_id = instance_item
instance_label = self._get_instance_label(instance)
version_entity = version_entities_by_id.get(version_id)
if not version_entity:
self.log.warning((
"Version entity for instance \"{}\" was not found."
).format(instance_label))
continue
thumbnail_id = ayon_api.create_thumbnail(
project_name, thumbnail_path
)
# Set thumbnail id for version
thumbnail_info_by_entity_id[version_id] = {
"thumbnail_id": thumbnail_id,
"entity_type": "version",
}
version_name = version_entity["version"]
if version_name < 0:
version_name = "Hero"
self.log.debug("Setting thumbnail for version \"{}\" <{}>".format(
version_name, version_id
))
folder_id = instance.data["folderEntity"]["id"]
folder_path = instance.data["folderPath"]
thumbnail_info_by_entity_id[folder_id] = {
"thumbnail_id": thumbnail_id,
"entity_type": "folder",
}
self.log.debug("Setting thumbnail for folder \"{}\" <{}>".format(
folder_path, version_id
))
op_session = OperationsSession()
for entity_id, thumbnail_info in thumbnail_info_by_entity_id.items():
thumbnail_id = thumbnail_info["thumbnail_id"]
op_session.update_entity(
project_name,
thumbnail_info["entity_type"],
entity_id,
{"thumbnailId": thumbnail_id}
)
op_session.commit()
def _get_instance_label(self, instance):
return (
instance.data.get("label")
or instance.data.get("name")
or "N/A"
)
|