RE:
http://bbs.applescript.net/viewtopic.php?t=9660
http://bbs.applescript.net/viewtopic.php?t=9654
http://bbs.applescript.net/viewtopic.php?t=9632
http://bbs.applescript.net/viewtopic.php?p=33672
The various isBusy() and isDone() solutions proposed in the above threads have only worked for me to an extend.
ftp-ing a file into the folder, things seem to work fine. But all kind of weird situations were observed when Windows FileSharing is used to copy the files to the Mac-folder (see the above threads for examples)
I have now worked out a different framework that allows a folder action to only begin its action when the file has been received.
In my testing, this turned out to be far more robust than the earlier proposals, on which the following draws.
Specifically, I found the decoupling of the two questions “Is file still growing?” and “Is file open for write access?” to be very important.
In my approach, outlined below, these questions are asked independently of each other, one after another. This seems to prevent many issues when Windows filesharing is involved.
To answer both questions, my approach relies completely on standard unix commands, which seem to give a much better control. The basic outline of my folder action is as such:
--folder action handler
on adding folder items to this_folder after receiving added_items
--do for every added item
repeat with this_item in added_items
try
--process added items one after another
ProcessItem(this_folder, this_item)
end try
end repeat
end adding folder items to
--subroutine that processes items that were added to a folder
on ProcessItem(this_folder, this_item)
--check if file is growing using UNIX "ls" command
set LastFileSize to -1
set isGrowing to true
repeat until isGrowing is false
set CurrentFileSize to do shell script ("/bin/ls -l " & (quoted form of (POSIX path of (this_item))) & " | /usr/bin/awk '{print $5}'")
if CurrentFileSize is equal to LastFileSize then
set isGrowing to false
else
set LastFileSize to CurrentFileSize
delay 2
end if
end repeat
--check if file is busy using UNIX "lsof" command
set isbusy to 1
repeat until isbusy is 0
set isbusy to ((do shell script ("echo `lsof " & (quoted form of (POSIX path of (this_item))) & " | wc -l`")) as integer)
if isbusy is not equal to 0 then
delay 5
end if
end repeat
--once the script arrives here, the file in question is not growing and is not busy anymore
--this has been tested for all kinds of file sizes (up to 1,2GB) and protocols (FTP, SMB)
--now that the file is ready, begin your processing
--you should check here if the file exists, because the Windows copy process could have been aborted by the user
end ProcessItem
feel free to test this framework for yourself, and post back comments and suggestions
cheers
-captnswing