moodle2cc 0.2.41 → 0.2.43

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/moodle2cc/canvas/assessment.rb +0 -0
  3. data/lib/moodle2cc/canvas/assignment.rb +0 -0
  4. data/lib/moodle2cc/canvas/converter.rb +0 -0
  5. data/lib/moodle2cc/canvas/discussion_topic.rb +0 -0
  6. data/lib/moodle2cc/canvas/label.rb +0 -0
  7. data/lib/moodle2cc/canvas/question.rb +3 -3
  8. data/lib/moodle2cc/canvas/question_bank.rb +0 -0
  9. data/lib/moodle2cc/canvas/question_group.rb +0 -0
  10. data/lib/moodle2cc/canvas/resource.rb +0 -0
  11. data/lib/moodle2cc/canvas/templates/assignment.html.erb +0 -0
  12. data/lib/moodle2cc/canvas/templates/syllabus.html.erb +0 -0
  13. data/lib/moodle2cc/canvas/templates/wiki_content.html.erb +0 -0
  14. data/lib/moodle2cc/canvas/web_content.rb +0 -0
  15. data/lib/moodle2cc/canvas/web_link.rb +0 -0
  16. data/lib/moodle2cc/canvas/wiki.rb +0 -0
  17. data/lib/moodle2cc/canvas_cc/models/assessment.rb +27 -17
  18. data/lib/moodle2cc/canvas_cc/models/question.rb +21 -15
  19. data/lib/moodle2cc/cc/assessment.rb +0 -0
  20. data/lib/moodle2cc/cc/assignment.rb +0 -0
  21. data/lib/moodle2cc/cc/course.rb +0 -0
  22. data/lib/moodle2cc/cc/discussion_topic.rb +0 -0
  23. data/lib/moodle2cc/cc/label.rb +0 -0
  24. data/lib/moodle2cc/cc/question.rb +0 -0
  25. data/lib/moodle2cc/cc/resource.rb +0 -0
  26. data/lib/moodle2cc/cc/templates/assignment.html.erb +0 -0
  27. data/lib/moodle2cc/cc/templates/syllabus.html.erb +0 -0
  28. data/lib/moodle2cc/cc/templates/wiki_content.html.erb +0 -0
  29. data/lib/moodle2cc/cc/web_link.rb +0 -0
  30. data/lib/moodle2cc/cc/wiki.rb +0 -0
  31. data/lib/moodle2cc/error.rb +0 -0
  32. data/lib/moodle2cc/logger.rb +0 -0
  33. data/lib/moodle2cc/moodle/course.rb +0 -0
  34. data/lib/moodle2cc/moodle/grade_item.rb +0 -0
  35. data/lib/moodle2cc/moodle/info.rb +0 -0
  36. data/lib/moodle2cc/moodle/question_category.rb +0 -0
  37. data/lib/moodle2cc/moodle/section.rb +0 -0
  38. data/lib/moodle2cc/moodle2/models/quizzes/question.rb +23 -7
  39. data/lib/moodle2cc/moodle2/parsers/forum_parser.rb +2 -2
  40. data/lib/moodle2cc/moodle2/parsers/question_category_parser.rb +31 -21
  41. data/lib/moodle2cc/moodle2/parsers/question_parsers/question_parser.rb +30 -31
  42. data/lib/moodle2cc/moodle2/parsers/quiz_parser.rb +54 -52
  43. data/lib/moodle2cc/moodle2converter/question_converters/question_converter.rb +16 -12
  44. data/lib/moodle2cc/version.rb +1 -1
  45. metadata +6 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fa603c9e3f922b9707a0eea13a3f307ac8a4453d6fd252696c6363b36948a8d
4
- data.tar.gz: 547291db25cdf930bef9b6a8f779426b269d67f844411fa9523618f604b2379d
3
+ metadata.gz: 00f4e9ab98639c0cfad6a74817e7658bcd09b6e8c7e5f6d344000321f3f226ae
4
+ data.tar.gz: f6ed3c60d489fc0949022feecf030cc8733b43294263da35844c866c63b3777c
5
5
  SHA512:
6
- metadata.gz: 66d6a5bd829bf90b7fe3032bea94e069f692d9b0e709664cc7f16a73cd16685d4742ee890030fa650fd84e7b0de9533092c89d0dbd3b1919f82cd904497ba442
7
- data.tar.gz: e1a9a228fab95550c39386a73baa2b03d90636e6b83884e7b91493001f3953b8111b7f3ebbea3a6e312e9cda0dc2dc8eef7e9b5366a656edc2d1ba67d66cab0d
6
+ metadata.gz: 90961bcb581bbb15314bce622dac900fca05a840e9c80f73602341759f69a00ce644299a9348015387067335d467549920f02d63ca147db503b6d3cbe441fba7
7
+ data.tar.gz: 3b8a6392926134b26847a2ada520eaff43698e27f9dcbd724acbd260a632c770775d15fea37786cf427527b1b81c65370e28aaebcc3038b74118e1f6eb6fc660
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -148,9 +148,9 @@ module Moodle2CC::Canvas
148
148
  end
149
149
  end
150
150
 
151
- if question.instance_id
152
- @assessment_question_identifierref = create_key(question.id, "#{@identifier_prefix}question_")
153
- end
151
+ # if question.instance_id
152
+ @assessment_question_identifierref = create_key(question.instance_id || question.id, "#{@identifier_prefix}question_")
153
+ # end
154
154
  end
155
155
 
156
156
  def create_item_xml(section_node)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,12 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moodle2CC::CanvasCC::Models
2
4
  class Assessment
3
- META_ATTRIBUTES = [:title, :description, :allowed_attempts,
4
- :scoring_policy, :access_code, :ip_filter, :shuffle_answers, :time_limit, :quiz_type]
5
- DATETIME_ATTRIBUTES = [:lock_at, :unlock_at]
6
-
7
- ASSESSMENT_TYPE = 'imsqti_xmlv1p2/imscc_xmlv1p1/assessment'
8
- LAR_TYPE = 'associatedcontent/imscc_xmlv1p1/learning-application-resource'
9
- ASSESSMENT_NON_CC_FOLDER = 'non_cc_assessments'
5
+ META_ATTRIBUTES = %i[title
6
+ description
7
+ allowed_attempts
8
+ scoring_policy
9
+ access_code
10
+ ip_filter
11
+ shuffle_answers
12
+ time_limit
13
+ quiz_type].freeze
14
+ DATETIME_ATTRIBUTES = [:lock_at, :unlock_at].freeze
15
+
16
+ ASSESSMENT_TYPE = "imsqti_xmlv1p2/imscc_xmlv1p1/assessment"
17
+ LAR_TYPE = "associatedcontent/imscc_xmlv1p1/learning-application-resource"
18
+ ASSESSMENT_NON_CC_FOLDER = "non_cc_assessments"
10
19
 
11
20
  attr_accessor :identifier, :workflow_state, :question_references, :items, *META_ATTRIBUTES, *DATETIME_ATTRIBUTES
12
21
 
@@ -54,14 +63,15 @@ module Moodle2CC::CanvasCC::Models
54
63
  question = nil
55
64
  group = nil
56
65
  question_banks.each do |bank|
57
- break if (question = bank.questions.detect{|q| q.original_identifier.to_s == ref[:question]}) ||
58
- (group = bank.question_groups.detect{|g| g.identifier.to_s == ref[:question]})
66
+ break if (question = bank.questions.detect { |q| q.original_identifier.to_s == ref[:question] })
67
+ break if (question = bank.questions.detect { |q| q.bank_entry_id.to_s == ref[:bank_entry_id] })
68
+ break if (group = bank.question_groups.detect { |g| g.identifier.to_s == ref[:question] })
59
69
 
60
- if bank.random_question_references.any?{|r| r.to_s == ref[:question]}
61
- random_bank_counts[bank] ||= 0
62
- random_bank_counts[bank] += 1
63
- break
64
- end
70
+ next unless bank.random_question_references.any? { |r| r.to_s == ref[:question] }
71
+
72
+ random_bank_counts[bank] ||= 0
73
+ random_bank_counts[bank] += 1
74
+ break
65
75
  end
66
76
 
67
77
  if question
@@ -93,11 +103,11 @@ module Moodle2CC::CanvasCC::Models
93
103
  @items << new_group
94
104
  end
95
105
 
96
- @items.select{|i| i.is_a?(Moodle2CC::CanvasCC::Models::QuestionGroup)}.each do |group|
106
+ @items.select { |i| i.is_a?(Moodle2CC::CanvasCC::Models::QuestionGroup) }.each do |group|
97
107
  group.questions.each do |q|
