I’m trying to use folder actions to create a workflow for moving and printing of files, but folder actions are so hit and miss I was wondering if there is an alternative? I just can’t rely on these actions to work by themselves right now.
What are your parameters? What “event” is supposed to trigger the move or printing of a file?
Whenever an item is added to a folder I need a script to run every time. But the actions just don’t run everytime.
Depending on the rate in which files are added to the folder, I have had a similar issue.
One way around it is to set a cron schedule that calls the script every couple of minutes that:
- makes a list of all existing files in that folder at that moment
- loops through that list printing and moving the files accordingly
– depending on the file sizes and write speeds, you may need to run a check that the file is saved completely before performing whatever action you need to on that file. For example, if you are working with large tiff files, it is possible that the file could be seen as existing in the folder, but it is still being written to the folder from somewhere else on the network.
You can also use an “on idle” script. They go like this:
(*An "on idle" script, saved as a stay-open application will run at specified time intervals. Often used to "watch" something and respond.*)
on run
(*do setup - this runs when the application is started to set things up. It is not necessary to have an 'on run' handler because the on idle handler runs immediately after this anyway. If you want this to run all the time after every login, list it your startup items. You quit it from it's dock icon.*)
end run
(*'on idle' runs immediately following the 'run' handler if there is one, and thereafter on the interval specified in the return at the end. (An 'on run' handler is not required, so omit if there is no setup)*)
on idle
-- In this section, you do your script operations every interval
return xx -- do this every xx *seconds*.
end idle
on quit
(*do stuff - assumes you want to clean things up or save preferences or change properties before the program quits. This section runs only if the application is quit from the dock, or by any other means. It is not necessary to have an on quit handler.*)
(*if there is an on quit handler, then 'continue quit' must be the last statement or the script will not stop! The presence of an 'on quit' handler 'grabs' the system command to stop, so it will not complete the quit process until notified to do so. 'continue quit' does that.*)
continue quit
end quit
The cron schedule sounds good, but I can barely figure out applescript right now. How do you go about attaching an ‘on idle’ script to a folder?
Yes, folder actions are terrible. I always do it in the applescript.
Here is the main parts of a script I have that looks in a folder for any XML files dropped in it. You can modify it to your needs:
on run
--Any initialization that needs to happen - mount servers? launch apps?
end run
on idle
set PathToDesktop to path to the desktop as text
set FormDataFolder to (PathToDesktop & "FormData") as alias
tell application "Finder" to set these_items to (every file of FormDataFolder whose kind contains "XML")
--Check to see if there are one or more XML files in the FormData folder on the desktop
if the number of items in these_items is greater than 0 then
tell me to activate
display dialog "Files located. Script starting!" buttons " " default button 1 giving up after 2
--Go through all XML files, one at a time
repeat with XMLfile in these_items
--Process XMLFile
end repeat
end if
return 5
end idle
Sorry, what’s wrong with folder actions? I use a few of them and they work very reliably.
Indeed the AppleScript code must be foolproof, because a folder action aborts silently when an error occurs.
An idle script is an incredible waste of resources, because 95% of the time the script checks for nothing.
I’d prefer a launchd agent watching the folder, which notifies just when the file system changes
I don’t understand why the folder action only works some of the time. I did a quick search on the launchd option, is that straightforward to set up?
Not really straightforward, launchd notifies also if a file was removed.
For a tutorial read this. It’s for a flash drive but uses the same technique
After some Googling I found Lingon, looks like it may help!
“Sorry, what’s wrong with folder actions?”
I have never had any luck with them. It will kick off the AppleScript and then if something else is added to the folder it tries to kick off the AppleScript again while the first one is still running. Causes all sorts of errors. That’s why I use the on idle loop version. I have never noticed any slowdown of my computer or problems with having it up and running.
For the record, I prefer to set this sort of thing up in XCode with a status window as opposed to doing it in plain AppleScript, but it works either way.
Maybe folder actions are just significantly better in 10.6, but I’ve been using them a lot and never had a single problem - things seem to work reliably 99.99% of the time, with the .01% being one time where my script was just not written right.
Matt-Boy,
I’m charged with migrating Folder Actions scripts from a 10.4 machine to a new MacPro 10.5.6 machine. I’ve found the FAs are now not reliable in 10.5. So I want to implement your on idle recommendation. My AppleScript experience is limited.
Here is one of the scripts:
on adding folder items to this_folder after receiving added_items
try
with timeout of 600 seconds
tell application "Finder"
repeat with this_item in added_items
if (name of this_item ends with "pdf") then
tell application "Finder" to move this_item to folder "PDF" of folder "jpg_version" of folder "Layout" of disk "AD_IMAGES_TEMP" with replacing
end if
end repeat
end tell
end timeout
end try
end adding folder items to
Instead of using ‘on adding folder items’ I’d like to use your option of looking in the folder for PDF files. I need the line “set PathToDesktop to path to the desktop as text” unpacked some more if I’m to follow that example. I guess I need a more literal example for a folder in any other location.