Skip to content

Instantly share code, notes, and snippets.

@jspiewak
Last active August 29, 2015 14:02
Show Gist options
  • Save jspiewak/fea5e2b033f909c65951 to your computer and use it in GitHub Desktop.
Save jspiewak/fea5e2b033f909c65951 to your computer and use it in GitHub Desktop.
PivotalTracker Sprint Breakdown by Team Member
#!/usr/bin/env ruby
require 'net/http'
require 'json'
require 'time'
class PivotalTracker
attr_accessor :token, :project
def initialize(args)
@token = args[0]
@project = args[1]
end
def get_done
Net::HTTP.start('www.pivotaltracker.com', 443, :use_ssl => true) do |http|
request = Net::HTTP::Get.new "/services/v5/projects/#{project}/iterations?scope=done&offset=-2"
request['X-TrackerToken'] = token
response = http.request(request)
if response.message == 'OK'
JSON.parse response.body
else
raise 'Failed to retrieve done iterations'
end
end
end
def get_iterations
Net::HTTP.start('www.pivotaltracker.com', 443, :use_ssl => true) do |http|
request = Net::HTTP::Get.new "/services/v5/projects/#{project}/iterations?scope=current_backlog&limit=3"
request['X-TrackerToken'] = token
response = http.request(request)
if response.message == 'OK'
JSON.parse response.body
else
raise 'Failed to retrieve current and backlog'
end
end
end
def get_people
Net::HTTP.start('www.pivotaltracker.com', 443, :use_ssl => true) do |http|
request = Net::HTTP::Get.new "/services/v5/projects/#{project}/memberships"
request['X-TrackerToken'] = token
response = http.request(request)
if response.message == 'OK'
memberships = JSON.parse response.body
people = {}
memberships.each { |pm|
people[pm['person']['id']] = pm['person']['name']
}
return people
else
raise 'Failed to retrieve project members'
end
end
end
def summarize_iteration(iteration, people)
stories = iteration['stories']
puts 'You have unestimated stories in your iteration!' if stories.any? { |story| story['estimate'].nil? }
stories.delete_if { |story| story['story_type'] == 'release' or story['estimate'].nil? }
puts "Iteration #{iteration['number']} ending on #{(Time.parse(iteration['finish']).localtime - 1).strftime('%D')} has #{stories.inject(0) { |points, story| points + story['estimate'] }} points"
# puts stories
load = {}
unassigned = 0
stories.each { |story|
story['owner_ids'].each { |owner|
unless load[owner]
load[owner] = {}
load[owner].default = 0.0
end
load[owner]['total'] += (story['estimate'] * 1.0 / story['owner_ids'].length)
load[owner][story['current_state']] += (story['estimate'] * 1.0 / story['owner_ids'].length)
}
unassigned += story['estimate'] if story['owner_ids'].empty?
}
load.sort_by { |k,v| -(v['total']) } .each { |k,v| puts "#{people[k]} has #{v} points." }
puts "There are #{unassigned} unassigned points" if unassigned > 0
puts '--------'
end
end
pt = PivotalTracker.new(ARGV)
people = pt.get_people
# puts people
iterations = pt.get_done + pt.get_iterations
iterations.each { |iteration| pt.summarize_iteration(iteration, people) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment