tin_can_api 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +12 -0
- data/lib/tin_can_api/about.rb +15 -0
- data/lib/tin_can_api/activity.rb +41 -0
- data/lib/tin_can_api/activity_definition.rb +139 -0
- data/lib/tin_can_api/agent.rb +44 -0
- data/lib/tin_can_api/agent_account.rb +33 -0
- data/lib/tin_can_api/attachment.rb +64 -0
- data/lib/tin_can_api/client.rb +402 -0
- data/lib/tin_can_api/context.rb +54 -0
- data/lib/tin_can_api/context_activities.rb +102 -0
- data/lib/tin_can_api/documents/activity_profile_document.rb +15 -0
- data/lib/tin_can_api/documents/agent_profile_document.rb +15 -0
- data/lib/tin_can_api/documents/document.rb +20 -0
- data/lib/tin_can_api/documents/state_document.rb +15 -0
- data/lib/tin_can_api/enum.rb +42 -0
- data/lib/tin_can_api/errors.rb +9 -0
- data/lib/tin_can_api/group.rb +37 -0
- data/lib/tin_can_api/interaction_component.rb +32 -0
- data/lib/tin_can_api/interaction_type.rb +58 -0
- data/lib/tin_can_api/lrs_response.rb +14 -0
- data/lib/tin_can_api/query_result_format.rb +6 -0
- data/lib/tin_can_api/remote_lrs.rb +15 -0
- data/lib/tin_can_api/result.rb +45 -0
- data/lib/tin_can_api/score.rb +39 -0
- data/lib/tin_can_api/statement.rb +53 -0
- data/lib/tin_can_api/statement_ref.rb +31 -0
- data/lib/tin_can_api/statements/statements_base.rb +70 -0
- data/lib/tin_can_api/statements_query.rb +42 -0
- data/lib/tin_can_api/statements_query_v095.rb +42 -0
- data/lib/tin_can_api/statements_result.rb +17 -0
- data/lib/tin_can_api/sub_statement.rb +19 -0
- data/lib/tin_can_api/tcapi_version.rb +27 -0
- data/lib/tin_can_api/verb.rb +35 -0
- data/lib/tin_can_api/version.rb +4 -0
- data/lib/tin_can_api.rb +37 -0
- data/spec/fixtures/about.json +10 -0
- data/spec/fixtures/statement.json +33 -0
- data/spec/spec_helper.rb +106 -0
- data/spec/support/helpers.rb +43 -0
- data/spec/tin_can_api/activity_definition_spec.rb +37 -0
- data/spec/tin_can_api/activity_spec.rb +23 -0
- data/spec/tin_can_api/agent_account_spec.rb +13 -0
- data/spec/tin_can_api/agent_spec.rb +24 -0
- data/spec/tin_can_api/attachment_spec.rb +26 -0
- data/spec/tin_can_api/client_spec.rb +44 -0
- data/spec/tin_can_api/context_activities_spec.rb +57 -0
- data/spec/tin_can_api/context_spec.rb +32 -0
- data/spec/tin_can_api/group_spec.rb +15 -0
- data/spec/tin_can_api/interaction_component_spec.rb +18 -0
- data/spec/tin_can_api/result_spec.rb +26 -0
- data/spec/tin_can_api/score_spec.rb +12 -0
- data/spec/tin_can_api/statement_ref_spec.rb +19 -0
- data/spec/tin_can_api/statement_spec.rb +57 -0
- data/spec/tin_can_api/sub_statement_spec.rb +30 -0
- data/spec/tin_can_api/verb_spec.rb +17 -0
- data/tin_can_api.gemspec +30 -0
- metadata +238 -0
@@ -0,0 +1,402 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'faraday'
|
3
|
+
require 'addressable/uri'
|
4
|
+
require 'tin_can_api/tcapi_version'
|
5
|
+
module TinCanApi
|
6
|
+
# Class used to communicate with a TCAPI endpoint synchronously
|
7
|
+
class Client
|
8
|
+
include TinCanApi::TCAPIVersion
|
9
|
+
|
10
|
+
VALID_PARAMS = %w(end_point user_name password version)
|
11
|
+
|
12
|
+
attr_accessor :end_point, :user_name, :password, :version
|
13
|
+
|
14
|
+
def initialize(options={}, &block)
|
15
|
+
setup_options(options)
|
16
|
+
yield_or_eval(&block) if block_given?
|
17
|
+
@version ||= latest_version
|
18
|
+
end
|
19
|
+
|
20
|
+
def about
|
21
|
+
response = connection.get("#{path}about")
|
22
|
+
LrsResponse.new do |lrs|
|
23
|
+
lrs.status = response.status
|
24
|
+
if response.status== 200
|
25
|
+
lrs.content = About.new(json: response.body)
|
26
|
+
lrs.success = true
|
27
|
+
else
|
28
|
+
lrs.success = false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def save_statement(statement)
|
34
|
+
# TODO: Complete this
|
35
|
+
if statement.id
|
36
|
+
response = connection.put do |req|
|
37
|
+
req.url("#{path}statements")
|
38
|
+
req.headers['Content-Type'] = 'application/json'
|
39
|
+
req.params.merge!({'statementId' => statement.id})
|
40
|
+
req.body = statement.serialize(latest_version).to_json
|
41
|
+
end
|
42
|
+
else
|
43
|
+
response = connection.post do |req|
|
44
|
+
req.url("#{path}statements")
|
45
|
+
req.headers['Content-Type'] = 'application/json'
|
46
|
+
req.body = statement.serialize(latest_version).to_json
|
47
|
+
end
|
48
|
+
end
|
49
|
+
LrsResponse.new do |lrs|
|
50
|
+
lrs.status = response.status
|
51
|
+
lrs.content = statement
|
52
|
+
if response.status == 200
|
53
|
+
statement.id = JSON.parse(response.body).first
|
54
|
+
lrs.success = true
|
55
|
+
elsif response.status == 204
|
56
|
+
lrs.success = true
|
57
|
+
else
|
58
|
+
lrs.success = false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def save_statements(statements)
|
64
|
+
# TODO: Complete this
|
65
|
+
if statements.empty?
|
66
|
+
return LrsResponse.new do |lrs|
|
67
|
+
lrs.success = true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
response = connection.post do |req|
|
71
|
+
req.url("#{path}statements")
|
72
|
+
req.headers['Content-Type'] = 'application/json'
|
73
|
+
req.body = statements.map {|s| s.serialize(latest_version)}.to_json
|
74
|
+
end
|
75
|
+
LrsResponse.new do |lrs|
|
76
|
+
lrs.status = response.status
|
77
|
+
if response.status == 200
|
78
|
+
lrs.content = statements
|
79
|
+
ids = JSON.parse(response.body)
|
80
|
+
statements.each_with_index do |statement, index|
|
81
|
+
statement.id = ids[index]
|
82
|
+
end
|
83
|
+
lrs.success = true
|
84
|
+
else
|
85
|
+
lrs.success = false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def retrieve_statement(id)
|
91
|
+
get_statement(id, 'statementId')
|
92
|
+
end
|
93
|
+
|
94
|
+
def retrieve_voided_statement(id)
|
95
|
+
param_name = version == TCAPIVersion.V095 ? 'statementId' : 'voidedStatementId'
|
96
|
+
get_statement(id, param_name)
|
97
|
+
end
|
98
|
+
|
99
|
+
def query_statements(statement_query)
|
100
|
+
# TODO: Complete this
|
101
|
+
query = statement_query
|
102
|
+
unless query
|
103
|
+
query = version == TCAPIVersion::V095 ? StatementsQueryV095.new : StatementsQuery.new
|
104
|
+
end
|
105
|
+
# Error if the query parameters don't match the LRS version
|
106
|
+
raise Errors::IncompatibleTCAPIVersion, "Attempted to issue #{version} query using a #{query.version} set of query parameters." unless version == query.version
|
107
|
+
|
108
|
+
response = connection.get do |req|
|
109
|
+
req.url("#{path}statements")
|
110
|
+
req.params.merge!(query.parameter_map)
|
111
|
+
end
|
112
|
+
LrsResponse.new do |lrs|
|
113
|
+
lrs.status = response.status
|
114
|
+
if response.status == 200
|
115
|
+
# TODO: FIX THIS
|
116
|
+
lrs.success = true
|
117
|
+
lrs.content = StatementsResult.new(json: response.body)
|
118
|
+
else
|
119
|
+
lrs.success = false
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def more_statements(more_url)
|
125
|
+
# TODO: Complete this
|
126
|
+
# more_url is relative to the endpoint's server root
|
127
|
+
response = connection.get do |req|
|
128
|
+
req.url("#{path}#{more_url}")
|
129
|
+
end
|
130
|
+
LrsResponse.new do |lrs|
|
131
|
+
lrs.status = response.status
|
132
|
+
if response.status == 200
|
133
|
+
# TODO: FIX THIS
|
134
|
+
lrs.success = true
|
135
|
+
lrs.content = StatementsResult.new(json: response.body)
|
136
|
+
else
|
137
|
+
lrs.success = false
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def retrieve_state_ids(activity, agent, registration)
|
143
|
+
# TODO: Complete this
|
144
|
+
query_params = {
|
145
|
+
'activityId' => activity.id,
|
146
|
+
'agent' => agent.serialize(version).to_json
|
147
|
+
}
|
148
|
+
query_params['registration'] = registration if registration
|
149
|
+
get_profile_keys('activities/state', query_params)
|
150
|
+
end
|
151
|
+
|
152
|
+
def retrieve_state(id, activity, agent, registration)
|
153
|
+
# TODO: Complete this
|
154
|
+
query_params = {
|
155
|
+
'stateId' => id,
|
156
|
+
'activityId' => activity.id,
|
157
|
+
'agent' => agent.serialize(version).to_json
|
158
|
+
}
|
159
|
+
document = StateDocument.new do |sd|
|
160
|
+
sd.id = id
|
161
|
+
sd.activity = activity
|
162
|
+
sd.agent = agent
|
163
|
+
end
|
164
|
+
lrs_response = get_document('activities/state', query_params, document)
|
165
|
+
if lrs_response.status == 200
|
166
|
+
lrs_response.content = document
|
167
|
+
end
|
168
|
+
lrs_response
|
169
|
+
end
|
170
|
+
|
171
|
+
def save_state(state)
|
172
|
+
# TODO: Complete this
|
173
|
+
query_params = {
|
174
|
+
'stateId' => state.id,
|
175
|
+
'activityId' => state.activity.id,
|
176
|
+
'agent' => state.agent.serialize(version).to_json
|
177
|
+
}
|
178
|
+
save_document('activities/state', query_params, state)
|
179
|
+
end
|
180
|
+
|
181
|
+
def delete_state(state)
|
182
|
+
# TODO: Complete this
|
183
|
+
query_params = {
|
184
|
+
'stateId' => state.id,
|
185
|
+
'activityId' => state.activity.id,
|
186
|
+
'agent' => state.agent.serialize(version).to_json
|
187
|
+
}
|
188
|
+
query_params['registration'] = state.registration if state.registration
|
189
|
+
delete_document('activities/state', query_params)
|
190
|
+
end
|
191
|
+
|
192
|
+
def clear_state(activity, agent, registration)
|
193
|
+
# TODO: Complete this
|
194
|
+
query_params = {
|
195
|
+
'activityId' => activity.id,
|
196
|
+
'agent' => agent.serialize(version).to_json
|
197
|
+
}
|
198
|
+
query_params['registration'] = registration if registration
|
199
|
+
delete_document('activities/state', query_params)
|
200
|
+
end
|
201
|
+
|
202
|
+
def retrieve_activity_profile_ids(activity)
|
203
|
+
# TODO: Complete this
|
204
|
+
query_params = {
|
205
|
+
'activityId' => activity.id
|
206
|
+
}
|
207
|
+
get_profile_keys('activities/profile', query_params)
|
208
|
+
end
|
209
|
+
|
210
|
+
def retrieve_activity_profile(id, activity)
|
211
|
+
# TODO: Complete this
|
212
|
+
query_params = {
|
213
|
+
'profileId' => id,
|
214
|
+
'activityId' => activity.id,
|
215
|
+
}
|
216
|
+
document = ActivityProfileDocument.new do |apd|
|
217
|
+
apd.id = id
|
218
|
+
apd.activity = activity
|
219
|
+
end
|
220
|
+
lrs_response = get_document('activities/profile', query_params, document)
|
221
|
+
if lrs_response.status == 200
|
222
|
+
lrs_response.content = document
|
223
|
+
end
|
224
|
+
lrs_response
|
225
|
+
end
|
226
|
+
|
227
|
+
def save_activity_profile(profile)
|
228
|
+
# TODO: Complete this
|
229
|
+
query_params = {
|
230
|
+
'profileId' => profile.id,
|
231
|
+
'activityId' => profile.activity.id,
|
232
|
+
}
|
233
|
+
save_document('activities/profile', query_params, profile)
|
234
|
+
end
|
235
|
+
|
236
|
+
def delete_activity_profile(profile)
|
237
|
+
# TODO: Complete this
|
238
|
+
query_params = {
|
239
|
+
'profileId' => profile.id,
|
240
|
+
'activityId' => profile.activity.id,
|
241
|
+
}
|
242
|
+
delete_document('activities/profile', query_params)
|
243
|
+
end
|
244
|
+
|
245
|
+
def retrieve_agent_profile_ids(agent)
|
246
|
+
# TODO: Complete this
|
247
|
+
query_params = {
|
248
|
+
'agent' => agent.serialize(version).to_json
|
249
|
+
}
|
250
|
+
get_profile_keys('agents/profile', query_params)
|
251
|
+
end
|
252
|
+
|
253
|
+
def retrieve_agent_profile(id, agent)
|
254
|
+
# TODO: Complete this
|
255
|
+
query_params = {
|
256
|
+
'profileId' => id,
|
257
|
+
'agent' => agent.serialize(version).to_json
|
258
|
+
}
|
259
|
+
document = AgentProfileDocument.new do |apd|
|
260
|
+
apd.id = id
|
261
|
+
apd.agent = agent
|
262
|
+
end
|
263
|
+
lrs_response = get_document('agents/profile', query_params, document)
|
264
|
+
if lrs_response.status == 200
|
265
|
+
lrs_response.content = document
|
266
|
+
end
|
267
|
+
lrs_response
|
268
|
+
end
|
269
|
+
|
270
|
+
def save_agent_profile(profile)
|
271
|
+
# TODO: Complete this
|
272
|
+
query_params = {
|
273
|
+
'profileId' => profile.id,
|
274
|
+
'agent' => profile.agent.serialize(version).to_json
|
275
|
+
}
|
276
|
+
save_document('agents/profile', query_params, profile)
|
277
|
+
end
|
278
|
+
|
279
|
+
def delete_agent_profile(profile)
|
280
|
+
# TODO: Complete this
|
281
|
+
query_params = {
|
282
|
+
'profileId' => profile.id,
|
283
|
+
'agent' => profile.agent.serialize(version).to_json
|
284
|
+
}
|
285
|
+
delete_document('agents/profile', query_params)
|
286
|
+
end
|
287
|
+
|
288
|
+
private
|
289
|
+
|
290
|
+
def setup_options(options={})
|
291
|
+
options.each_pair do |key, value|
|
292
|
+
if value && VALID_PARAMS.include?(key.to_s)
|
293
|
+
instance_variable_set("@#{key}", value)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def yield_or_eval(&block)
|
299
|
+
return unless block
|
300
|
+
block.arity < 1 ? instance_eval(&block) : block[self]
|
301
|
+
end
|
302
|
+
|
303
|
+
def uri
|
304
|
+
@uri ||= Addressable::URI.parse(end_point)
|
305
|
+
end
|
306
|
+
|
307
|
+
def path
|
308
|
+
@path ||= uri.path
|
309
|
+
@path += '/' unless @path.end_with?('/')
|
310
|
+
@path
|
311
|
+
end
|
312
|
+
|
313
|
+
def connection
|
314
|
+
base_url = "#{uri.scheme}://#{uri.host}"
|
315
|
+
base_url = "#{base_url}:#{uri.port}" if uri.port
|
316
|
+
@connection ||= Faraday.new(:url => base_url) do |faraday|
|
317
|
+
faraday.request :url_encoded # form-encode POST params
|
318
|
+
faraday.response :logger # log requests to STDOUT
|
319
|
+
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
320
|
+
faraday.headers['X-Experience-API-Version'] = version.to_s
|
321
|
+
faraday.basic_auth(user_name, password)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def get_statement(id, parameter)
|
326
|
+
response = connection.get do |req|
|
327
|
+
req.url("#{path}statements")
|
328
|
+
req.headers['Content-Type'] = 'application/json'
|
329
|
+
req.params.merge!({parameter => id})
|
330
|
+
end
|
331
|
+
LrsResponse.new do |lrs|
|
332
|
+
lrs.status = response.status
|
333
|
+
if response.status== 200
|
334
|
+
lrs.content = Statement.new(json: response.body)
|
335
|
+
lrs.success = true
|
336
|
+
else
|
337
|
+
lrs.success = false
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
def get_document(resource, params, document)
|
343
|
+
response = connection.get do |req|
|
344
|
+
req.url("#{path}#{resource}")
|
345
|
+
req.params.merge!(params)
|
346
|
+
end
|
347
|
+
LrsResponse.new do |lrs|
|
348
|
+
lrs.status = response.status
|
349
|
+
if response.status == 200
|
350
|
+
lrs.success = true
|
351
|
+
# TODO FIX THIS
|
352
|
+
elsif response.status == 404
|
353
|
+
lrs.success = true
|
354
|
+
else
|
355
|
+
lrs.success = false
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
def delete_document(resource, params)
|
361
|
+
response = connection.delete do |req|
|
362
|
+
req.url("#{path}#{resource}")
|
363
|
+
req.params.merge!(params)
|
364
|
+
end
|
365
|
+
LrsResponse.new do |lrs|
|
366
|
+
lrs.status = response.status
|
367
|
+
if response.status == 204
|
368
|
+
lrs.success = true
|
369
|
+
else
|
370
|
+
lrs.success = false
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
def save_document(resource, params, document)
|
376
|
+
# TODO: Complete this
|
377
|
+
response = connection.put do |req|
|
378
|
+
req.url("#{path}#{resource}")
|
379
|
+
req.headers['Content-Type'] = 'application/json'
|
380
|
+
req.headers['If-Match'] = document.etag if document.etag
|
381
|
+
req.params.merge!(params)
|
382
|
+
req.body = document.content
|
383
|
+
end
|
384
|
+
LrsResponse.new do |lrs|
|
385
|
+
lrs.status = response.status
|
386
|
+
if response.status == 204
|
387
|
+
lrs.success = true
|
388
|
+
else
|
389
|
+
lrs.success = false
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
def get_profile_keys(resource, params)
|
395
|
+
# TODO FIX THIS
|
396
|
+
connection.get do |req|
|
397
|
+
req.url("#{path}#{resource}")
|
398
|
+
req.params.merge!(params)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module TinCanApi
|
3
|
+
# Context Class Description
|
4
|
+
class Context
|
5
|
+
|
6
|
+
attr_accessor :registration, :instructor, :team, :context_activities, :revision
|
7
|
+
attr_accessor :platform, :language, :statement, :extensions
|
8
|
+
|
9
|
+
def initialize(options={}, &block)
|
10
|
+
json = options.fetch(:json, nil)
|
11
|
+
if json
|
12
|
+
attributes = JSON.parse(json)
|
13
|
+
self.registration = attributes['registration'] if attributes['registration']
|
14
|
+
self.instructor = TinCanApi::Agent.new(json: attributes['instructor'].to_json) if attributes['instructor']
|
15
|
+
self.team = TinCanApi::Agent.new(json: attributes['team'].to_json) if attributes['team']
|
16
|
+
self.context_activities = TinCanApi::ContextActivities.new(json: attributes['contextActivities'].to_json) if attributes['contextActivities']
|
17
|
+
self.revision = attributes['revision'] if attributes['revision']
|
18
|
+
self.platform = attributes['platform'] if attributes['platform']
|
19
|
+
self.language = attributes['language'] if attributes['language']
|
20
|
+
self.statement = TinCanApi::StatementRef.new(json: attributes['statement'].to_json) if attributes['statement']
|
21
|
+
self.extensions = attributes['extensions'] if attributes['extensions']
|
22
|
+
else
|
23
|
+
self.registration = options.fetch(:registration, nil)
|
24
|
+
self.instructor = options.fetch(:instructor, nil)
|
25
|
+
self.team = options.fetch(:team, nil)
|
26
|
+
self.context_activities = options.fetch(:context_activities, nil)
|
27
|
+
self.revision = options.fetch(:revision, nil)
|
28
|
+
self.platform = options.fetch(:platform, nil)
|
29
|
+
self.language = options.fetch(:language, nil)
|
30
|
+
self.extensions = options.fetch(:extensions, nil)
|
31
|
+
|
32
|
+
if block_given?
|
33
|
+
block[self]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def serialize(version)
|
39
|
+
node = {}
|
40
|
+
node['registration'] = registration if registration
|
41
|
+
node['instructor'] = instructor.serialize(version) if instructor
|
42
|
+
node['team'] = team.serialize(version) if team
|
43
|
+
node['contextActivities'] = context_activities.serialize(version) if context_activities
|
44
|
+
node['revision'] = revision if revision
|
45
|
+
node['platform'] = platform if platform
|
46
|
+
node['language'] = language if language
|
47
|
+
node['statement'] = statement.serialize(version) if statement
|
48
|
+
node['extensions'] = extensions if extensions
|
49
|
+
|
50
|
+
node
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module TinCanApi
|
3
|
+
# ContextActivities Model class
|
4
|
+
class ContextActivities
|
5
|
+
|
6
|
+
attr_accessor :parent, :grouping, :other, :category
|
7
|
+
|
8
|
+
def initialize(options={}, &block)
|
9
|
+
json = options.fetch(:json, nil)
|
10
|
+
if json
|
11
|
+
attributes = JSON.parse(json)
|
12
|
+
if attributes['parent']
|
13
|
+
if attributes['parent'].is_a?(Array)
|
14
|
+
self.parent = attributes['parent'].map {|element| Activity.new(json: element.to_json)}
|
15
|
+
else
|
16
|
+
self.parent = [Activity.new(json: attributes['parent'].to_json)]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if attributes['grouping']
|
21
|
+
if attributes['grouping'].is_a?(Array)
|
22
|
+
self.grouping = attributes['grouping'].map {|element| Activity.new(json: element.to_json)}
|
23
|
+
else
|
24
|
+
self.grouping = [Activity.new(json: attributes['grouping'].to_json)]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if attributes['other']
|
29
|
+
if attributes['other'].is_a?(Array)
|
30
|
+
self.other = attributes['other'].map {|element| Activity.new(json: element.to_json)}
|
31
|
+
else
|
32
|
+
self.other = [Activity.new(json: attributes['other'].to_json)]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
if attributes['category']
|
37
|
+
if attributes['category'].is_a?(Array)
|
38
|
+
self.category = attributes['category'].map {|element| Activity.new(json: element.to_json)}
|
39
|
+
else
|
40
|
+
self.category = [Activity.new(json: attributes['category'].to_json)]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
else
|
44
|
+
self.parent = options.fetch(:parent, nil)
|
45
|
+
self.grouping = options.fetch(:grouping, nil)
|
46
|
+
self.other = options.fetch(:other, nil)
|
47
|
+
self.category = options.fetch(:category, nil)
|
48
|
+
|
49
|
+
if block_given?
|
50
|
+
block[self]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def serialize(version)
|
56
|
+
node = {}
|
57
|
+
if parent && parent.any?
|
58
|
+
if version == TinCanApi::TCAPIVersion::V095 && parent.size > 1
|
59
|
+
raise TinCanApi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support lists of activities (parent)"
|
60
|
+
end
|
61
|
+
if version == TinCanApi::TCAPIVersion::V095
|
62
|
+
node['parent'] = parent.first.serialize(version)
|
63
|
+
else
|
64
|
+
node['parent'] = parent.map {|element| element.serialize(version)}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
if grouping && grouping.any?
|
69
|
+
if version == TinCanApi::TCAPIVersion::V095 && grouping.size > 1
|
70
|
+
raise TinCanApi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support lists of activities (grouping)"
|
71
|
+
end
|
72
|
+
if version == TinCanApi::TCAPIVersion::V095
|
73
|
+
node['grouping'] = grouping.first.serialize(version)
|
74
|
+
else
|
75
|
+
node['grouping'] = grouping.map {|element| element.serialize(version)}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
if other && other.any?
|
80
|
+
if version == TinCanApi::TCAPIVersion::V095 && other.size > 1
|
81
|
+
raise TinCanApi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support lists of activities (other)"
|
82
|
+
end
|
83
|
+
if version == TinCanApi::TCAPIVersion::V095
|
84
|
+
node['other'] = other.first.serialize(version)
|
85
|
+
else
|
86
|
+
node['other'] = other.map {|element| element.serialize(version)}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
if category && category.any?
|
91
|
+
if version.ordinal <= TinCanApi::TCAPIVersion::V100.ordinal
|
92
|
+
node['category'] = category.map {|element| element.serialize(version)}
|
93
|
+
else
|
94
|
+
raise TinCanApi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support the category context activity"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
node
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module TinCanApi
|
3
|
+
module Documents
|
4
|
+
class Document
|
5
|
+
|
6
|
+
attr_accessor :id, :etag, :timestamp, :content_type, :content
|
7
|
+
|
8
|
+
def initialize(&block)
|
9
|
+
if block_given?
|
10
|
+
block[self]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
require_relative 'activity_profile_document'
|
19
|
+
require_relative 'agent_profile_document'
|
20
|
+
require_relative 'state_document'
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module TinCanApi
|
3
|
+
module Enum
|
4
|
+
CONVERT_PROC = Proc.new do
|
5
|
+
@values = constants.collect{|c| const_get(c)}.freeze
|
6
|
+
|
7
|
+
@values.each_with_index do |value, idx|
|
8
|
+
the_symbol = constants.find{|c| const_get(c) == value}
|
9
|
+
sig = class << value ; self end
|
10
|
+
sig.send :define_method, :name, proc{the_symbol}
|
11
|
+
sig.send :define_method, :ordinal, proc{idx}
|
12
|
+
|
13
|
+
if value.is_a? Hash
|
14
|
+
value.each do |k, v|
|
15
|
+
sig.send :define_method, k, (v.is_a?(Proc) ? v : proc{v})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
value.freeze
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
alias :value_of :const_get
|
23
|
+
end
|
24
|
+
|
25
|
+
module_function
|
26
|
+
def each
|
27
|
+
@values.each { |v| yield v }
|
28
|
+
end
|
29
|
+
def values
|
30
|
+
@values
|
31
|
+
end
|
32
|
+
extend Enumerable
|
33
|
+
|
34
|
+
freeze
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.extended extending_obj
|
38
|
+
extending_obj.module_eval &CONVERT_PROC
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|