rtmilk 0.0.1 → 0.0.2

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/Manifest.txt CHANGED
@@ -3,7 +3,9 @@ README.txt
3
3
  CHANGELOG.txt
4
4
  Manifest.txt
5
5
  setup.rb
6
+ lib/rtmilk/api.rb
6
7
  lib/rtmilk/version.rb
7
8
  lib/rtmilk.rb
8
9
  test/test_helper.rb
9
- test/rtmilk_test.rb
10
+ test/rtm_test.rb
11
+ test/rtm_api_test.rb
data/Rakefile CHANGED
@@ -24,9 +24,12 @@ REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+
24
24
  VERS = ENV['VERSION'] || (Rtmilk::VERSION::STRING + (REV ? ".#{REV}" : ""))
25
25
  CLEAN.include ['**/.*.sw?', '*.gem', '.config']
26
26
  RDOC_OPTS = ['--quiet', '--title', "rtmilk documentation",
27
+ "--exclude", "test",
28
+ "--exclude", "pkg",
29
+ "--exclude", "setup.rb",
27
30
  "--opname", "index.html",
28
31
  "--line-numbers",
29
- "--main", "README",
32
+ "--main", "README.txt",
30
33
  "--inline-source"]
31
34
 
32
35
  class Hoe
@@ -52,3 +55,21 @@ hoe = Hoe.new(GEM_NAME, VERS) do |p|
52
55
  #p.extra_deps - An array of rubygem dependencies.
53
56
  #p.spec_extras - A hash of extra values to set in the gemspec.
54
57
  end
