senkyoshi_canvas_plugin 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []