Finding a file while in Photos

Photos for Mac 5.0 (Catalina) has broken photo imports, specifically it has chosen to change the filenames to ALL CAPS.

I have a custom script I’ve written that works within Photos, taking an imported photo with a filename like this:

19690716183000 Our Apollo 11 party.jpg

extracting the date and time from the first part, and then putting the title into the Title field in Photos. With this new version, unfortunately, the title from the imported photo now reads “OUR APOLLO 11 PARTY”.

My first solution was to force the title to Sentence case - which results in “Our apollo 11 party”, but then I have to manually go through and fix all of the titles that should have caps in them.

I considered this - while working on a photo from within Photos, find the source picture in the import folder, grab the title from there, and put that in the Title field of Photos.

Where I am having problems is with getting a proper path to the file so I can grab that non-caps photo title.

Here is a fragment of my code:


set inputFolder to "Thorin:users:a2history:Desktop:Import:"

repeat with i from 1 to count of imageSel
		
		set thePhoto to item i of imageSel
		
		-- Format of date in title is:
		-- "20070810140512 Title"
		-- which means August 10, 2007, 2:05:12 pm
		
		-- get filename of photo from within Photos
		set aTitle to filename of thePhoto
				
-- at this point, aTitle = "19550601120000 MIDLAND COLLEGE LIFETIME ATHLETIC PASS.JPG" 

		set fullPath to inputFolder & aTitle
		
		display dialog fullPath as text

-- this displays "Thorin:users:a2history:Desktop:Import:19550601120000 MIDLAND COLLEGE LIFETIME ATHLETIC PASS.JPG"
			
			set bTitle to name of (info for fullPath)
			set aPosix to quoted form of POSIX path of fullPath
		
		display dialog "bTitle='" & bTitle & "'" & return & "aPOSIX='" & aPosix & "'"

The first display dialog does execute, and shows the text listed in the code above.

The last display dialog never executes; instead, I see this error message:

FILE
Thorin:users:a2history:Desktop:Import:19550601120000 MIDLAND COLLEGE LIFETIME ATHLETIC PASS.JPG wasn’t found.

Finder got an error: File Thorin:users:a2history:Desktop:Import:19550601120000 MIDLAND COLLEGE LIFETIME ATHLETIC PASS.JPG wasn’t found. (-43)

What I want to do is get the original name of the file in the Import folder, the version that has not been capitalized. In this example the filename is “19550601120000 Midland College lifetime athletic pass.jpg”. I can use this to extract the correct photo title and put that info into the Title field in Photos.

Suggestions? Thanks in advance!

  1. The fullPath in your code is one HFS path, and HFS path is not file (that is, one numerical address to first byte of image file in the RAM), but already is a string (otherway named text). So here no need coercion as text.

So, replace

display dialog fullPath as text

with this

display dialog fullPath
  1. You wrote:
set bTitle to name of (info for fullPath)
set aPosix to quoted form of POSIX path of fullPath

I said already above that fullPath in your code isn’t file reference, but string (HFS path). And you should ask for the name not one string, but file reference. An alias keyword does needed coercion the string to file reference (of alias type, which is the most practical file reference in the AppleScript):

set bTitle to name of (info for alias fullPath)
set aPosix to quoted form of POSIX path of alias fullPath

So, to understand difference between file and it’s path: Only objects can provide you its properties. The file is one kind of the objects. Each object is identified by numerical address to its first byte in the RAM. The string (of plain AppleScript) is not object. It has not properties. So, it can’t provide you properties’s values. NOTE: The NSString of ASObjC is one object.

They are objects, and they do have properties. Although, you haven’t really defined what you mean by object. But in all the ways that something of class alias is an object, then so is something of class text. It’s quite a complex data structure, and infinitely self-referential: it contains other objects of class text, which all contain themselves; it has a length property and an id property; it has a class property and is a class object; and it belongs to the item superclass.

Also, contrary to what you stated, you don’t need an alias object or an explicit file reference in order to use info for or obtain a posix path, and a string will do. In the case of info for (and, I believe, most other Standard Additions commands that operate on a file), it understands posix paths but not HFS paths, because reasons. Therefore, this:

set bTitle to name of (info for fullPath)
set aPosix to quoted form of POSIX path of fullPath

is perfectly good AppleScript if fullPath is a path in posix notation, i.e./e.g.:

