Getting Media Item properties from Photos

AppleScript novice here. Trying to get some information from an image in Photos to populate some attributes in Tinderbox.

This is what I’ve got so far:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions


tell application "Photos"
	set currentSelection to the selection
	if currentSelection is {} then error number -28
	--tell currentSelection
	set PhotoCaption to description of currentSelection
	--	set PhotoDate to date
	set PhotoTitle to name of currentSelection
	set PhotoFileName to filename of currentSelection
	set PhotoID to id of currentSelection
	--end tell
end tell

The lines commented out don’t make any difference. The script always returns the same error:

“Can’t get description of {media item id “7F30275C-031C-4E00-BFCB-FA8C49135A1D/L0/001” of application “Photos”}.”

The “description” property of a Media Item in Photos is the photo caption. If you comment out description, the next property fails as well.

You can get these properties if you place the photo in an album and do something like this:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

tell application "Photos"
	tell its album "Blog"
		tell its media item "Tomatillos"
			set theDescription to description
			set theTitle to name
		end tell
	end tell
end tell

tell application "Tinderbox 9"
	tell note "blog" of front document
		set value of (attribute named "Text") to theDescription
		set value of (attribute named "Name") to theTitle
	end tell
end tell

Mark Anderson did this for me, posted it at the Tinderbox Forum, and I’ve verified it works, but it’s not suitable for what I’m trying to accomplish.

I don’t wish to create a unique album and specify the photo by name each time, I think I should be able to just operate on the selection.

Clearly, there’s something I’m missing. Any thoughts?

Thanks,
Dave Rogers

Hey, Dave, what’s happening is that Photos is returning the selection as a list of selected items. Even if it’s just one photo.

This version of your script goes through the list and extracts the info.

tell application "Photos"
	set currentSelection to the selection
	if currentSelection is {} then error number -28
	repeat with thisPhoto in currentSelection
		set PhotoCaption to description of thisPhoto
		set PhotoTitle to name of thisPhoto
		set PhotoFileName to filename of thisPhoto
		set PhotoID to id of thisPhoto
	end repeat
end tell

(Note, if you do have more than one photo selected, you’ll only get the info for the last photo in the selection. If you need the info from all of them, we can show you how)

AppleScript is an object-oriented language. When issuing commands, the first trick is to know which object you’re talking to (e.g., `selection of application “Photos”, and then determine what class/datatype of that object is. In short, talk to the right object and address it in a way it understands.

This info is available in the app’s dictionary, through when debugging complex scripts, asking for class of [something] can also be handy.

Check Photo’s dictionary entry for the class/type of Photo’s “selection” property:

Note that the property selection returns a list of items. This is true regardless of how many items you select. With one image selected, currentSelection will return something like:

{media item id "30BCB534-2A84-4B5A-AE6E-051C580E363F/L0/001"}

Note that the class of selection is list, not media item. A list has no description property, so when you ask for it, the list complains “I don’t know nuthin’ ‘bout birthing’ no descriptions!” You want to talk to the selected media items you’ve put in the list, not the list itself.

You could simply redefine currentSelection to refer to the first item in the list, rather than the list itself…

set currentSelection to selection
set currentSelection to item 1 of currentSelection

…but since Photos will let you select more than one image, it makes sense to write a script that can deal with as many images as you care to select. Ironically, the very thing that confused you will make this easy: selection returns a list. All you have to do is write a loop to examine each item in that list.

tell application “Photos”

set currentSelection to selection --					a list of the selected items
class of currentSelection --							→ list
if currentSelection ≠ {} then --						do nothing if nothing is selected
	set metaData to {} --								a place to store the properties
	repeat with thisMediaItem in currentSelection --	iterate through one or more items
		class of thisMediaItem --						→ media item
		tell thisMediaItem --							get the desired properties from the current item
			set theDescription to description
			set theTitle to name
			set theFileName to filename
			set theID to id
		end tell
		--												add a record of thisMediaItem's data to¬
		--												the list of data for all the selected items
		set metaData to metaData & ¬
			{{theDescription:theDescription, theTitle:theTitle, theFileName:theFileName, theID:theID}}
	end repeat
end if

--do something with metaData - a list of records

end tell

Notes:

  • Of course the class requests here are just for illustration and do nothing.

  • It’s good practice to write scripts that don’t do unnecessary work. For example if currentSelection ≠ {}, there’s nothing to do.

  • The repeat loop iterates through the selected image(s), and adds their metadata to the list of records metaData. Otherwise you’d end up with just data for the last selected image.

Thanks! Especially for the really quick reply! I haven’t tried it yet, just wanted to say thanks. I’ll try it here in a little bit (making some dinner just now).

Thanks for the detailed explanation. I never would have twigged to the “list”! I’ve seen a number of examples for Photos that treat currentSelection like a list, but I didn’t pay attention to them, because I’m only expecting to use one photo at a time.

Many thanks, to both of you. Appreciate the really quick response, very awesome!

Dave

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.