Tuesday, September 27, 2022

#1 2022-09-19 04:42:51 am

MrCee
Member
Registered: 2016-07-01
Posts: 18

Get NSURLContentModificationDateKey from array of NSURL's

Hey All,

I'd like to try retrieving NSURLContentModificationDateKey from an array of NSURL's with the end result being an NSDictionary with the POSIX path as key and NSURLContentModificationDateKey as the value.

If I'm using Music.app I'm starting out as per the below, and also I'd like to know if there is an option for building lists using 'script o'? I should be able to figure that out after I can get an NSArray/NSDictionary of NSURLContentModificationDateKey. If I can get pass this hurdle I'll hopefully be able to see which method is faster if 'script o' is possible...

Applescript:


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

tell application "Music"
   set trackNSURL to (current application's NSArray's arrayWithArray:(get location of every file track of library playlist 1))
   set trackPosixPath to trackNSURL's valueForKey:"path"
   set lastModifiedDict to current application's NSDictionary's dictionaryWithObjects:"***NSURLContentModificationDateKey goes here***" forKeys:trackPosixPath    
end tell

Thanks!

Last edited by MrCee (2022-09-19 04:50:19 am)

Offline

 

#2 2022-09-19 08:22:59 am

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

Re: Get NSURLContentModificationDateKey from array of NSURL's

MrCee wrote:

I'd like to try retrieving NSURLContentModificationDateKey from an array of NSURL's with the end result being an NSDictionary with the POSIX path as key and NSURLContentModificationDateKey as the value.



MrCee. The following should do what you want. I don't use the Music app, so I used Finder to get the files. You're probably aware of this, but you have to append "of me" if the handler is called from within the Music tell statement.

Applescript:

use framework "Foundation"
use scripting additions

set theFiles to (choose file with multiple selections allowed) -- a list of aliases
set theFiles to current application's NSArray's arrayWithArray:theFiles -- an array of URLs

set lastModifiedDic to getDictionary(theFiles)

