Create Project Folder Structure on Disk

Hey everyone!

Currently, project folders are created on the drive automatically after interacting with AYON, for example, logging into programs. We use a lot of different software in our studio’s pipeline, including AI, so we need to have the full project structure on the drive for convenient use right away. Is there a way to immediately publish the folder structure created through the browser in the editor?

We have this PR that fulfills your request.
Also, let me quote @BigRoy’s comment that explains the reason it’s not merged yet.

Yes, last I heard this is still a valid request but we did not 
want it inside the launcher, but instead wanted it to become a 
web action - so this was left here dangling.

I’m going to update your post name. because Publish Folder Structure can mean Create project hierarchy on AYON Server.

That’s exactly what I needed, thank you so much! Just to confirm, I understand correctly: I need to unpack the zip archive of ayon-core addon, modify the files, upload the updated addon zip archive to the server, and then the PR should work? I’m currently at the stage of uploading the addon to the server, and I’m getting the following error:

Could you please help me understand what I’m doing wrong?

The .zip is not directly the source code folder, but a “build package” of the source code.

You should be able to python create_package.py in the root of the repo, to generate an actual addon .zip package.

Also see:

1 Like

Thank you so much! I was able to install the PR, but unfortunately, it only creates the structure predefined in the core addon :cry:. It would be awesome if it could create the structure created in the Projects editor as well.

Thanks - this has come up before but may be non-trivial due to the folders the asset structure being defined based on the “template” structure in your project, which can be completely arbitrary.

  • Customizable anatomy: like adding {app} or {user}.

You could e.g. change it around to be the project root with directly the application name below, and then the full asset hierarchy, etc. However, when “creating the folder structure” we wouldn’t actually know for which applications you’d like to trigger that. ALL of them?
Similarly, what if you had user in there too. E.g. {root[work]}/{project[name]}/{user}/{app}/{folder[name]}/{task[name]}. What would you expect it to create, fo which users and for which applications?

  • Plus you may have multi-root projects.

An idea that came up before was to then create folder structure up to the first folder that has the {app} token so the ‘static’ parts of the folder structure are created instead. So basically format it up to the first folder that had a missing key.

Here’s how that could work:

import os
import re

import ayon_api
from ayon_core.pipeline import Anatomy
from ayon_core.pipeline.template_data import get_template_data
from ayon_core.pipeline.workfile import get_workfile_template_key
from ayon_core.settings import get_project_settings
from ayon_core.lib import get_ayon_username

project_name: str = "ayontest"  # <--- this project name would need to be set

# Get project data
anatomy = Anatomy(project_name)
project_settings = get_project_settings(project_name)
username = get_ayon_username()

# Get all project entities
project_entity = ayon_api.get_project(project_name)
folders = list(ayon_api.get_folders(project_name))
folders_by_id = {folder["id"]: folder for folder in folders}
tasks = list(ayon_api.get_tasks(project_name))

# Get all directories to create
paths = set()
for task_entity in tasks:
    folder_entity = folders_by_id[task_entity["folderId"]]
    workdir_data = get_template_data(
        project_entity=project_entity,
        folder_entity=folder_entity,
        task_entity=task_entity,
        settings=project_settings,
        username=username
    )

    workdir_template_key = get_workfile_template_key(
        project_name,
        task_type=task_entity["taskType"],
        host_name="<notset>",
        project_settings=project_settings
    )
    template_obj = anatomy.get_template_item(
        "work", workdir_template_key, "directory"
    )

    # Try and format the directory path with above info
    output = template_obj.format(workdir_data)
    path = str(output)
    path = path.replace("\\", "/")

    # Split up to the first folder that has any of the missing keys
    if output.missing_keys:
        missing_pattern = "|".join("{%s}" % (key,) for key in output.missing_keys)
        # match the pattern surrounded by any character except forward slash
        pattern = f"[^/]*{missing_pattern}[^/]*"  
        path = re.split(pattern, path, maxsplit=1)[0]

    paths.add(path)

# Create all directories
for path in sorted(paths):
    if not os.path.exists(path):
        print(f"Creating directory {path}")
        os.makedirs(path, exist_ok=True)

However, that may still feel a bit unreliable?

Thanks Roy !

But this creates disk folders, for stuff that is not intended to.

There are 2 very different disk trees :

  • The starting folder tree on disk, that is needed to help place stuff that is not handled by Ayon (clients briefs, fonts, sounds, etc…).
    As such we don’t want this structure to be visible in Ayon’s logical tree (in the WebApp’s Editor).
    That’s why the following PR is very good, it takes as input a json description of the folder tree, and creates it on disk : Add simple Create Project Structure launcher action by BigRoy · Pull Request #679 · ynput/ayon-core · GitHub
    I think it’s that PR that deserves to become a WebAction.

  • The Ayon’s logical tree (in the WebApp’s Editor), that only needs to be duplicated on disk when workfiles or products are created (this already works).

I personally fully agree - but it’s exactly what many have been requesting. Including what @leshavkleshah described here:

I personally prefer my folders to not exist on disk - unless there’s been some form of activity. It’s basically “just in time” creation. So again, I agree.