1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
MY_TASKO_ID = 1
MY_TASKO_KEY = 'AAAA'
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
|