Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
WWW::Myspace(3)	      User Contributed Perl Documentation      WWW::Myspace(3)

       WWW::Myspace - Access profile information from Perl

       Version 0.92

       March 2007: Using WWW::Myspace for commenting, messaging, or adding
       friends will probably get your Myspace account deleted or disabled.

SYNOPSIS provides	methods	to access your account and
       functions automatically.	It provides a simple interface for scripts to
       log in, access lists of friends,	scan user's profiles, retreive profile
       data, send messages, and	post comments.

	   use WWW::Myspace;
	   my $myspace = WWW::Myspace->new ($account, $password);
	   my $myspace = new WWW::Myspace; # Prompts for email and password
	   unless ( $myspace->logged_in	) { die	"Login failed: " . $myspace->error }

	   my (	@friends ) = $myspace->get_friends();

       This module is designed to help you automate and	centralize redundant
       tasks so	that you can better handle keeping in personal touch with
       numerous	friends	or fans, or coordinate fan communications among
       multiple	band members. This module operates well	within MySpace's
       security	measures. If you're looking for	a spambot, this	ain't it.

       WWW::Myspace works by interacting with the site through a UserAgent
       object, using HTTP::Request::Form to process forms. Since by nature web
       sites are dynamic, if you find that some	interaction with the site
       breaks, check for a new version of this module (or if you go source
       diving, submit a	patch).	You can	run "cpan -i WWW::Myspace" as a	cron
       job or before running your scripts, if appropriate, to make sure	you
       have the	latest version.

       The new method takes the	following options, all of which	are optional.
       See the accessor	methods	below for defaults.  Any option	can be passed
       in a hash or hashref to the "new" method, and retreived or set using
       the appropriate accessor	method below.

	account_name =>	'myaccount',
	password => 'mypass',
	cache_dir => '/path/to/dir',
	cache_file => 'filename', # $cache_dir/$cache_file
	auto_login => 1	 # 1 or	0, default is 1.
	human => 1  # Go slow.	Saves bandwidth.

       These methods can be used to set/retreive the respective	option's
       value.  They're also up top here	to document the	option,	which can be
       passed directly to the "new" method.

       Sets or returns the account name	(email address)	under which you're
       logged in.  Note	that the account name is retreived from	the user or
       from your program depending on how you called the "new" method. You'll
       probably	only use this accessor method to get account_name.


       The following would prompt the user for their login information,	then
       print out the account name:

	   use WWW::Myspace;
	   my $myspace = new WWW::Myspace;

	   print $myspace->account_name;

	   $myspace->account_name( '' );
	   $myspace->password( 'other_accounts_password' );

       WARNING:	If you do change account_name, make sure you change password
       and call	site_login.  Changing account_name doesn't (currently) log you
       out, nor	does it	clear "password".  If you change this and don't	log in
       under the new account, it'll just have the wrong	value, which will
       probably	be ignored, but	who knows.

       Sets or returns the password you	used, or will use, to log in. See the
       warning under "account_name" above - same applies here.

       WWW::Myspace stores the last account/password used in a cache file for
       convenience if the user's entering it. Other modules store other	cache
       data as well.

       cache_dir sets or returns the directory in which	we should store	cache
       data. Defaults to $ENV{'HOME'}/.www-myspace.

       If using	this from a CGI	script,	you will need to provide the account
       and password in the "new" method	call, or call "new" with "auto_login
       => 0" so	cache_dir will not be used.

       Sets or returns the name	of the file into which the login cache data is
       stored. Defaults	to login_cache.

       If using	this from a CGI	script,	you will need to provide the account
       and password in the "new" method	call, so cache_file will not be	used.

       Really only useful as an	option passed to the "new" method when
       creating	a new WWW::Myspace object.

	# Don't	log in,	just create a new object
	my $myspace = new WWW::Myspace(	auto_login => 0	);

       Defaults	to 1 for backwards compatibility.

       When set	to a true value	(which is the default),	adds delays to make
       the module act more like	a human.  This is both to offset "faux
       security" measures, and to conserve bandwidth.  If you're dumb enough
       to try to use multiple accounts to spam users who don't want to hear
       what you	have to	say, you should	turn this off because it'll make your
       spamming	go faster.

       This is only here by request and	should probably	be left	alone.
       Setting max_get_attempts	controls the number of times the module	will
       attempt to get a	page.  You can make your script	really robust by
       setting this to a really	high number.  For example setting it to	about
       17280 would make	the module try to get a	given page for about 24	hours
       before giving up.  Default is 20.  You could also set this to a lower
       number if you wanted to be "nice" to Myspace, although set get_page
       mostly retries on errors, this is a bit pointless.  Note	though that on
       some occasions if a regular expression on the page being	requested
       doesn't match (possibly due to a	change in the site), get_page will
       keep trying a page that will never load up to max_get_attempts times.

       This is the form	version	of max_get_attempts.  This controls the	number
       of times	the submit_form	function will attempt to submit	a form before
       giving up.  This	defaults to 5.	This should probably be	kept at	5
       since posting a form means you're usually sending some data (i.e. a
       comment), so in the event of a problem (such as the regular expression
       matching	issue mentioned	in max_get_attempts above), you	could in
       theory be posting a successful form up to max_post_attempts times.  In
       normal operation, however, submit_form will attempt to post until the
       post is successful, no matter what the outcome, so it will only retry
       if it gets an error page	or the page doesn't match an expected regular
       expression.  That is, when you're using myspace and have	to keep	trying
       things, submit_form does	the same thing,	but only up to
       max_post_attempts times.	 Change	at your	own risk.

       This can	be set to a reference to a subroutine that will	be called when
       a CAPTCHA is encountered.  The subroutine will be passed	two
       parameters:  the	value of the "captcha_handler_param" field (see
       below), and a hash reference containing the following elements:

       o   "image_data"	-- the actual binary image data	in a string

       o   "image_type"	-- the MIME type of the	data in	"image_data"

       o   "image_url" -- the absolute URL from	where the CAPTCHA was
	   retrieved; don't try	and download this again	yourself or it will
	   probably show a different CAPTCHA and the response will be rejected

       The following elements may exist	in the hash as well (always check that
       a value is defined before trying	to use it) :

       o   "attempt" --	beginning at 1,	this value is incremented each time a
	   CAPTCHA response was	rejected

       o   "action" -- the type	of action that prompted	the CAPTCHA response;
	   currently can be one	of:  "send_friend_request", "send_message",

       o   "friend_requires_captcha" --	for the	"send_friend_request" action,
	   this	value will evaluate to "true" if the person being added
	   requires a CAPTCHA response for all friend requests (configured in
	   Privacy Settings).  Currently broken	-- see KNOWN ISSUES.

       The handler is expected to return "undef" if it can't (or doesn't want
       to) provide a response to the CAPTCHA.  Otherwise, it should return a
       hashref containing only one element:

       o   "response" -- a string which	is thought to be the solution for the
	   CAPTCHA;  case insensitive but shouldn't contain spaces

       Here is an example of a fully working CAPTCHA handler:

	   sub my_captcha_handler {
	       my $self	= shift;   # Unused in this handler
	       my $data	= shift;

	       # Some people require that everyone solves a CAPTCHA to be able to add
	       #  them.	 As an example,	we decide not to respond those CAPTCHAs.
	       return if ( $data->{'friend_requires_captcha'} );

	       # Give up if 5 attempts to solve	a CAPTCHA failed for the same action
	       if ( defined $data->{'attempt'} && $data->{'attempt'} > 5 ) {
		   warn	"Failed	".($data->{'attempt'}-1)." times to solve CAPTCHA\n";
		   warn	" for action '".$data->{'action'}."'\n"	if $data->{'action'};

	       my $filename = "captcha";

	       # Try to	add a sensible filename	extension
	       if ($data->{'image_type'} eq "image/jpeg") {
		   $filename .=	".jpg";
	       } elsif ($data->{'image_type'} eq "image/png") {
		   $filename .=	".png";
	       } elsif ($data->{'image_type'} eq "image/gif") {
		   $filename .=	".gif";

	       # Save CAPTCHA image to file
	       open FILE, ">$filename"
		   or die "Couldn't write '$filename':	$!\n";
	       print FILE $data->{'image_data'};
	       close FILE;

	       # Ask user to manually input the	solution
	       print "Please see the CAPTCHA in	'$filename' and	enter the solution:\n";
	       my $response = <STDIN>;
	       chomp $response;

	       return {	response => $response };

	   use WWW::Myspace;

	   my $myspace = new WWW::Myspace;

	   # Enable the	user-defined CAPTCHA handler

	   # The CAPTCHA handler could be tested like this
	   my $solution	= $myspace->_handle_captcha( {
	       image_url => ''
	   } );

	   print "Got CAPTCHA solution:	 '$solution'\n";

       This field's value is passed as the first parameter to the CAPTCHA
       handler.	 By default it contains	"undef".  Some examples	of how this
       can be used are:

       o   A string identifying	the Myspace account

       o   A reference to the WWW::Myspace object

       o   A reference to the CAPTCHA handler instance,	if it is object-

       o   A hash reference containing multiple	data items which the handler
	   considers useful

       If you have an API key for, you can set it using this
       method, or pass it to the "new" method when creating the	myspace
       object.	Methods	that support it	will use captchakiller to process

	   use WWW::Myspace;

	   my $myspace = new WWW::Myspace( captcha_killer_api_key => 'asdfjhasdfe' );

       When this value is set, "captcha_handler" will be automatically set to
       the built-in Captcha Killer handler.

       This setting is for the Captcha Killer handler only.

       Sets or returns the number of attempts that should be made to retreive
       the catpcha code	(basically, how	long it	should wait before it gives up
       - each try takes	about 5	seconds).  Defaults to 20.

   new(	$account, $password )
   new(	)
       If called without the optional account and password, the	new method
       looks in	a user-specific	preferences file in the	user's home directory
       for the last-used account and password. It prompts for the username and
       password	with which to log in, providing	the last-used data (from the
       preferences file) as defaults.

       Once the	account	and password have been retreived, the new method
       automatically invokes the "site_login" method and returns a new
       WWW::Myspace object reference. The new object already contains the
       content of the user's "home" page, the user's friend ID,	and a
       UserAgent object	used internally	as the "browser" that is used by all
       methods in the WWW::Myspace class. is now a subclass of WWW::Myspace::MyBase (I couldn't
       resist, sorry), which basically just means you can call new in many

	       use WWW::Myspace;

	       # Prompt	for username and password
	       my $myspace = new WWW::Myspace;

	       # Pass just username and	password
	       my $myspace = new WWW::Myspace( '', 'mypass'	);

	       # Pass options as a hashref
	       my $myspace = new WWW::Myspace( {
		   account_name	=> '',
		   password => 'mypass',
		   cache_file => 'passcache',
	       } );

	       # Hash
	       my $myspace = new WWW::Myspace(
		   account_name	=> '',
		   password => 'mypass',
		   cache_file => 'passcache',
		   auto_login => 0,

	       # Print my friend ID
	       print $myspace->my_friend_id;

	       # Print the contents of the home	page
	       print $myspace->current_page->decoded_content;

	       # Print all my friends with a link to their profile.
	       @friend_ids = $myspace->get_friends;
	       foreach $id ( @friend_ids ) {
		   print ''.

	       # How many friends do we	have? (Note: we	don't include Tom
	       # because he's everybody's friend and we	don't want to be
	       # bugging him with comments and such).
	       print @friend_ids . " friends (not incl Tom)\n";

       It is possible to detect	if the supplied	username or password were
       invalid by doing	the following:

	   use WWW::Myspace;
	   my $myspace = new WWW::Myspace;

	   if (	$myspace->error	=~ qr/Login Failed.*username.*password/is )
	       die "Invalid username or	password!\n";

       Logs into the myspace account identified	by the "account_name" and
       "password" options.  You	don't need to call this	right now, because
       "new" does it for you.  BUT I PLAN TO CHANGE THAT.  You don't need to
       be logged in to access certain functions, so it's semi-silly to make
       you log in the second you call "new".  Plus, it's not good practice to
       have "new" require stuff. Bad me.

       If you call the new method with "auto_login => 0", you'll need to call
       this method if you want to log in.

       It's also called	automatically if the _check_login method finds that
       you've been mysteriously	logged out, for	example	if were
       written in Cold Fusion running on Windows.

       If the login gets a "you	must be	logged-in" page	when you first try to
       log in, $myspace->error will be set to an error message that says to
       check the username and password.

       Once login is successful	for a given username/password combination, the
       object "remembers" that the username/password is	valid, and if it
       encounters a "you must be logged-in" page, it will try up to 20 times
       to re-login.  Clever, huh?

   _set_locale(	$locale	)
       Changes the locale in use by the	current	Myspace	session.  This is
       called immediately after	login to set the locale	to en-US.  This	is
       necessary for the module's regexp matches to work as intended.

       The "locale" parameter is in ISO	3166-1-alpha-2 format, e.g. 'en-US'.

       At present, this	is implemented by modifying the	MSCulture cookie
       directly, changing the PreferredCulture setting.	 This mimics the
       behaviour of the	JavaScript used	on the website.

   _get_login_forms( $page )
       Attempts	to identify any	login forms on the page	whose HTML content is
       given by	$page.	Login forms are	identified by the presence of inputs
       for both	email address and password.

       Returns an array	containing zero	or more	hashes,	each representing a
       login form that was found on the	page.  The hashes are stored in	the
       array in	the same order the forms were declared in the HTML of

       Each hash provides the following	key-value pairs:

       o   "name" -- the name of the HTML form (may be an empty	string if no
	   name	was defined)

       o   "email_input_name" -- the name of the form input for	specifying the
	   account's registered	e-mail address

       o   "password_input_name" -- the	name of	the form input for specifying
	   the account's password

       Security	warning:  submitting login credentials to login	forms detected
       on any page other than the homepage may be unsafe.

       Pass this parameters you	wish the WWW::Mechanize	object to use, inside
       a hash reference. for example:

	     onerror =>	undef,
		 agent => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
	     stack_depth => 1,
	     quiet => 1,

       See the docs for	WWW::Mechanize for more	information. You should	really
       know what you are doing before using this feature.

       Clears the current web browsing object and resets any login-specific
       internal	values.	 Currently this	drops and creates a new	WWW::Mechanize
       object.	This may change	in the future to actually clicking "logout" or

       This handy little convenience method returns a string of	HTML code that
       is a login form pre-filled with the account_name	and password.  I use
       it in a little "Dashboard" script I wrote that displays the
       notifications and a Login button.

	use WWW::Myspace;
	use CGI	qw/:standard/;;
	my $myspace = new WWW::Myspace;

	# Display a login form
	print header,
	    start_html('Is it worth logging in?'),

       Returns true if login was successful. When you call the new method of
       WWW::Myspace, the class logs in using the username and password you
       provided	(or that it prompted for).  It then retreives your "home" page
       (the one	you see	when you click the "Home" button on, and
       checks it against an RE.	 If the	page matches the RE, logged_in is set
       to a true value.	Otherwise it's set to a	false value.

	- This method is only set on login. If you're logged out somehow,
	  this method won't tell you that (yet - I may add that	later).
	- The internal login method calls this method to set the value.
	  You can (currently) call logged_in with a value, and it'll set
	  it, but that would be	stupid,	and it might not work later
	  anyway, so don't.


	my $myspace = new WWW::Myspace;
	unless ( $myspace->logged_in ) {
	   die "Login failed\n";

	# This will try	forever	to log in
	my $myspace;

	do {
	   $myspace = new WWW::Myspace(	$username, $password );
	} until	( $myspace->logged_in );

       This value is set by some methods to return an error message.  If
       there's no error, it returns a false value, so you can do this:

	$myspace->get_profile( 12345 );
	if ( $myspace->error ) {
	    warn $myspace->error . "\n";
	} else {
	    # Do stuff

       Returns a reference to an HTTP::Response	object that contains the last
       page retreived by the WWW::Myspace object. All methods (i.e. get_page,
       post_comment, get_profile, etc) set this	value.


       The following will print	the content of the user's profile page:

	   use WWW::Myspace;
	   my $myspace = new WWW::Myspace;

	   print $myspace->current_page->decoded_content;

       The internal WWW::Mechanize object.  Use	at your	own risk: I don't
       promise this method will	stay here or work the same in the future.  The
       internal	methods	used to	access Myspace are subject to change at	any
       time, including using something different than WWW::Mechanize.

       Returns a hash of status	codes and printable indicators for "New"
       indicators ("New	Messages!", "New Comments!", etc).  Note that you
       probably	want to	call this right	after logging in, as if	you use	any of
       the "read" methods, Myspace will	reset that indicator.  For example, if
       you use "get_inbox", Myspace will think you looked at your mail.

	Codes returned are:
	NC  => New Comments!
	NM  => New Messages!
	NFR => New Friend Requests!
	NIC => New Image Comments!
	EV  => New Event Invitation!
	BC  => New Blog	Comments!
	BP  => New Blog	Posts!

	# Print	all notifications
	use WWW::Myspace;
	my $myspace = new WWW::Myspace(	$account, $password );

	my $notifiers =	$myspace->get_notifications;

	foreach	$code (	keys( %notifiers ) ) {
	   print $notifiers{ $code };

	# CGI script to	display	notifications and a Login button
	# to click if it's worth logging in (be	sure you provide the
	# account and password ;-):

	use CGI	qw/:standard/;
	use WWW::Myspace;
	my $myspace = new WWW::Myspace(	$account, $password );

	print header,
	    start_html('Is it worth logging in?');

	my ( %notifiers	) = $myspace->get_notifications;

	foreach	$code (	keys( %notifiers ) ) {
	    print $notifiers{ $code }, br;

	print p, $myspace->get_login_form, p,

       Returns the friendID of the user	you're logged in as.  Croaks if	you're
       not logged in.


	   print $myspace->my_friend_id;

   is_band( [friend_id]	)
       Returns true if friend_id is a band profile.  If	friend_id isn't
       passed, returns true if the account you're logged in under is a band
       account.	 If it can't get the profile page it returns -1	and you	can
       check $myspace->error for the reason (returns a printable message).
       This is used by send_friend_request to not send friend requests to
       people who don't	accept them from bands,	as myspace passively accepts
       the friend request without displaying an	error, but doesn't add the
       friend request.


	$myspace->is_band( $friend_id );

	if ( $myspace->error ) {
	    die	$myspace->error	. "\n";
	} else {
	    print "They're a band, go listen to	them!\n";

       IMPORTANT: You can NOT assume that a profile is a personal profile if
       is_band is false.  It could be a	film profile or	some future type of
       profile.	 There is currently no test for	a personal or film profile.

   is_comedy( [	$friend_id | friend_id => $friend_id ] [ page => $page ] );
       Returns true if the specified profile is	a comedy page.	The method
       checks for the existence	of the "Myspace	Comedy"	graphic	on the page.

   is_private( friend_id => $friend_id || page => $page	)
       Returns true if we think	the profile has	been set to private.  You
       should note that	you will get the most accurate results if you use this
       method while *not* logged in.  If you *are* logged in and you check the
       profile of someone who is your friend, you will never get a true
       response	returned you, even if this person has their profile set	to
       private.	 There will be no warnings or errors if	you call this method
       while logged in.	 We trust you'll "do the right thing".

       You can choose to pass either a friend_id OR a Myspace profile page in
       the form	of a response object.  You may use the get_profile method or
       just fetch the page on your own use WWW::Mechanize or an	object which
       provides	a $obj->decoded_content	method.

       Returns true (1)	if profile is private.	Otherwise returns false	(0).
       Returns undef and sets $myspace->error if there is an error.

	   # Thorough privacy check with error checking
	   if (	$myspace->is_private( friend_id	=> $friend_id )	) {
	       print "Ooh, it's	private...\n";
	   } elsif ( $myspace->error ) {
	       print $myspace->error;
	   } else {
	       print "It's so not private.\n";

   is_invalid( friend_id => $friend_id || page => $page	)
       Returns true if we think	the profile is invalid or disabled.

       You can choose to pass either a friend_id OR a Myspace profile page in
       the form	of a response object.  You may use the get_profile method or
       just fetch the page on your own use WWW::Mechanize or an	object which
       provides	a $obj->decoded_content	method.

       Returns true (1)	if profile is invalid/disabled.	 Otherwise returns
       false (0).  Returns undef and sets $myspace->error if there is an

	   # Thorough invalid profile check with error checking
	   if (	$myspace->is_invalid( friend_id	=> $friend_id )	) {
	       print "Profile is invalid or disabled.\n";
	   } elsif ( $myspace->error ) {
	       print $myspace->error;
	   } else {
	       print "Profile seems fine to me.\n";

       Returns the profile name	of the logged in account. This is the name
       that shows up at	the top	of your	profile	page above your	picture.  This
       is NOT the account name.

       Normally	you'll only retreive the value with this method. When logging
       in, the internal	login method calls this	routine	with the contents of
       the profile page	and this method	extracts the user_name from the	page
       code. You can, if you really need to, call user_name with the contents
       of a page to have it extract the	user_name from it. This	may not	be
       supported in the	future,	so it's	not recommended.

   friend_user_name( [friend_id] )
       Returns the profile name	of the friend specified	by friend_id.  This is
       the name	that shows up at the top of their profile page above their

       If no friend_id is specified, this method scans the current page	so you
       can do:

	$myspace->get_profile( $friend_id );
	print $myspace->friend_user_name;

       (Note, DON'T go using this to sign comments because most	users use
       funky names and it'll just look cheesy.	If you really want to
       personalize things, write a table mapping friend	IDs to first names -
       you'll have to enter them yourself).

   friend_url( [friend_id] )
       Returns the custom URL of friend_id's profile page. If they haven't
       specified one, it returns an empty string.


	foreach	my $friend_id (	$myspace->get_friends )	{
	    my $url = $myspace->friend_url( $friend_id );
	    if ( $url )	{
		print 'Friend's	custom URL:' .
		$myspace->friend_url( $friend_id );
	    } else {
		print 'Friend doesn't have a custom URL. Use: '.
		'' . $friend_id;

       If no friend_id is specified, this method scans the current page	so you
       can do:

	$myspace->get_profile( $friend_id );
	print $myspace->friend_url;

   friend_id ( friend_url )
       Returns the friend_id corresponding to a	given custom URL.  (This is
       basically the reverse of	friend_url).

	# Print	the friendID of	Amber G:
	print $myspace->friend_id("iamamberg");

	> 37033247

       If no friend_url	is specified, this method scans	the current page so
       you can do:

	$myspace->get_profile( $friend_id );
	print $myspace->friend_url;

   "get_real_name( [ $friend_id	| friend_id =" $friend_id | page => $page ] )>
       Tries to	determine the real name	of the person whose profile is
       specified.  It does this	by looking for "my name	is ____" or "my	real
       name is _____" on their profile page.  The regex	used takes several
       common myspace grammar/spelling erorrs into account.

       If passed no arguments, real_name parses	the current page. If passed a
       friend_id, it calls get_profile to retrieve the friend's	profile	page.
       If passed a page	(an HTTP::Response object), it parses

       Returns the logged in user's friend count as displayed on the profile
       page ("You have NN friends").

       Note that due to	one of WWW::Myspace's many bugs, this count may	not be
       equal to	the count of friends returned by get_friends.

       Like the	user_name method, friend_count is called by the	internal login
       method with the contents	of the user's profile page, from which it
       extracts	the friend count using a regexp	on the "You have NN friends"
       string. If you need to, you can do so also, but again this might	not be
       supported in the	future so do so	at your	own risk.

   last_login_ymd ( [$friend_id	|| $friend_url || friend_id => $friend_id ||
       page => $page] )
       Returns the "Last Login"	date for a profile in YYYY-MM-DD form (ISO

       Parameter is the	same as	for "last_login";  please refer	to that
       function's documentation.

       This date format	allows lexical comparisons to be made, for example:

	   # Remember to use eq, gt, lt	here instead of	==, <, >
	   if (	$myspace->last_login_ymd( $friend_id ) lt "2005-04" ) {
	       print "They haven't logged in since before April	2005!\n"

       Returns "undef" on failure.

   last_login( [$friend_id || $friend_url || friend_id => $friend_id ||	page
       => $page] )
       Returns the "Last Login"	date for a profile in POSIX time format, aka
       UNIX time: seconds since	the epoch (1970-01-01T00:00:00Z) excluding
       leap seconds.

       Parameter can be	a friend ID, a friend URL, or a	previously-retrieved
       HTTP::Response object;  if unspecified it will use the current page,
       for example:

	   $myspace->get_profile( $friend_id );

	   ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
	       localtime( $myspace->last_login );


	   if (	$myspace->last_login( $friend_id ) < today - 86400 * 90	) {
	       print "They haven't logged in in	90 days!\n"

       Returns "undef" on failure.

   get_profile(	$friend_id || $friend_url )
       Gets the	profile	identified by either $friend_id	or $friend_url.	That
       means both of these will	work:

	   $myspace->get_profile( "12345" );
	   $myspace->get_profile( "hilaryduff" );

       Returns a reference to an HTTP::Response	object for the profile page.

       The following displays the HTML source code of the profile identified
       by $friend_id:

	   my $res = $myspace->get_profile( $friend_id );
	   print $res->decoded_content;

   profile_views( $friend_id ||	friend_id => $friend_id	|| page	=> $page )
       Returns the listed number of Profile Views for a	given friend_id.  This
       has only	been tested on band profiles.  You can choose to pass either a
       friend_id OR a Myspace profile page in the form of a response object.
       You may use the get_profile method or just fetch	the page on your own
       use WWW::Mechanize or an	object which provides a	$obj->decoded_content


	my $views = $myspace->profile_views( friend_id => $friend_id );


	my $page = $myspace->get_profile( $friend_id );
	$myspace->profile_views( page => $page );

   comment_count( $friend_id ||	friend_id => $friend_id	|| page	=> $page )
       Returns the listed number comments posted a given friend_id.  Behaves
       the same	way as profile_views.  See profile_views for documentation on
       passing parameters to this function.

   get_basic_info( $friend_id || friend_id => $friend_id || page => $page );
       This routine takes either a friend_id or	a page response	object and
       returns a hash of information containing:

	country	    - country in profile (names	of countries are as
		      standardized on MySpace)
	cityregion  - the line with city and region information	(this
		      is free text)
	headline    - whatever it says next to the picture (including quotes)
	lastlogin   - date of last login
	city	    - city*
	region	    - region*

       in addition, for	profiles of individuals	returns

	age	    - as number
	gender	    - as text, either male or female

       while for band/music profile returns

	profileviews - number of people	that checked the profile


	my ( %info ) = $myspace->get_basic_info( $friend_id );

	print "Your friend is $info{'age'} years old and is a $info{'gender'}.\n";

	# sample output:
	Your friend is 25 years	old and	is a female.

       * Note: MySpace joins the profile data from city	and region to one line
       (such as	Berlin,	Germany).  However, both city and region are free text
       so people can write whatever they want. What is more, region and	city
       is optional. This function tries	to extract the city and	the region by
       splitting cityregion at the last	comma and do some other	guesswork if
       there is	only one value.	However, it might not work (depending on the
       profile information) so both city and region can	either be undefined or

       See profile_views for documentation on passing parameters to this

   "get_comments( friend_id =" $friend_id, last_comment_time =>	time(),
       last_comment => comment_id )>
       Returns a list of hashrefs, like	"get_inbox", of	comments left for the
       profile indicated by $friend_id.

       Returns the logged-in user's comments if	no friend_id is	specified.

       if last_comment_time is specified, returns comments left	at the same
       time or more recently than the time specified.  last_comment_time is a
       UTC time	value (i.e. what "time"	returns).  This	should work as
       expected	if you convert your local time,	as it is compared to the
       "time" return value (see	below),	which is also converted	to UTC.	 For
       example,	"last_comment_time => time - 3600" will	return all comments
       left within the last hour.  "last_comment_time => time( 2007, 11, 01,
       14, 00 )" will return comments left since 2PM Nov 1, 2007 in your
       server's	time zone.  (I might have the format to	"time" wrong there,
       but hopefully you get the idea that comment times are given to your
       server in your server's local time and this module converts all those
       times to	UTC for	comparison).

       If last_comment_id is specified,	get_comments will return all comments
       left AFTER the specified	comment.  Note that the	comment_id might not
       be a "real" unique ID, so this could break.

       get_comments returns a maximum of 100 pages of comments (about 5000).
       This limit was added in version 0.66 to prevent the method from
       "running	away" if myspace changes the code for which the	method looks
       when gathering the comments.  It	was updated from 50 to 100 pages in
       version 0.73.

	Each list element contains:
	  comment_id =>	$comment_id  # Myspace's unique	ID for this comment (might change/break)
	  sender => $friend_id,	# friendID of the person who sent the comment
	  sendername =>	$name, # Profile "name"	of the person who sent the comment
	  date => $date_time,	# As formatted on MySpace
	  time => $datetime,	# time the comment was left in "time" format.
	  comment => $string	# HTML of the comment.

       Note: The comment_id is used in myspace's "delete" buttons - it might
       be a unique ID, or it could change in the future.  Try not to depend on
       it for long-term	dependencies.  Short-term it might work.

       Comments	are returned in	the order in which they	appear on myspace
       (currently most recent first).

       Dies if called when not logged in.

   get_profile_type( $friend_id	|| friend_id =>	$friend_id || page => $page )
       Can take	either a friend	id or a	page response object and returns an
       integer that indicates the type of MySpace profile.

       The codes are as	follows
	 1 individual profile
	 2 band	profile	(detected by looking for the MySpace Music logo)
	 3 film	profile	(detected by looking for the MySpace Film logo)
	 4 comedy profile (detected by looking for the MySpace Comedy logo)

       First we	try to look for	all the	non-individual profiles. If these do
       not match, we try to make sure that we have at least a "Last Login"
       date on the profile to make sure	that this is really an individual's

       returns undef and sets an error if nothing of the above matches.

       Returns a hash of the birthdays from View Upcoming Birthdays as
       friendID	=> birthday, friend_id => birthday, ...

       Croaks if called	when not logged	in.

	my ( %birthays ) = $myspace->get_birthdays;

	foreach	my $friend ( keys( %birthdays )	) {
	    print "Friend ${friend}'s birthday is on ".	$birthdays{"$friend"} .	"\n";

   get_photo_ids( %options )
       Each of your profile's photos is	stored using a unique ID number.

       This method returns a list of the IDS of	the photos in your profile's
       photo section.

       The only	valid option at	this time is:

	friend_id => $friend_id

       Defaults	to your	friendID.

       Croaks if called	when not logged	in.

   set_default_photo( photo_id => $photo_id )
       Sets your profile's default photo to the	photo_id specified.

	Example:  Set your default photo to a random photo.

	use WWW::Myspace 0.60;
	my $myspace = new WWW::Myspace;

	my @ids	= $myspace->get_photo_ids;
	$myspace->set_default_photo( $ids[ int(	rand( @ids ) ) ] );

   "find_friend( $email	)"
       Takes an	email address and returns one or more matching friend IDs

       Sets "$myspace-"error> on failure.

	   use WWW::Myspace;
	   my $myspace=new WWW::Myspace( auto_login=>0 );

	   my $email = shift;
	   my (	@friend_ids ) =	$myspace->find_friend( $email );

	   if (	$myspace->error	) {
	      die $myspace->error;
	   } elsif ( @friend_ids ) {
	      print "${email}'s	friendID is @friend_ids\n";
	   } else {
	      print "Don't think $email	is on myspace, sorry\n";

   "search_friend_list(	$name )"
       Takes a name to search for and returns a	list of	the friend_ids of the
       owner.  Per Myspace's page, "You	can search for display name, full
       name, MySpace URL or email."

       It does so by clicking "View Friends" and filling in the	"Search	Friend
       List" form.

	   use WWW::Myspace;
	   my $myspace=new WWW::Myspace;

	   my $name = shift;
	   my (	@friend_ids ) =	$myspace->search_friend_list( $name );

	   if (	$myspace->error	) {
	      die $myspace->error;
	   } elsif ( @friend_ids ) {
	      print "Search for	$name yielded these friendID's:	",
		    join(', ", @friend_ids);
	   } else {
	      print "No	friend's matched the search for	$name.";

       Call browse with	a hashref of your search criteria and it returns a
       list of friendIDs that match your criteria.

       This is a complex form. Don't trust the defaults	you see	in your	web
       browser.	 Easiest thing to do is	paste this into	your script and	change
       the values you want. (This example script looks up the specified
       criteria	and dumps a list of friendIDs in YAML).

	use WWW::Myspace;
	use YAML;

	my $myspace = new WWW::Myspace(	human => 0, auto_login => 0 );

	 my @friends = $myspace->browse( {
	   'ctl00$Main$ctl00$Scope' => 'scopeFullNetwork', # or	'scopeMyFriends'

	   'ctl00$Main$ctl00$Gender' =>	'genderWomen', # or 'genderMen', 'genderBoth'
	   'ctl00$Main$ctl00$minAge' =>	18,
	   'ctl00$Main$ctl00$maxAge' =>	35,

	   # Marital Status
	   'ctl00$Main$ctl00$statusSingle' => 'on',
	   'ctl00$Main$ctl00$statusInRelationship' => 'off',
	   'ctl00$Main$ctl00$statusSwinger' => 'off',
	   'ctl00$Main$ctl00$statusMarried' => 'off',
	   'ctl00$Main$ctl00$statusDivorced' =>	'off',

	   # Here for
	   'ctl00$Main$ctl00$motiveDating' => 'on',
	   'ctl00$Main$ctl00$motiveNetworking' => 'off',
	   'ctl00$Main$ctl00$motiveRelationships' => 'on',

	   # Location (there are MANY country values. Check the	browse page
	   # source (see below)).
	   'ctl00$Main$ctl00$country' => 'US',
	   'ctl00$Main$ctl00$zipRadius'	=> 20,
	   'ctl00$Main$ctl00$zipCode' => 91604,
	   'ctl00$Main$ctl00$region' =>	'Any',

	   # Photos
	   'ctl00$Main$ctl00$showHasPhotoOnly' => 'on',
	   'ctl00$Main$ctl00$showNamePhotoOnly'	=> 'on', # Leave this on for speed.

	   # Ethnicity
	   'ctl00$Main$ctl00$asian' => 'on',
	   'ctl00$Main$ctl00$white' => 'on',
	   'ctl00$Main$ctl00$black' => 'off',
	   'ctl00$Main$ctl00$eastIndian' => 'off',
	   'ctl00$Main$ctl00$latino' =>	'off',
	   'ctl00$Main$ctl00$midEastern' => 'off',
	   'ctl00$Main$ctl00$nativeAmer' => 'off',
	   'ctl00$Main$ctl00$ethnOther'	=> 'off',
	   'ctl00$Main$ctl00$pacIslander' => 'off',

	   # Body Type
	   'ctl00$Main$ctl00$slimSlender' => 'on',
	   'ctl00$Main$ctl00$average' => 'off',
	   'ctl00$Main$ctl00$moreToLove' => 'off',

	   'ctl00$Main$ctl00$athletic' => 'on',
	   'ctl00$Main$ctl00$littleExtra' => 'off',
	   'ctl00$Main$ctl00$bodyBuilder' => 'off',

	   # Height
	   'ctl00$Main$ctl00$Height' =>	'heightBetween', # or 'heightNoPreference'
	   'ctl00$Main$ctl00$minFoot' => 5,
	   'ctl00$Main$ctl00$minInch' => 0,
	   'ctl00$Main$ctl00$maxFoot' => 6,
	   'ctl00$Main$ctl00$maxInch' => 0,

	   # Background	& Lifestyle
	   'ctl00$Main$ctl00$Smoker' =>	'smokerBoth', #	or 'smokerNo', 'smokerYes'
	   'ctl00$Main$ctl00$Drinker' => 'drinkerBoth',	# or 'drinkerNo', 'drinkerYes'

	   'ctl00$Main$ctl00$straight' => 'on',
	   'ctl00$Main$ctl00$bi' => 'on',
	   'ctl00$Main$ctl00$gay' => 'off',
	   'ctl00$Main$ctl00$notSure' => 'off',

	   # Education (note: all off means no preference)
	   'ctl00$Main$ctl00$highSchool' => 'off',
	   'ctl00$Main$ctl00$inCollege'	=> 'off',
	   'ctl00$Main$ctl00$gradSchool' => 'off',
	   'ctl00$Main$ctl00$someCollege' => 'off',
	   'ctl00$Main$ctl00$collegeGrad' => 'off',
	   'ctl00$Main$ctl00$postGrad' => 'off',

	   # Religion
	   'ctl00$Main$ctl00$religion' => 'NoPreference',
	    # Possible Values Are:
	    # NoPreference
	    # Agnostic
	    # Atheist
	    # Buddhist
	    # Catholic
	    # ChristianOther
	    # Hindu
	    # Jewish
	    # Mormon
	    # Muslim
	    # Other
	    # Protestant
	    # Scientologist
	    # Taoist
	    # Wiccan

	   # Income
	   'ctl00$Main$ctl00$income' =>	'NoPreference',
	    # Possible Values Are:
	    # NoPreference
	    # LessThan30000
	    # From30000To45000
	    # From45000To60000
	    # From60000To75000
	    # From75000To100000
	    # From100000To150000
	    # From150000To250000
	    # From250000ToHigher

	   # Children
	   'ctl00$Main$ctl00$children' => 'NoPreference',
	    # Possible Values Are:
	    # NoPreference
	    # IDontWantKids
	    # Someday
	    # Undecided
	    # LoveKidsButNotForMe
	    # Proud parent

	   # Sort By (last login is good to weed out dead accounts)
	   'ctl00$Main$ctl00$SortBy' =>	'sortByLastLogin',
	    # Possible Values Are:
	    # sortByLastLogin
	    # sortByNewToMySpace
	    # sortByDistance

	   } );

	print Dump( @friends );

       I'm not sure how	I'm going to make the criteria passing easier.	I'm
       also concerned about your script	breaking if they change	the browse
       form variable names. So maybe I'll add a	mapping	later.

       The values above	are current, and you can copy/paste that code, change
       the values, and browse away.

       If you need to look at values (i.e. something's not working or you need
       to change "Location" fields):

       Go to the browse	page:

       Switch to Advanced mode and enter your search criteria.

       View Source in your web browser and find	"<form".  The second form
       should be named "aspnetForm".

       Look through the	input tags on the form (hint: find "<input"), entering
       name and	value pairs as above for your search criteria.	Many/most of
       them are	in the example above, but myspace does weird things like
       differentiate checkboxes	solely by their	name instead of	name and value
       (i.e. you'd expect multiple inputs with
       name="ct100$Main$SexualPreference" , and	value="straight", value="bi",
       etc, but	instead	there are inputs with name="ct100$Main$straight" and
       name="ct100$Main$bi" and	no value attribute at all).

       Note: to	"check"	a checkbox with	no "value" attribute, use 'on' to turn
       it on, 'off' to turn it off.  If	you don't specify a field/checkbox in
       in your search criteria,	you'll get the default value, which is hard to
       determine with this weird form (and is quite possibly NOT the default
       value you'll see	if you open the	page in	your web browser).

   _browse_next( $page )
       The browse form's Next button calls a JavaScript	function that sets
       "action"	and "page" in the browse form and "clicks" submit.  So we do
       the same	here.  Called by browse	to simulate clicking "next".

   _browse_action( $function_name )
       Gets the	action set by the specificied function on the Browse page.

   cool_new_people( $country_code )
       2008-08-12 -- this feature no longer exists at Myspace.	It has been
       replaced	by a similar feature on	the homepage whcih may be supported in
       the future by WWW::Myspace.  This function is disabled until then.

       This method provides you	with a list of "cool new people".  Currently
       Myspace saves the "cool new people" data	to a JavaScript	file which is
       named something like this:

       Since these files are named using country codes,	you'll need to provide
       the ISO 3166-1 two letter code country code for the list	you'd like to
       get.  For example,

	$myspace->cool_new_people( 'US'	)

       When called in a	list context, this function returns the	friend ids of
       the cool	folks:

	my @friend_ids = $myspace->cool_new_people( 'US' );

       If you treat the	return value as	a hash reference, you'll get a hash
       keyed on	friend ids.  The values	consist	of hash	references containing
       the urls	of the friend thumbnails (thumb_url) as	well as	their display
       names (friend_user_name).  There	will probably be about 200 keys
       returned	in the hash.

	my $cool = $myspace->cool_new_people('US');
	my %cool_new_people = %{$cool};

	%cool_new_people = {


	    'friend_id'	=> {
		'thumb_url'	    => 'url_to_jpg_here',
		'friend_user_name'  => 'friend display name here'



       So far, we know of 4 country-specific cool new people lists: AU,	CA,
       UK/GB and US  Submitting	any of these values to the function should
       return valid friend ids.	 If you	want to	check for other	countries for
       which cool people lists may exist, you can do something like this:

	use Locale::SubCountry;

	my $world	  = new	Locale::SubCountry::World;
	my %countries	  = $world->code_full_name_hash();
	my @country_codes = sort keys %countries;

	foreach	my $country_code ( @country_codes ) {
	    my %cool_people = $myspace->cool_new_people($country_code);
	    if (%cool_people) {
		print "$country_code $countries{$country_code} has cool	folks\n";
	    else {
	       print "****** $country_code\n";

   get_friends(	%options )
       NOTE: As	of version 0.59, "source => inbox" has been removed due	to a
       formatting change in  Use the "friends_who_emailed"	method

       This method is a	complete re-write as of	version	0.62. Please see the
       Changes file.

       Returns,	as a list of friendIDs,	all of your friends. It	does not
       include Tom, because he's everybody's friend and	when you're debugging
       your band central CGI page it's probably	best to	limit your mistakes to
       actual friends.

	# Simplest form	- gets your friends.
	@friends = $myspace->get_friends;

	# Advanced form
	@friends = $myspace->(
	   source => 'group',  # 'profile', 'group', 'inbox', or ''
	   id => $group_id,    # friendID or groupID as	appropriate
	   start_page => $start_page  #	Start on this page. Starts on page 1 if	not included.
	   end_page => $end_page,  # Stop on this page.	Goes to	last page if not included.
	   max_count =>	300,   # Number	of friends to return

       Accepts the following options:

	source:	   "profile" or	"group"
		   If not specified, gets your friends.
		   profile: Get	friends	from the profile specified by the "id" option.
		   group: Get the friends from the group specified by the "id" option.
	id:	   The friendID	or groupID (depending on "source").
		   "id"	is only	needed for "profile" or	"group".
		   (See	the "friends_in_group" method for more info).
	start_page: Start on this page.
	end_page:  Stop	on this	page.
		   $myspace->get_friends( end_page => 5	);
		   If not specified, gets all pages.
		   See note below about	interaction with other options.
	max_count: Return this many friendIDs.
		   $myspace->get_friends( max_count => 300 );
		   Stops searching and returns when max_count is reached.
		   (See	note below).
	exclude:   Ignored as of version 0.62. Previous	versions took this
		   as a	list of	friends	to exclude.

       If you specify max_count	and end_page, get_friends will stop when it
       hits the	earliest condition that	matches.

       max_count may return up to 40 more friends than you specify.  This is
       because it reads	each friend page, and returns when it's	gathered
       max_count or more friends (and there are	40 per page).

       Myspace trivia: The friends on friends lists are	sorted by friendID.

       Croaks if called	with no	arguments (i.e.	to get your friends) and
       you're not logged in.

   friends_from_profile( %options )
       Returns a list of the friends of	the profile(s) specified by the	"id"
       option.	id can be a friendID or	a reference to an array	of friendIDs.
       If passed a list	of friend IDs, scans each profile and returns a
       sorted, unique list of friendIDs.  Yes, that means if you pass 5
       friendIDs and they have friends in common, you'll only get each
       friendID	once.  You're welcome.

       Also accepts the	same options as	the get_friends	method (end_page,
       max_count, etc).


	# Band 12345 and 54366 sound like us, get their	friends	list
	  $myspace->friends_from_profile( id =>	[ 12345, 54366 ] );

	# Get the first	500 friends from profile 12345
	@friends = $myspace->friends_from_profile(
		       id => 12345,
		       max_count => 500

   friends_in_group( group_id );
       Convenience method;  the	same as	calling:

	  get_friends( source => 'group', id =>	$group_id )

       Returns a list of the friend IDs	of all people in the group identified
       by "group_id".  Tom is excluded from this list (as is the case when
       using the "get_friends" method directly).


	  my @hilary_fans = $myspace->friends_in_group(	100011592 );

       @hilary_fans will now contain the friend	ID of everyone in the Hilary
       Duff Fan	Club group (group ID 100011592).

       The group ID can	be found immediately after "groupid=" in the URL of
       the group's page	on Myspace, for	example:

       Convenience method.  Reads messages from	"inbox"	method and returns a
       list of senders.

       This used to be the same	as calling "get_friends( source	=> 'inbox' )",
       but Myspace changed the way the inbox paging wored and it was more
       practical to read from the inbox	method.	Changed	in 0.59.

       Returns,	as a list of friend IDs, all friends with messages in your
       inbox (mail). Note that this only tells you who you have	mail from, not
       how many	messages, nor does it contain any method to link to those
       messages. Use "inbox" for that.

       This method is primarily	designed to aid	in auto-responding programs
       that want to not	contact	(comment or email) people who have sent
       messages	so someone can attend to them personally.  Frankly, it was
       written before "inbox" and may be deprecated in the future.  Croaks if
       you're not logged in.

	   @friends = $myspace->friends_who_emailed;

       Search for bands	using the search music form.

       Takes a hashref containing field	=> value pairs that are	passed
       directly	to submit_form to set the search criteria.

       The easiest way I've found to get your values is	to fill	them in	on the
       search form, click "Update", then look at the page source.  Scroll to
       the botton where	"PageForm" is and you'll see the values	you selected.
       Put the pertinent ones (i.e. things you changed)	into your script.
       Note that the field *names* are different, so just take the values, and
       use the names as	described below.

       Any value the form can take (present or future) can be passed, so in
       theory you could	write a	CGI front-end also that	just had the form,
       posted the values to itself, then used those values to call this	method
       (i.e. do	what I suggested above automatically).

       Here are	the currently available	form labels/values (looking at the
       form helps):

	genreID: See the form for values

	   0: Band Name
	   1: Band Bio
	   2: Band Members
	   3: Influences
	   4: Sounds like

	keywords: text field. Use it if	you're searching by band name, etc.

	Country: Labeled "Location" in the form. See the form source for values.

	localType: The radio buttons. Set to:
	  countryState:	To search by Country / State
	  distanceZip: To search by distance and zip code.

	if localType is	"countryState",	set this:
	  state: State code (like the post office uses,	thankfully. See	form code
		 if you	have any questions).

	If localType is	"distanceZip", set these:
	  zip: The 5-digit zip code.
	  distance: Distance from zip code [0|5|10|20|50|100|500]. 0="Any" and is the

	OrderBy: [ 5 = Plays | 4 = Friends |3 =	New | 2	= Alphabetical ]
		 Default is 2.

       IMPORTANT: Results are currently	sorted by friendID regardless of the
       OrderBy setting.

       For those who care about	details, here's	how the	Search Music page

       There are three forms on	the page, the generic "search" form in the nav
       bar, a second form called "myForm" that is the user-modified update
       form, and a third form called "PageForm"	that is	actually used to pass
       the values.  PageForm is	updated	with the values	after "update" is
       clicked in myForm. Clicking "Next" just sets (using JavaScript in
       Myspace)	the page value in PageForm and submits PageForm.  Oddly
       enough, PageForm	ends up	being a	"GET", so you could theoretically just
       loop through using URLs.	 But we	don't, we fill in the form like	a
       browser would.

       These methods interact with other users.

   post_comment( $friend_id, $message )
       Post $message as	a comment for the friend identified by $friend_id.
       The routine confirms success or failure by reading the resulting	page.
       It returns a status string as follows:

	P   =>	Passed!	Verification string received.
	PA  =>	Passed,	requires approval.
	FF  =>	Failed,	you must be someone's friend to	post a comment about them.
	FN  =>	Failed,	network	error (couldn't	get the	page, etc).
	FC  =>	Failed,	CAPTCHA	response requested.
	FI  =>	Failed,	Invalid	friendID.
	FL  =>	Failed,	Add Comment link not found on profile page.
	F   =>	Failed,	verification string not	found on page after posting.

       Warning:	It is possible for the status code to return a false "Failed"
       if the form post	is successful but the resulting	page fails to load.

       If called in scalar context, it returns the status code.	 If called in
       list context, returns the status	code and the description.

	   use WWW::Myspace;
	   my $myspace = new WWW::Myspace;

	   foreach $id ( $myspace->friends_who_emailed ) {
	       $status = $myspace->post_comment( $id, "Thanks for the message!"	)

	   # Get a printable status (and print it)
	   ( $status, $desc ) =	$myspace->post_comment(
	       $id, "Thanks for	being my friend!"
	   print "Status of post: $desc\n";

       post_comment loads $friend_id's profile page, clicks the	"Add Comment"
       link, fills in, posts, and confirms a comment. If $friend_id is a non-
       true value (i.e.	"0" or ''), post_comment will search for and click an
       "Add Comment" link on the last page loaded.  This lets you do this
       without double-loading the profile page wasting time and	bandwidth:

	$myspace->get_profile( $friend_id );
	if ( $myspace->current_page->decoded_content =~	/something special/ ) {
	    $myspace->post_comment( 0, "Your page is special!" );

       If called when you're not logged	in, post_comment croaks	to make	you
       look stupid.

       See also	the WWW::Myspace::Comment module that installs with the

       If post_comment returns "FC", the "captcha" method will return the URL
       to the CAPTCHA image that contains the text that	the user must enter to
       post the	comment.

	Psuedo-code example of how you can use this in a CGI script:

	my $response = $myspace->post_comment( 12345, 'This is a message' );
	if ( $response eq 'FC' ) {
	   # Get and display the image
	   print '<form>\n'.
	     "<img src='" . $myspace->captcha .	"'>\n".
	     '<input type=text name=\'CAPTCHAResponse\'>' .
	     '<input type=submit>' .

	# Post the comment
	$myspace->post_comment(	12345, 'This is	a message', $captcha_response );

	(Use in	a CGI script is	currently problematic since you'll lose	the
	Myspace	object.	I'll try to write a better example later. You could
	try doing a YAML Dump and Load of the $myspace object...)

   comment_friends( $message )
   comment_friends( $message, {	'ignore_dup' =>	1 } )
       This convenience	method sends the message in $message to	all of your
       friends.	(Since you can only comment friends, it	sends the comment to
       everyone	you can).

       By default it will scan the user's profile page for a previous comment
       (by searching for your profile URL on the page, which also detects you
       if you're in their top 8	or otherwise linked to from their page).

       If called in the	second form, it	forgoes	this duplicate checking
       (ignores	duplicates), and posts anyway.

       Note that you'll	probably want to use the WWW::Myspace::Comment module
       as if the process is interrupted	(which is likely), this	routine
       doesn't offer a way to recover.	The WWW::Myspace::Comment module logs
       where comments have been	left, scans for	previous comments we've	left
       on the user's page, and can stop	after a	specified number of posts to
       avoid triggering	security measures. It can also be re-run without
       leaving duplicate comments.

       Of course, if you just want to whip off a quick comment to a few	(less
       than 50)	friends, this method's for you.

	   A simple script to leave a comment saying "Merry Christmas"
	   to everyone on your friends list:

	   use WWW::Myspace;
	   my $myspace = new WWW::Myspace;
	   $myspace->comment_friends( "Merry Christmas!" );

       Returns true if there is	a link to our profile on "$friend_id"'s	page.
       (If we've left a	comment, there'll be a link).

       Note that if you're friends with	this person and	they have another link
       to your profile on their	page, this will	return true, even though you
       may not have left a comment.


	 my WWW::Myspace;
	 my $myspace = new WWW::Myspace;

	 foreach $friend_id ( $myspace->get_friends ) {
	     unless ( $myspace->already_commented( $friend_id )	) {
		   "Hi,	I haven't commented you	before!"

       already_commented croaks	if called when you're not logged in.

   get_inbox ( %options	)
       Returns a reference to an array of hash references that contain data
       about the messages in your Myspace message inbox. The hashes contain:

	sender (friendID)
	sendername (friend's display name)
	status (Read, Unread, Sent, Replied)
	message_id (The	unique ID of the message)
	subject	(The subject of	the message)

       The messages are	returned IN ORDER with the newest first	to oldest last
       (that is, the same order	in which they'd	appear if you were looking
       through your inbox).

       There is	currently one option:

	end_msg	=> $message_id # Stop and return when
			       # the message with this
			       # messageID is reached.
			       # Does NOT return message $message_id.
	end_page => $page_no   # Stop and return after reading this page.
	page_no	=> $page_no    # Only read this	page of	messages. (Must	do page	1 first).

       end_msg is primarily used if you're caching your	mail into a database.
       This lets you get all the mail since the	last message you cached.
       get_inbox does not return the message matching $message_id (because you
       already have it).  If there are no new messages before $message_id,
       returns an empty	list.

       end_page	will read up to	and including the page specified.  So if you
       pass "end_page => 1", it	will read only the first page of messages.

       page_no is handy	if you want to do some processing on the messages and
       step through the	inbox one page at a time.  See Example#3 below.

       I'm sure	reading	that first line	made you as dizzy as it	made me	typing
       it.  I think this says it all much more clearly:


	# This script displays the contents of your inbox.
	use WWW::Myspace;

	$myspace = new WWW::Myspace;

	print "Getting inbox...\n";
	my $messages = $myspace->get_inbox;

	# Display data for each	message
	foreach	$message ( @{$messages}	) {
	  print	"Sender: " . $message->{sender}	. "\n";
	  print	"Sendername: " . $message->{sendername}	. "\n";
	  print	"Status: " . $message->{status}	. "\n";
	  print	"messageID: " .	$message->{message_id} . "\n";
	  print	"Subject: " . $message->{subject} . "\n\n";

       (This script is in the sample_scripts directory,	named "get_inbox").


	# Read the messages since the last one we got
	my $last_msg = selectrow_array(
	   "select message_id from mydatabase order by messagedate desc	limit 1"
	);  # Sorry for	the psuedocode,	but hopefully you get the idea

	my $messages = $myspace->get_inbox( stop_at => $last_msg )


	# Step through the inbox reading and processing	unread messages
	# Note that you	must call get_inbox with page_no = 1 first to
	# "go to" the inbox screen.  Remember that WWW::Myspace	just acts like
	# a person at a	web browser.  If you were on myspace, you'd have to log	in,
	# click	inbox, then click a page in the	inbox.	Calling	get_inbox( page_no => 1)
	# does that for	you.
	my $page_no=0;
	while (	$page_no++ ) {

	  my $messages = $myspace->get_inbox( page_no => $page_no );
	  last MESSAGE if $myspace->error;
	  last MESSAGE unless $messages;
	  foreach my $msg ( @${messages}) {
	    last MESSAGE unless	$message->{status} eq "Unread";
	    &process_message( $msg );

       "inbox" croaks if called	when you're not	logged in.

       Here for	backwards compatibility	only.  Use get_inbox instead.
       (Version	0.69)

   read_message( message_id )
       Returns a hashref containing the	message	identified by message_id.

	my $message_ref	= $myspace->read_message( 123456 );

	print 'From: ' . $message_ref->{'from'}	. ."\n"	. # Friend ID of sender
	      'Name: ' . $message_ref->{'fromname'} . ."\n" . #	friend's display name
	      'Date: ' . $message_ref->{'date'}	. ."\n"	. # Date (as formatted on Myspace)
	      'Subject:	' . $message_ref->{'subject'} ."\n" .
	      'Body: ' . $message_ref->{'body'}	. "\n" .   # Message body
	      'URL: ' .	$message_ref->{'url'} .	"\n" . # URL to	the message
	      'Message ID: ' . $message_ref->{'message_id'} . "\n"; # Message unique ID.

       The message subject and body are	HTML, except that <br /> tags are
       turned into newlines in the message body	(because myspace ads them at
       the end of each line).  It could	be argued that these should be left,
       but since they're added,	not typed, we remove them.  Other HTML is left
       as-is, except that if a message has a </div> tag	in it, due to the way
       the message body	is extracted from the page's HTML code,	you'll only
       get the message body to the </div> tag.

       $message_ref->{'url'} is	new as of WWW::Myspace 0.74.  It's the URL to
       the message.  If	you go to that URL in your web browser (if you're
       logged into the account that can	read that message), you'll be able to
       read the	message.  It's handy if	you're writing a routine that caches
       or displays messages (perhaps filtering them), then displays the
       message with a link in case you want to read/delete/reply/etc the
       message on myspace.

       read_message croaks if you're not logged	in.

   reply_message( $message_id, $reply_message )
       Reply to	message	$message_id using the text in the string
       $reply_message.	Using this method is the equivilent of going to	the
       message,	clicking "Reply", and typing your message at the top of	the
       window (where your cursor lands bby default).  It properly retains the
       original	message	and once sent, the message status will show "Replied"
       in your myspace inbox.

       Returns a status	code:

	 P: Posted. Verified by	HTTP response code and reading a regexp
	   from	the resulting page saying the message was sent.
	FC: Failed. A CAPTCHA response was requested.
	FF: Failed. The	person's profile is set	to private. You	must
	    be their friend to message them.
	FA: Failed. The	person has set their status to "away".
	FE: Failed. The	account	has exceeded its daily usage.
	FN: Failed. The	POST returned an unsuccessful HTTP response code.
	F:  Failed. Post went through, but we didn't see the regexp on the
	   resulting page (message may or may not have been sent).

	my $status = $myspace->reply_message( 1234567, "Thanks for emailing me!" );

       If you're not logged in?	Croaks.

   send_message( $friend_id, $subject, $message, $add_friend_button )
   send_message( %options )
	Options	are friend_id, subject,	message, atf.

	$status	= $myspace->send_message(
	    friend_id => 12345,
	    subject => 'Hi there',
	    message => 'This is	the bestest message ever!',
	    atf	=> 0,
	    skip_re => 'i hate everyone', # Skip negative people

       The %options hash is the	"correct" method of passing arguments as of
       version 0.53.  The parameter based method is here for backwards-

       The "message" parameter can also	contain	HTML, but note that some
       accounts	remove HTML from incoming messages (it is not clear where in
       the account settings this is done).  In that case the HTML would	be
       replaced	with dots (..),	and that would include any <br>	tags included
       in "message".  Line breaks should use \n	or \r\n	instead.

       send_message sends a message to the user	identified by "friend_id".  If
       "atf" is	a true value, HTML code	for a "View My Profile"	link will be
       added at	the end	of the message.	(This was an Add To Friends button
       until Myspace started munging that code).

       If "skip_re" is defined,	friend_id's profile will be matched against
       the RE.	Whitespace will	be compressed and the match will NOT be	case-

	So you can do this:
	skip_re	=> 'i hate everyone!* ?(<br>)?'

	And it will match:
	I Hate EVERYONE!!!!
	I hate everyone<br>
	I Hate EvEryone!!! <BR>

       If "friend_id" is an untrue value (i.e. 0 or ''), send_message will
       look for	a Send Message button (identified by a
       "fuseaction=mail.message" URL if	you're curious)	on the current page.
       This lets you do	this efficiently:

	# Send a message only if the profile has "fancy	regex" on their	page
	$myspace->get_profile( $friend_id );
	if ( $myspace->current_page =~ /fancy regex/ ) {
	       subject => "Hello",
	       message => "I'm messaging you"

	$status	= $myspace->send_message(
	    friend_id => 6221,
	    subject => 'Hi Tom!',
	    message => 'Just saying hi!',
	    atf	=> 0

	if ( $status eq	"P" ) {	print "Sent!\n"	} else { print "Oops\n"	}

	Returns	a status code:

	P   =>	Passed!	Verification string received.
	FF  =>	Failed,	profile	set to private.	You must be their
		friend to message them.
	FN  =>	Failed,	network	error (couldn't	get the	page, etc).
	FA  =>	Failed,	this person's status is	set to "away".
	FS  =>	Failed,	skipped. Profile doesn't match RE.
	FE  =>	Failed,	you have exceeded your daily usage.
	FC  =>	Failed,	CAPTCHA	response requested.
	FI  =>	Failed,	Invalid	friend ID.
	F   =>	Failed,	verification string not	found on page after posting.

       If called in list context, returns the status code and text

	( $status, $desc ) = $myspace->send_message( $friend_id, $subject, $message );
	print $desc . "\n";

       See also	WWW::Myspace::Message, which installs along with the

       (Croaks if called when you're not logged	in).

   delete_message( @message_ids	)
       Deletes the message(s) identified by @message_ids. Takes	a list of
       messageIDs or of	hashrefs with a	message_id subcomponent	(such as one
       gets from the "inbox" method).  Croaks if called	when not logged	in.

       Deletes all messages in a single	post.  Returns true if it worked,
       false if	not, and sets the "error" method to the	error encountered.


	# Delete message 12345
	$myspace->delete_message( 12345	);

	# File myspace mail where it belongs.
	$all_messages =	$myspace->inbox;

	$myspace->delete_message( @{ $messages } );

   approve_friend_requests( [ "message"	] )
       Looks for any new friend	requests and approves them.  Returns a list of
       friendIDs that were approved.  If "message" is given, it	will be	posted
       as a comment to the new friends.	If called when you're not logged in,
       approve_friend_requests will croak.

       If approve_friend_requests runs into a CAPTCHA response when posting
       comments, it will set $myspace->captcha to the URL of the CAPTCHA
       image.  If no CAPTCHA was encountered, $myspace->captcha	will be	0.  So
       you can say:

	if ( $myspace->captcha ) { print "oh no!\n" }

       approve_friend_requests will approve all	friends	whether	or not it can
       comment them as it approves first, then comments	the list of approved


	 # Approve any friend requests
	 @friends_added	= $myspace->approve_friend_requests;

	 # Print the number of friends added and their friend IDs.
	 print "Added "	. @friends_added . " friends: @friends_added.";

	 # Approve new frieds and leave	them a thank you comment.
	 @friends_added	= $myspace->approve_friend_requests(
	   "Thanks for adding me!\n\n- Your nww	friend"	);

       Run it as a cron	job. :)

       Note that "\n" is properly handled if you pass it literally also	(i.e.
       from the	command	line). That is if you write this "approve_friends"

	#!/usr/bin/perl	-w
	# usage: approve_friends [ "message" ]

	use WWW::Myspace;
	my $myspace = new WWW::Myspace;

	$myspace->approve_friend_requests( @ARGV );

	And run	it as:

	approve_friends	"Thanks	for adding me\!\!\n\n- Me"

       You'll get newlines and not "\n"	in the message.	There, I even gave you
       your script.

   send_friend_request(	$friend_id, $message )
       Send a friend request to	the friend identified by $friend_id with the
       message $message.  Croaks if not	logged in.

       This is the same	as going to their profile page and clicking the	"add
       as friend" button and confirming	that you want to add them.

       Returns a status	code and a human-readable error	message	(yes, I	copied
       these right out of the code to make sure	they're	correct):

	FF  =>	'Failed, this person is	already	your friend.',
	FN  =>	'Failed, network error (couldn\'t get the page,	etc).',
	FL  =>	'Failed, Add Friend error clicking link	on profile page',
	FP  =>	'Failed, you already have a pending friend request for this person',
	FB  =>	'Failed, this person does not accept friend requests from bands.',
	FA  =>	'Failed, this person requires an email address or last name to add them',
	FC  =>	'Failed, CAPTCHA response requested.',
	FU  =>	'Failed, CAPTCHA response required by user.',
	FE  =>	'Failed, user has exceeded their daily usage.',
	FM  =>	'Failed, message length	greater	than 150 characters.',
	P   =>	'Passed! Verification string received.',
	F   =>	'Failed, verification string not found on page after posting.',

       After send_friend_request posts a friend	request, it searches for
       various Regular Expressions on the resulting page and sets the status
       code accordingly. The "F" response is of	particular interest because it
       means that the request went through fine, but none of the known failure
       messages	were received, but the verification message wasn't seen
       either.	This means it -might- have gone	through, but probably not.  Of
       course, worst case here is you try again.

       Advanced	features: If $message contains an array	reference,
       send_friend_request will	pick one of the	elements at random as the
       message to send.	 This means you	can do:

	$myspace->send_friend_request( $friend_id,
	    [ 'Hi!  I thought I\'d send	you a message",
	      'Hello!  I saw your profile and wanted to	add you.',
	      'Hi, I\'m	just adding you	at random, hope	you\'ll	accept!'

       This can	help add a bit more feeling to your requests.


	# Send a friend	request	and get	the response
	my $status = $myspace->send_friend_request( 12345 );

	# Send a friend	request	and print the result
	my ( $status, $desc ) =	$myspace->send_friend_request( 12345 );
	print "Received	code $status: $desc\n";

	# Send a friend	request	and check for some status responses.
	my $status = $myspace->send_friend_request( 12345 );
	if ( $status =~	/^P/ ) {
	   print "Friend request sent\n";
	} else {
	   if (	$status	eq 'FF'	) {
	       print "This person is already your friend\n";
	   } elsif ( $status eq	'FC' ) {
	       print "Received CAPTCHA image request\n";

	# Send a bunch of friend requests
	my @posted = ();
	my @failed = ();
	foreach	my $friend ( @friends )	{
	  print	"Posting to $friend: ";
	  my $status = $myspace->send_friend_request( $friend )

	  if ( $status =~ /^P/ ) {
	      print "Succeeded\n";
	      push ( @posted, $friend );
	  } else {
	      print "Failed with code $status\n";
	      push ( @failed, $friend );

	  # Stop if we got a CAPTCHA request.
	  last if $status eq 'FC';
	# Do what you want with	@posted	and @failed.

       Also see	the WWW::Myspace::FriendAdder module, which adds multiple
       friends and lets	you enter CAPTCHA codes.

   send_friend_requests( @friend_ids )
       Send friend requests to multiple	friends. Stops if it hits a CAPTCHA
       request.	Doesn't	currently give any indication of which requests
       succeeded or failed. Use	the code example above for that. Croaks	if
       you're not logged in.

       Convenience method - same as send_friend_request. This method's here
       because the button on Myspace's site that the method emulates is
       usually labeled "Add to Friends".

       Convenience method - same as send_friend_request. This method's here
       Solely for backwards compatibility. Use add_to_friends or
       send_friend_request in new code.

   delete_friend( @friend_ids )
       Deletes the list	of friend_ids passed from your list of friends.

	$myspace->delete_friend( 12345,	151133 );

       Returns true if it posted ok, false if it didn't.  Croaks if you're not
       logged in.

   send_event_invitation( $event_id, [ @friend_ids ] )
       Send an event invitation	to each	friend in @friend_ids.	You need to
       add the event in	Myspace	first, then run	a script that calls this
       method feeding it the event ID, which you can get from the URL of the
       page that lets you invite friends.  If no friend	IDs are	passed,
       send_event_invitation calls the get_friends method and sends to all of
       your friends.

       The method returns a reference to 2 arrays, "passed", and "failed".
       Because it wil probably take a long time	to run,	it also	prints a
       running report of the friends its inviting with "Passed"	or "Failed":

	Inviting 12345:	Passed
	Inviting 12346:	Failed

       Known issue: If you already have	people in your invitation list and
       this method attempts to add those friends again,	it will	cause
       substantial delays (up to a minute or two per friend ID).  This is
       because submit_form will	receive	an error message and will retry	the
       post 5 times for	each friend.


	my ( $passed, $failed )	=
	    $myspace->send_event_invitation( $event_id,	@friend_ids );
	die $myspace->error if $myspace->error;

	print "Sent to:\n";
	foreach	$id ( @{ $passed } ) {
	    print $id .	"\n";

	print "Failed to send to:\n";
	 foreach $id ( @{ $failed } ) {
	    print $id .	"\n";

       See also	the send_event_invitations sample script in the	sample_scripts
       directory included with this distribution.

   send_group_invitation( $event_id, [ @friend_ids ] )
       Send a group invitation to each friend in @friend_ids.  You need	to add
       the group in Myspace first, then	run a script that calls	this method
       feeding it the group ID,	which you can get from the URL of the group's
       page.  If no friend IDs are passed, send_event_invitation calls the
       get_friends method and sends to all of your friends.

       The method returns a reference to 2 arrays, "passed", and "failed".
       Because it wil probably take a long time	to run,	it also	prints a
       running report of the friends its inviting with "Passed"	or "Failed":

	Inviting 12345:	Passed
	Inviting 12346:	Failed

       You're only allowed to send 25 intivations at a time (because Myspace
       users are unpopular I guess?), so we pause for 25-30 seconds after each
       group of	25 to allow for	clicking time so we don't make the server mad.


	my ( $passed, $failed )	=
	    $myspace->send_group_invitation( $event_id,	@friend_ids );
	die $myspace->error if $myspace->error;

	print "Sent to:\n";
	foreach	$id ( @{ $passed } ) {
	    print $id .	"\n";

	print "Failed to send to:\n";
	 foreach $id ( @{ $failed } ) {
	    print $id .	"\n";

       See also	the send_group_invitations sample script in the	sample_scripts
       directory included with this distribution.

       Croaks if called	when not logged	in.

   post_bulletin( %options )
       Post a builletin	to your	friends.

	use WWW::Myspace;

	my $myspace = new WWW::Myspace;

	    subject => $subject,
	    message => $message

       Croaks if called	when not logged	in.

   post_blog( %options )
       Post a blog entry.

	    subject => $subject,
	    body    => $body
	) or die $myspace->error;

       You can also use	"message" instead of "body".

       Currently only Subject and Message fields are supported.	 Mood,
       Category, Music,	etc will be left at their default settings.

       Returns undef and sets $myspace->error if there's an error.

       Croaks if called	when not logged	in.

       These are methods used internally to maintain or	handle basic stuff
       (page retreival,	error handling,	cache file handling, etc) that you
       probably	won't need to use (and probably	shouldn't use unless you're
       submitting a code patch :).

       You may pass this a code	reference. If you do, it will be called	on
       EACH successful HTML page retreived this	module.	The arguments passed
       to this code reference are:

	 $trace_func->($where, $page)

       where $where is a descriptive but curt string explaining	where this
       page was	gotten and $page is a reference	to the actual HTML. Clever
       Perl programmers	can use	caller() (perldoc -f caller) to	find out where
       in the code that	this page was accessed.

   get_page( $url, [ $regexp ] )
       get_page	returns	a referece to a	HTTP::Response object that contains
       the web page specified by $url. If it can't get the page, returns undef
       and sets	$myspace->error.

       Use this	method if you need to get a page that's	not available via some
       other method. You could include the URL to a picture page for example
       then search that	page for friendIDs using get_friends_on_page.

       get_page	will try up to 20 times	until it gets the page,	with a
       2-second	delay between attempts.	It checks for invalid HTTP response
       codes, and known	Myspace	error pages. If	called with the	optional
       regexp, it will consider	the page an error unless the page content
       matches the regexp. This	is designed to get past	network	problems and


	   # Load the Myspace homepage and display the HTML source
	   my $response	= $myspace->get_page( ''	);
	   print $response->decoded_content;

   follow_to( $url, $regexp )
       Exactly the same	as get_page, but sets the Referer header so it looks
       like you're clicking the	link on	the current page instead of just
       GETting it directly.  Use this if you're	stepping through pages.

       This is like a robust version of	WWW::Mechanize's "follow_link" method.
       It calls	"find_link" with your arguments	(and as	such takes the same
       arguments.  It adds the "re" argument, which is passed to get_page to
       verify we in fact got the page.	Returns	an HTTP::Response object if it
       succeeds, sets $self->error and returns undef if	it fails.

	   $self->follow_link( text_regex => qr/inbox/i, re => 'Mail Center' )
	       or die $self->error;

       There are a lot of options, so perldoc WWW::Mechanize and search	for
       $mech->find_link	to see them all.

   _cache_page(	$url, $res )
       Stores $res in a	cache.

   _read_cache(	$url )
       Check the cache for this	page.

       Cleans any non-"fresh" page from	the cache.

       Checks for "You must be logged in to do that".  If found, tries to log
       in again	and returns 0, otherwise returns 1.

   submit_form(	$url, $form_no,	$button, $fields_ref, [	$regexp1 ], [ $regexp2
       ] )
       This format is being deprecated.	 Please	use the	format below if	you
       use this	method (which you shouldn't need unless	you're writing more
       methods).  Be aware that	I might	make this method private at some

   submit_form(	$options_hashref )
	Valid options:
	$myspace->submit_form( {
	   page	=> "",
	   follow => 1,	# 0 or 1
	   form_no => 1,
	   form_name =>	"myform",  # Use this OR form_no OR form
	   form	=> $form, # HTML::Form object with a ready-to-post form.
			  # (page, form_no, form_name, fields_ref and action will
			  # be ignored).
	   button => "mybutton",
	   no_click => 0,  # 0 or 1.
	   fields_ref => { field => 'value', field2 => 'value' },
	   re1 => 'something unique.?about this[ \t\n]+page',
	   re2 => 'something unique about the submitted	page',
	   action => '', # Only needed in weird occasions
	} );

       This powerful little method reads the web page specified	by "page",
       finds the form specified	by "form_no" or	"form_name", fills in the
       values specified	in "fields_ref", and clicks the	button named "button".

       You may or may not need this method - it's used internally by any
       method that needs to fill in and	post a form. I made it public just in
       case you	need to	fill in	and post a form	that's not handled by another
       method (in which	case, see CONTRIBUTING below :).

       "page" can either be a text string that is a URL	or a reference to an
       HTTP::Response object that contains the source of the page that
       contains	the form. If it	is an empty string or not specified, the
       current page ( $myspace->current_page ) is used.

       "follow"	indicates whether or not we're supposedly following a link to
       the URL supplied	in "page".  If "page" isn't a URL, "follow" is
       ignored.	 This causes "submit_form" to use the "follow_to" method
       instead of "get_page" when getting the URL.  This makes it look like we
       clicked a link to get to	this page instead of just going	straight to

       "form_no" is used to numerically	identify the form on the page. It's a
       simple counter starting from 0.	If there are 3 forms on	the page and
       you want	to fill	in and submit the second form, set "form_no => 1".
       For the first form, use "form_no	=> 0".

       "form_name" is used to indentify	the form by name.  In actuality,
       submit_form simply uses "form_name" to iterate through the forms	and
       sets "form_no" for you.

       "form" can be used if you have a	customized form	you want to submit.
       Pass an HTML::Form object and set "button", "no_click", and "re2" as
       desired,	and you	can use	submit_form's tenacious	submission routine
       with your own values.

       "button"	is the name of the button to submit. This will frequently be
       "submit", but if	they've	named the button something clever like
       "Submit22" (as MySpace did in their login form),	then you may have to
       use that.  If no	button is specified (either by button => '' or by not
       specifying button at all), the first button on the form is clicked.

       If "no_click" is	set to 1, the form willl be submitted without clicking
       any button.   This is used to simulate the JavaScript form submits
       Myspace does on the browse pages.

       "fields_ref" is a reference to a	hash that contains field names and
       values you want to fill in on the form.	For checkboxes with no "value"
       attribute, specify a value of "on" to check it, "off" to	uncheck	it.

       "re1" is	an optional Regular Expression that will be used to make sure
       the proper form page has	been loaded. The page content will be matched
       to the RE, and will be treated as an error page and retried until it
       matches.	See get_page for more info.

       "re2" is	an optional RE that will me used to make sure that the post
       was successful. USE THIS	CAREFULLY! If your RE breaks, you could	end up
       repeatedly posting a form. This is used by post_comemnts	to make	sure
       that the	Verify Comment page is actually	shown.

       "action"	is the post action for the form, as in:

	<form action="">

       This is here because Myspace likes to do	weird things like reset	form
       actions with Javascript then post them without clicking form buttons.

       "referer" is sent as the	HTTP Referer header.  This can be specified
       via the hash ref	method only.

       Internal	method to add a	hidden field to	a form.	HTML::Form thinks we
       don't want to change hidden fields, and if a hidden field has no	value,
       it won't	even create an input object for	it.  If	that's way over	your
       head don't worry, it just means we're fixing things with	this method,
       and submit_form will call this method for you if	you pass it a field
       that doesn't show up on the form.

       Returns a form object that is the old form with the new field in	it.

	# Add field $fieldname to form $form (a	HTML::Form object) and
	# set it's value to $value.
	$self->_add_to_form( $form, $fieldname,	$value )

   get_friends_on_page(	$friends_page, $exclude	);
       This routine takes the SOURCE CODE of an	HTML page and returns a	list
       of friendIDs for	which there are	profile	links on the page. This
       routine is used internally by "get_friends" to scan each	of the user's
       "View my	friends" pages.

	- It does not return the logged_in user's friendID.
	- We filter out	6221, Tom's ID.
	- friendIDs are	returned in the	order in which they appear on the
	  (note	that this is new in 0.62 - in previous versions	they were
	  in an	indetermined order)

       If $friends_page	is not specified or is '', the current page will be

       $exclude	is the number of a single friendID to exclude.	This is	used
       by get_friends to exclude the friendID of the profile whose friends
       you're getting since Myspace displays a link to that person's profile
       on every	page of	his friend list, which would show up in	the list
       returned	by this	method.


       List the	friendIDs mentioned on Tom's profile (i.e. his top 8, people
       who left	comments, etc):

	   use WWW::Myspace;
	   my $myspace = new WWW::Myspace;

	   $res	= $myspace->get_profile( 6221 );

	   @friends = $myspace->get_friends_on_page( $res->decoded_content );
	   print "These	people have left comments or have links	on Tom's page:\n";
	   foreach $id ( @friends ) {
	       print "$id\n";

   get_friends_images_on_page( $friends_page );
       This routine takes the SOURCE CODE of an	HTML page.  When called	in
       scalar context, this function returns the first profile image it	can
       find on the current page	(handy for getting a user's image if you're on
       their profile page or reading a single piece of mail).  When called in
       a list context, this function returns a list of all profile images on
       the current page.  If you treat the return value	as a hash reference,
       you'll get a hash keyed on friend ids (THIS IS NOT CURRENTLY

	- It does not return the logged_in user's friendID.

       Remove the login	cache file. Call this after creating the object	if you
       don't want the login data stored:

	my $myspace = new WWW::Myspace(	qw( myaccount, mypassword ) );

       Creates the cache directory in cache_dir. Only creates the top-level
       directory, croaks if it can't create it.


       This function mainly exists for the internal login method to use, and
       for related sub-modules that store their	cache files by default in
       WWW:Myspace's cache directory.

       Takes the source	code of	a page,	or nothing.  If	nothing	is passed,
       uses $self->current_page->decoded_content.

       Returns true if there is	a next button on the page.  This is so we can

	last unless ( $self->_next_button( $page_source	) );


	while (	$self->_next_button ) {	do stuff }
	while (	$self->_next_button ) {	do stuff and click next	}

       One of these days I'm going write a "stuff" subroutine so I can
       actually	type that.


       As you might guess, returns true	if there's a "Previous"	link on	the
       page. This is used to sanity-check functions like get_friends.  If
       there isn't a "Next" button, this method	can be used to make sure there
       is a "Previous" button.

	# Exit the loop	if we're on the	last page
	last unless (
	  $self->_next_button( $page_source ) &&
	  $self->_previous_button( $page_source	)

       Internal	method to go to	the home page.	Checks to see if we're already
       there.  If not, tries to	click the Home button on the page.  If there
       isn't one, loads	the page explicitly.

       A CAPTCHA handler which uses the	Captcha	Killer service to try to
       obtain a	solution for the CAPTCHA.

       This method is called when an action results in a CAPTCHA.  If a	user-
       defined "captcha_handler" has been configured, it will be called.

       The method returns the CAPTCHA response as a string, or undef if	it is
       not known.

       See the example in the "captcha_handler"	to see how this	method can be
       used to test a user-defined "captcha_handler".

       Methods that aren't quite working yet.

       Grant Grueninger, "<grantg at>"	(Bug reports sent to this
       address will probably be	lost - see "BUGS" below	to report bugs)

       Thanks to:

       Tom Kerswill ( for the friend_url method,
       which also inspired the friend_user_name	method.

       Olaf Alders ( for	the human-readable
       status codes in send_friend request, for	the excellent sample code
       which provides a	workaround for CAPTCHA responses, and for the
       friends_from_profile idea.

       -   2008-09-11 -- "captcha_handler" is currently	only known to work for
	   "post_comment", "send_message" and "send_friend_request"

       -   2008-09-11 -- currently, if a friend	request	results	in a CAPTCHA
	   being shown,	Myspace	claims that the	person requires	CAPTCHAs for
	   all friend requests (set in Privacy Settings), even if this is not
	   true.  Therefore, a CAPTCHA handler should not yet make use of the
	   "friend_requires_captcha" parameter.

       -   Version 0.83	onwards	-- it should no	longer matter what
	   language/location is	specified in the Myspace account settings.
	   This	is now handled automatically without changing your account
	   settings directly.

       -   2008-08-12 -- send_friend_request may be returning the wrong	status
	   codes in certain situations.	 More tests are	needed in the test

	   Also, the function does not currently retry automatically in	the
	   cases of a 'network'	error;	until then, a script may wish to retry
	   sending a friend request if 'FN' is returned.

       -   2008-08-12 -- read_message may be returning null 'fromname' some or
	   all of the time.  Tests for this are	needed in t/05-message.t.

       -   2008-08-12 -- A lot of these	warnings are generated when using the
	   'perl -w' option or during a	'make test' with TEST_VERBOSE enabled:

	       Parsing of undecoded UTF-8 will give garbage when decoding entities at
		/usr/local/lib/perl/5.8.8/HTML/ line 83.

	   The file 'mechanize.patch' included in the distribution has been
	   found to stop these warnings.  Read the comments at the top of the
	   patch file for details on how to use	it.

       -   One of the modules upon which WWW::Myspace depends generates	the
	   following warnings when logging in:

	       Day too big - 2932896 > 24855
	       Sec too big - 2932896 > 11647
	       Day too big - 2932896 > 24855
	       Sec too big - 2932896 > 11647

	   These are harmless but annoying.  See the "date.patch" file
	   included at the root	level of the distribution if you want to fix

       -   Some	myspace	error pages are	not accounted for, such	as their new
	   Server Application error page.  If you know enough about web
	   development to identify an error page that would return a
	   successful HTTP response code (i.e. returns 200 OK),	but then
	   displays an error message, please keep an eye out for such pages.
	   If you get such an error message page, PLEASE EMAIL ME (see BUGS
	   below) the page content so I	can account for	it.

       -   If the text used to verify that the profile page has	been loaded
	   changes, get_profile	and post_comments will report that the page
	   hasn't been loaded when in fact it has.

       -   A user has reported that the	module fails to	log in with human=>0.
	   We recommend	always leaving human=>1	(the default).

       -   Your	account	must be	set to the "classic" profile for the module to
	   work	when logged in.

       -   If the method used to go to the next	page in	get_inbox doesn't
	   work, get_inbox can enter an	endless	loop.

       Have 'approve_friends' method check GUIDS after first submit to make
       sure the	current	page of	GUIDS doesn't contain any duplicates. This is
       to prevent a possible infinite loop that	could occur if the submission
       of the friend requests fails, and also to signal	a warning if myspace
       changes in a way	that breaks the	method.

       Add checks to all methods to self-diagnose to detect changes in myspace
       site that break this module.

       get_friends needs to throw an error, or at least	set error, if it can't
       return the full list of friends (i.e. if	either of the "warn"
       statements are triggered)

       get_friends needs to check the number of	pages and try to get all of
       them.  Currently	if a next button isn't on a page for any reason, the
       method will think it's retreived	all the	friends.

       Add tests for get_comments.

       Add Internationalization	(i18n) support.

       Centralize all regular expressions into _regex and _apply_regex

       Have get_inbox check to see if it's paging properly - i.e. check	to see
       if a message on the current page	has the	same message_id	as a message
       on the previous page.

       If you would like to contribute to this module, you can post patches by
       following the simple 4-step process below.  If you end up posting
       several patches and your	code shows a good understanding	of the module,
       we will probbaly	ask you	if you'd like to be added as a developer on
       the project.

       There are many methods that could be added to this module (profile
       editing,	for example). If you find yourself using the "submit_form"
       method, it probably means you should write whatever you're editing into
       a method	and post it on RT.

       See the TODO section above for starters,	and be sure to read the	next
       section about how to submit patches for features/fixes.

       To submit a patch for a new feature or a	bug fix, please	observe	the
       following.  Doing so will allow us to implement your patch quickly.
       Not doing so may	delay its implementation or prevent us from
       implementing your patch at all.

	- Check	out the	newest development version from	SVN.
	  The command to use is	here:
	  (Or see
	- Makke	your changes to	that version. *
	- Create a unified or context diff of the changed file(s):
	  svn diff filename > filename.diff
	  (i.e.	svn diff >
	- Email	the output (filename.diff) with	comments regarding what
	  the patch implements/fixes to	C<bug-www-myspace at>,
	  or go	to the CPAN RT web site	(see below) and	submit
	  it there.

       We will apply your patch	and run	the tests on it.

       * You can use the checked-out version in	your scripts by	one of several

	# Somewhere in your script:
	use lib	'/path/to/svn/checkout/lib';

	# Top of your script:
	#!/usr/bin/perl	-w -I/path/to/svn/checkout/lib

	# Command line:
	perl -I'/path/to/svn/checkout/lib'

       Please report any bugs or feature requests, or send any patches,	to
       "bug-www-myspace	at", or through the	web interface at
       <>.  We will
       be notified, and	then you'll automatically be notified of progress on
       your bug	as we make changes.

       especially HOTMAIL or YAHOO, add	the bug	reporting email	address	above
       to your address book so that you	can receive status updates.

       Bug reports are nice, patches are nicer (see "HOW TO SUBMIT A PATCH"

       You can find documentation for this module with the perldoc command.

	   perldoc WWW::Myspace

       You can also look for information at:

       o   AnnoCPAN: Annotated CPAN documentation


       o   CPAN	Ratings


       o   RT: CPAN's request tracker


       o   Search CPAN


       Copyright 2005-2006 Grant Grueninger, all rights	reserved.

       This program is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

perl v5.32.0			  2009-01-29		       WWW::Myspace(3)


Want to link to this manual page? Use this URL:

home | help