set fullPath to "Macintosh HD:Users:CK:Pictures:"

info for the fullPath's POSIX path --> {name:"Pictures", creation date:date "Wednesday, 8 July 2015 at 23:33:09", modification date:date "Thursday, 21 June 2018 at 15:54:24", size:5.0665468454E+10, folder:true, alias:false, package folder:false, visible:true, extension hidden:false, name extension:missing value, displayed name:"Pictures", default application:alias "Macintosh HD:System:Library:CoreServices:Finder.app:", kind:"Folder", folder window:{0, 0, 0, 0}, file type:"", file creator:""}

Hi, CK.

Regarding objects: by object I mean the same thing as all programmers. This is a copy (instance) of a specific piece of code on a disk (class) into RAM memory. Immediately after copying the code into RAM, the class becomes an object. It has certain properties, the values of which can be found out by requesting the object itself.

Therefore, I confess that I mistakenly called the [b]text[/b] (or [b]string[/b]) not an object. It would be more correct to say that the text does not have such properties as a file name or file size.

Regarding the info for the fullPath’s POSIX path. It is interesting. I confess frankly: I did not know that info for is so smart. Although this is a non-standard file access template, as I checked, it works.

I tested both instructions.

set fullPath to (path to pictures folder) as text
# case 1
info for file fullPath
log result (*name:Pictures, creation date:date mercredi 21 mai 2014 à  18:23:17, modification date:date mardi 29 octobre 2019 à  18:54:35, size:2.694024161E+9, folder:true, alias:false, package folder:false, visible:true, extension hidden:false, name extension:missing value, displayed name:Images, default application:alias SSD 1000:System:Library:CoreServices:Finder.app:, kind:Dossier, folder window:0, 0, 0, 0, file type:, file creator:*)
--or
# case 2
info for fullPath's POSIX path

--info for the fullPath's POSIX path --> {name:"Pictures", creation date:date "Wednesday, 8 July 2015 at 23:33:09", modification date:date "Thursday, 21 June 2018 at 15:54:24", size:5.0665468454E+10, folder:true, alias:false, package folder:false, visible:true, extension hidden:false, name extension:missing value, displayed name:"Pictures", default application:alias "Macintosh HD:System:Library:CoreServices:Finder.app:", kind:"Folder", folder window:{0, 0, 0, 0}, file type:"", file creator:""}

My boot volume is the SSD named “SSD 1000”.
Most of the infos returned by the first one are correct but the second are perfectly wrong.

Maybe it’s why the dictionary of Standard Additions states:
info for v : Return information for a file or folder
info for file : an alias or file reference to the file or folder

Of course here I would use :

set fullPath to path to pictures folder # return an alias

info for fullPath
--> {name:"Pictures", creation date:date "mercredi 21 mai 2014 à  18:23:17", modification date:date "mardi 29 octobre 2019 à  18:54:35", size:2.694024161E+9, folder:true, alias:false, package folder:false, visible:true, extension hidden:false, name extension:missing value, displayed name:"Images", default application:alias "SSD 1000:System:Library:CoreServices:Finder.app:", kind:"Dossier", folder window:{0, 0, 0, 0}, file type:"", file creator:""}

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 3 décembre 2019 18:59:35

I must add that, after running it several times,

set fullPath to path to pictures folder as text
info for fullPath's POSIX path

returned the correct infos. It seems that with practice, the system learnt what to do.
I will retry tomorrow after re-booting to see if the lesson is definitely learnt.

As long as you’re happy to rely on undocumented behavior, that’s true. But the same thing happened with commands in lots of applications, for the same reason, and it worked there too – until it didn’t, courtesy of sandboxing and security issues. Given the trend on anything that might be construed as involving security, I’m not sure relying on it is particularly good long-term strategy.

Thanks to all for your comments. I don’t really understand the concept of objects (my brain is stuck in the days of BASIC), so I don’t follow that part or grasp why it’s important.

Anyway, on trying the code changed as suggested to this:

set bTitle to name of (info for alias fullPath)
set aPosix to quoted form of POSIX path of alias fullPath

I still got an error before it can get to the second display dialog. Here is the code from the result screen in Script Editor:

