|
|
#!/usr/bin/env ruby
MY_TASKO_ID = 1 # Your Tasko ID
MY_TASKO_KEY = 'AAAA' # Your Tasko key
MY_TASKS_DIR = ENV['HOME'] + '/Tasks'
MY_TASKO_SUMMARY_FILE = ENV['HOME'] + '/.tasko.yml'
require 'yaml'
require 'digest/md5'
require 'xmlrpc/client'
class String
def md5
Digest::MD5::hexdigest(self)
end
end
module XMLRPC::ParseContentType
def parse_content_type(str)
["text/xml", "utf-8"]
end
end
class TaskoAPI
XMLRPC::Config.module_eval { remove_const(:ENABLE_NIL_PARSER) }
XMLRPC::Config.const_set(:ENABLE_NIL_PARSER, true)
URL = "http://taskodone.com/api"
def initialize(id, pass)
@id, @pass = id, pass
end
def newpaper(*args)
client.call('new', @id, @pass, *args)
end
def method_missing(method, *args)
client.call(method, @id, @pass, *args)
end
private
def client
XMLRPC::Client.new2(URL)
end
end
class TaskoSyncer
EXT = '.taskpaper'
def initialize(id, pass, dir, summary_file)
@tasko = TaskoAPI.new(id, pass)
@dir = dir
@summary_file = summary_file
@summary = YAML::load(File.read(@summary_file)) rescue {}
end
def sync
begin
papers = @tasko.papers
local_files.each do |file|
papers = update_file_contents(file, papers)
end
papers.each do |paper|
update_missing_paper paper
end
save_summary
rescue SocketError
puts "No internet connection"
end
end
private
def write_task_file(paper, data)
File.open(File.join(@dir, paper + '.taskpaper'), 'w') do |f|
f.write data
end
update_summary(paper, data)
end
def update_summary(paper, data)
@summary[paper] = data.md5
end
def save_summary
File.open(@summary_file, 'w') do |f|
f.write @summary.to_yaml
end
end
def local_files
Dir[File.join(@dir, "*#{EXT}")]
end
def summary_match?(paper, data)
!@summary[paper].nil? and @summary[paper] == data.md5
end
def update_file_contents(file, papers)
paper = File.basename(file, EXT)
data = File.read(file)
if summary_match?(paper, data)
remote_data = @tasko.paper(paper)
if data != remote_data
puts "Pulling #{paper}"
write_task_file(paper, remote_data)
end
papers.delete(paper)
else
puts "Pushing #{paper}"
if papers.delete(paper)
@tasko.edit(paper, data)
else
@tasko.newpaper(paper, data)
end
update_summary(paper, data)
end
papers
end
def update_missing_paper(paper)
if @summary[paper].nil?
puts "Adding #{paper}"
data = @tasko.paper(paper)
write_task_file(paper, data)
else
puts "Deleting #{paper}"
@tasko.delete(paper)
@summary.delete(paper)
end
end
end
if __FILE__ == $0
TaskoSyncer.new(MY_TASKO_ID, MY_TASKO_KEY, MY_TASKS_DIR, MY_TASKO_SUMMARY_FILE).sync
end
|