moodle2cc 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog +7 -0
- data/lib/moodle2cc.rb +3 -0
- data/lib/moodle2cc/canvas_cc/calculated_question_writer.rb +11 -0
- data/lib/moodle2cc/canvas_cc/matching_question_writer.rb +6 -4
- data/lib/moodle2cc/canvas_cc/models/assessment.rb +1 -1
- data/lib/moodle2cc/canvas_cc/models/calculated_question.rb +13 -1
- data/lib/moodle2cc/canvas_cc/models/course.rb +2 -2
- data/lib/moodle2cc/canvas_cc/models/multiple_dropdowns_question.rb +7 -0
- data/lib/moodle2cc/canvas_cc/models/page.rb +7 -1
- data/lib/moodle2cc/canvas_cc/models/question.rb +1 -0
- data/lib/moodle2cc/canvas_cc/multiple_answers_question_writer.rb +7 -6
- data/lib/moodle2cc/canvas_cc/multiple_dropdowns_question_writer.rb +30 -0
- data/lib/moodle2cc/canvas_cc/question_writer.rb +2 -1
- data/lib/moodle2cc/moodle2/extractor.rb +7 -0
- data/lib/moodle2cc/moodle2/models.rb +1 -1
- data/lib/moodle2cc/moodle2/models/course.rb +3 -2
- data/lib/moodle2cc/moodle2/models/label.rb +5 -5
- data/lib/moodle2cc/moodle2/models/questionnaire.rb +1 -1
- data/lib/moodle2cc/moodle2/models/quizzes.rb +1 -0
- data/lib/moodle2cc/moodle2/models/quizzes/calculated_question.rb +2 -1
- data/lib/moodle2cc/moodle2/models/quizzes/multichoice_question.rb +6 -0
- data/lib/moodle2cc/moodle2/models/quizzes/question.rb +1 -1
- data/lib/moodle2cc/moodle2/models/wiki.rb +10 -0
- data/lib/moodle2cc/moodle2/parsers.rb +1 -0
- data/lib/moodle2cc/moodle2/parsers/course_parser.rb +5 -5
- data/lib/moodle2cc/moodle2/parsers/parser_helper.rb +7 -2
- data/lib/moodle2cc/moodle2/parsers/question_parsers/calculated_parser.rb +11 -1
- data/lib/moodle2cc/moodle2/parsers/question_parsers/match_parser.rb +2 -1
- data/lib/moodle2cc/moodle2/parsers/question_parsers/multichoice_parser.rb +2 -0
- data/lib/moodle2cc/moodle2/parsers/questionnaire_parser.rb +5 -0
- data/lib/moodle2cc/moodle2/parsers/quiz_parser.rb +5 -0
- data/lib/moodle2cc/moodle2/parsers/section_parser.rb +5 -1
- data/lib/moodle2cc/moodle2/parsers/wiki_parser.rb +47 -0
- data/lib/moodle2cc/moodle2converter/assessment_converter.rb +6 -4
- data/lib/moodle2cc/moodle2converter/assignment_converter.rb +1 -1
- data/lib/moodle2cc/moodle2converter/book_converter.rb +4 -4
- data/lib/moodle2cc/moodle2converter/converter_helper.rb +14 -0
- data/lib/moodle2cc/moodle2converter/discussion_converter.rb +1 -1
- data/lib/moodle2cc/moodle2converter/feedback_converter.rb +3 -3
- data/lib/moodle2cc/moodle2converter/html_converter.rb +16 -1
- data/lib/moodle2cc/moodle2converter/label_converter.rb +2 -2
- data/lib/moodle2cc/moodle2converter/migrator.rb +70 -2
- data/lib/moodle2cc/moodle2converter/question_bank_converter.rb +1 -1
- data/lib/moodle2cc/moodle2converter/question_converters.rb +1 -0
- data/lib/moodle2cc/moodle2converter/question_converters/calculated_converter.rb +1 -0
- data/lib/moodle2cc/moodle2converter/question_converters/matching_converter.rb +3 -0
- data/lib/moodle2cc/moodle2converter/question_converters/multichoice_converter.rb +15 -0
- data/lib/moodle2cc/moodle2converter/question_converters/multiple_blanks_converter.rb +1 -1
- data/lib/moodle2cc/moodle2converter/question_converters/question_converter.rb +3 -5
- data/lib/moodle2cc/moodle2converter/questionnaire_converter.rb +44 -8
- data/lib/moodle2cc/moodle2converter/section_converter.rb +3 -3
- data/lib/moodle2cc/moodle2converter/wiki_converter.rb +37 -0
- data/lib/moodle2cc/version.rb +1 -1
- data/spec/moodle2cc/canvas_cc/calculated_question_writer_spec.rb +7 -0
- data/spec/moodle2cc/canvas_cc/matching_question_writer_spec.rb +2 -2
- data/spec/moodle2cc/canvas_cc/models/assessment_spec.rb +1 -1
- data/spec/moodle2cc/canvas_cc/models/calculated_question_spec.rb +25 -0
- data/spec/moodle2cc/canvas_cc/models/page_spec.rb +6 -0
- data/spec/moodle2cc/canvas_cc/multiple_answers_question_writer_spec.rb +4 -1
- data/spec/moodle2cc/canvas_cc/multiple_blanks_question_writer_spec.rb +1 -1
- data/spec/moodle2cc/canvas_cc/multiple_dropdowns_question_writer_spec.rb +46 -0
- data/spec/moodle2cc/moodle2/extractor_spec.rb +8 -0
- data/spec/moodle2cc/moodle2/models/label_spec.rb +4 -4
- data/spec/moodle2cc/moodle2/parsers/parser_helper_spec.rb +10 -0
- data/spec/moodle2cc/moodle2/parsers/question_parsers/calculated_parser_spec.rb +17 -0
- data/spec/moodle2cc/moodle2/parsers/questionnaire_parser_spec.rb +4 -0
- data/spec/moodle2cc/moodle2/parsers/quiz_parser_spec.rb +1 -1
- data/spec/moodle2cc/moodle2/parsers/wiki_parser_spec.rb +23 -0
- data/spec/moodle2cc/moodle2converter/assessment_converter_spec.rb +12 -7
- data/spec/moodle2cc/moodle2converter/converter_helper_spec.rb +5 -0
- data/spec/moodle2cc/moodle2converter/html_converter_spec.rb +7 -2
- data/spec/moodle2cc/moodle2converter/label_converter_spec.rb +17 -0
- data/spec/moodle2cc/moodle2converter/migrator_spec.rb +83 -2
- data/spec/moodle2cc/moodle2converter/question_converters/calculated_converter_spec.rb +2 -0
- data/spec/moodle2cc/moodle2converter/question_converters/matching_converter_spec.rb +2 -3
- data/spec/moodle2cc/moodle2converter/question_converters/multichoice_converter_spec.rb +26 -0
- data/spec/moodle2cc/moodle2converter/question_converters/question_converter_spec.rb +0 -3
- data/spec/moodle2cc/moodle2converter/wiki_converter_spec.rb +36 -0
- data/test/fixtures/moodle2/backup/activities/quiz_5/quiz.xml +1 -1
- data/test/fixtures/moodle2/backup/activities/wiki_58541/calendar.xml +3 -0
- data/test/fixtures/moodle2/backup/activities/wiki_58541/completion.xml +3 -0
- data/test/fixtures/moodle2/backup/activities/wiki_58541/grades.xml +7 -0
- data/test/fixtures/moodle2/backup/activities/wiki_58541/inforef.xml +47 -0
- data/test/fixtures/moodle2/backup/activities/wiki_58541/module.xml +28 -0
- data/test/fixtures/moodle2/backup/activities/wiki_58541/roles.xml +7 -0
- data/test/fixtures/moodle2/backup/activities/wiki_58541/wiki.xml +70 -0
- data/test/fixtures/moodle2/backup/moodle_backup.xml +7 -0
- metadata +33 -2
@@ -22,10 +22,20 @@ module Moodle2CC::Moodle2
|
|
22
22
|
end
|
23
23
|
|
24
24
|
q_node.search('dataset_definitions/dataset_definition').each do |ds_node|
|
25
|
+
var_name = parse_text(ds_node, 'name')
|
25
26
|
question.dataset_definitions << {
|
26
|
-
:name =>
|
27
|
+
:name => var_name,
|
27
28
|
:options => parse_text(ds_node, 'options')
|
28
29
|
}
|
30
|
+
ds_node.search('dataset_items/dataset_item').each do |ds_item_node|
|
31
|
+
ident = parse_text(ds_item_node, 'number')
|
32
|
+
var_set = question.var_sets.detect{|vs| vs[:ident] == ident}
|
33
|
+
unless var_set
|
34
|
+
var_set = {:ident => ident, :vars => {}}
|
35
|
+
question.var_sets << var_set
|
36
|
+
end
|
37
|
+
var_set[:vars][var_name] = parse_text(ds_item_node, 'value')
|
38
|
+
end
|
29
39
|
end
|
30
40
|
|
31
41
|
q_node.search('calculated_records/calculated_record').each do |cr_node|
|
@@ -2,9 +2,10 @@ module Moodle2CC::Moodle2
|
|
2
2
|
class Parsers::QuestionParsers::MatchParser < Parsers::QuestionParsers::QuestionParser
|
3
3
|
include Parsers::ParserHelper
|
4
4
|
register_parser_type('match')
|
5
|
+
register_parser_type('ddmatch')
|
5
6
|
|
6
7
|
def parse_question(node)
|
7
|
-
question = super
|
8
|
+
question = super(node, 'match')
|
8
9
|
|
9
10
|
q_node = node.at_xpath("plugin_qtype_#{question.qtype}_question")
|
10
11
|
|
@@ -9,6 +9,8 @@ module Moodle2CC::Moodle2
|
|
9
9
|
answer_parser = Parsers::AnswerParser.new
|
10
10
|
question.answers += node.search('answers/answer').map { |n| answer_parser.parse(n) }
|
11
11
|
|
12
|
+
question.single = parse_boolean(node, 'plugin_qtype_multichoice_question/multichoice/single')
|
13
|
+
|
12
14
|
question
|
13
15
|
end
|
14
16
|
|
@@ -39,6 +39,11 @@ module Moodle2CC::Moodle2::Parsers
|
|
39
39
|
question.type_id = parse_text(node, 'type_id')
|
40
40
|
question.position = parse_text(node, 'position')
|
41
41
|
question.content = parse_text(node, 'content')
|
42
|
+
|
43
|
+
question.length = parse_text(node, 'length') # used for rating scale
|
44
|
+
question.precise = parse_text(node, 'precise') # used for rating scale type
|
45
|
+
|
46
|
+
question.deleted = parse_boolean(node, 'deleted')
|
42
47
|
node.search('quest_choices/quest_choice').each do |choice_node|
|
43
48
|
question.choices << {
|
44
49
|
:id => choice_node.attributes['id'].value,
|
@@ -69,6 +69,11 @@ module Moodle2CC::Moodle2::Parsers
|
|
69
69
|
}
|
70
70
|
end
|
71
71
|
|
72
|
+
question_order = parse_text(xml, '/activity/quiz/questions').to_s.split(',')
|
73
|
+
unless question_order.empty?
|
74
|
+
quiz.question_instances.sort_by!{|qi| question_order.index(qi[:question])}
|
75
|
+
end
|
76
|
+
|
72
77
|
xml.search('/activity/quiz/feedbacks/feedback').each do |node|
|
73
78
|
quiz.feedbacks << {
|
74
79
|
:text => parse_text(node, 'feedbacktext'),
|
@@ -25,7 +25,11 @@ module Moodle2CC::Moodle2::Parsers
|
|
25
25
|
section.summary = parse_text(section_xml, '/section/summary')
|
26
26
|
section.summary_format = parse_text(section_xml, 'section/summaryformat')
|
27
27
|
section.sequence = parse_text(section_xml, 'section/sequence')
|
28
|
-
|
28
|
+
if section.sequence
|
29
|
+
section.sequence = section.sequence.split(',')
|
30
|
+
else
|
31
|
+
section.sequence = []
|
32
|
+
end
|
29
33
|
section.visible = parse_text(section_xml, 'section/visible') == '1' ? true : false
|
30
34
|
section.available_from = parse_text(section_xml, 'section/availablefrom')
|
31
35
|
section.available_until = parse_text(section_xml, 'section/availableuntil')
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Moodle2CC::Moodle2::Parsers
|
2
|
+
class WikiParser
|
3
|
+
include ParserHelper
|
4
|
+
|
5
|
+
WIKI_XML = 'wiki.xml'
|
6
|
+
WIKI_MODULE_NAME = 'wiki'
|
7
|
+
|
8
|
+
def initialize(backup_dir)
|
9
|
+
@backup_dir = backup_dir
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse
|
13
|
+
activity_dirs = activity_directories(@backup_dir, WIKI_MODULE_NAME)
|
14
|
+
activity_dirs.map { |dir| parse_wiki(dir) }
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def parse_wiki(dir)
|
20
|
+
wiki = Moodle2CC::Moodle2::Models::Wiki.new
|
21
|
+
activity_dir = File.join(@backup_dir, dir)
|
22
|
+
File.open(File.join(activity_dir, WIKI_XML)) do |f|
|
23
|
+
wiki_xml = Nokogiri::XML(f)
|
24
|
+
wiki.id = wiki_xml.at_xpath('/activity/wiki/@id').value
|
25
|
+
wiki.module_id = wiki_xml.at_xpath('/activity/@moduleid').value
|
26
|
+
wiki.name = parse_text(wiki_xml, '/activity/wiki/name')
|
27
|
+
wiki.intro = parse_text(wiki_xml, '/activity/wiki/intro')
|
28
|
+
wiki.intro_format = parse_text(wiki_xml, '/activity/wiki/introformat')
|
29
|
+
|
30
|
+
wiki.first_page_title = parse_text(wiki_xml, '/activity/wiki/firstpagetitle')
|
31
|
+
|
32
|
+
wiki_xml.search('/activity/wiki/subwikis/subwiki/pages/page').each do |node|
|
33
|
+
wiki.pages << {
|
34
|
+
:id => node.attributes['id'].value,
|
35
|
+
:title => parse_text(node, 'title'),
|
36
|
+
:content => parse_text(node, 'cachedcontent')
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
parse_module(activity_dir, wiki)
|
41
|
+
|
42
|
+
wiki
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -11,7 +11,7 @@ module Moodle2CC::Moodle2Converter
|
|
11
11
|
def convert_quiz(moodle_quiz)
|
12
12
|
canvas_assessment = Moodle2CC::CanvasCC::Models::Assessment.new
|
13
13
|
canvas_assessment.identifier = generate_unique_identifier_for(moodle_quiz.id, ASSESSMENT_SUFFIX)
|
14
|
-
canvas_assessment.title = moodle_quiz.name
|
14
|
+
canvas_assessment.title = truncate_text(moodle_quiz.name)
|
15
15
|
canvas_assessment.description = moodle_quiz.intro
|
16
16
|
canvas_assessment.workflow_state = workflow_state(moodle_quiz.visible)
|
17
17
|
|
@@ -25,7 +25,9 @@ module Moodle2CC::Moodle2Converter
|
|
25
25
|
canvas_assessment.access_code = moodle_quiz.password
|
26
26
|
canvas_assessment.ip_filter = moodle_quiz.subnet
|
27
27
|
canvas_assessment.shuffle_answers = moodle_quiz.shuffle_answers
|
28
|
-
|
28
|
+
if moodle_quiz.time_limit && moodle_quiz.time_limit.to_i > 0
|
29
|
+
canvas_assessment.time_limit = (moodle_quiz.time_limit.to_f / 60).ceil
|
30
|
+
end
|
29
31
|
canvas_assessment.quiz_type = 'practice_quiz'
|
30
32
|
|
31
33
|
canvas_assessment.question_references = moodle_quiz.question_instances
|
@@ -36,7 +38,7 @@ module Moodle2CC::Moodle2Converter
|
|
36
38
|
def convert_choice(moodle_choice)
|
37
39
|
canvas_assessment = Moodle2CC::CanvasCC::Models::Assessment.new
|
38
40
|
canvas_assessment.identifier = generate_unique_identifier_for(moodle_choice.id, CHOICE_ASSESSMENT_SUFFIX)
|
39
|
-
canvas_assessment.title = moodle_choice.name
|
41
|
+
canvas_assessment.title = truncate_text(moodle_choice.name)
|
40
42
|
canvas_assessment.description = ''
|
41
43
|
canvas_assessment.workflow_state = workflow_state(moodle_choice.visible)
|
42
44
|
|
@@ -49,7 +51,7 @@ module Moodle2CC::Moodle2Converter
|
|
49
51
|
|
50
52
|
question = Moodle2CC::CanvasCC::Models::Question.create('multiple_choice_question')
|
51
53
|
question.identifier = generate_unique_identifier_for(moodle_choice.id, '_choice_question')
|
52
|
-
question.title = moodle_choice.name
|
54
|
+
question.title = truncate_text(moodle_choice.name)
|
53
55
|
question.material = moodle_choice.intro
|
54
56
|
question.answers = []
|
55
57
|
moodle_choice.options.each_with_index do |option, num|
|
@@ -5,7 +5,7 @@ module Moodle2CC::Moodle2Converter
|
|
5
5
|
def convert(moodle_assignment)
|
6
6
|
canvas_assignment = Moodle2CC::CanvasCC::Models::Assignment.new
|
7
7
|
canvas_assignment.identifier = generate_unique_identifier_for(moodle_assignment.id, ASSIGNMENT_SUFFIX)
|
8
|
-
canvas_assignment.title = moodle_assignment.name
|
8
|
+
canvas_assignment.title = truncate_text(moodle_assignment.name)
|
9
9
|
canvas_assignment.body = moodle_assignment.intro
|
10
10
|
canvas_assignment.due_at = Time.at(Integer(moodle_assignment.due_date)) if moodle_assignment.due_date
|
11
11
|
canvas_assignment.lock_at = Time.at(Integer(moodle_assignment.cut_off_date)) if moodle_assignment.cut_off_date
|
@@ -24,7 +24,7 @@ module Moodle2CC
|
|
24
24
|
page.identifier = generate_unique_identifier_for_book_intro(moodle_book)
|
25
25
|
page.body = moodle_book.intro
|
26
26
|
if pages.any?{|p| page.title == p.title}
|
27
|
-
page.title = "#{page.title} (Introduction)"
|
27
|
+
page.title = "#{truncate_text(page.title, MAX_TITLE_LENGTH - 20)} (Introduction)"
|
28
28
|
end
|
29
29
|
page.workflow_state = workflow_state(moodle_book.visible)
|
30
30
|
pages.unshift(page)
|
@@ -46,7 +46,7 @@ module Moodle2CC
|
|
46
46
|
def create_title(moodle_book)
|
47
47
|
module_item = create_module_item_with_defaults()
|
48
48
|
module_item.content_type = Moodle2CC::CanvasCC::Models::ModuleItem::CONTENT_TYPE_CONTEXT_MODULE_SUB_HEADER
|
49
|
-
module_item.title = moodle_book.name
|
49
|
+
module_item.title = truncate_text(moodle_book.name)
|
50
50
|
module_item.indent = "0"
|
51
51
|
module_item.identifier = generate_unique_identifier()
|
52
52
|
module_item.workflow_state = workflow_state(moodle_book.visible)
|
@@ -67,7 +67,7 @@ module Moodle2CC
|
|
67
67
|
|
68
68
|
def create_chapter(moodle_chapter)
|
69
69
|
module_item = create_module_item_with_defaults()
|
70
|
-
module_item.title = moodle_chapter.title
|
70
|
+
module_item.title = truncate_text(moodle_chapter.title)
|
71
71
|
module_item.indent = moodle_chapter.subchapter ? "2" : "1"
|
72
72
|
module_item.identifier = generate_unique_identifier()
|
73
73
|
module_item.identifierref = generate_unique_identifier_for_activity(moodle_chapter)
|
@@ -88,7 +88,7 @@ module Moodle2CC
|
|
88
88
|
page = CanvasCC::Models::Page.new
|
89
89
|
page.type = CanvasCC::Models::Resource::WEB_CONTENT_TYPE
|
90
90
|
page.href = generate_unique_resource_path(CanvasCC::Models::Page::BOOK_PATH, title)
|
91
|
-
page.title = title
|
91
|
+
page.title = truncate_text(title)
|
92
92
|
page.workflow_state = CanvasCC::Models::WorkflowState::ACTIVE
|
93
93
|
page.editing_roles = CanvasCC::Models::Page::EDITING_ROLE_TEACHER
|
94
94
|
page
|
@@ -20,6 +20,7 @@ module Moodle2CC
|
|
20
20
|
|
21
21
|
ACTIVITY_LOOKUP = {
|
22
22
|
Moodle2::Models::Page => {suffix: PAGE_SUFFIX, content_type: CanvasCC::Models::ModuleItem::CONTENT_TYPE_WIKI_PAGE},
|
23
|
+
Moodle2::Models::Wiki => {suffix: PAGE_SUFFIX, content_type: CanvasCC::Models::ModuleItem::CONTENT_TYPE_WIKI_PAGE},
|
23
24
|
Moodle2::Models::Assignment => {suffix: ASSIGNMENT_SUFFIX, content_type: CanvasCC::Models::ModuleItem::CONTENT_TYPE_ASSIGNMENT},
|
24
25
|
Moodle2::Models::Folder => {suffix: FOLDER_SUFFIX, content_type: CanvasCC::Models::ModuleItem::CONTENT_TYPE_WIKI_PAGE},
|
25
26
|
Moodle2::Models::Forum => {suffix: DISCUSSION_SUFFIX, content_type: CanvasCC::Models::ModuleItem::CONTENT_TYPE_DISCUSSION_TOPIC},
|
@@ -35,6 +36,8 @@ module Moodle2CC
|
|
35
36
|
Moodle2::Models::Resource => {suffix: nil, content_type: CanvasCC::Models::ModuleItem::CONTENT_TYPE_ATTACHMENT}
|
36
37
|
}
|
37
38
|
|
39
|
+
MAX_TITLE_LENGTH = 250
|
40
|
+
|
38
41
|
def generate_unique_resource_path(base_path, readable_name, file_extension = 'html')
|
39
42
|
file_name_suffix = readable_name ? Moodle2CC::CanvasCC::Models::Page.convert_name_to_url(readable_name) : ''
|
40
43
|
ext = file_extension ? ".#{file_extension}" : ''
|
@@ -69,6 +72,17 @@ module Moodle2CC
|
|
69
72
|
moodle_visibility ? CanvasCC::Models::WorkflowState::ACTIVE : CanvasCC::Models::WorkflowState::UNPUBLISHED
|
70
73
|
end
|
71
74
|
|
75
|
+
def truncate_text(text, max_length = nil, ellipsis = '...')
|
76
|
+
max_length ||= MAX_TITLE_LENGTH
|
77
|
+
return text if !text || text.length <= max_length
|
78
|
+
|
79
|
+
actual_length = max_length - ellipsis.length
|
80
|
+
|
81
|
+
# First truncate the text down to the bytes max, then lop off any invalid
|
82
|
+
# unicode characters at the end.
|
83
|
+
truncated = text[0,actual_length][/.{0,#{actual_length}}/mu]
|
84
|
+
truncated + ellipsis
|
85
|
+
end
|
72
86
|
|
73
87
|
end
|
74
88
|
end
|
@@ -6,7 +6,7 @@ module Moodle2CC::Moodle2Converter
|
|
6
6
|
def convert(forum)
|
7
7
|
discussion = Moodle2CC::CanvasCC::Models::Discussion.new
|
8
8
|
discussion.identifier = generate_unique_identifier_for(forum.id, DISCUSSION_SUFFIX)
|
9
|
-
discussion.title = forum.name
|
9
|
+
discussion.title = truncate_text(forum.name)
|
10
10
|
discussion.text = forum.intro
|
11
11
|
discussion.discussion_type = 'threaded'
|
12
12
|
discussion.workflow_state = workflow_state(forum.visible)
|
@@ -5,7 +5,7 @@ module Moodle2CC::Moodle2Converter
|
|
5
5
|
def convert_feedback(moodle_feedback)
|
6
6
|
canvas_assessment = Moodle2CC::CanvasCC::Models::Assessment.new
|
7
7
|
canvas_assessment.identifier = generate_unique_identifier_for(moodle_feedback.id, FEEDBACK_ASSESSMENT_SUFFIX)
|
8
|
-
canvas_assessment.title = moodle_feedback.name
|
8
|
+
canvas_assessment.title = truncate_text(moodle_feedback.name)
|
9
9
|
canvas_assessment.description = moodle_feedback.intro
|
10
10
|
canvas_assessment.workflow_state = workflow_state(moodle_feedback.visible)
|
11
11
|
|
@@ -40,10 +40,10 @@ module Moodle2CC::Moodle2Converter
|
|
40
40
|
canvas_question = Moodle2CC::CanvasCC::Models::Question.create(canvas_type)
|
41
41
|
canvas_question.identifier = generate_unique_identifier_for(moodle_question.id, "_feedback_question")
|
42
42
|
if moodle_question.type == 'label'
|
43
|
-
canvas_question.title = moodle_question.name
|
43
|
+
canvas_question.title = truncate_text(moodle_question.name)
|
44
44
|
canvas_question.material = moodle_question.presentation
|
45
45
|
else
|
46
|
-
canvas_question.title = moodle_question.label
|
46
|
+
canvas_question.title = truncate_text(moodle_question.label)
|
47
47
|
canvas_question.material = moodle_question.name
|
48
48
|
end
|
49
49
|
|
@@ -17,7 +17,9 @@ module Moodle2CC::Moodle2Converter
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def convert(content)
|
20
|
-
update_links(content.gsub('id="main"', ''))
|
20
|
+
content = update_links(content.gsub('id="main"', ''))
|
21
|
+
content = convert_equations(content)
|
22
|
+
content
|
21
23
|
end
|
22
24
|
|
23
25
|
private
|
@@ -92,5 +94,18 @@ module Moodle2CC::Moodle2Converter
|
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
97
|
+
def convert_equations(content)
|
98
|
+
# turn moodle equations ( e.g. $$3 * x$$ ) into canvas equations
|
99
|
+
content.gsub(/\$\$([^\$]*)\$\$/) do |match|
|
100
|
+
latex = $1.to_s.gsub("\"", "\\\"")
|
101
|
+
if latex.length > 0
|
102
|
+
url = "/equation_images/#{CGI.escape(CGI.escape(latex).gsub("+", "%20"))}"
|
103
|
+
|
104
|
+
"<img class=\"equation_image\" title=\"#{latex}\" alt=\"#{latex}\" src=\"#{url}\">"
|
105
|
+
else
|
106
|
+
""
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
95
110
|
end
|
96
111
|
end
|
@@ -7,7 +7,7 @@ module Moodle2CC
|
|
7
7
|
module_item = CanvasCC::Models::ModuleItem.new
|
8
8
|
module_item.identifier = generate_unique_identifier
|
9
9
|
module_item.workflow_state = workflow_state(moodle_label.visible)
|
10
|
-
module_item.title = moodle_label.converted_title
|
10
|
+
module_item.title = truncate_text(moodle_label.converted_title)
|
11
11
|
module_item.indent = '0'
|
12
12
|
|
13
13
|
if moodle_label.convert_to_page?
|
@@ -25,7 +25,7 @@ module Moodle2CC
|
|
25
25
|
if moodle_label.convert_to_page?
|
26
26
|
canvas_page = CanvasCC::Models::Page.new
|
27
27
|
canvas_page.identifier = generate_unique_identifier_for_activity(moodle_label)
|
28
|
-
canvas_page.title = moodle_label.converted_title
|
28
|
+
canvas_page.title = truncate_text(moodle_label.converted_title)
|
29
29
|
canvas_page.workflow_state = workflow_state(moodle_label.visible)
|
30
30
|
canvas_page.editing_roles = CanvasCC::Models::Page::EDITING_ROLE_TEACHER
|
31
31
|
canvas_page.body = moodle_label.intro
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Moodle2CC::Moodle2Converter
|
2
2
|
class Migrator
|
3
3
|
|
4
|
+
include ConverterHelper
|
5
|
+
|
4
6
|
def initialize(source_file, output_dir)
|
5
7
|
@extractor = Moodle2CC::Moodle2::Extractor.new(source_file)
|
6
8
|
@output_dir = output_dir
|
@@ -11,6 +13,7 @@ module Moodle2CC::Moodle2Converter
|
|
11
13
|
cc_course = convert_course(moodle_course)
|
12
14
|
cc_course.files += convert_files(moodle_course.files)
|
13
15
|
cc_course.pages += convert_pages(moodle_course.pages)
|
16
|
+
cc_course.pages += convert_wikis(moodle_course.wikis)
|
14
17
|
cc_course.discussions += convert_discussions(moodle_course.forums)
|
15
18
|
cc_course.assignments += convert_assignments(moodle_course.assignments)
|
16
19
|
|
@@ -19,7 +22,6 @@ module Moodle2CC::Moodle2Converter
|
|
19
22
|
cc_course.assessments += convert_assessments(moodle_course.quizzes, moodle_course.choices,
|
20
23
|
moodle_course.feedbacks, moodle_course.questionnaires)
|
21
24
|
cc_course.question_banks += convert_question_banks(moodle_course.question_categories)
|
22
|
-
cc_course.resolve_question_references
|
23
25
|
|
24
26
|
cc_course.pages += convert_sections_to_pages(moodle_course.sections)
|
25
27
|
cc_course.pages += convert_folders(moodle_course)
|
@@ -29,8 +31,10 @@ module Moodle2CC::Moodle2Converter
|
|
29
31
|
|
30
32
|
cc_course.canvas_modules += convert_sections(moodle_course.sections)
|
31
33
|
|
34
|
+
resolve_duplicate_page_titles!(cc_course)
|
32
35
|
convert_html!(cc_course, moodle_course)
|
33
36
|
|
37
|
+
cc_course.resolve_question_references!
|
34
38
|
@path = Moodle2CC::CanvasCC::CartridgeCreator.new(cc_course).create(@output_dir)
|
35
39
|
end
|
36
40
|
@path
|
@@ -61,6 +65,11 @@ module Moodle2CC::Moodle2Converter
|
|
61
65
|
pages.map { |page| page_converter.convert(page) }
|
62
66
|
end
|
63
67
|
|
68
|
+
def convert_wikis(wikis)
|
69
|
+
wiki_converter = Moodle2CC::Moodle2Converter::WikiConverter.new
|
70
|
+
wikis.map { |wiki| wiki_converter.convert(wiki) }.flatten
|
71
|
+
end
|
72
|
+
|
64
73
|
def convert_discussions(discussions)
|
65
74
|
discussion_converter = Moodle2CC::Moodle2Converter::DiscussionConverter.new
|
66
75
|
discussions.map { |discussion| discussion_converter.convert(discussion) }
|
@@ -118,8 +127,67 @@ module Moodle2CC::Moodle2Converter
|
|
118
127
|
cc_course.pages.each {|page| page.body = html_converter.convert(page.body)}
|
119
128
|
cc_course.discussions.each {|discussion| discussion.text = html_converter.convert(discussion.text)}
|
120
129
|
cc_course.assignments.each {|assignment| assignment.body = html_converter.convert(assignment.body)}
|
121
|
-
|
130
|
+
|
131
|
+
cc_course.assessments.each do |assessment|
|
132
|
+
assessment.description = html_converter.convert(assessment.description)
|
133
|
+
|
134
|
+
next unless assessment.items
|
135
|
+
assessment.items.each do |item|
|
136
|
+
if item.is_a?(Moodle2CC::CanvasCC::Models::QuestionGroup)
|
137
|
+
item.questions.each do |question|
|
138
|
+
convert_question_html!(question, html_converter)
|
139
|
+
end
|
140
|
+
elsif item.is_a?(Moodle2CC::CanvasCC::Models::Question)
|
141
|
+
convert_question_html!(item, html_converter)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
cc_course.question_banks.each do |question_bank|
|
147
|
+
question_bank.questions.each do |question|
|
148
|
+
convert_question_html!(question, html_converter)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def convert_question_html!(question, html_converter)
|
154
|
+
question.material = html_converter.convert(question.material)
|
155
|
+
question.general_feedback = html_converter.convert(question.general_feedback) if question.general_feedback
|
156
|
+
|
157
|
+
question.answers.each do |answer|
|
158
|
+
answer.answer_text = html_converter.convert(answer.answer_text)
|
159
|
+
answer.feedback = html_converter.convert(answer.feedback) if answer.feedback
|
160
|
+
end
|
161
|
+
|
162
|
+
question.post_process! if question.is_a?(Moodle2CC::CanvasCC::Models::CalculatedQuestion)
|
122
163
|
end
|
123
164
|
|
165
|
+
def resolve_duplicate_page_titles!(cc_course)
|
166
|
+
page_titles = cc_course.pages.map(&:title)
|
167
|
+
duplicate_page_map = cc_course.pages.group_by(&:title).select{|k, v| v.count > 1}
|
168
|
+
duplicate_page_map.each do |title, dup_pages|
|
169
|
+
dup_pages.sort_by!{|page| find_module_index_for_page(cc_course, page)}
|
170
|
+
|
171
|
+
dup_pages.each_with_index do |page, index|
|
172
|
+
next if index == 0
|
173
|
+
num = index + 1
|
174
|
+
while (title = "#{page.title}-#{num}") && page_titles.include?(title)
|
175
|
+
num += 1
|
176
|
+
end
|
177
|
+
page.title = title
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def find_module_index_for_page(cc_course, canvas_page)
|
183
|
+
cc_course.canvas_modules.each_with_index do |canvas_module, module_index|
|
184
|
+
canvas_module.module_items.each_with_index do |module_item, item_index|
|
185
|
+
if module_item.identifierref.to_s == canvas_page.identifier.to_s
|
186
|
+
return [module_index, item_index]
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
[Float::INFINITY]
|
191
|
+
end
|
124
192
|
end
|
125
193
|
end
|