error “Finder got an error: Can’t get POSIX path of document file "19550601120000 Midland College lifetime athletic pass.jpg" of folder "Import" of folder "Desktop" of folder "a2history" of folder "Users" of startup disk.” number -1728 from POSIX path of document file “19550601120000 Midland College lifetime athletic pass.jpg” of folder “Import” of folder “Desktop” of folder “a2history” of folder “Users” of startup disk

The most likely reason for this error to occur is that you have all the code wrapped in the tell “Photos” block. This confuses some AppleScript instructions. Better provide all your code so I can understand what you want to do. Then I can advise where it is better to tell to Photos, where tell to Finder, and where tell to Standard Additions.

Try my code (it is how I tested). We tell to Finder to display dialog to make display dialog window frontmost (for example, if we have the Safari window frontmost before running the script) :


set imageSel to choose file of type "jpg" with prompt "Select, please, the photos" with multiple selections allowed
tell application "Finder" to set inputFolder to (container of item 1 of imageSel) as string

repeat with i from 1 to count of imageSel
	set thePhoto to item i of imageSel
	tell application "Finder" to set aTitle to name of thePhoto
	set fullPath to inputFolder & aTitle
	
	tell application "Finder" to display dialog fullPath
	
	set bTitle to name of (info for alias fullPath)
	set aPosix to quoted form of POSIX path of alias fullPath
	
	tell application "Finder" to display dialog "bTitle='" & bTitle & "'" & return & "aPOSIX='" & aPosix & "'"
end repeat

Okay, I’ll include as much as I can (it’s a REALLY long script if I include it all):


set inputFolder to "Thorin:users:a2history:Desktop:Import:"

set theAlbumName to "DateFix" -- Hard code the name of the top-level album to scan and rename
-- zero these out
set imageSel to {}
set fullPath to ""
set aTitle to ""

tell application "Photos"
	activate
	
	--Check to see if the Album with photos to be changed exists
	try
		if exists container theAlbumName then
			set thePhotosBuffer to container theAlbumName
			set imageSel to every media item of thePhotosBuffer
		else
			error theAlbumName
			return
		end if
		
	on error errMsg number errNum
		display dialog "Zonker's Batch Date From Title" & return & return & "Album '" & errMsg & "' does not exist" & return & return & "(AppleScript error " & errNum & ")"
		return
	end try
	
	-- Okay, the album exists	
	
	display alert "Zonker's Batch Date From Title" message tab & return & "••• Preparing to process date and time •••" & return & "••• on " & (count of imageSel) & " photos in the " & theAlbumName & " folder •••"
	
	-- Now, loop through each subsequent image until COUNT is reached
	
	repeat with i from 1 to count of imageSel
		
		set thePhoto to item i of imageSel
		
		-- Format of date in title is:
		-- "20070810140512 Title"
		-- which means August 10, 2007, 2:05:12 pm
		
		-- get filename of photo
		set aTitle to filename of thePhoto
		
-- trying to find the original photo in the Finder folder
		set fullPath to inputFolder & aTitle
		
		display dialog fullPath -- this is here just to trace what is happening
		
		tell application "Finder"
			
			set bTitle to name of (info for alias fullPath)
			set aPosix to quoted form of POSIX path of alias fullPath
			
		end tell
		
		display dialog "bTitle='" & bTitle & "'" & return & "aPOSIX='" & aPosix & "'" -- this is also here just to trace what is happening

-- If this did what I want it to do, I now have the original filename of the photo from 
-- the Finder, the filename with the proper upper and lower case for the the photo title

		-- Characters 1 - 14 of the filename are the encoded date string
		-- Character 15 should be a blank
		-- Characters 16 through the file extension are for the title/name/description of the photo
		
		-- this flips the filename around in a temp variable
		set tmpFileName to (the reverse of every character of bTitle) as string
		-- this counts letters in the filename and then subtracts the count of the extension
		set myLength to (length of bTitle) - the (offset of "." in tmpFileName)
		-- This sets the name in Photos to the file name minus the extension (.jpg, .jpeg, .gif...etc)
		set bTitle to characters 1 thru myLength of bTitle as text
		
		-- pad the end with two blanks if there is no text after the encoded date
		if myLength < 15 then set bTitle to bTitle & "  "
		
		-- remove date from title
		-- (Note that if original filename did NOT have a title, the title will now be a single blank)
		set newTitle to characters 16 thru -1 of bTitle as string
		
		-- change the title of this photo
		set the name of thePhoto to newTitle as text
		
	end repeat
	
end tell
return

It isn’t so simple.
The Photos has media items instead of file references. So, you should make some manipulations. I wrote the code, but since I don’t have folder “Import” with your photos, it is better if you test my code on your machine. Maybe you will found other bugs:


set theAlbumName to "DateFix"
set inputFolder to ((path to desktop folder) as string) & "import:"
set photosLibrary to alias (((path to pictures folder) as string) & "Photos Library.photoslibrary:")
set {imageSel, fullPath, aTitle} to {{}, "", ""}
tell application "Finder" to set photosMasterFolder to folder "Masters" of photosLibrary

--Check to see if the Album with photos to be changed exists
tell application "Photos"
	activate
	try
		set thePhotosBuffer to container theAlbumName
	on error errMsg number errNum
		display dialog "Zonker's Batch Date From Title" & return & return & "Album '" & errMsg & "' does not exist" & return & return & "(AppleScript error " & errNum & ")"
		return
	end try
	set mediaItems to every media item of thePhotosBuffer
	set imageSelNames to filename of every media item of thePhotosBuffer
end tell

tell me to activate
display alert "Zonker's Batch Date From Title" message tab & return & "••• Preparing to process date and time •••" & return & "••• on " & (count of imageSel) & " photos in the " & theAlbumName & " folder •••"

-- Get Finder alias file references to photos
set imageSel to {}
repeat with aFileName in imageSelNames
	tell application "Finder" to set imageFile to ((first file of entire contents of photosMasterFolder) whose name contains aFileName)
	set imageFile to (imageFile as alias)
	if imageFile is not in imageSel then set imageSel to imageSel & imageFile
end repeat

-- Now, loop through each subsequent image until COUNT is reached
repeat with i from 1 to count of imageSel
	set thePhoto to item i of imageSel
	
	-- get filename of photo
	set aTitle to item i of imageSelNames
	
	-- trying to find the original photo's name in the Finder folder
	set fullPath to inputFolder & aTitle
	tell application "Finder" to display dialog fullPath
	set bTitle to name of (info for alias fullPath)
	set aPosix to quoted form of POSIX path of alias fullPath
	tell application "Finder" to display dialog "bTitle='" & bTitle & "'" & return & "aPOSIX='" & aPosix & "'"
	
	-- change the title of this photo
	set newTitle to ((characters 1 thru 14 of bTitle) as string) & " "
	tell application "Photos" to set the name of (item i of mediaItems) to newTitle
end repeat

NOTE: I see yet here many unneeded operations.

KniazidisR, thanks for looking at this.

I am unclear as to why you included this line:

tell application “Finder” to set photosMasterFolder to folder “Masters” of photosLibrary

On trying this, I get an error there, and when I look into the package contents for the Photos Library, there is no folder with that name (probably why if fails). There is a folder “Masters.legacy”, but I know it does not contain all of the photos for the library.

Maybe I’m not being clear about what I’m trying to do. The script that manipulates the metadata (time, date, title) for Photos does work already. It’s the problem with the photo title that I am trying to massage here.

The work flow I am trying to create is:

  1. Drag photo(s) into the DateFix folder in Photos for Mac

  2. With the Applescript, Extract the date and time from the filename for that photo, and put it into the date and time fields in Photos. (This part works already, and I excluded that from the code that I posted here just because is is so long, and because it works).

  3. The original script at this point extracted the title from the filename for the photo it was processing in Photos for Mac, and put that into the Title field of Photos for Mac. Because Photos 5.0 BROKE this by capitalizing the filename, I want to find the original file in the Import folder in the Finder, get that filename, strip off the date/time characters, and put THAT title into the Title field in Photos. I don’t need to or want to mess with the files within the Photos Library package, beyond automating the editing of the date, time and title fields for a particular photo.

For that reason, I don’t think I want to manipulate the files within the Photos Library package; I just want to script getting the filename of the original from that Import folder in the Finder, and put that title into the Title field in Photos.

Does that help?

OK, no need desktop folder, no need dragging the photos for this task, no need activate Photos, no need Finder, since no need finding a file while in Photos. As I say already, Photos works, and works fine, with media items, not with files:


set theAlbumName to "DateFix"

