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.
- data/lib/city.rb +52 -0
- data/lib/entry.rb +63 -0
- data/lib/goal.rb +73 -0
- data/lib/id.rb +39 -0
- data/lib/person.rb +74 -0
- data/lib/r43.rb +637 -0
- data/lib/r43.rb.~1.6.~ +645 -0
- data/lib/tag.rb +31 -0
- data/test/authentication.xml +2 -0
- data/test/echo.xml +6 -0
- data/test/get_city-36.xml +148 -0
- data/test/get_citys_people-1164-offset20.xml +20 -0
- data/test/get_citys_people-1164.xml +192 -0
- data/test/get_entry-33.xml +25 -0
- data/test/get_goal_by_id-255.xml +20 -0
- data/test/get_goal_by_name-255.xml +19 -0
- data/test/get_goals_entries-255-offset20.xml +265 -0
- data/test/get_goals_entries-533.xml +1 -0
- data/test/get_goals_people-533-offset20.xml +1 -0
- data/test/get_goals_people-533.xml +1 -0
- data/test/get_goals_similarities-255.xml +1 -0
- data/test/get_person-erik.xml +268 -0
- data/test/get_person-flickr_username.xml +4 -0
- data/test/get_person-sweeting.xml +2 -0
- data/test/get_persons_completed_things-erik.xml +89 -0
- data/test/get_persons_entries-erik.xml +515 -0
- data/test/get_persons_neighbors-erik-20.xml +200 -0
- data/test/get_persons_neighbors-erik.xml +201 -0
- data/test/get_persons_progress_on_goal-erik-9.xml +57 -0
- data/test/get_persons_tag_cloud-erik.xml +272 -0
- data/test/get_persons_tags-erik.xml +228 -0
- data/test/get_persons_teammates-erik.xml +183 -0
- data/test/search_cities-london.xml +119 -0
- data/test/search_goals-ruby-offset20-max10.xml +83 -0
- data/test/search_goals-ruby-offset20.xml +153 -0
- data/test/search_goals-ruby.xml +153 -0
- data/test/search_goals-schemer.xml +20 -0
- data/test/search_people-Sean.xml +118 -0
- data/test/search_people_by_email-erik@mockerybird.com.xml +38 -0
- data/test/test_r43.rb +852 -0
- data/test/test_r43.rb.~1.8.~ +728 -0
- metadata +77 -0
data/lib/city.rb
ADDED
|
@@ -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
|
+
|
data/lib/entry.rb
ADDED
|
@@ -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
|
data/lib/goal.rb
ADDED
|
@@ -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
|
data/lib/id.rb
ADDED
|
@@ -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
|
+
|
data/lib/person.rb
ADDED
|
@@ -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
|
data/lib/r43.rb
ADDED
|
@@ -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
|