Images from the iTunes/App/Mac App Stores

Last week, I ripped the CD of Hunky Dory to my iTunes library. When it was done, I was reminded that iTunes doesn’t add album artwork automatically, so I needed to get a good JPEG of the album cover. Searching Google Images for the best image seemed silly when Apple has a perfectly good version already sitting there in the iTunes Store. Wouldn’t it be better if I could just use the image from Apple? So instead of wasting my time searching Google, I wasted my time writing a script that would search the iTunes Store.

What I came up with is a Python script called ipic, which I’ve put in a GitHub repository. It will search the iTunes, App, or Mac App Stores for images associated with albums, movies, TV shows, books, or apps and display what it finds as a set of thumbnail images in your browser. Each thumbnail is a link to a full-sized version, 512×512 pixels for apps, 600×600 for everything else.

Here’s an example to get the icon for Agile Tortoise’s Drafts app (which was just updated today):

ipic -i drafts

The -i switch tells ipic that you’re looking for an iOS app. The complete list of switches is:

When the search is finished, ipic opens a new tab (or new window, depending on your configuration) in Safari with the thumbnail images it found:1

Web page from ipic

If you don’t recognize an image, hover over it and the name of the item will pop up. Click on an image to get the bigger version.

Here’s the ipic source code:

python:
 1:  #!/usr/bin/env python
 2:  # encoding: utf8
 3:  
 4:  import requests
 5:  import docopt
 6:  import os
 7:  import subprocess
 8:  
 9:  # You may want to change these.
10:  myDir = os.environ['HOME'] + '/Desktop/'    # directory for HTML file
11:  browser = 'com.apple.Safari'                # browser bundle identifier
12:  
13:  usage = '''Usage: ipic (-i | -m | -a | -f | -t | -b | -h) SEARCHTERM
14:    
15:  Generate and open a web page of thumbnail images and links to larger images
16:  for items in the iTunes/App/Mac App Stores.
17:  
18:  Options:
19:    -i      iOS app
20:    -m      Mac app
21:    -a      album
22:    -f      film
23:    -t      TV show
24:    -b      book
25:    -h      show this help message
26:  
27:  Only one option is allowed. The HTML file for the generated web page is
28:  saved on your Desktop.'''
29:  
30:  # Handle the command line.
31:  args = docopt.docopt(usage)
32:  searchterm = args['SEARCHTERM']
33:  if args['-i']:
34:    size = 512
35:    media = 'software'
36:    entity = 'software'
37:    name = 'trackName'
38:  elif args['-m']:
39:    size = 512
40:    media = 'software'
41:    entity = 'macSoftware'
42:    name = 'trackName'
43:  elif args['-a']:
44:    size = 600
45:    media = 'music'
46:    entity = 'album'
47:    name = 'collectionName'
48:  elif args['-f']:
49:    size = 600
50:    media = 'movie'
51:    entity = 'movie'
52:    name = 'trackName'
53:  elif args['-t']:
54:    size = 600
55:    media = 'tvShow'
56:    entity = 'tvSeason'
57:    name = 'collectionName'
58:  elif args['-b']:
59:    size = 600
60:    media = 'ebook'
61:    entity = 'ebook'
62:    name = 'trackName'
63:  else:
64:    size = 600
65:    media = ''
66:    entity = ''
67:    name = ''
68:  
69:  # Make the iTunes search call and collect the thumbnail and large image URLs.
70:  iURL = 'https://itunes.apple.com/search'
71:  parameters = {'term': searchterm, 'media': media, 'entity': entity}
72:  r = requests.get(iURL, params=parameters)
73:  results = r.json()['results']
74:  turls = [ x['artworkUrl100'] for x in results ]
75:  burls = [ x.replace('100x100', '{0}x{0}'.format(size)) for x in turls ]
76:  names = [ x[name] for x in results ]
77:  
78:  # Construct the HTML.
79:  linkFmt = '<a href="{1}"><img src="{0}" alt="{2}", title="{2}" /></a>'
80:  links = [linkFmt.format(x, y, z.encode('utf8'))
81:            for x, y, z in zip(turls, burls, names) ]
82:  html = '''<html>                                                        <head><title>{0} pictures</title></head>
83:  <body>
84:  <h1>“{0}” pictures</h1>
85:  {1}
86:  </body>
87:  </html>'''.format(searchterm, '\n'.join(links))
88:  
89:  # Create an HTML file and open it.
90:  htmlFile = myDir + searchterm + '.html'
91:  with open(htmlFile, 'w') as f:
92:    f.write(html)
93:  
94:  subprocess.check_call(['open', '-b', browser, htmlFile])

