The iTunes Helper tool

The _iTunes_ Helper tool

This tiny library will parse a playlist in the .txt format output by iTunes.
You may select a sub-playlist, and output it again.  I use this tool to select
a subset of my library to put on my iPod.  Here's how I do it:

1) Select the "Library" in iTunes
2) use "File>Export Song List..." to write the file "Library.txt"
3) use the following code to select about 4.6 Gig from the Library:

(require (planet "" ("clements" "iTunes-helper.plt" 1 0))
         (planet "" ("clements" "iTunes-helper.plt" 1 0)))

(let* ([library (parse-playlist "/Users/clements/Documents/Library.txt")]
       [selected (select-playlist library 4600000000)])
  (call-with-output-file "/Users/clements/Documents/new-list.txt"
    (lambda (port)
      ((music-db-outputter library) selected port))

4) in iTunes, use "File>Import..." to pull the new song list back in.
5) set the iPod to synchronize with the selected playlist.

Too many steps?  Perhaps, but I can't spend the time to get the apple events

The library consists of two modules, _parse-playlist_ and _select-playlist_.
The first of these is moderately general and would be useful to anyone
selecting a playlist.  The second one encodes personal preferences (I use a
weighted scheme where songs with higher ratings are more likely to be chosen)
and is probably most useful a) if you agree with me, b) if you're too lazy to
change it, or c) as a basis for modification.

parse-playlist provides the following functions:

> (parse-playlist filename) : reads the named file and returns a music-db

A music-db is a three-element structure containing an indexer, a list of
records, and an outputter. 

> (music-db? value) : returns true if the value is a music-db

> (music-db-indexer music-db) : returns a procedure which when given a string
  produces a function mapping records to the content of that field (or #f if
  the record does not have that field.)

> (music-db-records music-db) : returns the list of records

> (music-db-outputter music-db) : returns a procedure which accepts a list of
  records and a port and writes those records to the port in the iTunes
  playlist format.

There are two parameters that govern the parser's operation.

> (required-fields)
> (required-fields field-list)

The required-fields is a list of strings.  A record without all of these fields
will be discarded.  NB: if a name specified in the required-fields isn't even
defined by the .txt database, parse-playlist will signal an error.

> (verbose-output?)
> (verbose-output? boolean)

When the verbose-output? parameter is set to #t, you'll get warnings for each
record in the database that's discarded (because it's missing required fields).

Select-playlist provides only one function:

> (select-playlist music-db max-size) : return a list of records chosen from
  the music-db according to criteria defined internally.  As mentioned before,
  useful if you agree with my weighting scheme.