We’ve written an Applescript which watches several folders located on a Sun server running helios. Users are copying files to these folders from Mac’s running OS X 10.3.9. When the script runs it moves the files from the hot folder into another folder, opens them in Photoshop, and then runs some actions on them. The problem we are experiencing is that when multiple files are copied into the hot folder our Applescript sometimes grabs these files before they are done copying, causing files to become corrupt. We’ve tried writing in a size check to see if the file is growing and if so, don’t copy, however this isn’t working well. Does anyone have suggestions on how to determine if files have finished copying or can you offer a quick fix for this?
The files that are being moved into the hot folders are HDR camera files. The script opens them, exports a TIFF and applies some corrections. The only issue is trying to get the script to wait for this file to finish copying before it grabs it and tries to open it. I think it may have something to do with the way Mac OS X copies files. It seems to put a 2k placeholder at the destination while it waits to copy. My script sees this placeholder, notices that it hasn’t changed in a few seconds, grabs it and tries to process it. We’ve tried adjusting the wait times but it’s not an ideal way to handle it because people can drop 2 files or 10 into a folder and the wait times would need to accomodate this variable.
Here’s the way I solved this problem… Don’t know if it will work for you. It checks the folder every 30 seconds and will deal with any number of files.
This could probably be done cleaner, but it works for me and I’m not messing with it. :D:D
Edit:
Perhaps obviously, you’ll have to save this as a stay open application in order for the idle handler to work.
on run
set myRec to {}
set your_incoming_folder to "Folder where your files are."
end run
on idle
try
set fileList to list folder your_incoming_folder without invisibles
on error
set myRec to {}
end try
repeat with aFile in fileList
tell application "Finder" to set the_info to info for alias (your_incoming_folder & aFile)
set file_name to name of the_info
set new_file_size to size of the_info
set old_file_size to getFromRec(file_name, myRec, 2)
if old_file_size = new_file_size then -- done copying
DeleteListItem(file_name, myRec) -- clear the record of this file
--do your stuff here.
else
set record_exists to getFromRec(file_name, myRec, 1)
if record_exists = 0 then -- add a new record
set the end of myRec to {file_name, new_file_size}
else --update an existing record
updateRec(file_name, myRec, new_file_size)
end if
end if
end repeat
return 30
end idle
on updateRec(theProp, theRec, updated_value)
repeat with thisItem in theRec
if item 1 of thisItem is theProp then
set item 2 of thisItem to updated_value
end if
end repeat
end updateRec
on getFromRec(theProp, theRec, theItem)
set found to false
repeat with thisItem in theRec
if item 1 of thisItem is theProp then
set found to true
exit repeat
end if
end repeat
if found then
return item theItem of thisItem
else
return 0
end if
end getFromRec
-- Delete list item "itemNum" from "theList"
on DeleteListItem(theProp, theList)
--need to find out what item num it is.
set itemNum to 1
repeat with listItem in theList
if item 1 of listItem is theProp then
exit repeat
else
set itemNum to itemNum + 1
end if
end repeat
set theLength to length of theList
if theLength < 2 then
return {}
else if itemNum = 1 then
return items 2 thru theLength of theList
else if itemNum = theLength then
return items 1 thru (theLength - 1) of theList
else
return ((items 1 thru (itemNum - 1) of theList) & (items (itemNum + 1) thru theLength of theList))
end if
end DeleteListItem