maisonneuve-rtm 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt ADDED
@@ -0,0 +1,133 @@
1
+
2
+ = maisonneuve-rtm
3
+ Modified version of the rufus-rtm gem, removing the dependancy of rufus-verbs gem
4
+
5
+ == getting it
6
+
7
+ sudo gem install -y maisonneuve-rtm
8
+
9
+
10
+ == credentials
11
+
12
+ 'rufus-rtm' expects to find RTM credentials in the environment. It will look for :
13
+
14
+ * RTM_API_KEY
15
+ * RTM_SHARED_SECRET
16
+ * RTM_FROB
17
+ * RTM_AUTH_TOKEN
18
+
19
+ (Note since version 0.2, it's OK to not set these environment variables and to pass their values for each method with :api_key, :shared_secret, :frob and :auth_token optional parameters (see test_2 of test/tasks_test.rb))
20
+
21
+ You have to apply for the first two ones at http://www.rememberthemilk.com/services/api/keys.rtm
22
+
23
+ Once you have the API key and the shared secret, you have to get the frob and the auth token. Fire your 'irb' and
24
+
25
+ >> require 'rubygems'
26
+ >> require 'rufus/rtm'
27
+
28
+ please visit this URL with your browser and then hit 'enter' :
29
+
30
+ http://www.rememberthemilk.com/services/auth/?api_sig=70036e47c38da170fee431f04e29e8f0&frob=fa794036814b78fddf3e5641fe7c37f80e7d91fc&perms=delete&api_key=7f07e4fc5a944bf8c02a7d1e45c79346
31
+
32
+ visit, the given URL, you should finally be greeted by a message like "You have successfully authorized the application API Application. You may now close this window and continue the authentication process with the application that sent you here.", hit enter...
33
+
34
+ ok, now getting auth token...
35
+
36
+ here are your RTM_FROB and RTM_AUTH_TOKEN, make sure to place them
37
+ in your environment :
38
+
39
+ export RTM_FROB=3cef465718317b837eec2faeb5340fe777d55c7c
40
+ export RTM_AUTH_TOKEN=ca0022d705ea1831543b7cdd2d7e3d707a0e1efb
41
+
42
+ make then sure that all the 4 variables are set in the environment you use for running 'rufus-rtm'.
43
+
44
+
45
+ == usage
46
+
47
+ require 'rubygems'
48
+ require 'rufus/rtm'
49
+
50
+ include Rufus::RTM
51
+
52
+ #
53
+ # listing tasks
54
+
55
+ tasks = Task.find
56
+ # finding all the tasks
57
+
58
+ tasks = Task.find :filter => "status:incomplete"
59
+ # finding all the incomplete tasks
60
+
61
+ tasks.each do |task|
62
+
63
+ puts "task id #{task.task_id}"
64
+ puts " #{task.name} (#{task.tags.join(",")})"
65
+ puts
66
+ end
67
+
68
+ #
69
+ # adding a task
70
+
71
+ task = Task.add! "study this rufus-rtm gem"
72
+ # gets added to the 'Inbox' by default
73
+
74
+ puts "task id is #{task.task_id}"
75
+
76
+ #
77
+ # enumerating lists
78
+
79
+ lists = List.find
80
+
81
+ w = lists.find { |l| l.name == 'Work' }
82
+
83
+ puts "my Work list id is #{w.list_id}"
84
+
85
+ #
86
+ # adding a task to a list
87
+
88
+ task = Task.add! "work, more work", w.list_id
89
+
90
+ #
91
+ # completing a task
92
+
93
+ task.complete!
94
+
95
+ #
96
+ # deleting a task
97
+
98
+ task.delete!
99
+
100
+
101
+ Note that the methods that change the state of the Remember The Milk dataset have names ending with an exclamation mark.
102
+
103
+ Note as well that, there is a 1 second delay before any request to the RTM server, in order to respect their conditions. This may change in future releases.
104
+
105
+
106
+ = features yet to implement
107
+
108
+ * tags modifications
109
+ * smart lists
110
+ * ...
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+ == source
119
+
120
+ http://github.com/maisonneuve/rufus-rtm
121
+
122
+
123
+
124
+ == author
125
+ Nicolas Maisonneuve
126
+ version modified from the work of John Mettraux, jmettraux@gmail.com
127
+ http://jmettraux.wordpress.com
128
+
129
+
130
+ == license
131
+
132
+ MIT
133
+
@@ -0,0 +1,108 @@
1
+ # modified version to remove dependancies from rufus-verb gem
2
+ # author: Nicolas Maisonneuve n.maisonneuve@gmail.com
3
+
4
+ #--
5
+ # Copyright (c) 2008-2009, John Mettraux, jmettraux@gmail.com
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+ #
25
+ # Made in Japan.
26
+ #++
27
+
28
+
29
+ require 'rubygems'
30
+ require 'cgi'
31
+ require 'json'
32
+ require 'md5'
33
+
34
+ module Rufus
35
+ module RTM
36
+
37
+ VERSION = '0.1.2'
38
+
39
+ AUTH_ENDPOINT = "http://www.rememberthemilk.com/services/auth/"
40
+ REST_ENDPOINT = "http://api.rememberthemilk.com/services/rest/"
41
+
42
+ #
43
+ # Signs the RTM request (sets the 'api_sig' parameter).
44
+ #
45
+ def self.sign (params, secret) #:nodoc:
46
+
47
+ sig = MD5.md5(secret + params.sort.flatten.join)
48
+
49
+ params['api_sig'] = sig.to_s
50
+
51
+ params
52
+ end
53
+
54
+ #
55
+ # Calls an API method (milk the cow).
56
+ #
57
+ def self.milk (params={}) #:nodoc:
58
+
59
+ sleep 1
60
+
61
+ endpoint = params.delete(:endpoint)
62
+ endpoint = AUTH_ENDPOINT if endpoint == :auth
63
+ endpoint = endpoint || REST_ENDPOINT
64
+
65
+ ps = params.inject({}) { |r, (k, v)| r[k.to_s] = v; r }
66
+
67
+ ps['api_key'] = params[:api_key] || ENV['RTM_API_KEY']
68
+
69
+ raise 'API_KEY missing from environment or parameters, cannot proceed' \
70
+ unless ps['api_key']
71
+
72
+ ps['frob'] = params[:frob] || ENV['RTM_FROB']
73
+ ps.delete('frob') if ps['frob'] == nil
74
+
75
+ ps['auth_token'] = params[:auth_token] || ENV['RTM_AUTH_TOKEN']
76
+ ps.delete('auth_token') if ps['auth_token'] == nil
77
+
78
+ ps['format'] = 'json'
79
+
80
+ secret = params[:shared_secret] || ENV['RTM_SHARED_SECRET']
81
+
82
+ sign(ps, secret)
83
+
84
+ res = get(endpoint, :query => ps)
85
+
86
+ JSON.parse(res.body)['rsp']
87
+ end
88
+
89
+ #
90
+ # Requests a timeline from RTM.
91
+ #
92
+ def self.get_timeline #:nodoc:
93
+
94
+ milk(:method => 'rtm.timelines.create')['timeline']
95
+ end
96
+
97
+ def self.get(endpoint, hash)
98
+ query=hash.inject(""){|result, item|
99
+ result+="#{item[0].to_s}=#{CGI.escape(item[1].to_s)}&"
100
+ }
101
+ url=endpoint+'?'+query[0..query.length-2]
102
+ p url
103
+ Net::HTTP.get(URI.parse(url))
104
+ end
105
+
106
+ end
107
+ end
108
+
@@ -0,0 +1,103 @@
1
+ #--
2
+ # Copyright (c) 2008-2009, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Rufus::RTM
27
+
28
+ def self.auth_get_frob #:nodoc:
29
+
30
+ r = milk(:method => 'rtm.auth.getFrob')
31
+ r['frob']
32
+ end
33
+
34
+ def self.auth_get_frob_and_url #:nodoc:
35
+
36
+ frob = auth_get_frob
37
+
38
+ p = {}
39
+ p['api_key'] = ENV['RTM_API_KEY']
40
+ p['perms'] = 'delete'
41
+ p['frob'] = frob
42
+ sign(p, ENV['RTM_SHARED_SECRET'])
43
+
44
+ [
45
+ frob,
46
+ AUTH_ENDPOINT + '?' + p.collect { |k, v| "#{k}=#{v}" }.join("&")
47
+ ]
48
+ end
49
+
50
+ def self.auth_get_token (frob) #:nodoc:
51
+
52
+ begin
53
+ milk(:method => 'rtm.auth.getToken', :frob => frob)['auth']['token']
54
+ rescue Exception => e
55
+ nil
56
+ end
57
+ end
58
+
59
+ #
60
+ # ensuring the credentials are present...
61
+
62
+ unless ENV['RTM_FROB']
63
+
64
+ frob, auth_url = auth_get_frob_and_url
65
+
66
+ puts <<-EOS
67
+
68
+ please visit this URL with your browser and then hit 'enter' :
69
+
70
+ #{auth_url}
71
+
72
+ EOS
73
+
74
+ STDIN.gets
75
+ puts "ok, now getting auth token...\n"
76
+
77
+ auth_token = auth_get_token frob
78
+
79
+ if auth_token
80
+
81
+ puts <<-EOS
82
+
83
+ here are your RTM_FROB and RTM_AUTH_TOKEN, make sure to place them
84
+ in your environment :
85
+
86
+ export RTM_FROB=#{frob}
87
+ export RTM_AUTH_TOKEN=#{auth_token}
88
+
89
+ EOS
90
+ else
91
+
92
+ puts <<-EOS
93
+
94
+ couldn't get auth token, please retry...
95
+
96
+ EOS
97
+ end
98
+
99
+ exit 0
100
+ end
101
+
102
+ end
103
+
@@ -0,0 +1,337 @@
1
+ #--
2
+ # Copyright (c) 2008-2009, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Rufus::RTM
27
+
28
+ #
29
+ # A parent class for Task, List and co.
30
+ #
31
+ # Never use directly.
32
+ #
33
+ class MilkResource
34
+
35
+ def initialize (hsh)
36
+
37
+ @hsh = hsh
38
+ @operations = []
39
+ end
40
+
41
+ #
42
+ # Saves the instance back to RTM.
43
+ #
44
+ def save!
45
+
46
+ # TODO : compact !
47
+
48
+ @operations.reverse.each do |method_name, args|
49
+
50
+ self.class.execute method_name, args
51
+ end
52
+ @operations = []
53
+ end
54
+
55
+ protected
56
+
57
+ #
58
+ # a class method for listing attributes that can be found
59
+ # in the hash reply coming from RTM...
60
+ #
61
+ def self.milk_attr (*att_names) #:nodoc:
62
+
63
+ att_names.each do |att_name|
64
+ class_eval %{
65
+ def #{att_name}
66
+ @hsh['#{att_name}']
67
+ end
68
+ }
69
+ end
70
+ end
71
+
72
+ #
73
+ # Calls the milk() method (interacts with the RTM API).
74
+ #
75
+ def self.execute (method_name, args={})
76
+
77
+ args[:method] = "rtm.#{resource_name}.#{method_name}"
78
+
79
+ Rufus::RTM.milk(args)
80
+ end
81
+
82
+ #
83
+ # Returns the name of the resource as the API knows it
84
+ # (for example 'tasks' or 'lists').
85
+ #
86
+ def self.resource_name
87
+
88
+ self.to_s.split('::')[-1].downcase + 's'
89
+ end
90
+
91
+ #
92
+ # Simply calls the timeline() class method.
93
+ #
94
+ def timeline
95
+
96
+ MilkResource.timeline
97
+ end
98
+
99
+ #
100
+ # Returns the current timeline (fetches one if none has yet
101
+ # been prepared).
102
+ #
103
+ def self.timeline
104
+
105
+ @timeline ||= Rufus::RTM.get_timeline
106
+ end
107
+
108
+ def queue_operation (method_name, args)
109
+
110
+ @operations << [ method_name, args ]
111
+ end
112
+ end
113
+
114
+ #
115
+ # The RTM Task class.
116
+ #
117
+ class Task < MilkResource
118
+
119
+ def self.task_attr (*att_names) #:nodoc:
120
+
121
+ att_names.each do |att_name|
122
+ class_eval %{
123
+ def #{att_name}
124
+ @hsh['task']['#{att_name}']
125
+ end
126
+ }
127
+ end
128
+ end
129
+
130
+ attr_reader \
131
+ :list_id,
132
+ :taskseries_id,
133
+ :task_id,
134
+ :tags
135
+
136
+ milk_attr \
137
+ :name,
138
+ :modified,
139
+ :participants,
140
+ :url,
141
+ :notes,
142
+ :location_id,
143
+ :created,
144
+ :source
145
+
146
+ task_attr \
147
+ :completed,
148
+ :added,
149
+ :postponed,
150
+ :priority,
151
+ :deleted,
152
+ :has_due_time,
153
+ :estimate,
154
+ :due
155
+
156
+ def initialize (list_id, h)
157
+
158
+ super(h)
159
+
160
+ t = h['task']
161
+
162
+ @list_id = list_id
163
+ @taskseries_id = h['id']
164
+ @task_id = t['id']
165
+
166
+ @tags = TagArray.new(self, h['tags'])
167
+ end
168
+
169
+ #
170
+ # Deletes the task.
171
+ #
172
+ def delete!
173
+
174
+ self.class.execute('delete', prepare_api_args)
175
+ end
176
+
177
+ #
178
+ # Marks the task as completed.
179
+ #
180
+ def complete!
181
+
182
+ self.class.execute('complete', prepare_api_args)
183
+ end
184
+
185
+ #
186
+ # Sets the tags for the task.
187
+ #
188
+ def tags= (tags)
189
+
190
+ tags = tags.split(',') if tags.is_a?(String)
191
+
192
+ @tags = TagArray.new(list_id, tags)
193
+
194
+ queue_operation('setTasks', tags.join(','))
195
+ end
196
+
197
+ def self.find (params={})
198
+
199
+ parse_tasks(execute('getList', params))
200
+ end
201
+
202
+ #
203
+ # Adds a new task (and returns it).
204
+ #
205
+ def self.add! (name, list_id=nil)
206
+
207
+ args = {}
208
+ args[:name] = name
209
+ args[:list_id] = list_id if list_id
210
+ args[:timeline] = Rufus::RTM.get_timeline
211
+
212
+ h = execute('add', args)
213
+
214
+ parse_tasks(h)[0]
215
+ end
216
+
217
+ protected
218
+
219
+ def prepare_api_args
220
+ {
221
+ :timeline => timeline,
222
+ :list_id => list_id,
223
+ :taskseries_id => taskseries_id,
224
+ :task_id => task_id
225
+ }
226
+ end
227
+
228
+ def self.parse_tasks (o)
229
+
230
+ o = if o.is_a?(Hash)
231
+
232
+ r = o[resource_name]
233
+ o = r if r
234
+ o['list']
235
+ end
236
+
237
+ o = [ o ] unless o.is_a?(Array)
238
+ # Nota bene : not the same thing as o = Array(o)
239
+
240
+ o.inject([]) do |r, h|
241
+
242
+ list_id = h['id']
243
+ s = h['taskseries']
244
+ r += parse_taskseries(list_id, s) if s
245
+ r
246
+ end
247
+ end
248
+
249
+ def self.parse_taskseries (list_id, o)
250
+
251
+ o = [ o ] unless o.is_a?(Array)
252
+ o.collect { |s| self.new(list_id, s) }
253
+ end
254
+ end
255
+
256
+ class List < MilkResource
257
+
258
+ attr \
259
+ :list_id
260
+
261
+ milk_attr \
262
+ :name, :sort_order, :smart, :archived, :deleted, :position, :locked
263
+
264
+ def initialize (h)
265
+
266
+ super
267
+ @list_id = h['id']
268
+ end
269
+
270
+ def self.find (params={})
271
+
272
+ execute('getList', params)[resource_name]['list'].collect do |h|
273
+ self.new(h)
274
+ end
275
+ end
276
+ end
277
+
278
+ #
279
+ # An array of tasks.
280
+ #
281
+ class TagArray #:nodoc:
282
+ include Enumerable
283
+
284
+ def initialize (task, tags)
285
+
286
+ @task = task
287
+
288
+ @tags = if tags.is_a?(Array)
289
+ tags
290
+ else
291
+ tags['tag']
292
+ end
293
+ end
294
+
295
+ def << (tag)
296
+
297
+ @tags << tag
298
+
299
+ args = prepare_api_args
300
+ args[:tags] = tag
301
+
302
+ @task.queue_operation('addTags', args)
303
+ end
304
+
305
+ def delete (tag)
306
+
307
+ @tags.delete tag
308
+
309
+ args = prepare_api_args
310
+ args[:tags] = tag
311
+
312
+ @task.queue_operation('removeTags', args)
313
+ end
314
+
315
+ def clear
316
+
317
+ @tags.clear
318
+
319
+ args = prepare_api_args
320
+ args[:tags] = ''
321
+
322
+ @task.queue_operation('setTags', args)
323
+ end
324
+
325
+ def join (s)
326
+
327
+ @tags.join(s)
328
+ end
329
+
330
+ def each
331
+
332
+ @tags.each { |e| yield e }
333
+ end
334
+ end
335
+
336
+ end
337
+
data/lib/rufus/rtm.rb ADDED
@@ -0,0 +1,29 @@
1
+ #--
2
+ # Copyright (c) 2008-2009, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ require 'rufus/rtm/base'
27
+ require 'rufus/rtm/credentials'
28
+ require 'rufus/rtm/resources'
29
+
data/lib/rufus-rtm.rb ADDED
@@ -0,0 +1,3 @@
1
+
2
+ require 'rufus/rtm'
3
+
data/test/test.rb ADDED
@@ -0,0 +1,3 @@
1
+
2
+ Dir["#{File.dirname(__FILE__)}/*_test.rb"].each { |path| load(path) }
3
+
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: maisonneuve-rtm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Nicolas Maisonneuve
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-23 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: n.maisonneuve@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.txt
24
+ files:
25
+ - lib/rufus/rtm/base.rb
26
+ - lib/rufus/rtm/credentials.rb
27
+ - lib/rufus/rtm/resources.rb
28
+ - lib/rufus/rtm.rb
29
+ - lib/rufus-rtm.rb
30
+ - README.txt
31
+ has_rdoc: true
32
+ homepage:
33
+ licenses: []
34
+
35
+ post_install_message:
36
+ rdoc_options: []
37
+
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ version:
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ requirements: []
53
+
54
+ rubyforge_project:
55
+ rubygems_version: 1.3.5
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: Fork from Rufus RTM gem
59
+ test_files:
60
+ - test/test.rb