Update .ghuser Programmatically

I have a bunch of UserObjects.

Would like to apply a new naming format, for example, “Geometry_Sort” to “G_Sort” among other updates (new icons, new date format, authors, etc).

I couldn’t simply read a .ghuser as JSON and figure out where the metadata is stored. How can I group update the UserObjects programmatically, either from within the GH environment or from a text editor with Python.

Appreciate any tips.

Hi @xy236 ,

Hopefully someone will chime in with more gh dev experience but user objects, components, clusters all have properties associated with them that can be read and modifed via scripting in Python or C#.

So you could, I believe, have a script that gets all user objects in a certain tab in your gh document/toolbar, and then modify certain attributes about them such as their name/nickname and so on.

https://mcneel.github.io/grasshopper-api-docs/api/grasshopper/html/Properties_T_Grasshopper_Kernel_GH_UserObject.htm

Hope this at least gets you started!

Thanks Michael for the quick reply. I’ll start digging into it.

1 Like

I’ve managed to programmatically update the metadata of the clusters connected to my python module, as well as deleting their corresponding .ghuser from the UserObjects folder by matching the cluster name with the file name.

Now, however, I just can’t figure out how to save the new clusters as .ghuser to the folder. I know that this can be done manually by click on “File - Create User Object”, but obviously I am looking for a programmatic solution.

This is my latest attempt. It would print ('UserObject saved successfully to:', 'C:\\Users\\<username>\\AppData\\Roaming\\Grasshopper\\UserObjects\\some cluster.ghuser') but obviously it doesn’t save anything.

Very new to this. Appreciate all leads.

import os
import Grasshopper as gh
import System
from System import Guid

def UO_create(CLM, icon=None):
 """
    Creates a Grasshopper User Object from cluster metadata.

    Args:
        cluster_metadata (dict): Metadata of the cluster.
        icon (object, optional): Icon associated with the User Object. Defaults to None.

    Returns:
        Grasshopper.Kernel.GH_UserObject: The created User Object.
    """
    # Create an instance of GH_UserObject
    user_object = gh.Kernel.GH_UserObject()
    
    # Set the properties
    user_object.BaseGuid = CLM['InstanceGuid']
    user_object.Data = None
    user_object.Description = gh.Kernel.GH_InstanceDescription(CLM['Description'], CLM['NickName'], CLM['SubCategory'], CLM['Category'])
    user_object.Exposure = gh.Kernel.GH_Exposure.tertiary  
    user_object.Icon = icon
    
    # Set the file path
    UO_file_name = CLM['Name'] + '.ghuser'
    UO_fPath = os.path.join(r'C:\Users\<username>\AppData\Roaming\Grasshopper\UserObjects', UO_file_name)
    user_object.Path = UO_fPath
    
    # Save the UserObject to file
    try:
        user_object.SaveToFile()
        print("UserObject saved successfully to:", UO_fPath)
    except Exception as e:
        print("Error saving UserObject:", str(e))
        return None  # Return None to indicate failure
    
    # Verify if the file exists after saving
    if os.path.isfile(UO_fPath):
        print("File exists at the specified path.")
    else:
        print("File does not exist at the specified path.")
    
    return user_object

# Call the UO_create function
x = UO_create(CLM_current[0])

# Print the properties to verify
print("BaseGuid:", x.BaseGuid)
print("Description:", x.Description.Name)
print("Exposure:", x.Exposure)
print("Guid:", x.Guid)
print("Icon:", x.Icon)
print("Path:", x.Path)