ventura – Use Applescript to set a Music app playlist’s View Choices?

0
29
ventura – Use Applescript to set a Music app playlist’s View Choices?


I wrote an AppleScript that works 95% of the time for me with Catalina.

You may select any playlist as your supply (besides “Songs”) and apply the formatting to any playlist or folder.

Some playlists do not reply; they appear to be corrupted within the Music Library, and the one answer I may discover was to create a brand new playlist with a barely completely different title and duplicate the tracks over.

-- Conform Columns for Apple Music
-- Model 1.0
-- Created by Bret Barker 04/01/2024

-- This script asks for a supply playlist in Apple Music
--      and applys the column settings to chosen playlists (and folders).

-- You may't use a folder or the "Songs" playlist as a supply
--      (they lack the track index column).

-- You may apply adjustments to playlists, folders, and the "Songs" playlist.

-- If a playlist will not conform, there's something mistaken with it within the
--      Music Library database.

-- Resolution: create a brand new playlist (good or dumb) with a barely completely different
--      title and duplicate the tracks to it.


use AppleScript model "2.4" -- Yosemite (10.10) or later
use scripting additions
use framework "Basis"

set prefs_path to POSIX path of (path to preferences) & "com.apple.Music.plist"
set playlist_name_list to {}
set playlist_choose_list to {}
set change_name_list to {}
set playlist_ID_list to {}

set d to "This script copies a playlist’s column formatting to different playlists.
        
First, the Music software must stop and relaunch to save lots of column settings."

attempt
    set dialogAnswer to show dialog d buttons {"Cancel", "Go Forward"} ¬
        default button "Go Forward"
    
    -- restart Music to save lots of column prefs
    if button returned of dialogAnswer is "Go Forward" then
        inform software "Music" to stop
        delay 1
        inform software "Music" to activate
        
        repeat till software "Music" is working
            delay 0.5
        finish repeat
        
    finish if
    
on error quantity -128 -- userCanceledErr
    return
finish attempt


inform software "Music"
    activate
    
    -- get LIB ID
    set library_source to the supply named "Library"
    set lib_ID to my toLowerCase(persistent ID of library_source)
    
    set playlist_list to a reference to each person playlist in library_source
    
    -- construct listing of all playlists, listing of names, and listing of IDs
    repeat with the_playlist in playlist_list
        set playlist_name to call of the_playlist
        set playlist_ID to my toLowerCase(persistent ID of the_playlist)
        
        -- search for folders containing playlists
        set path_list to {}
        set tmp to the_playlist
        
        repeat whereas exists mum or dad of tmp
            set the_playlist_parent to mum or dad of tmp
            set parent_name to call of the_playlist_parent
            set parent_ID to my toLowerCase(persistent ID of the_playlist_parent)
            
            -- save title and ID to listing
            copy {parent_name, parent_ID} to starting of path_list
            set tmp to the_playlist_parent
        finish repeat
        
        -- construct listing of folders and sub-folders
        if path_list ≠ {} then
            set path_string to ""
            
            repeat with x in path_list
                set parent_name to merchandise 1 of x
                set the_ID to merchandise 2 of x
                
                -- base folder
                if path_string = "" then
                    set path_string to parent_name
                else
                    -- subfolders are separated by " > "
                    set path_string to path_string & " > " & parent_name
                finish if
                
                -- copy folders and sub-folders to remaining listing, add colon
                set tmp to (path_string & ":") as textual content
                if tmp will not be in playlist_name_list then
                    copy tmp to finish of playlist_name_list
                    copy the_ID to finish of playlist_ID_list
                finish if
            finish repeat
            
            -- add playlist to folder path
            copy path_string & " > " & playlist_name to finish of playlist_name_list
            copy path_string & " > " & playlist_name to finish of playlist_choose_list
            copy playlist_ID to finish of playlist_ID_list
            
            
            --  ELSE add playlist with out folder
        else
            if playlist_name = "Music" then
                set playlist_name to "Songs"
            else
                -- preserve "Music/Songs" out of supply select listing
                copy playlist_name to finish of playlist_choose_list
            finish if
            
            -- add "Music/Songs" and others to full listing
            copy playlist_name to finish of playlist_name_list
            copy playlist_ID to finish of playlist_ID_list
            
        finish if
    finish repeat
    
    
    -- select the supply playlist
    set the_list to select from listing playlist_choose_list ¬
        with immediate "Which playlist has the proper column format?"
    if the_list is fake then return -- stop if no choice
    
    set source_playlist to merchandise 1 of the_list
    
    -- get ID of supply playlist
    set item_index to my firstIndexOf(source_playlist, playlist_name_list)
    set playlist_ID to merchandise item_index of playlist_ID_list
    
    -- learn settings of supply playlist
    set source_settings to do shell script "defaults learn '" & prefs_path ¬
        & "' '" & "PPr4:LIB:" & lib_ID & ":" & playlist_ID & "' "
    
    -- change view to "as Songs" for goal playlists
    set source_settings to my regexReplace(source_settings, ¬
        "viewModeForPlaylist = d+", "viewModeForPlaylist = 4")
    
    
    -- take away supply playlist from listing of goal playlists
    repeat with tmp in playlist_name_list
        set tmp_playlist to tmp as textual content
        if tmp_playlist ≠ source_playlist then
            copy tmp_playlist to finish of change_name_list
        finish if
    finish repeat
    
    -- select goal playlists to alter
    set target_playlists to select from listing change_name_list ¬
        with immediate "Which playlist(s) to alter?" with a number of alternatives allowed
    if target_playlists is fake then return -- stop if no choice
    
    
    -- stop Music to save lots of adjustments to prefs file
    set d to "The Music software will shut and re-open to use the adjustments."
    attempt
        set dialogAnswer to show dialog d buttons {"Cancel", "Go Forward"} ¬
            default button "Go Forward"
        
    on error quantity -128 -- userCanceledErr
        return
    finish attempt
    
    stop
finish inform

-- anticipate file write
delay 1

-- write chosen settings to the "com.apple.Music.plist" prefs file
--      utilizing IDs of goal playlists
repeat with the_target_name in target_playlists
    -- get index of goal in ID listing
    set item_index to my firstIndexOf(the_target_name, playlist_name_list)
    set playlist_ID to merchandise item_index of playlist_ID_list
    
    -- write prefs
    do shell script "defaults write '" & prefs_path & "' '" & "PPr4:LIB:" & lib_ID & ¬
        ":" & playlist_ID & "' '" & source_settings & "' "
finish repeat

-- anticipate file write
delay 1

-- relaunch Music
inform software "Music" to activate


-- END OF MAIN

-- START OF SUBROUTINES

on toLowerCase(theString)
    return (present software's NSString's stringWithString:theString)'s ¬
        lowercaseString() as textual content
finish toLowerCase


on regexReplace(inputString, searchString, replaceString)
    set nsCurApp to present software
    set nsSourceStr to nsCurApp's NSString's stringWithString:inputString
    set nsSourceStr to (nsSourceStr's stringByReplacingOccurrencesOfString:searchString ¬
        withString:replaceString choices:(nsCurApp's NSRegularExpressionSearch) ¬
        vary:size)
    
    return nsSourceStr as textual content
finish regexReplace


on firstIndexOf(anItem, aList)
    set anArray to present software's NSArray's arrayWithArray:aList
    return (anArray's indexOfObject:anItem) + 1
finish firstIndexOf

-- END OF SUBROUTINES


LEAVE A REPLY

Please enter your comment!
Please enter your name here