Wednesday, February 14, 2024

AppleScript to very slowly list the albums a macOS Photos.app image is associated with

macOS Photos.app does not give users a way to identify which albums contain a selected photo. I found a relatively current AppleScript that works in Ventura; in our broken world there's no repository for these things so I've copied it below. You can select a photos then run the script in ScriptEditor or Export as application and run after selecting an image. On a 2023 Air with a large complex library it takes about 40 seconds to show results.

If you wish you can wrap the AppleScript in a Shortcuts.app Shortcut and from there configure it to show in the Ventura Services menu (all shortcuts can appear there).
 
Please submit a feedback request to Apple. Obviously Photos.app should support this function. Sadly, I suspect Apple goes by its usage data and has learned that most users of Photos do not use or create Albums -- or add any kind of metadata to images. So it will probably never be fixed.

Source: https://discussions.apple.com/docs/DOC-250005659
Author: Jacques Rioux, leonie

-- Jacques Rioux's script  https://discussions.apple.com/message/29601534#29601534

-- modified by leonie for Catalina

--  version 1.01, changed a dialog to a notification

-- version 2, added the support to suppress smart albums


-- Select the photo in Photos, then run this script 

-- by pressing the "Run" button in the script editor 

-- or run it from the scripts menu.

-- The script will show first a panel with the filename of the photo it is searching for.

-- Then it will show a second panel with the list of albums. 

-- if you do not see the panels, click the script Editor icon in the Dock, if it is bouncing.


global allalbums -- the list of all albums

global allfolders -- the list of all folders



set NoSmartAlbums to true -- set this to false, if you want to find the smart albums too


--part 1. get the selected photos

tell application "Photos"

activate

-- Add the photo you want to search for to a top level album as the first item in the album

set resultcaption to "Searching for: "

try

set sel to selection

if sel is {} then error "The selection  is empty" -- no selection 

on error errTexttwo number errNumtwo

display dialog "No photos selected " & errNumtwo & return & errTexttwo

return

end try

set imagename to "unknown filename"

try

set target to item 1 of sel -- the image to seach for

tell target

set imagename to the filename of target

end tell

on error errTexttwo number errNumtwo

display dialog "Cannot get the filename of the first image: " & errNumtwo & return & errTexttwo

end try

set resultcaption to (resultcaption & imagename)

end tell



display notification resultcaption subtitle imagename


-- Part 2: get a list of all albums by searching the nested folders

set allfolders to {}

set allalbums to {}



tell application "Photos"

set allalbums to the albums --  collect all albums

set allfoldernames to {}

set allalbumnames to {}

set level to 0 -- nesting level of folders

set nextlevelFolders to the folders

set currentLevelFolders to {}

repeat while (nextlevelFolders is not {})

set currentLevelFolders to nextlevelFolders

set nextlevelFolders to {}

repeat with fi in currentLevelFolders

tell fi

set ffolders to its folders

set falbums to its albums

set nextlevelFolders to ffolders & nextlevelFolders

set allalbums to falbums & allalbums

end tell

end repeat

set allfolders to currentLevelFolders & allfolders

set level to level + 1

end repeat

-- return allalbums --test

end tell


-- removing albums with "smart" in the name

if NoSmartAlbums then

set without_smart_Albums to {}

repeat with a in allalbums

if (the name of a does not contain "smart") then set without_smart_Albums to {a} & without_smart_Albums

end repeat

set allalbums to without_smart_Albums -- to exclude smart albums 

end if


-- From Jacques Rioux's script:

tell application "Photos"

if sel is {} then return -- no selection 

try

set thisId to id of item 1 of sel

on error errText number errNum

display dialog "Error: cannot get the image ID" & errNum & return & errText & "Trying again"

try

delay 1

set thisId to id of item 1 of sel

on error errTexttwo number errNumtwo

display dialog "Skipping image due to repeated error: " & errNumtwo & return & errTexttwo

error "giving up"

return

end try --second attempt

end try

set theseNames to {}

repeat with a in allalbums

try

tell a

if ((the id of media items) contains thisId) then

set theseNames to {the name of a} & theseNames

end if

end tell

--set theseNames to name of (albums whose id of media items contains thisId)

on error errText number errNum

display dialog "Error: cannot get the albums" & errNum & return & errText & "Trying again"

try

delay 1

tell a

if ((the id of media items) contains thisId) then

set theseNames to {the name of a} & theseNames

end if

end tell

on error errTexttwo number errNumtwo

display dialog "Skipping image due to repeated error: " & errNumtwo & return & errTexttwo

error "giving up"

return

end try

end try

end repeat

end tell


if theseNames is not {} then

set {oTid, text item delimiters} to {text item delimiters, return}

set {t, text item delimiters} to {theseNames as string, oTid}

-- return oTid

else

set t to "No album"

end if

activate


set resultcaption to resultcaption & ", found it in these albums:

" & t as string

set the clipboard to resultcaption

display notification resultcaption subtitle "Saved to the Clipboard"


display dialog resultcaption & ", Saved to the Clipboard" buttons {"OK"} default button "OK"

-- you can press the Enter key or the return Key to close the dialog

return resultcaption -- léonie