58
+
59
+ Rake::RDocTask.new do |rdoc|
60
+ rdoc.rdoc_dir = 'html'
61
+ rdoc.options += RDOC_OPTS
62
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
63
+ if ENV['DOC_FILES']
64
+ rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
65
+ else
66
+ rdoc.rdoc_files.include('README.txt', 'CHANGELOG.txt')
67
+ rdoc.rdoc_files.include('lib/**/*.rb')
68
+ end
69
+ end
70
+
71
+ desc "Publish to RubyForge"
72
+ task :rubyforge => [:rdoc, :package] do
73
+ Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'takayama').upload
74
+ end
75
+
data/lib/rtmilk/api.rb ADDED
@@ -0,0 +1,386 @@
1
+ #
2
+ # for Remember the Milk REST API
3
+ # http://www.rememberthemilk.com/services/api/overview.rtm
4
+ #
5
+ # $Id: api.rb 11 2007-01-08 04:02:44Z takayama $
6
+ #
7
+
8
+ require 'net/http'
9
+ require 'digest/md5'
10
+ require 'rubygems'
11
+ require 'xmlsimple'
12
+ require 'uri'
13
+
14
+ # access the {Remember the Milk}[http://www.rememberthemilk.com/] REST APIs.
15
+ module RTM
16
+
17
+ # API classes.
18
+ class API
19
+ RTM_URI = 'www.rememberthemilk.com'
20
+ REST_PATH = '/services/rest/'
21
+ AUTH_PATH = '/services/auth/'
22
+
23
+ PERMS = ['read', 'write', 'delete']
24
+
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
+
34
+ # 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
41
+
42
+ @@params = { 'api_key' => @@key }
43
+ @@http = Net::HTTP.new(RTM_URI)
44
+ end
45
+
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
52
+ end
53
+
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]
60
+
61
+ r = AUTH_PATH + '?'
62
+ r += p.collect { |k, v| [k, v].join('=') }.sort.join('&')
63
+
64
+ r += '&api_sig=' + sign(p)
65
+ r
66
+ end
67
+
68
+ # construct auth uri from params.
69
+ def API.auth_uri(params, h)
70
+ RTM_URI + uri_auth(params, h)
71
+ end
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
79
+ end
80
+
81
+ private
82
+
83
+ # sign parameters.
84
+ def API.sign(params)
85
+ sig = @@sec
86
+ sig += params.collect { |k, v| [k, v].join('') }.sort.join('')
87
+ sig = Digest::MD5.hexdigest(sig)
88
+ end
89
+ end # API
90
+
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
105
+ end
106
+
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
373
+
374
+ class TimeZones # TODO
375
+ def TimeZones.getList
376
+ end
377
+ end # TimeZones
378
+
379
+ class Transactions
380
+ def Transactions.undo
381
+ end
382
+ end # Transactions
383
+ end # API
384
+
385
+ end # RTM
386
+ # vim:fdm=indent
@@ -2,7 +2,7 @@ module Rtmilk #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
- TINY = 1
5
+ TINY = 2
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -0,0 +1,164 @@
1
+ #
2
+ # tests for rtm.rb
3
+ #
4
+ # see http://d.hatena.ne.jp/secondlife/20060927/1159334813
5
+ #
6
+ # $Id: test_rtm_api.rb 10 2006-12-30 06:37:24Z takayama $
7
+ #
8
+
9
+ require File.dirname(__FILE__) + '/test_helper.rb'
10
+
11
+ class RTMAPITest < Test::Unit::TestCase
12
+ CONFIG = File.dirname(__FILE__) + '/../config.dat' # config data file
13
+
14
+ KEY = 'aaa' # XXX specify API key
15
+ SEC = 'bbb' # XXX specify shared secret
16
+ FROB = 'ccc' # XXX enter some frob
17
+ TOKEN = 'ddd' # XXX enter some token
18
+
19
+ def setup
20
+ conf = begin
21
+ Marshal.load(open(CONFIG))
22
+ rescue
23
+ {
24
+ :key => KEY,
25
+ :secret => SEC,
26
+ :frob => FROB,
27
+ :token => TOKEN }
28
+ end
29
+
30
+ RTM::API.init(conf)
31
+ # @base = RTM::API.new(KEY, SIG)
32
+ # @test = RTM::TestAPI.new(KEY, SIG)
33
+ # @auth = RTM::AuthAPI.new(KEY, SIG)
34
+ # @lists = RTM::ListsAPI.new(KEY, SIG)
35
+ # @tasks = RTM::TasksAPI.new(KEY, SIG)
36
+ end
37
+
38
+ def test_init
39
+ assert_equal(1, RTM::API.params.size)
40
+ end
41
+
42
+ def test_instance
43
+ # assert_instance_of RTM::API, @base
44
+ # assert_instance_of RTM::TestAPI, @test
45
+ # assert_instance_of RTM::AuthAPI, @auth
46
+ # assert_instance_of RTM::ListsAPI, @lists
47
+ # assert_instance_of RTM::TasksAPI, @tasks
48
+ end
49
+
50
+ # -------------------------------------------------------------------
51
+ # API
52
+ #
53
+ def test_sign
54
+ sign = RTM::API.sign(RTM::API.params)
55
+ assert_equal(32, sign.length)
56
+ end
57
+
58
+ def test_uri_req
59
+ assert_equal(1, RTM::API.params.keys.size)
60
+ ur = RTM::API.uri_req(RTM::API.params)
61
+ assert_not_nil(ur)
62
+ assert_equal(1, RTM::API.params.keys.size)
63
+ end
64
+
65
+ def test_uri_auth
66
+ assert_equal(1, RTM::API.params.keys.size)
67
+ ra = RTM::API.uri_auth(RTM::API.params, 'read')
68
+ assert_not_nil(ra)
69
+ assert_equal(1, RTM::API.params.keys.size)
70
+ end
71
+
72
+ def test_auth_uri
73
+ au = RTM::API.auth_uri(RTM::API.params, 'read')
74
+ assert_not_nil(au)
75
+ end
76
+
77
+ def test_uri_auth_frob
78
+ frob = RTM::API::Auth.getFrob
79
+ assert_not_nil(frob)
80
+ assert_equal(40, frob.length)
81
+
82
+ RTM::API::PERMS.each do |p|
83
+ ra = RTM::API.uri_auth(RTM::API.params, {'perm'=>p, 'frob'=>frob})
84
+ assert_not_nil(ra)
85
+ assert_equal(1, RTM::API::params.keys.size)
86
+ end
87
+ end
88
+
89
+ # -------------------------------------------------------------------
90
+ # Auth
91
+ #
92
+ def test_authGetFrob
93
+ frob = RTM::API::Auth.getFrob
94
+ assert_not_nil(frob)
95
+ assert_equal(40, frob.length)
96
+ end
97
+
98
+ =begin
99
+ def test_authGetToken
100
+ frob = @auth.getFrob
101
+ assert_not_nil(frob)
102
+ assert_equal(40, frob.length)
103
+
104
+ ra = @base.uri_auth('read', frob)
105
+ assert_not_nil(ra)
106
+
107
+ puts 'auth this url : ' + 'http://' + RTM::RTM_URI + ra
108
+ # @base.auth(ra)
109
+ gets
110
+
111
+ token = @auth.getToken(frob)
112
+ assert_not_nil(token)
113
+ p token
114
+ assert_equal(40, token.length)
115
+ end
116
+ =end
117
+
118
+ def test_authCheckToken
119
+ assert_raise(RTM::API::Error) {
120
+ RTM::API::Auth.checkToken(TOKEN + 'a')
121
+ }
122
+ assert_nothing_raised {
123
+ checked = RTM::API::Auth.checkToken(RTM::API.token)
124
+ assert_not_nil(checked)
125
+ }
126
+ end
127
+
128
+ def test_taskGetList
129
+ tasks = RTM::API::Tasks.getList
130
+ assert_not_nil(tasks)
131
+ end
132
+
133
+
134
+ =begin
135
+ def test_testEcho
136
+ @test.echo
137
+ end
138
+
139
+ def test_testLogin
140
+ @test.login
141
+ end
142
+
143
+ def test_getList
144
+ @lists.get
145
+ end
146
+ =end
147
+
148
+ # -------------------------------------------------------------------
149
+ # API test
150
+ #
151
+ def test_api_init
152
+ RTM::API.init(:key => KEY)
153
+
154
+ assert_equal(KEY, RTM::API.key)
155
+ end
156
+
157
+ # -------------------------------------------------------------------
158
+ # TimeLines API test
159
+ #
160
+ def test_timelines_create
161
+ timeline = RTM::API::TimeLines.create
162
+ assert_not_nil(timeline)
163
+ end
164
+ end
data/test/rtm_test.rb ADDED
@@ -0,0 +1,80 @@
1
+ #
2
+ # tests for rtm.rb
3
+ #
4
+ # see http://d.hatena.ne.jp/secondlife/20060927/1159334813
5
+ #
6
+ # $Id: test_rtm.rb 10 2006-12-30 06:37:24Z takayama $
7
+ #
8
+
9
+ require File.dirname(__FILE__) + '/test_helper.rb'
10
+
11
+ class RTMTest < Test::Unit::TestCase
12
+ CONFIG = File.dirname(__FILE__) + '/../config.dat' # config data file
13
+
14
+ KEY = 'aaa' # XXX specify API key
15
+ SEC = 'bbb' # XXX specify shared secret
16
+ FROB = 'ccc' # XXX enter some frob
17
+ TOKEN = 'ddd' # XXX enter some token
18
+
19
+ def setup
20
+ conf = begin
21
+ Marshal.load(open(CONFIG))
22
+ rescue
23
+ {
24
+ :key => KEY,
25
+ :secret => SEC,
26
+ :frob => FROB,
27
+ :token => TOKEN }
28
+ end
29
+
30
+ RTM::API.init(conf)
31
+ @contact = RTM::Contact.new(0)
32
+ @group = RTM::Group.new
33
+ @list = RTM::List.new(:id => 0)
34
+ @lists = RTM::Lists.new
35
+ end
36
+
37
+ def test_instance
38
+ assert_instance_of RTM::Contact, @contact
39
+ assert_instance_of RTM::Group, @group
40
+ assert_instance_of RTM::List, @list
41
+ assert_instance_of RTM::Lists, @lists
42
+ end
43
+
44
+ # -----------------------------------------------------------------
45
+ # Lists
46
+ #
47
+ def test_lists0
48
+ assert_not_nil(@list)
49
+ assert_not_nil(@lists)
50
+ end
51
+
52
+ def test_lists_add
53
+ l = RTM::Lists.add('rtmilk test')
54
+ assert_not_nil(l)
55
+ end
56
+
57
+ # -----------------------------------------------------------------
58
+ # Tasks
59
+ #
60
+ def test_tasks_add
61
+ t = RTM::Tasks.add('rtmilk test task to add', @lists[0].id)
62
+ assert_not_nil(t)
63
+ end
64
+
65
+ def test_tasks_delete
66
+ t = RTM::Tasks.add('rtmilk test task to delete', @lists[0].id)
67
+ assert_not_nil(t)
68
+
69
+ deleted = RTM::Tasks.delete(t.id, t.task.first.id, @lists[0].id)
70
+ assert_not_nil(deleted)
71
+ end
72
+
73
+ # -----------------------------------------------------------------
74
+ # TimeLine
75
+ #
76
+ def test_get_timeline
77
+ timeline = RTM.get_timeline
78
+ assert_not_nil(timeline)
79
+ end
80
+ end
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.1
3
3
  specification_version: 1
4
4
  name: rtmilk
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.1
6
+ version: 0.0.2
7
7
  date: 2007-02-05 00:00:00 +09:00
8
8
  summary: a "Remember the Milk" wrapper library.
9
9
  require_paths:
@@ -34,12 +34,15 @@ files:
34
34
  - CHANGELOG.txt
35
35
  - Manifest.txt
36
36
  - setup.rb
37
+ - lib/rtmilk/api.rb
37
38
  - lib/rtmilk/version.rb
38
39
  - lib/rtmilk.rb
39
40
  - test/test_helper.rb
40
- - test/rtmilk_test.rb
41
+ - test/rtm_test.rb
42
+ - test/rtm_api_test.rb
41
43
  test_files:
42
- - test/rtmilk_test.rb
44
+ - test/rtm_api_test.rb
45
+ - test/rtm_test.rb
43
46
  rdoc_options: []
44
47
 
45
48
  extra_rdoc_files: []
data/test/rtmilk_test.rb DELETED
@@ -1,11 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper.rb'
2
-
3
- class RtmilkTest < Test::Unit::TestCase
4
-
5
- def setup
6
- end
7
-
8
- def test_truth
9
- assert true
10
- end
11
- end