rtmilk 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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