As you can see in Lines 4–5, ipic uses two non-standard modules: Kenneth Reitz’s well-known (and nearly standard) requests module for handling HTTP communication, and Vladimir Keleshev’s docopt module for handling the command line switches and the help message.

Because I don’t know a way to pipe HTML into Safari, ipic saves the HTML file of thumbnail images to the Desktop. I like saving it there because it’s easy to find (and easy to throw away), but if you prefer it to be saved somewhere else, you can change Line 10. And if you’d rather use a different browser, change Line 11 to the bundle identifier of you choice.

Lines 13–28 define the usage message, which docopt parses and turns into a dictionary in Line 31.

The long if/elif/else stanza in Lines 33–67 is an inelegant way to determine which sort of thing we’re searching for and to set up a few variables for the iTunes API call, which is done in Lines 70–73. I feel certain there’s a really cool Pythonic way of doing this, but I haven’t figured it out yet.

The URLs for the 100×100 thumbnails are collected in the turls list in Line 74, and these URLs are converted to point to full-sized images and saved to the burls list in Line 75. I learned this conversion trick a couple of years ago, and it still works. The names of the items are saved in the names list in Line 76.

With all the information collected, it’s pretty easy to put it all together into a bare-bones HTML file. The text is strung together in Lines 79–87, and the file is saved to disk in Lines 90–92. Two things of note:

  1. Because the items’ names may include Unicode characters, the encode method is invoked in Line 80.
  2. The name of the HTML file is set to the search term. I figured this was the easiest way to know which file was which when I saw them later on the Desktop.

All that remains is Line 94, which uses the subprocess module to call OS X’s open command. This opens the HTML file in Safari, launching it if necessary.

Gee, I wonder how I should end this post?

Gotta make way.

Update 3/3/16 6:58 AM
Although adding artwork to iTunes was what inspired me to write this script, I don’t expect that to be the main use of it. Most of the music I buy nowadays is digital-only, and it comes with the artwork already embedded, so I’d almost never use ipic for that purpose. The primary purpose for ipic is to have a quick way to add images to tweets, text messages, Slack entries, and blog posts.

Although ipic was written for the Mac, I think it can be adapted for iOS. I’d need to give it a graphical user interface, and I’d have to figure out how to handle local files, but those don’t seem insurmountable. The basic logic of the program would stay the same. It would probably be easier, though, to just turn ipic into a CGI script sitting on my server and access it directly from the browser. That would make it work the same on the Mac and iOS.

In fact, as Graham Spencer pointed out to me, there’s already a web-based tool for that from Ben Dodson, and he’s made its source code available. One thing I don’t like about Ben’s solution is that his search results are presented as a scrolling list of the full-sized images. This is not only a waste of bandwidth when there are a lot of hits, it can also take a long time to find the image you’re looking for if it’s way down the list. My thumbnail approach has neither of those disadvantages.

Finally, Dylan Ryan pointed out that the data URI scheme might be used as a way of piping HTML to the browser without creating a file. I don’t think I’ll use that in ipic, but it’s something to keep in mind for future projects.


  1. I would’ve used Hunky Dory as the example, but it had only two hits. The screenshot was boring.