Skip to content

Instantly share code, notes, and snippets.

@BigRoy
Last active July 23, 2024 19:45
Show Gist options
  • Save BigRoy/c3f21d5a349cafac888e60d5f2777c11 to your computer and use it in GitHub Desktop.
Save BigRoy/c3f21d5a349cafac888e60d5f2777c11 to your computer and use it in GitHub Desktop.
Scriptsmenu automate json creation from a folder with python scripts
import os
import json
from pathlib import Path
def scriptsmenu_from_folder(folder: str) -> list:
menu = []
root_to_submenu = {}
for root, dirs, files in os.walk(folder):
root_path = Path(root)
if root == folder:
parent = menu
else:
parent = root_to_submenu[root_path]["items"]
for subdir in dirs:
subdir_root_path = root_path / subdir
submenu = {
"type": "menu",
"title": subdir,
"items": []
}
parent.append(submenu)
root_to_submenu[subdir_root_path] = submenu
for fname in files:
if not fname.endswith(".py"):
continue
command_path = os.path.join(root, fname)
item = {
"type": "action",
"command": command_path,
"sourcetype": "file",
"title": fname,
# "tags": [],
# "tooltip": ""
}
parent.append(item)
# Remove any entries that ended up being empty menu entries (folders without python scripts)
def clean_empty(_menu):
for i, entry in reversed(list(enumerate(_menu))):
if entry.get("type") != "menu":
continue
if not entry.get("items"):
_menu.pop(i)
clean_empty(entry["items"])
clean_empty(menu)
return menu
folder = r"E:\tmp\menu"
data = scriptsmenu_from_folder(folder)
print(json.dumps(data, indent=4))
@BigRoy
Copy link
Author

BigRoy commented Mar 20, 2024

Got this from Pete Addington - who essentially wrote a similar thing:

from pathlib import Path
import json

class PypeMenuBuilder:
    def __init__(self, root_dir):
        self.root_dir = Path(root_dir)
        self.folder_names = []
        self.file_data = []

    def collect_folders(self):
        for item in self.root_dir.iterdir():
            if item.is_dir():
                self.folder_names.append(item.name)
        # Sort and title case folder names, with folders starting with underscore first
        self.folder_names.sort(key=lambda x: (not x.startswith('_'), x.casefold()))

    def scan_folders(self):
        for folder_name in self.folder_names:
            folder_path = self.root_dir / folder_name
            # Check if the folder name starts with an underscore
            if folder_name.startswith('_'):
                for item in folder_path.iterdir():
                    if item.is_file() and item.suffix in ['.py', '.mel'] and item.name != '__init__.py':
                        script_item = self.create_script_item(folder_name, item)
                        self.file_data.append(script_item)
                        # self.file_data.append({'separator': True})
            else:
                files = []
                for item in folder_path.iterdir():
                    if item.is_file() and item.suffix in ['.py', '.mel'] and item.name != '__init__.py':
                        script_item = self.create_script_item(folder_name, item)
                        files.append(script_item)
                menu_data = {
                    "type": "menu",
                    "title": folder_name.title(),
                    "items": files
                }
                self.file_data.append(menu_data) 
                self.file_data.append({'separator': True})

    def create_script_item(self, folder_name, file_item):
        file_name = file_item.stem
        # print (f'file_name {file_name}')
        nice_name = self.make_nice_name(file_name)
        return {
            "type": "action",
            "command": f"$PIPELINE\\maya\\core\\{folder_name}\\{file_item.name}",
            "sourcetype": "file",
            "tags": [],
            "title": nice_name,
            "tooltip": ""
        }

    def make_nice_name(self,name):
        nice_name = ''
        for i, char in enumerate(name):
            if char.isupper() and i > 0:
                if i < len(name) - 1 and name[i + 1].islower():
                    nice_name += ' ' + char
                else:
                    nice_name += char
            elif char == '_':
                nice_name += ' '
            else:
                nice_name += char
        print (f'PRE TO TITLE {nice_name}')
        return nice_name.title()

    def save_to_json(self, file_path):
        with open(file_path, 'w') as json_file:
            json.dump(self.file_data, json_file, indent=4)

# Example usage:
root_directory = r'Y:\PIPELINE\config\maya\core'
builder = PypeMenuBuilder(root_directory)
builder.collect_folders()
builder.scan_folders()
# builder.add_separator_after_menus()
builder.save_to_json('folder_structure.json')

Discord source (in PM)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment