NAME

LWP::UserAgent::iTMS_Client - libwww-perl client for Apple iTunes music store

SYNOPSIS

use LWP::UserAgent::iTMS_Client;

# search the Store   
my $ua = LWP::UserAgent::iTMS_Client->new(
  user_id => 'me@you', password => 'pwd');

my $listings = $ua->search( song => 'apples' );
foreach my $album (@{$listings}) { print $album->{songName} }

$listings = $ua->search(artist => 'Vangelis', song => 'long', 
  genre => 'Electronic');
foreach my $a (@{$results2}) { 
  foreach (sort keys %$a) { print "$_ => ", $a->{$_}, "\n" } 
}

# get my authorization keys
my $ua = new LWP::UserAgent::iTMS_Client(
    account_type => 'apple',
    user_id => 'name@email.org',
    password => 'password',
);
$ua->retrieve_keys_from_iTMS;

DESCRIPTION

This perl module implements a user agent which can interact with the Apple iTunes Music Store (iTMS). In the long run, we envision a Perl extension that will allow automated browsing and purchasing of music. For example, the module might be used to automatically get samples of new albums by a particular artist, or buy everything on a Top Ten list weekly.

LWP::UserAgent::iTMS_Client is a sub-class of LWP::UserAgent and implements the methods of UserAgent, but does so using Apple's officially undocumented protocols. Because these protocols change with revisions to iTunes, the modules may occasionally lag Apple's changes until this module, too, is updated.

The initial versions of this user agent will concentrate on browsing the listings and obtaining the user's keys.

METHODS

new
# set up new instance for anon search
my $ua = 
  LWP::UserAgent::iTMS_Client->new(user_id => 'me@you', password => 'pwd');

# set up for login
my $ua = new LWP::UserAgent::iTMS_Client(
    account_type => 'apple',
    user_id => 'name@email.org',
    password => 'password',
    gu_id => 'CF1121F1.13F11411.11B1F151.1611F111.1DF11711.11811F19.1011F1A1',
);

Create a new LWP::UserAgent::iTMS_Client object. Options are:

account_type
    Either 'apple' or 'aol', this determines where the authentication 
    password is to be checked--on an AOL user database or with Apple's 
    accounts.
    
user_id (required)
    User name, usually an email address.
    
ds_id 
    A user identifier used by iTMS for authentication. May be useful if
    accessing local key files.
    
gu_id 
    A user's machine identifier used by iTMS for authorization.
    
password (required)
    The user's own (user typed, in iTunes) password.
    
deauth_wait_secs
  Reserved, not currently implemented. 
  This is to be a mandatory wait before deauthorizing a machine.
  
country 
    The country where the user's account is based. Determines purchase 
    currency, etc.

home_dir 
    The directory where the drms keys subdirectory is located. Generally it
    may be best to allow the module to locate this by default.
    
maybe_dot 
    Determines if the drms subdirectory is called '.drms' or 'drms', again,
    best left to the default.

path_sep
    Generally '/'. Path separator for the local OS.
request

Sends a request to the iTunes Music Store. Handles encryption and compression, then returns an HTTP::Response object, as an overloaded method of the base LWP::UserAgent. Generally not called directly unless you know what you are doing.

use LWP::UserAgent::iTMS_Client;

my $ua = LWP::UserAgent::iTMS_Client->new;

my $results1 = $ua->search(song => 'Day', composer => 'Lennon'); print "\nResults for song => regret, artist => New Order:\n"; foreach my $a (@{$results1}) { foreach (sort keys %$a) { print "$_ => ", $a->{$_}, "\n" } }

my $results2 = $ua->search(artist => 'Vangelis', song => 'long ago'); print "\nResults for song => apples:\n"; foreach my $a (@{$results2}) { foreach (sort keys %$a) { print "$_ => ", $a->{$_}, "\n" } }

The following types of searches should be supported: album, artist, composer, song, genre, all. If used, 'all' should override other specifications.

retrieve_keys_from_iTMS

Get the keys from the Store. Attempts to be compatible with key locations used by default by the Videolan project's media player (FairKeys compatibility). This should generally be used with a gu_id known by the user, preferentially one given as a gu_id => 11111111.11111111.11111111.11111111.11111111.11111111 (6 8-digit hex numbers separated by periods) argument to new.

deauthorize_gu_id

$ua->deauthorize_gu_id($id);

Deauthorize the machine used to get the keys.

retrieve_keys_with_temp_id

ua->retrieve_keys_with_temp_id(\&callback);

Create a temporary machine ID (you need to have one of your 5 machine useages for iTunes available), get the keys with this virtual machine's authorization, then deauthorize. Note that since this may result in an additional key being created, you should limit the number of times you do this. If you generally only purchase music on one or two machines that do not change ID's, and only play copied music on your other (iPod?) machines, once downloading your keys may be enough. The program will display a progress bar betwwen key retrieval and deauthorization. The optional argument is to allow custom display of the wait period, which by default prints to stdout. The optional callback routine must accept a single argument which may have the values 'begin', an integer between 0 and 100, and 'end'.

purchase
$ua->purchase($song_id);

Not yet working, will be soon we hope

BUGS

The searches do not work if both 'composer' and 'artist' are specified.

Overuse of the purchase routine might allow you to spend more on music than you intended. This might be a bug, from the perspective of your budget. Enjoy :).

SEE ALSO

LWP::UserAgent, Audio::M4P::QuickTime, Audio::M4P::Decrypt, Mac::iTunes, Net::iTMS

AUTHOR

William Herrera wherrera@skylightview.com.

SUPPORT

Questions, feature requests and bug reports should go to <wherrera@skylightview.com>.

COPYRIGHT

    Copyright (c) 2003-2005 William Herrera. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

4 POD Errors

The following errors were encountered while parsing the POD:

Around line 565:

'=item' outside of any '=over'

Around line 684:

You forgot a '=back' before '=head1'

Around line 694:

'=item' outside of any '=over'

Around line 696:

You forgot a '=back' before '=head1'