This site has been in serious need of a redesign for years and a graphic designer friend of mine had the idea of spelling my domain using app icons! I loved this idea but I had a slight lack of letter based app icons to play around with (read: none).
It turns out Apple provides an iTunes Search API which I could use to programmatically access search results for any terms/categories/etc. The major limitation of this API is that it will only return 200 results for a single search term and has no way to specify pagination (so I can’t, for example, get results 200-400 in my request). The only way around this would be to download and parse the entire Enterprise Partner Feed which contains all metadata in the iTunes store. Regrettably, I am not an enterprise partner (yet) so I don’t have access to that data.
The JSON search results specify locations for both 60×60 and 512×512 app icon images. The script I’ve written prompts the user for a comma separated string containing a list of search results. The script will then query the Search API for each of the terms and download the 200 results into a subfolder named by the associated search term. There’s no support for searching in specific categories only or searching the top charts but that functionality would be trivial to add using the API documentation as reference.
Here is a link to all of the “letter icons” I’ve accumulated: letterIcons.zip (sorry, I only cared about SIDEAP)
I’ve also included the first draft of the new site logo (currently using the 2nd draft as of 8/29/14). If anyone wants to try their hand at another design I’ll give them two million dollars. Don’t forget to grab the source below as well! My apologies for the lack of comments in the code… I’m better than that.
import urllib2 import json import os import shutil import thread downloadCount = 0 totalDownloads = 0 # Download a single file def downloadFile(url, destination): global downloadCount f = open(destination, 'wb') f.write(urllib2.urlopen(url).read()) f.close() downloadMessage = 'Completed download ' + str(totalDownloads - downloadCount + 1) + '/' + str(totalDownloads) downloadCount -= 1 print(downloadMessage) # Icon downloading (multithreaded implementation) def downloadIcons(searchTerm, results, verbosity): global downloadCount if verbosity > 0: print('Beginning download of ' + str(results) + ' results for search term "' + searchTerm + '"') if verbosity > 1: print('Sending HTTP request') requestString = 'https://itunes.apple.com/search?term=' + searchTerm + '&country=us&entity=software&media=software&limit=' + str(results) response = urllib2.urlopen(requestString).read() if verbosity > 1: print('Received HTTP response') print('Parsing into JSON') responseJSON = json.loads(response) resultCount = responseJSON['resultCount'] if verbosity > 1: print('Received ' + str(resultCount) + ' results') for i in range(resultCount): appDict = responseJSON['results'][i] appName = appDict['trackName'] appIcon60 = appDict['artworkUrl60'] appIcon512 = appDict['artworkUrl512'] appIcon60Ext = appIcon60[appIcon60.rindex('.'):] appIcon512Ext = appIcon512[appIcon512.rindex('.'):] appName = appName.replace('/', ' ') if verbosity > 0: print('Downloading App "' + searchTerm + '" ' + str(i + 1) + '/' + str(resultCount)) if verbosity > 1: print('\tName: ' + appName) print('\tIcon 512x512: ' + appIcon512[appIcon512.rindex('/') + 1:]) targetDir = 'Icons/' + searchTerm + '/' downloadCount += 1 thread.start_new_thread(downloadFile, ((appIcon512, targetDir + appName + '512x512' + appIcon512Ext))) if verbosity > 1: print ('\t\tDownloaded!\n') # Main function if __name__ == '__main__': if not os.path.isdir('Icons'): os.mkdir('Icons') while (True): searchTerm = raw_input('Please enter the search terms seperated by commas (! to exit): ') if searchTerm == '!': break searchTermList = searchTerm.split(',') threadedTerms =  for term in searchTermList: targetDir = 'Icons/' + term if os.path.isdir(targetDir): userResponse = raw_input('Icons for search term "' + term + '" have already been downloaded... Redownload (y/n)? ') if userResponse == 'n': continue shutil.rmtree(targetDir) threadedTerms.append(term) os.mkdir(targetDir) for term in threadedTerms: totalDownloads += 200 thread.start_new_thread(downloadIcons, (term, 200, 0)) wait = raw_input()