Exporting files from Aperture

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.

Any help on this would be much appreciated.

Michael

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.

Thank you again though for this.

Michael

This should let you add an export setting:


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

Hi

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.

Regards,
Michael

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.

Thanks Shane.
I tried you code but it will not Compile or Run as I get an end of line error where I have put the smilie.

How much of the error report do you want, it is very long?

Michael

It sounds like you might have an old version. Try choosing check for Updates… from its menu.

I have version 1.9.4 of AObjC Runner.

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

See if this does the trick:

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 nameStub to name stub of ((parsed path of (item i of theFiles)) as text)


What do you suggest?

I guess you could also change the lines:

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

The parens are in the wrong place. Try:

set nameStub to name stub of (parsed path of ((item i of theFiles) as text))

set nameStub to name stub of (parsed path of ((item i of theFiles) as text))

returns

I took the original command from your post #6. I think the problem is the difference between file and file name.

Post #11

return item i of theFiles

file “Mac OS X:Users:John:Desktop:testfolder:IMG_0015 2000-07-21.jpg” of application “System Events”

Post #14

return item i of theFiles

“IMG_0015 2000-07-21.jpg”

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

Thank you both for taking the time with this.

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 :slight_smile:

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.

Once again Than You.

Michael

You should probably use something like:

set theFolder to alias ((path to desktop as text) & "test folder")