senkyoshi 1.0.1 → 1.0.2
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 +4 -4
- data/README.md +7 -2
- data/lib/senkyoshi/canvas_course.rb +15 -9
- data/lib/senkyoshi/models/assessment.rb +4 -93
- data/lib/senkyoshi/models/attachment.rb +21 -0
- data/lib/senkyoshi/models/content.rb +39 -18
- data/lib/senkyoshi/models/content_file.rb +21 -4
- data/lib/senkyoshi/models/external_url.rb +9 -0
- data/lib/senkyoshi/models/file.rb +22 -21
- data/lib/senkyoshi/models/gradebook.rb +5 -8
- data/lib/senkyoshi/models/module_item.rb +3 -1
- data/lib/senkyoshi/models/qti.rb +215 -0
- data/lib/senkyoshi/models/question.rb +3 -3
- data/lib/senkyoshi/models/question_bank.rb +46 -0
- data/lib/senkyoshi/models/questions/fill_in_blank.rb +3 -1
- data/lib/senkyoshi/models/questions/fill_in_blank_plus.rb +3 -1
- data/lib/senkyoshi/models/questions/matching.rb +8 -3
- data/lib/senkyoshi/models/questions/multiple_choice.rb +12 -0
- data/lib/senkyoshi/models/questions/numerical.rb +4 -1
- data/lib/senkyoshi/models/questions/true_false.rb +1 -1
- data/lib/senkyoshi/models/resource.rb +8 -6
- data/lib/senkyoshi/models/scorm_package.rb +51 -34
- data/lib/senkyoshi/models/staff_info.rb +49 -31
- data/lib/senkyoshi/models/survey.rb +10 -0
- data/lib/senkyoshi/models/wikipage.rb +55 -9
- data/lib/senkyoshi/version.rb +1 -2
- data/lib/senkyoshi/xml_parser.rb +60 -31
- data/lib/senkyoshi.rb +14 -8
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13edfb731484992561073e292a28f75a15bfaa5d
|
4
|
+
data.tar.gz: 528e83f4e9f0a60f88a40cd8d503e35b07fa8655
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 470eafc042455cf9221aac1dca5544fb2ad335c5c9ab5f4fc5c368bd270c6ee40d25ffcb4991f5625351f21ead8220f3178315bf9076d2c455f1d421b9debb1d
|
7
|
+
data.tar.gz: 57c7176e3b952dbf02dff18ba3546ac02a2ebe35b72bafd3f8b52f220cb9cf759f21c25ab9518d10ebadaafa4fe1eb6f739888badba46d5909de7f39a403cc12
|
data/README.md
CHANGED
@@ -57,13 +57,13 @@ Create a `senkyoshi.yml` and add credentials
|
|
57
57
|
|
58
58
|
Run the rake task to convert from .zip to .imscc
|
59
59
|
```sh
|
60
|
-
rake imscc
|
60
|
+
rake senkyoshi:imscc
|
61
61
|
```
|
62
62
|
This will take all your files in your source folder and convert them to your outputs folder
|
63
63
|
|
64
64
|
Run converting files in parallel
|
65
65
|
```sh
|
66
|
-
time rake imscc -m
|
66
|
+
time rake senkyoshi:imscc -m
|
67
67
|
```
|
68
68
|
|
69
69
|
Delete entire outputs folder
|
@@ -71,6 +71,11 @@ Delete entire outputs folder
|
|
71
71
|
rake clean
|
72
72
|
```
|
73
73
|
|
74
|
+
Upload to canvas to process
|
75
|
+
```sh
|
76
|
+
rake senkyoshi:upload
|
77
|
+
```
|
78
|
+
|
74
79
|
## Development
|
75
80
|
|
76
81
|
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.
|
@@ -3,11 +3,16 @@ require "senkyoshi/config"
|
|
3
3
|
require "senkyoshi/models/scorm_package"
|
4
4
|
require "rest-client"
|
5
5
|
|
6
|
+
require "openssl"
|
7
|
+
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
|
8
|
+
|
6
9
|
module Senkyoshi
|
7
10
|
##
|
8
11
|
# This class represents a canvas course for which we are uploading data to
|
9
12
|
##
|
10
13
|
class CanvasCourse
|
14
|
+
attr_reader :scorm_packages
|
15
|
+
|
11
16
|
##
|
12
17
|
# A new canvas course accepts the metadata for a course
|
13
18
|
# and the pandarus course resourse
|
@@ -48,14 +53,12 @@ module Senkyoshi
|
|
48
53
|
##
|
49
54
|
def self.from_metadata(metadata, blackboard_export = nil)
|
50
55
|
course_name = metadata[:name] || metadata[:title]
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
},
|
58
|
-
)
|
56
|
+
canvas_course = client.create_new_course(
|
57
|
+
Senkyoshi.account_id,
|
58
|
+
course: {
|
59
|
+
name: course_name,
|
60
|
+
},
|
61
|
+
)
|
59
62
|
CanvasCourse.new(metadata, canvas_course, blackboard_export)
|
60
63
|
end
|
61
64
|
|
@@ -76,6 +79,7 @@ module Senkyoshi
|
|
76
79
|
assignment__external_tool_tag_attributes__: {
|
77
80
|
url: url,
|
78
81
|
},
|
82
|
+
assignment__points_possible__: scorm_package["points_possible"],
|
79
83
|
}
|
80
84
|
|
81
85
|
CanvasCourse.client.create_assignment(
|
@@ -101,7 +105,9 @@ module Senkyoshi
|
|
101
105
|
},
|
102
106
|
SharedAuthorization: Senkyoshi.scorm_shared_auth,
|
103
107
|
) do |resp|
|
104
|
-
JSON.parse(resp.body)["response"]
|
108
|
+
result = JSON.parse(resp.body)["response"]
|
109
|
+
result["points_possible"] = scorm_package.points_possible
|
110
|
+
result
|
105
111
|
end
|
106
112
|
end
|
107
113
|
end
|
@@ -1,99 +1,10 @@
|
|
1
|
-
require "senkyoshi/models/
|
2
|
-
require "senkyoshi/models/assignment"
|
3
|
-
require "senkyoshi/models/question"
|
4
|
-
require "senkyoshi/models/resource"
|
1
|
+
require "senkyoshi/models/qti"
|
5
2
|
|
6
3
|
module Senkyoshi
|
7
|
-
class Assessment <
|
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
|
-
|
4
|
+
class Assessment < QTI
|
19
5
|
def iterate_xml(data, pre_data)
|
20
|
-
|
21
|
-
|
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
|
-
case @group_name.downcase
|
28
|
-
when "survey"
|
29
|
-
@quiz_type = "survey"
|
30
|
-
end
|
31
|
-
data.at("section").children.map do |item|
|
32
|
-
@items.push(item) if item.name == "item"
|
33
|
-
end
|
34
|
-
self
|
35
|
-
end
|
36
|
-
|
37
|
-
def canvas_conversion(course, resources)
|
38
|
-
if @items.count > 0
|
39
|
-
assessment = CanvasCc::CanvasCC::Models::Assessment.new
|
40
|
-
assessment.identifier = @id
|
41
|
-
course = create_assignment_group(course, resources)
|
42
|
-
assignment = create_assignment
|
43
|
-
assignment.quiz_identifier_ref = assessment.identifier
|
44
|
-
course.assignments << assignment
|
45
|
-
assessment = setup_assessment(assessment, assignment, resources)
|
46
|
-
course.assessments << assessment
|
47
|
-
end
|
48
|
-
course
|
49
|
-
end
|
50
|
-
|
51
|
-
def setup_assessment(assessment, assignment, resources)
|
52
|
-
assessment.title = @title
|
53
|
-
assessment.description = fix_html(@description, resources)
|
54
|
-
assessment.available = @available
|
55
|
-
assessment.quiz_type = @quiz_type
|
56
|
-
assessment.points_possible = @points_possible
|
57
|
-
assessment = create_items(assessment, resources)
|
58
|
-
assessment.assignment = assignment
|
59
|
-
assessment
|
60
|
-
end
|
61
|
-
|
62
|
-
def create_items(assessment, resources)
|
63
|
-
@items = @items - ["", nil]
|
64
|
-
questions = @items.map do |item|
|
65
|
-
Question.from(item)
|
66
|
-
end
|
67
|
-
assessment.items = []
|
68
|
-
questions.each do |item|
|
69
|
-
assessment = item.canvas_conversion(assessment, resources)
|
70
|
-
end
|
71
|
-
assessment
|
72
|
-
end
|
73
|
-
|
74
|
-
def create_assignment_group(course, resources)
|
75
|
-
group = course.assignment_groups.detect { |a| a.title == @group_name }
|
76
|
-
if group
|
77
|
-
@group_id = group.identifier
|
78
|
-
else
|
79
|
-
@group_id = Senkyoshi.create_random_hex
|
80
|
-
assignment_group = AssignmentGroup.new(@group_name, @group_id)
|
81
|
-
course = assignment_group.canvas_conversion(course, resources)
|
82
|
-
end
|
83
|
-
course
|
84
|
-
end
|
85
|
-
|
86
|
-
def create_assignment
|
87
|
-
assignment = CanvasCc::CanvasCC::Models::Assignment.new
|
88
|
-
assignment.identifier = Senkyoshi.create_random_hex
|
89
|
-
assignment.assignment_group_identifier_ref = @group_id
|
90
|
-
assignment.title = @title
|
91
|
-
assignment.position = 1
|
92
|
-
assignment.submission_types << "online_quiz"
|
93
|
-
assignment.grading_type = "points"
|
94
|
-
assignment.workflow_state = @workflow_state
|
95
|
-
assignment.points_possible = @points_possible
|
96
|
-
assignment
|
6
|
+
@quiz_type = "assignment"
|
7
|
+
super
|
97
8
|
end
|
98
9
|
end
|
99
10
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "senkyoshi/models/content"
|
2
|
+
require "senkyoshi/models/module_item"
|
3
|
+
|
4
|
+
module Senkyoshi
|
5
|
+
class Attachment < Content
|
6
|
+
def iterate_xml(xml, pre_data)
|
7
|
+
super
|
8
|
+
@module_item = ModuleItem.new(
|
9
|
+
@title,
|
10
|
+
@module_type,
|
11
|
+
@files.first.name,
|
12
|
+
@url,
|
13
|
+
).canvas_conversion
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def canvas_conversion(course, _resource)
|
18
|
+
create_module(course)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "senkyoshi/models/resource"
|
2
|
+
require "senkyoshi/models/content_file"
|
2
3
|
|
3
4
|
module Senkyoshi
|
4
5
|
class Content < Resource
|
@@ -8,11 +9,11 @@ module Senkyoshi
|
|
8
9
|
"x-bb-assignment" => "Assignment",
|
9
10
|
"x-bbpi-selfpeer-type1" => "Assignment",
|
10
11
|
"x-bb-document" => "WikiPage",
|
11
|
-
"x-bb-file" => "
|
12
|
-
"x-bb-audio" => "
|
13
|
-
"x-bb-image" => "
|
14
|
-
"x-bb-video" => "
|
15
|
-
"x-bb-externallink" => "
|
12
|
+
"x-bb-file" => "Attachment",
|
13
|
+
"x-bb-audio" => "Attachment",
|
14
|
+
"x-bb-image" => "Attachment",
|
15
|
+
"x-bb-video" => "Attachment",
|
16
|
+
"x-bb-externallink" => "ExternalUrl",
|
16
17
|
"x-bb-blankpage" => "WikiPage",
|
17
18
|
"x-bb-lesson" => "WikiPage",
|
18
19
|
"x-bb-folder" => "WikiPage",
|
@@ -21,11 +22,28 @@ module Senkyoshi
|
|
21
22
|
"x-bb-syllabus" => "WikiPage",
|
22
23
|
}.freeze
|
23
24
|
|
24
|
-
|
25
|
+
MODULE_TYPES = {
|
26
|
+
"Senkyoshi::Attachment" => "Attachment",
|
27
|
+
"Senkyoshi::Assignment" => "Assignment",
|
28
|
+
"Senkyoshi::ExternalUrl" => "ExternalUrl",
|
29
|
+
"Senkyoshi::WikiPage" => "WikiPage",
|
30
|
+
"Senkyoshi::Quiz" => "Quizzes::Quiz",
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
attr_accessor(:title, :body, :id, :files, :url)
|
34
|
+
attr_reader(:extendeddata)
|
25
35
|
|
26
|
-
def self.from(xml, pre_data)
|
36
|
+
def self.from(xml, pre_data, resource_xids)
|
27
37
|
type = xml.xpath("/CONTENT/CONTENTHANDLER/@value").first.text
|
28
38
|
type.slice! "resource/"
|
39
|
+
xml.xpath("//FILES/FILE").each do |file|
|
40
|
+
file_name = ContentFile.clean_xid file.at("NAME").text
|
41
|
+
is_attachment = CONTENT_TYPES[type] == "Attachment"
|
42
|
+
if !resource_xids.include?(file_name) && is_attachment
|
43
|
+
type = "x-bb-document"
|
44
|
+
break
|
45
|
+
end
|
46
|
+
end
|
29
47
|
if content_type = CONTENT_TYPES[type]
|
30
48
|
content_class = Senkyoshi.const_get content_type
|
31
49
|
content = content_class.new
|
@@ -35,25 +53,33 @@ module Senkyoshi
|
|
35
53
|
|
36
54
|
def iterate_xml(xml, pre_data)
|
37
55
|
@points = pre_data[:points] || 0
|
56
|
+
@parent_title = pre_data[:parent_title]
|
38
57
|
@title = xml.xpath("/CONTENT/TITLE/@value").first.text
|
39
58
|
@url = xml.at("URL")["value"]
|
40
59
|
@body = xml.xpath("/CONTENT/BODY/TEXT").first.text
|
60
|
+
@extendeddata = xml.at("/CONTENT/EXTENDEDDATA/ENTRY")
|
61
|
+
if @extendeddata
|
62
|
+
@extendeddata = @extendeddata.text
|
63
|
+
end
|
41
64
|
@type = xml.xpath("/CONTENT/RENDERTYPE/@value").first.text
|
42
65
|
@parent_id = pre_data[:parent_id]
|
43
|
-
|
44
|
-
bb_type.slice! "resource/"
|
45
|
-
@module_type = CONTENT_TYPES[bb_type]
|
66
|
+
@module_type = MODULE_TYPES[self.class.name]
|
46
67
|
@id = xml.xpath("/CONTENT/@id").first.text
|
47
68
|
if pre_data[:assignment_id] && !pre_data[:assignment_id].empty?
|
48
69
|
@id = pre_data[:assignment_id]
|
49
70
|
end
|
50
|
-
@module_item = set_module if @module_type
|
51
71
|
@files = xml.xpath("//FILES/FILE").map do |file|
|
52
72
|
ContentFile.new(file)
|
53
73
|
end
|
74
|
+
@module_item = set_module if @module_type
|
54
75
|
self
|
55
76
|
end
|
56
77
|
|
78
|
+
def set_module
|
79
|
+
module_item = ModuleItem.new(@title, @module_type, @id, @url)
|
80
|
+
module_item.canvas_conversion
|
81
|
+
end
|
82
|
+
|
57
83
|
def get_pre_data(xml, file_name)
|
58
84
|
id = xml.xpath("/CONTENT/@id").first.text
|
59
85
|
parent_id = xml.xpath("/CONTENT/PARENTID/@value").first.text
|
@@ -64,12 +90,6 @@ module Senkyoshi
|
|
64
90
|
}
|
65
91
|
end
|
66
92
|
|
67
|
-
def set_module
|
68
|
-
@module_type = "Quizzes::Quiz" if @module_type == "Quiz"
|
69
|
-
module_item = ModuleItem.new(@title, @module_type, @id)
|
70
|
-
module_item.canvas_conversion
|
71
|
-
end
|
72
|
-
|
73
93
|
def canvas_conversion(course, _resources = nil)
|
74
94
|
course
|
75
95
|
end
|
@@ -81,7 +101,8 @@ module Senkyoshi
|
|
81
101
|
if cc_module
|
82
102
|
cc_module.module_items << @module_item
|
83
103
|
else
|
84
|
-
|
104
|
+
title = @parent_title || @title
|
105
|
+
cc_module = Module.new(title, @parent_id)
|
85
106
|
cc_module = cc_module.canvas_conversion
|
86
107
|
cc_module.module_items << @module_item
|
87
108
|
course.canvas_modules << cc_module
|
@@ -2,17 +2,34 @@ require "senkyoshi/models/resource"
|
|
2
2
|
|
3
3
|
module Senkyoshi
|
4
4
|
class ContentFile < Resource
|
5
|
-
|
5
|
+
attr_reader(:id, :name, :linkname)
|
6
6
|
|
7
7
|
def initialize(xml)
|
8
8
|
@id = xml.xpath("./@id").first.text
|
9
|
-
@name = xml.xpath("./NAME").first.text
|
10
9
|
@linkname = xml.xpath("./LINKNAME/@value").first.text
|
10
|
+
@name = ContentFile.clean_xid xml.xpath("./NAME").first.text
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
##
|
14
|
+
# Remove leading slash if necessary so that ContentFile.name will match
|
15
|
+
# the Senkyoshi.xid
|
16
|
+
##
|
17
|
+
def self.clean_xid(xid)
|
18
|
+
if xid.start_with? "/"
|
19
|
+
xid[1..-1]
|
20
|
+
else
|
21
|
+
xid
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.correct_linkname(canvas_file)
|
26
|
+
canvas_file.file_path.split("/").last
|
27
|
+
end
|
28
|
+
|
29
|
+
def canvas_conversion(canvas_file = nil)
|
30
|
+
path = canvas_file ? canvas_file.file_path : @linkname
|
14
31
|
query = "?canvas_download=1&canvas_qs_wrap=1"
|
15
|
-
href = "$IMS_CC_FILEBASE$/#{
|
32
|
+
href = "$IMS_CC_FILEBASE$/#{path}#{query}"
|
16
33
|
%{
|
17
34
|
<a
|
18
35
|
class="instructure_scribd_file instructure_file_link"
|
@@ -3,23 +3,23 @@ require "senkyoshi/exceptions"
|
|
3
3
|
|
4
4
|
module Senkyoshi
|
5
5
|
class SenkyoshiFile < Resource
|
6
|
-
attr_accessor(:
|
7
|
-
@@dir = nil
|
6
|
+
attr_accessor(:xid, :location, :path)
|
8
7
|
|
9
8
|
FILE_BLACKLIST = [
|
10
9
|
"*.dat",
|
11
10
|
].freeze
|
12
11
|
|
13
12
|
def initialize(zip_entry)
|
14
|
-
path = zip_entry.name
|
15
|
-
id = File.basename(path)
|
16
|
-
xid = id[/__(xid-[0-9]+_[0-9]+)/, 1]
|
17
|
-
name = id.gsub(/__xid-[0-9]+_[0-9]+/, "")
|
18
|
-
|
13
|
+
@path = strip_xid zip_entry.name
|
19
14
|
@location = extract_file(zip_entry) # Location of file on local filesystem
|
20
|
-
|
21
|
-
|
22
|
-
@xid = xid
|
15
|
+
|
16
|
+
base_name = File.basename(zip_entry.name)
|
17
|
+
@xid = base_name[/__(xid-[0-9]+_[0-9]+)/, 1] ||
|
18
|
+
Senkyoshi.create_random_hex
|
19
|
+
end
|
20
|
+
|
21
|
+
def strip_xid(name)
|
22
|
+
name.gsub(/__xid-[0-9]+_[0-9]+/, "")
|
23
23
|
end
|
24
24
|
|
25
25
|
def matches_xid?(xid)
|
@@ -27,9 +27,9 @@ module Senkyoshi
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def extract_file(entry)
|
30
|
-
|
30
|
+
@dir ||= Dir.mktmpdir
|
31
31
|
|
32
|
-
name = "#{
|
32
|
+
name = "#{@dir}/#{entry.name}"
|
33
33
|
path = File.dirname(name)
|
34
34
|
FileUtils.mkdir_p path unless Dir.exist? path
|
35
35
|
entry.extract(name)
|
@@ -38,9 +38,9 @@ module Senkyoshi
|
|
38
38
|
|
39
39
|
def canvas_conversion(course, _resources = nil)
|
40
40
|
file = CanvasCc::CanvasCC::Models::CanvasFile.new
|
41
|
-
file.identifier = @
|
41
|
+
file.identifier = @xid
|
42
42
|
file.file_location = @location
|
43
|
-
file.file_path =
|
43
|
+
file.file_path = @path
|
44
44
|
file.hidden = false
|
45
45
|
|
46
46
|
course.files << file
|
@@ -50,8 +50,8 @@ module Senkyoshi
|
|
50
50
|
##
|
51
51
|
# Remove temporary files
|
52
52
|
##
|
53
|
-
def
|
54
|
-
FileUtils.rm_r
|
53
|
+
def cleanup
|
54
|
+
FileUtils.rm_r @dir unless @dir.nil?
|
55
55
|
end
|
56
56
|
|
57
57
|
##
|
@@ -64,14 +64,15 @@ module Senkyoshi
|
|
64
64
|
##
|
65
65
|
# Determine whether or not a file is a metadata file or not
|
66
66
|
##
|
67
|
-
def self.metadata_file?(
|
67
|
+
def self.metadata_file?(entry_names, file)
|
68
68
|
if File.extname(file.name) == ".xml"
|
69
69
|
# Detect and skip metadata files.
|
70
|
-
|
70
|
+
non_meta_file = File.join(
|
71
71
|
File.dirname(file.name),
|
72
72
|
File.basename(file.name, ".xml"),
|
73
73
|
)
|
74
|
-
|
74
|
+
|
75
|
+
entry_names.include?(non_meta_file)
|
75
76
|
else
|
76
77
|
false
|
77
78
|
end
|
@@ -89,9 +90,9 @@ module Senkyoshi
|
|
89
90
|
##
|
90
91
|
# Determine if a file should be included in course files or not
|
91
92
|
##
|
92
|
-
def self.valid_file?(
|
93
|
+
def self.valid_file?(entry_names, scorm_paths, file)
|
93
94
|
return false if SenkyoshiFile.blacklisted? file
|
94
|
-
return false if SenkyoshiFile.metadata_file?
|
95
|
+
return false if SenkyoshiFile.metadata_file? entry_names, file
|
95
96
|
return false if SenkyoshiFile.belongs_to_scorm_package? scorm_paths, file
|
96
97
|
true
|
97
98
|
end
|
@@ -3,16 +3,13 @@ module Senkyoshi
|
|
3
3
|
def get_pre_data(data, _)
|
4
4
|
categories = get_categories(data)
|
5
5
|
data.search("OUTCOMEDEFINITIONS").children.map do |outcome|
|
6
|
-
content_id = outcome.at("CONTENTID").attributes["value"].value
|
7
|
-
assignment_id = outcome.at("ASIDATAID").attributes["value"].value
|
8
6
|
category_id = outcome.at("CATEGORYID").attributes["value"].value
|
9
|
-
category = categories[category_id]
|
10
|
-
points = outcome.at("POINTSPOSSIBLE").attributes["value"].value
|
11
7
|
{
|
12
|
-
category:
|
13
|
-
points:
|
14
|
-
content_id:
|
15
|
-
assignment_id:
|
8
|
+
category: categories[category_id],
|
9
|
+
points: outcome.at("POINTSPOSSIBLE").attributes["value"].value,
|
10
|
+
content_id: outcome.at("CONTENTID").attributes["value"].value,
|
11
|
+
assignment_id: outcome.at("ASIDATAID").attributes["value"].value,
|
12
|
+
due_at: outcome.at("DUE").attributes["value"].value,
|
16
13
|
}
|
17
14
|
end
|
18
15
|
end
|
@@ -2,12 +2,13 @@ require "senkyoshi/models/resource"
|
|
2
2
|
|
3
3
|
module Senkyoshi
|
4
4
|
class ModuleItem < Resource
|
5
|
-
def initialize(title, type, identifierref)
|
5
|
+
def initialize(title, type, identifierref, url)
|
6
6
|
@title = title
|
7
7
|
@identifier = Senkyoshi.create_random_hex
|
8
8
|
@content_type = type
|
9
9
|
@identifierref = identifierref
|
10
10
|
@workflow_state = "active"
|
11
|
+
@url = url
|
11
12
|
end
|
12
13
|
|
13
14
|
def canvas_conversion(*)
|
@@ -17,6 +18,7 @@ module Senkyoshi
|
|
17
18
|
item.content_type = @content_type
|
18
19
|
item.identifierref = @identifierref
|
19
20
|
item.workflow_state = @workflow_state
|
21
|
+
item.url = @url
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|