Skip to content

Instantly share code, notes, and snippets.

@dcadenas
Created March 28, 2012 00:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dcadenas/2222145 to your computer and use it in GitHub Desktop.
Save dcadenas/2222145 to your computer and use it in GitHub Desktop.
Popular Uruguayan githubbers
#!/usr/bin/env ruby
require 'rubygems'
require 'json'
require 'rankable_graph'
require 'net/http'
require 'mechanize'
require 'nokogiri'
def follower_usernames_of(user)
@follower_usernames_of ||= {}
return @follower_usernames_of[user] if @follower_usernames_of.has_key?(user)
@time_of_last_req ||= Time.now
json_result = Net::HTTP.get(URI("http://github.com/api/v2/json/user/show/#{user}/followers"))
time_since_last_req = Time.now - @time_of_last_req
@time_of_last_req = Time.now
time_to_sleep = 1 - time_since_last_req
if time_to_sleep > 0
puts "Sleeping #{time_to_sleep} secs"
sleep(time_to_sleep)
end
@follower_usernames_of[user] = [JSON.parse(json_result)["users"]].flatten.compact
end
def get_uruguayan_usernames
a = Mechanize.new { |agent|
agent.user_agent_alias = 'Mac Safari'
}
html = ""
(1..10).each do |i|
html += a.get("https://github.com/search?langOverride=&language=&q=location%3A+uruguay&repo=&start_value=#{i}&type=Users").body
end
doc = Nokogiri(html)
doc.css("h2.title a").map{|a| a.text}.uniq
end
def grow_list_with_followers(initial_username_list)
followers_of_initial_list = initial_username_list.map do |username|
follower_usernames_of(username)
end
followers_of_initial_list.flatten!.uniq!
(initial_username_list + followers_of_initial_list).uniq
end
def get_uruguayans_and_their_followers(levels)
if !File.exists?("usernames")
uruguayan_usernames = get_uruguayan_usernames
usernames = uruguayan_usernames
#The biggest the number of leves, the more precise the calculation is but slower
levels.times do
usernames = grow_list_with_followers(usernames)
end
File.open("usernames", 'wb') do |f|
f.write Marshal.dump([usernames, uruguayan_usernames])
end
[usernames, uruguayan_usernames]
else
Marshal.load(File.binread("usernames"))
end
end
usernames, uruguayan_usernames = get_uruguayans_and_their_followers(levels = 2)
puts "#{usernames.size} usernames"
unused_id = usernames.size
id2username_hash = {}
username2id_hash = {}
usernames.each_with_index do |username, user_id|
id2username_hash[user_id] = username
username2id_hash[username] = user_id
end
puts
rankable_graph = RankableGraph.new
id2username_hash.each do |id, user|
follower_usernames = follower_usernames_of(user)
follower_usernames.each do |follower_name|
follower_id = username2id_hash[follower_name]
if follower_id.nil?
follower_id = unused_id
unused_id += 1
end
puts "#{follower_name}(#{follower_id}) follows #{user}(#{id})"
rankable_graph.link(follower_id.to_i, id.to_i)
end
end
ranked_uruguayans = []
rankable_graph.rank(0.85, 0.0001) do |id, rank|
ranked_uruguayans << [id, rank] if uruguayan_usernames.include?(id2username_hash[id])
end
ranked_uruguayans.sort! do |a, b|
b.last <=> a.last
end
ranked_uruguayans.each do |id, rank|
puts "#{id2username_hash[id]}: #{rank}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment