opensocial 0.0.4
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/LICENSE +202 -0
- data/NOTICE +60 -0
- data/README +108 -0
- data/lib/opensocial.rb +29 -0
- data/lib/opensocial/activity.rb +116 -0
- data/lib/opensocial/appdata.rb +117 -0
- data/lib/opensocial/auth/action_controller_request.rb +87 -0
- data/lib/opensocial/auth/base.rb +114 -0
- data/lib/opensocial/base.rb +54 -0
- data/lib/opensocial/connection.rb +146 -0
- data/lib/opensocial/group.rb +83 -0
- data/lib/opensocial/person.rb +198 -0
- data/lib/opensocial/request.rb +273 -0
- data/lib/opensocial/string/merb_string.rb +32 -0
- data/lib/opensocial/string/os_string.rb +23 -0
- data/tests/activity_test.rb +107 -0
- data/tests/appdata_test.rb +59 -0
- data/tests/connection_test.rb +54 -0
- data/tests/fixtures/activities.json +28 -0
- data/tests/fixtures/activity.json +13 -0
- data/tests/fixtures/appdata.json +6 -0
- data/tests/fixtures/appdatum.json +5 -0
- data/tests/fixtures/group.json +7 -0
- data/tests/fixtures/groups.json +16 -0
- data/tests/fixtures/people.json +20 -0
- data/tests/fixtures/person.json +9 -0
- data/tests/fixtures/person_appdata_rpc.json +1 -0
- data/tests/fixtures/person_rpc.json +1 -0
- data/tests/group_test.rb +72 -0
- data/tests/online_test.rb +56 -0
- data/tests/person_test.rb +109 -0
- data/tests/request_test.rb +51 -0
- data/tests/rpcrequest_test.rb +95 -0
- data/tests/test.rb +41 -0
- data/tests/test_helper.rb +39 -0
- metadata +129 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
# Copyright (c) 2008 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
module OpenSocial #:nodoc:
|
17
|
+
|
18
|
+
# Acts as a wrapper for an OpenSocial group.
|
19
|
+
#
|
20
|
+
# The Group class takes input JSON as an initialization parameter, and
|
21
|
+
# iterates through each of the key/value pairs of that JSON. For each key
|
22
|
+
# that is found, an attr_accessor is constructed, allowing direct access
|
23
|
+
# to the value. Each value is stored in the attr_accessor, either as a
|
24
|
+
# String, Fixnum, Hash, or Array.
|
25
|
+
#
|
26
|
+
|
27
|
+
|
28
|
+
class Group < Base
|
29
|
+
|
30
|
+
# Initializes the Group based on the provided json fragment. If no JSON
|
31
|
+
# is provided, an empty object (with no attributes) is created.
|
32
|
+
def initialize(json)
|
33
|
+
if json
|
34
|
+
json.each do |key, value|
|
35
|
+
proper_key = key.snake_case
|
36
|
+
begin
|
37
|
+
self.send("#{proper_key}=", value)
|
38
|
+
rescue NoMethodError
|
39
|
+
add_attr(proper_key)
|
40
|
+
self.send("#{proper_key}=", value)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Provides the ability to request a Collection of groups for a given
|
48
|
+
# user.
|
49
|
+
#
|
50
|
+
# The FetchGroupsRequest wraps a simple request to an OpenSocial
|
51
|
+
# endpoint for a collection of groups. As parameters, it accepts
|
52
|
+
# a user ID. This request may be used, standalone, by calling send, or
|
53
|
+
# bundled into an RpcRequest.
|
54
|
+
#
|
55
|
+
|
56
|
+
|
57
|
+
class FetchGroupsRequest < Request
|
58
|
+
# Defines the service fragment for use in constructing the request URL or
|
59
|
+
# JSON
|
60
|
+
SERVICE = 'groups'
|
61
|
+
|
62
|
+
# Initializes a request to fetch groups for the specified user, or the
|
63
|
+
# default (@me). A valid Connection is not necessary if the request is to
|
64
|
+
# be used as part of an RpcRequest.
|
65
|
+
def initialize(connection = nil, guid = '@me')
|
66
|
+
super
|
67
|
+
end
|
68
|
+
|
69
|
+
# Sends the request, passing in the appropriate SERVICE and specified
|
70
|
+
# instance variables.
|
71
|
+
def send
|
72
|
+
json = send_request(SERVICE, @guid)
|
73
|
+
|
74
|
+
groups = Collection.new
|
75
|
+
for entry in json['entry']
|
76
|
+
group = Group.new(entry)
|
77
|
+
groups[group.id] = group
|
78
|
+
end
|
79
|
+
|
80
|
+
return groups
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
# Copyright (c) 2008 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
# Extends the OpenSocial module, providing a wrapper for OpenSocial people.
|
16
|
+
#
|
17
|
+
# Person: Acts as a wrapper for an OpenSocial person.
|
18
|
+
# FetchPersonRequest: Provides the ability to request a single person.
|
19
|
+
# FetchPeopleRequest: Provides the ability to request a collection of people
|
20
|
+
# by describing their relationship to a single person.
|
21
|
+
#
|
22
|
+
|
23
|
+
|
24
|
+
module OpenSocial #:nodoc:
|
25
|
+
|
26
|
+
# Acts as a wrapper for an OpenSocial person.
|
27
|
+
#
|
28
|
+
# The Person class takes input JSON as an initialization parameter, and
|
29
|
+
# iterates through each of the key/value pairs of that JSON. For each key
|
30
|
+
# that is found, an attr_accessor is constructed, allowing direct access
|
31
|
+
# to the value. Each value is stored in the attr_accessor, either as a
|
32
|
+
# String, Fixnum, Hash, or Array.
|
33
|
+
#
|
34
|
+
|
35
|
+
|
36
|
+
class Person < Base
|
37
|
+
|
38
|
+
# Initializes the Person based on the provided json fragment. If no JSON
|
39
|
+
# is provided, an empty object (with no attributes) is created.
|
40
|
+
def initialize(json)
|
41
|
+
if json
|
42
|
+
json.each do |key, value|
|
43
|
+
proper_key = key.snake_case
|
44
|
+
begin
|
45
|
+
self.send("#{proper_key}=", value)
|
46
|
+
rescue NoMethodError
|
47
|
+
add_attr(proper_key)
|
48
|
+
self.send("#{proper_key}=", value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the complete name of the Person, to the best ability, given
|
55
|
+
# available fields.
|
56
|
+
def long_name
|
57
|
+
if @name && @name['givenName'] && @name['familyName']
|
58
|
+
return @name['givenName'] + ' ' + @name['familyName']
|
59
|
+
elsif @nickname
|
60
|
+
return @nickname
|
61
|
+
else
|
62
|
+
return ''
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the first name or nickname of the Person, to the best ability,
|
67
|
+
# given available fields.
|
68
|
+
def short_name
|
69
|
+
if @name && @name['givenName']
|
70
|
+
return @name['givenName']
|
71
|
+
elsif @nickname
|
72
|
+
return @nickname
|
73
|
+
else
|
74
|
+
return ''
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Provides the ability to request a single Person.
|
80
|
+
#
|
81
|
+
# The FetchPeopleRequests wraps a simple request to an OpenSocial
|
82
|
+
# endpoint for a single person. As parameters, it accepts a user ID and
|
83
|
+
# selector and optionally an ID of a particular person, in order to display
|
84
|
+
# the user ID's view of that person. This request may be used, standalone,
|
85
|
+
# by calling send, or bundled into an RpcRequest.
|
86
|
+
#
|
87
|
+
|
88
|
+
|
89
|
+
class FetchPersonRequest < Request
|
90
|
+
# Defines the service fragment for use in constructing the request URL or
|
91
|
+
# JSON
|
92
|
+
SERVICE = 'people'
|
93
|
+
|
94
|
+
# Initializes a request to the specified user, or the default (@me, @self).
|
95
|
+
# A valid Connection is not necessary if the request is to be used as part
|
96
|
+
# of an RpcRequest.
|
97
|
+
def initialize(connection = nil, guid = '@me', selector = '@self')
|
98
|
+
super
|
99
|
+
end
|
100
|
+
|
101
|
+
# Sends the request, passing in the appropriate SERVICE and specified
|
102
|
+
# instance variables.
|
103
|
+
def send
|
104
|
+
json = send_request(SERVICE, @guid, @selector)
|
105
|
+
|
106
|
+
return parse_response(json['entry'])
|
107
|
+
end
|
108
|
+
|
109
|
+
# Selects the appropriate fragment from the JSON response in order to
|
110
|
+
# create a native object.
|
111
|
+
def parse_rpc_response(response)
|
112
|
+
return parse_response(response['data'])
|
113
|
+
end
|
114
|
+
|
115
|
+
# Converts the request into a JSON fragment that can be used as part of a
|
116
|
+
# larger RpcRequest.
|
117
|
+
def to_json(*a)
|
118
|
+
value = {
|
119
|
+
'method' => SERVICE + GET,
|
120
|
+
'params' => {
|
121
|
+
'userId' => ["#{@guid}"],
|
122
|
+
'groupId' => "#{@selector}"
|
123
|
+
},
|
124
|
+
'id' => @key
|
125
|
+
}.to_json(*a)
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
# Converts the JSON response into a person.
|
131
|
+
def parse_response(response)
|
132
|
+
return Person.new(response)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Provides the ability to request a Collection of people by describing their
|
137
|
+
# relationship to a single person.
|
138
|
+
#
|
139
|
+
# The FetchPeopleRequests wraps a simple request to an OpenSocial
|
140
|
+
# endpoint for a Collection of people. As parameters, it accepts
|
141
|
+
# a user ID and selector. This request may be used, standalone, by calling
|
142
|
+
# send, or bundled into an RpcRequest.
|
143
|
+
#
|
144
|
+
|
145
|
+
|
146
|
+
class FetchPeopleRequest < Request
|
147
|
+
# Defines the service fragment for use in constructing the request URL or
|
148
|
+
# JSON
|
149
|
+
SERVICE = 'people'
|
150
|
+
|
151
|
+
# Initializes a request to the specified user's group, or the default (@me,
|
152
|
+
# @friends). A valid Connection is not necessary if the request is to be
|
153
|
+
# used as part of an RpcRequest.
|
154
|
+
def initialize(connection = nil, guid = '@me', selector = '@friends')
|
155
|
+
super
|
156
|
+
end
|
157
|
+
|
158
|
+
# Sends the request, passing in the appropriate SERVICE and specified
|
159
|
+
# instance variables.
|
160
|
+
def send
|
161
|
+
json = send_request(SERVICE, @guid, @selector)
|
162
|
+
|
163
|
+
return parse_response(json['entry'])
|
164
|
+
end
|
165
|
+
|
166
|
+
# Selects the appropriate fragment from the JSON response in order to
|
167
|
+
# create a native object.
|
168
|
+
def parse_rpc_response(response)
|
169
|
+
return parse_response(response['data']['list'])
|
170
|
+
end
|
171
|
+
|
172
|
+
# Converts the request into a JSON fragment that can be used as part of a
|
173
|
+
# larger RPC request.
|
174
|
+
def to_json(*a)
|
175
|
+
value = {
|
176
|
+
'method' => SERVICE + GET,
|
177
|
+
'params' => {
|
178
|
+
'userId' => ["#{@guid}"],
|
179
|
+
'groupId' => "#{@selector}"
|
180
|
+
},
|
181
|
+
'id' => @key
|
182
|
+
}.to_json(*a)
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
# Converts the JSON response into a Collection of people, indexed by id.
|
188
|
+
def parse_response(response)
|
189
|
+
people = Collection.new
|
190
|
+
for entry in response
|
191
|
+
person = Person.new(entry)
|
192
|
+
people[person.id] = person
|
193
|
+
end
|
194
|
+
|
195
|
+
return people
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,273 @@
|
|
1
|
+
# Copyright (c) 2008 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
module OpenSocial #:nodoc:
|
17
|
+
|
18
|
+
# Provides a wrapper for a single request to an OpenSocial endpoint, either
|
19
|
+
# as a standalone request, or as a fragment of an RPC request.
|
20
|
+
#
|
21
|
+
# The Request class wraps an HTTP request to an OpenSocial endpoint for
|
22
|
+
# social data. A Request may be used, directly, to access social resources
|
23
|
+
# that may not be currently wrapped by Request's child classes. Used in this
|
24
|
+
# was it gives near-raw access to social data. The Request class supplies
|
25
|
+
# OAuth signing when the supplied connection contains appropriate
|
26
|
+
# credentials.
|
27
|
+
#
|
28
|
+
|
29
|
+
|
30
|
+
class Request
|
31
|
+
GET = '.get'
|
32
|
+
|
33
|
+
# Defines the connection that will be used in the request.
|
34
|
+
attr_accessor :connection
|
35
|
+
|
36
|
+
# Defines the guid for the request.
|
37
|
+
attr_accessor :guid
|
38
|
+
|
39
|
+
# Defines the selector for the request.
|
40
|
+
attr_accessor :selector
|
41
|
+
|
42
|
+
# Defines the pid for the request.
|
43
|
+
attr_accessor :pid
|
44
|
+
|
45
|
+
# Defines the key used to lookup the request result in an RPC request.
|
46
|
+
attr_accessor :key
|
47
|
+
|
48
|
+
# Initializes a request using the optionally supplied connection, guid,
|
49
|
+
# selector, and pid.
|
50
|
+
def initialize(connection = nil, guid = nil, selector = nil, pid = nil)
|
51
|
+
@connection = connection
|
52
|
+
@guid = guid
|
53
|
+
@selector = selector
|
54
|
+
@pid = pid
|
55
|
+
end
|
56
|
+
|
57
|
+
# Generates a request given the service, guid, selector, and pid, to the
|
58
|
+
# OpenSocial endpoint by constructing the service URI and dispatching the
|
59
|
+
# request. When data is returned, it is parsed as JSON after being
|
60
|
+
# optionally unescaped.
|
61
|
+
def send_request(service, guid, selector = nil, pid = nil,
|
62
|
+
unescape = false)
|
63
|
+
if !@connection
|
64
|
+
raise RequestException.new('Request requires a valid connection.')
|
65
|
+
end
|
66
|
+
|
67
|
+
uri = @connection.service_uri(@connection.container[:rest] + service,
|
68
|
+
guid, selector, pid)
|
69
|
+
data = dispatch(uri)
|
70
|
+
|
71
|
+
if unescape
|
72
|
+
JSON.parse(data.os_unescape)
|
73
|
+
else
|
74
|
+
JSON.parse(data)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
# Dispatches a request to a given URI with optional POST data. If a
|
81
|
+
# request's connection has specified HMAC-SHA1 authentication, OAuth
|
82
|
+
# parameters and signature are appended to the request.
|
83
|
+
def dispatch(uri, post_data = nil)
|
84
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
85
|
+
|
86
|
+
if post_data
|
87
|
+
if @connection.container[:use_request_body_hash]
|
88
|
+
hash = request_body_hash(post_data)
|
89
|
+
|
90
|
+
# Appends the hash parameter
|
91
|
+
query = uri.query
|
92
|
+
if query
|
93
|
+
uri.query = query + '&oauth_body_hash=' + hash
|
94
|
+
else
|
95
|
+
uri.query = 'oauth_body_hash=' + hash
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
req = Net::HTTP::Post.new(uri.request_uri)
|
100
|
+
if @connection.container[:post_body_signing]
|
101
|
+
req.set_form_data(post_data)
|
102
|
+
end
|
103
|
+
else
|
104
|
+
req = Net::HTTP::Get.new(uri.request_uri)
|
105
|
+
end
|
106
|
+
|
107
|
+
@connection.sign!(http, req)
|
108
|
+
|
109
|
+
if post_data
|
110
|
+
resp = http.post(req.path, post_data, {'Content-type' =>
|
111
|
+
@connection.container[:content_type]})
|
112
|
+
check_for_json_error!(resp)
|
113
|
+
else
|
114
|
+
resp = http.get(req.path)
|
115
|
+
check_for_http_error!(resp)
|
116
|
+
end
|
117
|
+
|
118
|
+
return resp.body
|
119
|
+
end
|
120
|
+
|
121
|
+
# Generates a request body hash as outlined by the OAuth spec:
|
122
|
+
# http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/drafts/1/spec.html
|
123
|
+
def request_body_hash(post_data)
|
124
|
+
CGI.escape(Base64.encode64(Digest::SHA1.digest(post_data)).rstrip)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Checks the response object's status code. If the response is is
|
128
|
+
# unauthorized, an exception is raised.
|
129
|
+
def check_for_http_error!(resp)
|
130
|
+
if !resp.kind_of?(Net::HTTPSuccess)
|
131
|
+
if resp.is_a?(Net::HTTPUnauthorized)
|
132
|
+
raise AuthException.new('The request lacked proper authentication ' +
|
133
|
+
'credentials to retrieve data.')
|
134
|
+
else
|
135
|
+
resp.value
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Checks the JSON response for a status code. If a code is present an
|
141
|
+
# exception is raised.
|
142
|
+
def check_for_json_error!(resp)
|
143
|
+
json = JSON.parse(resp.body)
|
144
|
+
if json.is_a?(Hash) && json.has_key?('code') && json.has_key?('message')
|
145
|
+
rc = json['code']
|
146
|
+
message = json['message']
|
147
|
+
case rc
|
148
|
+
when 401:
|
149
|
+
raise AuthException.new('The request lacked proper authentication ' +
|
150
|
+
'credentials to retrieve data.')
|
151
|
+
else
|
152
|
+
raise RequestException.new("The request returned an unsupported " +
|
153
|
+
"status code: #{rc} #{message}.")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Provides a wrapper for a single RPC request to an OpenSocial endpoint,
|
160
|
+
# composed of one or more individual requests.
|
161
|
+
#
|
162
|
+
# The RpcRequest class wraps an HTTP request to an OpenSocial endpoint for
|
163
|
+
# social data. An RpcRequest is intended to be used as a container for one
|
164
|
+
# or more Requests (or Fetch*Requests), but may also be used with a manually
|
165
|
+
# constructed post body. The RpcRequest class uses OAuth signing inherited
|
166
|
+
# from the Request class, when appropriate OAuth credentials are supplied.
|
167
|
+
#
|
168
|
+
|
169
|
+
|
170
|
+
class RpcRequest < Request
|
171
|
+
|
172
|
+
# Defines the requests sent in the single RpcRequest. The requests are
|
173
|
+
# stored a key/value pairs.
|
174
|
+
attr_accessor :requests
|
175
|
+
|
176
|
+
# Initializes an RpcRequest with the supplied connection and an optional
|
177
|
+
# hash of requests.
|
178
|
+
def initialize(connection, requests = {})
|
179
|
+
@connection = connection
|
180
|
+
|
181
|
+
@requests = requests
|
182
|
+
end
|
183
|
+
|
184
|
+
# Adds one or more requests to the RpcRequest. Expects a hash of key/value
|
185
|
+
# pairs (key used to refernece the data when it returns => the Request).
|
186
|
+
def add(requests = {})
|
187
|
+
@requests.merge!(requests)
|
188
|
+
end
|
189
|
+
|
190
|
+
# Sends an RpcRequest to the OpenSocial endpoint by constructing JSON for
|
191
|
+
# the POST body and delegating the request to send_request. If an
|
192
|
+
# RpcRequest is sent with an empty list of requests, an exception is
|
193
|
+
# thrown. The response JSON is optionally unescaped (defaulting to true).
|
194
|
+
def send(unescape = true)
|
195
|
+
if @requests.length == 0
|
196
|
+
raise RequestException.new('RPC request requires a non-empty hash ' +
|
197
|
+
'of requests in order to be sent.')
|
198
|
+
end
|
199
|
+
|
200
|
+
json = send_request(request_json, unescape)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Sends an RpcRequest to the OpenSocial endpoint by constructing the
|
204
|
+
# service URI and dispatching the request. This method is public so that
|
205
|
+
# an arbitrary POST body can be constructed and sent. The response JSON is
|
206
|
+
# optionally unescaped.
|
207
|
+
def send_request(post_data, unescape)
|
208
|
+
uri = @connection.service_uri(@connection.container[:rpc], nil, nil, nil)
|
209
|
+
data = dispatch(uri, post_data)
|
210
|
+
|
211
|
+
parse_response(data, unescape)
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
|
216
|
+
# Parses the response JSON. First, the JSON is unescaped, when specified,
|
217
|
+
# then for each element specified in @requests, the appropriate response
|
218
|
+
# is selected from the larger JSON response. This element is then delegated
|
219
|
+
# to the appropriate class to be turned into a native object (Person,
|
220
|
+
# Activity, etc.)
|
221
|
+
def parse_response(response, unescape)
|
222
|
+
if unescape
|
223
|
+
parsed = JSON.parse(response.os_unescape)
|
224
|
+
else
|
225
|
+
parsed = JSON.parse(response)
|
226
|
+
end
|
227
|
+
keyed_by_id = key_by_id(parsed)
|
228
|
+
|
229
|
+
native_objects = {}
|
230
|
+
@requests.each_pair do |key, request|
|
231
|
+
native_object = request.parse_rpc_response(keyed_by_id[key.to_s])
|
232
|
+
native_objects.merge!({key => native_object})
|
233
|
+
end
|
234
|
+
|
235
|
+
return native_objects
|
236
|
+
end
|
237
|
+
|
238
|
+
# Constructs a hash of the elements in data referencing each element
|
239
|
+
# by its 'id' attribute.
|
240
|
+
def key_by_id(data)
|
241
|
+
keyed_by_id = {}
|
242
|
+
for entry in data
|
243
|
+
keyed_by_id.merge!({entry['id'] => entry})
|
244
|
+
end
|
245
|
+
|
246
|
+
return keyed_by_id
|
247
|
+
end
|
248
|
+
|
249
|
+
# Modifies each request in an outgoing RpcRequest so that its key is set
|
250
|
+
# to the value specified when added to the RpcRequest.
|
251
|
+
def request_json
|
252
|
+
keyed_requests = []
|
253
|
+
@requests.each_pair do |key, request|
|
254
|
+
request.key = key
|
255
|
+
keyed_requests << request
|
256
|
+
end
|
257
|
+
|
258
|
+
return keyed_requests.to_json
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
# An exception thrown when a request cannot return data.
|
263
|
+
#
|
264
|
+
|
265
|
+
|
266
|
+
class RequestException < RuntimeError; end
|
267
|
+
|
268
|
+
# An exception thrown when a request returns a 401 unauthorized status.
|
269
|
+
#
|
270
|
+
|
271
|
+
|
272
|
+
class AuthException < RuntimeError; end
|
273
|
+
end
|