Album art on desktop


Preamble

In researching and collecting links for this post, I found a recent solution that does half of what my script does, but in a cleaner way. If all you want to do is display the album art on your desktop, then go with the CoverArt widget by Andreas Schaefer. The AppleScript is cleaner, and you don’t need GeekTool.

If you want to also be saving the album art for your five-star tracks, or just curious to know what this is about, read on.


I wrote artwork.widget. It’s an Übersicht widget that, with the help of GeekTool, puts the album art of the current playing track in iTunes in the bottom right corner of the screen.

Along with the itunes-now Übersicht widget, this gives me all the information I want to know about what’s playing now.

GeekTool only displays the album art, it doesn’t extract it from the currently playing track. The Übersicht widget does the extraction, and a bit of album art archiving.

The script is set to run every 3 seconds (this can be easily changed in the first line of the index.coffee file). It saves the current track’s album art to currentPlayingCover.png in the artwork.widget folder. GeekTool checks that file every 3 seconds, and updates the display as needed.

Then I thought “wouldn’t it be neat if, as time went on, I kept an archive of all the album art of the tracks I’ve listened to? Especially the 5-star rated ones?”

The iTunes library directory does not give you access to the album art files. Not in any usable way.

iTunes Artwork folder hierarchy

What I want is a flat directory that has all the album art I want, with clean titles: [artist] - [album] ([year]).png. But I don’t want this to be done for all the tracks I listen to, just for 5-star rated tracks.

This is the final version of the script. You can get the complete widget here.

on replace_chars(this_text, search_string, replacement_string)
	set AppleScript's text item delimiters to the search_string
	set the item_list to every text item of this_text
	set AppleScript's text item delimiters to the replacement_string
	set this_text to the item_list as string
	set AppleScript's text item delimiters to ""
	return this_text
end replace_chars

on is_running(appName)
	tell application "System Events" to (name of processes) contains appName
end is_running

set safRunning to is_running("iTunes")

if safRunning then
	run script "tell application \"iTunes\" 
	if player state is playing then
	
		tell artwork 1 of current track
			set artData to raw data
		end tell

		(((path to home folder) as text) & \"Dropbox:Ubersicht:widgets:artwork.widget:currentPlayingCover.png\")
		set deskFile to open for access file result with write permission
		set eof deskFile to 0
		write artData to deskFile
		close access deskFile

	
		set artFileName to (artist of current track) & \" - \" & (album of current track) & \" (\" & year of current track & \").png\"

		set theText to artFileName
		set oldString to \":\"
		set newString to \";\"

		local ASTID, lst
		set ASTID to AppleScript's text item delimiters
		try
			considering case
				set AppleScript's text item delimiters to oldString
				set lst to every text item of theText
				set AppleScript's text item delimiters to newString
				set theText to lst as string
			end considering
			set AppleScript's text item delimiters to ASTID
			set artFileName to theText
		on error eMsg number eNum
			set AppleScript's text item delimiters to ASTID
			error \"Can't replaceString: \" & eMsg number eNum
		end try

		set fullArchivePath to ((path to home folder) as text) & \"Dropbox:albumArt:\" & artFileName
		
		if rating of current track = 100 then
			tell application \"System Events\"
				if exists file fullArchivePath then
					return true
				else
					(fullArchivePath)
					set archiveFile to open for access file result with write permission
					set eof archiveFile to 0
					write artData to archiveFile
					close access archiveFile
				end if
			end tell
		end if
		
	end if
	
	end tell"
end if

The script checks to see if iTunes is running. This step is important because if osascript attempts to run the script without that first check, it will launch iTunes if iTunes is not running. Since this script is always running in the background, that would mean that you can never quit iTunes. Every time I would quit it, it would launch again in a few seconds when art.applescript would check to see if iTunes is playing a track.

If iTunes is running, the script checks to see if a track is currently playing. If not, it does nothing.

If a track is currently playing, it grabs the first artwork in the track data and saves it to currentPlayingCover.png. That’s the file GeekTool is watching for.

Then the script checks to see if the current track has a 5-star rating.1 If it does, it grabs the album art and saves it to albumArt in my Dropbox folder. The filename is obtained from the track metadata: [artist] - [album] ([year]).png, and is only saved if that file does not already exist in albumArt.

Album art files in folder

Update (27/04/2015)

Here’s a catch. The colon character : is illegal for a filename on HFS+.2 Despite what Finder and terminal will make you think, the colon : is the real directory separator in the file system, not the /. You can see this in action in the script. All paths are created by stringing directory names together with :, not /.

So what happens when I’m listening to Puscifer and art.applescript wants to save the album art for “V” Is for Viagra: The Remixes? It won’t work. It will throw an error saying that it cannot find the path: .../Puscifer - "V" is for Viagra/ The Remixes.png.

I’ve updated the script to replace : with ;. It’s the closest visual match.

The script is messy. AppleScript doesn’t have a built-in method for string replacement, so I had to look around for solutions online, and ended up using this code with a bit of modification. Ideally I would define a sub-routine at the start of the script and then use it, but I couldn’t get that to work. My guess is that because this is a script within a script (see the if safRunning then run script... part, and me having to escape a lot of " with \"), AppleScript kept getting tripped up on scope problems. I’m just glad I got it to work.

The script will replace : with ; in the album title. What about artist name? I don’t think I’ve come across that, and frankly your band’s album art has no place in my collection if you have a colon in your name. Don’t be a jerk.

  1. iTunes saves the ratings on a scale from 0 to 100, at 20 point increments. A 5-star rating = 100, 4-star rating = 80, and so on. 

  2. This is an oversimplification. See here for more details.