98
- @items.delete_if{|i| i.respond_to?(:original_identifier) && i.original_identifier == q.original_identifier}
108
+ @items.delete_if { |i| i.respond_to?(:original_identifier) && i.original_identifier == q.original_identifier }
99
109
  end
100
110
  end
101
111
  end
102
112
  end
103
- end
113
+ end
@@ -1,22 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moodle2CC::CanvasCC::Models
2
4
  class Question
3
- QTI_META_ATTRIBUTES = [:question_type, :points_possible, :assessment_question_identifierref]
4
- STANDARD_QUESTION_TYPES = ['essay_question', 'fill_in_multiple_blanks_question',
5
- 'multiple_choice_question', 'multiple_answers_question',
6
- 'short_answer_question', 'text_only_question', 'true_false_question']
5
+ QTI_META_ATTRIBUTES = %i[question_type points_possible assessment_question_identifierref].freeze
6
+ STANDARD_QUESTION_TYPES = %w[essay_question
7
+ fill_in_multiple_blanks_question
8
+ multiple_choice_question
9
+ multiple_answers_question
10
+ short_answer_question
11
+ text_only_question
12
+ true_false_question].freeze
7
13
 
8
- attr_accessor :identifier, :original_identifier, :title, :material, :answers, :general_feedback, *QTI_META_ATTRIBUTES
14
+ attr_accessor :identifier, :original_identifier, :bank_entry_id, :title, :material, :answers, :general_feedback, *QTI_META_ATTRIBUTES
9
15
 
10
16
  @@subclasses = {}
11
17
 
12
18
  def self.create(type)
13
19
  q = if STANDARD_QUESTION_TYPES.include?(type)
14
- self.new
15
- elsif c = @@subclasses[type]
16
- c.new
17
- else
18
- raise "Unknown question type: #{type}"
19
- end
20
+ new
21
+ elsif (c = @@subclasses[type])
22
+ c.new
23
+ else
24
+ raise "Unknown question type: #{type}"
25
+ end
20
26
  q.question_type = type
21
27
  q
22
28
  end
@@ -31,7 +37,7 @@ module Moodle2CC::CanvasCC::Models
31
37
  end
32
38
  end
33
39
 
34
- require_relative 'calculated_question'
35
- require_relative 'matching_question'
36
- require_relative 'multiple_dropdowns_question'
37
- require_relative 'numerical_question'
40
+ require_relative "calculated_question"
41
+ require_relative "matching_question"
42
+ require_relative "multiple_dropdowns_question"
43
+ require_relative "numerical_question"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,17 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moodle2CC::Moodle2::Models::Quizzes
2
4
  class Question
3
-
4
5
  @@subclasses = {}
5
6
 
6
- STANDARD_TYPES = ['description', 'essay', 'random', 'shortanswer']
7
+ STANDARD_TYPES = %w[description essay random shortanswer].freeze
7
8
 
8
9
  def self.create(type)
9
- if c = @@subclasses[type]
10
+ if (c = @@subclasses[type])
10
11
  q = c.new
11
12
  q.type = type
12
13
  q
13
14
  elsif STANDARD_TYPES.include?(type)
14
- q = self.new
15
+ q = new
15
16
  q.type = type
16
17
  q
17
18
  else
@@ -23,11 +24,26 @@ module Moodle2CC::Moodle2::Models::Quizzes
23
24
  @@subclasses[name] = self
24
25
  end
25
26
 
26
- attr_accessor :id, :parent, :name, :question_text, :question_text_format, :general_feedback, :default_mark, :max_mark,
27
- :penalty, :qtype, :length, :stamp, :version, :hidden, :answers, :type
27
+ attr_accessor :id,
28
+ :bank_entry_id,
29
+ :parent,
30
+ :name,
31
+ :question_text,
32
+ :question_text_format,
33
+ :general_feedback,
34
+ :default_mark,
35
+ :max_mark,
36
+ :penalty,
37
+ :qtype,
38
+ :length,
39
+ :stamp,
40
+ :version,
41
+ :hidden,
42
+ :answers,
43
+ :type
28
44
 
29
45
  def initialize
30
46
  @answers = []
31
47
  end
32
48
  end
33
- end
49
+ end
@@ -22,8 +22,8 @@ module Moodle2CC::Moodle2::Parsers
22
22
  activity_dir = File.join(@backup_dir, forum_dir)
23
23
  File.open(File.join(activity_dir, xml_file)) do |f|
24
24
  forum_xml = Nokogiri::XML(f)
25
- forum.id = forum_xml.at_xpath("/activity/#{module_name}/@id").value
26
- forum.module_id = forum_xml.at_xpath("/activity/@moduleid").value
25
+ forum.id = forum_xml.at_xpath("/activity/#{module_name}/@id")&.value
26
+ forum.module_id = forum_xml.at_xpath("/activity/@moduleid")&.value
27
27
  forum.name = parse_text(forum_xml, "/activity/#{module_name}/name")
28
28
  forum.type = parse_text(forum_xml, "/activity/#{module_name}/type")
29
29
  forum.intro = parse_text(forum_xml, "/activity/#{module_name}/intro")
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moodle2CC::Moodle2
2
4
  class Parsers::QuestionCategoryParser
3
5
  include Parsers::ParserHelper
4
6
 
5
- QUESTIONS_XML = 'questions.xml'
7
+ QUESTIONS_XML = "questions.xml"
6
8
 
7
9
  def initialize(backup_dir)
8
10
  @backup_dir = backup_dir
@@ -11,7 +13,7 @@ module Moodle2CC::Moodle2
11
13
  def parse
12
14
  File.open(File.join(@backup_dir, QUESTIONS_XML)) do |f|
13
15
  root_xml = Nokogiri::XML(f)
14
- root_xml.search('/question_categories/question_category').map { |node| question_category_parser(node) }
16
+ root_xml.search("/question_categories/question_category").map { |node| question_category_parser(node) }
15
17
  end
16
18
  end
17
19
 
@@ -19,30 +21,38 @@ module Moodle2CC::Moodle2
19
21
 
20
22
  def question_category_parser(node)
21
23
  category = Models::Quizzes::QuestionCategory.new
22
- category.id = node.at_xpath('@id').value
23
- category.name = parse_text(node, 'name')
24
- category.context_id = parse_text(node, 'contextid')
25
- category.context_level = parse_text(node, 'contextlevel')
26
- category.context_instance_id = parse_text(node, 'contextinstanceid')
27
- category.info = parse_text(node, 'info')
28
- category.info_format = parse_text(node, 'infoformat')
29
- category.stamp = parse_text(node, 'stamp')
30
- category.parent = parse_text(node, 'parent')
31
- category.sort_order = parse_text(node, 'sortorder')
32
-
33
- category.questions += node.search('questions/question').map { |question_node| question_parser(question_node) }.compact
24
+ category.id = node.at_xpath("@id").value
25
+ category.name = parse_text(node, "name")
26
+ category.context_id = parse_text(node, "contextid")
27
+ category.context_level = parse_text(node, "contextlevel")
28
+ category.context_instance_id = parse_text(node, "contextinstanceid")
29
+ category.info = parse_text(node, "info")
30
+ category.info_format = parse_text(node, "infoformat")
31
+ category.stamp = parse_text(node, "stamp")
32
+ category.parent = parse_text(node, "parent")
33
+ category.sort_order = parse_text(node, "sortorder")
34
+
35
+ category.questions += node.search("questions/question").filter_map { |question_node| question_parser(question_node) }
36
+ category.questions += node.search("question_bank_entries/question_bank_entry").map do |question_bank_entry|
37
+ question_bank_entry.search("question_version/question_versions").map do |question_versions|
38
+ question_versions.search("questions/question").map do |question_node|
39
+ bank_entry_reference = Nokogiri::XML::DocumentFragment.parse("<bank_entry_id>#{question_bank_entry.at_xpath("@id").value}</bank_entry_id>")
40
+ question_node.add_child(bank_entry_reference)
41
+ question_parser(question_node)
42
+ end
43
+ end
44
+ end.flatten.compact
45
+
46
+ category.questions = category.questions.flatten
34
47
 
35
48
  category
36
49
  end
37
50
 
38
51
  def question_parser(node)
39
- begin
40
- Parsers::QuestionParsers::QuestionParser.parse(node)
41
- rescue Exception => e
42
- Moodle2CC::OutputLogger.logger.info e.message
43
- nil
44
- end
52
+ Parsers::QuestionParsers::QuestionParser.parse(node)
53
+ rescue Exception => e
54
+ Moodle2CC::OutputLogger.logger.info e.message
55
+ nil
45
56
  end
46
-
47
57
  end
48
58
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moodle2CC::Moodle2
2
4
  class Parsers::QuestionParsers::QuestionParser
3
5
  include Parsers::ParserHelper
@@ -5,8 +7,8 @@ module Moodle2CC::Moodle2
5
7
  @@subclasses = {}
6
8
 
7
9
  def self.parse(node)
8
- type = node.%('qtype').text
9
- if c = @@subclasses[type]
10
+ type = node.%("qtype").text
11
+ if (c = @@subclasses[type])
10
12
  c.new.parse_question(node)
11
13
  else
12
14
  raise "Unknown parser type: #{type}"
@@ -18,37 +20,34 @@ module Moodle2CC::Moodle2
18
20
  end
19
21
 
20
22
  # simple question types
21
- register_parser_type('description')
22
- register_parser_type('essay')
23
- register_parser_type('random')
23
+ register_parser_type("description")
24
+ register_parser_type("essay")
25
+ register_parser_type("random")
24
26
 
25
27
  def parse_question(node, question_type = nil)
26
- begin
27
- question_type ||= parse_text(node, 'qtype')
28
- question = Models::Quizzes::Question.create question_type
29
-
30
- question.id = node.at_xpath('@id').value
31
- question.parent = parse_text(node, 'parent')
32
- question.name = parse_text(node, 'name')
33
- question.question_text = parse_text(node, 'questiontext')
34
- question.question_text_format = parse_text(node, 'questiontextformat')
35
- question.general_feedback = parse_text(node, 'generalfeedback')
36
- question.default_mark = parse_text(node, 'defaultmark')
37
- question.max_mark = parse_text(node, 'maxmark')
38
- question.penalty = parse_text(node, 'penalty')
39
- question.qtype = parse_text(node, 'qtype')
40
- question.length = parse_text(node, 'length')
41
- question.stamp = parse_text(node, 'stamp')
42
- question.version = parse_text(node, 'version')
43
- question.hidden = parse_boolean(node, 'hidden')
44
-
45
- question
46
- rescue Exception => e
47
- Moodle2CC::OutputLogger.logger.info e.message
48
- nil
49
- end
28
+ question_type ||= parse_text(node, "qtype")
29
+ question = Models::Quizzes::Question.create question_type
30
+
31
+ question.id = node.at_xpath("@id").value
32
+ question.bank_entry_id = parse_text(node, "bank_entry_id")
33
+ question.parent = parse_text(node, "parent")
34
+ question.name = parse_text(node, "name")
35
+ question.question_text = parse_text(node, "questiontext")
36
+ question.question_text_format = parse_text(node, "questiontextformat")
37
+ question.general_feedback = parse_text(node, "generalfeedback")
38
+ question.default_mark = parse_text(node, "defaultmark")
39
+ question.max_mark = parse_text(node, "maxmark")
40
+ question.penalty = parse_text(node, "penalty")
41
+ question.qtype = parse_text(node, "qtype")
42
+ question.length = parse_text(node, "length")
43
+ question.stamp = parse_text(node, "stamp")
44
+ question.version = parse_text(node, "version")
45
+ question.hidden = parse_boolean(node, "hidden")
46
+
47
+ question
48
+ rescue Exception => e
49
+ Moodle2CC::OutputLogger.logger.info e.message
50
+ nil
50
51
  end
51
-
52
-
53
52
  end
54
53
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moodle2CC::Moodle2::Parsers
2
4
  class QuizParser
3
5
  include ParserHelper
4
6
 
5
- QUIZ_XML = 'quiz.xml'
6
- QUIZ_MODULE_NAME = 'quiz'
7
+ QUIZ_XML = "quiz.xml"
8
+ QUIZ_MODULE_NAME = "quiz"
7
9
 
8
10
  def initialize(backup_dir)
9
11
  @backup_dir = backup_dir
@@ -21,65 +23,66 @@ module Moodle2CC::Moodle2::Parsers
21
23
  activity_dir = File.join(@backup_dir, dir)
22
24
  File.open(File.join(activity_dir, QUIZ_XML)) do |f|
23
25
  xml = Nokogiri::XML(f)
