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.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<em>frequency' # Text to find correct XML element
  18.  
  19.   FETCH</em>NUMBER = 8 # how many username rates to fetch from URL<em>PREFIX at once
  20.   SLEEP</em>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<em>friends(username)
  29.     @friends = @twitter.friends</em>for(username).map {|friend| friend.screen<em>name}.sort</em>by{rand}
  30.     STDERR.puts "Fetched #{@friends.size} friends"
  31.   end
  32.  
  33.   def get<em>update</em>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<em>line = lines.select{|line| line.include? PATTERN}.first
  43.       if update</em>line.nil?
  44.         -1
  45.       else
  46.         update<em>line.match(/<#{PATTERN}>([0-9]*)<\/#{PATTERN}>/).captures.first.to</em>i
  47.       end
  48.     end
  49.   end
  50.  
  51.   def fetch<em>stats
  52.     STDERR.puts "Fetching friends of #{USERNAME}…"
  53.     fetch</em>friends(USERNAME)
  54.     total = @friends.size
  55.     fetched = 0
  56.     @friends.each<em>by(FETCH</em>NUMBER) do |set|
  57.       STDERR.puts "Fetching rates for #{set.join(', ')}"
  58.       STDERR.print "Fetching: "
  59.       set.each do |friend|
  60.         @stats[friend] = get<em>update</em>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<em>INTERVAL} seconds …"
  67.         sleep SLEEP</em>INTERVAL + (rand * 5).to<em>i
  68.       end
  69.     end
  70.     @stats
  71.   end
  72.  
  73.   def sorted</em>stats
  74.     sorted = @stats.to<em>a.sort</em>by {|pair| pair.reverse}
  75.     partitioned = sorted.partition{|pair| pair.last == -1}
  76.     partitioned.last + partitioned.first
  77.   end
  78.  
  79.   def print<em>table
  80.     fetch</em>stats
  81.  
  82.     username<em>width = [@stats.keys.map{|username| username.length}.max, 10].max + 1
  83.     username</em>header = 'Username'.center(username<em>width)
  84.  
  85.     rate</em>width = [@stats.keys.map{|rate| rate.to<em>s.length + 8}.max, 13].max + 1
  86.     rate</em>header = 'Updates every'.center(rate<em>width)
  87.  
  88.     header = username</em>header + '|' + rate<em>header
  89.     underline = "-" * header.length
  90.  
  91.     puts
  92.     puts header
  93.     puts underline
  94.  
  95.     sorted</em>stats.each do |pair|
  96.       username, rate = pair.first, pair.last
  97.       rate = rate == -1 ? 'no data' : "#{rate.to<em>s} seconds"
  98.       puts username.center(username</em>width) + '|' + rate.center(rate<em>width)
  99.     end
  100.   end
  101. end
  102.  
  103. FriendStats.new.print</em>table

Thanks to:

Comments

Hi Ben! I’m really glad

Hi Ben! I’m really glad you made this script–quick question, as it’s not working on my MBP running Leopard–I keep getting “friendstats.rb:3:in `require’: no such file to load – twitter (LoadError) from friendstats.rb:3” even though I made sure to install twitter in the way suggested, as well as facets. Do you have any idea what I’m doing wrong?

John: not too familiar with

John: not too familiar with Ruby on the MBP, but try requiring ‘rubygems’ first, so place above line 3 above the line require 'rubygems'. Let me know how that works!

Original Author

Post new comment

Join the conversation! Tell me what you think:
The content of this field is kept private and will not be shown publicly.
  • You can use Markdown syntax to format and style the text.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <apachelog>, <bash>, <c>, <cfdg>, <cpp>, <cpp-qt>, <csharp>, <css>, <drupal5>, <drupal6>, <haskell>, <html4strict>, <io>, <java-generic>, <java>, <javascript>, <latex>, <lisp>, <mysql>, <ocaml>, <ocaml-breif>, <perl>, <php>, <php-breif>, <python>, <rails>, <robots>, <ruby>, <smalltalk>, <sql>, <text>, <xml>.
  • Syntax: [amazon title|cover|info asin] Example: [amazon cover B0007M123K]
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

Be sure to read my comment policy.

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
4 + 4 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.