Class: CanvasQtiToLearnosityConverter::QuizQuestion
- Inherits:
-
Object
- Object
- CanvasQtiToLearnosityConverter::QuizQuestion
show all
- Extended by:
- Forwardable
- Defined in:
- lib/canvas_qti_to_learnosity_converter/questions/question.rb
Direct Known Subclasses
CategorizationQuestion, EssayQuestion, FileUploadQuestion, HotSpotQuestion, MatchingQuestion, MultipleChoiceQuestion, NumericalQuestion, OrderingQuestion, ShortAnswerQuestion, TemplateQuestion, TextOnlyQuestion
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
Returns a new instance of QuizQuestion.
12
13
14
|
# File 'lib/canvas_qti_to_learnosity_converter/questions/question.rb', line 12
def initialize(xml)
@xml = xml
end
|
Class Method Details
.for(xml) ⇒ Object
8
9
10
|
# File 'lib/canvas_qti_to_learnosity_converter/questions/question.rb', line 8
def self.for(xml)
new(xml)
end
|
Instance Method Details
#convert(assets, path) ⇒ Object
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
# File 'lib/canvas_qti_to_learnosity_converter/questions/question.rb', line 110
def convert(assets, path)
object = to_learnosity
add_learnosity_assets(assets, path, object) feedback =
unless feedback.empty?
feedback.each do |key, value|
if value.is_a?(String)
process_assets!(assets, path, value)
elsif key.to_s == "distractor_rationale_response_level" && value.is_a?(Array)
value.each do |entry|
process_assets!(assets, path, entry) if entry.is_a?(String)
end
end
end
object[:metadata] ||= {}
object[:metadata].merge!(feedback)
end
object
end
|
#dynamic_content_data ⇒ Object
57
58
59
|
# File 'lib/canvas_qti_to_learnosity_converter/questions/question.rb', line 57
def dynamic_content_data()
{}
end
|
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/canvas_qti_to_learnosity_converter/questions/question.rb', line 27
def
feedback = {}
distractor_rationale = []
@xml.css("item > itemfeedback").each do |node|
ident = node.attribute("ident")&.value
text = node.css("flow_mat > material > mattext").first&.content
next if text.nil? || text.empty?
case ident
when "correct_fb" then feedback[:correct_feedback] = text
when "general_fb" then feedback[:general_feedback] = text
when "general_incorrect_fb" then feedback[:incorrect_feedback] = text
else distractor_rationale << text if ident&.end_with?("_fb")
end
end
feedback[:distractor_rationale_response_level] = distractor_rationale unless distractor_rationale.empty?
feedback
end
|
49
50
51
|
# File 'lib/canvas_qti_to_learnosity_converter/questions/question.rb', line 49
def (mattext_node)
mattext_node.content
end
|
21
22
23
24
25
|
# File 'lib/canvas_qti_to_learnosity_converter/questions/question.rb', line 21
def
@xml.css(%{ item > itemmetadata > qtimetadata >
qtimetadatafield > fieldlabel:contains("points_possible")})
&.first&.next&.text&.to_f || 1.0
end
|
16
17
18
19
|
# File 'lib/canvas_qti_to_learnosity_converter/questions/question.rb', line 16
def ()
mattext = @xml.css("item > presentation > material > mattext").first
(mattext)
end
|
#make_identifier ⇒ Object
53
54
55
|
# File 'lib/canvas_qti_to_learnosity_converter/questions/question.rb', line 53
def make_identifier()
SecureRandom.uuid
end
|
#process_assets!(assets, path, text) ⇒ Object
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/canvas_qti_to_learnosity_converter/questions/question.rb', line 61
def process_assets!(assets, path, text)
doc = Nokogiri::XML.fragment(text)
changed = false
doc.css("img").each do |node|
source = node["src"]
next if !source
source = URI::DEFAULT_PARSER.unescape(source)
if /^\$IMS-CC-FILEBASE\$(.*)/.match(source) || /^((?!https?:).*)/.match(source)
if source.start_with?("$IMS-CC-FILEBASE$")
path = ''
end
asset_path = $1
asset_path = asset_path.split("?").first.gsub(/^\//, '')
asset_path = File.join(path, asset_path)
clean_ext = File.extname(asset_path).gsub(/[^a-z0-9_.-]/i, '')
assets[asset_path] ||= "#{SecureRandom.uuid}#{clean_ext}"
node["src"] = "___EXPORT_ROOT___/assets/#{assets[asset_path]}"
changed = true
end
end
doc.css("audio").each do |node|
source_node = node.css("source").first
raw_src = source_node&.[]("src") || node["src"]
next unless raw_src
src = URI::DEFAULT_PARSER.unescape(raw_src)
if /^\$IMS-CC-FILEBASE\$(.*)/.match(src) || /^((?!https?:).*)/.match(src)
asset_path_base = src.start_with?("$IMS-CC-FILEBASE$") ? '' : path
asset_path = $1.split("?").first.gsub(/^\//, '')
asset_path = File.join(asset_path_base, asset_path)
clean_ext = File.extname(asset_path).gsub(/[^a-z0-9_.-]/i, '')
assets[asset_path] ||= "#{SecureRandom.uuid}#{clean_ext}"
src = "___EXPORT_ROOT___/assets/#{assets[asset_path]}"
end
span = Nokogiri::XML::Node.new("span", doc)
span["class"] = "learnosity-feature"
span["data-player"] = "bar"
span["data-simplefeature_id"] = SecureRandom.uuid
span["data-src"] = src
span["data-type"] = "audioplayer"
span.add_child(Nokogiri::XML::Text.new("", doc))
node.replace(span)
changed = true
end
text.replace(doc.to_xml) if changed
end
|