The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Net::iTMS - Low(ish)-level interface to the iTunes Music Store (iTMS)

SYNOPSIS

    use Net::iTMS;

    my $iTMS    = Net::iTMS->new;
    my $results = $iTMS->search_for('Elliott Smith');
    
    my %tracklist = %{$results->TrackList};
    # See the Net::iTMS::XML doc for other methods

DESCRIPTION

Net::iTMS is a low-but-not-too-low-level interface to the iTunes Music Store. It handles the fetching, decrypting, and uncompressing of content as well as provides a few convenience methods.

Further development will most likely include more convenience methods for common tasks. If there is a method you'd particularly like to see, contact me (see website in AUTHOR section) about it, and I'll consider writing it.

Patches are welcome. : )

Methods

All methods return undef on error and (should) set an error message, which is available through the error method. (Unless I note otherwise.)

Nota Bene: Most of information-fetching methods return, by default, a Net::iTMS::XML object which can be used to selectively extract information from the XML. If a different XML "parser" is in use, the return value could be something totally different.

new([ debug => 1, [...] ])

Takes an argument list of key = value> pairs. The options available are:

tmpdir => '/some/path'

Used to specify the path to the directory where temporary files should be created. Default's to File::Temp's default.

debug => 0 or 1

If set to a true value, debug messages to be printed to STDERR.

parser => 'Foo::Bar'

"Parser" to use in place of the default Net::iTMS::XML. Don't change this unless you know what you're doing.

Returns a blessed hashref (object) for Net::iTMS.

search_for($terms)

Does a simple search of the catalog.

get_album($albumId)

Takes an albumId and fetches the album information page.

get_artist($artistId)

Takes an artistId and fetches the artist information page.

get_artist_biography($artistId)

Takes an artistId and fetches the artist's iTMS biography, if there is one.

get_artist_influencers($artistId)

Takes an artistId and fetches the artist's iTMS influencers, if there are any.

get_artist_discography($artistId)

Takes an artistId and fetches all the albums (really a browseArtist request).

fetch_iTMS_info($url, [ gunzip => 1, decrypt => 0 ])

This is one of the lower-level methods used mostly internally for convenience. Still, it might be of use to implement something I haven't thought of.

It takes a URL (that should be for the iTMS) as the first argument and an optional hashref of options as the second argument. The available options are:

gunzip => 0 or 1

A true value means the (presumably) gzipped content is gunzipped. A false value means it is not.

Default is 1 (unzip content).

decrypt => 0, 1, or 2

A true value other than 2 means the content retrieved from the URL is first decrypted after fetching if it appears to be encrypted (that is, if no initialization vector was passed as a response header for the request). A false value means no decryption is done at all. A value of 2 means decryption will be forced no matter what.

Default is 1 ("intelligent" decrypt), which should work for most, if not all, cases.

error

Returns a string containing an error message (if there is one). Usually useful after a method has returned undef for finding out what went wrong.

TODO / FUTURE DIRECTION

I'm thinking of totally changing the public interface.

The subclasses Net::iTMS::Album, Net::iTMS::Artist, Net::iTMS::Song, et al. would represent individual artists, albums, and songs.

Code would then look like:

    my $iTMS = Net::iTMS->new;

    my $artist = $iTMS->get_artist(123456);
    # or maybe...
    my $artist = $iTMS->find_artist('Elliott Smith');

    print "Artist: ", $artist->name, "\n";

    for my $album ($artist->discography) {
        print $album->title, "(", $album->year, ")\n";

        for my $track ($album->tracks) {    # also $album->songs
            print "\t ", $track->number, ": ", $track->title, "\n";
        }
    }

instead of

    my $iTMS = Net::iTMS->new;

    my $artist = $iTMS->get_artist(123456);
    print "Artist: ", $artist->{name}, "\n";
    
    for my $album ($iTMS->get_artist_discography(123456)) {
        print $album->{playlistName}, ..., "\n";
        
        my $tracks = $iTMS->get_album($album->{playlistId})
                          ->genericPlist;
        
        for my $track (@$tracks) {
            print "\t ", $track->{trackNumber}, ": ", $track->{songName}, "\n";
        }
    }
    

Could this be made efficient -- that is, minimal # of HTTP requests? Would it require a major rewrite of existing XML munging code? It would certainly be easier to work with.

LICENSE

Copyright 2004, Thomas R. Sibley.

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/ or send a letter to:

    Creative Commons
    559 Nathan Abbott Way
    Stanford, California 94305, USA.

AUTHOR

Thomas R. Sibley, http://zulutango.org:82/