I can do most of this with Automator, with the exception of looking for files that already exist, so have to add a delete option to clean the folder before each export, but feel a script might be more elegant.
What I want to do is have a script that watches a Smart Album in Aperture, called Flagged Slideshow, and periodically exports any new images within that Album to a designated folder on my desktop without creating duplicates. Ideally it would match the Smart Album contents so images could be deleted from the folder simply by unflagging them in Aperture.
At the moment the Automator Export option exports ALL images and that creates multiple duplicates in the desktop folder, so I have to delete all jpg images in the folder prior to each export. As this folder is running a slide show, that way interferes with the way the slide show runs.
You need to install ASObjC Runner for this to work. http://www.macosxautomation.com/applescript/apps/runner_vanilla.html
There is often a difference between the name of an image version in aperture “IMG_2655” and the name of the file it is exported as “IMG_2655.jpg”. To resolve the difference I used ASObjC Runner’s stub command. Please test this script with test files as it will delete any files of the directory that do not share a name with a file in your target album.
tell application "Aperture"
tell its album "test album" -- This is your target Aperture album
set listA to name of its every image version
set aCount to count of listA
end tell
end tell
set theFolder to alias "Mac OS X:Users:John:Desktop:testfolder"
tell application "System Events"
set theFiles to every file of theFolder
set fileCount to count of theFiles
end tell
set listB to {}
tell application "ASObjC Runner"
repeat with i from 1 to fileCount
tell (about file item i of theFiles as alias)
if name stub is not in listA then
tell application "Finder" to delete item i of theFiles
else
set end of listB to name stub
end if
end tell
end repeat
end tell
set listC to {}
repeat with j from 1 to aCount
if item j of listA is not in listB then
tell application "Aperture" to set end of listC to image version (item j of listA)
end if
end repeat
if listC ≠{} then tell application "Aperture" to export listC to theFolder
Thanks adayzdone, I will take a look at this when I get a bit more time, next week now, and report back.
Ok, I decided to give it a quick go this evening and it works just fine, thank you very much. Would it be possible to either add an Export Preset into the command, or reverse the watch so that files within a folder are added to or deleted from an Aperture Project or Album? The idea being that I can add a watermark to and scale the images ready for wed upload.
tell application "Aperture"
tell its album "test album" -- This is your target Aperture album
set listA to name of its every image version
set aCount to count of listA
end tell
end tell
set theFolder to alias "Mac OS X:Users:John:Desktop:testfolder"
tell application "System Events"
set theFiles to every file of theFolder
set fileCount to count of theFiles
end tell
set listB to {}
if fileCount > 0 then
tell application "ASObjC Runner"
repeat with i from 1 to fileCount
tell (about file item i of theFiles as alias)
if name stub is not in listA then
tell application "Finder" to delete item i of theFiles
else
set end of listB to name stub
end if
end tell
end repeat
end tell
end if
set listC to {}
repeat with j from 1 to aCount
if item j of listA is not in listB then
tell application "Aperture" to set end of listC to image version (item j of listA)
end if
end repeat
if listC ≠{} then tell application "Aperture" to export listC using export setting "JPEG - 100X100" to theFolder
I am running into a couple of problems with this now.
First on my MacBook Pro where I first used it and it worked, I now get an error which is “ASObjC Runner got an error: Connection is invalid.” number -609. and the line tell (about file item i of theFiles as alias) is highlighted, well the bit in brackets is. I am not getting this error on my iMac.
The second issue is that it is not just searching the chosen Album but the whole Library and if two files exist with the same name, it is taking the file name from the chosen Album but exporting the earliest one and not the one in the chosen Album. This will not be a huge issue on the day at events as it is unlikely the camera counter will roll round another 9,999 in a day and I would start another Library for a new event, but thought I should mention it.
Are both computers running the same version of the OS? That error suggests something has made Runner crash, so if you can have a look in Console for any error messages, I’d be most grateful.
You might also modify the middle part like this:
Nesting calls to apps is not a good idea, and “parsed path” is a lot quicker than “about file” because it’s a simple string manipulation rather than a file system operation.
That’s odd that it won’t compile – I wonder if there is a conflict with a scripting addition. Can you try this and see if it compiles there:
tell application "ASObjC Runner"
set thePath to (item i of theFiles) as text
set parsedPath to parsed path of thePath
set nameStub to name stub of parsedPath
end tell
tell application "Aperture"
set listA to name of every image version of album "test album"
set aCount to count of listA
end tell
set theFolder to alias "Mac OS X:Users:John:Desktop:testfolder"
tell application "System Events"
set theFiles to every file of theFolder whose visible is true
set fileCount to count of theFiles
end tell
set listB to {}
if fileCount > 0 then
tell application "ASObjC Runner"
repeat with i from 1 to fileCount
set nameStub to name stub of ((parsed path of (item i of theFiles as alias)))
if nameStub is not in listA then
manage file (item i of theFiles as alias) with deleting
else
set end of listB to nameStub
end if
end repeat
end tell
end if
set listC to {}
repeat with j from 1 to aCount
if item j of listA is not in listB then
tell application "Aperture" to set end of listC to image version (item j of listA)
end if
end repeat
if listC ≠{} then tell application "Aperture" to export listC using export setting "JPEG - 100X100" to theFolder
FYI, parsed path requires a path as a string, not a file or alias, so that “as alias” is likely to be problematic. But it may be that Cocoa scripting coerces it silently anyway.
set theFiles to list folder theFolder without invisibles
and
set nameStub to name stub of (parsed path of (item i of theFiles as text))
if nameStub is not in listA then
manage file ((theFolder as text) & (item i of theFiles) as text) with deleting
The script would look like this:
tell application "Aperture"
set listA to name of every image version of album "test album"
set aCount to count of listA
end tell
set theFolder to alias "Mac OS X:Users:John:Desktop:testfolder"
tell application "System Events"
set theFiles to list folder theFolder without invisibles
set fileCount to count of theFiles
end tell
set listB to {}
if fileCount > 0 then
tell application "ASObjC Runner"
repeat with i from 1 to fileCount
set nameStub to name stub of (parsed path of (item i of theFiles as text))
if nameStub is not in listA then
manage file ((theFolder as text) & (item i of theFiles) as text) with deleting
else
set end of listB to nameStub
end if
end repeat
end tell
end if
set listC to {}
repeat with j from 1 to aCount
if item j of listA is not in listB then
tell application "Aperture" to set end of listC to image version (item j of listA)
end if
end repeat
if listC ≠{} then tell application "Aperture" to export listC using export setting "JPEG - 100X100" to theFolder
Ah, I see the problem: System Events is returning its own references rather than aliases or paths. You can remove System Events altogether; the ‘list folder’ command is a standalone command from Standard Additions – although it is listed as deprecated.
If you’re happy to upgrade to ASObjC Runner 1.9.5, which has been available for, oh, about 10 minutes :), you can use it to get the list of files as well, something like:
set theFolder to alias "Mac OS X:Users:John:Desktop:testfolder"
tell application "ASObjC Runner" --version 1.9.5
set theFiles to enumerate folder theFolder without including folders
set theStubs to about file theFiles include only {"name stub"} -- requires Runner version 1.9.5
set fileCount to count of theFiles
set listB to {}
if fileCount > 0 then
repeat with i from 1 to fileCount
set nameStub to name stub of item i of theStubs
if nameStub is not in listA then
manage file (item i of theFiles) with deleting
else
set end of listB to nameStub
end if
end repeat
end if
end tell
It now works on the laptop, I did upgrade but not sure if that is why. I also have to change ‘Mac OS X’ to ‘Macintosh HD’ so it looks like this.
tell application "Aperture"
set listA to name of every image version of album "test album"
set aCount to count of listA
end tell
set theFolder to alias "Macintosh HD:Users:John:Desktop:testfolder"
tell application "System Events"
set theFiles to list folder theFolder without invisibles
set fileCount to count of theFiles
end tell
set listB to {}
if fileCount > 0 then
tell application "ASObjC Runner"
repeat with i from 1 to fileCount
set nameStub to name stub of (parsed path of (item i of theFiles as text))
if nameStub is not in listA then
manage file ((theFolder as text) & (item i of theFiles) as text) with deleting
else
set end of listB to nameStub
end if
end repeat
end tell
end if
set listC to {}
repeat with j from 1 to aCount
if item j of listA is not in listB then
tell application "Aperture" to set end of listC to image version (item j of listA)
end if
end repeat
if listC ≠{} then tell application "Aperture" to export listC using export setting "JPEG - 100X100" to theFolder
This has great potential for me in saving time, but it would also be good to expand on this to work with folders that don’t yet exist. Let me explain.
I have a website on my Mac in the Sites folder which I use to display many hundreds of images taken during an event. The event may be divided into various Classes (Equestrian/Sporting) so I have an Application Script that I type the name of a Class into and it creates a Project in Aperture and a corresponding Folder in the webpage Parent Folder. So if the Parent folder is “Macintosh HD:Users:Event:Sites:Website”, a subfolder called Class One will be added and a Project in Aperture called Class One will also be created. I have a Script attached to the Folder “Website” that adds two sub-folders to whatever folder is added to it, so “Class One” will have “Thumbs” & “Photos” sub-folders added. At the same time another script is added to “Class One” that takes any images that are dropped into it, makes copies for both “Thumbs” & “Photos” and scales to 220px & 900px respectively. This works well and is a simple two click process from within the Aperture user interface to import the images from a card reader and build the website.
Now what would be very cool would be to have this new script watch the Aperture Project and its corresponding "Thumbs’ folder without me having to manually edit the script for each one. This way if upon going through the Aperture images I find one that is sub standard etc, I can delete it and it will be deleted from the “Thumbs” folder as well. There is no need to delete it from the “Photos” or the “Class One” folders as if there is no Thumbnail, the client will not have access to the larger image anyway. Of course, this all needs to happen with a single mouse click
Having said that it might be easier to add a section to some of the existing script that does the scaling and copying from “Class One”. Lots to be getting on with now.