strongmind_multi_version_common_cartridge 1.0.4

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 (39) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/gem-push.yml +46 -0
  3. data/.gitignore +14 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +60 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +674 -0
  8. data/PULL_REQUEST_TEMPLATE.md +7 -0
  9. data/README.md +36 -0
  10. data/lib/multi_version_common_cartridge/cartridge.rb +58 -0
  11. data/lib/multi_version_common_cartridge/cartridge_versions.rb +25 -0
  12. data/lib/multi_version_common_cartridge/item.rb +29 -0
  13. data/lib/multi_version_common_cartridge/manifest.rb +33 -0
  14. data/lib/multi_version_common_cartridge/resources/basic_lti_link.rb +46 -0
  15. data/lib/multi_version_common_cartridge/resources/canvas_assignment.rb +30 -0
  16. data/lib/multi_version_common_cartridge/resources/canvas_course_settings.rb +29 -0
  17. data/lib/multi_version_common_cartridge/resources/canvas_elements/assignment.rb +33 -0
  18. data/lib/multi_version_common_cartridge/resources/canvas_elements/course_settings.rb +111 -0
  19. data/lib/multi_version_common_cartridge/resources/resource.rb +23 -0
  20. data/lib/multi_version_common_cartridge/sax_machine_nokogiri_xml_saver.rb +85 -0
  21. data/lib/multi_version_common_cartridge/version.rb +19 -0
  22. data/lib/multi_version_common_cartridge/writers/basic_lti_extension_writer.rb +45 -0
  23. data/lib/multi_version_common_cartridge/writers/basic_lti_link_writer.rb +242 -0
  24. data/lib/multi_version_common_cartridge/writers/basic_lti_vendor_writer.rb +66 -0
  25. data/lib/multi_version_common_cartridge/writers/canvas_assignment_writer.rb +104 -0
  26. data/lib/multi_version_common_cartridge/writers/canvas_course_settings_writer.rb +218 -0
  27. data/lib/multi_version_common_cartridge/writers/cartridge_writer.rb +85 -0
  28. data/lib/multi_version_common_cartridge/writers/factory.rb +61 -0
  29. data/lib/multi_version_common_cartridge/writers/item_writer.rb +60 -0
  30. data/lib/multi_version_common_cartridge/writers/manifest_metadata_writer.rb +62 -0
  31. data/lib/multi_version_common_cartridge/writers/manifest_organization_writer.rb +68 -0
  32. data/lib/multi_version_common_cartridge/writers/manifest_resources_writer.rb +48 -0
  33. data/lib/multi_version_common_cartridge/writers/manifest_writer.rb +88 -0
  34. data/lib/multi_version_common_cartridge/writers/resource_writer.rb +54 -0
  35. data/lib/multi_version_common_cartridge/writers/supported_versions.rb +37 -0
  36. data/lib/multi_version_common_cartridge/xml_definitions.rb +149 -0
  37. data/lib/multi_version_common_cartridge.rb +45 -0
  38. data/multi_version_common_cartridge.gemspec +27 -0
  39. metadata +164 -0
@@ -0,0 +1,242 @@
1
+ # multi_version_common_cartridge
2
+ # Copyright © 2019 Vista Higher Learning, Inc.
3
+ #
4
+ # multi_version_common_cartridge is free software: you can redistribute it
5
+ # and/or modify it under the terms of the GNU General Public
6
+ # License as published by the Free Software Foundation, either
7
+ # version 3 of the License, or (at your option) any later version.
8
+ #
9
+ # multi_version_common_cartridge is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with multi_version_common_cartridge. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ module MultiVersionCommonCartridge
18
+ module Writers
19
+ class BasicLtiLinkWriter < ResourceWriter
20
+ REQUIRED_NAMESPACES = {
21
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_1_0 => {
22
+ 'xmlns' => 'http://www.imsglobal.org/xsd/imslticc_v1p0',
23
+ 'xmlns:blti' => 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0',
24
+ 'xmlns:lticm' => 'http://www.imsglobal.org/xsd/imslticm_v1p0',
25
+ 'xmlns:lticp' => 'http://www.imsglobal.org/xsd/imslticp_v1p0',
26
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
27
+ },
28
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_2_0 => {
29
+ 'xmlns' => 'http://www.imsglobal.org/xsd/imslticc_v1p2',
30
+ 'xmlns:blti' => 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0',
31
+ 'xmlns:lticm' => 'http://www.imsglobal.org/xsd/imslticm_v1p0',
32
+ 'xmlns:lticp' => 'http://www.imsglobal.org/xsd/imslticp_v1p0',
33
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
34
+ },
35
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_3_0 => {
36
+ 'xmlns' => 'http://www.imsglobal.org/xsd/imslticc_v1p3',
37
+ 'xmlns:blti' => 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0',
38
+ 'xmlns:lticm' => 'http://www.imsglobal.org/xsd/imslticm_v1p0',
39
+ 'xmlns:lticp' => 'http://www.imsglobal.org/xsd/imslticp_v1p0',
40
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
41
+ },
42
+ MultiVersionCommonCartridge::CartridgeVersions::THIN_CC_1_2_0 => {
43
+ 'xmlns' => 'http://www.imsglobal.org/xsd/imslticc_v1p2',
44
+ 'xmlns:blti' => 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0',
45
+ 'xmlns:lticm' => 'http://www.imsglobal.org/xsd/imslticm_v1p0',
46
+ 'xmlns:lticp' => 'http://www.imsglobal.org/xsd/imslticp_v1p0',
47
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
48
+ },
49
+ MultiVersionCommonCartridge::CartridgeVersions::THIN_CC_1_3_0 => {
50
+ 'xmlns' => 'http://www.imsglobal.org/xsd/imslticc_v1p3',
51
+ 'xmlns:blti' => 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0',
52
+ 'xmlns:lticm' => 'http://www.imsglobal.org/xsd/imslticm_v1p0',
53
+ 'xmlns:lticp' => 'http://www.imsglobal.org/xsd/imslticp_v1p0',
54
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
55
+ }
56
+ }.freeze
57
+ REQUIRED_SCHEMA_LOCATIONS = {
58
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_1_0 => [
59
+ [
60
+ 'http://www.imsglobal.org/xsd/imslticc_v1p0',
61
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticc_v1p0p1.xsd'
62
+ ],
63
+ [
64
+ 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0',
65
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0p1.xsd'
66
+ ],
67
+ [
68
+ 'http://www.imsglobal.org/xsd/imslticm_v1p0',
69
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd'
70
+ ],
71
+ [
72
+ 'http://www.imsglobal.org/xsd/imslticp_v1p0',
73
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd'
74
+ ]
75
+ ],
76
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_2_0 => [
77
+ [
78
+ 'http://www.imsglobal.org/xsd/imslticc_v1p2',
79
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p2/imslticc_v1p2.xsd'
80
+ ],
81
+ [
82
+ 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0',
83
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0p1.xsd'
84
+ ],
85
+ [
86
+ 'http://www.imsglobal.org/xsd/imslticm_v1p0',
87
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd'
88
+ ],
89
+ [
90
+ 'http://www.imsglobal.org/xsd/imslticp_v1p0',
91
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd'
92
+ ]
93
+ ],
94
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_3_0 => [
95
+ [
96
+ 'http://www.imsglobal.org/xsd/imslticc_v1p3',
97
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p3/imslticc_v1p3.xsd'
98
+ ],
99
+ [
100
+ 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0',
101
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0p1.xsd'
102
+ ],
103
+ [
104
+ 'http://www.imsglobal.org/xsd/imslticm_v1p0',
105
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd'
106
+ ],
107
+ [
108
+ 'http://www.imsglobal.org/xsd/imslticp_v1p0',
109
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd'
110
+ ]
111
+ ],
112
+ MultiVersionCommonCartridge::CartridgeVersions::THIN_CC_1_2_0 => [
113
+ [
114
+ 'http://www.imsglobal.org/xsd/imslticc_v1p2',
115
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p2/imslticc_v1p2.xsd'
116
+ ],
117
+ [
118
+ 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0',
119
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0p1.xsd'
120
+ ],
121
+ [
122
+ 'http://www.imsglobal.org/xsd/imslticm_v1p0',
123
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd'
124
+ ],
125
+ [
126
+ 'http://www.imsglobal.org/xsd/imslticp_v1p0',
127
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd'
128
+ ]
129
+ ],
130
+ MultiVersionCommonCartridge::CartridgeVersions::THIN_CC_1_3_0 => [
131
+ [
132
+ 'http://www.imsglobal.org/xsd/imslticc_v1p3',
133
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p3/imslticc_v1p3.xsd'
134
+ ],
135
+ [
136
+ 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0',
137
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0p1.xsd'
138
+ ],
139
+ [
140
+ 'http://www.imsglobal.org/xsd/imslticm_v1p0',
141
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd'
142
+ ],
143
+ [
144
+ 'http://www.imsglobal.org/xsd/imslticp_v1p0',
145
+ 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd'
146
+ ]
147
+ ]
148
+ }.freeze
149
+ MESSAGES = {
150
+ no_title: 'A title is required.',
151
+ no_secure_launch_url: 'A secure launch url is required.'
152
+ }.freeze
153
+
154
+ TYPE = {
155
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_1_0 => 'imsbasiclti_xmlv1p0',
156
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_2_0 => 'imsbasiclti_xmlv1p0',
157
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_3_0 => 'imsbasiclti_xmlv1p3',
158
+ MultiVersionCommonCartridge::CartridgeVersions::THIN_CC_1_2_0 => 'imsbasiclti_xmlv1p0',
159
+ MultiVersionCommonCartridge::CartridgeVersions::THIN_CC_1_3_0 => 'imsbasiclti_xmlv1p3'
160
+ }.freeze
161
+ BASIC_LTI_LINK_FILENAME = 'basic_lti_link.xml'.freeze
162
+
163
+ def finalize
164
+ super
165
+ validate_title
166
+ validate_secure_launch_url
167
+ vendor_writer.finalize
168
+ end
169
+
170
+ def type
171
+ TYPE[@version]
172
+ end
173
+
174
+ def files
175
+ [
176
+ File.join(resource_path, BASIC_LTI_LINK_FILENAME)
177
+ ]
178
+ end
179
+
180
+ def create_files(out_dir)
181
+ FileUtils.mkdir_p(File.join(out_dir, resource_path))
182
+ doc = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |builder|
183
+ SaxMachineNokogiriXmlSaver.new.save(
184
+ builder, basic_lti_link_element, 'cartridge_basiclti_link'
185
+ )
186
+ end
187
+ File.open(File.join(out_dir, resource_path, BASIC_LTI_LINK_FILENAME), 'w') do |file|
188
+ file.write(doc.to_xml)
189
+ end
190
+ end
191
+
192
+ def basic_lti_link_element
193
+ @basic_lti_link_element ||=
194
+ CommonCartridge::Elements::Resources::BasicLtiLink::BasicLtiLink.new.tap do |element|
195
+ element.xmlns = required_namespaces['xmlns']
196
+ element.xmlns_blti = required_namespaces['xmlns:blti']
197
+ element.xmlns_lticm = required_namespaces['xmlns:lticm']
198
+ element.xmlns_lticp = required_namespaces['xmlns:lticp']
199
+ element.xmlns_xsi = required_namespaces['xmlns:xsi']
200
+ element.xsi_schema_location = xsi_schema_location
201
+ element.title = resource.title
202
+ element.description = resource.description if resource.description
203
+ element.launch_url = resource.secure_launch_url
204
+ element.secure_launch_url = resource.secure_launch_url
205
+ element.vendor = vendor_writer.vendor_element
206
+ element.extensions = extensions_element
207
+ end
208
+ end
209
+
210
+ private def validate_title
211
+ raise StandardError, MESSAGES[:no_title] unless resource.title
212
+ end
213
+
214
+ private def validate_secure_launch_url
215
+ raise StandardError, MESSAGES[:no_secure_launch_url] unless resource.secure_launch_url
216
+ end
217
+
218
+ private def vendor_writer
219
+ @vendor_writer ||= BasicLtiVendorWriter.new(resource.vendor, @version)
220
+ end
221
+
222
+ private def extensions_element
223
+ resource.extensions.map do |extension|
224
+ BasicLtiExtensionWriter.new(extension, @version).extension_element
225
+ end
226
+ end
227
+
228
+ private def required_namespaces
229
+ REQUIRED_NAMESPACES[@version]
230
+ end
231
+
232
+ private def xsi_schema_location
233
+ locations = REQUIRED_SCHEMA_LOCATIONS[@version]
234
+ locations.flatten.join(' ')
235
+ end
236
+
237
+ private def resource_path
238
+ resource.identifier
239
+ end
240
+ end
241
+ end
242
+ end
@@ -0,0 +1,66 @@
1
+ # multi_version_common_cartridge
2
+ # Copyright © 2019 Vista Higher Learning, Inc.
3
+ #
4
+ # multi_version_common_cartridge is free software: you can redistribute it
5
+ # and/or modify it under the terms of the GNU General Public
6
+ # License as published by the Free Software Foundation, either
7
+ # version 3 of the License, or (at your option) any later version.
8
+ #
9
+ # multi_version_common_cartridge is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with multi_version_common_cartridge. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ module MultiVersionCommonCartridge
18
+ module Writers
19
+ class BasicLtiVendorWriter
20
+ include SupportedVersions
21
+
22
+ MESSAGES = {
23
+ no_code: 'A code is required.',
24
+ no_name: 'A name is required.',
25
+ no_contact_email: 'A contact email is required.'
26
+ }.freeze
27
+
28
+ attr_reader :vendor
29
+
30
+ def initialize(vendor, version)
31
+ @vendor = vendor
32
+ @version = validate_version(version)
33
+ end
34
+
35
+ def finalize
36
+ validate_code
37
+ validate_name
38
+ validate_contact_email
39
+ end
40
+
41
+ def vendor_element
42
+ @vendor_element ||= CommonCartridge::Elements::Resources::BasicLtiLink::Vendor.new.tap do |element|
43
+ element.code = vendor.code
44
+ element.name = vendor.name
45
+ element.description = vendor.description if vendor.description
46
+ element.url = vendor.url if vendor.url
47
+ element.contact = CommonCartridge::Elements::Resources::BasicLtiLink::VendorContact.new(
48
+ email: vendor.contact_email
49
+ )
50
+ end
51
+ end
52
+
53
+ private def validate_code
54
+ raise StandardError, MESSAGES[:no_code] unless vendor.code
55
+ end
56
+
57
+ private def validate_name
58
+ raise StandardError, MESSAGES[:no_name] unless vendor.name
59
+ end
60
+
61
+ private def validate_contact_email
62
+ raise StandardError, MESSAGES[:no_contact_email] unless vendor.contact_email
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,104 @@
1
+ # multi_version_common_cartridge
2
+ # Copyright © 2023 StrongMind
3
+ #
4
+ # multi_version_common_cartridge is free software: you can redistribute it
5
+ # and/or modify it under the terms of the GNU General Public
6
+ # License as published by the Free Software Foundation, either
7
+ # version 3 of the License, or (at your option) any later version.
8
+ #
9
+ # multi_version_common_cartridge is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with multi_version_common_cartridge. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ module MultiVersionCommonCartridge
18
+ module Writers
19
+ class CanvasAssignmentWriter < ResourceWriter
20
+ REQUIRED_NAMESPACES = {
21
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_1_0 => {
22
+ 'xmlns' => 'http://canvas.instructure.com/xsd/cccv1p0',
23
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
24
+ }
25
+ }.freeze
26
+
27
+ MESSAGES = {
28
+ no_title: 'A title is required.',
29
+ no_external_tool_url: 'An external tool url is required.'
30
+ }.freeze
31
+
32
+ CANVAS_ASSIGNMENT_FILENAME = 'assignment_settings.xml'.freeze
33
+ CANVAS_ASSIGNMENT_HTML_FILENAME = 'assignment.html'.freeze
34
+
35
+ def finalize
36
+ super
37
+ validate_title
38
+ validate_external_tool_url
39
+ end
40
+
41
+ def type
42
+ 'associatedcontent/imscc_xmlv1p1/learning-application-resource'
43
+ end
44
+
45
+ def files
46
+ [
47
+ File.join(resource_path, CANVAS_ASSIGNMENT_FILENAME),
48
+ File.join(resource_path, CANVAS_ASSIGNMENT_HTML_FILENAME)
49
+ ]
50
+ end
51
+
52
+ def create_files(out_dir)
53
+ FileUtils.mkdir_p(File.join(out_dir, resource_path))
54
+ doc = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |builder|
55
+ SaxMachineNokogiriXmlSaver.new.save(
56
+ builder, canvas_assignment_element, 'assignment'
57
+ )
58
+ end
59
+ File.open(File.join(out_dir, resource_path, CANVAS_ASSIGNMENT_FILENAME), 'w') do |file|
60
+ file.write(doc.to_xml)
61
+ end
62
+
63
+ File.open(File.join(out_dir, resource_path, CANVAS_ASSIGNMENT_HTML_FILENAME), 'w') do |file|
64
+ file.write("<p></p>")
65
+ end
66
+ end
67
+
68
+ def canvas_assignment_element
69
+ @canvas_assignment_element ||=
70
+ CanvasCartridge::Elements::Resources::CanvasAssignment::Assignment.new.tap do |element|
71
+ element.xmlns = required_namespaces['xmlns']
72
+ element.xmlns_xsi = required_namespaces['xmlns:xsi']
73
+ element.identifier = resource.identifier
74
+ element.title = resource.title
75
+ element.assignment_group_identifierref = resource.assignment_group_identifierref
76
+ element.points_possible = resource.points_possible
77
+ element.max_attempts = resource.max_attempts
78
+ element.allowed_attempts = resource.allowed_attempts
79
+ element.is_end_of_module_exam = resource.is_end_of_module_exam
80
+ element.grading_type = resource.grading_type
81
+ element.submission_types = resource.submission_types
82
+ element.peer_review_count = resource.peer_review_count
83
+ element.external_tool_url = resource.external_tool_url
84
+ end
85
+ end
86
+
87
+ private def validate_title
88
+ raise StandardError, MESSAGES[:no_title] unless resource.title
89
+ end
90
+
91
+ private def validate_external_tool_url
92
+ raise StandardError, MESSAGES[:no_external_tool_url] unless resource.external_tool_url
93
+ end
94
+
95
+ private def required_namespaces
96
+ REQUIRED_NAMESPACES[@version]
97
+ end
98
+
99
+ private def resource_path
100
+ resource.identifier
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,218 @@
1
+ # multi_version_common_cartridge
2
+ # Copyright © 2023 StrongMind
3
+ #
4
+ # multi_version_common_cartridge is free software: you can redistribute it
5
+ # and/or modify it under the terms of the GNU General Public
6
+ # License as published by the Free Software Foundation, either
7
+ # version 3 of the License, or (at your option) any later version.
8
+ #
9
+ # multi_version_common_cartridge is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with multi_version_common_cartridge. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ module MultiVersionCommonCartridge
18
+ module Writers
19
+ class CanvasCourseSettingsWriter < ResourceWriter
20
+ REQUIRED_NAMESPACES = {
21
+ MultiVersionCommonCartridge::CartridgeVersions::CC_1_1_0 => {
22
+ 'xmlns' => 'http://canvas.instructure.com/xsd/cccv1p0',
23
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
24
+ }
25
+ }.freeze
26
+
27
+ COURSE_SETTINGS_FILENAME = 'course_settings.xml'.freeze
28
+ CANVAS_EXPORT_FILENAME = 'canvas_export.txt'.freeze
29
+ ASSIGNMENT_GROUPS_FILENAME = 'assignment_groups.xml'.freeze
30
+ MODULE_META_FILENAME = 'module_meta.xml'.freeze
31
+
32
+ def type
33
+ 'webcontent'
34
+ end
35
+
36
+ def files
37
+ [
38
+ File.join(resource_path, COURSE_SETTINGS_FILENAME),
39
+ File.join(resource_path, CANVAS_EXPORT_FILENAME),
40
+ File.join(resource_path, ASSIGNMENT_GROUPS_FILENAME),
41
+ File.join(resource_path, MODULE_META_FILENAME),
42
+ ]
43
+ end
44
+
45
+ def create_files(out_dir)
46
+ FileUtils.mkdir_p(File.join(out_dir, resource_path))
47
+ course_settings_doc = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |builder|
48
+ SaxMachineNokogiriXmlSaver.new.save(
49
+ builder, course_settings_element, 'course'
50
+ )
51
+ end
52
+
53
+ assignment_groups_doc = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |builder|
54
+ SaxMachineNokogiriXmlSaver.new.save(
55
+ builder, assignment_groups_element, 'assignmentGroups'
56
+ )
57
+ end
58
+
59
+ module_meta_doc = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |builder|
60
+ SaxMachineNokogiriXmlSaver.new.save(
61
+ builder, module_meta_element, 'modules'
62
+ )
63
+ end
64
+
65
+ File.open(File.join(out_dir, resource_path, COURSE_SETTINGS_FILENAME), 'w') do |file|
66
+ file.write(course_settings_doc.to_xml)
67
+ end
68
+
69
+ File.open(File.join(out_dir, resource_path, CANVAS_EXPORT_FILENAME), 'w') do |file|
70
+ file.write(canvas_export_contents)
71
+ end
72
+
73
+ File.open(File.join(out_dir, resource_path, ASSIGNMENT_GROUPS_FILENAME), 'w') do |file|
74
+ file.write(assignment_groups_doc.to_xml)
75
+ end
76
+
77
+ File.open(File.join(out_dir, resource_path, MODULE_META_FILENAME), 'w') do |file|
78
+ file.write(module_meta_doc.to_xml)
79
+ end
80
+ end
81
+
82
+ def course_settings_element
83
+ @course_settings_element ||=
84
+ CanvasCartridge::Elements::Resources::CourseSettings::CourseSettings.new.tap do |element|
85
+ element.identifier = resource.identifier
86
+ element.xmlns = required_namespaces['xmlns']
87
+ element.xmlns_xsi = required_namespaces['xmlns:xsi']
88
+ element.image_url = resource.image_url
89
+ element.group_weighting_scheme = resource.group_weighting_scheme
90
+ end
91
+ end
92
+
93
+ def assignment_groups_element
94
+ @assignment_groups_element ||=
95
+ CanvasCartridge::Elements::Resources::CourseSettings::AssignmentGroups.new.tap do |element|
96
+ element.xmlns = required_namespaces['xmlns']
97
+ element.xmlns_xsi = required_namespaces['xmlns:xsi']
98
+ element.groups = groups_child_elements
99
+ end
100
+ end
101
+
102
+ def groups_child_elements
103
+ return if resource.assignment_groups.nil?
104
+
105
+ resource.assignment_groups.map do |key, value|
106
+ CanvasCartridge::Elements::Resources::CourseSettings::AssignmentGroup.new.tap do |element|
107
+ element.identifier = key
108
+ element.title = value[:title]
109
+ element.position = value[:position]
110
+ element.group_weight = value[:group_weight]
111
+ end
112
+ end
113
+ end
114
+
115
+ def module_meta_element
116
+ @module_meta_element ||=
117
+ CanvasCartridge::Elements::Resources::CourseSettings::Modules.new.tap do |element|
118
+ element.xmlns = required_namespaces['xmlns']
119
+ element.xmlns_xsi = required_namespaces['xmlns:xsi']
120
+ element.modules = modules_child_elements
121
+ end
122
+ end
123
+
124
+ def modules_child_elements
125
+ return if resource.modules.nil?
126
+
127
+ resource.modules.map do |key, value|
128
+ CanvasCartridge::Elements::Resources::CourseSettings::Module.new.tap do |element|
129
+ element.identifier = key
130
+ element.title = value[:title]
131
+ element.workflow_state = value[:workflow_state]
132
+ element.position = value[:position]
133
+ element.require_sequential_progress = value[:require_sequential_progress]
134
+ element.requirement_count = value[:requirement_count]
135
+ element.root_prerequisites = prerequisites_root_element(value[:prerequisites])
136
+ element.root_items = items_root_element(value[:items])
137
+ element.root_requirements = completion_requirements_root_element(value[:completion_requirements])
138
+ end
139
+ end
140
+ end
141
+
142
+ def prerequisites_root_element(prerequisites)
143
+ return if prerequisites.nil?
144
+
145
+ CanvasCartridge::Elements::Resources::CourseSettings::Prerequisites.new.tap do |element|
146
+ element.prerequisites = prerequisites_child_elements(prerequisites)
147
+ end
148
+ end
149
+
150
+ def prerequisites_child_elements(prerequisites)
151
+ prerequisites.map do |prerequisite|
152
+ CanvasCartridge::Elements::Resources::CourseSettings::Prerequisite.new.tap do |element|
153
+ element.type = prerequisite[:type]
154
+ element.title = prerequisite[:title]
155
+ element.identifierref = prerequisite[:identifierref]
156
+ end
157
+ end
158
+ end
159
+
160
+ def items_root_element(items)
161
+ return if items.nil?
162
+
163
+ CanvasCartridge::Elements::Resources::CourseSettings::Items.new.tap do |element|
164
+ element.items = items_child_elements(items)
165
+ end
166
+ end
167
+
168
+ def items_child_elements(items)
169
+ items.map do |item|
170
+ CanvasCartridge::Elements::Resources::CourseSettings::Item.new.tap do |element|
171
+ element.identifier = item[:identifier]
172
+ element.title = item[:title]
173
+ element.workflow_state = item[:workflow_state]
174
+ element.content_type = item[:content_type]
175
+ element.identifierref = item[:identifierref]
176
+ element.url = item[:url]
177
+ element.position = item[:position]
178
+ element.indent = item[:indent]
179
+ element.global_identifierref = item[:global_identifierref]
180
+ end
181
+ end
182
+ end
183
+
184
+ def completion_requirements_root_element(completion_requirements)
185
+ return if completion_requirements.nil?
186
+
187
+ CanvasCartridge::Elements::Resources::CourseSettings::CompletionRequirements.new.tap do |element|
188
+ element.completion_requirements = completion_requirements_child_elements(completion_requirements)
189
+ end
190
+ end
191
+
192
+ def completion_requirements_child_elements(completion_requirements)
193
+ completion_requirements.map do |completion_requirement|
194
+ CanvasCartridge::Elements::Resources::CourseSettings::CompletionRequirement.new.tap do |element|
195
+ element.type = completion_requirement[:type]
196
+ element.identifierref = completion_requirement[:identifierref]
197
+ end
198
+ end
199
+ end
200
+
201
+ def canvas_export_contents
202
+ 'What did the panda say when he was forced out of his natural habitat? Bamboo-zled!'
203
+ end
204
+
205
+ private def validate_external_tool_url
206
+ raise StandardError, MESSAGES[:no_external_tool_url] unless resource.external_tool_url
207
+ end
208
+
209
+ private def required_namespaces
210
+ REQUIRED_NAMESPACES[@version]
211
+ end
212
+
213
+ private def resource_path
214
+ 'course_settings'
215
+ end
216
+ end
217
+ end
218
+ end