rtmilk 0.0.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG.txt CHANGED
@@ -1,5 +1,28 @@
1
+ 2007-03-17 mootoh@gmail.com
2
+
3
+ * 0.3.0
4
+ based on rev36.
5
+ RTM::Note added.
6
+ That is used by taskMap.
7
+
8
+ 2007-03-16 mootoh@gmail.com
9
+
10
+ * 0.2.0
11
+ RTM::Task is now creatable/deletable in easy way.
12
+
13
+ 2007-03-10 mootoh@gmail.com
14
+
15
+ * CHANGELOG.txt:
16
+ all tests passed.
17
+
18
+ 2007-03-08 mootoh@gmail.com
19
+
20
+ * CHANGELOG.txt:
21
+ architecture totally rewrited.
22
+ add tasks.notes stuff.
23
+
1
24
  2007-02-05 mootoh@gmail.com
2
25
 
3
26
  * CHANGELOG.txt:
4
- packed gem.
27
+ packed gem.
5
28
 
data/History.txt ADDED
File without changes
data/Manifest.txt CHANGED
@@ -1,11 +1,25 @@
1
- Rakefile
2
1
  README.txt
2
+ Rakefile
3
3
  CHANGELOG.txt
4
4
  Manifest.txt
5
+ History.txt
5
6
  setup.rb
7
+ example/get.rb
8
+ lib/rtmilk/api/auth.rb
9
+ lib/rtmilk/api/lists.rb
10
+ lib/rtmilk/api/notes.rb
11
+ lib/rtmilk/api/tasks.rb
12
+ lib/rtmilk/api/timelines.rb
6
13
  lib/rtmilk/api.rb
14
+ lib/rtmilk/error.rb
7
15
  lib/rtmilk/version.rb
8
16
  lib/rtmilk.rb
17
+ test/auth_api_test.rb
18
+ test/error_test.rb
19
+ test/lists_api_test.rb
20
+ test/make_config.rb
21
+ test/notes_api_test.rb
22
+ test/Rakefile
23
+ test/tasks_api_test.rb
9
24
  test/test_helper.rb
10
- test/rtm_test.rb
11
- test/rtm_api_test.rb
25
+ test/timelines_api_test.rb
data/README.txt CHANGED
@@ -1,4 +1,3 @@
1
- README for rtmilk
2
- =================
1
+ = README for rtmilk
3
2
 
4
- rtmilk is a "Remember the Milk" wrapper library.
3
+ rtmilk is a {Remember the Milk}[http://www.rememberthemilk.com/] wrapper library.
data/Rakefile CHANGED
@@ -30,6 +30,7 @@ RDOC_OPTS = ['--quiet', '--title', "rtmilk documentation",
30
30
  "--opname", "index.html",
31
31
  "--line-numbers",
32
32
  "--main", "README.txt",
33
+ "-diagram",
33
34
  "--inline-source"]
34
35
 
35
36
  class Hoe
data/example/get.rb ADDED
@@ -0,0 +1,43 @@
1
+ #
2
+ # simple example for rtm.rb
3
+ $LOAD_PATH << File.dirname(__FILE__) + '/../lib'
4
+ require 'rtmilk'
5
+
6
+ # -------------------------------------------------------------------
7
+ # API_KEY and SHARED_SECRET are required.
8
+ #
9
+ API_KEY = 'aaa'
10
+ SHARED_SECRET = 'bbb'
11
+
12
+ RTM::API.init(API_KEY, SHARED_SECRET)
13
+
14
+ # -------------------------------------------------------------------
15
+ # get auth url for read
16
+ #
17
+ frob = RTM::Auth::GetFrob.new.invoke
18
+ url = RTM::API.get_auth_url('read', frob)
19
+
20
+ puts 'access, login, and authenticate following uri on your browser,'
21
+ puts 'then hit return to continue'
22
+ puts ' ' + url
23
+
24
+ gets
25
+
26
+
27
+ res = RTM::Auth::GetToken.new(frob).invoke
28
+ token = res[:token]
29
+ RTM::API.token = token
30
+
31
+ # -------------------------------------------------------------------
32
+ # get all lists
33
+ #
34
+ #
35
+ lists = RTM::List.alive_all
36
+ lists.each { |l| puts l['name'] }
37
+
38
+ # -------------------------------------------------------------------
39
+ # get all tasks
40
+ #
41
+ #tasks = RTM::Tasks.new
42
+ #tasks.each { |t| puts t.name }
43
+
data/lib/rtmilk.rb CHANGED
@@ -5,191 +5,14 @@
5
5
  # $Id: rtm.rb 10 2006-12-30 06:37:24Z takayama $
6
6
  #
7
7
 
8
- require 'rtmilk/api.rb'
8
+ require 'rtmilk/error'
9
+ require 'rtmilk/api'
9
10
 
10
11
  =begin rdoc
11
12
  access Remember the Milk REST APIs.
12
13
  =end
13
14
  module RTM
14
15
 
15
- def RTM.get_timeline
16
- API::TimeLines.create
17
- end
18
-
19
- # use frob for Desktop Application.
20
- # perm should be one of ['read', 'write', 'delete'].
21
- def RTM.get_auth_url(h)
22
- raise unless API::PERMS.include?(h[:perm])
23
-
24
- API.auth_uri(API.params, h)
25
- end
26
-
27
- def RTM.get_frob
28
- API::Auth.getFrob
29
- end
30
-
31
-
32
- class Contact
33
- attr_accessor :id, :fullname, :username
34
-
35
- def initialize(id, full=nil, user=nil)
36
- @id = id
37
- @fullname = full
38
- @user = user
39
- end
40
- end # Contact
41
-
42
- class Group
43
- attr_accessor :id, :name
44
- end # Group
45
-
46
- class List
47
- attr_accessor :id, :name, :deleted, :locked, :archived, :position, :smart, :filter
48
-
49
- def initialize(h)
50
- @id = h['id']
51
- @name = h['name']
52
- @deleted = h['deleted'] == '0'
53
- @locked = h['locked'] == '1'
54
- @archived = h['archived'] == '1'
55
- @position = h['position']
56
- @smart = h['smart'] == '1'
57
- @filter = h['filter']
58
- end
59
-
60
- def setDefault
61
- end # setDefault
62
-
63
- def setName(name)
64
- end # setName
65
-
66
- def archive
67
- end # archive
68
-
69
- def unarchive
70
- end # unarchive
71
-
72
- def <=>(other)
73
- @name <=> other.name
74
- end
75
- end # List
76
-
77
- class Lists
78
- include Enumerable
79
-
80
- attr_accessor :ls
81
-
82
- def initialize
83
- @ls = API::Lists.getList.collect do |x|
84
- List.new x
85
- end
86
- end
87
-
88
- def each
89
- @ls.each do |x|
90
- yield x
91
- end
92
- end
93
-
94
- def Lists.add(name, filter=nil)
95
- timeline = RTM.get_timeline
96
- l = API::Lists.add(timeline, name, filter)
97
- List.new l
98
- end # add
99
-
100
- def [](i)
101
- to_a[i]
102
- end
103
-
104
- def size
105
- to_a.size
106
- end
107
- end # Lists
108
-
109
- class TaskSeries
110
- attr_accessor :id, :created, :modified, :name, :source,
111
- :tags, :participants, :notes, :task
112
-
113
- def initialize(h)
114
- @id = h['id'] if h['id']
115
- @created = h['created'] if h['created']
116
- @modified = h['modified'] if h['modified']
117
- @name = h['name'] if h['name']
118
- @source = h['source'] if h['source']
119
- @tags = h['tags'].first['tag'] if h['tags']
120
- @participants = h['participants'].first if h['participants']
121
- @notes = h['notes'].first if h['notes']
122
-
123
- if h['task']
124
- @task = h['task'].collect do |t|
125
- Task.new(t)
126
- end.flatten.compact
127
- end
128
- end
129
-
130
- class Task
131
- attr_accessor :id, :due, :has_due_time, :added, :completed,
132
- :deleted, :priority, :postponed, :estimate
133
-
134
- def initialize(h)
135
- @id = h['id'] if h['id']
136
- @due = h['due'] if h['due']
137
- @has_due_time = h['has_due_time'] == '1' if h['has_due_time']
138
- @added = h['added'] if h['added']
139
- @completed = h['completed'] if h['completed']
140
- @deleted = h['deleted'] if h['deleted']
141
- @priority = h['priority'] if h['priority']
142
- @postponed = h['postponed'] if h['postponed']
143
- @estimate = h['estimate'] if h['estimate']
144
- end
145
- end # Task
146
- end
147
-
148
- class Tasks
149
- include Enumerable
150
-
151
- attr_accessor :ts
152
-
153
- def initialize(list=nil, last=nil)
154
- @ts = API::Tasks.getList(list, last).collect do |x|
155
- if x['taskseries']
156
- x['taskseries'].collect do |t|
157
- TaskSeries.new t
158
- end
159
- else
160
- nil
161
- end
162
- end.flatten.compact
163
- end
164
-
165
- def each
166
- @ts.each do |x|
167
- yield x
168
- end
169
- end
170
-
171
- def Tasks.add(name, list)
172
- timeline = RTM.get_timeline
173
- t = API::Tasks.add(timeline, list, name)
174
- TaskSeries.new t
175
- end
176
-
177
- def Tasks.delete(series, task, list)
178
- timeline = RTM.get_timeline
179
- t = API::Tasks.delete(timeline, list, series, task)
180
- TaskSeries.new t
181
- end
182
-
183
- def [](i)
184
- to_a[i]
185
- end
186
-
187
- def size
188
- to_a.size
189
- end
190
-
191
- end # Tasks
192
-
193
16
  end # RTM
194
17
 
195
18
  # vim:fdm=indent
data/lib/rtmilk/api.rb CHANGED
@@ -2,8 +2,6 @@
2
2
  # for Remember the Milk REST API
3
3
  # http://www.rememberthemilk.com/services/api/overview.rtm
4
4
  #
5
- # $Id: api.rb 11 2007-01-08 04:02:44Z takayama $
6
- #
7
5
 
8
6
  require 'net/http'
9
7
  require 'digest/md5'
@@ -14,373 +12,110 @@ require 'uri'
14
12
  # access the {Remember the Milk}[http://www.rememberthemilk.com/] REST APIs.
15
13
  module RTM
16
14
 
17
- # API classes.
15
+ # API class
18
16
  class API
17
+
18
+ private
19
19
  RTM_URI = 'www.rememberthemilk.com'
20
20
  REST_PATH = '/services/rest/'
21
21
  AUTH_PATH = '/services/auth/'
22
-
23
22
  PERMS = ['read', 'write', 'delete']
24
23
 
25
- #--
26
- # -----------------------------------------------------------------
27
- # class methods
28
- #++
29
-
30
- def API.key ; @@key ; end
31
- def API.params ; @@params ; end
32
- def API.token ; @@token ; end
33
-
24
+ public
34
25
  # initialize the API context.
35
- # make sure to call this before using any API calls.
36
- def API.init(h)
37
- @@key = h[:key] if h.has_key? :key
38
- @@sec = h[:secret] if h.has_key? :secret
39
- @@frob = h[:frob] if h.has_key? :frob
40
- @@token = h[:token] if h.has_key? :token
26
+ def API.init(key, sec, option=nil)
27
+ @@key = key
28
+ @@sec = sec
29
+
30
+ if (option)
31
+ begin
32
+ @@token = option[:token] if option.has_key? :token
33
+ rescue => e
34
+ puts e.message
35
+ end
36
+ end
41
37
 
42
- @@params = { 'api_key' => @@key }
43
- @@http = Net::HTTP.new(RTM_URI)
44
38
  end
45
39
 
46
- # tailor parameters into request uri.
47
- def API.uri_req(params)
48
- r = REST_PATH + '?'
49
- r += params.collect { |k, v| [k, v].join('=') }.sort.join('&')
50
- r += '&api_sig=' + sign(params)
51
- URI.escape r
40
+ def API.token=(token)
41
+ @@token = token
52
42
  end
53
43
 
54
- # tailor parameters into auth uri.
55
- def API.uri_auth(params, h)
56
- p = params.dup
57
- p[:perms] = h[:perm]
58
- p[:frob] = h[:frob] if h[:frob]
59
- p[:callback] = h[:callback] if h[:callback]
44
+ # getter methods
45
+ def API.key; @@key; end
46
+ def API.token; @@token; end
47
+
48
+ # invoke a method
49
+ def invoke
50
+ response = Net::HTTP.get(RTM_URI, make_url)
51
+ # puts '--------------------------------------------------'
52
+ # puts response
53
+ # puts '--------------------------------------------------'
54
+ result = XmlSimple.new.xml_in(response)
55
+ ret = parse_result(result)
56
+ end
60
57
 
61
- r = AUTH_PATH + '?'
62
- r += p.collect { |k, v| [k, v].join('=') }.sort.join('&')
58
+ # get Auth URL (both desktop/webapp)
59
+ def API.get_auth_url(perms, frob=nil)
60
+ param = { :api_key => @@key, :perms => perms }
61
+ if frob
62
+ param['frob'] = frob
63
+ end
63
64
 
64
- r += '&api_sig=' + sign(p)
65
- r
66
- end
65
+ sig = API.sign(param)
67
66
 
68
- # construct auth uri from params.
69
- def API.auth_uri(params, h)
70
- RTM_URI + uri_auth(params, h)
67
+ r = 'http://' + RTM_URI + AUTH_PATH + '?'
68
+ r += param.collect { |k, v| [k, v].join('=') }.sort.join('&')
69
+ r += '&api_sig=' + sig
70
+ r
71
71
  end
72
72
 
73
- # process http request, return response.
74
- def API.request(uri)
75
- head, body = @@http.get(uri)
76
- res = XmlSimple.new.xml_in(body)
77
- raise Error, res if 'fail' == res['stat']
78
- res
73
+ def sign
74
+ API.sign(@param)
79
75
  end
80
76
 
81
- private
82
-
83
- # sign parameters.
84
- def API.sign(params)
77
+ private
78
+ # sign parameters
79
+ def API.sign(param)
85
80
  sig = @@sec
86
- sig += params.collect { |k, v| [k, v].join('') }.sort.join('')
87
- sig = Digest::MD5.hexdigest(sig)
81
+ sig += param.collect { |k, v| [k, v].join('') }.sort.join('')
82
+ Digest::MD5.hexdigest(sig)
88
83
  end
89
- end # API
90
84
 
91
- #--
92
- # ---------------------------------------------------------------
93
- # subclasses
94
- #++
95
-
96
- class API
97
- # Exception class, takes msg and code.
98
- class Error < StandardError
99
- def initialize(h)
100
- err = h['err'].first
101
- @code = err['code'].to_i
102
- msg = err['msg'] + ' (error code=' + err['code'] + ')'
103
- super(msg)
104
- end
85
+ def initialize(method, token=nil, timeline=nil)
86
+ @method = method
87
+ @token = token ? token : nil
88
+ @timeline = timeline ? timeline : nil
89
+ @param = {}
105
90
  end
106
91
 
107
- # rtm.auth API.
108
- class Auth
109
- METHOD = 'rtm.auth'
110
-
111
- # see spec[http://www.rememberthemilk.com/services/api/methods/rtm.auth.checkToken.rtm].
112
- def Auth.checkToken(token)
113
- p = API.params.dup
114
- p['method'] = METHOD + '.checkToken'
115
- p['auth_token'] = token
116
- res = API.request(API.uri_req(p))
117
- end
118
-
119
- # see spec[http://www.rememberthemilk.com/services/api/methods/rtm.auth.getFrob.rtm].
120
- def Auth.getFrob
121
- p = API.params.dup
122
- p['method'] = METHOD + '.getFrob'
123
-
124
- res = API.request(API.uri_req(p))
125
- res['frob'].first
126
- end
127
-
128
- # see {spec}[http://www.rememberthemilk.com/services/api/methods/rtm.auth.getToken.rtm].
129
- def Auth.getToken(frob)
130
- p = API.params.dup
131
- p['method'] = METHOD + '.getToken'
132
- p['frob'] = frob
133
-
134
- res = API.request(API.uri_req(p))
135
- res['auth'].first['token'].first
136
- end
137
- end # Auth
138
-
139
- class Contacts
140
- def Contacts.add
141
- end
142
-
143
- def Contacts.delete
144
- end
145
-
146
- def Contacts.getList
147
- end
148
- end # Contacts
149
-
150
- class Groups
151
- def Groups.add
152
- end
153
-
154
- def Groups.addContact
155
- end
156
-
157
- def Groups.delete
158
- end
159
-
160
- def Groups.getList
161
- end
162
-
163
- def Groups.removeContact
164
- end
165
- end # Groups
166
-
167
- class Lists
168
- METHOD = 'rtm.lists'
169
-
170
- def Lists.add(timeline, name, filter=nil)
171
- p = API.params.dup
172
- p['method'] = METHOD + '.add'
173
- p['auth_token'] = API.token
174
- p['timeline'] = timeline
175
- p['name'] = name
176
- p['filter'] = filter if filter
177
-
178
- res = API.request(API.uri_req(p))
179
- end
180
-
181
- def Lists.archive
182
- end
183
-
184
- def Lists.getList(alive_only=true)
185
- p = API.params.dup
186
- p['method'] = METHOD + '.getList'
187
- p['auth_token'] = API.token
188
-
189
- res = API.request(API.uri_req(p))
190
- lists = res['lists'].first['list']
191
-
192
- if alive_only
193
- lists.collect { |l| l if l['deleted'] == '0' }.compact
194
- else
195
- lists
196
- end
197
- end
198
-
199
- def Lists.setDefaultList
200
- end
201
-
202
- def Lists.setName
203
- end
204
-
205
- def Lists.unarchive
206
- end
207
- end # Lists
208
-
209
- class Reflection
210
- def Reflection.getMethodInfo
211
- end
212
-
213
- def Reflection.getMethods
214
- end
215
- end # Reflection
216
-
217
- class Settings
218
- def Settings.getList
219
- end
220
- end # Settings
221
-
222
- class Tasks
223
- METHOD = 'rtm.tasks'
224
-
225
- def Tasks.add(timeline, list, name)
226
- p = API.params.dup
227
- p['method'] = METHOD + '.add'
228
- p['auth_token'] = API.token
229
- p['timeline'] = timeline
230
- p['name'] = name
231
- p['list_id'] = list
232
-
233
- res = API.request(API.uri_req(p))
234
- res['list'].first['taskseries'].first
235
- end
236
-
237
- def Tasks.addTags
238
- end
239
-
240
- def Tasks.complete
241
- end
242
-
243
- def Tasks.delete(timeline, list, series, task)
244
- p = API.params.dup
245
- p['method'] = METHOD + '.delete'
246
- p['auth_token'] = API.token
247
- p['timeline'] = timeline
248
- p['list_id'] = list
249
- p['taskseries_id'] = series
250
- p['task_id'] = task
251
-
252
- res = API.request(API.uri_req(p))
253
- res['list'].first['taskseries'].first
254
- end
255
-
256
- def Tasks.getList(list=nil, last_sync=nil)
257
- p = API.params.dup
258
-
259
- p['method'] = METHOD + '.getList'
260
- p['auth_token'] = API.token
261
- p['list_id'] = list if list
262
- p['last_sync'] = last_sync if last_sync
263
-
264
- res = API.request(API.uri_req(p))
265
- res['tasks'].first['list']
266
- end
267
-
268
- def Tasks.moveProiority
269
- end
270
-
271
- def Tasks.moveTo
272
- end
273
-
274
- def Tasks.postpone
275
- end
276
-
277
- def Tasks.removeTags
278
- end
279
-
280
- def Tasks.setDueDate
281
- end
282
-
283
- def Tasks.setEstimate
284
- end
285
-
286
- def Tasks.setName
287
- end
288
-
289
- def Tasks.setPriority
290
- end
291
-
292
- def Tasks.setRecurrence
293
- end
294
-
295
- def Tasks.setTags
296
- end
297
-
298
- def Tasks.setURL
299
- end
300
-
301
- def Tasks.uncomplete
302
- end
303
-
304
- class Notes # TODO
305
- def Notes.add # TODO
306
- end
307
-
308
- def Notes.delete # TODO
309
- end
310
-
311
- def Notes.edit # TODO
312
- end
313
- end # Notes
314
- end # Tasks
315
-
316
- class Test # TODO
317
- METHOD = 'rtm.test'
318
-
319
- def Test.echo # TODO
320
- req = REST_PATH + '?method=' + METHOD + '.echo' + '&api_key=' + @k
321
- puts req
322
-
323
- r, b = @http.get(req)
324
- puts r
325
- puts b
326
- end
327
-
328
- def Test.login # TODO
329
- params = {
330
- 'method' => METHOD + '.login',
331
- 'api_key' => @k
332
- }
333
-
334
- sig = @s
335
- sig += params.collect { |k, v| [k, v].join('') }.sort.join('')
336
- puts "sig = " + sig
337
- sig = Digest::MD5.hexdigest(sig)
338
- puts "hexed sig = " + sig
339
-
340
- req = REST_PATH + '?'
341
- req += params.collect { |k, v| [k, v].join('=') }.sort.join('&')
342
- req += "&api_sig=" + sig
343
-
344
- puts "\n"
345
- puts "req = " + req
346
-
347
- r, b = @http.get(req)
348
- puts r
349
- puts b
350
- end
351
- end # Test
352
-
353
- class Time # TODO
354
- def Time.convert # TODO
355
- end
356
-
357
- def Time.parse # TODO
358
- end
359
- end # Time
360
-
361
- class TimeLines
362
- METHOD = 'rtm.timelines'
363
-
364
- def TimeLines.create
365
- p = API.params.dup
366
- p['method'] = METHOD + '.create'
367
- p['auth_token'] = API.token
368
-
369
- res = API.request(API.uri_req(p))
370
- t = res['timeline'].first
371
- end
372
- end # TimeLines
92
+ def make_url
93
+ r = REST_PATH + '?'
373
94
 
374
- class TimeZones # TODO
375
- def TimeZones.getList
376
- end
377
- end # TimeZones
95
+ @param = {} if @param == nil
96
+ @param['method'] = @method
97
+ @param['auth_token'] = @token unless @token == nil
98
+ @param['timeline'] = @timeline unless @timeline == nil
99
+ @param['api_key'] = @@key
100
+ r += @param.collect { |k, v| [k, v].join('=') }.sort.join('&')
101
+ r += '&api_sig=' + sign
102
+ URI.escape r
103
+ end
378
104
 
379
- class Transactions
380
- def Transactions.undo
105
+ protected
106
+ # parse result
107
+ def parse_result(result)
108
+ unless result['stat'] == 'ok'
109
+ raise RTM::Error, result['err'].first['msg']
381
110
  end
382
- end # Transactions
111
+ end
383
112
  end # API
384
113
 
385
114
  end # RTM
115
+ require 'rtmilk/api/auth'
116
+ require 'rtmilk/api/timelines'
117
+ require 'rtmilk/api/lists'
118
+ require 'rtmilk/api/tasks'
119
+ require 'rtmilk/api/notes'
120
+
386
121
  # vim:fdm=indent