Given a map of a portion of the Facebook network, this script would try to identify groups of friends, based on the number of mutual friends shared between individuals. I guess you could call this a "poor man's k-means".
read more
on friendExtractionGivenan(id, type)
if type is equal to "indirect" then
tell application "Safari"
set doc to front document
set done_loading to false
do JavaScript "
window.location.assign('https://www.facebook.com/" & id & "?sk=friends&v=friends');
" in doc
delay 1
end tell
end if
if type is equal to "direct" then
tell application "Safari"
set doc to front document
set done_loading to false
do JavaScript "
window.location.assign('https://www.facebook.com/profile.php?id=" & id & "&sk=friends&v=friends');
" in doc
delay 1
end tell
end if
delay 4
tell application "Safari"
repeat while done_loading is not equal to true
set doc to front document
set done_loading to do JavaScript "
var done = false;
if (document.readyState=='complete'){
done=true;
}
done;
" in doc
delay 1
end repeat
end tell
tell application "Safari"
set doc to front document
set this_url to URL of doc
set done_scrolling to false
set filtered_URLs to {}
set completed_once to false
set erred_once to false
repeat while done_scrolling is not equal to true
try
set done_scrolling to do JavaScript "
var completed_once = " & completed_once & ";
if(completed_once!=true){
var done;
var number_of_trys =0;
}
function scrollToBottom(){
bottom = document.body.scrollHeight;
current = window.innerHeight+ document.body.scrollTop;
done = false;
if((bottom-current) >0){
window.scrollTo(0, bottom);
setTimeout (scrollToBottom, 3500 ); //If the loading exceeds this timeout, a try will be used.
}
else {
done = true;
}
};
if(completed_once!=true){
scrollToBottom();
}
if(done==true&&number_of_trys<10){//This number changes the number of allowed timeouts
done=false;
number_of_trys++;
setTimeout(scrollToBottom, 2000);
//This number sets the allotted timeout length.
//If the loading exceeds both the timeout above and this timeout, another try will be used immediately.
}
done;
" in doc
set completed_once to true
delay 1.0
on error
end try
end repeat
set URLs to false
repeat while URLs is equal to false
set URLs to do JavaScript "
URLArray = [];
allLinks = document.links;
for (i = 0; i < allLinks.length; i++) {
URLArray.push(allLinks[i].href);
}
URLArray;
" in doc
end repeat
return URLs
end tell
end friendExtractionGivenan
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on extractionOfIDsFrom(unfiltered_links)
set unfiltered to unfiltered_links
set filtered to {}
set direct_IDs to {}
set indirect_IDs to {}
set refined_IDs to {}
set returned_IDs to {}
repeat with x from 1 to count of items of unfiltered
set n to item x of unfiltered
if "=pb" is in n then
if n is not in filtered then set end of filtered to n
end if
end repeat
repeat with y from 1 to count of items of filtered
set profile to item y of filtered
if "profile.php?" is in profile then
set end of direct_IDs to text ((offset of "=" in profile) + 1) thru ((offset of "&" in profile) - 1) of profile
else
set end of indirect_IDs to text 25 thru ((offset of "?" in profile) - 1) of profile
end if
end repeat
return direct_IDs & indirect_IDs
end extractionOfIDsFrom
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on dataExtraction(startingID, id, type)
tell application "Safari"
set doc to front document
set done_loading to false
do JavaScript "
window.location.assign('https://www.facebook.com/" & startingID & "?and=" & id & "');
" in doc
delay 1
end tell
tell application "Safari"
repeat while done_loading is not equal to true
set doc to front document
set done_loading to do JavaScript "
var done = false;
if (document.readyState=='complete'){
done=true;
}
done;
" in doc
delay 1
end repeat
end tell
delay 5
tell application "Safari"
set doc to front document
set sourceCode to do JavaScript "
document.documentElement.outerHTML;
" in doc
end tell
set AppleScript's text item delimiters to ">Mutual Friends ("
set refinedForPhotoCount to text items of sourceCode
try
set block to item 2 of refinedForPhotoCount
on error
delay 10
tell application "Safari"
set doc to front document
set sourceCode to do JavaScript "
document.documentElement.outerHTML;
" in doc
end tell
set refinedForPhotoCount to text items of sourceCode
set block to item 2 of refinedForPhotoCount --we're getting an error here
end try
set AppleScript's text item delimiters to ")"
set refined to text items of block
set blah to item 1 of refined
--display dialog blah
--return photoCount
set numberOfMutualFriends to blah
set weveGotAnError to false
--https://graph.facebook.com/btaylor?fields=gender
try
set numberOfMutualFriends to numberOfMutualFriends as number
on error
set weveGotAnError to true
end try
if weveGotAnError is false then
set returned to {id, numberOfMutualFriends}
else
set returned to {"false", "false"}
end if
return returned
end dataExtraction
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on storeIDs(user_id, friendPhotoCount, database1)
tell application "Database Events"
tell database1
set node to make new record with properties {name:user_id}
tell node
make new field with properties {name:"Name", value:(item 1 of friendPhotoCount)}
make new field with properties {name:"Number Of Mutual Friends", value:(item 2 of friendPhotoCount)}
end tell
end tell
end tell
save database1
end storeIDs
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on existsInDatabaseChecker(user_id, database1)
tell application "Database Events"
if record user_id of database1 exists then
return true
else
return false
end if
end tell
end existsInDatabaseChecker
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on exportToPlist(database1)
tell application "System Events"
set parent_dictionary to make new property list item with properties {kind:record}
set the plistfile_path to ("Macintosh HD:Users:Puccio:Documents:My Documents:Scripts:Database:" & "FriendPhoto.plist")
set plist to make new property list file with properties {contents:parent_dictionary, name:plistfile_path}
end tell
tell application "Database Events"
repeat with y from 4 to count of records in database1
set thefields to {}
set currentRecordName to name of record y of database1
repeat with x from 2 to count of fields of record currentRecordName in database1
set end of thefields to value of field x of record currentRecordName of database1
end repeat
tell application "System Events"
tell plist
set node to make new property list item at end with properties {kind:record, name:currentRecordName}
tell node
set fieldID to item 1 of thefields
make new property list item at end with properties {name:"Number of Friends", value:fieldID}
set fieldID to item 2 of thefields
make new property list item at end with properties {name:"Number of Photos", value:fieldID}
end tell
end tell
end tell
end repeat
end tell
end exportToPlist
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
set theOutputFolder to POSIX path of "Macintosh HD:Users:Puccio:Documents:My Documents:Scripts:Database:"
set databaselocation to POSIX path of "Macintosh HD:Users:Puccio:Documents:My Documents:Scripts:Database:GroupPrediction.dbev"
tell application "Database Events"
set database1 to database databaselocation
end tell
--exportToPlist(database1)
set processCancelled to false
set requestingStartingID to display dialog "Enter the subject whose friends you want to analyze" default answer "Monstermac77" with title "Analyze" buttons {"Indirect", "Direct", "Cancel"} default button "Indirect"
set button_pressed to the button returned of the result
if the button_pressed is "Direct" then
set startingIDType to "Direct"
else if the button_pressed is "Indirect" then
set startingIDType to "Indirect"
else
set processCancelled to true
end if
display dialog "Would you like to use what's already in the database?" buttons {"Yes", "No"} default button "Yes"
if button returned of the result is "No" then
set startingID to text returned of requestingStartingID
set unfiltered_links to friendExtractionGivenan(startingID, startingIDType)
set returnedIDs to extractionOfIDsFrom(unfiltered_links)
set refinedIDs to {}
repeat with b from 1 to count of returnedIDs
set IDinterest to item b of returnedIDs
set done to existsInDatabaseChecker(IDinterest, database1)
--set done to false
if done is false then
set end of refinedIDs to IDinterest
end if
end repeat
repeat with a from 1 to count of refinedIDs
set IDofInterest to item a of refinedIDs
set mutualFriendCount to dataExtraction(startingID, IDofInterest, "Indirect")
storeIDs(IDofInterest, mutualFriendCount, database1)
end repeat
else
end if
display dialog "What would you like to do?" buttons {"Export groups", "Analyze"} default button "Export groups"
if button returned of the result is "Export groups" then
set outputText to ""
tell application "Database Events"
repeat with y from 1 to count of records in database1
set thefields to {}
set currentRecordName to name of record y of database1
repeat with x from 2 to count of fields of record currentRecordName in database1
set end of thefields to value of field x of record currentRecordName of database1
end repeat
set outputText to outputText & return & (item 1 of thefields) & "," & (item 2 of thefields)
end repeat
end tell
tell application "TextEdit"
activate
make new document
set text of document 1 to outputText as text
--save document 1 in "/Users/Puccio/Desktop/hey.txt"
end tell
else
set frequencyTable to {}
set mutualFriendTable to {}
tell application "Database Events"
repeat with y from 1 to count of records in database1
set currentRecordName to name of record y of database1
set numberOfMutualFriends to value of field 3 of record currentRecordName of database1
set end of mutualFriendTable to {currentRecordName, numberOfMutualFriends}
end repeat
repeat with y from 1 to count of records in database1
set currentRecordName to name of record y of database1
set currentFrequency to 0
repeat with x from 1 to count of records in database1
set secondRecordName to name of record x of database1
if x is not equal to y then
if value of field 3 of record currentRecordName of database1 is equal to value of field 3 of record secondRecordName of database1 then
set currentFrequency to currentFrequency + 1
end if
end if
end repeat
set end of frequencyTable to {currentRecordName, currentFrequency}
end repeat
end tell
set currentHighestFrequency to 0
set guyWithHighestFrequency to 0
repeat with a from 1 to count of items in frequencyTable
if item 2 of item a of frequencyTable is greater than currentHighestFrequency then
set guyWithHighestFrequency to item 1 of item a of frequencyTable
end if
end repeat
return guyWithHighestFrequency
set theMostMutual to 0
repeat with a from 1 to count of items in mutualFriendTable
if item 1 of item a of mutualFriendTable is equal to guyWithHighestFrequency then
set theMostMutual to item 2 of item a of mutualFriendTable
end if
end repeat
set aGroup to {}
set range to 0
repeat with a from 1 to count of items in mutualFriendTable
if item 2 of item a of mutualFriendTable is greater than theMostMutual - range and item 2 of item a of mutualFriendTable is less than theMostMutual + range or item 2 of item a of mutualFriendTable is equal to theMostMutual then
set end of aGroup to {item 1 of item a of mutualFriendTable, item 2 of item a of mutualFriendTable}
end if
end repeat
set range to range + 1
end if