No internet connection
  1. Home
  2. How to

Copy a pre-existing folder in Finder to the current folder location

By Andrew Sherman @Andrew_Sherman
    2021-02-05 10:51:07.092Z

    Hi Soundflow gurus.

    I'm trying to set up a macro to copy my template folder for new projects to the current location in Finder. Can you point me in the right direction?

    This is what I'm looking for:

    • Active app: Finder
    • Press streamdeck trigger
    • My template folder, at a specific location on my internal hard drive, is copied, including subfolders (keeping directory structure) as well as any files in the folders
    • This is all pasted/copied into my currently selected Finder folder

    The amount of data is relatively small, it's about 2mb total inside the template folder.

    Thanks in advance for any pointers.

    Solved in post #2, click to view
    • 22 replies

    There are 22 replies. Estimated reading time: 14 minutes

    1. Hey Andrew!

      This should do the trick. It'll copy over a file of your choosing to the first folder currently selected in Finder. Just make sure to change the templateFolderPath to the path of your template!

      function copyTemplateToSelectedFolder() {
          // Insert the template folder's path here
          const templateFolderPath = '~/Desktop/Template';
          const templateFolderName = templateFolderPath.split('/').slice(-1)[0];
      
          // Get path of selected directory
          const selectedPath = sf.ui.finder.firstSelectedPath;
      
          // Copy
          sf.file.copy({
              sourcePath: templateFolderPath,
              destinationPath: `${selectedPath}/${templateFolderName}`
          });
      
          log('Template copied!')
      };
      
      copyTemplateToSelectedFolder();
      
      Reply1 LikeSolution
      1. Chris Shaw @Chris_Shaw2021-02-05 18:20:21.525Z2021-02-05 18:44:16.335Z

        To get the path of the Finder folder, click on the folder and while holding down the option key go to the Edit menu. You see "Copy" has changed to "Copy {folder name} as Pathname…". Then paste that into Raphael's script.

        1. AAndrew Sherman @Andrew_Sherman
            2021-02-05 18:43:21.455Z

            What a great trick

            1. Chris Shaw @Chris_Shaw2021-02-05 18:46:41.124Z2021-02-05 19:04:43.762Z

              There are a lot of options in the finder menus when you click, um, option…

          • AAndrew Sherman @Andrew_Sherman
              2021-02-05 18:43:12.047Z

              Fantastic, thank you

              1. AAntonio Esguerra @Antonio_Esguerra
                  2023-11-01 18:19:43.860Z

                  Raphael I'm getting an IOEXception in file.copy on line 10. It states the file doesn't exist... Tried changing the pathname referencing the folder to be copied, not sure whats going on.

                  1. Hey @Antonio_Esguerra, just tested this in Ventura 13.6 and it's still working. Let's review a few things:

                    • You have to change the value of templateFolderPath in Line 3 to the path where your "template" folder is.
                    • You have to have another folder selected in Finder before running this script.
                    • What this script does is take the contents of your "template" folder and copy them inside the currently selected folder.

                    To troubleshoot, I would create a folder on your desktop called "Template", put some random files in there, select a folder somewhere else, and run this script as originally written. It should copy those files over.

                    If none of this helps, we're going to need more info such as the full error and the script as you have it now.

                    1. AAntonio Esguerra @Antonio_Esguerra
                        2023-11-09 15:10:14.382Z

                        Hi Raphael,

                        Thanks for the response man! you are quick. I am getting the error regardless of where I place the folder. I am switching up the path name and everything... Here is a copy of the script as I have it:

                        function copyTemplateToSelectedFolder() {
                            // Insert the template folder's path here
                            const templateFolderPath = '~/Users/werk/Desktop/New Song Folder';
                            const templateFolderName = templateFolderPath.split('/').slice(-1)[0];
                        
                            // Get path of selected directory
                            const selectedPath = sf.ui.finder.firstSelectedPath;
                        
                            // Copy
                            sf.file.copy({
                                sourcePath: templateFolderPath,
                                destinationPath: `${selectedPath}/${templateFolderName}`
                            });
                        
                            log('Template copied!')
                        };
                        
                        copyTemplateToSelectedFolder();
                        

                        The error message reads:

                        09.11.2023 10:09:06.45 [Backend]: Logging error in action (01) FileCopyAction: IOException in file.copy: The file “New Song Folder” couldn’t be opened because there is no such file.
                        !! Command Error: Folder Template New Song [user:clib1gj170003rz10d2pqs4s4:clorbiv060001r610tzov33lv]:
                        IOException in file.copy: The file “New Song Folder” couldn’t be opened because there is no such file. (Folder Template New Song: Line 10)

                        I am pretty sure the file exists and that the pathname is correct.

                        Heading

                        preformatted text
                        
                        1. @Antonio_Esguerra, thanks for showing me that. I can see where the issue is.

                          The problem is the misuse of the ~ character in the templateFolderPath on line 3.
                          ~ is a path shorthand for /Users/YOUR USER NAME HERE/, therefore you don't need to add that again if you're using it.

                          You can fix the issue in two ways. Replace line 3 with either of these:

                          const templateFolderPath = '/Users/werk/Desktop/New Song Folder';
                          

                          or

                          const templateFolderPath = '~/Desktop/New Song Folder';
                          
                  2. A
                    Andrew Sherman @Andrew_Sherman
                      2021-02-08 14:56:58.662Z

                      This is working great. In addition, I'm trying to set up another new script that allows me to do something similar to this, but in reverse; i want to take my currently selected file and copy that file to a fixed pre-defined location. I've tried switching the constants and re-looking at the code but I'm getting stuck. Can you show me how?

                      1. For sure, this'll do!

                        function copyFileToPredeterminedLocation() {
                            // Get path of selected file
                            const selectedPath = sf.ui.finder.firstSelectedPath;
                            const selectedFileName = selectedPath.split('/').slice(-1)[0];
                        
                            // Set destination path here
                            const destinationPath = '~/Desktop';
                        
                            // Copy
                            sf.file.copy({
                                sourcePath: selectedPath,
                                destinationPath: `${destinationPath}/${selectedFileName}`
                            });
                        
                            log('File copied!')
                        };
                        
                        copyFileToPredeterminedLocation();
                        
                        1. AAndrew Sherman @Andrew_Sherman
                            2021-02-08 18:49:04.950Z

                            Thank you Raphael! Much appreciated; I need to improve my javascript. Working on it!

                            1. AAndrew Sherman @Andrew_Sherman
                                2021-03-19 19:19:47.432Z

                                Hi Raphael,

                                I hope you're doing well.

                                These scripts are serving me well. I'm looking to modify one of them. I want to copy the contents of a folder (not the folder itself), to another location (current folder selected in Finder).

                                Would you use a "for" loop or something like that?

                                
                                const sourceFolderPath = '~/Desktop/TemplateFolder';
                                const sourceFolderName = sourceFolderPath.split('/').slice(-1)[0];
                                const selectedPath = sf.ui.finder.firstSelectedPath;
                                
                                function copyTemplateToSelectedFolder() {
                                
                                    sf.file.copy({
                                        sourcePath: sourceFolderPath,
                                        destinationPath: `${selectedPath}/${sourceFolderName}`
                                    });
                                
                                };
                                
                                copyTemplateToSelectedFolder();
                                
                                
                                1. Raphael Sepulveda @raphaelsepulveda2021-03-19 20:43:46.655Z2021-03-20 16:47:05.958Z

                                  Andrew! I'm doing well, thanks!

                                  Yes, this is definitely doable. I would opt to use .forEach for this, like so:

                                  function copyTemplateToSelectedFolder() {
                                      const sourceFolderPath = '~/Desktop/TemplateFolder';
                                      const sourceFolderName = sourceFolderPath.split('/').slice(-1)[0];
                                      const selectedPath = sf.ui.finder.firstSelectedPath;
                                  
                                      // Get paths of all files in Source Folder
                                      const folderContents = sf.file.directoryGetEntries({
                                          path: sourceFolderPath,
                                      }).paths;
                                  
                                      // Copy files
                                      folderContents.forEach(filePath => {
                                          // Get file name
                                          const fileName = filePath.split('/').slice(-1)[0];
                                  
                                          // Filter out hidden files
                                          if (fileName.startsWith('.')) return;
                                  
                                          // Copy file
                                          sf.file.copy({
                                              sourcePath: filePath,
                                              destinationPath: `${selectedPath}/${fileName}`
                                          });
                                      });
                                  
                                      log('All files copied.');
                                  }
                                  
                                  copyTemplateToSelectedFolder();
                                  
                                  1. AAndrew Sherman @Andrew_Sherman
                                      2021-03-20 05:40:58.356Z

                                      Thanks Raphael. How do I get it to copy folders as well (the template folder nested folders in it)?

                                      1. Ah sorry, forgot to take that into consideration. I've updated my previous script to handle that as well!

                                        1. AAndrew Sherman @Andrew_Sherman
                                            2021-03-20 17:39:23.342Z

                                            Thanks so much, I really appreciate it.

                                      2. Hi @raphaelsepulveda,

                                        Found this been using it in a little more universal way with

                                        const destinationPath = sf.interaction.selectFolder().path;
                                        

                                        I have an idea but can't quite get it to work wondering if you had the time to help.
                                        I'd like the script to ask me once at the beginning of my soundflow session where this file is supposed to go and then every time after that send the following file (well usually a folder) to that same destination.

                                        Here's my attempt at doing that with globalState ... but it's not working.

                                        function copyFileToGlobalStateLocation() {
                                            // Get path of selected file
                                            const selectedPath = sf.ui.finder.firstSelectedPath;
                                            const selectedFileName = selectedPath.split('/').slice(-1)[0];
                                            globalState.pathName = destinationPath;
                                            
                                            // Set destination path here
                                            if (globalState.pathName === undefined) {
                                                var destinationPath = sf.interaction.selectFolder().path;
                                                log(globalState.pathName)
                                        
                                            } else {
                                        
                                        
                                                // Copy
                                                sf.file.copy({
                                                    sourcePath: selectedPath,
                                                    destinationPath: `${globalState.destinationPath}/${selectedFileName}`
                                                });
                                        
                                                log('File Copied!')
                                                log(globalState.pathName)
                                            }
                                        };
                                        
                                        copyFileToGlobalStateLocation();
                                        

                                        Basically when I'm on the Mix Stage supervising I am constantly sending little adds and fixes to the Mixers and I'd like to automate dropping those fixes into their fix folders. Which obivously change from day to day, stage to stage, episode to episode.

                                        Bonus of course would be some sort of control click to reset the destination folder...

                                        1. AAndrew Sherman @Andrew_Sherman8
                                            2022-11-04 18:27:58.140Z

                                            Hi Owen, I'm not sure if this would work for you, but I use an alternative method to global state; instead using a json file to store values, the benefit is that the values stay stored even if there's a restart.

                                            1. Thanks Andrew I think this one might have the tools i'm looking for

                                              1. So I got this working then decided to try the Json version. Thanks @Dustin_Harris for the JSON crib sheet. HUGE.

                                                1. Glad you got it working! SF community coming in clutch with the assist 👌🏼