kcw | journal | 2001 << Previous Page | Next Page >>

Although this is a relatively simple AppleScript. It still took me about a day to write and test. And it has a long way to go before I feel it's done. For this first version, the objective was to copy one folder structure to another folder structure. The tricky part is to not copy unchanged files, which saves a huge amount of time. In testing, this is still a very slow script which takes about half an hour to run on my couple thousand file web sites -- even with no copying to do.

  -- While items remain in queue, process each one
repeat while ((length of l_pending_folders) > 0)

-- Remove the first item from l_pending_folders
set l_current_folder to first item of l_pending_folders
if (length of l_pending_folders = 1) then
set l_pending_folders to {}
else
set l_pending_folders to rest of l_pending_folders
end if

-- Log current folder
log "Checking folder " & l_current_folder as string

As you can see, the outer loop cycles through folders. The inner loop cycles through the files of each folder. An alternative design is to have one loop where the queue is the files to process. If you process a folder add its contents to the queue. That's a bad design because with my website I quickly end up with over a thousand files in the queue, which is quite a memory hog.

    -- Determine destination folder string
set l_string to l_current_folder as string
try
set l_string to (text l_source_length through (length of l_string) of l_string)
on error l_error
-- error if this is the source folder base string
set l_string to ""
end try
set l_string to l_destination_folder_string & l_string

-- Determine destination folder.
-- Note that destination folder must exist.
set l_dest_folder to alias l_string

So l_pending_folders holds folder items. Theoretically I could also have a l_destination_folders queue to hold destination folders and then I wouldn't have to do the above. But that would mean another queue with dozens of items, versus a bit of a slowdown to do string manipulations. I chose to do the string manipulations, so why do I need to do it? Well, based on one folder object I can't easily pick the corresponding folder object in the destination hierarchy. So I extract the current folder as a path like "::". Then I strip out the source folder base path and replace it with the destination folder base path. Then I use the string to retrieve the corresponding destination folder.

Now, if the destination folder does not exist, I'll get an error and without a try...catch block the script stops. So why do I not need it? Well, for the root folder obviously the destination exists because the user had to select it at the start. Now, as we process each item in the source folder in the inner loop, if it's a folder we make sure the corresponding folder exists in the destination folder, otherwise we create it then. So by the time we get back to the outer loop we guarantee that the destination folder exists. Well, not quite. Someone else could always delete that destination folder before we get to it and we could have errored making the destination folder -- neither of which we take into account in this first version.


Copyright (c) 2001 Kevin C. Wong
Page Created: August 20, 2004
Page Last Updated: August 20, 2004