-
-
Save nachowski/50cf59e7414e6c891f3c to your computer and use it in GitHub Desktop.
Facebook friend classifier script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script | |
src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> | |
<div id="fb-root"></div> | |
<script> | |
var users = []; | |
var llamas = []; | |
var accessToken = null; | |
// descending order | |
function sortfunction(a, b){ | |
var diff = b.score - a.score; | |
if (diff == 0) // same score | |
diff = b.id - a.id; | |
return diff; | |
} | |
function score(id) { | |
if (id === uid || typeof id === 'undefined' ) // this is us, do nothing | |
return; | |
if (!users[id]) { // corner case for non-friends | |
if (!llamas[id]) { // new category: drama llamas | |
var unknown = new Object(); | |
unknown.id = id; | |
unknown.name = "Some Drama Llama"; | |
unknown.score = 0; | |
llamas[id] = unknown; | |
} | |
llamas[id].score++; | |
return; | |
} | |
users[id].score++; | |
} | |
var totalCalls = 0; | |
var finishes = 0; | |
function finish() { | |
finishes++; | |
if (finishes === totalCalls) { | |
// sort users by score | |
var sorted = []; | |
// clone | |
for (var key in users) { | |
if(users.hasOwnProperty(key)) | |
{ | |
sorted.push(users[key]) | |
} | |
} | |
sorted.sort(sortfunction); | |
var friendCount = sorted.length; | |
// top 10% or top 30 = close friends | |
var topLimit = Math.floor(10 / 100 * friendCount); | |
if (topLimit > 30) | |
topLimit = 30; | |
// shit-list = bottom 3% or bottom 10 of your friend-list | |
var shitCount = Math.floor(3 / 100 * friendCount); | |
if (shitCount > 10) | |
shitCount = 10; | |
var shitListLimit = friendCount - shitCount; | |
var foundBottom = false; | |
// friends0, friends1, friends2, friends3, friends4, friends5 | |
var divname = 'friends0'; | |
for (var i=0; i < sorted.length; i++) { | |
var user = sorted[i]; | |
if (i == 5) | |
divname = 'friends1'; | |
// score = 0 = restricted | |
if (user.score == 0 && !foundBottom) { | |
divname = 'friends3'; | |
foundBottom = true; | |
} | |
var image = "http://graph.facebook.com/"+ user.id+ "/picture"; | |
var profileLink = "http://facebook.com/profile.php?id=" + user.id; | |
var altText = user.name + " (rank: "+ (i+1) + " of "+friendCount+", total score: " + user.score + ")"; | |
addImage(image, profileLink, altText, i, divname); | |
if (i == topLimit) { | |
divname = 'friends2'; | |
} else if (i == shitListLimit) { | |
divname = 'friends4'; | |
} | |
} | |
llamas.sort(sortfunction); | |
// deal with the llamas - this can be refactored but I am lazy | |
var sortedLlamas = []; | |
// clone | |
for (var key in llamas) { | |
if(llamas.hasOwnProperty(key)) | |
{ | |
if (llamas[key].score > 4) // llamas only have scores 5 and up | |
sortedLlamas.push(llamas[key]) | |
} | |
} | |
if (sortedLlamas.length > 0) { | |
divname = "friends5"; | |
for (var i=0; i < sortedLlamas.length; i++) { | |
var user = sortedLlamas[i]; | |
var image = "http://graph.facebook.com/"+ user.id+ "/picture"; | |
var profileLink = "http://facebook.com/profile.php?id=" + user.id; | |
var altText = user.name + " (total score: " + user.score + ")"; | |
addImage(image, profileLink, altText, (1000+i), divname); // yes i'm ashamed of myself here | |
} | |
} else { | |
document.getElementById("friends5").innerHTML = "No Drama Llamas found!"; | |
} | |
document.getElementById("container").style.display = "block"; | |
status(""); | |
} else { | |
var completed = Math.floor(finishes / totalCalls * 100); | |
status('Loading data. This may take a few minutes... ' + completed + '%'); | |
} | |
} | |
function addImage(image, profileLink, altText, i, divname) { | |
var img = new Image(); | |
img.parentImageId = divname; | |
img.fbLink = profileLink; | |
$('#'+divname).append( img ); | |
$(img) | |
.attr('src', image) | |
.attr('id', 'img' + i) | |
.attr('title', altText) | |
.load(function(){ | |
var a = $('<a/>').attr('href', this.fbLink); | |
$(this).wrap(a); | |
$(this).css( { | |
"height": "50px", | |
"width": "50px", | |
"padding": "4px", | |
"margin": "2px", | |
"border": "1px solid #333" | |
}); | |
}); | |
} | |
var scoreFQL = function(queryString, fieldName) { | |
totalCalls++; | |
FB.api( | |
{ | |
method: 'fql.query', | |
query: queryString, | |
access_token: accessToken | |
}, | |
function(response) { | |
for (var i=0; i< response.length; i++) { | |
var obj = response[i]; | |
score(obj[fieldName]); | |
} | |
finish(); | |
} | |
); | |
} | |
function doStuff() { | |
status("Loading data. This may take a few minutes..."); | |
FB.api('/me/friends',{limit: '1000'}, function(response) { | |
//users = response.data; | |
for (var i=0; i< response.data.length; i++) { | |
var user = response.data[i]; | |
user.score = 0; | |
users[user.id] = user; | |
} | |
var fromid = 'fromid'; | |
var user_id = 'user_id'; | |
var snippet_author = 'snippet_author'; | |
var commentTags = 'SELECT fromid FROM comment WHERE object_id IN (SELECT object_id FROM photo WHERE object_id IN (SELECT object_id FROM photo_tag WHERE subject=me()))'; | |
var commentPhotos = 'SELECT fromid FROM comment WHERE object_id IN (SELECT object_id FROM photo WHERE aid IN (SELECT aid FROM album WHERE owner=me()))'; | |
var likeTags ='SELECT user_id FROM like WHERE object_id IN (SELECT object_id FROM photo WHERE object_id IN (SELECT object_id FROM photo_tag WHERE subject=me()))'; | |
var likePhotos ='SELECT user_id FROM like WHERE object_id IN (SELECT object_id FROM photo WHERE aid IN (SELECT aid FROM album WHERE owner=me()))'; | |
var likeStatus = 'SELECT user_id FROM like WHERE object_id IN (SELECT status_id FROM status WHERE uid=me())'; | |
var commentStatus = 'SELECT fromid FROM comment WHERE object_id IN (SELECT status_id FROM status WHERE uid=me())'; | |
var commentLink = 'SELECT fromid FROM comment WHERE object_id IN (SELECT link_id FROM link WHERE owner=me())'; | |
var likeLink = 'SELECT user_id FROM like WHERE object_id IN (SELECT link_id FROM link WHERE owner=me())'; | |
var inboxMessages = 'SELECT snippet_author FROM thread WHERE folder_id = 0 AND viewer_id = me()'; | |
scoreFQL(commentTags, fromid); | |
scoreFQL(commentPhotos, fromid); | |
scoreFQL(likeTags, user_id); | |
scoreFQL(likePhotos, user_id); | |
scoreFQL(likeStatus, user_id); | |
scoreFQL(commentStatus, fromid); | |
scoreFQL(commentLink, fromid); | |
scoreFQL(likeLink, fromid); | |
scoreFQL(inboxMessages, snippet_author); | |
}); | |
} | |
function login() { | |
FB.login(function(response) { | |
if (response.authResponse) { | |
uid = response.authResponse.userID; | |
accessToken = response.authResponse.accessToken; | |
checkPermissions(); | |
} | |
}, {scope: 'read_stream,user_photos,read_mailbox'}); | |
} | |
function checkPermissions() { | |
FB.api('/me/permissions',{access_token: accessToken}, function(response) { | |
//users = response.data; | |
if (response.data[0].read_stream == 1 && response.data[0].user_photos == 1 && response.data[0].read_mailbox == 1) { | |
document.getElementById("loginButton").style.display = "none"; | |
doStuff(); | |
} else { | |
// damn you facebook, reauthenticate | |
document.getElementById("loginButton").style.display = "block"; | |
status("You haven't authorized all actions, please login to facebook and re-authorize the app"); | |
} | |
}); | |
} | |
function status(text) { | |
document.getElementById("data").innerHTML = text; | |
} | |
window.fbAsyncInit = function() { | |
FB.init({ | |
appId : '321149014639670', // App ID | |
status : true, // check login status | |
cookie : true, // enable cookies to allow the server to access the session | |
xfbml : true // parse XFBML | |
}); | |
document.getElementById("loginButton").style.display = "none"; | |
document.getElementById("container").style.display = "none"; | |
// Additional initialization code here | |
FB.getLoginStatus(function(response) { | |
if (response.status === 'connected') { | |
// the user is logged in and has authenticated your | |
// app, and response.authResponse supplies | |
// the user's ID, a valid access token, a signed | |
// request, and the time the access token | |
// and signed request each expire | |
uid = response.authResponse.userID; | |
accessToken = response.authResponse.accessToken; | |
checkPermissions(); | |
} else if (response.status === 'not_authorized') { | |
// the user is logged in to Facebook, | |
// but has not authenticated your app | |
document.getElementById("loginButton").style.display = "block"; | |
status("Please login to facebook and authorize the app"); | |
} else { | |
// the user isn't logged in to Facebook. | |
document.getElementById("loginButton").style.display = "block"; | |
status("Please login to facebook and authorize the app"); | |
} | |
}); | |
}; | |
// Load the SDK Asynchronously | |
(function(d){ | |
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0]; | |
if (d.getElementById(id)) {return;} | |
js = d.createElement('script'); js.id = id; js.async = true; | |
js.src = "http://connect.facebook.net/en_US/all.js"; | |
ref.parentNode.insertBefore(js, ref); | |
}(document)); | |
</script> | |
<body> | |
<button id="loginButton" onclick="javascript:login();return null">Login to facebook</button> | |
<div id="container"> | |
<fieldset> | |
<legend>Top Friends - these 5 friends show you more love on facebook than anyone else</legend> | |
<div id="friends0"></div> | |
</fieldset> | |
<fieldset> | |
<legend>Close Friends - your BFFs</legend> | |
<div id="friends1"></div> | |
</fieldset> | |
<fieldset> | |
<legend>Acquaintances - regular, healthy amounts of interaction</legend> | |
<div id="friends2"></div> | |
</fieldset> | |
<fieldset> | |
<legend>Restricted - you have nothing in common and almost never interact</legend> | |
<div id="friends3"></div> | |
</fieldset> | |
<fieldset> | |
<legend>Shit list - you should probably unfriend these folks</legend> | |
<div id="friends4"></div> | |
</fieldset> | |
<fieldset> | |
<legend>Potential sources of drama and/or stalkers (not from your friend list)</legend> | |
<div id="friends5"></div> | |
</fieldset> | |
</div> | |
<p id="data"></p> | |
<p id="footer">This page fetches your data directly from facebook and none of it is transmitted or collected. <a href="https://gist.github.com/50cf59e7414e6c891f3c">Source code here</a> (or just press Ctrl + U!)</p> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment