senkyoshi 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +92 -0
  4. data/bin/console +14 -0
  5. data/bin/import_blackboard +6 -0
  6. data/lib/senkyoshi/canvas_course.rb +179 -0
  7. data/lib/senkyoshi/collection.rb +26 -0
  8. data/lib/senkyoshi/config.rb +35 -0
  9. data/lib/senkyoshi/exceptions.rb +13 -0
  10. data/lib/senkyoshi/models/announcement.rb +36 -0
  11. data/lib/senkyoshi/models/answer.rb +32 -0
  12. data/lib/senkyoshi/models/assessment.rb +95 -0
  13. data/lib/senkyoshi/models/assignment.rb +26 -0
  14. data/lib/senkyoshi/models/assignment_group.rb +23 -0
  15. data/lib/senkyoshi/models/blog.rb +22 -0
  16. data/lib/senkyoshi/models/content.rb +92 -0
  17. data/lib/senkyoshi/models/content_file.rb +26 -0
  18. data/lib/senkyoshi/models/course.rb +39 -0
  19. data/lib/senkyoshi/models/file.rb +99 -0
  20. data/lib/senkyoshi/models/forum.rb +28 -0
  21. data/lib/senkyoshi/models/gradebook.rb +30 -0
  22. data/lib/senkyoshi/models/group.rb +22 -0
  23. data/lib/senkyoshi/models/module.rb +22 -0
  24. data/lib/senkyoshi/models/module_item.rb +23 -0
  25. data/lib/senkyoshi/models/question.rb +188 -0
  26. data/lib/senkyoshi/models/questions/calculated.rb +72 -0
  27. data/lib/senkyoshi/models/questions/either_or.rb +31 -0
  28. data/lib/senkyoshi/models/questions/essay.rb +11 -0
  29. data/lib/senkyoshi/models/questions/file_upload.rb +4 -0
  30. data/lib/senkyoshi/models/questions/fill_in_blank.rb +15 -0
  31. data/lib/senkyoshi/models/questions/fill_in_blank_plus.rb +20 -0
  32. data/lib/senkyoshi/models/questions/hot_spot.rb +11 -0
  33. data/lib/senkyoshi/models/questions/jumbled_sentence.rb +37 -0
  34. data/lib/senkyoshi/models/questions/matching.rb +57 -0
  35. data/lib/senkyoshi/models/questions/multiple_answer.rb +56 -0
  36. data/lib/senkyoshi/models/questions/multiple_choice.rb +18 -0
  37. data/lib/senkyoshi/models/questions/numerical.rb +31 -0
  38. data/lib/senkyoshi/models/questions/opinion_scale.rb +18 -0
  39. data/lib/senkyoshi/models/questions/ordering.rb +40 -0
  40. data/lib/senkyoshi/models/questions/quiz_bowl.rb +11 -0
  41. data/lib/senkyoshi/models/questions/short_response.rb +4 -0
  42. data/lib/senkyoshi/models/questions/true_false.rb +15 -0
  43. data/lib/senkyoshi/models/quiz.rb +7 -0
  44. data/lib/senkyoshi/models/resource.rb +33 -0
  45. data/lib/senkyoshi/models/scorm_package.rb +109 -0
  46. data/lib/senkyoshi/models/staff_info.rb +72 -0
  47. data/lib/senkyoshi/models/wikipage.rb +34 -0
  48. data/lib/senkyoshi/tasks.rb +90 -0
  49. data/lib/senkyoshi/version.rb +3 -0
  50. data/lib/senkyoshi/xml_parser.rb +154 -0
  51. data/lib/senkyoshi.rb +69 -0
  52. metadata +250 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cb37815e8613f1dc566a20f201f9613fd0caa850
4
+ data.tar.gz: e7c7eb79f471a87f0e2f3f103074294649128659
5
+ SHA512:
6
+ metadata.gz: 437ab1a18a0f0fa3038317efaf884341ad25b03f0fcf3c9b3d0bbd44cefec3e407ee3f7a6c302ea1eb8e1455330f33ca09e0d2d17d0c6c042ece072715eaedb3
7
+ data.tar.gz: 2fe6f2ab0dba999722a2b93d4d2f7667a1833d00c2b0a62e6b6600fb1439e882d2981bbfbf3a31e3a64619f0711b8f4d45f89743b5c76f5539918e4498f74dc6
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 AtomicJolt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # Senkyoshi Converter [![Build Status](https://travis-ci.org/atomicjolt/senkyoshi.svg?branch=master)](https://travis-ci.org/atomicjolt/senkyoshi)
2
+
3
+ TODO: Describe the gem
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem "senkyoshi"
11
+ gem "canvas_cc", git: "https://github.com/atomicjolt/canvas_cc.git"
12
+ ```
13
+
14
+ And then execute:
15
+ ```sh
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```sh
21
+ $ gem install senkyoshi
22
+ ```
23
+
24
+ Create a `Rakefile` and add
25
+ ```ruby
26
+ require "senkyoshi/tasks"
27
+ Senkyoshi::Tasks.install_tasks
28
+ ```
29
+
30
+ Create a `senkyoshi.yml` and add credentials
31
+ ```yaml
32
+ # Generally looks like https://< mycanvas_instance >/api
33
+ :canvas_url: <canvas instance api url>
34
+
35
+ # Canvas tokens can be generated at <my_canvas_url>/profile/setting provided
36
+ # that the user has the required priviledges
37
+ :canvas_token: <canvas token>
38
+
39
+ # Url of scorm manager. This could the the adhesion app
40
+ # [https://github.com/atomicjolt/adhesion]
41
+ :scorm_url: <scorm manager url>
42
+
43
+ # This should be the endpoint to launch a given scorm course, in the case of
44
+ # adhesion this will look like https://<adhesion url>/scorm_course
45
+ :scorm_launch_url: <scorm launch url>
46
+
47
+ # This is the secret to authenticate requests to the scorm manager. In the case
48
+ # of adhesion you can generate a shared secret by logging into the server and
49
+ # running rake shared_auth, which will generate and save a token
50
+ :scorm_shared_auth: <scorm manager token>
51
+
52
+ # The account or sub-account id. This can be :self, :default, or an id
53
+ :account_id: <id>
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ Run the rake task to convert from .zip to .imscc
59
+ ```sh
60
+ rake imscc
61
+ ```
62
+ This will take all your files in your source folder and convert them to your outputs folder
63
+
64
+ Run converting files in parallel
65
+ ```sh
66
+ time rake imscc -m
67
+ ```
68
+
69
+ Delete entire outputs folder
70
+ ```sh
71
+ rake clean
72
+ ```
73
+
74
+ ## Development
75
+
76
+ After checking out the repo, run `bundle install` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
77
+
78
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
79
+
80
+ ## Contributing
81
+
82
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/senkyoshi. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
83
+
84
+
85
+ ## License
86
+
87
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
88
+
89
+
90
+ ### Things not quite implemented
91
+ People Group Sets
92
+ Blogs
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "senkyoshi"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.start
12
+
13
+ # require "irb"
14
+ # IRB.start
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "senkyoshi"
4
+
5
+ # ruby -Ilib ./bin/import_blackboard ~/sources ~/canvas
6
+ Senkyoshi.parse(*ARGV)
@@ -0,0 +1,179 @@
1
+ require "pandarus"
2
+ require "senkyoshi/config"
3
+ require "senkyoshi/models/scorm_package"
4
+ require "rest-client"
5
+
6
+ module Senkyoshi
7
+ ##
8
+ # This class represents a canvas course for which we are uploading data to
9
+ ##
10
+ class CanvasCourse
11
+ ##
12
+ # A new canvas course accepts the metadata for a course
13
+ # and the pandarus course resourse
14
+ ##
15
+ def initialize(metadata, course_resource, blackboard_export)
16
+ @metadata = metadata
17
+ @course_resource = course_resource
18
+ @scorm_packages = ScormPackage.get_scorm_packages(blackboard_export)
19
+ end
20
+
21
+ ##
22
+ # Given a filename to a zip file, extract the necessary metadata
23
+ # for the course
24
+ ##
25
+ def self.metadata_from_file(filename)
26
+ Zip::File.open(filename) do |file|
27
+ settings = "course_settings/course_settings.xml"
28
+ config = file.find_entry(settings).get_input_stream.read
29
+ doc = Nokogiri::XML(config)
30
+ {
31
+ name: doc.at("title").text,
32
+ }
33
+ end
34
+ end
35
+
36
+ ##
37
+ # Create a new pandarus instance to communicate with the canvas server
38
+ ##
39
+ def self.client
40
+ @client ||= Pandarus::Client.new(
41
+ prefix: Senkyoshi.canvas_url,
42
+ token: Senkyoshi.canvas_token,
43
+ )
44
+ end
45
+
46
+ ##
47
+ # Find or Create a new CanvasCourse instance from the given metadata
48
+ ##
49
+ def self.from_metadata(metadata, blackboard_export = nil)
50
+ course_name = metadata[:name] || metadata[:title]
51
+ courses = client.list_active_courses_in_account(Senkyoshi.account_id)
52
+ canvas_course = courses.detect { |course| course.name == course_name } ||
53
+ client.create_new_course(
54
+ Senkyoshi.account_id,
55
+ course: {
56
+ name: course_name,
57
+ },
58
+ )
59
+ CanvasCourse.new(metadata, canvas_course, blackboard_export)
60
+ end
61
+
62
+ ##
63
+ # Creates a canvas assignment from a scorm package that has already been
64
+ # uploaded to a scorm manager
65
+ ##
66
+ def create_scorm_assignment(scorm_package, course_id)
67
+ url = Senkyoshi.scorm_launch_url +
68
+ "?course_id=#{scorm_package['package_id']}"
69
+
70
+ payload = {
71
+ assignment__submission_types__: ["external_tool"],
72
+ assignment__integration_id__: scorm_package["package_id"],
73
+ assignment__integration_data__: {
74
+ provider: "atomic-scorm",
75
+ },
76
+ assignment__external_tool_tag_attributes__: {
77
+ url: url,
78
+ },
79
+ }
80
+
81
+ CanvasCourse.client.create_assignment(
82
+ course_id,
83
+ scorm_package["title"],
84
+ payload,
85
+ )
86
+ end
87
+
88
+ ##
89
+ # Uploads a scorm package to scorm manager specified in senkyoshi.yml
90
+ # config file
91
+ ##
92
+ def upload_scorm_package(scorm_package, course_id, tmp_name)
93
+ zip = scorm_package.write_zip tmp_name
94
+ File.open(zip, "rb") do |file|
95
+ RestClient.post(
96
+ "#{Senkyoshi.scorm_url}/api/scorm_courses",
97
+ {
98
+ oauth_consumer_key: "scorm-player",
99
+ lms_course_id: course_id,
100
+ file: file,
101
+ },
102
+ SharedAuthorization: Senkyoshi.scorm_shared_auth,
103
+ ) do |resp|
104
+ JSON.parse(resp.body)["response"]
105
+ end
106
+ end
107
+ end
108
+
109
+ ##
110
+ # Creates assignments from all previously uploaded scorm packages
111
+ ##
112
+ def create_scorm_assignments(scorm_packages, course_id)
113
+ scorm_packages.each { |pack| create_scorm_assignment(pack, course_id) }
114
+ end
115
+
116
+ ##
117
+ # Uploads all scorm packages to scorm manager specified in senkyoshi.yml
118
+ # config file
119
+ ##
120
+ def upload_scorm_packages(scorm_packages)
121
+ package_index = 0
122
+ scorm_packages.map do |pack|
123
+ package_index += 1
124
+ tmp_name = "#{@metadata[:name]}_#{package_index}.zip"
125
+ upload_scorm_package(pack, @course_resource.id, tmp_name)
126
+ end
127
+ end
128
+
129
+ ##
130
+ # Create a migration for the course
131
+ # and upload the imscc file to be imported into the course
132
+ ##
133
+ def upload_content(filename)
134
+ client = CanvasCourse.client
135
+ name = File.basename(filename)
136
+ # Create a migration for the course and get S3 upload authorization
137
+ migration = client.
138
+ create_content_migration_courses(
139
+ @course_resource.id,
140
+ :canvas_cartridge_importer,
141
+ pre_attachment: { name: name },
142
+ )
143
+
144
+ puts "Uploading: #{name}"
145
+ upload_to_s3(migration, filename)
146
+ puts "Done uploading: #{name}"
147
+
148
+ puts "Creating Scorm: #{name}"
149
+ create_scorm_assignments(
150
+ upload_scorm_packages(@scorm_packages),
151
+ @course_resource.id,
152
+ )
153
+ puts "Done creating scorm: #{name}"
154
+ end
155
+
156
+ def upload_to_s3(migration, filename)
157
+ File.open(filename, "rb") do |file|
158
+ # Attach the file to the S3 auth
159
+ pre_attachment = migration.pre_attachment
160
+ upload_url = pre_attachment["upload_url"]
161
+ upload_params = pre_attachment["upload_params"]
162
+ upload_params[:file] = file
163
+
164
+ # Post to S3
165
+ RestClient.post(
166
+ upload_url,
167
+ upload_params,
168
+ ) do |response|
169
+ # Post to Canvas
170
+ RestClient.post(
171
+ response.headers[:location],
172
+ nil,
173
+ Authorization: "Bearer #{Senkyoshi.canvas_token}",
174
+ )
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,26 @@
1
+ module Senkyoshi
2
+ class Collection
3
+ attr_reader :resources
4
+
5
+ def initialize
6
+ @resources = []
7
+ end
8
+
9
+ def add(resources)
10
+ @resources.concat(resources)
11
+ end
12
+
13
+ def detect_xid(xid)
14
+ @resources.detect do |resource|
15
+ resource.matches_xid? xid
16
+ end
17
+ end
18
+
19
+ def each
20
+ @resources.each do |resource|
21
+ yield resource
22
+ end
23
+ self
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+ require "yaml"
2
+
3
+ module Senkyoshi
4
+ def self.canvas_url
5
+ Senkyoshi._config[:canvas_url]
6
+ end
7
+
8
+ def self.canvas_token
9
+ Senkyoshi._config[:canvas_token]
10
+ end
11
+
12
+ def self.scorm_launch_url
13
+ Senkyoshi._config[:scorm_launch_url]
14
+ end
15
+
16
+ def self.scorm_url
17
+ Senkyoshi._config[:scorm_url]
18
+ end
19
+
20
+ def self.scorm_shared_auth
21
+ Senkyoshi._config[:scorm_shared_auth]
22
+ end
23
+
24
+ def self.account_id
25
+ Senkyoshi._config[:account_id] || :self
26
+ end
27
+
28
+ def self._config
29
+ @config ||= if File.exists? "senkyoshi.yml"
30
+ YAML::load(File.read("senkyoshi.yml"))
31
+ else
32
+ {}
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,13 @@
1
+ module Exceptions
2
+ class BadFileNameError < StandardError
3
+ def initialize(msg = "Bad File Name")
4
+ super(msg)
5
+ end
6
+ end
7
+
8
+ class MissingFileError < StandardError
9
+ def initialize(msg = "Couldn't find file")
10
+ super(msg)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,36 @@
1
+ require "senkyoshi/models/resource"
2
+
3
+ module Senkyoshi
4
+ class Announcement < Resource
5
+ def initialize
6
+ @title = ""
7
+ @text = ""
8
+ @delayed_post = ""
9
+ @posted_at = ""
10
+ @identifier = Senkyoshi.create_random_hex
11
+ @dependency = Senkyoshi.create_random_hex
12
+ @type = "announcement"
13
+ end
14
+
15
+ def iterate_xml(data, _)
16
+ dates = data.children.at("DATES")
17
+ @title = Senkyoshi.get_attribute_value(data, "TITLE")
18
+ @text = Senkyoshi.get_text(data, "TEXT")
19
+ @delayed_post = Senkyoshi.get_attribute_value(dates, "RESTRICTSTART")
20
+ @posted_at = Senkyoshi.get_attribute_value(dates, "CREATED")
21
+ self
22
+ end
23
+
24
+ def canvas_conversion(course, _resources = nil)
25
+ announcement = CanvasCc::CanvasCC::Models::Announcement.new
26
+ announcement.title = @title
27
+ announcement.text = @text
28
+ announcement.delayed_post = @delayed_post
29
+ announcement.posted_at = @posted_at
30
+ announcement.identifier = @identifier
31
+ announcement.dependency = @dependency
32
+ course.announcements << announcement
33
+ course
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,32 @@
1
+ require "senkyoshi/models/resource"
2
+
3
+ module Senkyoshi
4
+ class Answer < Resource
5
+ attr_reader :id, :answer_text
6
+ attr_accessor :fraction, :resp_ident, :feedback
7
+
8
+ def initialize(text, id = Senkyoshi.create_random_hex)
9
+ @answer_text = text
10
+ @resp_ident = ""
11
+ @fraction = ""
12
+ @feedback = ""
13
+ @points = 0
14
+ @id = id
15
+ end
16
+
17
+ def iterate_xml
18
+ self
19
+ end
20
+
21
+ def canvas_conversion(question, resources)
22
+ answer = CanvasCc::CanvasCC::Models::Answer.new(@answer_text)
23
+ answer.answer_text = fix_html(@answer_text, resources)
24
+ answer.id = @id
25
+ answer.fraction = @fraction
26
+ answer.feedback = @feedback
27
+ answer.resp_ident = @resp_ident
28
+ question.answers << answer
29
+ question
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,95 @@
1
+ require "senkyoshi/models/assignment_group"
2
+ require "senkyoshi/models/assignment"
3
+ require "senkyoshi/models/question"
4
+ require "senkyoshi/models/resource"
5
+
6
+ module Senkyoshi
7
+ class Assessment < Resource
8
+ def initialize
9
+ @title = ""
10
+ @description = ""
11
+ @quiz_type = "assignment"
12
+ @points_possible = 0
13
+ @items = []
14
+ @group_name = ""
15
+ @workflow_state = "published"
16
+ @available = true
17
+ end
18
+
19
+ def iterate_xml(data, pre_data)
20
+ pre_data ||= {}
21
+ @id = pre_data[:assignment_id] || Senkyoshi.create_random_hex
22
+ @title = data.at("assessment").attributes["title"].value
23
+ @points_possible = data.at("qmd_absolutescore_max").text
24
+ @description = data.at("presentation_material").
25
+ at("mat_formattedtext").text
26
+ @group_name = data.at("bbmd_assessmenttype").text
27
+ data.at("section").children.map do |item|
28
+ @items.push(item) if item.name == "item"
29
+ end
30
+ self
31
+ end
32
+
33
+ def canvas_conversion(course, resources)
34
+ if @items.count > 0
35
+ assessment = CanvasCc::CanvasCC::Models::Assessment.new
36
+ assessment.identifier = @id
37
+ course = create_assignment_group(course, resources)
38
+ assignment = create_assignment
39
+ assignment.quiz_identifier_ref = assessment.identifier
40
+ course.assignments << assignment
41
+ assessment = setup_assessment(assessment, assignment, resources)
42
+ course.assessments << assessment
43
+ end
44
+ course
45
+ end
46
+
47
+ def setup_assessment(assessment, assignment, resources)
48
+ assessment.title = @title
49
+ assessment.description = fix_html(@description, resources)
50
+ assessment.available = @available
51
+ assessment.quiz_type = @quiz_type
52
+ assessment.points_possible = @points_possible
53
+ assessment = create_items(assessment, resources)
54
+ assessment.assignment = assignment
55
+ assessment
56
+ end
57
+
58
+ def create_items(assessment, resources)
59
+ @items = @items - ["", nil]
60
+ questions = @items.map do |item|
61
+ Question.from(item)
62
+ end
63
+ assessment.items = []
64
+ questions.each do |item|
65
+ assessment = item.canvas_conversion(assessment, resources)
66
+ end
67
+ assessment
68
+ end
69
+
70
+ def create_assignment_group(course, resources)
71
+ group = course.assignment_groups.detect { |a| a.title == @group_name }
72
+ if group
73
+ @group_id = group.identifier
74
+ else
75
+ @group_id = Senkyoshi.create_random_hex
76
+ assignment_group = AssignmentGroup.new(@group_name, @group_id)
77
+ course = assignment_group.canvas_conversion(course, resources)
78
+ end
79
+ course
80
+ end
81
+
82
+ def create_assignment
83
+ assignment = CanvasCc::CanvasCC::Models::Assignment.new
84
+ assignment.identifier = Senkyoshi.create_random_hex
85
+ assignment.assignment_group_identifier_ref = @group_id
86
+ assignment.title = @title
87
+ assignment.position = 1
88
+ assignment.submission_types << "online_quiz"
89
+ assignment.grading_type = "points"
90
+ assignment.workflow_state = @workflow_state
91
+ assignment.points_possible = @points_possible
92
+ assignment
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,26 @@
1
+ require "senkyoshi/models/resource"
2
+
3
+ module Senkyoshi
4
+ class Assignment < Content
5
+ def canvas_conversion(course, resources)
6
+ unless @title == "--TOP--"
7
+ assignment = CanvasCc::CanvasCC::Models::Assignment.new
8
+ assignment.identifier = @id
9
+ assignment.title = @title
10
+ assignment.body = fix_html(@body, resources)
11
+ assignment.points_possible = @points
12
+ assignment.assignment_group_identifier_ref = @group_id
13
+ assignment.position = 1
14
+ assignment.workflow_state = "published"
15
+ assignment.submission_types << "online_text_entry"
16
+ assignment.submission_types << "online_upload"
17
+ assignment.grading_type = "points"
18
+
19
+ @files.each { |f| assignment.body << f.canvas_conversion }
20
+ course = create_module(course)
21
+ course.assignments << assignment
22
+ end
23
+ course
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ require "senkyoshi/models/resource"
2
+
3
+ module Senkyoshi
4
+ class AssignmentGroup < Resource
5
+ attr_reader :id
6
+ def initialize(name, group_id)
7
+ @title = name
8
+ @group_weight = ""
9
+ @rules = {}
10
+ @id = group_id
11
+ end
12
+
13
+ def canvas_conversion(course, _resources = nil)
14
+ assignment_group = CanvasCc::CanvasCC::Models::AssignmentGroup.new
15
+ assignment_group.identifier = @id
16
+ assignment_group.title = @title
17
+ assignment_group.group_weight = @group_weight
18
+ assignment_group.rules = @rules
19
+ course.assignment_groups << assignment_group
20
+ course
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ require "senkyoshi/models/resource"
2
+
3
+ module Senkyoshi
4
+ class Blog < Resource
5
+ def initialize
6
+ @title = ""
7
+ @description = ""
8
+ @is_public = true
9
+ end
10
+
11
+ def iterate_xml(data, _)
12
+ @name = Senkyoshi.get_attribute_value(data, "TITLE")
13
+ @description = data.at("TEXT").text
14
+ @is_public = Senkyoshi.get_attribute_value(data, "ISAVAILABLE")
15
+ self
16
+ end
17
+
18
+ def canvas_conversion(course, _resources = nil)
19
+ course
20
+ end
21
+ end
22
+ end