Skip to content

Instantly share code, notes, and snippets.

@lazyatom
Created February 17, 2010 15:41
Show Gist options
  • Select an option

  • Save lazyatom/306724 to your computer and use it in GitHub Desktop.

Select an option

Save lazyatom/306724 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'free_agent'
# You'll need the 'free_agent' gem, which is on gemcutter, or available here:
# http://github.com/lazyatom/free_agent
# Next, you'll want the config:
#
# ---
# :domain: lazyatom # for example
# :email: [email protected]
# :password: yourpassword
# :user_id: <your user id on freeagent for this company>
# :freerange:
# :domain: freerange
# :email: [email protected]
# :password: yourpassword
# :user_id: <your user id on freeagent for this company>
# :mapping:
# <id of project in your company>: 27129 # Internal
# <id of project in your company>: 27506 # Chromaroma
# <id of project in your company>: 26465 # TellYouGov
# <id of project in your company>: 28588 # #blue
#
config = YAML.load_file(File.expand_path("~/.freeagent.yml"))
# and change this:
date_limit = Time.parse("2010-02-16 00:00:00")
# Maybe uncomment these...
# RestClient.log = 'stdout'
# RestClient.proxy = "http://127.0.0.1:8888/"
# OK, the rest should be good to leave as-is
MyCompany = FreeAgent::Company.new(config[:domain], config[:email], config[:password])
me = MyCompany.users.find(config[:user_id])
FreeRange = FreeAgent::Company.new(config[:freerange][:domain], config[:freerange][:email], config[:freerange][:password])
me_on_freerange = FreeRange.users.find(config[:freerange][:user_id])
project_mapping = config[:freerange][:mapping].inject({}) do |m, (your_company_id, freerange_id)|
m[MyCompany.projects.find(your_company_id)] = FreeRange.projects.find(freerange_id)
end
class Syncer
SYNC_TOKEN = "✓"
attr_reader :target_company, :target_user, :project_mapping, :task_mapping
def initialize(target_company, target_user, project_mapping)
@target_company = target_company
@target_user = target_user
@project_mapping = project_mapping
@task_mapping = {}
end
module TimeslipSync
def synced?
self.comment =~ /#{SYNC_TOKEN}$/
end
def mark_as_synced
self.comment = [self.comment || "", SYNC_TOKEN].join(" ")
save
end
end
def sync(timeslip)
timeslip.extend(TimeslipSync)
unless timeslip.synced?
source_project = project_mapping.keys.find { |p| p.id == timeslip.project_id }
next unless source_project # skip projects we don't care about
target_project = project_mapping[source_project]
new_attributes = timeslip.attributes.merge({
"project_id" => target_project.id,
"user_id" => target_user.id
})
new_attributes.delete("id")
new_attributes.delete("updated_at")
new_attributes.delete("task_id")
new_attributes.merge!(attributes_for_target_task(timeslip, source_project, target_project))
new_timeslip = target_company.timeslips.create(new_attributes)
timeslip.mark_as_synced
end
end
def attributes_for_target_task(timeslip, source_project, target_project)
if task = task_mapping[timeslip.task_id]
{"task_id" => task.id}
else
source_task = source_project.tasks.find(timeslip.task_id)
if target_task = target_project.tasks.find { |t| t.name == source_task.name }
task_mapping[source_task.id] = target_task
{"task_id" => target_task.id}
else
{"new_task" => source_task.name}
end
end
end
end
my_timeslips = MyCompany.projects.map do |project|
project.timeslips.select { |t| t.user_id == me.id }
end.flatten
my_timeslips.reject! { |t| t.dated_on < date_limit }
syncer = Syncer.new(FreeRange, me_on_freerange, project_mapping)
my_timeslips.each do |timeslip|
if syncer.sync(timeslip)
puts "Synced #{timeslip.comment} (#{timeslip.hours.to_f})"
else
puts "Skipped #{timeslip.comment}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment