One of the best features of Mac OS X is a feature called ‘Folder Actions’. What this feature allows the power user to do is to watch a folder on the computer and whenever that folder receives a file, folder action kicks in and runs a script of the user’s choosing.
I’ve used this feature for a long, long time. I use it among other things to archive all the files submitted to my main site into a folder tree organized by date. For example a story submitted on April 20th, 2008 will end up in:
I’ve been doing this for years. So long ago that I can’t recall when I started doing it that way; it may have started on Mac OS 9. So needless to say, it’s very useful.
I have few other folder actions set up to do various routine tasks.
But it all came to a halt with my upgrade to Leopard or Mac OS X 10.5.
In Leopard, I couldn’t get folder actions to work with more than one active folder action. If I set up 2 of them, only the second one will work. If I set up three, the third will work and the system will completely ignore the first two. I’ve filed bug reports with Apple, and now at 10.5.2 the problem persists.
This weekend, I’ve had to do something that I rarely do, which is to archive a massive number of files; around 27,000 files at the same time. So what better need for an automated thing other than a massive job?
Well, as it turned out, a massive job is what you don’t want to handle with the current version of Folder Actions.
As soon as I dumped the 27,000 files into the watched folder, my computer (a 2.8 Ghz iMac) slowed down to a crawl. A quick check in the terminal showed that the Folder Actions daemon consuming 100% of one CPU core and the Finder was consuming the remaining 80% of the other core. The funny part is that no files were being moved. After 30 minutes, files started moving at the speed of 1 file every 4 seconds. At that rate, the job would take 30 hours to finish.
But the kicker is that the Finder kept crashing and throwing a dialog about an invalid connection and requiring me to click ‘OK’ in order for it to proceed. So even if I were willing to wait, without constant clicking OK, the job wouldn’t proceed at all.
I worked around the problem by creating a new script that reads the list of files from a flat text file that I created by selecting all the files in the Finder and copying and then pasting into a BBEdit document. So the script reads that text file, line by line and hands the file’s path to the finder and the finder moves it to its destination.
It’s slow, it’s doing about 2 files per second as I write this, so theoretically it should be done in like three hours or so.
I wish I knew more about shell scripting. I’m sure such a job for a good shell scripter would take no time to set up and few minutes at the most to execute. I guess that’s something that I need to add to my arsenal of tools.
And here’s a free tip: In AppleScript’s date function, if you want the number of the month do it like this:
set theMonth to the month of theDate as integer
if you don’t add that ‘as integer’ bit, you always get the name of the month and that bit is not documented anywhere that I could find. I stumbled on it by sheer dumb luck. Page 88 of AppleScript’s language guide gives you this:
Class: constant (page 86)
Specifies the month of the year of a date object, with one of the constants
January, February, March, April, May, June, July, August, September, October, November, or December.
But if you you try this:
set theMonth to July as integer
You get 7 back.
Talk about counterintuitive.