Skip to content

Instantly share code, notes, and snippets.

@realfirst
Forked from Yengas/README.md
Created July 9, 2018 07:56
Show Gist options
  • Save realfirst/eaac82a8036c7f0c02d5098062bee636 to your computer and use it in GitHub Desktop.
Save realfirst/eaac82a8036c7f0c02d5098062bee636 to your computer and use it in GitHub Desktop.
Finding common friends of a given steam users, and creating a graph network.

Steam Friends

This is a simple ruby script to create (in adjacent list format) graph networks of a given array of steam users. You can also use this script to find the most common friends of a given group of users.

Examples

Below are some examples of using this script.

Creating a graph network

outputCSV(createNetwork(['yigitcan2', 'Boneslark']), 'output.csv');

This line gets the friends of the users yigitcan2 and Boneslark, then outputs a csv file; representing the nodes and edges of the friends network of these users.

Finding the common friends

puts findCommon(['yigitcan2', 'Boneslark']).inspect;

This line finds the common friends of the users yigitcan2 and Boneslark, outputs the resulting request to the $stdin.

require 'uri'
require 'open-uri'
require 'nokogiri'
# Outputs an adjacent list graph network in csv format.
# @param network {Object} key/value mappings of users to their friends.
# @param file_name {String} file to save the generated csv string.
def outputCSV(network, file_name = 'output.csv')
output = File.open(file_name, 'w');
network.each{|name, friends|
output.write(([name] + friends).join(';') + "\n");
}
output.close
end
# Returns an url that points to the given user's friends page.
# @param name {String} name/id of the user.
# @return {String} full url to the friends page of the user.
def getURLByName(name)
path = name.match(/[^0-9]+/) ? 'id' : 'profiles'
return 'http://steamcommunity.com/%s/%s/friends' % [path, URI::escape(name)]
end
# Returns the id/name of a user given a steam profile url.
# @param uri {String} full url of the steam profile page.
# @return {String} id/name of the user that the page belongs to.
def getNameByURL(uri)
match = uri.to_str.match(/(?:profiles|id)\/(.*?)(?:$|\/)/);
return match ? match[1] : match;
end
# Returns the friends of a given user.
# @param id {String} id/name of the user to retrieve the friends of.
# @return {Array} an array of strings that holds the id/names of the friends of the user.
def getFriends(id)
uri = getURLByName(id)
doc = Nokogiri::HTML(open(uri));
return doc.css('a[class="friendBlockLinkOverlay"]').map{ |a| getNameByURL(a.attributes["href"]) };
end
# Generates a key/value mapping of users to friends, given an array of ids/names.
# @param ids {Array} an array of users to retrieve friends for.
# @return {Object} key/value mapping of user to his/her friends.
def createNetwork(ids)
friends = {};
ids.each{ |id|
friends[id] = getFriends(id);
}
return friends
end
# Adds a given user to the given hashmap, if it already exists increments the counter.
def addToCommon(common, user)
common[user] = 0 unless common.has_key? user
common[user] += 1;
end
# Finds the commons friends of a given array of users.
# @param ids {Array} of users to get compare friends of.
# @return {Object} key/value map containing common friends, with a value of occurrence.
def findCommon(ids)
commons, before_friends = {}, [];
ids.each{|id|
friends = getFriends(id);
# For each friends array, we got before...
before_friends.each{ |before|
# Get intersection of current users friends and previous ones,
# and insert them into the commons map.
(before & friends).each{ |f| addToCommon(commons, f) };
}
# add this users friends to the previous friends array.
before_friends.push(friends);
};
return commons;
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment