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:
twittergemfacetsgem
To install: sudo gem install facets twitter.
(Download the code. Sample output.)
- #!/usr/bin/env ruby
- require 'twitter'
- require 'open-uri'
- require 'facets/enumerable'
- $stdout.sync = true
- class FriendStats
- ########## Configuration start here: ##########
- EMAIL = 'your@email.com' # Authorization email
- PASSWORD = 'yourpassword' # Authorization password
- USERNAME = 'yourusername' # Username whose friends to analyze
- URL = 'http://tweeterboard.com/data/%s/dashboard' # URL to fetch update rate from
- PATTERN = 'update<em>frequency' # Text to find correct XML element
- FETCH</em>NUMBER = 8 # how many username rates to fetch from URL<em>PREFIX at once
- SLEEP</em>INTERVAL = 30 # Sleep time between fetching rate, in seconds
- ########### Configuration ends here ###########
- def initialize
- @twitter = Twitter::Base.new(EMAIL, PASSWORD)
- @stats = {}
- end
- def fetch<em>friends(username)
- @friends = @twitter.friends</em>for(username).map {|friend| friend.screen<em>name}.sort</em>by{rand}
- STDERR.puts "Fetched #{@friends.size} friends"
- end
- def get<em>update</em>rate(username)
- url = URL % username
- begin
- STDERR.print '.'
- lines = open(url) {|io| io.readlines}
- rescue SocketError => e
- STDERR.puts "Could not connect to #{url}"
- exit 1
- else
- update<em>line = lines.select{|line| line.include? PATTERN}.first
- if update</em>line.nil?
- -1
- else
- update<em>line.match(/<#{PATTERN}>([0-9]*)<\/#{PATTERN}>/).captures.first.to</em>i
- end
- end
- end
- def fetch<em>stats
- STDERR.puts "Fetching friends of #{USERNAME}…"
- fetch</em>friends(USERNAME)
- total = @friends.size
- fetched = 0
- @friends.each<em>by(FETCH</em>NUMBER) do |set|
- STDERR.puts "Fetching rates for #{set.join(', ')}"
- STDERR.print "Fetching: "
- set.each do |friend|
- @stats[friend] = get<em>update</em>rate(friend)
- end
- STDERR.puts
- fetched += set.size
- STDERR.puts "Fetched #{fetched} out of #{total} friends"
- if fetched != total
- STDERR.puts "Sleeping #{SLEEP<em>INTERVAL} seconds …"
- sleep SLEEP</em>INTERVAL + (rand * 5).to<em>i
- end
- end
- @stats
- end
- def sorted</em>stats
- sorted = @stats.to<em>a.sort</em>by {|pair| pair.reverse}
- partitioned = sorted.partition{|pair| pair.last == -1}
- partitioned.last + partitioned.first
- end
- def print<em>table
- fetch</em>stats
- username<em>width = [@stats.keys.map{|username| username.length}.max, 10].max + 1
- username</em>header = 'Username'.center(username<em>width)
- rate</em>width = [@stats.keys.map{|rate| rate.to<em>s.length + 8}.max, 13].max + 1
- rate</em>header = 'Updates every'.center(rate<em>width)
- header = username</em>header + '|' + rate<em>header
- underline = "-" * header.length
- puts
- puts header
- puts underline
- sorted</em>stats.each do |pair|
- username, rate = pair.first, pair.last
- rate = rate == -1 ? 'no data' : "#{rate.to<em>s} seconds"
- puts username.center(username</em>width) + '|' + rate.center(rate<em>width)
- end
- end
- end
- FriendStats.new.print</em>table
Thanks to:
- Gene Smith (gsmith) for the excellent Tweeterboard service.
- Mike Doeff (mdoeff) for the initial idea.
- John Nunemaker (jnunemaker) for his excellent Twitter gem.
- David Sifry (dsifry) for Hoosgot, and letting me know about Mike’s idea.
