Topic “AppleScript”

iTunes favorites mix tape generator: Now with more Entropy

Last summer I devised an AppleScript to generate a fixed-length, one track per-artist iTunes playlist. This worked pretty well, but I’ve been using this script long enough and frequently enough that I started to notice that my supposedly random playlists contained clumps of tracks that had all been played on the same date a few months ago, as though my previous random playlists were just getting recycled into new ones.

So I added some additional logic to enforce a one track per artist, one track per-date rule - no more clustered tracks.

The updated script also contains a couple of other niceties:

  • It tells iTunes to focus (in case you’re running the script via some sort of launcher like Quicksilver)
  • It presents you with a choice of durations.

The next logical iteration would be additional interface allowing you to select source and destination playlists, but I haven’t gotten irked enough by that problem to solve it yet.

-- Mix Tape iTunes playlist generator
-- by Andy Chase | http://andychase.net
-- January 11, 2010

tell application "iTunes" to activate tell application "iTunes" set theSmartPL to playlist "Unrecent Alt/Rock Faves" set theDumbPL to playlist "Unrecent Faves Cassette"

set cassetteLengths to {30, 45, 60, 74, 90, 120}

set theDuration to 60 * {choose from list cassetteLengths with title "Cassette Length" default items {45} without multiple selections allowed}

set allArtists to {}
set allDates to {}

delete every track of theDumbPL

set selectedTracks to every track of theSmartPL

repeat with aTrack in selectedTracks

    if (the duration of theDumbPL ? theDuration) then

        set theArtist to the artist of aTrack
        set theDate to the played date of aTrack
        set theDateString to the date string of theDate
        if (theArtist is not in allArtists and ((duration of aTrack) + (duration of theDumbPL)) ? theDuration and theDateString is not in allDates) then
            duplicate aTrack to theDumbPL
            set end of allArtists to theArtist
            set end of allDates to theDateString
        end if

    end if
end repeat

set the shuffle of theDumbPL to true
reveal theDumbPL
play theDumbPL

end tell

Recapture the Cassette Experience (Sort of) with iTunes and AppleScript

I've been using iTunes for over six years now, and I rely pretty heavily on ratings and playcounts to create any number of Smart Playlists, most of which revolve around finding music in a particular genre that is highly rated OR frequently played AND has not been played in a while.

The result is not unlike the mix tapes of favorite music that I used to make for myself, back when I had few enough albums that picking a mere 90 minutes' worth of faves was not a laughable notion.

But having one giant, never-ending Smart Playlist is depressing in some ways; I could start my "unrecent favorites" playlist and never reach the end, thanks to the "Live Updating" feature. The major thing missing from having a massive digital music library is that sense of deliberateness that used to accompany listing to music on physical media. In particular, cassettes and vinyl LP's, which required the listener to get up, flip sides, and resume playing.

For a while now I've been paying homage in the nerdliest possible way to the act of flipping over a humble 45-minute per side mix tape. I started with a smart playlist titled "Unrecent alt/rock Faves", limited it to 45 minutes, and then unchecked the 'Live Updating Box'; after all of the songs play, I edit the playlist, re-check 'Live Updating', click 'OK', then re-edit the playlist and un-check 'Live Updating' again. Kind of a pain, but it does break the music up into nice listenable chunks.

Just now I decided to bite the bullet and hack together an AppleScript that consolidated this silliness into one step, and managed to pull it off. You need two playlists: The aforementioned "Unrecent Alt/Rock Faves" smart playlist (limited to 45 minutes, with the 'Live Updating' option checked) and a new regular playlist called "Unrecent Faves Cassette". As far as I can tell, there's no way to alter the 'Live Updating' attribute of a Smart Playlist via AppleScript, so this method just copies from a Smart Playlist to a static one.

Here's the script:

tell application "iTunes"
	set theSmartPL to playlist "Unrecent Alt/Rock Faves"
	set theDumbPL to playlist "Unrecent Faves Cassette"
	
	delete every track of theDumbPL
	
	set selectedTracks to every track of theSmartPL
	
	repeat with aTrack in selectedTracks
		duplicate aTrack to theDumbPL
	end repeat
	
	reveal theDumbPL
	play theDumbPL
	
