r43 0.2.0

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