canvas_cc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +1 -0
  7. data/canvas_cc.gemspec +37 -0
  8. data/lib/canvas_cc/canvas/assessment.rb +124 -0
  9. data/lib/canvas_cc/canvas/assignment.rb +98 -0
  10. data/lib/canvas_cc/canvas/converter.rb +30 -0
  11. data/lib/canvas_cc/canvas/course.rb +143 -0
  12. data/lib/canvas_cc/canvas/discussion_topic.rb +64 -0
  13. data/lib/canvas_cc/canvas/label.rb +8 -0
  14. data/lib/canvas_cc/canvas/question.rb +492 -0
  15. data/lib/canvas_cc/canvas/question_bank.rb +57 -0
  16. data/lib/canvas_cc/canvas/question_group.rb +35 -0
  17. data/lib/canvas_cc/canvas/resource.rb +16 -0
  18. data/lib/canvas_cc/canvas/templates/assignment.html.erb +9 -0
  19. data/lib/canvas_cc/canvas/templates/syllabus.html.erb +9 -0
  20. data/lib/canvas_cc/canvas/templates/wiki_content.html.erb +10 -0
  21. data/lib/canvas_cc/canvas/web_content.rb +15 -0
  22. data/lib/canvas_cc/canvas/web_link.rb +16 -0
  23. data/lib/canvas_cc/canvas/wiki.rb +26 -0
  24. data/lib/canvas_cc/canvas_cc/assessment_writer.rb +82 -0
  25. data/lib/canvas_cc/canvas_cc/assignment_group_writer.rb +48 -0
  26. data/lib/canvas_cc/canvas_cc/assignment_writer.rb +68 -0
  27. data/lib/canvas_cc/canvas_cc/calculated_question_writer.rb +72 -0
  28. data/lib/canvas_cc/canvas_cc/canvas_export_writer.rb +18 -0
  29. data/lib/canvas_cc/canvas_cc/cartridge_creator.rb +60 -0
  30. data/lib/canvas_cc/canvas_cc/course_setting_writer.rb +35 -0
  31. data/lib/canvas_cc/canvas_cc/discussion_writer.rb +52 -0
  32. data/lib/canvas_cc/canvas_cc/essay_question_writer.rb +19 -0
  33. data/lib/canvas_cc/canvas_cc/file_meta_writer.rb +38 -0
  34. data/lib/canvas_cc/canvas_cc/ims_manifest_generator.rb +123 -0
  35. data/lib/canvas_cc/canvas_cc/matching_question_writer.rb +43 -0
  36. data/lib/canvas_cc/canvas_cc/models/answer.rb +12 -0
  37. data/lib/canvas_cc/canvas_cc/models/assessment.rb +102 -0
  38. data/lib/canvas_cc/canvas_cc/models/assignment.rb +30 -0
  39. data/lib/canvas_cc/canvas_cc/models/assignment_group.rb +9 -0
  40. data/lib/canvas_cc/canvas_cc/models/calculated_question.rb +19 -0
  41. data/lib/canvas_cc/canvas_cc/models/canvas_file.rb +22 -0
  42. data/lib/canvas_cc/canvas_cc/models/canvas_module.rb +10 -0
  43. data/lib/canvas_cc/canvas_cc/models/course.rb +53 -0
  44. data/lib/canvas_cc/canvas_cc/models/discussion.rb +36 -0
  45. data/lib/canvas_cc/canvas_cc/models/discussion_topic.rb +5 -0
  46. data/lib/canvas_cc/canvas_cc/models/matching_question.rb +7 -0
  47. data/lib/canvas_cc/canvas_cc/models/module_item.rb +16 -0
  48. data/lib/canvas_cc/canvas_cc/models/multiple_dropdowns_question.rb +7 -0
  49. data/lib/canvas_cc/canvas_cc/models/numerical_question.rb +7 -0
  50. data/lib/canvas_cc/canvas_cc/models/page.rb +41 -0
  51. data/lib/canvas_cc/canvas_cc/models/question.rb +37 -0
  52. data/lib/canvas_cc/canvas_cc/models/question_bank.rb +42 -0
  53. data/lib/canvas_cc/canvas_cc/models/question_group.rb +10 -0
  54. data/lib/canvas_cc/canvas_cc/models/resource.rb +23 -0
  55. data/lib/canvas_cc/canvas_cc/models/web_content.rb +7 -0
  56. data/lib/canvas_cc/canvas_cc/models/web_link.rb +7 -0
  57. data/lib/canvas_cc/canvas_cc/models/workflow_state.rb +6 -0
  58. data/lib/canvas_cc/canvas_cc/module_meta_writer.rb +52 -0
  59. data/lib/canvas_cc/canvas_cc/multiple_answers_question_writer.rb +41 -0
  60. data/lib/canvas_cc/canvas_cc/multiple_blanks_question_writer.rb +51 -0
  61. data/lib/canvas_cc/canvas_cc/multiple_choice_question_writer.rb +48 -0
  62. data/lib/canvas_cc/canvas_cc/multiple_dropdowns_question_writer.rb +30 -0
  63. data/lib/canvas_cc/canvas_cc/numerical_question_writer.rb +40 -0
  64. data/lib/canvas_cc/canvas_cc/page_writer.rb +38 -0
  65. data/lib/canvas_cc/canvas_cc/question_bank_writer.rb +44 -0
  66. data/lib/canvas_cc/canvas_cc/question_group_writer.rb +23 -0
  67. data/lib/canvas_cc/canvas_cc/question_writer.rb +129 -0
  68. data/lib/canvas_cc/canvas_cc/short_answer_question_writer.rb +42 -0
  69. data/lib/canvas_cc/canvas_cc/text_only_question_writer.rb +19 -0
  70. data/lib/canvas_cc/canvas_cc/true_false_question_writer.rb +38 -0
  71. data/lib/canvas_cc/cc/assessment.rb +25 -0
  72. data/lib/canvas_cc/cc/assignment.rb +61 -0
  73. data/lib/canvas_cc/cc/cc_helper.rb +285 -0
  74. data/lib/canvas_cc/cc/converter.rb +137 -0
  75. data/lib/canvas_cc/cc/course.rb +16 -0
  76. data/lib/canvas_cc/cc/discussion_topic.rb +53 -0
  77. data/lib/canvas_cc/cc/label.rb +6 -0
  78. data/lib/canvas_cc/cc/question.rb +23 -0
  79. data/lib/canvas_cc/cc/resource.rb +30 -0
  80. data/lib/canvas_cc/cc/templates/assignment.html.erb +13 -0
  81. data/lib/canvas_cc/cc/templates/syllabus.html.erb +9 -0
  82. data/lib/canvas_cc/cc/templates/wiki_content.html.erb +10 -0
  83. data/lib/canvas_cc/cc/web_content.rb +48 -0
  84. data/lib/canvas_cc/cc/web_link.rb +75 -0
  85. data/lib/canvas_cc/cc/wiki.rb +73 -0
  86. data/lib/canvas_cc/version.rb +3 -0
  87. data/lib/canvas_cc.rb +94 -0
  88. data/spec/moodle2cc/canvas_cc/assessment_writer_spec.rb +95 -0
  89. data/spec/moodle2cc/canvas_cc/assignment_group_writer_spec.rb +51 -0
  90. data/spec/moodle2cc/canvas_cc/assignment_writer_spec.rb +74 -0
  91. data/spec/moodle2cc/canvas_cc/calculated_question_writer_spec.rb +88 -0
  92. data/spec/moodle2cc/canvas_cc/canvas_export_writer_spec.rb +26 -0
  93. data/spec/moodle2cc/canvas_cc/cartridge_creator_spec.rb +50 -0
  94. data/spec/moodle2cc/canvas_cc/course_setting_writer_spec.rb +47 -0
  95. data/spec/moodle2cc/canvas_cc/discussion_writer_spec.rb +38 -0
  96. data/spec/moodle2cc/canvas_cc/essay_question_writer_spec.rb +31 -0
  97. data/spec/moodle2cc/canvas_cc/file_meta_writer_spec.rb +57 -0
  98. data/spec/moodle2cc/canvas_cc/ims_manifest_generator_spec.rb +141 -0
  99. data/spec/moodle2cc/canvas_cc/matching_question_writer_spec.rb +51 -0
  100. data/spec/moodle2cc/canvas_cc/models/assessment_spec.rb +131 -0
  101. data/spec/moodle2cc/canvas_cc/models/assignment_group_spec.rb +9 -0
  102. data/spec/moodle2cc/canvas_cc/models/assignment_spec.rb +45 -0
  103. data/spec/moodle2cc/canvas_cc/models/calculated_question_spec.rb +25 -0
  104. data/spec/moodle2cc/canvas_cc/models/canvas_file_spec.rb +23 -0
  105. data/spec/moodle2cc/canvas_cc/models/canvas_module_spec.rb +16 -0
  106. data/spec/moodle2cc/canvas_cc/models/course_spec.rb +43 -0
  107. data/spec/moodle2cc/canvas_cc/models/discussion_spec.rb +47 -0
  108. data/spec/moodle2cc/canvas_cc/models/discussion_topic_spec.rb +7 -0
  109. data/spec/moodle2cc/canvas_cc/models/module_item_spec.rb +15 -0
  110. data/spec/moodle2cc/canvas_cc/models/page_spec.rb +34 -0
  111. data/spec/moodle2cc/canvas_cc/models/question_spec.rb +8 -0
  112. data/spec/moodle2cc/canvas_cc/models/resource_spec.rb +17 -0
  113. data/spec/moodle2cc/canvas_cc/models/web_content_spec.rb +7 -0
  114. data/spec/moodle2cc/canvas_cc/models/web_link_spec.rb +9 -0
  115. data/spec/moodle2cc/canvas_cc/module_meta_writer_spec.rb +118 -0
  116. data/spec/moodle2cc/canvas_cc/multiple_answers_question_writer_spec.rb +50 -0
  117. data/spec/moodle2cc/canvas_cc/multiple_blanks_question_writer_spec.rb +77 -0
  118. data/spec/moodle2cc/canvas_cc/multiple_choice_question_writer_spec.rb +69 -0
  119. data/spec/moodle2cc/canvas_cc/multiple_dropdowns_question_writer_spec.rb +46 -0
  120. data/spec/moodle2cc/canvas_cc/numerical_question_writer_spec.rb +69 -0
  121. data/spec/moodle2cc/canvas_cc/page_writer_spec.rb +29 -0
  122. data/spec/moodle2cc/canvas_cc/question_bank_writer_spec.rb +43 -0
  123. data/spec/moodle2cc/canvas_cc/question_writer_spec.rb +129 -0
  124. data/spec/moodle2cc/canvas_cc/short_answer_question_writer_spec.rb +50 -0
  125. data/spec/moodle2cc/canvas_cc/text_only_question_writer_spec.rb +23 -0
  126. data/spec/moodle2cc/canvas_cc/true_false_question_writer_spec.rb +62 -0
  127. data/spec/spec_helper.rb +12 -0
  128. data/spec/support/shared_examples_for_models.rb +26 -0
  129. data/test/acceptance/migrator_test.rb +24 -0
  130. data/test/fixtures/cc.imscc +0 -0
  131. data/test/fixtures/common_cartridge/ims_manifest_simple.xml +45 -0
  132. data/test/fixtures/common_cartridge/schema/cccv1p0.xsd +563 -0
  133. data/test/fixtures/common_cartridge/schema/ccv1p1_imsccauth_v1p1.xsd +203 -0
  134. data/test/fixtures/common_cartridge/schema/ccv1p1_imscp_v1p2_v1p0.xsd +827 -0
  135. data/test/fixtures/common_cartridge/schema/ccv1p1_lommanifest_v1p0.xsd +822 -0
  136. data/test/fixtures/common_cartridge/schema/ccv1p1_lomresource_v1p0.xsd +273 -0
  137. data/test/fixtures/common_cartridge/schema/xml.xsd +286 -0
  138. data/test/test_helper.rb +71 -0
  139. data/test/test_question_helper.rb +122 -0
  140. data/test/test_wiki_helper.rb +21 -0
  141. data/test/unit/canvas/assessment_test.rb +261 -0
  142. data/test/unit/canvas/assignment_test.rb +220 -0
  143. data/test/unit/canvas/converter_test.rb +171 -0
  144. data/test/unit/canvas/course_test.rb +176 -0
  145. data/test/unit/canvas/discussion_topic_test.rb +129 -0
  146. data/test/unit/canvas/label_test.rb +32 -0
  147. data/test/unit/canvas/question_bank_test.rb +92 -0
  148. data/test/unit/canvas/question_group_test.rb +90 -0
  149. data/test/unit/canvas/question_test.rb +876 -0
  150. data/test/unit/canvas/web_content_test.rb +46 -0
  151. data/test/unit/canvas/web_link_test.rb +48 -0
  152. data/test/unit/canvas/wiki_test.rb +74 -0
  153. data/test/unit/cc/assessment_test.rb +48 -0
  154. data/test/unit/cc/assignment_test.rb +72 -0
  155. data/test/unit/cc/cc_helper_test.rb +19 -0
  156. data/test/unit/cc/converter_test.rb +173 -0
  157. data/test/unit/cc/course_test.rb +36 -0
  158. data/test/unit/cc/discussion_topic_test.rb +83 -0
  159. data/test/unit/cc/label_test.rb +29 -0
  160. data/test/unit/cc/question_test.rb +54 -0
  161. data/test/unit/cc/web_content_test.rb +76 -0
  162. data/test/unit/cc/web_link_test.rb +159 -0
  163. data/test/unit/cc/wiki_test.rb +139 -0
  164. data/test/unit/logger_test.rb +33 -0
  165. data/test/unit/migrator_test.rb +67 -0
  166. data/test/unit/resource_factory_test.rb +216 -0
  167. metadata +499 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8d5b190664a730e9d2839c9b715a20e8a91988d9
