moodle2cc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. data/.gitignore +20 -0
  2. data/Gemfile +4 -0
  3. data/Guardfile +14 -0
  4. data/LICENSE +661 -0
  5. data/README.md +38 -0
  6. data/Rakefile +12 -0
  7. data/bin/moodle2cc +6 -0
  8. data/lib/moodle2cc.rb +60 -0
  9. data/lib/moodle2cc/canvas/.converter.rb.swo +0 -0
  10. data/lib/moodle2cc/canvas/.wiki.rb.swo +0 -0
  11. data/lib/moodle2cc/canvas/assessment.rb +109 -0
  12. data/lib/moodle2cc/canvas/assignment.rb +108 -0
  13. data/lib/moodle2cc/canvas/converter.rb +28 -0
  14. data/lib/moodle2cc/canvas/course.rb +145 -0
  15. data/lib/moodle2cc/canvas/discussion_topic.rb +64 -0
  16. data/lib/moodle2cc/canvas/label.rb +8 -0
  17. data/lib/moodle2cc/canvas/question.rb +468 -0
  18. data/lib/moodle2cc/canvas/question_bank.rb +54 -0
  19. data/lib/moodle2cc/canvas/resource.rb +16 -0
  20. data/lib/moodle2cc/canvas/templates/assignment.html.erb +9 -0
  21. data/lib/moodle2cc/canvas/templates/syllabus.html.erb +9 -0
  22. data/lib/moodle2cc/canvas/templates/wiki_content.html.erb +10 -0
  23. data/lib/moodle2cc/canvas/web_content.rb +10 -0
  24. data/lib/moodle2cc/canvas/web_link.rb +17 -0
  25. data/lib/moodle2cc/canvas/wiki.rb +25 -0
  26. data/lib/moodle2cc/cc/assessment.rb +25 -0
  27. data/lib/moodle2cc/cc/assignment.rb +66 -0
  28. data/lib/moodle2cc/cc/cc_helper.rb +282 -0
  29. data/lib/moodle2cc/cc/converter.rb +136 -0
  30. data/lib/moodle2cc/cc/course.rb +16 -0
  31. data/lib/moodle2cc/cc/discussion_topic.rb +53 -0
  32. data/lib/moodle2cc/cc/label.rb +6 -0
  33. data/lib/moodle2cc/cc/question.rb +23 -0
  34. data/lib/moodle2cc/cc/resource.rb +30 -0
  35. data/lib/moodle2cc/cc/templates/assignment.html.erb +9 -0
  36. data/lib/moodle2cc/cc/templates/syllabus.html.erb +9 -0
  37. data/lib/moodle2cc/cc/templates/wiki_content.html.erb +10 -0
  38. data/lib/moodle2cc/cc/web_content.rb +40 -0
  39. data/lib/moodle2cc/cc/web_link.rb +53 -0
  40. data/lib/moodle2cc/cc/wiki.rb +72 -0
  41. data/lib/moodle2cc/cli.rb +14 -0
  42. data/lib/moodle2cc/error.rb +3 -0
  43. data/lib/moodle2cc/migrator.rb +23 -0
  44. data/lib/moodle2cc/moodle/backup.rb +38 -0
  45. data/lib/moodle2cc/moodle/course.rb +24 -0
  46. data/lib/moodle2cc/moodle/grade_item.rb +24 -0
  47. data/lib/moodle2cc/moodle/info.rb +8 -0
  48. data/lib/moodle2cc/moodle/mod.rb +127 -0
  49. data/lib/moodle2cc/moodle/question.rb +98 -0
  50. data/lib/moodle2cc/moodle/question_category.rb +17 -0
  51. data/lib/moodle2cc/moodle/section.rb +37 -0
  52. data/lib/moodle2cc/resource_factory.rb +32 -0
  53. data/lib/moodle2cc/version.rb +3 -0
  54. data/moodle2cc.gemspec +29 -0
  55. data/test/acceptance/migrator_test.rb +23 -0
  56. data/test/fixtures/cc.imscc +0 -0
  57. data/test/fixtures/moodle_backup/course_files/folder/test.txt +1 -0
  58. data/test/fixtures/moodle_backup/course_files/test.txt +1 -0
  59. data/test/fixtures/moodle_backup/moodle.xml +916 -0
  60. data/test/test_helper.rb +43 -0
  61. data/test/test_question_helper.rb +107 -0
  62. data/test/test_wiki_helper.rb +21 -0
  63. data/test/unit/canvas/assessment_test.rb +218 -0
  64. data/test/unit/canvas/assignment_test.rb +220 -0
  65. data/test/unit/canvas/converter_test.rb +159 -0
  66. data/test/unit/canvas/course_test.rb +176 -0
  67. data/test/unit/canvas/discussion_topic_test.rb +129 -0
  68. data/test/unit/canvas/label_test.rb +32 -0
  69. data/test/unit/canvas/question_bank_test.rb +73 -0
  70. data/test/unit/canvas/question_test.rb +824 -0
  71. data/test/unit/canvas/web_content_test.rb +37 -0
  72. data/test/unit/canvas/web_link_test.rb +48 -0
  73. data/test/unit/canvas/wiki_test.rb +74 -0
  74. data/test/unit/cc/assessment_test.rb +48 -0
  75. data/test/unit/cc/assignment_test.rb +67 -0
  76. data/test/unit/cc/cc_helper_test.rb +19 -0
  77. data/test/unit/cc/converter_test.rb +159 -0
  78. data/test/unit/cc/course_test.rb +36 -0
  79. data/test/unit/cc/discussion_topic_test.rb +83 -0
  80. data/test/unit/cc/label_test.rb +29 -0
  81. data/test/unit/cc/question_test.rb +49 -0
  82. data/test/unit/cc/web_content_test.rb +76 -0
  83. data/test/unit/cc/web_link_test.rb +79 -0
  84. data/test/unit/cc/wiki_test.rb +139 -0
  85. data/test/unit/migrator_test.rb +56 -0
  86. data/test/unit/moodle/backup_test.rb +30 -0
  87. data/test/unit/moodle/course_test.rb +57 -0
  88. data/test/unit/moodle/grade_item_test.rb +72 -0
  89. data/test/unit/moodle/info_test.rb +21 -0
  90. data/test/unit/moodle/mod_test.rb +301 -0
  91. data/test/unit/moodle/question_category_test.rb +34 -0
  92. data/test/unit/moodle/question_test.rb +185 -0
  93. data/test/unit/moodle/section_test.rb +75 -0
  94. data/test/unit/resource_factory_test.rb +119 -0
  95. metadata +342 -0
