Skip to content

Instantly share code, notes, and snippets.

@elijah
Forked from tswicegood/sync_things.rb
Created November 17, 2010 19:28

Revisions

  1. @tswicegood tswicegood revised this gist Oct 1, 2009. 1 changed file with 18 additions and 1 deletion.
    19 changes: 18 additions & 1 deletion sync_things.rb
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,26 @@
    #!/usr/bin/env ruby
    #
    # Biggest problem with this is that it checks everything. Needs
    # to be adjusted to only check N days and/or N tasks on Basecamp.
    #
    # Also has a problem in that Completed always wins. If you have a
    # task marked at completed, then mark it as open again on just one
    # side, it'll mark the other as completed if you run the sync again.
    #
    # All that said, it provides a basic, very rudimentary sync.
    #
    # TODO:
    # - Check Logbook for items if they don't exist in their current
    # current location in Things.
    # - Control how many items to actually check for syncing purposes
    # - Use local cache to determine what syncing has happened in the
    # past and try to be smart about future syncs.

    require 'basecamp' # you need to d/l the basecamp.rb file from Basecamp
    require 'appscript' # gem install rb-appscript
    require 'yaml'

    conf = YAML.load(File.open("~/.sync_things.yaml"))
    conf = YAML.load(File.open(ENV['HOME'] + "/.sync_things.yaml"))
    Basecamp.establish_connection!(conf['url'], conf['username'], conf['password'], true)

    bucket_names = {
  2. @tswicegood tswicegood created this gist Oct 1, 2009.
    70 changes: 70 additions & 0 deletions sync_things.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,70 @@
    #!/usr/bin/env ruby
    require 'basecamp' # you need to d/l the basecamp.rb file from Basecamp
    require 'appscript' # gem install rb-appscript
    require 'yaml'

    conf = YAML.load(File.open("~/.sync_things.yaml"))
    Basecamp.establish_connection!(conf['url'], conf['username'], conf['password'], true)

    bucket_names = {
    :inbox => 1,
    :today => 2,
    :next => 3,
    :someday => 5,
    }

    basecamp_bucket = {}
    on_basecamp = {}


    lists = Basecamp::TodoList.all(3786988)
    lists.each do |list|
    name = list.name.downcase.to_sym
    basecamp_bucket[name] = {} if basecamp_bucket[name].nil?
    on_basecamp[name] = [] if on_basecamp[name].nil?
    list.todo_items.each do |item|
    begin
    if item.responsible_party_id == conf['current_user']
    on_basecamp[name] << item.content
    basecamp_bucket[name][item.content] = item
    end
    rescue
    # I know, I know...
    end
    end
    end

    things = Appscript.app('Things')
    bucket_names.each do |name,key|
    things.lists[key].to_dos.get.each do |to_do|
    idx = on_basecamp[name].index(to_do.name.get) unless on_basecamp[name].nil? # not sure why, but this is sometimes nil
    if !idx.nil?
    puts "attempting to sync [#{to_do.name.get}]"

    # check to see if its been completed on Basecamp
    if basecamp_bucket[name][to_do.name.get].completed
    puts " - marking local as completed"
    to_do.status.set(:completed)
    else if to_do.status.get == :completed
    puts " - marking remote as completed"
    basecamp_bucket[name][to_do.name.get].complete!
    end end

    on_basecamp[name].delete(to_do.name.get)
    end
    end
    end

    # now start adding from basecamp to things
    on_basecamp.each do |bucket_name, entries|
    entries.each do |entry|
    puts "adding new entry [#{entry}]"
    things.lists[bucket_names[bucket_name]].make(
    :new => :to_do,
    :with_properties => {
    :name => entry
    }
    )
    end
    end

    5 changes: 5 additions & 0 deletions ~/.sync_things.yaml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    ---
    url: yoursubdomain.basecamphq.com
    username: your_username
    password: your_password
    current_user: your_current_user_id (pull it out of your edit URL)