PDA

View Full Version : Folder event firing too soon?




FullGaz
Mar 1, 2008, 03:40 AM
I wrote an automator script called by an event on a folder. The idea is to convert some video files when I drop them on the folder. These files are stored on a network drive so I just drag them from one Finder window to another to quick the process. The script works and I have no problem with it.

However, I've noticed that the File Added event gets fired before the end of the copy from the network drive to the local drive with the script attached to it. It seems to get fired at the beginning of the copy, not at the end. The AppleScript starts with: on adding folder items to this_folder after receiving added_items so in theory it should wait for the end of the copy, but it doesn't. Of course, my script gives me an error saying that the file is in use by OS X...

Has anybody had that problem when copying - not moving - a file to a folder with a Folder Event?



HiRez
Mar 1, 2008, 05:41 AM
Yes, it's a real problem which I consider a bug. I have the same problem all the time with AppleScript, which is probably using the same event mechanism. Basically I have to write into my script a loop that checks the sizes of all the dropped files periodically, and when the sizes stop growing it assumes the copy is complete. A real inefficient PITA. Not sure how you'd go about that from Automator, maybe add a pause step until you are sure the files would be copied...a far from ideal solution though. I think the Finder is supposed to set the "busy" status of the file to true while copying as well so maybe you could check on that, though for some reason I feel like that does not work, possibly because OS X no longer tracks this status.

FullGaz
Mar 1, 2008, 01:47 PM
Thanks HiRez, that was useful. I'll have a look at the possibilities to use Automator to implement your trick.
BTW, I found Automator to be full of bugs, I mean, FULL to the throat of bugs! It's like this stuff was never really tested, just banged together by some bored programmers at Apple and included because it looks pretty... Shame, really.

HiRez
Mar 1, 2008, 05:36 PM
If you are interested, here is the basic form I use for watch folders:
property DELAY_TIME_SECONDS : 5 -- How long to wait between checking file size.

on adding folder items to thisFolder after receiving theItems
repeat with f in theItems
set oldSize to 0
set newSize to -1
-- When newSize equals oldSize, it means the copy is complete because the size hasn't changed.
repeat while newSize ≠ oldSize
-- Get the file size.
set oldSize to size of (info for f)
delay DELAY_TIME_SECONDS
-- Sample the size again after delay for comparison.
set newSize to size of (info for f)
end repeat
-- Do your processing here on file f...
end repeat
end adding folder items to
I agree it's a shame that the AppleScript and Automator technologies are so flakey, unreliable, and buggy, it could be really amazing resource. Well, it can be, but it's always painful. Add to that the fact that Apple has very poor to no support for AppleScript in most of its own pro applications. They aren't setting a very good example.

Plus, I just don't like the AppleScript language very much. It tricks you into thinking it's friendly and easy but in reality it's more stubborn and vague and flakey than most other languages I've programmed in including C, Objective-C, Python, and Java. It can do things otherwise impossible, but some things which should be simple are not. I wish Apple or somebody would torch AppleScript and start from the ground up with a new AppleScript, which is well-supported, reliable, fast, and uses a better language. When I upgrade to Leopard I'll have to check out the new AppleScript bridge, that might alleviate some of the pain.

FullGaz
Mar 2, 2008, 07:23 PM
Well, I'm running Leo now and I don't think that AS has changed. I don't think that the language itself is that bad but obviously it's very different from many other languages I've used before so it takes a while to get used to it. It tries too much to look like plain english so when you're trying to just program, you have to translate basic programming skills into Shakespearian prose...

Back to my problem...

I've played with AS tonight and did something similar to what you've suggested but I've noticed that the file size goes up in huge quantum at a time when copying them. The problem here is that if you work over a relatively slow network (which I don't), how long do you have to wait between 2 checks before you know it's really the end of the copy? I've checked to see if the is locked property works, it doesn't. Also, I've tried to open the file with the open for access statement and... it worked! It opened the file for access in read write mode, while it's still being copied.

In other words, I haven't found any simple reliable way to tell whether the file is still being copied or not.

One thing I've found that I could use the Terminal command lsof which returns a list of processes locking a file. That particular trick shows the file being locked as it's being copied. So I can monitor the copy process by doing this:


Get the list of files being copied
Run the lsof command and check which file is being locked
Set a flag for that file
Check if al the files are flagged: we're done!


So now, I need to play some more and try to implement that in AS.

I'll post my results here (unless you beat me to the post ;))

FullGaz
Mar 2, 2008, 08:26 PM
So I think I've found a solution that actually works.

Assuming you're copying files to the folder MyFolder:


on adding folder items to this_folder after receiving added_files
...could filter files here
wait for added_files
...do some more stuff here
end adding folder items to

on wait for theFiles
tell application "Finder"
set wait to true
repeat while wait
set wait to false
set newFiles to {}
repeat with aFile in theFiles
set posixPath to POSIX path of aFile
if size of aFile = 0 then
copy aFile to the end of newFiles
set wait to true
else
try
do shell script ("lsof \"" & posixPath & "\"")
set wait to true
copy aFile to the end of newFiles
end try
end if
end repeat
set theFiles to newFiles
end repeat
end tell
end wait

This piece of code will only return when all the files are copied in full. I suppose it could easily be adapted to be fully recursive, and to filter folder items, but I don't need that so I'll leave it to you.

Enjoy!

justbcuz
Mar 11, 2008, 04:44 PM
I tried you recommendation of the "on wait for theFiles" and it work pretty good when you are copying files to the folder with the actionScript attached.

I am running into a problem when I save a file from an application to the same folder.

I am converting .mov files to .flv using ffmpeg. When I save a file from Quicktime the "do shell script ("lsof \"" & posixPath & "\"")" part of the script attaches it self to the quicktime process and remains in a loop until the quicktime process ends.

Is there another way to watch when a file done being saved from an application and being copied?

Thanks,
Justin