How to sort your Twitter friends by update frequency

Have you ever wished you could sort all of the people you follow on Twitter by how frequently they update? Here is a Ruby script that will do that for you. It asks Twitter for your friends, and uses Gene Smith’s Tweeterboard.com to determine update frequency. (Follow tweeterboard to let it know to track your stats).

To use the script, simply download it below, edit the constants at the top of the file, at run: ruby friendstats.rb. (Optional step: unfollow your boring-but-prolific “friends”).

Feedback appreciated. Usual disclaimer applies: beware, may kill your cat, I’m not liable, etc.

Requirements:

  • twitter gem
  • facets gem

To install: sudo gem install facets twitter.

(Download the code. Sample output.)

  1. #!/usr/bin/env ruby
  2.  
  3. require ‘twitter’
  4. require ‘open-uri’
  5. require ‘facets/enumerable’
  6.  
  7. $stdout.sync = true
  8.  
  9. class FriendStats
  10. ########## Configuration start here: ##########
  11.   EMAIL = your {@} email [dot] com # Authorization email
  12.   PASSWORD = ‘yourpassword’ # Authorization password
  13.  
  14.   USERNAME = ‘yourusername’ # Username whose friends to analyze
  15.  
  16.   URL = ‘http://tweeterboard.com/data/%s/dashboard’ # URL to fetch update rate from
  17.   PATTERN = ‘update_frequency’ # Text to find correct XML element
  18.  
  19.   FETCH_NUMBER = 8 # how many username rates to fetch from URL_PREFIX at once
  20.   SLEEP_INTERVAL = 30 # Sleep time between fetching rate, in seconds
  21. ########### Configuration ends here ###########
  22.  
  23.   def initialize
  24.     @twitter = Twitter::Base.new(EMAIL, PASSWORD)
  25.     @stats = {}
  26.   end
  27.  
  28.   def fetch_friends(username)
  29.     @friends = @twitter.friends_for(username).map {|friend| friend.screen_name}.sort_by{rand}
  30.     STDERR.puts "Fetched #{@friends.size} friends"
  31.   end
  32.  
  33.   def get_update_rate(username)
  34.     url = URL % username
  35.     begin
  36.       STDERR.print ’.’
  37.       lines = open(url) {|io| io.readlines}
  38.     rescue SocketError => e
  39.       STDERR.puts "Could not connect to #{url}"
  40.       exit 1
  41.     else
  42.       update_line = lines.select{|line| line.include? PATTERN}.first
  43.       if update_line.nil?
  44.         -1
  45.       else
  46.         update_line.match(/<#{PATTERN}>([0-9]*)<\/#{PATTERN}>/).captures.first.to_i
  47.       end
  48.     end
  49.   end
  50.  
  51.   def fetch_stats
  52.     STDERR.puts "Fetching friends of #{USERNAME}…"
  53.     fetch_friends(USERNAME)
  54.     total = @friends.size
  55.     fetched = 0
  56.     @friends.each_by(FETCH_NUMBER) do |set|
  57.       STDERR.puts "Fetching rates for #{set.join(‘, ‘)}"
  58.       STDERR.print "Fetching: "
  59.       set.each do |friend|
  60.         @stats[friend] = get_update_rate(friend)
  61.       end
  62.       STDERR.puts
  63.       fetched += set.size
  64.       STDERR.puts "Fetched #{fetched} out of #{total} friends"
  65.       if fetched != total
  66.         STDERR.puts "Sleeping #{SLEEP_INTERVAL} seconds …"
  67.         sleep SLEEP_INTERVAL + (rand * 5).to_i
  68.       end
  69.     end
  70.     @stats
  71.   end
  72.  
  73.   def sorted_stats
  74.     sorted = @stats.to_a.sort_by {|pair| pair.reverse}
  75.     partitioned = sorted.partition{|pair| pair.last == -1}
  76.     partitioned.last + partitioned.first
  77.   end
  78.  
  79.   def print_table
  80.     fetch_stats
  81.  
  82.     username_width = [@stats.keys.map{|username| username.length}.max, 10].max + 1
  83.     username_header = ‘Username’.center(username_width)
  84.  
  85.     rate_width = [@stats.keys.map{|rate| rate.to_s.length + 8}.max, 13].max + 1
  86.     rate_header = ‘Updates every’.center(rate_width)
  87.  
  88.     header = username_header + ’|’ + rate_header
  89.     underline = "-" * header.length
  90.  
  91.     puts
  92.     puts header
  93.     puts underline
  94.  
  95.     sorted_stats.each do |pair|
  96.       username, rate = pair.first, pair.last
  97.       rate = rate == -1 ? ‘no data’ : "#{rate.to_s} seconds"
  98.       puts username.center(username_width) + ’|’ + rate.center(rate_width)
  99.     end
  100.   end
  101. end
  102.  
  103. FriendStats.new.print_table

Thanks to: