Search code examples
applescriptrepeatautomatorfinder

Apple Script Time-Out "Finder got an error: Connection is invalid"


I have this Apple Script working with huge amount of data. What it does is pretty much compares hundreds of folder names to hundreds of picture names. If folder name is contained in the picture name .. it copies this specific picture to the corresponding folder. The data needs to be compared is huge.. sometimes it takes more than an hour to finish. I need an advice how to solve this specific problem.

This error message appears regardles of time and place where the script is executed ( my desktop or working server machine ). Usually appears between 40minute and 60minute.

enter image description here

As a result all finder windows are closed and the script stops. Looks like it's some kind of time-out period. Is there a way to extend this period or remove it completly ?

Thank you ! EDIT: Here is the script itself:

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
property defaultColor : "Green"
on run {input}
    tell application "Finder"
        set MainFolder to (choose folder with prompt "ART.Numbers FOLDERS Directory:")
        set theArtFoldersList to every folder of MainFolder
        set NameOfMainFolder to name of MainFolder as text
        set targetFolder to "Users:zzz:Desktop:Pictures" as alias
        set pictures_collection to every file of entire contents of (targetFolder)
    end tell
    set userColor to 5
    repeat with CurrItem in theArtFoldersList
        tell application "Finder"
            if label index of CurrItem is not 7 and label index of CurrItem is not 6 and label index of CurrItem is not 5 then
                tell application "Finder" to set ArtFolderName to name of CurrItem as text
                tell application "Finder" to set elementpath to container of CurrItem as text
                set elementfolder to (elementpath & ArtFolderName) as alias
                
                repeat with anItem in pictures_collection
                    tell application "Finder" to set NameOfPicture to name of anItem
                    tell application "Finder" to set outpath to container of anItem as text
                    
                    tell application "Finder"
                        if NameOfPicture contains ArtFolderName and NameOfPicture does not contain (ArtFolderName & "_VIGN_N.jpg") and label index of anItem is 7 then
                            tell application "Finder" to duplicate anItem to folder (elementfolder as alias)
                            if label index of elementfolder is not 2 then -- пази червеният цвят на папката
                                set label index of elementfolder to userColor
                            end if
                        end if
                        if NameOfPicture contains (ArtFolderName & "_VIGN_N.jpg") and label index of anItem is 7 then
                            tell application "Finder" to duplicate anItem to folder (elementfolder as alias)
                            if label index of elementfolder is not 2 then
                                set label index of elementfolder to userColor
                                exit repeat
                            end if
                        end if
                    end tell
                end repeat
            end if
        end tell
    end repeat
    tell me to activate -- display dialog as active window
    display dialog NameOfMainFolder & " is Done !"
    return input
end run


Solution

  • I've only been able to test the following script lightly, since I don't have access to your file structures, so please test it on copies of your data until you're sure it works the way you want.

    My due diligence done...

    The 'Connection is invalid' error comes from the Finder's entire contents command, executed on a folder with a lot of files. The script is timing out while the Finder is still plugging away trying to build the file list. It's generally a bad idea to script the Finder this heavily anyway; the Finder can be temperamental. With that in mind, I made three basic changes to your script:

    • I shifted from scripting the Finder to scripting System Events where possible. System Events is generally more stable.
    • I wrote an iterative handler which drills down through the folder structure instead of trying to gather all the files in advance. Thi breaks up the work the Finder has to do into small, manageable chunks.
    • I put all the Finder calls into separate handlers, for clarity.

    I also shifted a couple of variable to properties so that they could be seen by the script handler as it iterates down.

    property defaultColor : "Green"
    property userColor : 5
    property image_folder : "/Users/zzz/Desktop/Pictures"
    
    on run
        set sorting_folder to (choose folder with prompt "ART.Numbers FOLDERS Directory:")
        tell application "System Events"
            set sorting_folder_name to name of sorting_folder as text
            my iterateThroughFolder(sorting_folder)
        end tell
        tell me to activate -- display dialog as active window
        display dialog sorting_folder_name & " is Done !"
    end run
    
    on iterateThroughFolder(sorted_art_folder)
        tell application "System Events"
            set subfolder_list to every folder of (sorted_art_folder)
            repeat with a_folder in subfolder_list
                my iterateThroughFolder(a_folder)
            end repeat
            
            -- skip top level       
            if POSIX path of sorted_art_folder is equal to image_folder then return
            
            set sorted_art_folder_list to folders of sorted_art_folder
            repeat with an_sorted_art_folder in sorted_art_folder_list
                set artFolderName to name of an_sorted_art_folder
                set file_list to (every file of folder image_folder whose name contains artFolderName)
                repeat with a_file in file_list
                    if (my finderLabelIndex(path of a_file)) ≠ 7 then
                        my finderDupFile(path of a_file, path of an_sorted_art_folder)
                        if (my finderLabelIndex(path of an_sorted_art_folder)) ≠ 2 then
                            my finderSetLabelIndex(path of an_sorted_art_folder, userColor)
                        end if
                    end if
                end repeat
            end repeat
        end tell
    end iterateThroughFolder
    
    on finderLabelIndex(finderPath)
        tell application "Finder"
            return label index of item finderPath
        end tell
    end finderLabelIndex
    
    on finderSetLabelIndex(finderPath, idx)
        tell application "Finder"
            set label index of item finderPath to idx
        end tell
    end finderSetLabelIndex
    
    on finderDupFile(fileFinderPath, destingationFinderPath)
        tell application "Finder"
            duplicate file fileFinderPath to folder destingationFinderPath
        end tell
    end finderDupFile
    

    N.B.: Be aware of the often confusing path reference styles.

    • System Events has its own file system reference objects (disk item, file, folder)
    • Finder has its own file system reference objects (item, file, folder)
    • posix paths (/users/.../Desktop/...) work in System Events, but not the Finder
    • system paths (Maintosh HD:users:...:Desktop:...) work in both apps

    If you want to send a reference from System Events to the Finder, use SE's path property (which returns a system path), then convert it to a Finder object in a Finder tell block. See my Finder handlers, above.