Class: Senkyoshi::CanvasCourse

Inherits:
Object
  • Object
show all
Defined in:
lib/senkyoshi/canvas_course.rb

Overview

This class represents a canvas course for which we are uploading data to

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(metadata, course_resource, blackboard_export) ⇒ CanvasCourse

A new canvas course accepts the metadata for a course and the pandarus course resourse



20
21
22
23
24
# File 'lib/senkyoshi/canvas_course.rb', line 20

def initialize(, course_resource, blackboard_export)
  @metadata = 
  @course_resource = course_resource
  @scorm_packages = ScormPackage.get_scorm_packages(blackboard_export)
end

Instance Attribute Details

#scorm_packagesObject (readonly)

Returns the value of attribute scorm_packages.



14
15
16
# File 'lib/senkyoshi/canvas_course.rb', line 14

def scorm_packages
  @scorm_packages
end

Class Method Details

.clientObject

Create a new pandarus instance to communicate with the canvas server



44
45
46
47
48
49
# File 'lib/senkyoshi/canvas_course.rb', line 44

def self.client
  @client ||= Pandarus::Client.new(
    prefix: Senkyoshi.canvas_url,
    token: Senkyoshi.canvas_token,
  )
end

.from_metadata(metadata, blackboard_export = nil) ⇒ Object

Find or Create a new CanvasCourse instance from the given metadata



54
55
56
57
58
59
60
61
62
63
# File 'lib/senkyoshi/canvas_course.rb', line 54

def self.(, blackboard_export = nil)
  course_name = [:name] || [:title]
  canvas_course = client.create_new_course(
    Senkyoshi.,
    course: {
      name: course_name,
    },
  )
  CanvasCourse.new(, canvas_course, blackboard_export)
end

.metadata_from_file(filename) ⇒ Object

Given a filename to a zip file, extract the necessary metadata for the course



30
31
32
33
34
35
36
37
38
39
# File 'lib/senkyoshi/canvas_course.rb', line 30

def self.(filename)
  Zip::File.open(filename) do |file|
    settings = "course_settings/course_settings.xml"
    config = file.find_entry(settings).get_input_stream.read
    doc = Nokogiri::XML(config)
    {
      name: doc.at("title").text,
    }
  end
end

Instance Method Details

#create_scorm_assignment(scorm_package, course_id) ⇒ Object

Creates a canvas assignment from a scorm package that has already been uploaded to a scorm manager



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/senkyoshi/canvas_course.rb', line 69

def create_scorm_assignment(scorm_package, course_id)
  url = Senkyoshi.scorm_launch_url +
    "?course_id=#{scorm_package['package_id']}"

  payload = {
    assignment__submission_types__: ["external_tool"],
    assignment__integration_id__: scorm_package["package_id"],
    assignment__integration_data__: {
      provider: "atomic-scorm",
    },
    assignment__external_tool_tag_attributes__: {
      url: url,
    },
    assignment__points_possible__: scorm_package["points_possible"],
  }

  CanvasCourse.client.create_assignment(
    course_id,
    scorm_package["title"],
    payload,
  )
end

#create_scorm_assignments(scorm_packages, course_id) ⇒ Object

Creates assignments from all previously uploaded scorm packages



118
119
120
# File 'lib/senkyoshi/canvas_course.rb', line 118

def create_scorm_assignments(scorm_packages, course_id)
  scorm_packages.each { |pack| create_scorm_assignment(pack, course_id) }
end

#upload_content(filename) ⇒ Object

Create a migration for the course and upload the imscc file to be imported into the course



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/senkyoshi/canvas_course.rb', line 139

def upload_content(filename)
  client = CanvasCourse.client
  name = File.basename(filename)
  # Create a migration for the course and get S3 upload authorization
  migration = client.
    create_content_migration_courses(
      @course_resource.id,
      :canvas_cartridge_importer,
      pre_attachment: { name: name },
    )

  puts "Uploading: #{name}"
  upload_to_s3(migration, filename)
  puts "Done uploading: #{name}"

  puts "Creating Scorm: #{name}"
  create_scorm_assignments(
    upload_scorm_packages(@scorm_packages),
    @course_resource.id,
  )
  puts "Done creating scorm: #{name}"
end

#upload_scorm_package(scorm_package, course_id, tmp_name) ⇒ Object

Uploads a scorm package to scorm manager specified in senkyoshi.yml config file



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/senkyoshi/canvas_course.rb', line 96

def upload_scorm_package(scorm_package, course_id, tmp_name)
  zip = scorm_package.write_zip tmp_name
  File.open(zip, "rb") do |file|
    RestClient.post(
      "#{Senkyoshi.scorm_url}/api/scorm_courses",
      {
        oauth_consumer_key: "scorm-player",
        lms_course_id: course_id,
        file: file,
      },
      SharedAuthorization: Senkyoshi.scorm_shared_auth,
    ) do |resp|
      result = JSON.parse(resp.body)["response"]
      result["points_possible"] = scorm_package.points_possible
      result
    end
  end
end

#upload_scorm_packages(scorm_packages) ⇒ Object

Uploads all scorm packages to scorm manager specified in senkyoshi.yml config file



126
127
128
129
130
131
132
133
# File 'lib/senkyoshi/canvas_course.rb', line 126

def upload_scorm_packages(scorm_packages)
  package_index = 0
  scorm_packages.map do |pack|
    package_index += 1
    tmp_name = "#{@metadata[:name]}_#{package_index}.zip"
    upload_scorm_package(pack, @course_resource.id, tmp_name)
  end
end

#upload_to_s3(migration, filename) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/senkyoshi/canvas_course.rb', line 162

def upload_to_s3(migration, filename)
  File.open(filename, "rb") do |file|
    # Attach the file to the S3 auth
    pre_attachment = migration.pre_attachment
    upload_url = pre_attachment["upload_url"]
    upload_params = pre_attachment["upload_params"]
    upload_params[:file] = file

    # Post to S3
    RestClient.post(
      upload_url,
      upload_params,
    ) do |response|
      # Post to Canvas
      RestClient.post(
        response.headers[:location],
        nil,
        Authorization: "Bearer #{Senkyoshi.canvas_token}",
      )
    end
  end
end