4
+ data.tar.gz: 4452a41e24adc5fd4bf4770c5b323ea30e505e63
5
+ SHA512:
6
+ metadata.gz: 519c8fc168efbd2d16d9a5ddfcc55acd3f35f6463834d99099e73300972e1672f1510c035001e484b1fa99e858cf9104e5bc04568797f2320251d600bc78c7b3
7
+ data.tar.gz: 3a6c5a60d809a6e047e5e4d2c57d234137ad2c31b2b1a87b057176237fbf95e5ffafee18b853315f614c46cce15a8a1ba40a7b737e85d7910d63dbe5b01941c8
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in canvas_cc.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Brandon Broschinsky
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # CanvasCc
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'canvas_cc'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install canvas_cc
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( http://github.com/<my-github-username>/canvas_cc/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/canvas_cc.gemspec ADDED
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'canvas_cc/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "canvas_cc"
8
+ spec.version = CanvasCc::VERSION
9
+ spec.authors = ["Instructure"]
10
+ spec.email = ["pseng@instructure.com"]
11
+ spec.summary = %q{Create Canvas CC compatible file}
12
+ spec.description = %q{Create Canvas CC compatible file}
13
+ spec.homepage = ""
14
+ spec.license = "AGPLv3"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "rubyzip", '>=1.0.0'
22
+ spec.add_runtime_dependency "happymapper"
23
+ spec.add_runtime_dependency "builder"
24
+ spec.add_runtime_dependency "thor"
25
+ spec.add_runtime_dependency "nokogiri"
26
+ spec.add_runtime_dependency "rdiscount"
27
+
28
+ spec.add_development_dependency "rake"
29
+ spec.add_development_dependency "minitest"
30
+ spec.add_development_dependency "rspec", "~> 2"
31
+ spec.add_development_dependency "guard"
32
+ spec.add_development_dependency "guard-bundler"
33
+ spec.add_development_dependency "guard-minitest"
34
+ spec.add_development_dependency "guard-rspec"
35
+ spec.add_development_dependency "debugger"
36
+ spec.add_development_dependency "bundler", "~> 1.5"
37
+ end
@@ -0,0 +1,124 @@
1
+ module CanvasCc::Canvas
2
+ class Assessment < CanvasCc::CC::Assessment
3
+ include Resource
4
+ META_ATTRIBUTES = [:title, :description, :lock_at, :unlock_at, :allowed_attempts,
5
+ :scoring_policy, :access_code, :ip_filter, :shuffle_answers, :time_limit, :quiz_type]
6
+
7
+ attr_accessor :questions, :non_cc_assessments_identifier, *META_ATTRIBUTES
8
+
9
+ def initialize(mod, position=0)
10
+ super
11
+ description = [mod.intro, mod.content, mod.text, mod.summary].compact.reject { |d| d.length == 0 }.first || ''
12
+ @description = convert_file_path_tokens(description)
13
+ if mod.time_close.to_i > 0
14
+ @lock_at = ims_datetime(Time.at(mod.time_close))
15
+ end
16
+ if mod.time_open.to_i > 0
17
+ @unlock_at = ims_datetime(Time.at(mod.time_open))
18
+ end
19
+ @time_limit = mod.time_limit
20
+ @allowed_attempts = mod.attempts_number
21
+ @scoring_policy = mod.grade_method == 4 ? 'keep_latest' : 'keep_highest'
22
+ @access_code = mod.password
23
+ @ip_filter = mod.subnet
24
+ @shuffle_answers = mod.shuffle_answers
25
+ @quiz_type = 'survey' unless mod.mod_type == 'quiz'
26
+ @non_cc_assessments_identifier = create_key(@id, 'non_cc_assessments_')
27
+ @questions = []
28
+ mod.questions.each do |question|
29
+ if question.type == 'random'
30
+ question_bank = QuestionBank.new question.question_category
31
+ last = @questions.last
32
+ if last && last.is_a?(QuestionGroup) && last.points_per_item == question.grade && last.sourcebank_ref == question_bank.identifier
33
+ last.increment_selection_number
34
+ else
35
+ group = @questions.select { |q| q.is_a?(QuestionGroup) }.last
36
+ id = group ? group.id + 1 : 1
37
+ @questions << QuestionGroup.new(:id => id, :question_bank => question_bank, :points_per_item => question.grade)
38
+ end
39
+ else
40
+ @questions << Question.new(question, self)
41
+ end
42
+ end
43
+ end
44
+
45
+ def create_resource_node(resources_node)
46
+ super
47
+
48
+ href = File.join(identifier, ASSESSMENT_META)
49
+ resources_node.resource(
50
+ :href => href,
51
+ :type => LOR,
52
+ :identifier => non_cc_assessments_identifier
53
+ ) do |resource_node|
54
+ resource_node.file(:href => href)
55
+ resource_node.file(:href => File.join(ASSESSMENT_NON_CC_FOLDER, "#{identifier}.xml.qti"))
56
+ end
57
+ end
58
+
59
+ def create_resource_sub_nodes(resource_node)
60
+ resource_node.dependency :identifierref => non_cc_assessments_identifier
61
+ end
62
+
63
+ def create_files(export_dir)
64
+ create_assessment_meta_xml(export_dir)
65
+ create_non_cc_qti_xml(export_dir)
66
+ end
67
+
68
+ def create_assessment_meta_xml(export_dir)
69
+ path = File.join(export_dir, identifier, ASSESSMENT_META)
70
+ FileUtils.mkdir_p(File.dirname(path))
71
+ File.open(path, 'w') do |file|
72
+ node = Builder::XmlMarkup.new(:target => file, :indent => 2)
73
+ node.instruct!
74
+ node.quiz(
75
+ :identifier => identifier,
76
+ 'xsi:schemaLocation' => "http://canvas.instructure.com/xsd/cccv1p0 http://canvas.instructure.com/xsd/cccv1p0.xsd",
77
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
78
+ 'xmlns' => "http://canvas.instructure.com/xsd/cccv1p0"
79
+ ) do |quiz_node|
80
+ META_ATTRIBUTES.each do |attr|
81
+ quiz_node.tag!(attr, send(attr)) unless send(attr).nil?
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ def create_non_cc_qti_xml(export_dir)
88
+ path = File.join(export_dir, ASSESSMENT_NON_CC_FOLDER, "#{identifier}.xml.qti")
89
+ FileUtils.mkdir_p(File.dirname(path))
90
+ File.open(path, 'w') do |file|
91
+ node = Builder::XmlMarkup.new(:target => file, :indent => 2)
92
+ node.instruct!
93
+ node.questestinterop(
94
+ 'xsi:schemaLocation' => "http://www.imsglobal.org/xsd/ims_qtiasiv1p2 http://www.imsglobal.org/xsd/ims_qtiasiv1p2p1.xsd",
95
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
96
+ 'xmlns' => "http://www.imsglobal.org/xsd/ims_qtiasiv1p2"
97
+ ) do |root_node|
98
+ root_node.assessment(:title => title, :ident => identifier) do |assessment_node|
99
+ assessment_node.qtimetadata do |qtimetadata_node|
100
+ qtimetadata_node.qtimetadatafield do |qtimetadatafield_node|
101
+ qtimetadatafield_node.fieldlabel "qmd_timelimit"
102
+ qtimetadatafield_node.fieldentry time_limit
103
+ end
104
+ qtimetadata_node.qtimetadatafield do |qtimetadatafield_node|
105
+ qtimetadatafield_node.fieldlabel "cc_maxattempts"
106
+ qtimetadatafield_node.fieldentry allowed_attempts
107
+ end
108
+ end
109
+ assessment_node.section(:ident => 'root_section') do |section_node|
110
+ @questions.each do |question|
111
+ question.create_item_xml(section_node)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ def create_module_meta_item_elements(item_node)
120
+ item_node.content_type 'Quiz'
121
+ item_node.identifierref @identifier
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,98 @@
1
+ module CanvasCc::Canvas
2
+ class Assignment < CanvasCc::CC::Assignment
3
+ include Resource
4
+ SETTINGS_ATTRIBUTES = [:title, :points_possible, :grading_type, :due_at,
5
+ :lock_at, :unlock_at, :all_day, :all_day_date, :submission_types,
6
+ :position, :peer_reviews, :automatic_peer_reviews, :peer_review_count,
7
+ :anonymous_peer_reviews, :assignment_group_identifierref]
8
+
9
+ attr_accessor *SETTINGS_ATTRIBUTES
10
+
11
+ def initialize(mod, position=0)
12
+ super
13
+ @rel_path = "#{identifier}/#{file_slug(@title)}.html"
14
+ @resource_type = LOR
15
+ @body = convert_file_path_tokens(mod.description)
16
+ @points_possible = mod.grade_item ? mod.grade_item.grade_max : mod.grade
17
+ @grading_type = 'points'
18
+ if mod.time_due.to_i > 0
19
+ @due_at = ims_datetime(Time.at(mod.time_due))
20
+ @all_day = Time.at(mod.time_due).utc.strftime('%H:%M') == '23:59' ? true : false
21
+ if @all_day
22
+ @all_day_date = ims_date(Time.at(mod.time_due))
23
+ end
24
+ if mod.prevent_late
25
+ @lock_at = @due_at
26
+ end
27
+ end
28
+ if mod.time_available.to_i > 0
29
+ @unlock_at = ims_datetime(Time.at(mod.time_available))
30
+ end
31
+ if mod.submission_end.to_i > 0
32
+ @due_at = ims_datetime(Time.at(mod.submission_end))
33
+ end
34
+ @submission_types = get_submission_types(mod)
35
+ @position = position
36
+ @peer_reviews = @automatic_peer_reviews = mod.mod_type == 'workshop'
37
+ @peer_review_count = mod.number_of_student_assessments
38
+ @anonymous_peer_reviews = mod.anonymous
39
+ @assignment_group_identifierref = create_key(mod.section_mod.section.id, 'assignment_group_')
40
+ end
41
+
42
+ def get_submission_types(mod)
43
+ if mod.mod_type == 'assignment'
44
+ case mod.assignment_type
45
+ when 'online'
46
+ 'online_text_entry'
47
+ when 'upload'
48
+ if mod.var2 == 1
49
+ 'online_upload,online_text_entry'
50
+ else
51
+ 'online_upload'
52
+ end
53
+ when 'uploadsingle'
54
+ 'online_upload'
55
+ else
56
+ 'none'
57
+ end
58
+ elsif mod.mod_type == 'workshop'
59
+ submission_types = ['online_text_entry']
60
+ submission_types.unshift('online_upload') if mod.number_of_attachments > 0
61
+ submission_types.join(',')
62
+ end
63
+ end
64
+
65
+ def create_resource_sub_nodes(resource_node)
66
+ resource_node.file(:href => File.join(identifier, ASSIGNMENT_SETTINGS))
67
+ end
68
+
69
+ def create_files(export_dir)
70
+ super
71
+ create_settings_xml(export_dir)
72
+ end
73
+
74
+ def create_settings_xml(export_dir)
75
+ path = File.join(export_dir, identifier, ASSIGNMENT_SETTINGS)
76
+ FileUtils.mkdir_p(File.dirname(path))
77
+ File.open(path, 'w') do |file|
78
+ settings_node = Builder::XmlMarkup.new(:target => file, :indent => 2)
79
+ settings_node.instruct!
80
+ settings_node.assignment(
81
+ :identifier => identifier,
82
+ 'xsi:schemaLocation' => "http://canvas.instructure.com/xsd/cccv1p0 http://canvas.instructure.com/xsd/cccv1p0.xsd",
83
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
84
+ 'xmlns' => "http://canvas.instructure.com/xsd/cccv1p0"
85
+ ) do |assignment_node|
86
+ SETTINGS_ATTRIBUTES.each do |attr|
87
+ assignment_node.tag!(attr, send(attr)) unless send(attr).nil?
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ def create_module_meta_item_elements(item_node)
94
+ item_node.content_type 'Assignment'
95
+ item_node.identifierref @identifier
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,30 @@
1
+ module CanvasCc::Canvas
2
+ class Converter < CanvasCc::CC::Converter
3
+ def initialize(moodle_backup, destination_dir)
4
+ super
5
+ @resource_factory = CanvasCc::ResourceFactory.new CanvasCc::Canvas
6
+ end
7
+
8
+ def create_resources(resources_node)
9
+ create_course_content(resources_node)
10
+ @moodle_backup.course.question_categories.each do |question_category|
11
+ create_question_bank_resource(resources_node, question_category)
12
+ end
13
+ super
14
+ end
15
+
16
+ def create_question_bank_resource(resources_node, question_category)
17
+ question_bank = QuestionBank.new(question_category)
18
+ if question_bank.questions.length > 0
19
+ question_bank.create_resource_node(resources_node)
20
+ question_bank.create_files(@export_dir)
21
+ end
22
+ end
23
+
24
+ def create_course_content(resources_node)
25
+ course = Course.new(@moodle_backup.course)
26
+ course.create_resource_node(resources_node)
27
+ course.create_files(@export_dir)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,143 @@
1
+ module CanvasCc::Canvas
2
+ class Course < CanvasCc::CC::Course
3
+
4
+ attr_accessor :id, :title, :course_code, :start_at, :format, :is_public, :syllabus_body
5
+
6
+ def initialize(course)
7
+ super
8
+
9
+ @course = course
10
+
11
+ @id = course.id
12
+ @title = course.fullname
13
+ @course_code = course.shortname
14
+ @start_at = ims_datetime(Time.at(course.startdate))
15
+ @is_public = course.visible
16
+ @syllabus_body = convert_file_path_tokens(course.sections.first.summary)
17
+ @resource_factory = CanvasCc::ResourceFactory.new CanvasCc::Canvas
18
+ end
19
+
20
+ def identifier
21
+ create_key(id, 'course_')
22
+ end
23
+
24
+ def create_resource_node(resources_node)
25
+ syllabus_href = File.join(COURSE_SETTINGS_DIR, SYLLABUS)
26
+ resources_node.resource(
27
+ :intendeduse => 'syllabus',
28
+ :href => syllabus_href,
29
+ :type => LOR,
30
+ :identifier => create_key(syllabus_href, 'resource_')
31
+ ) do |resource_node|
32
+ resource_node.file(:href => File.join(COURSE_SETTINGS_DIR, SYLLABUS))
33
+ resource_node.file(:href => File.join(COURSE_SETTINGS_DIR, COURSE_SETTINGS))
34
+ resource_node.file(:href => File.join(COURSE_SETTINGS_DIR, FILES_META))
35
+ resource_node.file(:href => File.join(COURSE_SETTINGS_DIR, MODULE_META))
36
+ resource_node.file(:href => File.join(COURSE_SETTINGS_DIR, ASSIGNMENT_GROUPS))
37
+ end
38
+ end
39
+
40
+ def create_files(export_dir)
41
+ create_syllabus_file(export_dir)
42
+ create_course_settings_xml(export_dir)
43
+ create_files_meta_xml(export_dir)
44
+ create_assignment_groups_xml(export_dir)
45
+ create_module_meta_xml(export_dir)
46
+ end
47
+
48
+ def create_syllabus_file(export_dir)
49
+ template = File.expand_path('../templates/syllabus.html.erb', __FILE__)
50
+ path = File.join(export_dir, COURSE_SETTINGS_DIR, SYLLABUS)
51
+ FileUtils.mkdir_p(File.dirname(path))
52
+ File.open(path, 'w') do |file|
53
+ erb = ERB.new(File.read(template))
54
+ file.write(erb.result(binding))
55
+ end
56
+ end
57
+
58
+ def create_course_settings_xml(export_dir)
59
+ path = File.join(export_dir, COURSE_SETTINGS_DIR, COURSE_SETTINGS)
60
+ FileUtils.mkdir_p(File.dirname(path))
61
+ File.open(path, 'w') do |file|
62
+ document = Builder::XmlMarkup.new(:target => file, :indent => 2)
63
+ document.instruct!
64
+ document.course(
65
+ :identifier => identifier,
66
+ 'xsi:schemaLocation' => "http://canvas.instructure.com/xsd/cccv1p0 http://canvas.instructure.com/xsd/cccv1p0.xsd",
67
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
68
+ 'xmlns' => "http://canvas.instructure.com/xsd/cccv1p0"
69
+ ) do |course_node|
70
+ course_node.title @title
71
+ course_node.course_code @course_code
72
+ course_node.start_at @start_at
73
+ course_node.is_public @is_public
74
+ course_node.license 'private'
75
+ end
76
+ end
77
+ end
78
+
79
+ def create_module_meta_xml(export_dir)
80
+ path = File.join(export_dir, COURSE_SETTINGS_DIR, MODULE_META)
81
+ FileUtils.mkdir_p(File.dirname(path))
82
+ File.open(path, 'w') do |file|
83
+ document = Builder::XmlMarkup.new(:target => file, :indent => 2)
84
+ document.instruct!
85
+ document.modules(
86
+ 'xsi:schemaLocation' => "http://canvas.instructure.com/xsd/cccv1p0 http://canvas.instructure.com/xsd/cccv1p0.xsd",
87
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
88
+ 'xmlns' => "http://canvas.instructure.com/xsd/cccv1p0"
89
+ ) do |modules_node|
90
+ @course.sections.each do |section|
91
+ next if section.mods.length == 0
92
+ modules_node.module(:identifier => create_key(section.id, 'section_')) do |module_node|
93
+ module_node.title "#{@format} #{section.number}"
94
+ module_node.position section.number
95
+ module_node.require_sequential_progress false
96
+ module_node.items do |items_node|
97
+ section.mods.each_with_index do |mod, index|
98
+ resource = @resource_factory.get_resource_from_mod(mod.instance)
99
+ resource.create_module_meta_item_node(items_node, index) if resource
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def create_assignment_groups_xml(export_dir)
109
+ path = File.join(export_dir, COURSE_SETTINGS_DIR, ASSIGNMENT_GROUPS)
110
+ FileUtils.mkdir_p(File.dirname(path))
111
+ File.open(path, 'w') do |file|
112
+ document = Builder::XmlMarkup.new(:target => file, :indent => 2)
113
+ document.instruct!
114
+ document.assignmentGroups(
115
+ 'xsi:schemaLocation' => "http://canvas.instructure.com/xsd/cccv1p0 http://canvas.instructure.com/xsd/cccv1p0.xsd",
116
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
117
+ 'xmlns' => "http://canvas.instructure.com/xsd/cccv1p0"
118
+ ) do |assignment_groups_node|
119
+ @course.sections.each do |section|
120
+ next unless section.mods.select { |mod| mod.instance.mod_type == "assignment" }.length > 0
121
+ assignment_groups_node.assignmentGroup(:identifier => create_key(section.id, "assignment_group_")) do |assignment_group_node|
122
+ assignment_group_node.title "Week #{section.number}"
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ def create_files_meta_xml(export_dir)
130
+ path = File.join(export_dir, COURSE_SETTINGS_DIR, FILES_META)
131
+ FileUtils.mkdir_p(File.dirname(path))
132
+ File.open(path, 'w') do |file|
133
+ document = Builder::XmlMarkup.new(:target => file, :indent => 2)
134
+ document.instruct!
135
+ document.filesMeta(
136
+ 'xsi:schemaLocation' => "http://canvas.instructure.com/xsd/cccv1p0 http://canvas.instructure.com/xsd/cccv1p0.xsd",
137
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
138
+ 'xmlns' => "http://canvas.instructure.com/xsd/cccv1p0")
139
+ end
140
+ end
141
+
142
+ end
143
+ end
@@ -0,0 +1,64 @@
1
+ module CanvasCc::Canvas
2
+ class DiscussionTopic < CanvasCc::CC::DiscussionTopic
3
+ include Resource
4
+ attr_accessor :posted_at, :position, :type, :identifierref
5
+
6
+ def initialize(mod, position=0)
7
+ super
8
+ @text = convert_file_path_tokens(mod.intro)
9
+
10
+ if mod.section_mod && mod.section_mod.added.to_i > 0
11
+ @posted_at = ims_datetime(Time.at(mod.section_mod.added))
12
+ end
13
+
14
+ @position = position
15
+ @type = 'topic'
16
+ @identifierref = create_key(@id, 'topic_meta_')
17
+ end
18
+
19
+ def create_resource_node(resources_node)
20
+ super
21
+ resources_node.resource(
22
+ :type => LOR,
23
+ :identifier => @identifierref,
24
+ :href => "#{@identifierref}.xml"
25
+ ) do |resource_node|
26
+ resource_node.file(:href => "#{@identifierref}.xml")
27
+ end
28
+ end
29
+
30
+ def create_resource_sub_nodes(resource_node)
31
+ resource_node.dependency(:identifierref => @identifierref)
32
+ end
33
+
34
+ def create_files(export_dir)
35
+ super
36
+ create_topic_meta_xml(export_dir)
37
+ end
38
+
39
+ def create_topic_meta_xml(export_dir)
40
+ path = File.join(export_dir, "#{@identifierref}.xml")
41
+ File.open(path, 'w') do |file|
42
+ document = Builder::XmlMarkup.new(:target => file, :indent => 2)
43
+ document.instruct!
44
+ document.topicMeta(
45
+ :identifier => @identifierref,
46
+ 'xsi:schemaLocation' => "http://canvas.instructure.com/xsd/cccv1p0 http://canvas.instructure.com/xsd/cccv1p0.xsd",
47
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
48
+ 'xmlns' => "http://canvas.instructure.com/xsd/cccv1p0"
49
+ ) do |topic_meta|
50
+ topic_meta.topic_id identifier
51
+ topic_meta.title @title
52
+ topic_meta.posted_at @posted_at
53
+ topic_meta.position @position
54
+ topic_meta.type @type
55
+ end
56
+ end
57
+ end
58
+
59
+ def create_module_meta_item_elements(item_node)
60
+ item_node.content_type 'DiscussionTopic'
61
+ item_node.identifierref @identifier
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,8 @@
1
+ module CanvasCc::Canvas
2
+ class Label < CanvasCc::CC::Label
3
+ include Resource
4
+ def create_module_meta_item_elements(item_node)
5
+ item_node.content_type 'ContextModuleSubHeader'
6
+ end
7
+ end
8
+ end