senkyoshi_canvas_plugin 1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f5f2c6cbc6d5973e7c8b10b93a2293d365b6c3e5
4
+ data.tar.gz: 7b141a269fd70dfe2d51e297bab57064d3938e23
5
+ SHA512:
6
+ metadata.gz: dd324b5342914f3e59c3b2be0288123674a735bb4421fb44b5bb1032da7d12b830760c520b056f7d1176b2907a2950c30d4399c4f40c470a2410a0518721ea27
7
+ data.tar.gz: 6bff729cc57f5b57cefc2f457357f27bf2e3c466d9791f482ce8b99d26f350ee5a8e9a17aaf32bacf544ffbfe4845bae4cfb0b5b1daf4f33efdba67bb984be95
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # Senkyoshi Canvas Plugin
2
+
3
+ This plugin enables the use of the Senkyoshi converter inside of Canvas. It adds a blackboard cartridge option to the import content dropdown for a course.
4
+
5
+ ## Installation
6
+
7
+ Add a file inside the `Gemfile.d` folder
8
+
9
+ ```ruby
10
+ # Gemfile.d/senkyoshi.rb
11
+ gem "canvas_cc", git: "https://github.com/atomicjolt/canvas_cc.git"
12
+ ```
13
+
14
+ ```sh
15
+ sysadmin@appserver:~$ cd /path/to/canvas/gems/plugins
16
+ sysadmin@appserver:/path/to/canvas/gems/plugins$ git clone https://github.com/atomicjolt/senkyoshi_canvas_plugin.git
17
+ ```
18
+
19
+ Now `bundle install` and `bundle exec rake canvas:compile_assets` and `rails server`.
20
+
21
+ After it is up, login with the site admin account and head over to the `/plugins` route (Navigated to by clicking `Admin -> Site Admin -> Plugins`).
22
+ Once there, scroll down to `Senkyoshi Conversion Importer` and click into it. Enable the plugin and add your Scorm information if needed.
23
+
24
+ You should be all set now. Enjoy!
25
+
@@ -0,0 +1,18 @@
1
+ # Copyright (C) 2017 Atomic Jolt
2
+
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Affero General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Affero General Public License for more details.
12
+
13
+ # You should have received a copy of the GNU Affero General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require [
17
+ 'senkyoshi_canvas_plugin/compiled/content_migration_setup_senkyoshi'
18
+ ], () ->
@@ -0,0 +1,71 @@
1
+ # Copyright (C) 2017 Atomic Jolt
2
+
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Affero General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Affero General Public License for more details.
12
+
13
+ # You should have received a copy of the GNU Affero General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ # Parts of this file have been copied from Instructures file located at
17
+ # https://github.com/instructure/canvas-lms/blob/4d944663f8ee9e17eb20fdf280333f9a6c04e749/app/coffeescripts/bundles/modules/content_migration_setup.coffee
18
+
19
+ define [
20
+ 'jquery'
21
+ 'i18n!content_migrations'
22
+ 'compiled/collections/DaySubstitutionCollection'
23
+ 'compiled/views/CollectionView'
24
+ 'compiled/views/content_migrations/ConverterViewControl'
25
+ 'compiled/views/content_migrations/CanvasExportView'
26
+ 'compiled/views/content_migrations/subviews/ChooseMigrationFileView'
27
+ 'compiled/views/content_migrations/subviews/SelectContentCheckboxView'
28
+ 'compiled/views/content_migrations/subviews/DateShiftView'
29
+ 'compiled/views/content_migrations/subviews/DaySubstitutionView'
30
+ 'vendor/jquery.ba-tinypubsub'
31
+ 'jst/content_migrations/subviews/DaySubstitutionCollection'
32
+ 'compiled/bundles/modules/content_migration_setup'
33
+ ], (
34
+ $,
35
+ I18n,
36
+ DaySubstitutionCollection,
37
+ CollectionView,
38
+ ConverterViewControl,
39
+ CanvasExportView,
40
+ ChooseMigrationFileView,
41
+ SelectContentCheckboxView,
42
+ DateShiftView,
43
+ DaySubView,
44
+ pubsub,
45
+ daySubCollectionTemplate
46
+ ) ->
47
+
48
+ emptyMessage = I18n.t('no_day_substitutions', "No Day Substitutions Added")
49
+ daySubCollection = new DaySubstitutionCollection
50
+ daySubCollectionView = new CollectionView
51
+ collection: daySubCollection
52
+ emptyMessage: -> emptyMessage
53
+ itemView: DaySubView
54
+ template: daySubCollectionTemplate
55
+
56
+ ConverterViewControl.register
57
+ key: 'senkyoshi_importer'
58
+ view: new CanvasExportView
59
+ chooseMigrationFile: new ChooseMigrationFileView
60
+ model: ConverterViewControl.getModel()
61
+ fileSizeLimit: ENV.UPLOAD_LIMIT
62
+
63
+ selectContent: new SelectContentCheckboxView
64
+ model: ConverterViewControl.getModel()
65
+
66
+ dateShift: new DateShiftView
67
+ model: ConverterViewControl.getModel()
68
+ collection: daySubCollection
69
+ daySubstitution: daySubCollectionView
70
+ oldStartDate: ENV.OLD_START_DATE
71
+ oldEndDate: ENV.OLD_END_DATE
@@ -0,0 +1,19 @@
1
+ <!--
2
+ Copyright (C) 2017 Atomic Jolt
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Affero General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ This program 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
12
+ GNU Affero General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Affero General Public License
15
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ -->
17
+
18
+ <%= render file: "#{Rails.root}/app/views/content_migrations/index.html.erb" %>
19
+ <% js_bundle :content_migration_senkyoshi, plugin: :senkyoshi_canvas_plugin %>
@@ -0,0 +1,38 @@
1
+ <!--
2
+ Copyright (C) 2017 Atomic Jolt
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Affero General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ This program 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
12
+ GNU Affero General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Affero General Public License
15
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ -->
17
+
18
+ <%= fields_for :settings, OpenObject.new(settings) do |f| %>
19
+ <table style="width: 500px;" class="formtable">
20
+ <tr>
21
+ <td colspan="2">
22
+ <%= mt :description, "You will need access to a [Scorm Player](%{url}) service if you want to also convert courses with scorm content.", url: "https://github.com/atomicjolt/adhesion" %>
23
+ </td>
24
+ </tr>
25
+ <tr>
26
+ <td><%= f.blabel :scorm_url, en: "Scorm URL" %></td>
27
+ <td><%= f.text_field :scorm_url %></td>
28
+ </tr>
29
+ <tr>
30
+ <td><%= f.blabel :scorm_launch_url, en: "Scorm Launch URL" %></td>
31
+ <td><%= f.text_field :scorm_launch_url %></td>
32
+ </tr>
33
+ <tr>
34
+ <td><%= f.blabel :scorm_shared_auth, en: "Scorm Shared Auth" %></td>
35
+ <td><%= f.text_field :scorm_shared_auth %></td>
36
+ </tr>
37
+ </table>
38
+ <% end %>
@@ -0,0 +1,198 @@
1
+ # Copyright (C) 2017 Atomic Jolt
2
+
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Affero General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Affero General Public License for more details.
12
+
13
+ # You should have received a copy of the GNU Affero General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "senkyoshi"
17
+
18
+ ARGUMENT_ERROR =
19
+ "converter_class required for content migration with no file".freeze
20
+
21
+ module Canvas
22
+ module Migration
23
+ module Worker
24
+ class SenkyoshiWorker < Base
25
+ def perform
26
+ migration ||= ContentMigration.where(id: migration_id).first
27
+ migration.job_progress.start unless migration.skip_job_progress
28
+
29
+ begin
30
+ migration.update_conversion_progress(1)
31
+
32
+ settings = _setup_settings(migration)
33
+
34
+ # Create the imscc file using Senkyoshi
35
+ imscc_path = settings[:file_path].ext(".imscc")
36
+ Senkyoshi.parse_and_process_single(settings[:file_path], imscc_path)
37
+
38
+ migration.update_conversion_progress(50)
39
+
40
+ if File.exists?(imscc_path)
41
+ _process_imscc(migration, settings, imscc_path)
42
+ else
43
+ text = I18n.t(:no_imscc_file, "Imscc file creation failed.")
44
+ raise Canvas::Migration::Error, text
45
+ end
46
+ rescue Canvas::Migration::Error => e
47
+ migration.add_error(e.message, exception: e)
48
+ migration.workflow_state = :failed
49
+ migration.job_progress.fail unless migration.skip_job_progress
50
+ migration.save
51
+ rescue => e
52
+ migration.fail_with_error!(e) if migration
53
+ end
54
+ end
55
+
56
+ def self.enqueue(content_migration)
57
+ Delayed::Job.enqueue(
58
+ new(content_migration.id),
59
+ priority: Delayed::LOW_PRIORITY,
60
+ max_attempts: 1,
61
+ strand: content_migration.strand,
62
+ )
63
+ end
64
+
65
+ def _setup_settings(migration)
66
+ settings = migration.migration_settings.clone
67
+ settings[:content_migration_id] = migration_id
68
+ settings[:user_id] = migration.user_id
69
+ settings[:content_migration] = migration
70
+
71
+ if migration.attachment
72
+ settings[:attachment_id] = migration.attachment.id
73
+ settings[:file_path] = migration.attachment.full_filename
74
+ elsif settings[:file_url]
75
+ attachment = Canvas::Migration::Worker.
76
+ download_attachment(migration, settings[:file_url])
77
+ settings[:attachment_id] = attachment.id
78
+ settings[:file_path] = attachment.full_filename
79
+ elsif !settings[:no_archive_file]
80
+ no_migration_file = "File required for content migration."
81
+ text = I18n.t(:no_migration_file, no_migration_file)
82
+ raise Canvas::Migration::Error, text
83
+ end
84
+ settings
85
+ end
86
+
87
+ def _process_imscc(migration, settings, imscc_path)
88
+ # Get the attachment for the ContentMigration
89
+ # And change its file to the imscc file temporarily
90
+ attachment = migration.attachment
91
+ attachment.write_attribute(:filename, File.basename(imscc_path))
92
+ attachment.save
93
+
94
+ converter_class = settings[:converter_class]
95
+ unless converter_class
96
+ if settings[:no_archive_file]
97
+ raise ArgumentError, ARGUMENT_ERROR
98
+ end
99
+ settings[:archive] = Canvas::Migration::Archive.new(settings)
100
+ converter_class = settings[:archive].get_converter
101
+ end
102
+
103
+ converter = converter_class.new(settings)
104
+ course = converter.export
105
+ export_folder_path = course[:export_folder_path]
106
+ overview_file_path = course[:overview_file_path]
107
+
108
+ _process_converted_data(
109
+ migration,
110
+ overview_file_path,
111
+ export_folder_path,
112
+ )
113
+
114
+ migration.migration_settings[:worker_class] = converter_class.name
115
+ migration.migration_settings[:migration_ids_to_import] =
116
+ { copy: { everything: true } }.merge(
117
+ migration.migration_settings[:migration_ids_to_import] || {},
118
+ )
119
+ if path = converter.course[:files_import_root_path]
120
+ migration.migration_settings[:files_import_root_path] = path
121
+ end
122
+
123
+ migration.workflow_state = :exported
124
+ saved = migration.save
125
+ migration.update_conversion_progress(100)
126
+
127
+ if migration.import_immediately? && !migration.for_course_copy?
128
+ _import_scorm(migration, settings)
129
+ saved = _import_content(migration, settings, attachment, converter)
130
+ end
131
+ saved
132
+ end
133
+
134
+ def _process_converted_data(migration,
135
+ overview_file_path,
136
+ export_folder_path)
137
+ if overview_file_path
138
+ file = File.new(overview_file_path)
139
+ Canvas::Migration::Worker::upload_overview_file(file, migration)
140
+ migration.update_conversion_progress(90)
141
+ end
142
+
143
+ if export_folder_path
144
+ Canvas::Migration::Worker::upload_exported_data(
145
+ export_folder_path,
146
+ migration,
147
+ )
148
+ Canvas::Migration::Worker::clear_exported_data(
149
+ export_folder_path,
150
+ )
151
+ end
152
+ end
153
+
154
+ def _import_scorm(migration, settings)
155
+ plugin = PluginSetting.find_by(name: "senkyoshi_importer")
156
+ if !plugin.disabled
157
+ Senkyoshi.configure do |config|
158
+ config.scorm_url = plugin.settings[:scorm_url]
159
+ config.scorm_launch_url = plugin.settings[:scorm_launch_url]
160
+ config.scorm_shared_auth = plugin.settings[:scorm_shared_auth]
161
+ end
162
+
163
+ meta = {
164
+ name: migration.context.name,
165
+ }
166
+ Zip::File.open(settings[:file_path], "rb") do |bb_zip|
167
+ senkyoshi_course = Senkyoshi::CanvasCourse.new(
168
+ meta,
169
+ migration.context,
170
+ bb_zip,
171
+ )
172
+ senkyoshi_course.process_scorm(local: true)
173
+ end
174
+ migration.update_import_progress(90)
175
+ end
176
+ end
177
+
178
+ def _import_content(migration, settings, attachment, converter)
179
+ migration.import_content
180
+
181
+ # Now that the import is done, change the attachment back
182
+ # to the blackboard zip for record keeping
183
+ attachment.write_attribute(
184
+ :filename,
185
+ File.basename(settings[:file_path]),
186
+ )
187
+ attachment.save
188
+ migration.update_import_progress(100)
189
+ saved = migration.save
190
+ if converter.respond_to?(:post_process)
191
+ converter.post_process
192
+ end
193
+ saved
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,19 @@
1
+ # Copyright (C) 2017 Atomic Jolt
2
+
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Affero General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Affero General Public License for more details.
12
+
13
+ # You should have received a copy of the GNU Affero General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "senkyoshi_canvas_plugin/engine"
17
+
18
+ module SenkyoshiCanvasPlugin
19
+ end
@@ -0,0 +1,51 @@
1
+ # Copyright (C) 2017 Atomic Jolt
2
+
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Affero General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Affero General Public License for more details.
12
+
13
+ # You should have received a copy of the GNU Affero General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ module SenkyoshiCanvasPlugin
17
+ NAME = "Senkyoshi Conversion Importer".freeze
18
+ DISPLAY_NAME = "Blackboard Cartridge".freeze
19
+ DESCRIPTION =
20
+ "This enables importing Blackboard Cartridges into Canvas.".freeze
21
+ class Engine < ::Rails::Engine
22
+ config.autoload_paths << File.expand_path(File.join(__FILE__, "../.."))
23
+
24
+ config.to_prepare do
25
+ Canvas::Plugin.register(
26
+ :senkyoshi_importer,
27
+ :export_system,
28
+ name: -> { I18n.t(:senkyoshi_name, NAME) },
29
+ display_name: -> { I18n.t :senkyoshi_display, DISPLAY_NAME },
30
+ author: "Atomic Jolt",
31
+ author_website: "http://www.atomicjolt.com/",
32
+ description: -> { t(:description, DESCRIPTION) },
33
+ version: SenkyoshiCanvasPlugin::VERSION,
34
+ settings_partial: "senkyoshi_canvas_plugin/plugin_settings",
35
+ select_text: -> do
36
+ I18n.t(:senkyoshi_importer_description, DISPLAY_NAME)
37
+ end,
38
+ settings: {
39
+ worker: "SenkyoshiWorker",
40
+ migration_partial: "canvas_config",
41
+ requires_file_upload: true,
42
+ provides: {
43
+ bb_learn: CC::Importer::Canvas::Converter,
44
+ },
45
+ valid_contexts: %w{Account Course},
46
+ },
47
+ )
48
+ require "senkyoshi_canvas_plugin/senkyoshi_migration"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright (C) 2017 Atomic Jolt
2
+
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Affero General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Affero General Public License for more details.
12
+
13
+ # You should have received a copy of the GNU Affero General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require_dependency "app/controllers/content_migrations_controller"
17
+
18
+ ENGINE_ROOT = SenkyoshiCanvasPlugin::Engine.root
19
+
20
+ class ContentMigrationsController
21
+ alias index_without_senkyoshi index
22
+ def index
23
+ index_without_senkyoshi
24
+ if !performed?
25
+ render file: "#{ENGINE_ROOT}/app/views/content_migrations/index.erb"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ # Copyright (C) 2017 Atomic Jolt
2
+
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Affero General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Affero General Public License for more details.
12
+
13
+ # You should have received a copy of the GNU Affero General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ module SenkyoshiCanvasPlugin
17
+ VERSION = "1.0.1".freeze
18
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: senkyoshi_canvas_plugin
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - James Carbine
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.1'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.2'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.1'
33
+ - !ruby/object:Gem::Dependency
34
+ name: canvas_cc
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: senkyoshi
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ description:
62
+ email:
63
+ - james.carbine@atomicjolt.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files:
67
+ - README.md
68
+ files:
69
+ - README.md
70
+ - app/coffeescripts/bundles/content_migration_senkyoshi.coffee
71
+ - app/coffeescripts/content_migration_setup_senkyoshi.coffee
72
+ - app/views/content_migrations/index.erb
73
+ - app/views/senkyoshi_canvas_plugin/_plugin_settings.erb
74
+ - lib/canvas/migration/worker/senkyoshi_worker.rb
75
+ - lib/senkyoshi_canvas_plugin.rb
76
+ - lib/senkyoshi_canvas_plugin/engine.rb
77
+ - lib/senkyoshi_canvas_plugin/senkyoshi_migration.rb
78
+ - lib/senkyoshi_canvas_plugin/version.rb
79
+ homepage: http://www.atomicjolt.com
80
+ licenses:
81
+ - AGPL-3.0
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '2.0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.6.8
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Senkyoshi Blackboard importer
103
+ test_files: []