Tuesday, September 27, 2022

#1 2022-06-30 07:17:22 pm

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 1458

Error when obtaining metadata from files

I've been working on a script that sorts and moves digital photos by orientation and have given up for now. The line that begins "set itemOrientation" occasionally returns missing value when clearly it shouldn't. Anyways, I thought I'd post the handler just in case someone could spot some error.

BTW, this issue seems to arise most often when the file or files have just been copied to theFolder, and I have to wonder if the issue arises due to a delay in updating the metadata. I added some one-second delays to the script but that did not resolve the issue, and, unfortunately, my knowledge of this topic is quite limited. Thanks for the help.

Applescript:

on getFiles(theFolder, theOrientation)
   set fileManager to current application's NSFileManager's defaultManager()
   set theFolder to current application's |NSURL|'s fileURLWithPath:(POSIX path of theFolder)
   set folderContents to fileManager's contentsOfDirectoryAtURL:theFolder includingPropertiesForKeys:{} options:4 |error|:(missing value)
   set thePredicate to current application's NSPredicate's predicateWithFormat:"pathExtension ==[c] 'jpg'"
   set folderContents to folderContents's filteredArrayUsingPredicate:thePredicate
   
   set theFiles to current application's NSMutableArray's new()
   repeat with anItem in folderContents
       set mdItem to (current application's NSMetadataItem's alloc()'s initWithURL:anItem)
       set itemOrientation to (mdItem's valueForAttribute:"kMDItemOrientation")
       if (itemOrientation is not missing value) then
           if (itemOrientation's isEqualToNumber:theOrientation) as boolean is true then (theFiles's addObject:anItem)
       end if
   end repeat
   return theFiles as list
end getFiles

Last edited by peavine (2022-06-30 07:21:24 pm)


2018 Mac mini - macOS Monterey - Script Debugger 8

Offline

 

#2 2022-07-01 07:27:47 am

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 1458

Re: Error when obtaining metadata from files

I found the issue. The digital photo is on an external SSD, and this drive is not reliably indexed, which appears to be a known issue with Monterey. I checked all Spotlight and read/write settings and forced reindexing of the drive, but this didn't help.


2018 Mac mini - macOS Monterey - Script Debugger 8

Offline

 

#3 2022-07-01 01:29:31 pm

KniazidisR
Member
From:: Greece
Registered: 2019-03-03
Posts: 2524

Re: Error when obtaining metadata from files

You should provide variable theOrientation as NSNumber 0 or NSNumber 1. Then compare the NSIntegers this way:

Applescript:


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

set theFolder to choose folder
my getFiles(theFolder, 0) -- get landscape images

on getFiles(theFolder, theOrientation)
   -- coerce integer to NSNumber (NSNumber 0 = Landscape, NSNumber 1 = Portrait)
   set theOrientation to current application's NSNumber's numberWithInteger:0 -- ADDED
   set fileManager to current application's NSFileManager's defaultManager()
   set theFolder to current application's |NSURL|'s fileURLWithPath:(POSIX path of theFolder)
   set folderContents to fileManager's contentsOfDirectoryAtURL:theFolder includingPropertiesForKeys:{} options:4 |error|:(missing value)
   set thePredicate to current application's NSPredicate's predicateWithFormat:"pathExtension ==[c] 'jpg'"
   set folderContents to folderContents's filteredArrayUsingPredicate:thePredicate
   set theFiles to current application's NSMutableArray's new()
   repeat with anItem in folderContents
       set mdItem to (current application's NSMetadataItem's alloc()'s initWithURL:anItem)
       set itemOrientation to (mdItem's valueForAttribute:"kMDItemOrientation")
       if (itemOrientation's isEqualToNumber:theOrientation) then (theFiles's addObject:anItem) -- EDITED
   end repeat
   return theFiles as list
end getFiles

Last edited by KniazidisR (2022-07-01 01:42:35 pm)


Model: MacBook Pro
OS X: Catalina 10.15.7
Web Browser: Safari 14.1
Ram: 4 GB

Offline

 

#4 2022-07-01 02:41:00 pm

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 1458

Re: Error when obtaining metadata from files

KniazidisR. Thanks for looking at my post and for the suggestion. I tested your script with a test photo, and it worked correctly if the photo is on my boot drive but returns the following error if the photo is on my external SSD:

missing value doesn’t understand the “isEqualToNumber_” message.

Last edited by peavine (2022-07-01 03:43:33 pm)


2018 Mac mini - macOS Monterey - Script Debugger 8

Offline

 

#5 2022-07-01 07:48:00 pm

technomorph
Member
Registered: 2017-12-14
Posts: 279

Re: Error when obtaining metadata from files

Have a look at this page where they discuss how MetaData is lazyily fetched and they
Show how to use the AVSynchronus Loading protocol:

https://developer.apple.com/documentati … guage=objc

This is by using the AVFoundation framework.
And creating a AVAsset, NSURLAsset.
Since your already working with a NSURL I would create
A NSURLAsset as it’s super easy from a NSURL.

The you can provide specific keys that you
want to load asynchronously.  You can then Check the status of the
Loading to make sure it was fetched before you get the value.

https://developer.apple.com/documentati … guage=objc

Offline

 

#6 2022-07-01 07:57:48 pm

technomorph
Member
Registered: 2017-12-14
Posts: 279

Re: Error when obtaining metadata from files

The other route you wanna look into is NSMetaDataQuery
I believe Shane also has an appleScriptLib too
https://forum.latenightsw.com/t/spotlig … ibrary/688


https://developer.apple.com/documentati … guage=objc

This will allow you to also set a predicate so that
It only finds certain items (ie: shootDate, photoSize etc)

When you creat the query you also provide a list of keys
That are prefetched for you.  (ie: photoRotation, isLandscape etc)

Once you create the query. And then start it.
It does it’s own synchronous loading and you
Just have to adapt to its KVO protocol to be
Notified when it’s gathered data, finished gathering,
Failed etc

Last edited by technomorph (2022-07-01 08:05:06 pm)

Offline

 

#7 2022-07-02 08:13:10 am

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 1458

Re: Error when obtaining metadata from files

technomorph. Thanks for the posts and suggestions.

I had previously come to the tentative conclusion that indexing on my external drive was broken, but the idea that metadata on this drive is lazily fetched is probably the more reasonable conclusion. This doesn't appear to be the case with the boot drive where my script returns the photo files under all circumstances.

I did test Shane's metadata lib script library and did a minor rewrite of a section of Shane's script, but neither recognized photos recently added to my external drive. Prefetching the required metadata seems a great idea, but I think that's a bit beyond my current knowledge level (at least based on the referenced documentation). I also tested the mdfind shell command, but it did not resolve this issue.

Applescript:

use framework "Foundation"
use scripting additions

set theFolder to POSIX path of (choose folder)
set thePredicate to "(kMDItemOrientation == 1) AND (kMDItemFSName ENDSWITH[c] '.jpg')"
set theFiles to getFiles(theFolder, thePredicate)

on getFiles(theFolder, thePredicate)
   set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
   set thePredicate to current application's NSPredicate's predicateWithFormat:thePredicate
   set theQuery to current application's NSMetadataQuery's new()
   theQuery's setSearchScopes:{theFolder}
   theQuery's setPredicate:thePredicate
   theQuery's startQuery()
   repeat while theQuery's isGathering() as boolean
       delay 0.01
   end repeat
   theQuery's stopQuery()
   set theCount to theQuery's resultCount()
   set theFiles to current application's NSMutableArray's array()
   repeat with i from 0 to (theCount - 1)
       set aResult to (theQuery's resultAtIndex:i)
       set thePath to (aResult's valueForAttribute:"kMDItemPath")
       (theFiles's addObject:thePath)
       -- if ((thePath's stringByDeletingLastPathComponent())'s isEqualToString:(theFolder's |path|())) as boolean is true then (theFiles's addObject:thePath) -- instead of above to not recurse
   end repeat
   return theFiles
end getFiles

Last edited by peavine (2022-07-03 08:40:37 am)


2018 Mac mini - macOS Monterey - Script Debugger 8

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)