The best kittens, technology, and video games blog in the world.

Tuesday, October 01, 2013

Displaying your beeminder goal status with Ruby

Taz, working on his cat loaf by DirtBikeDBA (Mike) from flickr (CC-NC-ND)
I have one rake task that updates everything that needs updating (git fetch -p and such stuff), and another that displays status of all things in progress. I want to add status of my Beeminder goals to that.

Step one is to login to Beeminder in a browser, open this URL, and copy auth token (without the rest of JSON stuff) to ~/.beeminder_auth_token.

Step two is to gem install beeminder.

Step three is the following code:
require "beeminder"

class Beeminder::Goal
  def days_to_lose
    (losedate.to_date - Date.today).to_i
  end
end

class Array
  def avg
    inject(0.0, &:+) / size
  end
end

desc "Display beeminder status"
task "beeminder:status" do
  token = File.read("#{ENV["HOME"]}/.beeminder_auth_token").chomp
  goals = Beeminder::User.new(token).goals.select{|g| g.days_to_lose >= 0 }
  goals.sort_by(&:days_to_lose).each do |g|
    puts "* #{g.title} - #{g.days_to_lose}"
  end
  puts "Avearge: %.2f" % [goals.map(&:days_to_lose).avg]
end

I monkeypatch Beeminder::Goal#days_to_lose since that's the most relevant information here. It is one higher than number displayed on Beeminder graphs, since it includes reporting day - you're not really meant to do things that extra day.

Then I add Array#avg - something that really should be in the standard library.

Then I get auth token, fetch goals from beeminder, reject goals that are already lost (one from my previous attempt forever ago), and display and average the rest.

It's all pretty straightforward, and it seems that submitting datapoints via API will also be pretty simple once I get to that.

No comments: