-
Notifications
You must be signed in to change notification settings - Fork 346
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #449 from doubtfire-lms/new/scorm
New/scorm
- Loading branch information
Showing
44 changed files
with
2,120 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module Entities | ||
class TestAttemptEntity < Grape::Entity | ||
expose :id | ||
expose :task_id | ||
expose :attempted_time | ||
expose :terminated | ||
expose :success_status | ||
expose :score_scaled | ||
expose :completion_status | ||
expose :cmi_datamodel | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
require 'grape' | ||
require 'zip' | ||
require 'mime/types' | ||
class ScormApi < Grape::API | ||
# Include the AuthenticationHelpers for authentication functionality | ||
helpers AuthenticationHelpers | ||
helpers AuthorisationHelpers | ||
|
||
before do | ||
authenticated? :scorm | ||
end | ||
|
||
helpers do | ||
# Method to stream a file from a zip archive at the specified path | ||
# @param zip_path [String] the path to the zip archive | ||
# @param file_path [String] the path of the file within the zip archive | ||
def stream_file_from_zip(zip_path, file_path) | ||
file_stream = nil | ||
|
||
logger.debug "Streaming zip file at #{zip_path}" | ||
# Get an input stream for the requested file within the ZIP archive | ||
Zip::File.open(zip_path) do |zip_file| | ||
zip_file.each do |entry| | ||
next unless entry.name == file_path | ||
logger.debug "Found file #{file_path} from SCORM container" | ||
file_stream = entry.get_input_stream | ||
break | ||
end | ||
end | ||
|
||
# If the file was not found in the ZIP archive, return a 404 response | ||
unless file_stream | ||
error!({ error: 'File not found' }, 404) | ||
end | ||
|
||
# Set the content type based on the file extension | ||
content_type = MIME::Types.type_for(file_path).first.content_type | ||
logger.debug "Content type: #{content_type}" | ||
|
||
# Set the content type header | ||
header 'Content-Type', content_type | ||
|
||
# Set cache control header to prevent caching | ||
header 'Cache-Control', 'no-cache, no-store, must-revalidate' | ||
|
||
# Set the body to the contents of the file_stream and return the response | ||
body file_stream.read | ||
end | ||
end | ||
|
||
desc 'Serve SCORM content' | ||
params do | ||
requires :task_def_id, type: Integer, desc: 'Task Definition ID to get SCORM test data for' | ||
end | ||
get '/scorm/:task_def_id/:username/:auth_token/*file_path' do | ||
task_def = TaskDefinition.find(params[:task_def_id]) | ||
|
||
unless authorise? current_user, task_def.unit, :get_unit | ||
error!({ error: 'You cannot access SCORM tests of unit' }, 403) | ||
end | ||
|
||
env['api.format'] = :txt | ||
if task_def.has_scorm_data? | ||
zip_path = task_def.task_scorm_data | ||
content_type 'application/octet-stream' | ||
stream_file_from_zip(zip_path, params[:file_path]) | ||
else | ||
error!({ error: 'SCORM data does not exist.' }, 404) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
require 'grape' | ||
|
||
class ScormExtensionCommentsApi < Grape::API | ||
helpers AuthenticationHelpers | ||
helpers AuthorisationHelpers | ||
|
||
desc 'Request a scorm extension for a task' | ||
params do | ||
requires :comment, type: String, desc: 'The details of the request' | ||
end | ||
post '/projects/:project_id/task_def_id/:task_definition_id/request_scorm_extension' do | ||
project = Project.find(params[:project_id]) | ||
task_definition = project.unit.task_definitions.find(params[:task_definition_id]) | ||
task = project.task_for_task_definition(task_definition) | ||
|
||
# check permissions using specific permission has with addition of request extension if allowed in unit | ||
unless authorise? current_user, task, :request_scorm_extension | ||
error!({ error: 'Not authorised to request a scorm extension for this task' }, 403) | ||
end | ||
|
||
if task_definition.scorm_attempt_limit == 0 | ||
error!({ message: 'This task allows unlimited attempts to complete the test' }, 400) | ||
return | ||
end | ||
|
||
result = task.apply_for_scorm_extension(current_user, params[:comment]) | ||
present result.serialize(current_user), Grape::Presenters::Presenter | ||
end | ||
|
||
desc 'Assess a scorm extension for a task' | ||
params do | ||
requires :granted, type: Boolean, desc: 'Assess a scorm extension' | ||
end | ||
put '/projects/:project_id/task_def_id/:task_definition_id/assess_scorm_extension/:task_comment_id' do | ||
project = Project.find(params[:project_id]) | ||
task_definition = project.unit.task_definitions.find(params[:task_definition_id]) | ||
task = project.task_for_task_definition(task_definition) | ||
|
||
unless authorise? current_user, task, :assess_scorm_extension | ||
error!({ error: 'Not authorised to assess a scorm extension for this task' }, 403) | ||
end | ||
|
||
task_comment = task.all_comments.find(params[:task_comment_id]).becomes(ScormExtensionComment) | ||
|
||
unless task_comment.assess_scorm_extension(current_user, params[:granted]) | ||
if task_comment.errors.count >= 1 | ||
error!({ error: task_comment.errors.full_messages.first }, 403) | ||
else | ||
error!({ error: 'Error saving scorm extension' }, 403) | ||
end | ||
end | ||
present task_comment.serialize(current_user), Grape::Presenters::Presenter | ||
end | ||
end |
Oops, something went wrong.