|
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 |