#!/usr/bin/perl
use WWW::Mechanize;
use HTTP::Cookies;
use HTML::TokeParser;
use POSIX;


# Mechanize Configuration Variables
#aarons userID = 14796603
my $UseragentAlias = "Windows Mozilla";
my $url;
my $CurrentID;
my @UserIDs;
my $DEBUG = 0;


# Username/Password
$user = 'jibjabjam@yahoo.com';
$pass = 'badpass!';

# Connect
# We need to bless $bot as a WWW::Mechanize object
# in order for the various subroutines to correctly
# utilize the bot.
my $bot = &MyspaceConnect($user, $pass);
bless $bot, 'WWW::Mechanize';

$CurrentID = 14796603;
# Get test profile
&GetProfile($CurrentID);
#&ScrapeProfile();
# Get his friends list
&GetFriends($CurrentID);

#foreach (@UserIDs){
#   print "UserID - $_ \n";
#}

sub ScrapeProfile(){
    my %user;
    #Get fresh user ID from the URL
    $user{id} = $bot->uri();
    $user{id} =~ s/http.*friendID=//gi;
    
    #Pull page content out of the bot for parsing
    my $profile_page = $bot->content();
    
    #Build HTML::TokeParser object
    my $parser = new HTML::TokeParser(\$profile_page);
 
    #Here we grab the basic user information from
    #the meta tags. The existence of meta tags with
    #this information on the page, as well as the general
    #structure of this site (veeerrry open to mining) is somewhat
    #puzzling.
    my $result;
    while (my $tag = $parser->get_tag("meta"))
	{
	$result =  $tag->[3];
	if ($result =~ /.*meta name="description".*/g)
	    {
	    #Strip out the tags and split into the @stats array
	    $result =~  s/<meta.*Profile - //g;
	    $result =~ s/" \/>//g;
	    my @stats = split (', ', $result);
	    #Store the Name
	    $user{name} = $stats[0];
	    #Get rid of the "Years Old" trailing text
	    #and just store the age
	    $user{age} = $stats[1];
	    $user{age} =~ s/ Years Old//g;
	    #Check the sex, and store M or F instead of
	    #Female or Male
	    if ($stats[2] eq "Male") { $user{sex} = 'M'; } 
	    if ($stats[2] eq "Female") {$user{sex} = 'F'; }
	    #Store the users location
	    $user{city} = $stats[3];
	    $user{state} = $stats[4];
	    $user{country} = $stats[5];
	    }	
       }
    # For some reason, if you want to search a new tag
    # you need to destroy the current TokeParser object
    # and build a new one. Should report this as a bug
    # when I'm sure that I'm not just making a dumb mistake
    undef $parser;
    $parser = new HTML::TokeParser(\$profile_page);

    #Now we get the specific likes and dislikes, which
    #are also neatly organized for us in table rows.
    #again, this is really really easy to mine...
    while (my $tag2 = $parser->get_tag("td"))
	{
	if ($tag2->[1]{id} eq "ProfileStatus:") {$user{relationship} = $parser->get_trimmed_text("/td");}
	if($tag2->[1]{id} eq "ProfileReligion:") {$user{religion} = $parser->get_trimmed_text("/td");}
	if($tag2->[1]{id} eq "ProfileZodiac Sign:") {$user{zodiac} = $parser->get_trimmed_text("/td");}
	if($tag2->[1]{id} eq"ProfileEducation:") {$user{education} = $parser->get_trimmed_text("/td"); }
	if($tag2->[1]{id} eq"ProfileIncome:") {$user{income} = $parser->get_trimmed_text("/td"); }
	}
}
#Subroutine to Build the Mechanize bot and login to myspace.
sub MyspaceConnect($$)
{      
#Get the username and Password from arguments
my ($username, $password) = @_;

# Build the Bot
$url  = 'http://myspace.com/index.cfm?fuseaction=splash'; 
my $bot = WWW::Mechanize->new(autocheck => 1);
$bot->agent_alias( $UseragentAlias );
$bot->timeout(60);
# Initialize the Cookie Jar.
#I'm storing it in cookie.txt right now for testing
# purposes, once I've got it all together
# I'll use a temporary memory-only cookie jar
my $cookie = HTTP::Cookies->new( file => 'cookie.txt', autosave => 1);
$bot->cookie_jar($cookie);

print "**MyspaceConnect\tBot Built, Logging in \n" if ($DEBUG);
# Log-In
$bot->get($url) or die "WTF!!! : $!\n";
$bot->form_name('theForm');
$bot->field('email', $username); 
$bot->field('password', $password);
$bot->click("Submit22");

# Sometimes Myspace pops up advertisements,
# check to see if we're on an ad, and if so
# skip through to the main page.
if ($bot->find_link( text_regex => qr/Skip this Advertisement/i))
	{
	$bot->follow_link( text_regex => qr/Skip this Advertisement/i);
	} 
#bless $bot, 'WWW::Mechanize';
print "**MyspaceConnect\tLogged in \n" if ($DEBUG);
return $bot;
}



#Subroutine to retrieve a specific user profile once
#we're logged in. The myspace userid is passed to
#the subroutine and it fetches the page with $bot
sub GetProfile ($)
{ 
    ($CurrentID) = @_;
    $url = join '', 'http://myspace.com/index.cfm?fuseaction=user.viewprofile&friendID=', $CurrentID;
    $bot->get($url);
    print "**GetProfile\tProfile Fetched\n" if ($DEBUG);
}

#GetFriends gets a list of the current users
#friends from their profile page. If passed no
#argument it uses whatever profile page the
#bot is currently holding. If passed a userID
#it calls GetProfile and then proceeds to get
#the friends list. 
sub GetFriends($)
{
    #In order to stay consistent here, a fresh ID
    #needs to be grabbed from the URL if none is supplied.

    # http://profile.myspace.com/index.cfm?fuseaction=user.viewprofile&friendID=14883149
    # If passed an ID, then call getprofile
    ($CurrentID) = @_;
    if ($CurrentID) { GetProfile($CurrentID); }
    
    # Go to the "My Friends" page and get all of
    # the links to user profiles. Right now we're
    # just grabbing the first page. Iterating through
    # all the pages will come later
    $bot->follow_link( text_regex => qr/View .* Friends/);
    
    #Check how many friends they have
    $bot->form_name("PageForm");
    my $friendct = $bot->value("friendCount");
    #40 friends are stored per page, so divide the total
    #friends by 40, then round up (ceil) to get the total number
    #of friend pages this person has. Then subtract one from
    #the total count to use it in a for loop
    my $pages = ceil($friendct / 40);

   my @friend_links;
   print "$CurrentID \n";
   my @tst;
    for ($ct = 1; $ct <= $pages; $ct++)
	{
	print "taking page $ct \n";
        $url = join '', 'http://myfriends.myspace.com/index.cfm?fuseaction=user.viewfriends&friendID=', $CurrentID, '&page=', $ct;
        $bot->get($url);
	
        @tst = $bot->find_all_links(url_regex => qr/user.viewprofile/i);
        foreach (@tst) { push (@friend_links, $_);}
	}
    my $friendID;
    foreach (@friend_links)
    {
	#Strip out duplicates from Image links
	if ($_->text() eq '[IMG]') { }
	#Strip out the self-referencing link
	elsif($_->text() =~ /Back To .* Profile/i) {}
	#Otherwise, record the userid in @UserIDs
	else
	{ 
	$friendID = $_->url();
	$friendID =~ s/http.*friendID=//gi;
	push (@UserIDs, $friendID);    
	}  
    }
    print "retrieved $#UserIDs friend ID's\n";

    
}