Apple links and images

I’ve changed the affiliate links in the sidebar again, eliminating the Amazon link and settling (for now) on a Mac app, an iOS app, and an iTunes album or movie. Because all the links are to Apple stores, I decided to rewrite the script that generates the HTML for the link, the image, and the popup description. In the process, I learned a few things about the format of Apple’s links and product images that I thought worth sharing.

The script is called apple-sidebar-link, and I call it from the command line like this:

apple-sidebar-link ''

where the argument is the URL of the product I want to link to. In the example, it’s Marked, Brett Terpstra’s Markdown previewer/processor/integrator/thingy. It’s not usually necessary to put the argument in quotes, but it’s a good habit to get into, because sometimes the URL includes characters that are special to the shell.

The command generates this HTML code,

<h1><a href="" rel="nofollow" class="affiliate-header">Mac App Store link:<br />&nbsp;Marked</a></h1>

<div class="affiliate">
  <a href="javascript:$('#macapp-popup'"><img src="" alt="Marked" title="Click for description" /></a>
  <div id="macapp-popup" class="affiliate-popup">
  <a href="javascript:$('#macapp-popup').hide()">&#x2612</a>

which looks like this in the sidebar:

Sample sidebar affiliate link

I replace the DESCRIPTION with a paragraph of text explaining why I’m linking to the product. That description will appear in a popup when you click on the image. Clicking on the text above the image takes you to the appropriate Apple product page or store and tells Apple where you came from so I get a kickback if you buy.

The script is smart enough to recognize the difference between a Mac App Store link, an iOS App Store link, and an iTunes Store link and return HTML appropriate for each. Here’s the source code:

 1:  #!/usr/bin/python
 3:  import itunes
 4:  import re
 5:  import sys
 7:  # Called from the command line as
 8:  #
 9:  #   apple-sidebar-link <url>
10:  #
11:  # The URL may need to be quoted to avoid problems with shell special characters.
13:  # Dictionaries keyed on media type. For the full list of types, see
14:  #
15:  linkIDs = {"12": "macapp-popup",
16:              "8": "iosapp-popup"}
17:  headerText = {"12": "Mac App Store link:",
18:                 "8": "App Store link:"}
20:  # Get the item ID and media type (if present) from the URL on the command line.
21:  # "itunes-popup" is the default link ID.
22:  itemID ='/id([^/?%]+)', sys.argv[1]).group(1)
23:  try:
24:    mt ='[&?]mt=(\d+)', sys.argv[1]).group(1)
25:    linkID = linkIDs.get(mt, "itunes-popup")
26:    header = headerText.get(mt, "iTunes Store link:")
27:  except AttributeError:
28:    linkID = "itunes-popup"
29:    header = "iTunes Store link:"
31:  # Lookup the item.
32:  item = itunes.lookup(itemID)
33:  itemURL = item.get_url() + "&partnerId=30&siteID=L4JhWyGwYTM"
35:  # Apps always seem to have a link to 512x512 artwork, but music and movies
36:  # top out at 100x100, even though iTunes has much larger images. Since the
37:  # image URLs include the size, we can link to the 600x600 image by changing
38:  # that part of the URL.
39:  if linkID == "itunes-popup":
40:    imageURL = item.get_artwork()['100'].replace('100x100', '600x600')
41:  else:
42:    imageURL = item.get_artwork()['512']
43:  name = item.get_name()
45:  # Print the HTML to be added to the sidebar
46:  print '''<h1><a href="{0}" rel="nofollow" class="affiliate-header">{4}<br />&nbsp;{2}</a></h1>
48:  <div class="affiliate">
49:    <a href="javascript:$('#{3}'"><img src="{1}" alt="{2}" title="Click for description" /></a>
50:    <div id="{3}" class="affiliate-popup">
52:    <a href="javascript:$('#{3}').hide()">&#x2612</a>
53:    </div>
54:  </div>'''.format(itemURL, imageURL, name, linkID, header)

As you can see in Line 3, it uses the python-itunes library to access the iTunes Search API. You’ll have to install that library if you want to use this script to create your own affiliate links.

Lines 13-29 distinguish between the various product types. The key is the mt= parameter in the product URL. If it’s mt=12, the product is a Mac app; if it’s mt=8, the product is an iOS app; and if it’s anything else, the product is a song, album, movie, TV show, book, etc.—something in the iTunes store. The full set of mt parameters is listed in this Stack Overflow discussion. The mt parameter is plucked out of the URL in Line 24, and Lines 25-26 set the linkID and header variables according to a dictionary lookup. I use the get method to set the defaults: if the mt is anything other than 12 or 8, the product is considered an iTunes Store product.

Music, movies, and TV shows often don’t have an mt= parameter, which is why there’s a try/except block in the code. If the regex search for mt= fails, the product is considered an iTunes Store product.

Line 32 actually looks up the product according to its ID string, and Line 33 creates an affiliate URL by tacking on the partnerID and siteID parameters. The parameters in this line are for me, so make sure you change them to your parameters if you adapt this code for your own use.

Lines 35-42 handle the surprisingly roundabout method necessary to get decent resolution product images. The get_artwork method returns a dictionary of image URLs keyed to the image size. For Mac and iOS apps, the product image is the app icon and the maximum size in this dictionary always seems to be 512 (i.e., 512×512), which is plenty big for my purposes.1 Mac and iOS app image URLs are gathered in Line 42.

For movies and music, though, the maximum size in the dictionary returned by get_artwork always seems to be 100—way too small for my needs. To be sure, Apple has bigger images, but it doesn’t provide their URLs in through the Search API. I complained about this on Twitter last month and got a very helpful response from Dan Burbul:

@drdrang you can hack URL to get 600x600
Dan Burbul (@danburbul) Sun Jun 30 2013 12:04 AM CDT

This is where Line 40 comes from.

As an aside, I should also mention Rob Mathers’ reply to my Twitter complaint:

@drdrang I don’t have a sample URL handy, but I believe you can chop off the last grouping of digits to get the largest size available.
Rob Mathers (@robmathers) Sun Jun 30 2013 11:04 AM CDT

This trick of removing the size part from the URL, turning, say,


can return some really big images, but it seems to be restricted to movies and TV shows, so I couldn’t use it in apple-sidebar-links. Good to know, though.

Finally, Lines 46-54 put all the information gathered earlier into an HTML template string and prints it out.

I usually pipe the output of apple-sidebar-link into pbcopy, which puts it on the clipboard, and then paste it into my WordPress template. The process is much faster than dealing with the hopelessly clunky LinkShare system, and it creates links that fit my blog’s layout. It’s not what I’d call an elegant script, but it does the job and should be easy to modify when I want something different.

Update 7/21/13
I added the rel="nofollow" attribute to the link on the advice of Ben (@Gridlock) who pointed me to this article on Search Engine Land. Since these are Apple links, I’m sure Google deals with them just fine, but nofollow is apparently the preferred practice for affiliate links. Live and learn.

  1. The CSS for my sidebar sets the max-width for images to a value that won’t be wider than the sidebar itself. Using an <img> that’s bigger that the sidebar width wastes a little bandwidth but insures that the images aren’t undersized.