#!/usr/local/bin/ruby # MySpace friend adder script. # # - Searches Google for a term you give it. # - Rips friend ID's to a SQLite database in memory. # - Adds those friends to your MySpace. # # !!! THIS SCRIPT IS FREE TO DISTRIBUTE, JUST KEEP THESE COMMENTS INTACT !!! # # Work by Subimage.com # http://sublog.subimage.com/articles/2007/07/11/ruby-myspace-friend-adder-script # # REQUIRED GEMS: # # - activerecord # - hpricot # - mechanize # - sqlite3-ruby # # GLOBALS ===================================================================== # STUFF YOU SHOULD CHANGE RECORDS_PER_PAGE = 100 PAGES = 10 # Should enter these here, otherwise it'll prompt you for it... MYSPACE_USERNAME = '' MYSPACE_PASSWORD = '' # mac BROWSER_EXE = 'open -a firefox' # windoze # BROWSER_EXE = 'c:/progra~1/mozill~1/firefox.exe' # Maximum sleep time between page reloads in seconds MAX_SLEEP_TIME = 10 # DON'T CHANGE THIS STUFF SCRIPT_VERSION = "1.2" DBFILE = "myspace_adder_db.sqlite" SEPARATOR = "--------------------------------------------------------------------------------" # User agents UA = [ 'Windows IE 6' , 'Windows Mozilla', 'Mac Safari' , 'Mac Mozilla' , 'Linux Mozilla', 'Linux Konqueror' ] # SETUP CONFIGURATION ========================================================= begin require 'rubygems' require 'active_record' require 'open-uri' require 'mechanize' require 'fileutils' require 'cgi' rescue puts "!!! SETUP ERROR !!!" puts "Please make sure you have followed the setup directions at: " puts "http://sublog.subimage.com/articles/2007/07/11/ruby-myspace-friend-adder-script" end class Friend < ActiveRecord::Base end class MySpaceAdder # Initializes... def initialize # Initialize mechanize agent @agent = WWW::Mechanize.new # Set random user agent @agent.user_agent_alias = UA[rand(UA.size)] @myspace_username = MYSPACE_USERNAME if @myspace_username.blank? printf "MySpace email address / username: " @myspace_username = gets.chomp end @myspace_password = MYSPACE_PASSWORD if @myspace_password.blank? printf "MySpace password: " @myspace_password = gets.chomp end end # GOOGLE SEARCH # # Looks at google for phrase given and snags friend IDs # def do_google_search puts SEPARATOR puts "" printf "Should we search Google or Yahoo?: (G/y)" @goog_yahoo = gets.chomp printf "What should we search for: " search_string = gets # Open url, get up to 10 pages of links since that's all google gives # Each page contains 100 search results...(or whatever you've set the variable to) puts "\n\nGrabbing page results..." for page_index in 0..PAGES do puts "...getting page #{page_index}" if @goog_yahoo != 'y' # Search google query = "http://www.google.com/search?q=#{CGI.escape(search_string.chomp)}" query << "+site%3Awww.myspace.com&" query << "&hl=en&safe=off&client=firefox-a&rls=org.mozilla:en-US:official&" query << "&num=#{RECORDS_PER_PAGE}" query << "&start=#{(page_index * RECORDS_PER_PAGE)+1}" if page_index > 0 else # Search yahoo query = "http://search.yahoo.com/search?p=#{CGI.escape(search_string.chomp)}" query << "+site%3Awww.myspace.com&" query << "&ei=utf-8&va_vt=any&vo_vt=any&ve_vt=any&vp_vt=any&vd=all&vf=all&vm=p&fl=0&xargs=0" query << "&n=#{RECORDS_PER_PAGE}" query << "&pstart=1&b=#{(page_index * RECORDS_PER_PAGE)+1}" if page_index > 0 end puts "Getting..." puts query begin page = @agent.get(query) rescue next end #puts page # Rip out all the friend names page.links.each do |link| str_to_look_for = "www.myspace.com/" start_pos = link.href.index(str_to_look_for) next if !start_pos # Offset start slice pos start_pos = start_pos+str_to_look_for.size next if link.href.index("+") next if link.href.index("&") username = link.href[start_pos, link.href.length-1] if !Friend.find(:first, :conditions => ["username = ?", username]) Friend.create( :username => username, :link => link.href ) end end # Sleep between page grabs so sites doesn't freak out... sleep_time = rand(MAX_SLEEP_TIME) puts "...sleeping #{sleep_time} seconds so the search engine doesn't freak out..." next if page_index == PAGES sleep(sleep_time) end puts SEPARATOR puts "Total friend count: #{Friend.count()}" puts "Done searching...time to add these suckers" end # Tries to login to myspace... # def myspace_login # Login to myspace... puts "...Trying to login to MySpace..." page = @agent.get("http://www.myspace.com/?Mytoken=90f1eeb2-f110-401b-a150-d9053692048f") # Fill in the form #login_form = page.form("theForm") login_form = page.form("aspnetForm") #login_form['email'] = @myspace_username login_form['ctl00$Main$SplashDisplay$ctl00$Email_Textbox'] = @myspace_username #login_form['password'] = @myspace_password login_form['ctl00$Main$SplashDisplay$ctl00$Password_Textbox'] = @myspace_password # Click the login button page = @agent.submit(login_form) if !page.form("aspnetForm") puts "...We're logged in!" # Try to print out number of pending add requests page = @agent.get("http://messaging.myspace.com/index.cfm?fuseaction=mail.pendingFriendRequests") #pending_str = (page/"div.pagingLeft").first.inner_html # Chop out bullshit #pending_str = pending_str[pending_str.index('of')+2, pending_str.size] #puts "You have #{pending_str.strip} pending friend requests." # pagingLeft else puts "...I think we're already logged in..." #exit end end # ADD FRIENDS # # Adds friends stored in the SQLite database. # def add_friends puts SEPARATOR self.myspace_login() # Loop through all friends Friend.find(:all).each do |f| # Navigate to person's page, find the add link, go there... puts "\n\nTrying to add: #{f.username}" # Remove friend from the db...just because we don't want to # do any odd condition checking later. f.destroy # @agent.read_timeout = 120 begin page = @agent.get(f.link) rescue Timeout::Error "Getting the page is taking too long...skipping." next rescue "General error trying to load page...skipping" next end add_link = nil # Mechanize's find method on urls is shitty, so lets do this # oldschool while add_link == nil do page.links.each do |link| add_link = link.href if link.href && link.href.index('addfriend') end # Can't find the add link, move on... puts "Add link: #{add_link}" break if !add_link end # Get contents so we can parse... begin page_contents = @agent.get_file(add_link) page = @agent.get(add_link) rescue puts $! next end # Look for the "confirm add friend button" if (page_contents =~ /person.is.already.your.Friend/) puts "#{f.username} is already your friend." next elsif (page_contents =~ /pending.friend.request/) puts "Pending add request." next elsif (page_contents =~ /only.accepts.add.requests.from/) puts "Private profile. Moving on." next elsif (page_contents =~ /from.bands/) puts "#{f.username} doesn't accept requests from bands..." next elsif (page_contents =~ /Invalid.FriendID/i) puts "Invalid friend ID, moving on..." next elsif (page_contents =~ /CAPTCHA/) puts "********************" puts "* CAPTCHA DETECTED *" puts "********************" puts add_link # I put escaped quotes around the '&' in the next line so that my bash # wouldn't interpret it as a line break and foul up the system command system("#{BROWSER_EXE} \"#{add_link}\"") puts "Press enter when you're typing it in..." gets next end add_form = page.form('addFriend') if add_form && add_form.class != String @agent.submit(add_form) puts "...Added!" else puts "Couldn't find the add form...moving on" end # Sleep between friend adds grabs so myspace doesn't freak out... sleep_time = rand(MAX_SLEEP_TIME) puts "...sleeping #{sleep_time} seconds so MySpace doesn't freak out..." sleep(sleep_time) end end end # / END CLASS # DO THIS!@ puts "********************************************************************************" puts " S U B I M A G E M Y S P A C E F R I E N D A D D E R" puts "********************************************************************************" #ActiveRecord::Base.logger = Logger.new(STDERR) ActiveRecord::Base.colorize_logging = false ActiveRecord::Base.establish_connection( :adapter => "sqlite3", :dbfile => DBFILE ) adder = MySpaceAdder.new() if File.size(DBFILE) > 0 puts "An existing database filled with (#{Friend.count()}) friends has been found." printf "Would you like to use it to finish your last adding session? (Y/n): " init_response = gets.chomp end if (File.size(DBFILE) == 0 || (init_response == "n" || init_response == "N")) puts "\nInitializing the database..." ActiveRecord::Schema.define do begin drop_table :friends rescue # Who cares if we can't drop it... end create_table :friends do |table| table.column :link, :string table.column :username, :string end end puts "Done...\n\n" adder.do_google_search() adder.add_friends() else adder.add_friends() end puts "No more friends to add...start a new search."