24
- quiz.id = xml.at_xpath('/activity/quiz/@id').value
25
- quiz.module_id = xml.at_xpath('/activity/@moduleid').value
26
- quiz.name = parse_text(xml, '/activity/quiz/name')
27
- quiz.intro = parse_text(xml, '/activity/quiz/intro')
28
- quiz.intro_format = parse_text(xml, '/activity/quiz/introformat')
29
- quiz.time_open = parse_text(xml, '/activity/quiz/timeopen')
30
- quiz.time_close = parse_text(xml, '/activity/quiz/timeclose')
31
- quiz.time_limit = parse_text(xml, '/activity/quiz/timelimit')
32
- quiz.overdue_handling = parse_text(xml, '/activity/quiz/overduehandling')
33
- quiz.grace_period = parse_text(xml, '/activity/quiz/graceperiod')
34
- quiz.preferred_behavior = parse_text(xml, '/activity/quiz/preferredbehaviour')
35
- quiz.attempts_number = parse_text(xml, '/activity/quiz/attempts_number')
36
- quiz.attempt_on_last = parse_text(xml, '/activity/quiz/attemptonlast')
37
- quiz.grade_method = parse_text(xml, '/activity/quiz/grademethod')
38
- quiz.decimal_points = parse_text(xml, '/activity/quiz/decimalpoints')
39
- quiz.question_decimal_points = parse_text(xml, '/activity/quiz/questiondecimalpoints')
40
- quiz.review_attempt = parse_text(xml, '/activity/quiz/reviewattempt')
41
- quiz.review_correctness = parse_text(xml, '/activity/quiz/reviewcorrectness')
42
- quiz.review_marks = parse_text(xml, '/activity/quiz/reviewmarks')
43
- quiz.review_specific_feedback = parse_text(xml, '/activity/quiz/reviewspecificfeedback')
44
- quiz.review_general_feedback = parse_text(xml, '/activity/quiz/reviewgeneralfeedback')
45
- quiz.review_right_answer = parse_text(xml, '/activity/quiz/reviewrightanswer')
46
- quiz.review_overall_feedback = parse_text(xml, '/activity/quiz/reviewoverallfeedback')
47
- quiz.questions_per_page = parse_text(xml, '/activity/quiz/questionsperpage')
48
- quiz.nav_method = parse_text(xml, '/activity/quiz/navmethod')
26
+ quiz.id = xml.at_xpath("/activity/quiz/@id").value
27
+ quiz.module_id = xml.at_xpath("/activity/@moduleid").value
28
+ quiz.name = parse_text(xml, "/activity/quiz/name")
29
+ quiz.intro = parse_text(xml, "/activity/quiz/intro")
30
+ quiz.intro_format = parse_text(xml, "/activity/quiz/introformat")
31
+ quiz.time_open = parse_text(xml, "/activity/quiz/timeopen")
32
+ quiz.time_close = parse_text(xml, "/activity/quiz/timeclose")
33
+ quiz.time_limit = parse_text(xml, "/activity/quiz/timelimit")
34
+ quiz.overdue_handling = parse_text(xml, "/activity/quiz/overduehandling")
35
+ quiz.grace_period = parse_text(xml, "/activity/quiz/graceperiod")
36
+ quiz.preferred_behavior = parse_text(xml, "/activity/quiz/preferredbehaviour")
37
+ quiz.attempts_number = parse_text(xml, "/activity/quiz/attempts_number")
38
+ quiz.attempt_on_last = parse_text(xml, "/activity/quiz/attemptonlast")
39
+ quiz.grade_method = parse_text(xml, "/activity/quiz/grademethod")
40
+ quiz.decimal_points = parse_text(xml, "/activity/quiz/decimalpoints")
41
+ quiz.question_decimal_points = parse_text(xml, "/activity/quiz/questiondecimalpoints")
42
+ quiz.review_attempt = parse_text(xml, "/activity/quiz/reviewattempt")
43
+ quiz.review_correctness = parse_text(xml, "/activity/quiz/reviewcorrectness")
44
+ quiz.review_marks = parse_text(xml, "/activity/quiz/reviewmarks")
45
+ quiz.review_specific_feedback = parse_text(xml, "/activity/quiz/reviewspecificfeedback")
46
+ quiz.review_general_feedback = parse_text(xml, "/activity/quiz/reviewgeneralfeedback")
47
+ quiz.review_right_answer = parse_text(xml, "/activity/quiz/reviewrightanswer")
48
+ quiz.review_overall_feedback = parse_text(xml, "/activity/quiz/reviewoverallfeedback")
49
+ quiz.questions_per_page = parse_text(xml, "/activity/quiz/questionsperpage")
50
+ quiz.nav_method = parse_text(xml, "/activity/quiz/navmethod")
49
51
 
