r43 0.2.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.
Files changed (42) hide show
  1. data/lib/city.rb +52 -0
  2. data/lib/entry.rb +63 -0
  3. data/lib/goal.rb +73 -0
  4. data/lib/id.rb +39 -0
  5. data/lib/person.rb +74 -0
  6. data/lib/r43.rb +637 -0
  7. data/lib/r43.rb.~1.6.~ +645 -0
  8. data/lib/tag.rb +31 -0
  9. data/test/authentication.xml +2 -0
  10. data/test/echo.xml +6 -0
  11. data/test/get_city-36.xml +148 -0
  12. data/test/get_citys_people-1164-offset20.xml +20 -0
  13. data/test/get_citys_people-1164.xml +192 -0
  14. data/test/get_entry-33.xml +25 -0
  15. data/test/get_goal_by_id-255.xml +20 -0
  16. data/test/get_goal_by_name-255.xml +19 -0
  17. data/test/get_goals_entries-255-offset20.xml +265 -0
  18. data/test/get_goals_entries-533.xml +1 -0
  19. data/test/get_goals_people-533-offset20.xml +1 -0
  20. data/test/get_goals_people-533.xml +1 -0
  21. data/test/get_goals_similarities-255.xml +1 -0
  22. data/test/get_person-erik.xml +268 -0
  23. data/test/get_person-flickr_username.xml +4 -0
  24. data/test/get_person-sweeting.xml +2 -0
  25. data/test/get_persons_completed_things-erik.xml +89 -0
  26. data/test/get_persons_entries-erik.xml +515 -0
  27. data/test/get_persons_neighbors-erik-20.xml +200 -0
  28. data/test/get_persons_neighbors-erik.xml +201 -0
  29. data/test/get_persons_progress_on_goal-erik-9.xml +57 -0
  30. data/test/get_persons_tag_cloud-erik.xml +272 -0
  31. data/test/get_persons_tags-erik.xml +228 -0
  32. data/test/get_persons_teammates-erik.xml +183 -0
  33. data/test/search_cities-london.xml +119 -0
  34. data/test/search_goals-ruby-offset20-max10.xml +83 -0
  35. data/test/search_goals-ruby-offset20.xml +153 -0
  36. data/test/search_goals-ruby.xml +153 -0
  37. data/test/search_goals-schemer.xml +20 -0
  38. data/test/search_people-Sean.xml +118 -0
  39. data/test/search_people_by_email-erik@mockerybird.com.xml +38 -0
  40. data/test/test_r43.rb +852 -0
  41. data/test/test_r43.rb.~1.8.~ +728 -0
  42. metadata +77 -0
@@ -0,0 +1,52 @@
1
+ # copyright 2005 Pat Eyler, Sean Carley, & Edward Cho
2
+ # distributed under the same terms as Ruby
3
+
4
+
5
+ #
6
+ # Implements a city object from 43 things. Currently only meant
7
+ # to be contructed by an R43::Request object.
8
+ #
9
+
10
+
11
+
12
+ class City
13
+ attr_accessor :city_id, :name, :region, :country, :num_people,
14
+ :link, :goals
15
+
16
+ def initialize()
17
+ # just to initialize the object, we'll always feed the attributes
18
+ # in some other way
19
+ end
20
+
21
+ def initialize_copy(city)
22
+ @goals= city.goals.collect{|goal| goal.clone}
23
+ self
24
+ end
25
+
26
+ def to_i()
27
+ @city_id
28
+ end
29
+
30
+ #
31
+ # Builds a City object from 43 things. Currently only meant to
32
+ # constructed by an R43::Request object.
33
+ #
34
+ def City.from_xml(xml)
35
+ city = City.new()
36
+ city.name= xml.elements["name"].text
37
+ city.region= xml.elements["region"].text
38
+ city.country= xml.elements["country"].text
39
+ city.num_people= xml.elements["num_people"].text.to_i
40
+ city.link= xml.elements["link"].attributes["href"]
41
+ city.city_id= xml.attributes["city_id"].to_i
42
+
43
+ city.goals = Array.new
44
+ xml.elements.each("goal") do |goal_element|
45
+ goal = Goal.from_xml(goal_element)
46
+ city.goals.push(goal)
47
+ end
48
+
49
+ city
50
+ end
51
+ end
52
+
@@ -0,0 +1,63 @@
1
+ # copyright 2005 Pat Eyler, Sean Carley, & Edward Cho
2
+ # distributed under the same terms as Ruby
3
+
4
+ #
5
+ # Implements an entry object from 43 things. Currently only meant
6
+ # to be constructed by an R43::Request object.
7
+ #
8
+ #
9
+
10
+ class Entry
11
+ attr_accessor :title, :author, :dc_subject, :goal, :content,
12
+ :num_comments, :issued, :link, :id, :entry_id
13
+
14
+ def initialize()
15
+ # just to initialize the object, we'll always feed the attributes
16
+ # in some other way
17
+ end
18
+
19
+ def initialize_copy(entry)
20
+ @author = entry.author.clone if entry.author
21
+ @goal = entry.goal.clone if entry.goal
22
+ @id = entry.id.clone if entry.id
23
+ self
24
+ end
25
+
26
+ def to_i()
27
+ @entry_id
28
+ end
29
+
30
+ #
31
+ # Builds an Entry object from an xml object. Normally, this is
32
+ # called by the get_entry method of an R43::Request object.
33
+ #
34
+ def Entry.from_xml(xml)
35
+ entry = Entry.new
36
+
37
+ if xml.elements["title"] then
38
+ entry.title= xml.elements["title"].text
39
+ end
40
+ entry.dc_subject= xml.elements["dc:subject"].text
41
+ entry.content= xml.elements["content"].text
42
+ entry.num_comments=
43
+ xml.elements["num_comments"].text.to_i
44
+ entry.issued= xml.elements["issued"].text
45
+ entry.link= xml.elements["link"].attributes["href"]
46
+
47
+ entry.id= Id.from_xml(xml.elements["id"])
48
+ entry.entry_id = entry.id.to_i
49
+
50
+ xml.elements.each("author") do |entry_element|
51
+ entry.author= Person.from_xml(entry_element)
52
+ end
53
+
54
+ goal = Goal.new
55
+ xml.elements.each("goal") do |goal_entry|
56
+ goal = Goal.from_xml(goal_entry)
57
+ end
58
+ entry.goal= goal
59
+
60
+ entry
61
+ end
62
+
63
+ end
@@ -0,0 +1,73 @@
1
+ # copyright 2005 Pat Eyler, Sean Carley, & Edward Cho
2
+ # distributed under the same terms as Ruby
3
+
4
+ #
5
+ # Implements a goal object from 43 things. Currently only meant to be
6
+ # constructed by an R43::Request object
7
+ #
8
+ # require 'r43'
9
+ # connect = R43::Request.new(<api_key>)
10
+ # goal = get_goal_by_id(<goal_id>)
11
+ #
12
+ class Goal
13
+ attr_accessor :goal_id, :name, :link, :num_registered_people,
14
+ :num_unregistered_people, :num_say_worth_it,
15
+ :num_say_not_worth_it, :percentage_worth_it,
16
+ :tags, :id, :progress_link, :team_link
17
+
18
+ def initialize()
19
+ # just to initialize the object, we'll always feed the attributes in
20
+ # some other way
21
+ end
22
+
23
+ def initialize_copy(goal)
24
+ @tags= goal.tags.collect{|tag| tag.clone}
25
+ @id = goal.id.clone if goal.id
26
+ self
27
+ end
28
+
29
+ def to_i()
30
+ @goal_id
31
+ end
32
+
33
+ #
34
+ # Builds a Goal object from an xml object. Normally, this is
35
+ # called by the get_goal_by_id or get_goal_by_name methods of
36
+ # an R43::Request object.
37
+ #
38
+ def Goal.from_xml(xml)
39
+ goal = Goal.new()
40
+
41
+ goal.goal_id= xml.attributes["goal_id"].to_i
42
+ goal.name= xml.elements["name"].text
43
+ goal.link= xml.elements["link"].attributes["href"]
44
+
45
+ if xml.elements["num_registered_people"] then
46
+ goal.num_registered_people=
47
+ xml.elements["num_registered_people"].text.to_i
48
+ end
49
+
50
+ if xml.elements["num_unregistered_people"] then
51
+ goal.num_unregistered_people=
52
+ xml.elements["num_unregistered_people"].text.to_i
53
+ end
54
+
55
+ if xml.elements["worth_it_data"] then
56
+ goal.num_say_worth_it=
57
+ xml.elements["worth_it_data"].elements["num_say_worth_it"].text.to_i
58
+ goal.num_say_not_worth_it=
59
+ xml.elements["worth_it_data"].elements["num_say_not_worth_it"].text.to_i
60
+ goal.percentage_worth_it=
61
+ xml.elements["worth_it_data"].elements["percentage_worth_it"].text.to_i
62
+ end
63
+ goal.id= Id.from_xml(xml.elements["id"])
64
+
65
+ tags = []
66
+ xml.elements.each("tags/tag") do |tag_element|
67
+ tags.push(Tag.from_xml(tag_element))
68
+ end
69
+ goal.tags= tags
70
+
71
+ goal
72
+ end
73
+ end
@@ -0,0 +1,39 @@
1
+ # copyright 2005 Pat Eyler, Sean Carley, & Edward Cho
2
+ # distributed under the same terms as Ruby
3
+
4
+
5
+ #
6
+ # Implements an id object. This object encapsulates the 43 Things
7
+ # id string format of "tag:43things.com:joshp:entry:33". Currently,
8
+ # intended to be constructed only by other domain objects.
9
+ #
10
+ class Id
11
+ attr_accessor :string_value, :int_value
12
+
13
+ def initialize()
14
+ # just to initialize the object, we'll always feed the attributes
15
+ # in some other way
16
+ end
17
+
18
+ def to_i()
19
+ @int_value
20
+ end
21
+
22
+ def to_s()
23
+ @string_value
24
+ end
25
+
26
+ #
27
+ # Builds an Id object from the format
28
+ # "<id>tag:43things.com:joshp:entry:33</id>"
29
+ #
30
+ def Id.from_xml(xml)
31
+ id = Id.new()
32
+ xml.text =~ /^(.*:(\d+))$/
33
+ id.string_value= $1
34
+ id.int_value= $2
35
+
36
+ id
37
+ end
38
+ end
39
+
@@ -0,0 +1,74 @@
1
+ # copyright 2005 Pat Eyler, Sean Carley, & Edward Cho
2
+ # distributed under the same terms as Ruby
3
+
4
+
5
+ #
6
+ # Implements a person object from 43 things. Currently only meant to
7
+ # be constructed by a R43::Request object:
8
+ #
9
+ # require 'r43'
10
+ # connect = R43::Request.new(<api_key>)
11
+ # person = connect.get_person('<username>')
12
+ #
13
+ class Person
14
+ attr_accessor :username, :name, :url, :profile_image_url,
15
+ :num_open_goals, :link, :city, :goals,
16
+ :completed_goals, :flickr_username
17
+
18
+ def initialize()
19
+ # just to create the object, we'll always feed the attributes in
20
+ # some other way
21
+ end
22
+
23
+ def initialize_copy(person)
24
+ @city = person.city.clone if person.city
25
+ @goals = person.goals.collect{|goal| goal.clone}
26
+ @completed_goals = person.completed_goals.collect{|goal| goal.clone}
27
+ self
28
+ end
29
+
30
+ #
31
+ # Builds a Person object from an xml object. Normally, this is
32
+ # called by the get_person method of an R43::Request object.
33
+ #
34
+ def Person.from_xml(xml)
35
+ person = Person.new
36
+
37
+ person.username= xml.elements["username"].text
38
+ person.name= xml.elements["name"].text
39
+ person.url= xml.elements["url"].text
40
+ person.num_open_goals=
41
+ xml.elements["num_open_goals"].text.to_i
42
+ person.link= xml.elements["link"].attributes["href"]
43
+
44
+ person.flickr_username=xml.elements["flickr_username"].text if xml.elements["flickr_username"]
45
+
46
+ if xml.elements["profile_image_url"] then
47
+ person.profile_image_url=
48
+ xml.elements["profile_image_url"].text
49
+ else
50
+ person.profile_image_url= "none"
51
+ end
52
+
53
+ if xml.elements["city"] then
54
+ xml.elements.each("city") do |element|
55
+ person.city = City.from_xml(element)
56
+ end
57
+ end
58
+
59
+ person.goals = Array.new
60
+ xml.elements.each("open_goals/goal") do |goal_element|
61
+ goal = Goal.from_xml(goal_element)
62
+ person.goals.push(goal)
63
+ end
64
+
65
+ person.completed_goals = Array.new
66
+ xml.elements.each("completed_goals/goal") do |goal_element|
67
+ goal = Goal.from_xml(goal_element)
68
+ person.completed_goals.push(goal)
69
+ end
70
+
71
+ person
72
+ end
73
+
74
+ end
@@ -0,0 +1,637 @@
1
+ # copyright 2005 Pat Eyler, Sean Carley, & Edward Cho
2
+ # distributed under the same terms as Ruby
3
+
4
+
5
+ require 'net/http'
6
+ require 'rexml/document'
7
+ require 'city'
8
+ require 'entry'
9
+ require 'goal'
10
+ require 'id'
11
+ require 'person'
12
+ require 'tag'
13
+
14
+ module R43
15
+
16
+
17
+ private
18
+
19
+ class R43::Service
20
+ attr_reader :key, :proxy_addr
21
+
22
+ def initialize(key, proxy_addr, proxy_port, proxy_user, proxy_pass)
23
+ @key = key.to_s
24
+ @proxy_addr = proxy_addr
25
+ @proxy_port = proxy_port
26
+ @proxy_user = proxy_user
27
+ @proxy_pass = proxy_pass
28
+ end
29
+
30
+ protected
31
+
32
+ #
33
+ # a private method to add the api_key to the url
34
+ #
35
+ def _inject_key(url)
36
+ key_str = "api_key=#{@key}"
37
+ if url =~ /\?$/
38
+ url + key_str
39
+ elsif url =~ /\?/
40
+ url.sub /\?/, "?#{key_str}&"
41
+ else
42
+ url + "?" + key_str
43
+ end
44
+ end
45
+
46
+ def _get_http()
47
+ if @proxy_addr
48
+ Net::HTTP::Proxy(@proxy_addr, @proxy_port, @proxy_user, @proxy_pass)
49
+ else
50
+ Net::HTTP
51
+ end
52
+ end
53
+
54
+ #
55
+ # a private method for getting responses from 43 things.
56
+ #
57
+ def _get_response(url)
58
+ _get_http.start('www.43things.com') do |http|
59
+ response = _build_response(http, url)
60
+ end
61
+ end
62
+
63
+ def _build_response(http, url)
64
+ full_url = _inject_key url
65
+ response = http.get("/service/#{url}")
66
+ if response.code == "200"
67
+ xml = REXML::Document.new(response.body)
68
+ return xml
69
+ else
70
+ return response.code
71
+ end
72
+ end
73
+
74
+
75
+
76
+ public
77
+
78
+ def get_response(url)
79
+ _get_response(_inject_key(url))
80
+ end
81
+
82
+ end
83
+
84
+ public
85
+
86
+ #
87
+ # Implements the 43 Things API. This is where you actually
88
+ # instantiate objects.
89
+ #
90
+ # require 'r43'
91
+ # connection = R43::Connection.new(<api_key>)
92
+ #
93
+ class R43::Connection
94
+ attr_reader :service, :response
95
+
96
+ def initialize(key, proxy_addr=nil, proxy_port=nil,
97
+ proxy_user=nil, proxy_pass=nil)
98
+ @service = R43::Service.new(key, proxy_addr, proxy_port,
99
+ proxy_user, proxy_pass)
100
+ end
101
+
102
+
103
+ protected
104
+ attr_reader :return_reference
105
+
106
+ #
107
+ # a private method for getting responses from 43 things.
108
+ #
109
+ def _get_response(url)
110
+ @response = Response.new(@service, url)
111
+ end
112
+
113
+ def return_by_value(object)
114
+ if object.kind_of? Enumerable then
115
+ object.collect{|element| element.clone}
116
+ else
117
+ return object.clone
118
+ end
119
+ end
120
+
121
+ def store_and_return(object)
122
+ @return_reference = object
123
+ return_by_value(object)
124
+ end
125
+
126
+ public
127
+
128
+ #
129
+ # Exposes paging from the last connection.
130
+ #
131
+ def more()
132
+ @response.more()
133
+ return_by_value(@return_reference)
134
+ end
135
+
136
+ #
137
+ # Implements the echo method from the General API. Returns a hash
138
+ # with the keys; <em>api_key</em>, <em>action</em>,
139
+ # <em>controller</em>
140
+ #
141
+ # require 'r43'
142
+ # connection = R43::Connection.new(<api_key>)
143
+ # response = connection.echo
144
+ #
145
+ def echo()
146
+ xml = _get_response("echo").xml
147
+ response = {
148
+ "api_key" =>
149
+ xml.elements["parameters"].elements["api_key"].text,
150
+ "action" =>
151
+ xml.elements["parameters"].elements["action"].text,
152
+ "controller" =>
153
+ xml.elements["parameters"].elements["controller"].text
154
+ }
155
+ end
156
+
157
+
158
+ #
159
+ # Implements the authentication_test method from the General API.
160
+ # returns "true" if the connection works. Only uses the cleartext
161
+ # username and password at this point
162
+ #
163
+ # require 'r43'
164
+ # connection = R43::Connection.new(<api_key>)
165
+ # response = connection.authentication_test(<username>,<password>)
166
+ #--
167
+ # This really needs ATOM style authentication to work properly
168
+ #++
169
+ #
170
+ def authentication_test(username, password)
171
+ xml = _get_response("authentication_test?username=#{username}&password=#{password}").xml
172
+ xml.elements["authentication_test"].text
173
+ end
174
+
175
+ #
176
+ # Implements the get_goal_by_id method from the Goals API. Returns a
177
+ # Goal object.
178
+ #
179
+ # require 'r43'
180
+ # connection = R43::Connection.new(<api_key>)
181
+ # goal = connection.get_goal_by_id(255)
182
+ #
183
+ def get_goal_by_id(id)
184
+ store_and_return(_get_response("get_goal_by_id?id=#{id}").goal)
185
+ end
186
+
187
+
188
+ #
189
+ # Implements the get_goal_by_name method from the Goals API. Returns
190
+ # a Goal object
191
+ #
192
+ # require 'r43'
193
+ # connection = R43::Connection.new(<api_key>)
194
+ # goal = connection.get_goal_by_name(<name>)
195
+ #
196
+ def get_goal_by_name(name)
197
+ name = name.gsub!(/\s/, '+')
198
+ store_and_return(_get_response("get_goal_by_name?name=#{name}").goal)
199
+ end
200
+
201
+
202
+ #
203
+ # Implements the get_goals_similarities method from the Goals API and
204
+ # returns an array of Goal objects
205
+ #
206
+ #
207
+ # require 'r43'
208
+ # connection = R43::Connection.new(<api_key>)
209
+ # goals = connection.get_goals_similarities(<id>)
210
+ #
211
+ def get_goals_similarities(id)
212
+ store_and_return(_get_response("get_goals_similarities?id=#{id}").goals)
213
+ end
214
+
215
+ #
216
+ # Implements the search_goals method from the Goals API and
217
+ # returns an array of Goal objects
218
+ #
219
+ #
220
+ # require 'r43'
221
+ # connection = R43::Connection.new(<api_key>)
222
+ # goals = connection.search_goals(<query string>[,
223
+ # {["offset" => <offset>],
224
+ # ["max" => <max>]}])
225
+ #
226
+ def search_goals(string, optional={})
227
+ string.gsub!(/\s/, "+")
228
+ if optional["offset"] then
229
+ string += "&offset=#{optional["offset"]}"
230
+ end
231
+ if optional["max"] then
232
+ string += "&max=#{optional["max"]}"
233
+ end
234
+
235
+ store_and_return(_get_response("search_goals?q=#{string}").goals)
236
+ end
237
+
238
+ #
239
+ # Implements the get_goals_people method from the Goals API and
240
+ # returns an array of Person objects
241
+ #
242
+ # require 'r43'
243
+ # connection = R43::Connection.new(<api_key>)
244
+ # people = connection.get_goals_people(<id>[,
245
+ # {["offset" => <offset>],
246
+ # ["max" => <max>]}])
247
+ #
248
+ def get_goals_people(id, optional={})
249
+ string = "id=#{id}"
250
+ if optional["offset"] then
251
+ string += "&offset=#{optional["offset"]}"
252
+ end
253
+ if optional["max"] then
254
+ string += "&max=#{optional["max"]}"
255
+ end
256
+
257
+ store_and_return(_get_response("get_goals_people?#{string}").people)
258
+ end
259
+
260
+ #
261
+ # Implements the get_goals_entries method from the Goals API and
262
+ # returns an array of Entry objects
263
+ #
264
+ # require 'r43'
265
+ # connection = R43::Connection.new(<api_key>)
266
+ # entries = connection.get_goals_entries(<id>,[{["offset" => <offset>],
267
+ # ["max" => <max>],
268
+ # ["view" => <view>]}])
269
+ #
270
+ def get_goals_entries(id, optional={})
271
+ string = "id=#{id}"
272
+ if optional["offset"] then
273
+ string += "&offset=#{optional["offset"]}"
274
+ end
275
+ if optional["max"] then
276
+ string += "&max=#{optional["max"]}"
277
+ end
278
+ if optional["view"] then
279
+ string += "&view=#{optional["view"]}"
280
+ end
281
+
282
+ store_and_return(_get_response("get_goals_entries?#{string}").entries)
283
+ end
284
+
285
+
286
+ #
287
+ # Implements the search_people method from the People API and returns
288
+ # an array of Person objects. Response will be set on Connection and
289
+ # this is a paged collection.
290
+ #
291
+ # require 'r43'
292
+ # connection = R43::Connection.new(<api_key>)
293
+ # people = connection.search_people(<query>)
294
+ # people += connection.more
295
+ #
296
+ def search_people(query, options={})
297
+ # TODO: add paging options
298
+ store_and_return(_get_response("search_people?q=#{query}").people)
299
+ end
300
+
301
+ #
302
+ # Implements the search_people_by_email method from the People API
303
+ # and returns an array of Person objects. Response will be set on
304
+ # Connection and this is a paged collection.
305
+ #
306
+ # require 'r43'
307
+ # connection = R43::Connection.new(<api_key>)
308
+ # people = connection.search_people_by_email(<query>)
309
+ # people += connection.more
310
+ #
311
+ def search_people_by_email(query, options={})
312
+ # TODO: add paging options
313
+ store_and_return(_get_response("search_people_by_email?q=#{query}").people)
314
+ end
315
+
316
+ #
317
+ # Implements the get_person method from the People API and returns a
318
+ # Person object. If the optional true or false value is set to true,
319
+ # the username is treated as a flickr username instead of a 43 Things
320
+ # username. If the value is false or not set, the username is treated
321
+ # as a 43 Things username.
322
+ #
323
+ # require 'r43'
324
+ # connection = R43::Connection.new(<api_key>)
325
+ # person = connection.get_person(<username>[, <true|false>])
326
+ #
327
+ def get_person(id,use_flickr=false)
328
+ if (use_flickr)
329
+ id_cmd = "flickr_username"
330
+ else
331
+ id_cmd = "id"
332
+ end
333
+ store_and_return(_get_response("get_person?#{id_cmd}=#{id}").person)
334
+ end
335
+
336
+ #
337
+ # Implements get_persons_completed_things from the People API and
338
+ # returns a Person object with completed_goals populated.
339
+ #
340
+ # require 'r43'
341
+ # connection = R43::Connection.new(<api_key>)
342
+ # person = connection.get_persons_completed_things("erik")
343
+ # completed_goals = person.completed_goals
344
+ #
345
+ def get_persons_completed_things(username, options={})
346
+ # TODO: add flickr_username handling
347
+ store_and_return(_get_response("get_persons_completed_things?id=#{username}").person)
348
+ end
349
+
350
+ #
351
+ # Implements get_persons_entries from the People API and
352
+ # returns an array of the person's entries. This method
353
+ # sets connection.response and configures paging via connection.
354
+ #
355
+ # Currently broken. The web service never returns entries.
356
+ #
357
+ # require 'r43'
358
+ # connection = R43::Connection.new(<api_key>)
359
+ # entries = connection.get_persons_completed_things(<username>)
360
+ # entries += connection.more
361
+ #
362
+ def get_persons_entries(username, options={})
363
+ # TODO: add flickr_username handling
364
+ store_and_return(_get_response("get_persons_entries?id=#{username}").entries)
365
+ end
366
+
367
+ #
368
+ # Implements get_persons_progress_on_goal from the People
369
+ # API and returns an array of entries for the goal. The
370
+ # entries may be paginated.
371
+ #
372
+ # require 'r43'
373
+ # connection = R43::Connection.new(<api_key>)
374
+ # entries = connection.get_persons_progress_on_goal(<username>, goal_id
375
+ # [, options])
376
+ # entries += connection.more
377
+ #
378
+ def get_persons_progress_on_goal(username, goal_id, options={})
379
+ # TODO: add flickr_username handling
380
+ store_and_return(_get_response("get_persons_progress_on_goal?id=#{username}&goal_id=#{goal_id}").entries)
381
+ end
382
+
383
+
384
+ #
385
+ # Implements get_persons_teammates from the People
386
+ # API and returns an array of people. The people
387
+ # may be paginated.
388
+ #
389
+ # require 'r43'
390
+ # connection = R43::Connection.new(<api_key>)
391
+ # people = connection.get_persons_teammates(<username>
392
+ # [, options])
393
+ # people += connection.more
394
+ #
395
+ def get_persons_teammates(username, options={})
396
+ # TODO: add flickr_username handling
397
+ # TODO: add paging options
398
+ store_and_return(_get_response("get_persons_teammates?id=#{username}").people)
399
+ end
400
+
401
+
402
+ #
403
+ # Implements get_persons_neighbors from the People
404
+ # API and returns an array of people. The array
405
+ # may be paginated.
406
+ #
407
+ # require 'r43'
408
+ # connection = R43::Connection.new(<api_key>)
409
+ # people = connection.get_persons_neighborss(<username>
410
+ # [, options])
411
+ # people += connection.more
412
+ #
413
+ def get_persons_neighbors(username, options={})
414
+ # TODO: add flickr_username handling
415
+ # TODO: add paging options
416
+ store_and_return(_get_response("get_persons_neighbors?id=#{username}").people)
417
+ end
418
+
419
+
420
+ #
421
+ # Implements get_persons_tags from the People
422
+ # API and returns an array of tags.
423
+ #
424
+ # require 'r43'
425
+ # connection = R43::Connection.new(<api_key>)
426
+ # tags = connection.get_persons_tags(<username>
427
+ # [, options])
428
+ #
429
+ def get_persons_tags(username, options={})
430
+ # TODO: add flickr_username handling
431
+ store_and_return(_get_response("get_persons_tags?id=#{username}").tags)
432
+ end
433
+
434
+
435
+ #
436
+ # Implements get_persons_tag_cloud from the People
437
+ # API and returns an array of tags.
438
+ #
439
+ # require 'r43'
440
+ # connection = R43::Connection.new(<api_key>)
441
+ # tags = connection.get_persons_tag_cloud(<username>
442
+ # [, options])
443
+ #
444
+ def get_persons_tag_cloud(username, options={})
445
+ # TODO: add flickr_username handling
446
+ store_and_return(_get_response("get_persons_tag_cloud?id=#{username}").tags)
447
+ end
448
+
449
+
450
+ #
451
+ # Implements the get_entry method of the Entries API and
452
+ # returns an Entry object.
453
+ #
454
+ # require 'r43'
455
+ # connection = R43::Connection.new(<api_key>)
456
+ # entry = connection.get_entry(<id>)
457
+ #
458
+ def get_entry(id)
459
+ store_and_return(_get_response("get_entry?id=#{id}").entry)
460
+ end
461
+
462
+ #
463
+ # Implements the search_cities method of the Cities API
464
+ #
465
+ # require 'r43'
466
+ # connection = R43::Connection.new(<api_key>)
467
+ # cities = connection.search_cities(<query>)
468
+ #
469
+ def search_cities(query)
470
+ store_and_return(_get_response("search_cities?q=#{query}").cities)
471
+ end
472
+
473
+ #
474
+ # Implements the get_city method of the Cities API
475
+ #
476
+ # require 'r43'
477
+ # connection = R43::Connection.new(<api_key>)
478
+ # city = connection.get_city(<id>)
479
+ #
480
+
481
+ def get_city(id)
482
+ store_and_return(_get_response("get_city?id=#{id}").city)
483
+ end
484
+
485
+ #
486
+ # Implements the get_citys_people method of the Cities API
487
+ #
488
+ # require 'r43'
489
+ # connection = R43::Connection.new(<api_key>)
490
+ # people = connection.get_citys_people(<id>)
491
+ #
492
+
493
+ def get_citys_people(id, optional={})
494
+ params = "id=#{id}"
495
+ params += "&offset=#{optional["offset"]}" if optional["offset"]
496
+ params += "&max=#{optional["max"]}" if optional["max"]
497
+
498
+ store_and_return(_get_response("get_citys_people?#{params}").people)
499
+ end
500
+
501
+ end
502
+
503
+ class R43::Response
504
+ attr_reader :service, :query, :xml,
505
+ :object, :entry, :person, :goal, :city,
506
+ :objects, :entries, :people, :goals, :cities, :tags,
507
+ :has_object, :max_in_page, :total_available, :next_offset
508
+
509
+ def initialize(service, query)
510
+ @service = service
511
+ @query = query
512
+ @has_object = false
513
+ @objects = []
514
+ @entries = []
515
+ @people = []
516
+ @goals = []
517
+ @cities = []
518
+ @tags = []
519
+ @max_in_page = 0
520
+ @total_available = 0
521
+ @next_offset = 0
522
+ _from_xml(service.get_response(query))
523
+ end
524
+
525
+ def more()
526
+ clear_arrays()
527
+ _populate_collections_from_xml(service.get_response(query + "&offset=#{@next_offset}"))
528
+ end
529
+
530
+ private
531
+
532
+ def clear_arrays()
533
+ @objects.clear()
534
+ @entries.clear()
535
+ @people.clear()
536
+ @goals.clear()
537
+ @cities.clear()
538
+ @tags.clear()
539
+ end
540
+
541
+ def object=(object)
542
+ if @has_object
543
+ @object = nil
544
+ else
545
+ @has_object = true
546
+ @object = object
547
+ end
548
+ end
549
+
550
+ def entry=(entry)
551
+ @entry = entry
552
+ self.object = @entry
553
+ add_entry(@entry)
554
+ end
555
+
556
+ def person=(person)
557
+ @person = person
558
+ self.object = @person
559
+ add_person @person
560
+ end
561
+
562
+ def goal=(goal)
563
+ @goal = goal
564
+ self.object = @goal
565
+ add_goal @goal
566
+ end
567
+
568
+ def city=(city)
569
+ @city = city
570
+ self.object = @city
571
+ add_city @city
572
+ end
573
+
574
+ def add_entry(entry)
575
+ @entries.push entry
576
+ @objects.push entry
577
+ end
578
+
579
+ def add_person(person)
580
+ @people.push person
581
+ @objects.push person
582
+ end
583
+
584
+ def add_goal(goal)
585
+ @goals.push goal
586
+ @objects.push goal
587
+ end
588
+
589
+ def add_city(city)
590
+ @cities.push city
591
+ @objects.push city
592
+ end
593
+
594
+ def add_tag(tag)
595
+ @tags.push tag
596
+ @objects.push tag
597
+ end
598
+
599
+ def _from_xml(xml)
600
+ @xml = xml
601
+ self.entry = Entry.from_xml(xml.elements["entry"]) if xml.elements["entry"]
602
+ self.person = Person.from_xml(xml.elements["person"]) if xml.elements["person"]
603
+ self.goal = Goal.from_xml(xml.elements["goal"]) if xml.elements["goal"]
604
+ self.city = City.from_xml(xml.elements["city"]) if xml.elements["city"]
605
+ _populate_collections_from_xml xml
606
+ end
607
+
608
+ def _populate_collections_from_xml(xml)
609
+ if xml.elements["feed/pagination"] then
610
+ @max_per_page = xml.elements["feed/pagination/max"].text.to_i
611
+ @total_available = xml.elements["feed/pagination/total"].text.to_i
612
+ @next_offset = xml.elements["feed/pagination/next_offset"].text.to_i
613
+ end
614
+
615
+ xml.elements.each("feed/entry") do |entry_element|
616
+ add_entry(Entry.from_xml(entry_element))
617
+ end
618
+
619
+ xml.elements.each("feed/person") do |person_element|
620
+ add_person(Person.from_xml(person_element))
621
+ end
622
+
623
+ xml.elements.each("feed/goal") do |goal_element|
624
+ add_goal(Goal.from_xml(goal_element))
625
+ end
626
+
627
+ xml.elements.each("feed/city") do |city_element|
628
+ add_city(City.from_xml(city_element))
629
+ end
630
+
631
+ xml.elements.each("feed/tags/tag") do |tag_element|
632
+ tag = Tag.from_xml(tag_element)
633
+ add_tag(tag)
634
+ end
635
+ end
636
+ end
637
+ end