Get project name at documentSaved event

Get project name at documentSaved event

PinRudolf
Advocate Advocate
890 Views
4 Replies
Message 1 of 5

Get project name at documentSaved event

PinRudolf
Advocate
Advocate

Hi, 

 

I'm trying to get the name of a project from a document; the only way I can find to do that is through the dataFile of the document. However, when I read the info just after it is saved for the first time (using the documentSaved  event) the dataFile is not yet available.
I feel like there my be a solution, like waiting for the file to be available, but I can't think of way to do something like that.

 

As far as I understand the file is saved locally, then the documentSaved event triggers and then the file is saved to A360 as a dataFile. I tried using a sleep() timer to check if it was available after a while but all it did was delay the creation of the dataFile.

 

Is there anyone who can think of a better solution to this situation? 

 

 

This is what I've got:

import adsk.core, adsk.fusion, traceback

_handlers = []

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        onDocumentSaved = runAfterSave()
        app.documentSaved.add(onDocumentSaved)
        _handlers.append(onDocumentSaved)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))



# Event handler for the documentSaved event.
class runAfterSave(adsk.core.DocumentEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            app = adsk.core.Application.get()
            ui  = app.userInterface
            doc = app.activeDocument


            data  = doc.dataFile            #!
            project = data.parentProject
            ui.messageBox(project.name) 

            
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
0 Likes
891 Views
4 Replies
Replies (4)
Message 2 of 5

PinRudolf
Advocate
Advocate

I 've been trying to use multithreading but so far the new thread simply doesn't run. Is this not possible? Or am I making a mistake in the code:

 

def projName():
    ui.messageBox('multiThread start')
    time.sleep(4)
    data  = doc.dataFile            #!
    project = data.parentProject
    ui.messageBox(project.name) 

x = threading.Thread(target=projName, daemon=True)
x.start()

 

I need to get the datafile to get to the project but also to get a unique id for the documents since the id is not available in the document object.

0 Likes
Message 3 of 5

kandennti
Mentor
Mentor

Hi @PinRudolf .

 

I think that using time.sleep stops the Fusion360 operation.
You can use this to restore the operation to Fusion360.

adsk.doEvents()

 

I thought it could be done simply by this process.

# This is not a very good process!!!
# Event handler for the documentSaved event.
import time
class runAfterSave(adsk.core.DocumentEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        ui = None
        try:
            app = adsk.core.Application.get()
            ui :adsk.core.UserInterface = app.userInterface
            doc = app.activeDocument

            data = adsk.core.Data.cast(None)
            while True:
                try:
                    data = doc.dataFile
                    break
                except:
                    time.sleep(0.01)
                    adsk.doEvents()

            project = data.parentProject
            ui.messageBox(project.name) 

        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 As long as you do not do anything in the GUI until the last dialog appears, it will work correctly.


However, if you do anything (even a spin with the mouse) before the dialog appears, Fusion360 will go into an infinite loop, and there is no way to stop it except to crash Fusion360 from the Task Manager. It is a very unstable process.
(I couldn't figure out how to make Fusion360 ignore the user's operation at the same time as returning the operation to Fusion360.)

 

 

If the user tries to run with an unsaved document, I think the safest thing to do is to prompt the user once to save the document and then abort the process.

0 Likes
Message 4 of 5

PinRudolf
Advocate
Advocate

Ah I see! Thank you Kandennti! I learn a lot from your posts! I'm going to work on this a bit shortly! 

 

Just before I read your post I started off in a different direction and got the project name. It's not the solution i was looking for as I wanted the project ID and dataFile ID as well but it's something at least.

When the fusion file is saved locally it also creates a metadata file with the extension '_xx'. The file is saved as xml data and contains the project name.

 

class runAfterSave(adsk.core.DocumentEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            app = adsk.core.Application.get()
            ui  = app.userInterface

            # Get project id from meta-file
            localFile = app.executeTextCommand("Document.Path").replace('"', '')
            metadataFile = localFile + '._xx'
            tree = ET.parse(metadataFile)
            root = tree.getroot()
            for prN in root.iter('ProjectName'):
                projectName = prN.text
                ui.messageBox(projectName)
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

(I've got the app.executeTextCommand() from one of your posts as well!)

 

The file also contains;

<ProjectId>D2020....</ProjectId> which does not seem to be the same format as the dataProject ID. Looks like it is used for local data such as materials?

<ProjectDmId>a360prod:group:7...</ProjectDmId> No idea what this is for or how to use it.

<ProjectFolderUrn>urn:adsk.wipprod:fs.folder:co.W....</ProjectFolderUrn> This seems to be the urn to de folder! Yay! Unfortunately the data object in the API does not allow a data.findFolderById(urn) though

 

There is some other interesting onformation in there as wel such as the design branch 😛

0 Likes
Message 5 of 5

kandennti
Mentor
Mentor

@PinRudolf .

 

I did find the project name in the "_xx" file.

The metadata file can be opened directly with the TextCommands here.

data.metadata

https://github.com/kantoku-code/Fusion360_Small_Tools_for_Developers/blob/master/TextCommands/TextCo... 

 

I don't know anything about metadata because I haven't looked into it.

 

When I tried this one, I was able to get some kind of metadata of documents in the same folder.

wip.getFolderContents <ProjectFolderUrn>

https://github.com/kantoku-code/Fusion360_Small_Tools_for_Developers/blob/master/TextCommands/TextCo... 

"wip.~" might be of some use.

 

Thank you for providing this information.

 

0 Likes