Skip to content

Commit 3d1b340

Browse files
committed
Revised publish movie template logic to better match Shotgun tk-config-default2
1 parent 54eeb59 commit 3d1b340

File tree

2 files changed

+78
-71
lines changed

2 files changed

+78
-71
lines changed

hooks/tk-multi-publish2/basic/publish_movie.py

Lines changed: 78 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import pprint
99
import subprocess
1010
import sys
11+
import datetime
1112

1213
HookBaseClass = sgtk.get_hook_baseclass()
1314

@@ -35,11 +36,12 @@ def description(self):
3536
contain simple html for formatting.
3637
"""
3738

38-
return """Publishes the sequence as a rendered movie to Shotgun. A <b>Publish</b> entry will be
39-
created in Shotgun which will include a reference to the movie's current
40-
path on disk. A <b>Version</b> entry will also be created in Shotgun
41-
with the movie file being uploaded there. Other users will be able to
42-
review the movie in the browser or in RV."""
39+
return """Publishes the sequence as a rendered movie to Shotgun. A
40+
<b>Publish</b> entry will be created in Shotgun which will include a
41+
reference to the movie's current path on disk. A <b>Version</b> entry
42+
will also be created in Shotgun with the movie file being uploaded
43+
there. Other users will be able to review the movie in the browser or
44+
in RV."""
4345

4446
@property
4547
def settings(self):
@@ -75,19 +77,8 @@ def settings(self):
7577
}
7678
}
7779

78-
work_template_setting = {
79-
"Work Template": {
80-
"type": "template",
81-
"default": None,
82-
"description": "Template path for rendered movie files. Should"
83-
"correspond to a template defined in "
84-
"templates.yml.",
85-
}
86-
}
87-
8880
# update the base settings
8981
base_settings.update(publish_template_setting)
90-
base_settings.update(work_template_setting)
9182

9283
return base_settings
9384

@@ -130,16 +121,6 @@ def accept(self, settings, item):
130121

131122
accepted = True
132123
publisher = self.parent
133-
134-
# ensure a work file template is available in the settings
135-
work_template_setting = settings.get("Work Template")
136-
work_template = publisher.get_template_by_name(work_template_setting.value)
137-
if not work_template:
138-
self.logger.debug(
139-
"A work template is required for the sequence item in order to "
140-
"publish it. Not accepting the item."
141-
)
142-
accepted = False
143124

144125
# ensure the publish template is defined
145126
publish_template_setting = settings.get("Publish Template")
@@ -154,7 +135,6 @@ def accept(self, settings, item):
154135
# we've validated the work and publish templates. add them to the item properties
155136
# for use in subsequent methods
156137
item.properties["publish_template"] = publish_template
157-
item.properties["work_template"] = work_template
158138

159139
return {
160140
"accepted": accepted,
@@ -196,27 +176,27 @@ def validate(self, settings, item):
196176
self.logger.debug("Sequence path or name not configured.")
197177
return False
198178

179+
# Get the configured publish template
199180
publish_template = item.properties.get("publish_template")
200-
if not publish_template:
201-
self.logger.debug("No publish template configured.")
202-
return False
203-
204-
# Get the work template which should have been retrieved from the settings and set on the item
205-
work_template = item.properties.get("work_template")
206-
if not work_template:
207-
self.logger.debug("No work template configured.")
208-
return False
209-
210-
# Get destination path for rendered movie
211-
work_path_fields = {"name" : asset_name}
212-
work_path = work_template.apply_fields(work_path_fields)
213-
work_path = os.path.normpath(work_path)
214-
215-
# Remove the filename from the work path
216-
destination_path = os.path.split(work_path)[0]
181+
182+
# Get the context from the Publisher UI
183+
context = item.context
184+
unreal.log("context: {}".format(context))
217185

218-
# Ensure that the destination path exists before rendering the sequence
219-
self.parent.ensure_folder_exists(destination_path)
186+
# Query the fields needed for the publish template from the context
187+
try:
188+
fields = context.as_template_fields(publish_template)
189+
except Exception:
190+
# We likely failed because of folder creation, trigger that
191+
self.parent.sgtk.create_filesystem_structure(
192+
context.entity["type"],
193+
context.entity["id"],
194+
self.parent.engine,
195+
)
196+
# In theory, this should now work because we've created folders and
197+
# updated the path cache
198+
fields = item.context.as_template_fields(publish_template)
199+
unreal.log("context fields: {}".format(fields))
220200

221201
# Ensure that the current map is saved on disk
222202
unreal_map = unreal.EditorLevelLibrary.get_editor_world()
@@ -227,24 +207,37 @@ def validate(self, settings, item):
227207
self.logger.debug("Current map must be saved first.")
228208
return False
229209

230-
# Try to render the sequence
210+
# Add the map name and level sequence to fields
231211
world_name = unreal_map.get_name()
212+
fields["world"] = world_name
213+
fields["level_sequence"] = asset_name
214+
215+
# Stash the level sequence and map paths in properties for the render
216+
item.properties["unreal_asset_path"] = asset_path
217+
item.properties["unreal_map_path"] = unreal_map_path
232218

233-
# Add a version number to the name, incremented from the current asset version
219+
# Add a version number to the fields, incremented from the current asset version
234220
version_number = self._unreal_asset_get_version(asset_path)
235221
version_number = version_number + 1
236-
237-
# Name must match the work/publish templates
238-
movie_name = "{}-{}.v{:03d}".format(world_name, asset_name, version_number)
239-
succeeded, output_filepath = self._unreal_render_sequence_to_movie(destination_path, unreal_map_path, asset_path, movie_name)
222+
fields["version"] = version_number
223+
224+
# Add today's date to the fields
225+
date = datetime.date.today()
226+
fields["YYYY"] = date.year
227+
fields["MM"] = date.month
228+
fields["DD"] = date.day
229+
230+
# ensure the fields work for the publish template
231+
missing_keys = publish_template.missing_keys(fields)
232+
if missing_keys:
233+
error_msg = "Missing keys required for the publish template " \
234+
"%s" % (missing_keys)
235+
self.logger.error(error_msg)
236+
raise Exception(error_msg)
240237

241-
if not succeeded:
242-
return False
243-
244-
self._unreal_asset_set_version(asset_path, version_number)
245-
246-
item.properties["path"] = output_filepath.replace("/", "\\")
247-
item.properties["publish_name"] = movie_name
238+
item.properties["path"] = publish_template.apply_fields(fields)
239+
item.properties["publish_path"] = item.properties["path"]
240+
# item.properties["publish_name"] = movie_name
248241
item.properties["version_number"] = version_number
249242

250243
return True
@@ -267,9 +260,28 @@ def publish(self, settings, item):
267260
# are appropriate for current os, no double separators, etc.
268261

269262
# let the base class register the publish
270-
# the publish_file will copy the file from the work path to the publish path
271-
# if the item is provided with the worK_template and publish_template properties
272263

264+
publish_path = item.properties.get("path")
265+
publish_path = os.path.normpath(publish_path)
266+
267+
# Split the destination path into folder and filename
268+
destination_folder = os.path.split(publish_path)[0]
269+
movie_name = os.path.split(publish_path)[1]
270+
movie_name = os.path.splitext(movie_name)[0]
271+
272+
# Ensure that the destination path exists before rendering the sequence
273+
self.parent.ensure_folder_exists(destination_folder)
274+
275+
# Get the level sequence and map paths again
276+
unreal_asset_path = item.properties["unreal_asset_path"]
277+
unreal_map_path = item.properties["unreal_map_path"]
278+
unreal.log("movie name: {}".format(movie_name))
279+
# Render the movie
280+
self._unreal_render_sequence_to_movie(destination_folder, unreal_map_path, unreal_asset_path, movie_name)
281+
282+
# Increment the version number
283+
self._unreal_asset_set_version(unreal_asset_path, item.properties["version_number"])
284+
273285
# Publish the movie file to Shotgun
274286
super(UnrealMoviePublishPlugin, self).publish(settings, item)
275287

@@ -280,9 +292,10 @@ def publish(self, settings, item):
280292
self.logger.info("Creating Version...")
281293
version_data = {
282294
"project": item.context.project,
283-
"code": publish_name,
295+
"code": movie_name,
284296
"description": item.description,
285297
"entity": self._get_version_entity(item),
298+
"sg_path_to_movie": publish_path,
286299
"sg_task": item.context.task
287300
}
288301

@@ -314,7 +327,8 @@ def publish(self, settings, item):
314327

315328
# On windows, ensure the path is utf-8 encoded to avoid issues with
316329
# the shotgun api
317-
upload_path = item.properties.get("path")
330+
upload_path = item.properties.get("publish_path")
331+
unreal.log("upload_path: {}".format(upload_path))
318332
if sys.platform.startswith("win"):
319333
upload_path = upload_path.decode("utf-8")
320334

@@ -341,14 +355,7 @@ def finalize(self, settings, item):
341355
# do the base class finalization
342356
super(UnrealMoviePublishPlugin, self).finalize(settings, item)
343357

344-
# Delete the rendered movie from the work folder
345-
file_to_delete = item.properties.get("path")
346-
347-
if file_to_delete:
348-
try:
349-
os.remove(file_to_delete)
350-
except OSError, e:
351-
pass
358+
pass
352359

353360
def _get_version_entity(self, item):
354361
"""
12.8 KB
Loading

0 commit comments

Comments
 (0)