growthtribe_xapi 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/.github/workflows/ci.yml +28 -0
- data/CHANGELOG.md +2 -0
- data/CONTRIBUTING.md +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +78 -0
- data/LICENSE.txt +22 -0
- data/README.md +299 -0
- data/Rakefile +12 -0
- data/bin/rspec +29 -0
- data/lib/growthtribe_xapi.rb +2 -0
- data/lib/xapi.rb +224 -0
- data/lib/xapi/about.rb +15 -0
- data/lib/xapi/activity.rb +37 -0
- data/lib/xapi/activity_definition.rb +131 -0
- data/lib/xapi/agent.rb +44 -0
- data/lib/xapi/agent_account.rb +33 -0
- data/lib/xapi/attachment.rb +64 -0
- data/lib/xapi/context.rb +54 -0
- data/lib/xapi/context_activities.rb +102 -0
- data/lib/xapi/documents/activity_profile_document.rb +15 -0
- data/lib/xapi/documents/agent_profile_document.rb +15 -0
- data/lib/xapi/documents/document.rb +20 -0
- data/lib/xapi/documents/state_document.rb +15 -0
- data/lib/xapi/enum.rb +42 -0
- data/lib/xapi/errors.rb +9 -0
- data/lib/xapi/group.rb +37 -0
- data/lib/xapi/interaction_component.rb +32 -0
- data/lib/xapi/interaction_type.rb +58 -0
- data/lib/xapi/lrs_response.rb +14 -0
- data/lib/xapi/query_result_format.rb +6 -0
- data/lib/xapi/remote_lrs.rb +416 -0
- data/lib/xapi/result.rb +46 -0
- data/lib/xapi/score.rb +39 -0
- data/lib/xapi/statement.rb +53 -0
- data/lib/xapi/statement_ref.rb +31 -0
- data/lib/xapi/statements/statements_base.rb +70 -0
- data/lib/xapi/statements_query.rb +42 -0
- data/lib/xapi/statements_query_v095.rb +42 -0
- data/lib/xapi/statements_result.rb +17 -0
- data/lib/xapi/sub_statement.rb +19 -0
- data/lib/xapi/tcapi_version.rb +27 -0
- data/lib/xapi/team.rb +44 -0
- data/lib/xapi/team_analytics_query.rb +36 -0
- data/lib/xapi/verb.rb +35 -0
- data/lib/xapi/version.rb +4 -0
- data/spec/fixtures/about.json +10 -0
- data/spec/fixtures/statement.json +33 -0
- data/spec/spec_helper.rb +107 -0
- data/spec/support/helpers.rb +60 -0
- data/spec/xapi/activity_definition_spec.rb +37 -0
- data/spec/xapi/activity_spec.rb +23 -0
- data/spec/xapi/agent_account_spec.rb +13 -0
- data/spec/xapi/agent_spec.rb +24 -0
- data/spec/xapi/attachment_spec.rb +26 -0
- data/spec/xapi/context_activities_spec.rb +57 -0
- data/spec/xapi/context_spec.rb +32 -0
- data/spec/xapi/group_spec.rb +15 -0
- data/spec/xapi/interaction_component_spec.rb +18 -0
- data/spec/xapi/remote_lrs_spec.rb +46 -0
- data/spec/xapi/result_spec.rb +24 -0
- data/spec/xapi/score_spec.rb +12 -0
- data/spec/xapi/statement_ref_spec.rb +19 -0
- data/spec/xapi/statement_spec.rb +73 -0
- data/spec/xapi/sub_statement_spec.rb +30 -0
- data/spec/xapi/verb_spec.rb +17 -0
- data/xapi.gemspec +30 -0
- metadata +244 -0
data/lib/xapi/agent.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'xapi/tcapi_version'
|
3
|
+
module Xapi
|
4
|
+
# Agent model class
|
5
|
+
class Agent
|
6
|
+
|
7
|
+
attr_accessor :name, :mbox, :mbox_sha1_sum, :open_id, :account, :object_type
|
8
|
+
|
9
|
+
def initialize(options={}, &block)
|
10
|
+
@object_type = 'Agent'
|
11
|
+
json = options.fetch(:json, nil)
|
12
|
+
if json
|
13
|
+
attributes = JSON.parse(json)
|
14
|
+
self.name = attributes['name'] if attributes['name']
|
15
|
+
self.mbox = attributes['mbox'] if attributes['mbox']
|
16
|
+
self.mbox_sha1_sum = attributes['mbox_sha1sum'] if attributes['mbox_sha1sum']
|
17
|
+
self.open_id = attributes['openid'] if attributes['openid']
|
18
|
+
self.account = AgentAccount.new(json: attributes['account'].to_json) if attributes['account']
|
19
|
+
else
|
20
|
+
self.name = options.fetch(:name, nil)
|
21
|
+
self.mbox = options.fetch(:mbox, nil)
|
22
|
+
self.mbox_sha1_sum = options.fetch(:mbox_sha1_sum, nil)
|
23
|
+
self.open_id = options.fetch(:open_id, nil)
|
24
|
+
self.account = options.fetch(:account, nil)
|
25
|
+
|
26
|
+
if block_given?
|
27
|
+
block[self]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def serialize(version)
|
33
|
+
node = {}
|
34
|
+
node['objectType'] = object_type
|
35
|
+
node['name'] = name if name
|
36
|
+
node['mbox'] = mbox if mbox
|
37
|
+
node['mbox_sha1sum'] = mbox_sha1_sum if mbox_sha1_sum
|
38
|
+
node['openid'] = open_id if open_id
|
39
|
+
node['account'] = account.serialize(version) if account
|
40
|
+
node
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'json'
|
3
|
+
module Xapi
|
4
|
+
# Agent Account model class
|
5
|
+
class AgentAccount
|
6
|
+
|
7
|
+
attr_accessor :homePage, :name
|
8
|
+
|
9
|
+
def initialize(options={}, &block)
|
10
|
+
json = options.fetch(:json, nil)
|
11
|
+
if json
|
12
|
+
attributes = JSON.parse(json)
|
13
|
+
self.name = attributes['name'] if attributes['name']
|
14
|
+
self.homePage = attributes['homePage'] if attributes['homePage']
|
15
|
+
else
|
16
|
+
self.homePage = options.fetch(:home_page, nil)
|
17
|
+
self.name =options.fetch(:name, nil)
|
18
|
+
|
19
|
+
if block_given?
|
20
|
+
block[self]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def serialize(version)
|
26
|
+
node = {}
|
27
|
+
node['name'] = name if name
|
28
|
+
node['homePage'] = homePage if homePage
|
29
|
+
node
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Xapi
|
3
|
+
# Attachment Class
|
4
|
+
class Attachment
|
5
|
+
|
6
|
+
attr_accessor :display, :description, :content_type, :length, :sha2
|
7
|
+
attr_reader :usage_type, :file_url
|
8
|
+
|
9
|
+
def initialize(options={}, &block)
|
10
|
+
json = options.fetch(:json, nil)
|
11
|
+
if json
|
12
|
+
attributes = JSON.parse(json)
|
13
|
+
self.usage_type = attributes['usageType'] if attributes['usageType']
|
14
|
+
self.display = attributes['display'] if attributes['display']
|
15
|
+
self.description = attributes['description'] if attributes['description']
|
16
|
+
self.content_type = attributes['contentType'] if attributes['contentType']
|
17
|
+
self.length = attributes['length'] if attributes['length']
|
18
|
+
self.sha2 = attributes['sha2'] if attributes['sha2']
|
19
|
+
self.file_url = attributes['fileUrl'] if attributes['fileUrl']
|
20
|
+
else
|
21
|
+
self.usage_type = options.fetch(:usage_type, nil)
|
22
|
+
self.display = options.fetch(:display, nil)
|
23
|
+
self.description = options.fetch(:description, nil)
|
24
|
+
self.content_type = options.fetch(:content_type, nil)
|
25
|
+
self.length = options.fetch(:length, nil)
|
26
|
+
self.sha2 = options.fetch(:sha2, nil)
|
27
|
+
self.file_url = options.fetch(:file_url, nil)
|
28
|
+
|
29
|
+
if block_given?
|
30
|
+
block[self]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def usage_type=(value)
|
36
|
+
if value.is_a?(String)
|
37
|
+
@usage_type = Addressable::URI.parse(value)
|
38
|
+
else
|
39
|
+
@usage_type = value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def file_url=(value)
|
44
|
+
if value.is_a?(String)
|
45
|
+
@file_url = Addressable::URI.parse(value)
|
46
|
+
else
|
47
|
+
@file_url = value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def serialize(version)
|
52
|
+
node = {}
|
53
|
+
node['usageType'] = usage_type.to_s if usage_type
|
54
|
+
node['display'] = display if display
|
55
|
+
node['description'] = description if description
|
56
|
+
node['contentType'] = content_type if content_type
|
57
|
+
node['length'] = length if length
|
58
|
+
node['sha2'] = sha2 if sha2
|
59
|
+
node['fileUrl'] = file_url.to_s if file_url
|
60
|
+
node
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
data/lib/xapi/context.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Xapi
|
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 = Xapi::Agent.new(json: attributes['instructor'].to_json) if attributes['instructor']
|
15
|
+
self.team = Xapi::Team.new(json: attributes['team'].to_json) if attributes['team']
|
16
|
+
self.context_activities = Xapi::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 = Xapi::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 Xapi
|
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 == Xapi::TCAPIVersion::V095 && parent.size > 1
|
59
|
+
raise Xapi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support lists of activities (parent)"
|
60
|
+
end
|
61
|
+
if version == Xapi::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 == Xapi::TCAPIVersion::V095 && grouping.size > 1
|
70
|
+
raise Xapi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support lists of activities (grouping)"
|
71
|
+
end
|
72
|
+
if version == Xapi::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 == Xapi::TCAPIVersion::V095 && other.size > 1
|
81
|
+
raise Xapi::Errors::IncompatibleTCAPIVersion, "Version #{version.to_s} doesn't support lists of activities (other)"
|
82
|
+
end
|
83
|
+
if version == Xapi::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 >= Xapi::TCAPIVersion::V100.ordinal
|
92
|
+
node['category'] = category.map {|element| element.serialize(version)}
|
93
|
+
else
|
94
|
+
raise Xapi::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 Xapi
|
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'
|
data/lib/xapi/enum.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Xapi
|
3
|
+
module Enum
|
4
|
+
CONVERT_PROC = Proc.new do
|
5
|
+
@values = constants.sort.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
|
data/lib/xapi/errors.rb
ADDED
data/lib/xapi/group.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Xapi
|
3
|
+
# Group model class
|
4
|
+
class Group < Agent
|
5
|
+
|
6
|
+
attr_accessor :members
|
7
|
+
|
8
|
+
def initialize(options={}, &block)
|
9
|
+
super(options, &block)
|
10
|
+
|
11
|
+
@object_type = 'Group'
|
12
|
+
@members = []
|
13
|
+
json = options.fetch(:json, nil)
|
14
|
+
if json
|
15
|
+
attributes = JSON.parse(json)
|
16
|
+
attributes['member'].each do |member|
|
17
|
+
members << Agent.new(json: member.to_json)
|
18
|
+
end
|
19
|
+
else
|
20
|
+
self.members = options.fetch(:members, nil)
|
21
|
+
|
22
|
+
if block_given?
|
23
|
+
block[self]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def serialize(version)
|
29
|
+
node = super(version)
|
30
|
+
if members.any?
|
31
|
+
node['member'] = members.map {|member| member.serialize(version)}
|
32
|
+
end
|
33
|
+
node
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|