diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index f2fffd8f74c..e2fbd154f71 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -141,6 +141,7 @@ class SubmissionsController < ApplicationController "online_url" => ["url"].freeze, "online_upload" => ["file_ids"].freeze, "media_recording" => ["media_comment_id", "media_comment_type"].freeze, + "basic_lti_launch" => ["url"].freeze }.freeze # @API Submit an assignment @@ -158,7 +159,7 @@ class SubmissionsController < ApplicationController # @argument comment[text_comment] [String] # Include a textual comment with the submission. # - # @argument submission[submission_type] [Required, String, "online_text_entry"|"online_url"|"online_upload"|"media_recording"] + # @argument submission[submission_type] [Required, String, "online_text_entry"|"online_url"|"online_upload"|"media_recording"|"basic_lti_launch"] # The type of submission being made. The assignment submission_types must # include this submission type as an allowed option, or the submission will be rejected with a 400 error. # @@ -177,7 +178,7 @@ class SubmissionsController < ApplicationController # Submit the assignment as a URL. The URL scheme must be "http" or "https", # no "ftp" or other URL schemes are allowed. If no scheme is given (e.g. # "www.example.com") then "http" will be assumed. Requires a submission_type - # of "online_url". + # of "online_url" or "basic_lti_launch". # # @argument submission[file_ids][] [Integer] # Submit the assignment as a set of one or more previously uploaded files diff --git a/app/models/assignment.rb b/app/models/assignment.rb index 08752a48b31..200482f2ccd 100644 --- a/app/models/assignment.rb +++ b/app/models/assignment.rb @@ -1321,7 +1321,7 @@ class Assignment < ActiveRecord::Base submitted = case opts[:submission_type] when "online_text_entry" opts[:body].present? - when "online_url" + when "online_url", "basic_lti_launch" opts[:url].present? when "online_upload" opts[:attachments].size > 0 diff --git a/app/models/assignment/speed_grader.rb b/app/models/assignment/speed_grader.rb index 51f68891e92..e9182975688 100644 --- a/app/models/assignment/speed_grader.rb +++ b/app/models/assignment/speed_grader.rb @@ -2,7 +2,6 @@ require_relative '../assignment' class Assignment class SpeedGrader - def initialize(assignment, user, avatars: false, grading_role: :grader) @assignment = assignment @user = user @@ -117,7 +116,7 @@ class Assignment res[:submissions] = submissions.map do |sub| json = sub.as_json(:include_root => false, - :methods => [:submission_history, :late], + :methods => [:submission_history, :late, :external_tool_url], :only => submission_fields ).merge("from_enrollment_type" => enrollment_types_by_id[sub.user_id]) diff --git a/app/models/lti/lti_assignment_creator.rb b/app/models/lti/lti_assignment_creator.rb index cd06d05a405..4fd9760309f 100644 --- a/app/models/lti/lti_assignment_creator.rb +++ b/app/models/lti/lti_assignment_creator.rb @@ -3,8 +3,9 @@ module Lti SUBMISSION_TYPES_MAP = { 'online_upload' => 'file', 'online_url' => 'url', - 'external_tool' => ['url', 'text'] - } + 'external_tool' => ['url', 'text'].freeze, + 'basic_lti_launch' => 'url' + }.freeze def initialize(assignment, source_id = nil) @assignment = assignment diff --git a/app/models/submission.rb b/app/models/submission.rb index e00fd1cee35..2cdd57b5b82 100644 --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -482,6 +482,13 @@ class Submission < ActiveRecord::Base turnitin_data.select{|_, v| v.is_a?(Hash) && v.key?(:outcome_response)}.any? end + def external_tool_url + if self.submission_type == 'basic_lti_launch' + base_url = "#{HostUrl.protocol}://#{HostUrl.default_host}" + base_url + "/courses/#{assignment.context.id}/external_tools/retrieve?display=borderless&assignment_id=#{assignment.id}&url=#{URI.encode(url)}" + end + end + def touch_graders self.class.connection.after_transaction_commit do if self.assignment && self.user && self.assignment.context.is_a?(Course) diff --git a/lib/basic_lti/basic_outcomes.rb b/lib/basic_lti/basic_outcomes.rb index 561d5f399d0..e7ecf71a1e7 100644 --- a/lib/basic_lti/basic_outcomes.rb +++ b/lib/basic_lti/basic_outcomes.rb @@ -124,6 +124,10 @@ module BasicLTI @lti_request && @lti_request.at_css('imsx_POXBody > replaceResultRequest > resultRecord > result > resultData > url').try(:content) end + def result_data_launch_url + @lti_request && @lti_request.at_css('imsx_POXBody > replaceResultRequest > resultRecord > result > resultData > ltiLaunchUrl').try(:content) + end + def to_xml xml = LtiResponse.envelope.dup xml.at_css('imsx_POXHeader imsx_statusInfo imsx_codeMajor').content = code_major @@ -186,7 +190,7 @@ module BasicLTI protected - def handle_replaceResult(tool, course, assignment, user) + def handle_replaceResult(_tool, _course, assignment, user) text_value = self.result_score new_score = Float(text_value) rescue false raw_score = Float(self.result_total_score) rescue false @@ -196,9 +200,12 @@ module BasicLTI if text = result_data_text submission_hash[:body] = text submission_hash[:submission_type] = 'online_text_entry' - elsif url = result_data_url + elsif (url = result_data_url) submission_hash[:url] = url submission_hash[:submission_type] = 'online_url' + elsif (launch_url = result_data_launch_url) + submission_hash[:url] = launch_url + submission_hash[:submission_type] = 'basic_lti_launch' end old_submission = assignment.submissions.where(user_id: user.id).first diff --git a/public/javascripts/speed_grader.js b/public/javascripts/speed_grader.js index 748a1487e71..fca419628c2 100644 --- a/public/javascripts/speed_grader.js +++ b/public/javascripts/speed_grader.js @@ -1772,13 +1772,11 @@ define([ $iframe_holder.show().loadDocPreview($.extend(previewOptions, { crocodoc_session_url: (attachment.provisional_crocodoc_url || attachment.crocodoc_url) })); - } - else if (attachment && attachment.canvadoc_url) { + } else if (attachment && attachment.canvadoc_url) { $iframe_holder.show().loadDocPreview($.extend(previewOptions, { canvadoc_session_url: attachment.canvadoc_url })); - } - else if ( attachment && ($.isPreviewable(attachment.content_type, 'google')) ) { + } else if ( attachment && ($.isPreviewable(attachment.content_type, 'google')) ) { if (!INST.disableCrocodocPreviews) $no_annotation_warning.show(); var currentStudentIDAsOfAjaxCall = this.currentStudent.id; @@ -1787,16 +1785,20 @@ define([ return(currentStudentIDAsOfAjaxCall == this.currentStudent.id); },this)}); $iframe_holder.show().loadDocPreview(previewOptions); - } - else if (attachment && browserableCssClasses.test(attachment.mime_class)) { - var src = unescape($submission_file_hidden.find('.display_name').attr('href')) - .replace("{{submissionId}}", this.currentStudent.submission.user_id) - .replace("{{attachmentId}}", attachment.id); - $iframe_holder.html('').show(); - } - else { - //load in the iframe preview. if we are viewing a past version of the file pass the version to preview in the url - $iframe_holder.html($.raw( + } else if (attachment && browserableCssClasses.test(attachment.mime_class)) { + var src = unescape($submission_file_hidden.find('.display_name').attr('href')) + .replace("{{submissionId}}", this.currentStudent.submission.user_id) + .replace("{{attachmentId}}", attachment.id); + $iframe_holder.html('').show(); + } else if (this.currentStudent.submission.external_tool_url) { + $iframe_holder.html( + $.raw('' + ) + ).show(); + } else { + //load in the iframe preview. if we are viewing a past version of the file pass the version to preview in the url + $iframe_holder.html($.raw( '