0

I am from Ukraine and as you know we have a big war with Russia.

Earlier, I used to listen to many Russian songs, but now I want to remove all of them from my iTunes library in order not to give Russians availability to earn money and pay taxes in Russia and prevent sponsoring war. Maybe someone have an idea how to do this?

I think it would be very popular in Ukraine, so you will help not only me.

Thanks.

IconDaemon
  • 19,234
  • 1
    Are you using Apple Music to stream songs, or are these song files you have downloaded to your device(s)? – IconDaemon Nov 03 '22 at 12:22
  • @IconDaemon I have many playlists in which I am adding songs from search. The songs are in cloud, I have not downloaded them – mikeKlech Nov 03 '22 at 12:36
  • Identifying Russian songs is probably the first step, this related question might be helpful. – Saaru Lindestøkke Nov 03 '22 at 12:56
  • @SaaruLindestøkke Thanks for your comment. But the problem is also that ukrainian people also used to write songs in russian, so I don't want to remove those songs. Maybe it possible to detect the country of the artist? – mikeKlech Nov 03 '22 at 13:06
  • This depends on your programming skills, but to me it seems that you'll have the highest chance of success if you can export your playlist, then lookup an artist country in an online music database via an API (e.g. musicbrainz), then remove all songs of artist which are from an unfavourable country of your choice and then programmatically re-create the playlist and import the "cleaned" version into iTunes. – Saaru Lindestøkke Nov 03 '22 at 13:36
  • Alternatively you can simply skip Russian songs as soon as they start, I would think the streaming money starts flowing only after the song plays for X seconds. Then you can later use the skip counter of iTunes (not sure if it still exists) to identify the skipped songs in a playlist and remove them. – Saaru Lindestøkke Nov 03 '22 at 13:39
  • @SaaruLindestøkke Thanks for the musicbrainz. I will look at their API. Maybe its really solution. I am newbie in AppleScript, but I have programming skill in other languages – mikeKlech Nov 03 '22 at 14:34

1 Answers1

0

Thanks everyone who helped me to to find a solution. Finally I wrote the Applescript that find russian tracks and after promting delete them. The script uses musicbrainz API(thanks @SaaruLindestøkke).

PAY ATTANTION!!!

To parse JSON response from API you should install the [JSON Helper App][1] - https://apps.apple.com/us/app/json-helper-for-applescript/id453114608?mt=12, otherwise script won't work.

global russianCities
set russianCities to {"Moscow", "Saint Petersburg", "Novosibirsk", "Yekaterinburg", "Kazan", "Nizhny Novgorod", "Chelyabinsk", "Krasnoyarsk", "Samara", "Ufa", "Rostov-on-Don", "Omsk", "Krasnodar", "Voronezh", "Perm", "Volgograd", "Saratov", "Tyumen", "Barnaul", "Izhevsk", "Makhachkala", "Khabarovsk", "Ulyanovsk", "Irkutsk", "Vladivostok", "Yaroslavl", "Kemerovo", "Tomsk", "Sevastopol", "Stavropol", "Orenburg", "Ryazan", "Penza", "Cheboksary", "Lipetsk", "Kaliningrad", "Astrakhan", "Tula", "Kirov", "Kursk", "Ulan-Ude", "Tver", "Bryansk", "Ivanovo", "Yakutsk", "Vladimir", "Belgorod", "Kaluga", "Chita", "Grozny", "Smolensk", "Saransk", "Vologda", "Kurgan", "Oryol", "Arkhangelsk", "Vladikavkaz", "Yoshkar-Ola", "Murmansk", "Kostroma", "Tambov", "Nalchik", "Blagoveshchensk", "Petrozavodsk", "Veliky Novgorod", "Syktyvkar", "Pskov", "Abakan", "Yuzhno-Sakhalinsk", "Petropavlovsk-Kamchatsky", "Maykop", "Kyzyl", "Cherkessk", "Khanty-Mansiysk", "Elista", "Magadan", "Birobidzhan", "Gorno-Altaysk"}

on isMatchArtistName(appleAPIArtist, brainsAPIArtist) if appleAPIArtist contains |name| of brainsAPIArtist or appleAPIArtist contains |sort-name| of brainsAPIArtist then return true end if try repeat with al in |aliases| of brainsAPIArtist if appleAPIArtist contains |name| of al then return true end if end repeat on error errMsg --log "ERROR: " & errMsg end try return false end isMatchArtistName

on getIsRussianArtist(theArtist, strict)

set weblink to "'https://musicbrainz.org/ws/2/artist' --data-urlencode 'limit=10' --data-urlencode 'fmt=json' --data-urlencode " & quoted form of ("query=" & theArtist)
log weblink

set curl_command to "curl -G -v " & weblink
log curl_command
set res to do shell script curl_command

tell application "JSON Helper"
    set parsedJSON to read JSON from res
    set artists to artists of parsedJSON
    repeat with artist in artists
        set checkArtist to true
        if strict then
            set checkArtist to my isMatchArtistName(theArtist, artist)
        end if

        if checkArtist then
            try
                set theCountry to country of artist
                if theCountry contains "UA" then
                    return false
                end if
                if theCountry contains "RU" then
                    return true
                end if
            on error errMsg
                log "ERROR: " & errMsg
            end try
            try
                set theArea to |name| of area of artist
                if russianCities contains theArea then
                    return true
                end if
            on error errMsg
                log "ERROR: " & errMsg
            end try
        end if

    end repeat
end tell
return false

end getIsRussianArtist

on composePlaylistName(name, id) set nextName to name & "(ID:" & id & ")" return nextName end composePlaylistName

on pickThePlaylist() tell application "Music" set AllUserPlaylists to every user playlist set thePlaylistNames to {} repeat with thePlaylist in AllUserPlaylists set end of thePlaylistNames to my composePlaylistName(name of thePlaylist, id of thePlaylist) end repeat set thePickedPlaylistName to choose from list thePlaylistNames with prompt "Select your playlist:" set currentPlaylist to first item of AllUserPlaylists

    repeat with thePlaylist in AllUserPlaylists
        if thePickedPlaylistName contains my composePlaylistName(name of thePlaylist, id of thePlaylist) then
            return tracks of thePlaylist
        end if
    end repeat
    error "Playlist was not found."
end tell

end pickThePlaylist

on composeTrackName(artist, name, id) set nextName to artist & "-" & name & "(ID:" & id & ")" return nextName end composeTrackName

on pickRussianTracksToDelete(theTracks) tell application "Music" set theTrackNames to {} repeat with theTrack in theTracks set end of theTrackNames to my composeTrackName(artist of theTrack, name of theTrack, id of theTrack) end repeat set thePickedPlaylistNames to choose from list theTrackNames with prompt "Select the tracks you want to delete(this is a multiple selection list, use 'Command (⌘) + Mouse Click' to select/unselect):" default items theTrackNames with multiple selections allowed set selectedTracks to {}

    repeat with theTrack in theTracks
        repeat with pickedName in thePickedPlaylistNames
            if pickedName contains my composeTrackName(artist of theTrack, name of theTrack, id of theTrack) then
                set end of selectedTracks to theTrack
            end if
        end repeat
    end repeat
    return selectedTracks
end tell

end pickRussianTracksToDelete

on promptForStrictMode() tell application "Music" set theDialogText to "Hello. I will remove russian songs from your playlist. The script is working in two modes: 1. Strict - only russian songs will be affected but many songs may be skipped. 2. No Strict - finding more russian songs, but also Ukrainian songs might be affected." set result to display dialog theDialogText buttons {"No Strict", "Strict"} default button "Strict" set isStrict to button returned of result is equal to "Strict" return isStrict end tell end promptForStrictMode

on initProgressBar(tracksCount) set progress total steps to tracksCount set progress completed steps to 0 set progress description to "Processing Songs..." set progress additional description to "Preparing to process." end initProgressBar on updateProgressBar(a, tracksCount) set progress additional description to "Processing song " & a & " of " & tracksCount set progress completed steps to a end updateProgressBar on resetProgressBar() set progress total steps to 0 set progress completed steps to 0 set progress description to "" set progress additional description to "" end resetProgressBar on findAndDeleteRussianTracks() set strict to my promptForStrictMode() set currentPlaylist to my pickThePlaylist() set delayTime to 0.5 set russianTracks to {} set tracksCount to length of currentPlaylist --initial set of progress bar my initProgressBar(tracksCount)

repeat with a from 1 to length of currentPlaylist
    set theTrack to item a of currentPlaylist
    delay delayTime
    my updateProgressBar(a, tracksCount)
    tell application "Music"
        set isRussianArtist to my getIsRussianArtist(artist of theTrack, strict)
        if isRussianArtist is true then
            set end of russianTracks to theTrack
        end if
    end tell
end repeat
my resetProgressBar()
tell application "Music"
    if (count of russianTracks) is equal to 0 then
        set theDialogText to "Russian songs were not found. Try another playlist."
        display dialog theDialogText
        return my copyRussianTrackToPlaylist()
    end if
    set selectedTracks to my pickRussianTracksToDelete(russianTracks)
    repeat with theTrack in currentPlaylist
        repeat with theDeleteTrack in selectedTracks
            try
                if (id of theDeleteTrack) is (id of theTrack) then
                    log "delete" & id of theTrack
                    delete theTrack
                end if
            on error errMsg
                log "Error: " & errMsg
            end try
        end repeat
    end repeat
    set theDialogText to "HOORAY! Your Playlist was cleared from russian songs."
    display dialog theDialogText buttons {"Okay"} default button "Okay"
end tell

end findAndDeleteRussianTracks

my findAndDeleteRussianTracks()