Report abuse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
-- Set “Sort Artists” for iTunes Selection, by Jacob Rus, 20 March 2007
-- 
-- This script will pop up a dialog for each artist represented
-- among the selected tracks in iTunes, asking what to put in the
-- “Sort Artists” field for all selected songs by that artist.
--
-- Note: this script breaks if the the current iTunes view is sorted by
-- artist, or by ‘album by artist’ or ‘album by year’, because the order
-- of the selection then changes as the tracks gain a ‘sort artist’
-- attribute.  Also, it may bog down a bit if very large numbers of
-- tracks are selected.
--
-- Suggestion: create a new smart playlist called “Not Sorted” which
-- matches tracks where “Sort Artist” is "".  Make sure that this
-- smart playlist is *NOT* set to “Live Updating”, as this will
-- cause the same problem as sorting by Artist. Sort this by Album, 
-- and then select up to a few dozen albums, and run this script.


-- set this to true if you want the script to ignore any artists all
-- of whose tracks already have a “Sort Artist” attribute
property check_for_existing_sort_artist : false



tell application "iTunes"
    activate
    -- set track_list to (tracks in selection)
    set artist_list to 
    repeat with track_ in (selection)
        set artist_ to (artist of track_)
        
        -- if we are not checking for already sorted artists, then we
        -- should make sure `no_sort_artist` is true, so every artist
        -- will be included in the list
        if check_for_existing_sort_artist then
            set no_sort_artist to (sort artist of track_ is "")
        else
            set no_sort_artist to true
        end if
        
        if (artist_list does not contain artist_) and no_sort_artist then
            set artist_list to artist_list & artist_
        end if
    end repeat
    
    -- pop up a dialog box for every unique artist, and then add the
    -- “Sort Artist” attribute to all tracks for that artist when the
    -- user confirms.
    repeat with artist_ in artist_list
        set dialog_prompt to "Type the desired value for “Sort Artist”, for the artist:" & return & return & artist_
        set default_text to my put_last_name_first(artist_)
        set b2 to "Use “Artist” for “Sort Artist”"
        set b3 to "Set “Sort Artist”"
        
        set the_result to display dialog dialog_prompt with icon 1 ¬
            default answer default_text ¬
            buttons  default button b3
        set button_pressed to button returned of the_result
        set text_typed to text returned of the_result
        if button_pressed is b3 then
            -- use typed text
            my set_sort_artist_on_selection(artist_, text_typed)
        else if button_pressed is b2 then
            -- use artist
            my set_sort_artist_on_selection(artist_, artist_)
        end if
    end repeat
    
    -- we're finished; better let the user know
    display dialog "All Done" with icon 1 buttons  default button 1
end tell


-- Subroutines:

-- changes every song in the selection by 'artist_' to have sort artist 'sort_artist'
on set_sort_artist_on_selection(artist_, sort_artist)
    tell application "iTunes"
        set artist_ to artist_ as Unicode text
        repeat with track_ in selection
            if (artist_ = artist of track_) then
                set (sort artist of track_) to sort_artist
            end if
        end repeat
    end tell
end set_sort_artist_on_selection


-- Turn "First Middle Last" into "Last, First Middle".  Note, this function
-- does not get every name perfect.  That's what the text box is for. ;)
on put_last_name_first(artist_name)
    
    -- handle the case where multiple artists are involved.  Put last name
    -- first on the first artist, and then just leave everyone else's name
    -- alone.
    repeat with conj_ in 
        if (artist_name contains conj_) then
            set parts_ to split of artist_name by conj_
            set (item 1 of parts_) to put_last_name_first(item 1 of parts_)
            return (join of parts_ by (conj_ as string))
        end if
    end repeat
    
    set name_list to split of artist_name by " "
    
    if (length of name_list)  1 then
        return artist_name
    else
        return (item -1 of name_list) & ", " & ¬
            (join of () by " ")
    end if
end put_last_name_first

-- split the string into a list by some separator
to split of aString by sep
    local aList, delims
    tell AppleScript
        set delims to text item delimiters
        set text item delimiters to sep
        set aList to text items of aString
        set text item delimiters to delims
    end tell
    return aList
end split

-- join a list into a string with some separator
to join of aList by sep
    local aString, delims
    tell AppleScript
        set delims to text item delimiters
        set text item delimiters to sep
        set aString to aList as string
        set text item delimiters to delims
    end tell
    return aString
end join