on getDictionary(theFiles)
   set theDates to current application's NSMutableArray's new()
   repeat with aFile in theFiles
       set {theResult, aDate} to (aFile's getResourceValue:(reference) forKey:(current application's NSURLContentModificationDateKey) |error|:(missing value))
       (theDates's addObject:aDate)
   end repeat
   set thePaths to theFiles's valueForKey:"path"
   set theDictionary to current application's NSDictionary's dictionaryWithObjects:theDates forKeys:thePaths
end getDictionary

Last edited by peavine (2022-09-20 03:04:07 pm)


2018 Mac mini - macOS Monterey - Script Debugger 8

Offline

 

#3 2022-09-23 11:33:31 pm

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

Re: Get NSURLContentModificationDateKey from array of NSURL's

Pretty sure the iTunesFileTrack class has a
Modified Date property you can access as well.

NSObject has a function dictionaryWithValuesForKeys
https://developer.apple.com/documentati … uesforkeys

You could apply that to each track and then recreate
Your own dictionary from that dictionary (remap)

Last edited by technomorph (2022-09-23 11:41:14 pm)

Offline

 

#4 2022-09-24 10:05:56 am

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

Re: Get NSURLContentModificationDateKey from array of NSURL's

technomorph wrote:

Pretty sure the iTunesFileTrack class has a
Modified Date property you can access as well.



That is much simpler and takes the same amount of time.

Applescript:

use framework "Foundation"
use scripting additions

tell application "Music" to set {theFiles, theDates} to {location, modification date} of every file track of library playlist 1
set theFiles to (current application's NSArray's arrayWithArray:theFiles)'s valueForKey:"path"
set theDictionary to current application's NSDictionary's dictionaryWithObjects:theDates forKeys:theFiles

Last edited by peavine (2022-09-24 02:20:25 pm)


2018 Mac mini - macOS Monterey - Script Debugger 8

Offline

 

#5 Today 04:27:58 am

MrCee
Member
Registered: 2016-07-01
Posts: 18

Re: Get NSURLContentModificationDateKey from array of NSURL's

Hey, thanks so much, guys; it works well.

At the time, I was working on optimising the refresh part of a script to only refresh tags that were recently modified.  In iTunes/Music.app, most of us have all seen the code to refresh all tracks in the GUI should the tags have been modified in another app. This takes forever (this is likely to be as just tested a 1 hour + 50 minute process) with over 15,000 tracks:

Applescript:


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

tell application "Music"
set allTracks to (get every file track of library playlist 1)
   repeat with aTrack in allTracks
       try
           refresh aTrack
       end try
   end repeat
end tell

I'm not sure if what I'm seeing now is new; if anyone can shed some light, that would be great.

To refresh all tags in iTunes/Music.app across 15,000 tracks on Monterey, this code will do the trick in about 50 seconds. The GUI is fully updated in a flash, not each record at a time.
I've been getting the location of all tracks using this method for years but never thought to put this first above any refresh commands....

Applescript:


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

tell application "Music"
   set trackLocation to current application's NSArray's arrayWithArray:(get location of every file track of library playlist 1)
end tell

Is it just me discovering this now, or is this new?
I have tested with Traktor and mp3tag updates, and any updates to a usual iTunes/Music.app tag field is picked up and reflected in the iTunes/Music.app GUI in an approximately 50-second, one update flash once the array has been built.

Last edited by MrCee (Today 06:56:25 am)

Offline

 

#6 Today 07:52:07 am

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

Re: Get NSURLContentModificationDateKey from array of NSURL's

MrCee wrote:

At the time, I was working on optimising the refresh part of a script to only refresh tags that were recently modified.



MrCee. I don't know the answer to your question regarding tags.

FWIW, the following script date-limits the tracks that are refreshed. I only have 1 playlist with 3 songs, so it's hard to know for certain if this script works correctly. The dialog is for testing purposes only and would be removed in actual use.

Applescript:

set refreshDate to (current date) - 100 * days -- date after which to refresh

tell application "Music"
   set theFileTracks to every file track of library playlist 1
   repeat with aFileTrack in theFileTracks
       set theModificationDate to modification date of aFileTrack
       if theModificationDate > refreshDate then
           display dialog "A track with a modification date of " & (theModificationDate as text) & " will be updated"
           refresh aFileTrack
       end if
   end repeat
end tell


2018 Mac mini - macOS Monterey - Script Debugger 8

Offline

 

#7 Today 08:04:45 am

MrCee
Member
Registered: 2016-07-01
Posts: 18

Re: Get NSURLContentModificationDateKey from array of NSURL's

@peavine that seems to be the exact method I was testing with your suggestion. But it seems we can get the job done in one sweep without a repeat loop now. Potentially?  Previously accurate data across 15,000 track tags were never accurate without the repeat loop. Something has changed, I'm sure.

@technomorph, any chance you could please test this across your collection should a tag be updated in another app?

I see every tag in the iTunes/Music.app GUI update in a second using simply this...

Applescript:


tell application "Music"
-- This updates the GUI faster than a repeat loop, and therefore there is no need to consider last modified dates
set trackLocation to current application's NSArray's arrayWithArray:(get location of every file track of library playlist 1)
end tell

Last edited by MrCee (Today 08:14:13 am)

Offline

 

#8 Today 08:14:57 am

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

Re: Get NSURLContentModificationDateKey from array of NSURL's

MrCee wrote:

@peavine that seems to be the exact method I was testing with your suggestion. But it seems we can get the job done in one sweep without a repeat loop now. Potentially?  Previously accurate data across 15,000 track tags were never accurate without the repeat loop. Something has changed, I'm sure.... I see every tag in the iTunes/Music.app GUI update in a second using simply this...



MrCee. The Music app dictionary defines the refresh command as:

update file track information from the current information in the track’s file



I'm not able to test this, but I would question whether running the refresh command and updating tags (by whatever method) perform the same task. If all you want to do is update tags, then it appears you've found a great solution.

BTW, if the repeat loop is a concern, you might try the following, which appears to work in my testing. It almost certainly will be slow compared with updating tags, though.

Applescript:

set refreshDate to (current date) - 100 * days -- date after which to refresh

tell application "Music"
   refresh (every file track of library playlist 1 whose modification date is greater than refreshDate)
end tell

Last edited by peavine (Today 09:57:18 am)


2018 Mac mini - macOS Monterey - Script Debugger 8

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)