Link Published File to a Version

Hi all!

I’m a bit struggling trying to get how can I link a specific “Version” to a “Published File” entry.

As version I have a playblast, and as Publish I have a Maya .ma file. To publish I’m using the tk-multy-publish2.

Could anyone illuminate me?

Thank you in advance!

Here I just created a “version” field in the PublishedFile entity, of the type entity->version. But on your script you must update that field after creating the version entity.

Hi @guilhermecasagrandi , thank you for your answer!

So the default Version field that is present in every Published File entry is not programmatically writable?

I don’t remember exactly when it’s automatic (maybe when manually uploading a file using the browser or when you actualy upload a video file?), but at least in my studio, we don’t upload the original videos to SG, we create a PublishedFile entity with a local file path. To create the version, we create a lightweight mp4 version of the same video and use the create version hook to upload it to SG and create the version. Since we are running the hooks in sequence, after the version is created, we update the PublishedFile entity with the version link.
BTW, we only use Houdini here.

Hi @aaaa !

The publisher can achieve what you want, but you need to hijack its logic a bit. In the default implementation the publisher will link publish and version to each other only if they are representing the same item (so in your case the published playblast movie and the SG version created for it will be linked).
There are several ways to go about this. One could be that you search for the right Maya publish when trying create a Version for a playblast and link them together.
That would be somewhere around here

. Sorry for being somewhat general here. Your issue is not super trivially solved and touches on a lot of areas. Hope this helps a little!

Hi @guilhermecasagrandi and @Fabian many thanks to you both for your advice.

I have not solved my problem yet, but maybe I’m closer to a solution thanks to your help.

Looking into the file embedded by Fabian: tk-multi-publish2/upload_version.py at master · shotgunsoftware/tk-multi-publish2 · GitHub I have seen that maybe I can set the item.properties["sg_publish_data"] property inside the collect_playblasts function (inside collector.py), so this payload could be available to the upload_version.py.

This is what I’m trying to do (look at the end this piece of code):

# Taking over the "collector.py" hook from "tk-multi-publish2"

    def collect_playblasts(self, parent_item, project_root):
        """
        Creates items for quicktime playblasts.

        Looks for a 'project_root' property on the parent item, and if such
        exists, look for movie files in a 'movies' subfolder.

        :param parent_item: Parent Item instance
        :param str project_root: The maya project root to search for playblasts
        """

        movie_dir_name = None

        # try to query the file rule folder name for movies. This will give
        # us the directory name set for the project where movies will be
        # written
        if "movie" in cmds.workspace(fileRuleList=True):
            # this could return an empty string
            movie_dir_name = cmds.workspace(fileRuleEntry="movie")

        if not movie_dir_name:
            # fall back to the default
            movie_dir_name = "movies"

        # ensure the movies dir exists
        movies_dir = os.path.join(project_root, movie_dir_name)
        if not os.path.exists(movies_dir):
            return

        self.logger.info(
            "Processing movies folder: %s" % (movies_dir,),
            extra={"action_show_folder": {"path": movies_dir}},
        )

        # look for movie files in the movies folder
        for filename in os.listdir(movies_dir):

            # do some early pre-processing to ensure the file is of the right
            # type. use the base class item info method to see what the item
            # type would be.
            item_info = self._get_item_info(filename)
            if item_info["item_type"] != "file.video":
                continue

            movie_path = os.path.join(movies_dir, filename)

            # allow the base class to collect and create the item. it knows how
            # to handle movie files
            item = super(MayaSessionCollector, self)._collect_file(
                parent_item, movie_path
            )

            #### BELOW THIS LINE THERE IS MY CHANGE!
            #### I'm assigning the .ma file's name hard-coded, just for debug purpose.
            item.properties["sg_publish_data"] = 'ch_dog_mdl_v0061.ma'

Doing this, and debugging from the Publisher I can see the published_files value in the Version Data log:

{'code': 'ch_dog_mdl_v0061.mov',
 'description': None,
 'entity': {'id': 1976, 'name': 'ch_dog', 'type': 'Asset'},
 'project': {'id': 223, 'name': 'tk_anlm', 'type': 'Project'},
 'published_files': ['ch_dog_mdl_v0061.ma'],
 'sg_path_to_movie': 'C:\\ANML\\work\\ch\\dog\\mdl\\movies\\ch_dog_mdl_v0061.mov',
 'sg_task': {'id': 7090, 'name': 'Modeling', 'type': 'Task'}}

The problem now is that I also get an error that block the publishing process:

tank_vendor.shotgun_api3.shotgun.Fault:

API create() invalid/missing entity hash: "ch_dog_mdl_v0061.ma"

I’m not sure that if I solve this issue I’ll get what I want, but seems like that, if the value assigned to the Version’s published_files field is the .ma filename, this will automatically link the Published File’s version field to the playblast of the Version: ch_dog_mdl_v0061.mov in my example,

Am I being clear? Does all this makes any sense? :face_with_peeking_eye:

Thanks!!

Yes, you are almost there. What you need to assign to item.properties["sg_publish_data"] is a dictionary that describes the PublishedFile of the Maya file. So something like {'type': 'PublishedFile', 'id': 1111} as an example. Problem is that you need to create the published file first which likely did not happen in the collect phase where you currently try to make this happen. You should do that in the publish function. You can search for the PublishedFile there like:

maya_publish = self.shotgun.find_one('PubilshedFile', 
                                     [['name', 'is', 'some_name'],  # please adjust the filters to something meaningful, I am just doing this out of the top of my head.
                                      ['project', 'is', self.parent.context.project]])
if maya_publish is not None:
    item.properties["sg_publish_data"] = maya_publish

Hope that helps :slight_smile:

1 Like

Thank you very very much @Fabian ! I’m gonna go in the direction you said. I’ll report here the results :slight_smile:

1 Like