Last active
December 11, 2015 14:58
-
-
Save darkhelmet/4618013 to your computer and use it in GitHub Desktop.
A migrator for 37Signals' BCX.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'httparty' | |
require 'active_support/all' | |
module PartyPooper | |
def get(url, options = {}) | |
self.class.get("/#{account_id}/api/v1/#{url}", options.merge(extras)) | |
rescue => boom | |
puts boom.message | |
retry | |
end | |
def post(url, data, options = {}) | |
self.class.post("/#{account_id}/api/v1/#{url}", options.merge(extras(post_headers)).merge(body: data.to_json)) | |
rescue => boom | |
puts boom.message | |
retry | |
end | |
def put(url, data, options = {}) | |
self.class.put("/#{account_id}/api/v1/#{url}", options.merge(extras(post_headers)).merge(body: data.to_json)) | |
rescue => boom | |
puts boom.message | |
retry | |
end | |
def extras(h = headers) | |
{ basic_auth: basic_auth, headers: h } | |
end | |
def basic_auth | |
{ username: username, password: password } | |
end | |
def headers | |
{ 'User-Agent' => user_agent } | |
end | |
def post_headers | |
headers.merge('Content-Type' => 'application/json') | |
end | |
end | |
Client = Struct.new(:username, :password, :user_agent, :account_id, :project_id) do | |
include HTTParty | |
include PartyPooper | |
base_uri 'https://basecamp.com' | |
def todo_lists | |
get("/projects/#{project_id}/todolists.json") | |
end | |
def completed_todo_lists | |
get("/projects/#{project_id}/todolists/completed.json") | |
end | |
def todo_list(id) | |
get("/projects/#{project_id}/todolists/#{id}.json") | |
end | |
def create_todo_list(data) | |
post("/projects/#{project_id}/todolists.json", data) | |
end | |
def todos(list) | |
get("/projects/#{project_id}/todolists/#{list}.json") | |
end | |
def todo(id) | |
get("/projects/#{project_id}/todos/#{id}.json") | |
end | |
def create_todo(list, data) | |
post("/projects/#{project_id}/todolists/#{list}/todos.json", data) | |
end | |
def complete_todo(id) | |
put("/projects/#{project_id}/todos/#{id}.json", completed: true) | |
end | |
def create_todo_comment(id, data) | |
post("/projects/#{project_id}/todos/#{id}/comments.json", data) | |
end | |
end | |
Migrator = Struct.new(:from, :to, :log) do | |
def migrate | |
lists.each { |list| migrate_list(list) } | |
end | |
def migrate_list(list) | |
log.info("Migrating #{list['name']}") | |
destination = to.create_todo_list(list.slice('name')) | |
todos_from_list(list).each { |todo| migrate_todo(todo, destination) } | |
end | |
def migrate_todo(todo, destination) | |
log.info("\tMigrating todo #{todo['content']}") | |
todo = from.todo(todo['id']) | |
ctodo = to.create_todo(destination['id'], todo.slice('content')) | |
comments = comments_from_todo(todo) | |
if comments.present? | |
log.info("\tMigrating #{comments.count} comments") | |
comments.each { |comment| migrate_comment(comment, ctodo) } | |
end | |
complete_todo(ctodo) if todo['completed'] | |
end | |
def complete_todo(todo) | |
log.info("\tCompleting #{todo['content']}") | |
to.complete_todo(todo['id']) | |
end | |
def comments_from_todo(todo) | |
Array(todo['comments']) | |
end | |
def migrate_comment(comment, todo) | |
to.create_todo_comment(todo['id'], comment.slice('content')) | |
end | |
def lists | |
from.completed_todo_lists.reverse + from.todo_lists.reverse | |
end | |
def todos_from_list(list) | |
todos = from.todo_list(list['id'])['todos'] | |
Array(todos['remaining']) + Array(todos['completed']) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'logger' | |
require_relative 'client' | |
username = 'username' | |
password = 'password' | |
user_agent = 'BCX Mover (email@example.com)' | |
from_account_id = 1234 | |
from_project_id = 2345 | |
to_account_id = 5678 | |
to_project_id = 6789 | |
from = Client.new(username, password, user_agent, from_account_id, from_project_id) | |
to = Client.new(username, password, user_agent, to_account_id, to_project_id) | |
log = Logger.new(STDOUT) | |
log.formatter = Logger::Formatter.new | |
Migrator.new(from, to, log).migrate |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment