# Python appscript and random ten

Last summer, I wrote a post about the Python appscript module. I liked it, but got away from using it because Apple didn’t include it with Leopard, going with the Scripting Bridge framework instead. I’ve done some reading on the Scripting Bridge, but it just hasn’t clicked with me; appscript seems so much easier to use.

As I learned with my shortened URL scripts, AppleScript itself is sometimes the best language to use when plucking information out of a Macintosh application. But AppleScript’s text handling pales in comparison with Python and Ruby’s, so when most of the script involves manipulation of text, appscript seems like the best way to go.

To get myself back in appscript shape, I rewrote my random ten script. The AppleScript version looks like this:

 1:  tell application "iTunes"
2:      set p to  playlist "****"
3:      set songlist to (get name of every track of p)
4:      set artistList to (get artist of every track of p)
5:      set albumList to (get album of every track of p)
6:      set textlist to ""
7:      repeat with i from 1 to 10
8:          set textlist to textlist & i & ". \"" & ¬
9:              item i of songlist & ¬
10:              "\" by " & item i of artistList & "
11:  from *" & item i of albumList & "*
12:  "
13:      end repeat
14:      set the clipboard to textlist
15:  end tell


The repeat loop from line 7 through 13 is not the most clumsy example of text handling in AppleScript, but there are better ways to grab a bunch of strings and put them together. Here it is in Python:

 1:  #!/usr/bin/env python
2:
3:  import appscript
4:  import os
5:
6:  # Get the first 10 tracks from the **** playlist.
7:  tracks = appscript.app('iTunes').playlists['****'].tracks.get()[0:10]
8:
9:  # Get the name, artist, and album from the tracks and format them for
10:  Markdown.
11:  info = [ (n, x.name.get(), x.artist.get(), x.album.get())
12:          for n,x in zip(range(1,11), tracks) ]
13:  infoString = '\n'.join([ '%d. "%s" by %s  \nfrom *%s*' % x for x in info ])
14:
15:  # Put the information onto the clipboard, ready for pasting.
16:  os.popen('pbcopy', 'w').write(infoString)


Overall, I like this one better. may have gotten carried away with stacking methods on top of one another, but it’s so easy to write and doesn’t really seem hard to understand. On the other hand, os.popen('pbcopy', 'w').write(infoString) does seem a bit more opaque than set the clipboard to textlist.

And the output:

1. “Bulldog” by The Fireballs
from Rock Instrumental Classics Vol. 2: The Sixties
2. “Heart Association” by The Emotions
from Stax-Volt Soul Singles Vol. 2
3. “Further On Up The Road” by Eric Clapton
from The Blues [Disc 2]
4. “Jump Up” by Elvis Costello
from My Aim Is True
5. “Almost Grown” by Chuck Berry
from The Great Twenty-Eight
6. “Because They’re Young” by Duane Eddy & The Rebels
from Rock Instrumental Classics Vol. 2: The Sixties
7. “The Long Black Veil” by Johnny Cash
from The Essential Johnny Cash 1955-1983
8. “Hey Joe” by Wilson Pickett
from A Man And A Half: The Best of Wilson Pickett
9. “She Don’t Love Nobody” by Nick Lowe
from Basher -The Best of Nick Lowe
10. “Tupelo (Part 1)” by Pop Staples, Albert King, Steve Cropper
from Stax-Volt Soul Singles Vol. 2