50
- quiz.shuffle_questions = parse_boolean(xml, '/activity/quiz/shufflequestions')
51
- quiz.shuffle_answers = parse_boolean(xml, '/activity/quiz/shuffleanswers')
52
+ quiz.shuffle_questions = parse_boolean(xml, "/activity/quiz/shufflequestions")
53
+ quiz.shuffle_answers = parse_boolean(xml, "/activity/quiz/shuffleanswers")
52
54
 
53
- quiz.sum_grades = parse_text(xml, '/activity/quiz/sumgrades')
54
- quiz.grade = parse_text(xml, '/activity/quiz/grade')
55
- quiz.time_created = parse_text(xml, '/activity/quiz/timecreated')
56
- quiz.time_modified = parse_text(xml, '/activity/quiz/timemodified')
57
- quiz.password = parse_text(xml, '/activity/quiz/password')
58
- quiz.subnet = parse_text(xml, '/activity/quiz/subnet')
59
- quiz.browser_security = parse_text(xml, '/activity/quiz/browsersecurity')
60
- quiz.delay1 = parse_text(xml, '/activity/quiz/delay1')
61
- quiz.delay2 = parse_text(xml, '/activity/quiz/delay2')
62
- quiz.show_user_picture = parse_text(xml, '/activity/quiz/showuserpicture')
63
- quiz.show_blocks = parse_text(xml, '/activity/quiz/showblocks')
55
+ quiz.sum_grades = parse_text(xml, "/activity/quiz/sumgrades")
56
+ quiz.grade = parse_text(xml, "/activity/quiz/grade")
57
+ quiz.time_created = parse_text(xml, "/activity/quiz/timecreated")
58
+ quiz.time_modified = parse_text(xml, "/activity/quiz/timemodified")
59
+ quiz.password = parse_text(xml, "/activity/quiz/password")
60
+ quiz.subnet = parse_text(xml, "/activity/quiz/subnet")
61
+ quiz.browser_security = parse_text(xml, "/activity/quiz/browsersecurity")
62
+ quiz.delay1 = parse_text(xml, "/activity/quiz/delay1")
63
+ quiz.delay2 = parse_text(xml, "/activity/quiz/delay2")
64
+ quiz.show_user_picture = parse_text(xml, "/activity/quiz/showuserpicture")
65
+ quiz.show_blocks = parse_text(xml, "/activity/quiz/showblocks")
64
66
 
65
- xml.search('/activity/quiz/question_instances/question_instance').each do |node|
67
+ xml.search("/activity/quiz/question_instances/question_instance").each do |node|
66
68
  quiz.question_instances << {
67
- :question => parse_text(node, 'question') || parse_text(node, 'questionid'),
68
- :grade => parse_text(node, 'grade') || parse_text(node, 'maxmark')
69
+ question: parse_text(node, "question") || parse_text(node, "questionid"),
70
+ bank_entry_id: parse_text(node, "question_reference/questionbankentryid"),
71
+ grade: parse_text(node, "grade") || parse_text(node, "maxmark")
69
72
  }
70
73
  end
71
74
 
72
- question_order = parse_text(xml, '/activity/quiz/questions').to_s.split(',')
75
+ question_order = parse_text(xml, "/activity/quiz/questions").to_s.split(",")
73
76
  unless question_order.empty?
74
- quiz.question_instances.sort_by!{|qi| question_order.index(qi[:question])}
77
+ quiz.question_instances.sort_by! { |qi| question_order.index(qi[:question]) || 0 }
75
78
  end
76
79
 
77
- xml.search('/activity/quiz/feedbacks/feedback').each do |node|
80
+ xml.search("/activity/quiz/feedbacks/feedback").each do |node|
78
81
  quiz.feedbacks << {
79
- :text => parse_text(node, 'feedbacktext'),
80
- :format => parse_text(node, 'feedbacktextformat'),
81
- :min_grade => parse_text(node, 'mingrade'),
82
- :max_grade => parse_text(node, 'maxgrade')
82
+ text: parse_text(node, "feedbacktext"),
83
+ format: parse_text(node, "feedbacktextformat"),
84
+ min_grade: parse_text(node, "mingrade"),
85
+ max_grade: parse_text(node, "maxgrade")
83
86
  }
84
87
  end
85
88
  end
@@ -87,6 +90,5 @@ module Moodle2CC::Moodle2::Parsers
87
90
 
88
91
  quiz