tell application "Photos"
	--Check to see if the Album with photos to be changed exists
	try
		set thePhotosBuffer to container theAlbumName
	on error errMsg number errNum
		display dialog "Zonker's Batch Date From Title" & return & return & "Album '" & errMsg & "' does not exist" & return & return & "(AppleScript error " & errNum & ")"
		return
	end try
	-- Set title of each photo to its stripped filename
	set mediaItems to every media item of thePhotosBuffer
	repeat with aMedia in mediaItems
		set aFileName to filename of aMedia
		set newTitle to ((characters 1 thru 14 of aFileName) as string) & " "
		set name of aMedia to newTitle
	end repeat
end tell

I’m puzzled by what you wrote because here it works flawlessly.

set photosLibrary to alias (((path to pictures folder) as string) & "Photos Library.photoslibrary:")

tell application "Finder" to set photosMasterFolder to folder "Masters" of photosLibrary
--> folder "Masters" of document file "Photos Library.photoslibrary" of folder "Pictures" of folder "**********" of folder "Users" of startup disk of application "Finder"

For my own use I would code:

set photosLibrary to (((path to pictures folder) as string) & "Photos Library.photoslibrary:")
set photosMasterFolder to (photosLibrary & "Masters:") as alias
--> alias "SSD 1000:Users:**********:Pictures:Photos Library.photoslibrary:Masters:"

Back to your very first message, what would return the script :

set inputFolder to "Thorin:users:a2history:Desktop:Import:"

set aTitle to "19550601120000 MIDLAND COLLEGE LIFETIME ATHLETIC PASS.JPG"

set fullPath to inputFolder & aTitle
try
	fullPath as alias
on error errMsg
	log errMsg
end try

tell application "Finder"
	name of files of folder inputFolder
end tell

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) jeudi 5 décembre 2019 19:46:44

I believe I am still not making myself clear. Let me see if I can better explain the workflow.

I scan many photos, and I put a date and name on the filename for each photo. For the sake of this example, I am putting the scanned pictures into a folder named “Imports”, located on the Desktop.

I drag these scanned photos into Photos, specifically into a folder called DateFIx.

I run my script in Photos, it takes the filename of each photo in the DateFix folder, puts that info into the date and time fields for that photo, and also takes the title in the filename past the date/time numbers, and puts that into the title for that photo.

So, for the file named “19690725180000 Our Apollo 11 party.jpg” that was imported to Photos, it puts July 25, 1969 into the date field in Photos, and 18:00:00 into the time field in Photos. It would put “Our Apollo 11 party” into the title field.

The script still works correctly in Photos 5.0. But the filename for this picture after being imported to Photos 5.0 reads “19690725180000 OUR APOLLO 11 PARTY.JPG” This was broken on this update.

S at this point, I have a file within Photos named “19690725180000 OUR APOLLO 11 PARTY.JPG”, and the original file in the Import folder, named “19690725180000 Our Apollo 11 party.jpg”.

I do not want “OUR APOLLO 11 PARTY”, I want “Our Apollo 11 party”.

Since I do have the original file with the correct title, what I want to do is to FIND that file, outside of Photos, using the Finder, get that name, and put THAT title, “Our Apollo 11 party” into the title field of that photo in Photos.

So, THIS is the reason that I do need to use the Import folder in the Finder, and to have a working path to that file, that ORIGINAL file, in order to get the non-uppercase title.

I feel like it should be something simple and straightforward, taking the created path from within Photos, “Thorin:users:a2history:Desktop:Import:19690725180000 OUR APOLLO 11 PARTY.JPG” to get ask Finder to give back to me the full ORIGINAL path “Thorin:users:a2history:Desktop:Import:19690725180000 Our Apollo 11 Party.jpg”. Once I’ve got that, I can extract the title from that, and put that into Photos, instead of what I get from Apple’s broken Photos 5.0.

Does that explain it better?

As for this code:

set photosLibrary to alias (((path to pictures folder) as string) & "Photos Library.photoslibrary:")

tell application "Finder" to set photosMasterFolder to folder "Masters" of photosLibrary
--> folder "Masters" of document file "Photos Library.photoslibrary" of folder "Pictures" of folder "**********" of folder "Users" of startup disk of application "Finder"

it does not work for me, because the folder within Photos Library.photoslibrary on my computer is named “Masters.legacy”, and not “Masters”. But even if I renamed the place in this script to “Masters.legacy”, it does not contain any photos; it has a lot of files with “attr” XML data within it.