end tell

When saved in ~/Library/iTunes/Scripts it shows up in the iTunes Scripts Menu, and when run it wipes out the current contents of 'Unrecent Faves Cassette' playlist, replacing it with the newly updated contents of the 'Unrecent Alt/Rock Faves' playlist. It then selects and plays the Cassette playlist. I can even run the script from Quicksilver! The only thing that would make it better is have the script play a .wav file of a cassette being flipped over before re-starting, but I can't seem find a free one online.

You can download the .scpt file as an attachment, but if you want to name your playlists something else you'll need to open it in Script Editor.app and tweak it yourself.

AppleScript, XML-RPC, Base64

The XML-RPC calls work as described by the documentation and examples, but they make no mention of what to do if you need to send Base64 dataFor a while it looked like I might actually be able to consolidate my current Rube Goldberg iPhoto to Movable Type solution into a single AppleScript, thanks to OS X's AppleScript Support for Remote Procedure Calls.

The XML-RPC calls work as described by the documentation and examples, but they make no mention of what to do if you need to send Base64 data; in my own tests of the Movable Type metaWeblog.newMediaObject method, a base64 encoded string simply gets handled as a plain text string on the other side, and gets written directly to the file.

On a hunch I tried passing the raw file data as an AppleScript data variable, hoping against hope that the Apple Event handler would take care of the encoding on the fly, but as far as I can tell the raw data also gets passed along as a string, leading to a munged XML-RPC message.

And naturally, there's absolutely nothing out there on the web or usenet regarding this issue... I can't believe I'm the first person to try this, but perhaps those before me have given up in disgust before getting as far as writing about it.

I dropped the good folks at developer.apple.com a note regarding the documentation, politely suggesting that some clarification would be very helpful.. we'll see what happens.

In the meantime, I may as well make the XML-RPC call via PHP with a do shell script statement.

If anyone who comes across this has a solution, I would be most grateful if you could drop me a line with a quick code snippet.

AppleScript: UNIX and HFS Filenames

In my ongoing attempt to perfect my iPhoto to Movable Type solution, I ran into the need to convert a Unix path (/tmp/foo.jpg) into an HFS style path (Mac HD:tmp:foo.jpg) that plays nicely with AppleScript's 'read' command.

Apparently this isn't all that common an issue, since file paths tend to be grabbed programmatically by AppleScript... but because I'm doing stuff with shell commands I'm working with Unix paths.

After much Googling, I found my answer in the first comment of a post on macosxhints.com.

In a nutshell, to convert a string representing a Unix file path into an HFS file path, do like so:

posix file "/path/to/my/file.txt"

This is probably not news to anybody who actually knows AppleScript, but I'm still stumbling my way along, grabbing other people's code and making educated guesses. The plain English style syntax is disconcerting.

iPhoto/AppleScript date field inconsistencies

If you're doing any parsing on the 'image_date' field as grabbed by AppleScript, beware.I just noticed a strange thing about the iPhoto 2.0 date/time field - if you don't touch the date set by iPhoto on import, AppleScript will read the date in the format 'YYYY:MM:DD HH:MM:SS'.

If you go in and tweak the date manually, however, AppleScript reads the date in the format 'YYYY-MM-DD HH:MM:SS -XXXX' where XXXX is the GMT offset. (note the hyphens between Y/M/D, compared to the colons above.)

So, if you're doing any parsing on the 'image_date' field as grabbed by AppleScript, this will probably give you grief.

Syndicate content
Syndicate content

Twitter

  • Score! http://t.co/KVDyULXM 4 years 27 weeks ago
  • @ComcastBill Thanks. 4 years 28 weeks ago
  • @wstites Thanks. @comcast is making it awfully hard for me to give them more money. 4 years 28 weeks ago
  • @comcastbill(have called 4 or 5 numbers so far. Am told I don't qualify as existing customer, no way to track who it was who called me.) 4 years 28 weeks ago
  • @ComcastBill I received a call with a bundle offer yesterday, but I lost the rep's contact info. I get the runaround calling the main #. 4 years 28 weeks ago

Older

Contact

Andy Chase
(978) 297-6402
andychase [at] gmail.com
GPG/PGP Public Key