89
92
  end
90
-
91
93
  end
92
- end
94
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Moodle2CC::Moodle2Converter
2
4
  module QuestionConverters
3
5
  class QuestionConverter
@@ -13,17 +15,17 @@ module Moodle2CC::Moodle2Converter
13
15
  end
14
16
 
15
17
  STANDARD_CONVERSIONS = {
16
- 'description' => 'text_only_question',
17
- 'essay' => 'essay_question',
18
- 'shortanswer' => 'short_answer_question'
19
- }
18
+ "description" => "text_only_question",
19
+ "essay" => "essay_question",
20
+ "shortanswer" => "short_answer_question"
21
+ }.freeze
20
22
 
21
23
  def convert(moodle_question)
22
24
  type = moodle_question.type
23
- if type && c = @@subclasses[type]
25
+ if type && (c = @@subclasses[type])
24
26
  c.new.convert_question(moodle_question)
25
- elsif type && question_type = STANDARD_CONVERSIONS[type]
26
- self.convert_question(moodle_question, question_type)
27
+ elsif type && (question_type = STANDARD_CONVERSIONS[type])
28
+ convert_question(moodle_question, question_type)
27
29
  else
28
30
  raise "Unknown converter type: #{type}"
29
31
  end
@@ -31,29 +33,31 @@ module Moodle2CC::Moodle2Converter
31
33
 
32
34
  def convert_question(moodle_question, question_type = nil)
33
35
  canvas_question = create_canvas_question(question_type, moodle_question)
34
- canvas_question.identifier = generate_unique_identifier_for(moodle_question.id, '_quiz_question')
36
+ canvas_question.identifier = generate_unique_identifier_for(moodle_question.id, "_quiz_question")
35
37
  canvas_question.original_identifier = moodle_question.id
38
+ canvas_question.bank_entry_id = moodle_question.bank_entry_id
36
39
  canvas_question.title = truncate_text(moodle_question.name)
37
40
  canvas_question.points_possible = moodle_question.max_mark
38
41
  canvas_question.general_feedback = moodle_question.general_feedback
39
42
  canvas_question.answers = moodle_question.answers.map do |moodle_answer|
40
- Moodle2CC::CanvasCC::Models::Answer.new(moodle_answer)
43
+ Moodle2CC::CanvasCC::Models::Answer.new(moodle_answer)
41
44
  end
42
45
  canvas_question.material = convert_question_text(moodle_question)
43
46
  canvas_question
44
47
  end
45
48
 
46
49
  def convert_question_text(moodle_question)
47
- material = moodle_question.question_text || ''
50
+ material = moodle_question.question_text || ""
48
51
  material = RDiscount.new(material).to_html if moodle_question.question_text_format.to_i == 4 # markdown
49
52
  material
50
53
  end
51
54
 
52
55
  def create_canvas_question(question_type = nil, question = nil)
53
56
  question_type ||= self.class.canvas_question_type
54
- raise 'set canvas_question_type in question converter subclasses' unless question_type
57
+ raise "set canvas_question_type in question converter subclasses" unless question_type
58
+
55
59
  Moodle2CC::CanvasCC::Models::Question.create(question_type)
56
60
  end
57
61
  end
58
62
  end
59
- end
63
+ end
@@ -1,3 +1,3 @@
1
1
  module Moodle2CC
2
- VERSION = "0.2.41"
2
+ VERSION = "0.2.43"
3
3
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moodle2cc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.41
4
+ version: 0.2.43
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Durtschi
8
8
  - Kevin Carter
9
9
  - Instructure
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-05-11 00:00:00.000000000 Z
13
+ date: 2024-01-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubyzip
@@ -409,7 +409,7 @@ homepage: https://github.com/instructure/moodle2cc
409
409
  licenses:
410
410
  - AGPLv3
411
411
  metadata: {}
412
- post_install_message:
412
+ post_install_message:
413
413
  rdoc_options: []
414
414
  require_paths:
415
415
  - lib
@@ -424,9 +424,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
424
424
  - !ruby/object:Gem::Version
425
425
  version: '0'
426
426
  requirements: []
427
- rubyforge_project:
428
- rubygems_version: 2.7.3
429
- signing_key:
427
+ rubygems_version: 3.3.3
428
+ signing_key:
430
429
  specification_version: 4
431
430
  summary: Migrates Moodle backup ZIP to IMS Common Cartridge package
432
431
  test_files: []