No internet connection
  1. Home
  2. How to

Directing to custom directory in import window.

By Mike Wax @mikewax
    2021-01-26 00:27:37.176Z

    How would i navigate to a specific folder in the Open dialogue box in Pro Tools.

    I am setting up a custom import script (video and AAF), but I don't store those files in the session folder. This is my typical folder structure:

    AAF - /Volumes/ScorpDrive/[CLIENT_NAME]/Audio/AAF/
    VIDEO - /Volumes/ScorpDrive/[CLIENT_NAME]/Audio/Video_REF/

    When i bring up my import dialogue, I'd like it to automatically route to those folders. I have a prompt to ask for the client name.
    I'm pretty sure I'm doing a lot of things wrong here, so any help is appreciated.

    I was able to find other scripts about automating this, but none of them worked for what i was trying to do (again, I'm probably doing something wrong.).

    Thank you!!

    sf.ui.proTools.appActivate();
    
    const clientName = prompt("Please enter the Client Name.\n\n *NOTE* - All spaces will be replacced with _.");
    const replaceSpaces = clientName.replace(' ', '_');
    
    // IMPORT VIDEO
    sf.ui.proTools.menuClick({
        menuPath: ["File", "Import", "Video..."],
    });
    
    // Wait for window to open
    var importWin = sf.ui.proTools.windows.whoseTitle.is('Open').first;
    
    sf.file.directoryGetDirectories({
        path: "/Volumes/ScorpDrive/" + replaceSpaces + "/Audio/Video_REF/"
    });
    
    // Click Open
    importWin.buttons.whoseTitle.is('Open').first.elementClick();
    
    // Wait for import window to close
    importWin.elementWaitFor({ 
        waitForNoElement: true 
    });
    
    
    // IMPORT SESSION DATA
    sf.ui.proTools.menuClick({
        menuPath: ["File", "Import", "Session Data..."],
    });
    
    // Wait for window to open
    var importWin = sf.ui.proTools.windows.whoseTitle.is('Open').first;
    
    sf.file.directoryGetDirectories({
        path: "/Volumes/ScorpDrive/" + replaceSpaces + "/Audio/AAF/"
    });
    
    // Click Open
    importWin.buttons.whoseTitle.is('Open').first.elementClick();
    
    // Wait for import window to close
    importWin.elementWaitFor({ 
        waitForNoElement: true 
    });
    
    • 14 replies

    There are 14 replies. Estimated reading time: 15 minutes

    1. Use the navigateToInDialog function from here:

      1. You can also see it in action in the post linked just above the one I linked to:

        1. Mike Wax @mikewax
            2021-01-26 05:46:28.634Z

            Thank you so much for the reference! I had no idea about the "Go to" screen. That is super useful!

            So I'm trying to make some modifications, and trying to pull up a list of folders on my external hard drive. This will complete the file path by allowing me to select which client folder I'm working in.

            So I am trying to gather all the folders and put them in a popupSearch, but I am getting an error saying something about being denied? I checked the permissions on the hard drive and there is read & write access.

            Here is the updated code (only the last function i changed):

            function main() {
               var getClientFolder = sf.file.directoryGetEntries({
                   path: "/Volumes/ScorpDrive/",
                   isRecursive: true,
                   includeDirectories: false,
               });
            
               var clientFolder = sf.interaction.popupSearch({
                   title: "Select Client Folder",
                   items: getClientFolder
               });
            
               //Import session
               importSession(clientFolder + "/Audio/AAF/");
            
               //Wait for Import Session Data
               var importSessionWin = sf.ui.proTools.windows.whoseTitle.is('Import Session Data').first.elementWaitFor().element;
            }
            
            main();
            

            And here is the error I receive:

            As always, thank you for the help!

            1. Hi Mike,

              This is a SoundFlow bug, you could say. It enumerates through all files, in this case even system files like the .DocumentRevisions-V100 which macOS denies access to. SoundFlow should be able to ignore that error and move on, but apparently it doesn't.

              Can I get you to log this as a bug report?
              Please click here to send us the information we need

              The workaround is to add a searchpattern to directoryGetEntries, or to search something that isn't a volume root, so that SF (the user) will have access to all special folders and files within the folder you're searching.

              1. Unfortunately, as far as I remember, the bug is in an underlying component SoundFlow uses, which means it's not necessarily up to us to fix it. Instead, we'll need to upgrade the component version to fix the bug, which may be a large project. That's why I listed some workarounds, because while it feels like a simple bug, due to the component dependencies in SF, this may take some time to fix (hence also why it's good to have it logged in our bug system).

                1. Mike Wax @mikewax
                    2021-01-26 17:58:10.023Z

                    See, that's what I've been saying the whole time...LOL. I appreciate the information!

                    Bug report has been submitted!

                    I am looking into the workaround using searchPattern. How would I use this to obtain folders? Seems like it would only work for file types (.mp4, .mp3, .wav).

                    Also, what's the difference between using directoryGetEntries and directoryGetDirectories?
                    Thank you!

                    1. Yes, using a search pattern would generally only work for file types (or for directories with extensions, which is more rare).

                      directoryGetEntries is the raw, underlying function that can obtain entries (directories or files) whereas directoryGetDirectories only gets directories.

                      1. Mike Wax @mikewax
                          2021-01-26 21:52:56.868Z

                          Got it.

                          So is it safe to say that if I'm looking to pull a list of folders, I should use directoryGetDirectories? Or is there an alternative work around for being able to a list of folders to select?

                          Thank you!

                          1. That's right.

                            With regards to the issue, if you need to be able to list folders at the root level of a drive, for now, you'll need to use something else to get that list.

                            For example:

                            
                            function getDirectories(path) {
                                return sf.system.exec({
                                    commandLine: `find "${path}" -maxdepth 1 -type d | tr '\n' '|'`
                                }).result.split('|').filter(s => s !== "");
                            }
                            
                            log(getDirectories('/Volumes/ScorpDrive'));
                            
                            1. Mike Wax @mikewax
                                2021-01-26 22:45:51.162Z

                                I seem to be having troubles getting that code to work in what I already have (my apologies, I'm not super JavaScript savvy).

                                I am getting an error in my code and not completely sure what I'm doing wrong.
                                Here's the entire code:

                                function navigateToInDialog(win, path) {
                                    //Open the Go to... sheet
                                    sf.keyboard.type({ 
                                        text: '/' 
                                    });
                                
                                    //Wait for the sheet to appear
                                    var sheet = win.sheets.first.elementWaitFor({ timeout: 500 }, 'Could not find "Go to" sheet in the Save/Open dialog').element;
                                
                                    //Set the value of the combo box
                                    sheet.comboBoxes.first.value.value = path;
                                
                                    //Press OK
                                    sheet.buttons.whoseTitle.is('Go').first.elementClick({}, 'Could not click "Go"');
                                
                                    //Wait for sheet to close
                                    win.sheets.first.elementWaitFor({ waitForNoElement: true, timeout: 500 }, '"Go to" sheet didn\'t close in time');
                                }
                                
                                function importSession(sessionPath) {
                                    // Open up Import Session Data
                                    sf.ui.proTools.menuClick({ 
                                        menuPath: ['File', 'Import', 'Session Data...']
                                    });
                                
                                    // Wait for window to open
                                    var importWin = sf.ui.proTools.windows.whoseTitle.is('Open').first;
                                
                                    // Navigate to folder
                                    navigateToInDialog(importWin, sessionPath);
                                
                                    // Click Open
                                    importWin.buttons.whoseTitle.is('Open').first.elementClick();
                                
                                    // Wait for import window to close
                                    importWin.elementWaitFor({ 
                                        waitForNoElement: true,
                                        timeout: -1
                                    });
                                }
                                
                                function getDirectories(path) {
                                    return sf.system.exec({
                                        commandLine: `find "${path}" -maxdepth 1 -type d | tr '\n' '|'`
                                    }).result.split('|').filter(s => s !== "");
                                
                                    var clientFolder = sf.interaction.popupSearch({
                                        title: "Select Client Folder",
                                        items: path
                                    });
                                
                                    //Import session
                                    importSession(clientFolder + "/Audio/AAF/");
                                
                                    //Wait for Import Session Data
                                    var importSessionWin = sf.ui.proTools.windows.whoseTitle.is('Import Session Data').first.elementWaitFor().element;
                                }
                                
                                getDirectories('/Volumes/ScorpDrive');
                                
                                1. Hi Mike,

                                  Please specify the error you're getting, otherwise it's very hard to help :)

                                  1. Ah, ok.

                                    Sorry, it was obvious when looking at the code.

                                    Something like this should be closer:

                                    
                                    function getDirectories(path) {
                                        return sf.system.exec({
                                            commandLine: `find "${path}" -maxdepth 1 -type d | tr '\n' '|'`
                                        }).result.split('|').filter(s => s !== "");
                                    }
                                    
                                    function main() {
                                        var clientFolders = getDirectories('/Volumes/ScorpDrive');
                                    
                                        var clientFolder = sf.interaction.popupSearch({
                                            title: "Select Client Folder",
                                            items: clientFolders.map(p => ({ name: p, path: p, })),
                                        }).selectedItem.path;
                                    
                                        //Import session
                                        importSession(clientFolder + "/Audio/AAF/");
                                    
                                        //Wait for Import Session Data
                                        var importSessionWin = sf.ui.proTools.windows.whoseTitle.is('Import Session Data').first.elementWaitFor().element;
                                    }
                                    
                                    main();
                                    
                                    
                                    1. Mike Wax @mikewax
                                        2021-01-27 23:29:54.102Z2021-01-27 23:46:51.235Z

                                        Ah, I tried setting it to a variable before but didn't add the popupSearch to a variable.

                                        So out of the box, it gives me an error:

                                        TypeError: Cannot read property 'path' of undefined (File TEST 01 line 58)
                                        

                                        So after playing with that, i removed .path from .selectedItem and it worked!

                                        The last issue I'm not having is it doesn't seem to be focusing on the Import Video window, so the Go To combo box cannot be initiated.

                                        Is there any way to ensure the import window is focused? For now, i just used the work around of clicking the mouse on it.
                                        Thank you!

                                        Here's the code in its entirety if you need it:

                                        function navigateToInDialog(win, path) {
                                            sf.mouse.click({
                                                position: {"x":1000, "y":600},
                                            });
                                        
                                            //Open the Go to... sheet
                                            sf.keyboard.type({ 
                                                text: '/' 
                                            });
                                        
                                            //Wait for the sheet to appear
                                            var sheet = win.sheets.first.elementWaitFor({ 
                                                timeout: 500 
                                            }, 'Could not find "Go to" sheet in the Save/Open dialog').element;
                                        
                                            //Set the value of the combo box
                                            sheet.comboBoxes.first.value.value = path;
                                        
                                            //Press OK
                                            sheet.buttons.whoseTitle.is('Go').first.elementClick({}, 'Could not click "Go"');
                                        
                                            //Wait for sheet to close
                                            win.sheets.first.elementWaitFor({ 
                                                waitForNoElement: true, 
                                                timeout: 500 
                                            }, '"Go to" sheet didn\'t close in time');
                                        }
                                        
                                        function importSession(sessionPath) {
                                            // Open up Import Session Data
                                            sf.ui.proTools.menuClick({ 
                                                menuPath: ['File', 'Import', 'Session Data...']
                                            });
                                        
                                            // Wait for window to open
                                            var importWin = sf.ui.proTools.windows.whoseTitle.is('Open').first;
                                        
                                            // Navigate to folder
                                            navigateToInDialog(importWin, sessionPath);
                                        
                                            // Click Open
                                            importWin.buttons.whoseTitle.is('Open').first.elementClick();
                                        
                                            // Wait for import window to close
                                            importWin.elementWaitFor({ 
                                                waitForNoElement: true,
                                                timeout: -1
                                            });
                                        }
                                        
                                        function getDirectories(path) {
                                            return sf.system.exec({
                                                commandLine: `find "${path}" -maxdepth 1 -type d | tr '\n' '|'`
                                            }).result.split('|').filter(s => s !== "");
                                        }
                                        
                                        function main() {
                                            var clientFolders = getDirectories('/Volumes/ScorpDrive');
                                        
                                            var clientFolder = sf.interaction.popupSearch({
                                                title: "Select Client Folder",
                                                items: clientFolders.map(p => ({ name: p, path: p, })),
                                            }).item.path;
                                        
                                            //Import session
                                            importSession(clientFolder + "/Audio/AAF/");
                                        
                                            //Wait for Import Session Data
                                            var importSessionWin = sf.ui.proTools.windows.whoseTitle.is('Import Session Data').first.elementWaitFor().element;
                                        }
                                        
                                        main();
                                        
                                        1. Mike Wax @mikewax
                                            2021-01-27 23:38:58.005Z

                                            Correction, i had to change selectedItem.path to item.path.