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