@@ -0,0 +1,136 @@
1
+ module Moodle2CC::CC
2
+ class Converter
3
+ include CCHelper
4
+
5
+ def initialize(moodle_backup, destination_dir)
6
+ @resource_factory = Moodle2CC::ResourceFactory.new Moodle2CC::CC
7
+ @moodle_backup = moodle_backup
8
+ @export_dir = Dir.mktmpdir
9
+ @destination_dir = destination_dir
10
+ end
11
+
12
+ def imscc_file_name
13
+ "#{file_slug(@moodle_backup.course.fullname)}.imscc"
14
+ end
15
+
16
+ def imscc_path
17
+ @imscc_path ||= File.join(@destination_dir, imscc_file_name)
18
+ end
19
+
20
+ def imscc_tmp_path
21
+ @imscc_tmp_path ||= File.join(@export_dir, imscc_file_name)
22
+ end
23
+
24
+ def convert
25
+ File.open(File.join(@export_dir, MANIFEST), 'w') do |file|
26
+ @document = Builder::XmlMarkup.new(:target => file, :indent => 2)
27
+ @document.instruct!
28
+ create_manifest
29
+ end
30
+ create_web_resources
31
+ Zip::ZipFile.open(imscc_tmp_path, Zip::ZipFile::CREATE) do |zipfile|
32
+ Dir["#{@export_dir}/**/*"].each do |file|
33
+ zipfile.add(file.sub(@export_dir + '/', ''), file)
34
+ end
35
+ end
36
+ FileUtils.mv imscc_tmp_path, imscc_path
37
+ FileUtils.rm_r @export_dir
38
+ end
39
+
40
+ def create_manifest
41
+ @document.manifest(
42
+ "identifier" => create_key(@moodle_backup.course.id, "common_cartridge_"),
43
+ "xmlns" => "http://www.imsglobal.org/xsd/imsccv1p1/imscp_v1p1",
44
+ "xmlns:lom" => "http://ltsc.ieee.org/xsd/imsccv1p1/LOM/resource",
45
+ "xmlns:lomimscc" => "http://ltsc.ieee.org/xsd/imsccv1p1/LOM/manifest",
46
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
47
+ "xsi:schemaLocation" => "http://www.imsglobal.org/xsd/imsccv1p1/imscp_v1p1 http://www.imsglobal.org/profile/cc/ccv1p1/ccv1p1_imscp_v1p2_v1p0.xsd http://ltsc.ieee.org/xsd/imsccv1p1/LOM/resource http://www.imsglobal.org/profile/cc/ccv1p1/LOM/ccv1p1_lomresource_v1p0.xsd http://ltsc.ieee.org/xsd/imsccv1p1/LOM/manifest http://www.imsglobal.org/profile/cc/ccv1p1/LOM/ccv1p1_lommanifest_v1p0.xsd"
48
+ ) do |manifest_node|
49
+ @manifest_node = manifest_node
50
+ @manifest_node.metadata do |md|
51
+ md.schema "IMS Common Cartridge"
52
+ md.schemaversion "1.1.0"
53
+ md.lomimscc :lom do |lom|
54
+ lom.lomimscc :general do |general|
55
+ general.lomimscc :title do |title|
56
+ title.lomimscc :string, @moodle_backup.course.fullname
57
+ end
58
+ end
59
+ lom.lomimscc :lifeCycle do |lifecycle|
60
+ lifecycle.lomimscc :contribute do |contribute|
61
+ contribute.lomimscc :date do |date|
62
+ date.lomimscc :dateTime, ims_date
63
+ end
64
+ end
65
+ end
66
+ lom.lomimscc :rights do |rights|
67
+ rights.lomimscc :copyrightAndOtherRestrictions do |node|
68
+ node.lomimscc :value, 'yes'
69
+ end
70
+ rights.lomimscc :description do |desc|
71
+ desc.lomimscc :string, 'Private (Copyrighted) - http://en.wikipedia.org/wiki/Copyright'
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ create_organizations
78
+
79
+ @manifest_node.resources do |resources_node|
80
+ create_resources(resources_node)
81
+ end
82
+ end
83
+ end
84
+
85
+ def create_organizations
86
+ course = Course.new(@moodle_backup.course)
87
+ @manifest_node.organizations do |orgs|
88
+ orgs.organization(
89
+ :identifier => 'org_1',
90
+ :structure => 'rooted-hierarchy'
91
+ ) do |org|
92
+ org.item(:identifier => "LearningModules") do |root_item|
93
+ @moodle_backup.course.sections.each do |section|
94
+ next unless section.visible
95
+ root_item.item(:identifier => create_key(section.id, "section_")) do |item_node|
96
+ item_node.title "#{course.format} #{section.number}"
97
+ section.mods.each do |mod|
98
+ resource = @resource_factory.get_resource_from_mod(mod.instance)
99
+ resource.create_organization_item_node(item_node) if resource
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def create_resources(resources_node)
109
+ @moodle_backup.course.mods.each_with_index do |mod, index|
110
+ resource = @resource_factory.get_resource_from_mod(mod, index)
111
+ if resource
112
+ resource.create_resource_node(resources_node)
113
+ resource.create_files(@export_dir)
114
+ end
115
+ end
116
+
117
+ @moodle_backup.files.each do |file|
118
+ href = File.join(WEB_RESOURCES_FOLDER, file)
119
+ resources_node.resource(
120
+ :type => WEBCONTENT,
121
+ :identifier => create_key(href, 'resource_'),
122
+ :href => href
123
+ ) do |resource_node|
124
+ resource_node.file(:href => href)
125
+ end
126
+ end
127
+ end
128
+
129
+ def create_web_resources
130
+ web_resources_folder = File.join(@export_dir, WEB_RESOURCES_FOLDER)
131
+ FileUtils.mkdir(web_resources_folder)
132
+ @moodle_backup.copy_files_to(web_resources_folder)
133
+ end
134
+
135
+ end
136
+ end
@@ -0,0 +1,16 @@
1
+ module Moodle2CC::CC
2
+ class Course
3
+ include CCHelper
4
+
5
+ attr_accessor :format
6
+
7
+ def initialize(course)
8
+ @format = case course.format
9
+ when 'weeks', 'weekscss'
10
+ 'Week'
11
+ else
12
+ 'Topic'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,53 @@
1
+ module Moodle2CC
2
+ module CC
3
+ class DiscussionTopic
4
+ include CCHelper
5
+ include Resource
6
+
7
+ attr_accessor :text
8
+
9
+ def initialize(mod, position=0)
10
+ super
11
+ @text = convert_file_path_tokens(mod.intro)
12
+ end
13
+
14
+ def identifierref
15
+ create_key(id, 'topic_meta_')
16
+ end
17
+
18
+ def create_resource_node(resources_node)
19
+ resources_node.resource(
20
+ :type => DISCUSSION_TOPIC,
21
+ :identifier => identifier
22
+ ) do |resource_node|
23
+ resource_node.file(:href => "#{identifier}.xml")
24
+ create_resource_sub_nodes(resource_node)
25
+ end
26
+ end
27
+
28
+ def create_resource_sub_nodes(resource_node)
29
+ end
30
+
31
+ def create_files(export_dir)
32
+ create_topic_xml(export_dir)
33
+ end
34
+
35
+ def create_topic_xml(export_dir)
36
+ path = File.join(export_dir, "#{identifier}.xml")
37
+ File.open(path, 'w') do |file|
38
+ document = Builder::XmlMarkup.new(:target => file, :indent => 2)
39
+ document.instruct!
40
+ document.topicMeta(
41
+ :identifier => identifierref,
42
+ 'xsi:schemaLocation' => "http://www.imsglobal.org/xsd/imsccv1p1/imsdt_v1p1 http://www.imsglobal.org/profile/cc/ccv1p1/ccv1p1_imsdt_v1p1.xsd",
43
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
44
+ 'xmlns' => "http://www.imsglobal.org/xsd/imsccv1p1/imsdt_v1p1"
45
+ ) do |topic|
46
+ topic.title @title
47
+ topic.text @text, :texttype => 'text/html'
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,6 @@
1
+ module Moodle2CC::CC
2
+ class Label
3
+ include CCHelper
4
+ include Resource
5
+ end
6
+ end
@@ -0,0 +1,23 @@
1
+ module Moodle2CC::CC
2
+ class Question
3
+ include CCHelper
4
+
5
+ attr_accessor :id, :title, :identifier
6
+
7
+ def initialize(question, assessment=nil)
8
+ @id = question.id
9
+ @title = (question.name || '').gsub('$@NULL@$', '')
10
+ @identifier_prefix = "#{assessment.mod.mod_type}_" if assessment
11
+
12
+ if question.instance_id
13
+ @identifier = create_key(question.instance_id, "#{@identifier_prefix}question_instance_")
14
+ else
15
+ @identifier = create_key(question.id, "#{@identifier_prefix}question_")
16
+ end
17
+ end
18
+
19
+ def create_item_xml(section_node)
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ module Moodle2CC::CC
2
+ module Resource
3
+ def self.included(klass)
4
+ klass.class_eval do
5
+ attr_accessor :mod, :identifier, :id, :title, :indent
6
+ end
7
+ end
8
+
9
+ def initialize(mod, *args)
10
+ @mod = mod
11
+ @id = mod.id
12
+ @title = mod.name
13
+ @indent = mod.section_mod.nil? ? 0 : mod.section_mod.indent
14
+ @identifier = create_resource_key(mod)
15
+ end
16
+
17
+ def create_files(export_dir)
18
+ end
19
+
20
+ def create_resource_node(resources_node)
21
+ end
22
+
23
+ def create_organization_item_node(item_node)
24
+ item_node.item(:identifier => create_mod_key(@mod), :identifierref => @identifier) do |sub_item|
25
+ sub_item.title @title
26
+ end
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
4
+ <title>Assignment: <%= title %></title>
5
+ </head>
6
+ <body>
7
+ <%= body %>
8
+ </body>
9
+ </html>
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
4
+ <title>Syllabus</title>
5
+ </head>
6
+ <body>
7
+ <%= syllabus_body %>
8
+ </body>
9
+ </html>
@@ -0,0 +1,10 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
4
+ <title><%= title %></title>
5
+ <meta name="identifier" content="<%= identifier %>"/>
6
+ </head>
7
+ <body>
8
+ <%= body %>
9
+ </body>
10
+ </html>
@@ -0,0 +1,40 @@
1
+ module Moodle2CC::CC
2
+ class WebContent
3
+ include CCHelper
4
+ include Resource
5
+
6
+ attr_accessor :body
7
+
8
+ def initialize(mod)
9
+ super
10
+ body = mod.alltext
11
+ body = mod.content || '' if body.nil? || body.length == 0
12
+ @body = convert_file_path_tokens(body)
13
+ end
14
+
15
+ def create_resource_node(resources_node)
16
+ href = File.join(WIKI_FOLDER, "#{file_slug(@title)}.html")
17
+ resources_node.resource(
18
+ :type => WEBCONTENT,
19
+ :identifier => identifier,
20
+ :href => href
21
+ ) do |resource_node|
22
+ resource_node.file(:href => href)
23
+ end
24
+ end
25
+
26
+ def create_files(export_dir)
27
+ create_html(export_dir)
28
+ end
29
+
30
+ def create_html(export_dir)
31
+ template = File.expand_path('../templates/wiki_content.html.erb', __FILE__)
32
+ path = File.join(export_dir, 'wiki_content', "#{file_slug(title)}.html")
33
+ FileUtils.mkdir_p(File.dirname(path))
34
+ File.open(path, 'w') do |file|
35
+ erb = ERB.new(File.read(template))
36
+ file.write(erb.result(binding))
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,53 @@
1
+ module Moodle2CC::CC
2
+ class WebLink
3
+ include CCHelper
4
+ include Resource
5
+
6
+ attr_accessor :url
7
+
8
+ def initialize(mod)
9
+ super
10
+ @url = mod.reference
11
+ end
12
+
13
+ def self.create_resource_key(mod)
14
+ if !URI.parse(mod.reference).scheme
15
+ create_key(File.join(WEB_RESOURCES_FOLDER, mod.reference), 'resource_')
16
+ else
17
+ super
18
+ end
19
+ end
20
+
21
+ def create_resource_node(resources_node)
22
+ resources_node.resource(
23
+ :type => WEB_LINK,
24
+ :identifier => identifier
25
+ ) do |resource_node|
26
+ resource_node.file(:href => "#{identifier}.xml")
27
+ end
28
+ end
29
+
30
+ def create_files(export_dir)
31
+ create_xml(export_dir)
32
+ end
33
+
34
+ def create_xml(export_dir)
35
+ path = File.join(export_dir, "#{identifier}.xml")
36
+ FileUtils.mkdir_p(File.dirname(path))
37
+ File.open(path, 'w') do |file|
38
+ settings_node = Builder::XmlMarkup.new(:target => file, :indent => 2)
39
+ settings_node.instruct!
40
+ settings_node.webLink(
41
+ :identifier => identifier,
42
+ 'xsi:schemaLocation' => "http://www.imsglobal.org/xsd/imsccv1p1/imswl_v1p1 http://www.imsglobal.org/profile/cc/ccv1p1/ccv1p1_imswl_v1p1.xsd",
43
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
44
+ 'xmlns' => "http://www.imsglobal.org/xsd/imsccv1p1/imswl_v1p1"
45
+ ) do |web_link_node|
46
+ web_link_node.title @title
47
+ web_link_node.url(:href => @url)
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,72 @@
1
+ module Moodle2CC::CC
2
+ class Wiki
3
+ include CCHelper
4
+ include Resource
5
+
6
+ attr_accessor :pages
7
+
8
+ def initialize(mod)
9
+ super
10
+ page_versions = mod.pages.inject({}) do |result, page|
11
+ version = result[page.page_name]
12
+ result[page.page_name] = page.version if version.nil? || page.version > version
13
+ result
14
+ end
15
+
16
+ @pages = mod.pages.map do |page|
17
+ if page.version == page_versions[page.page_name]
18
+ title_slug = file_slug(@title)
19
+ body = page.content
20
+ slug = [title_slug, file_slug(page.page_name)].join('-')
21
+ href = "#{WIKI_FOLDER}/#{slug}.html"
22
+ Moodle2CC::OpenStruct.new(:title => page.page_name, :body => body, :href => href, :identifier => create_key(href))
23
+ end
24
+ end.compact
25
+
26
+ if @pages.empty?
27
+ slug = file_slug(@title)
28
+ href = File.join(WIKI_FOLDER, "#{slug}.html")
29
+ @pages = [Moodle2CC::OpenStruct.new(:title => @title, :body => mod.summary, :href => href, :identifier => create_key(href))]
30
+ end
31
+
32
+ @identifier = root_page.identifier
33
+ end
34
+
35
+ def self.create_resource_key(mod)
36
+ Wiki.new(mod).identifer
37
+ end
38
+
39
+ def root_page
40
+ @pages.find { |page| page.title == @title }
41
+ end
42
+
43
+ def create_resource_node(resources_node)
44
+ @pages.each do |page|
45
+ href = page.href
46
+ resources_node.resource(
47
+ :href => href,
48
+ :type => WEBCONTENT,
49
+ :identifier => create_key(href)
50
+ ) do |resource_node|
51
+ resource_node.file(:href => href)
52
+ end
53
+ end
54
+ end
55
+
56
+ def create_files(export_dir)
57
+ create_html(export_dir)
58
+ end
59
+
60
+ def create_html(export_dir)
61
+ template = File.expand_path('../templates/wiki_content.html.erb', __FILE__)
62
+ @pages.each do |page|
63
+ path = File.join(export_dir, page.href)
64
+ FileUtils.mkdir_p(File.dirname(path))
65
+ File.open(path, 'w') do |file|
66
+ erb = ERB.new(File.read(template))
67
+ file.write(erb.result(page.instance_eval { binding }))
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end