canvas-lms/lib/services/submit_homework_service.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

220 lines
6.0 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
#
# Copyright (C) 2016 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
module Services
class SubmitHomeworkService
CloneUrlError = Class.new(StandardError)
EmailWorker = Struct.new(:message) do
def perform
Mailer.deliver(Mailer.create_message(message))
end
def on_permanent_failure(error)
Canvas::Errors.capture_exception(self.class.name, error)
end
end
CloneUrlExecutor = Struct.new(:url, :duplicate_handling, :check_quota, :opts) do
def execute(attachment)
attachment.clone_url(url, duplicate_handling, check_quota, opts)
end
end
Fix comments for external tool file submissions Comments when submitting a file upload via an external tool appear to have been broken in https://github.com/instructure/canvas-lms/commit/8cdf400ba720623d8d2c This commit changes the UI to again send the comment to the server, and changes the server-side code to process the comment. The server side code has two possible data paths: * With InstFS: include the comment in the JWT we send (in capture_params) to InstFS. When InstFS is done it hits FilesController#api_capture. Now it include comment -- so we now take the comment and pass it into SubmitHomeworkService which submits it. * Without InstFS: pass the comment in when making the asynchronous job in SubmitHomeworkService.submit_job() in this case, though. Note: File uploads using an external tool appear to not work at all (?) using Assignments 2. This fix is for "classic" Assignments. Also, I can get file uploads using an external tool for group assignments to work at all, locally or production. It was supposedly working as of b55cf587. Someone else should check and we can create another ticket for that apparently separate issue. I did test that the "comment" is now getting through to the call to SubmitHomeworkService. flag=none closes PLAT-4390 Test plan: - If running locally, disable Assignments 2 by editing config/feature_flags/meeseeks_release_flags.yml and commenting out the hardcoded "environments: development: state: on" config under "assignments_2_student" - You may need to run `node_modules/bin/.webpack` or `rails canvas:compile_assets` to compile the coffeescript. - Install an LTI tool such as Box or Google Drive which allows file upload. - Make an assignment that accepts file upload - As a student, submit an assignment by choosing a file to upload with the LTI tool. After choosing a file, add a comment and submit. - Start asynchronous jobs if running Canvas locally. - Previously, the assignment would be submitted with no comment. Now, once submitted, the attachment should show up on the right side of the assignment page for the student. Under this the comment should appear. - Submit again, this time with no comment, and check that no comment is added. - InstFS team will help test this for the InstFS route. - Test external tool file submission for group assignments on production (or beta) and we can create another ticket if that isn't working. Change-Id: Ie0bbacae1e732518aae46017f72be8a72f567510 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/221096 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Product-Review: Evan Battaglia <ebattaglia@instructure.com> Reviewed-by: Marc Phillips <mphillips@instructure.com> QA-Review: Jonathan Featherstone <jfeatherstone@instructure.com>
2019-12-17 10:34:56 +08:00
CopyWorker = Struct.new(:attachment_id, :progress_id, :clone_url_executor) do
def progress
@progress ||= Progress.find(progress_id)
end
def attachment
@attachment ||= Attachment.find(attachment_id)
end
def perform
progress.start! unless progress.running?
clone_url_executor.execute(attachment)
raise(CloneUrlError, attachment.upload_error_message) if attachment.file_state == "errored"
progress.complete! unless progress.failed?
rescue => e
mark_as_failure(e)
end
def on_permanent_failure(error)
mark_as_failure(error)
end
private
def mark_as_failure(error)
Canvas::Errors.capture_exception(self.class.name, error)[:error_report]
progress.message = error
progress.save!
progress.fail!
end
end
Fix comments for external tool file submissions Comments when submitting a file upload via an external tool appear to have been broken in https://github.com/instructure/canvas-lms/commit/8cdf400ba720623d8d2c This commit changes the UI to again send the comment to the server, and changes the server-side code to process the comment. The server side code has two possible data paths: * With InstFS: include the comment in the JWT we send (in capture_params) to InstFS. When InstFS is done it hits FilesController#api_capture. Now it include comment -- so we now take the comment and pass it into SubmitHomeworkService which submits it. * Without InstFS: pass the comment in when making the asynchronous job in SubmitHomeworkService.submit_job() in this case, though. Note: File uploads using an external tool appear to not work at all (?) using Assignments 2. This fix is for "classic" Assignments. Also, I can get file uploads using an external tool for group assignments to work at all, locally or production. It was supposedly working as of b55cf587. Someone else should check and we can create another ticket for that apparently separate issue. I did test that the "comment" is now getting through to the call to SubmitHomeworkService. flag=none closes PLAT-4390 Test plan: - If running locally, disable Assignments 2 by editing config/feature_flags/meeseeks_release_flags.yml and commenting out the hardcoded "environments: development: state: on" config under "assignments_2_student" - You may need to run `node_modules/bin/.webpack` or `rails canvas:compile_assets` to compile the coffeescript. - Install an LTI tool such as Box or Google Drive which allows file upload. - Make an assignment that accepts file upload - As a student, submit an assignment by choosing a file to upload with the LTI tool. After choosing a file, add a comment and submit. - Start asynchronous jobs if running Canvas locally. - Previously, the assignment would be submitted with no comment. Now, once submitted, the attachment should show up on the right side of the assignment page for the student. Under this the comment should appear. - Submit again, this time with no comment, and check that no comment is added. - InstFS team will help test this for the InstFS route. - Test external tool file submission for group assignments on production (or beta) and we can create another ticket if that isn't working. Change-Id: Ie0bbacae1e732518aae46017f72be8a72f567510 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/221096 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Product-Review: Evan Battaglia <ebattaglia@instructure.com> Reviewed-by: Marc Phillips <mphillips@instructure.com> QA-Review: Jonathan Featherstone <jfeatherstone@instructure.com>
2019-12-17 10:34:56 +08:00
SubmitWorker = Struct.new(:attachment_id, :progress_id, :eula_agreement_timestamp, :comment, :clone_url_executor) do
def progress
@progress ||= Progress.find(progress_id)
end
def attachment
@attachment ||= Attachment.find(attachment_id)
end
def homework_service
@homework_service ||= SubmitHomeworkService.new(attachment, progress)
end
def perform
return unless attachment
homework_service.start!
clone_url_executor.execute(attachment)
raise(CloneUrlError, attachment.upload_error_message) if attachment.file_state == "errored"
Fix comments for external tool file submissions Comments when submitting a file upload via an external tool appear to have been broken in https://github.com/instructure/canvas-lms/commit/8cdf400ba720623d8d2c This commit changes the UI to again send the comment to the server, and changes the server-side code to process the comment. The server side code has two possible data paths: * With InstFS: include the comment in the JWT we send (in capture_params) to InstFS. When InstFS is done it hits FilesController#api_capture. Now it include comment -- so we now take the comment and pass it into SubmitHomeworkService which submits it. * Without InstFS: pass the comment in when making the asynchronous job in SubmitHomeworkService.submit_job() in this case, though. Note: File uploads using an external tool appear to not work at all (?) using Assignments 2. This fix is for "classic" Assignments. Also, I can get file uploads using an external tool for group assignments to work at all, locally or production. It was supposedly working as of b55cf587. Someone else should check and we can create another ticket for that apparently separate issue. I did test that the "comment" is now getting through to the call to SubmitHomeworkService. flag=none closes PLAT-4390 Test plan: - If running locally, disable Assignments 2 by editing config/feature_flags/meeseeks_release_flags.yml and commenting out the hardcoded "environments: development: state: on" config under "assignments_2_student" - You may need to run `node_modules/bin/.webpack` or `rails canvas:compile_assets` to compile the coffeescript. - Install an LTI tool such as Box or Google Drive which allows file upload. - Make an assignment that accepts file upload - As a student, submit an assignment by choosing a file to upload with the LTI tool. After choosing a file, add a comment and submit. - Start asynchronous jobs if running Canvas locally. - Previously, the assignment would be submitted with no comment. Now, once submitted, the attachment should show up on the right side of the assignment page for the student. Under this the comment should appear. - Submit again, this time with no comment, and check that no comment is added. - InstFS team will help test this for the InstFS route. - Test external tool file submission for group assignments on production (or beta) and we can create another ticket if that isn't working. Change-Id: Ie0bbacae1e732518aae46017f72be8a72f567510 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/221096 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Product-Review: Evan Battaglia <ebattaglia@instructure.com> Reviewed-by: Marc Phillips <mphillips@instructure.com> QA-Review: Jonathan Featherstone <jfeatherstone@instructure.com>
2019-12-17 10:34:56 +08:00
homework_service.submit(eula_agreement_timestamp, comment)
homework_service.success!
rescue => e
mark_as_failure(e)
end
def on_permanent_failure(error)
mark_as_failure(error)
end
private
def mark_as_failure(error)
homework_service.failed!(error)
end
end
class << self
def create_clone_url_executor(url, duplicate_handling, check_quota, opts)
CloneUrlExecutor.new(url, duplicate_handling, check_quota, opts)
end
Fix comments for external tool file submissions Comments when submitting a file upload via an external tool appear to have been broken in https://github.com/instructure/canvas-lms/commit/8cdf400ba720623d8d2c This commit changes the UI to again send the comment to the server, and changes the server-side code to process the comment. The server side code has two possible data paths: * With InstFS: include the comment in the JWT we send (in capture_params) to InstFS. When InstFS is done it hits FilesController#api_capture. Now it include comment -- so we now take the comment and pass it into SubmitHomeworkService which submits it. * Without InstFS: pass the comment in when making the asynchronous job in SubmitHomeworkService.submit_job() in this case, though. Note: File uploads using an external tool appear to not work at all (?) using Assignments 2. This fix is for "classic" Assignments. Also, I can get file uploads using an external tool for group assignments to work at all, locally or production. It was supposedly working as of b55cf587. Someone else should check and we can create another ticket for that apparently separate issue. I did test that the "comment" is now getting through to the call to SubmitHomeworkService. flag=none closes PLAT-4390 Test plan: - If running locally, disable Assignments 2 by editing config/feature_flags/meeseeks_release_flags.yml and commenting out the hardcoded "environments: development: state: on" config under "assignments_2_student" - You may need to run `node_modules/bin/.webpack` or `rails canvas:compile_assets` to compile the coffeescript. - Install an LTI tool such as Box or Google Drive which allows file upload. - Make an assignment that accepts file upload - As a student, submit an assignment by choosing a file to upload with the LTI tool. After choosing a file, add a comment and submit. - Start asynchronous jobs if running Canvas locally. - Previously, the assignment would be submitted with no comment. Now, once submitted, the attachment should show up on the right side of the assignment page for the student. Under this the comment should appear. - Submit again, this time with no comment, and check that no comment is added. - InstFS team will help test this for the InstFS route. - Test external tool file submission for group assignments on production (or beta) and we can create another ticket if that isn't working. Change-Id: Ie0bbacae1e732518aae46017f72be8a72f567510 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/221096 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Product-Review: Evan Battaglia <ebattaglia@instructure.com> Reviewed-by: Marc Phillips <mphillips@instructure.com> QA-Review: Jonathan Featherstone <jfeatherstone@instructure.com>
2019-12-17 10:34:56 +08:00
def submit_job(attachment, progress, eula_agreement_timestamp, comment, executor, submit_assignment)
if progress.context.is_a?(Assignment) && submit_assignment
SubmitWorker
Fix comments for external tool file submissions Comments when submitting a file upload via an external tool appear to have been broken in https://github.com/instructure/canvas-lms/commit/8cdf400ba720623d8d2c This commit changes the UI to again send the comment to the server, and changes the server-side code to process the comment. The server side code has two possible data paths: * With InstFS: include the comment in the JWT we send (in capture_params) to InstFS. When InstFS is done it hits FilesController#api_capture. Now it include comment -- so we now take the comment and pass it into SubmitHomeworkService which submits it. * Without InstFS: pass the comment in when making the asynchronous job in SubmitHomeworkService.submit_job() in this case, though. Note: File uploads using an external tool appear to not work at all (?) using Assignments 2. This fix is for "classic" Assignments. Also, I can get file uploads using an external tool for group assignments to work at all, locally or production. It was supposedly working as of b55cf587. Someone else should check and we can create another ticket for that apparently separate issue. I did test that the "comment" is now getting through to the call to SubmitHomeworkService. flag=none closes PLAT-4390 Test plan: - If running locally, disable Assignments 2 by editing config/feature_flags/meeseeks_release_flags.yml and commenting out the hardcoded "environments: development: state: on" config under "assignments_2_student" - You may need to run `node_modules/bin/.webpack` or `rails canvas:compile_assets` to compile the coffeescript. - Install an LTI tool such as Box or Google Drive which allows file upload. - Make an assignment that accepts file upload - As a student, submit an assignment by choosing a file to upload with the LTI tool. After choosing a file, add a comment and submit. - Start asynchronous jobs if running Canvas locally. - Previously, the assignment would be submitted with no comment. Now, once submitted, the attachment should show up on the right side of the assignment page for the student. Under this the comment should appear. - Submit again, this time with no comment, and check that no comment is added. - InstFS team will help test this for the InstFS route. - Test external tool file submission for group assignments on production (or beta) and we can create another ticket if that isn't working. Change-Id: Ie0bbacae1e732518aae46017f72be8a72f567510 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/221096 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Product-Review: Evan Battaglia <ebattaglia@instructure.com> Reviewed-by: Marc Phillips <mphillips@instructure.com> QA-Review: Jonathan Featherstone <jfeatherstone@instructure.com>
2019-12-17 10:34:56 +08:00
.new(attachment.id, progress.id, eula_agreement_timestamp, comment, executor)
.tap { |worker| enqueue_attachment_job(worker) }
else
CopyWorker
Fix comments for external tool file submissions Comments when submitting a file upload via an external tool appear to have been broken in https://github.com/instructure/canvas-lms/commit/8cdf400ba720623d8d2c This commit changes the UI to again send the comment to the server, and changes the server-side code to process the comment. The server side code has two possible data paths: * With InstFS: include the comment in the JWT we send (in capture_params) to InstFS. When InstFS is done it hits FilesController#api_capture. Now it include comment -- so we now take the comment and pass it into SubmitHomeworkService which submits it. * Without InstFS: pass the comment in when making the asynchronous job in SubmitHomeworkService.submit_job() in this case, though. Note: File uploads using an external tool appear to not work at all (?) using Assignments 2. This fix is for "classic" Assignments. Also, I can get file uploads using an external tool for group assignments to work at all, locally or production. It was supposedly working as of b55cf587. Someone else should check and we can create another ticket for that apparently separate issue. I did test that the "comment" is now getting through to the call to SubmitHomeworkService. flag=none closes PLAT-4390 Test plan: - If running locally, disable Assignments 2 by editing config/feature_flags/meeseeks_release_flags.yml and commenting out the hardcoded "environments: development: state: on" config under "assignments_2_student" - You may need to run `node_modules/bin/.webpack` or `rails canvas:compile_assets` to compile the coffeescript. - Install an LTI tool such as Box or Google Drive which allows file upload. - Make an assignment that accepts file upload - As a student, submit an assignment by choosing a file to upload with the LTI tool. After choosing a file, add a comment and submit. - Start asynchronous jobs if running Canvas locally. - Previously, the assignment would be submitted with no comment. Now, once submitted, the attachment should show up on the right side of the assignment page for the student. Under this the comment should appear. - Submit again, this time with no comment, and check that no comment is added. - InstFS team will help test this for the InstFS route. - Test external tool file submission for group assignments on production (or beta) and we can create another ticket if that isn't working. Change-Id: Ie0bbacae1e732518aae46017f72be8a72f567510 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/221096 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Product-Review: Evan Battaglia <ebattaglia@instructure.com> Reviewed-by: Marc Phillips <mphillips@instructure.com> QA-Review: Jonathan Featherstone <jfeatherstone@instructure.com>
2019-12-17 10:34:56 +08:00
.new(attachment.id, progress.id, executor)
.tap { |worker| enqueue_attachment_job(worker) }
end
end
def enqueue_attachment_job(worker)
Delayed::Job.enqueue(
worker,
priority: Delayed::HIGH_PRIORITY,
n_strand: Attachment.clone_url_strand(worker.clone_url_executor.url)
)
end
end
def initialize(attachment, progress)
@attachment = attachment
@progress = progress
end
Fix comments for external tool file submissions Comments when submitting a file upload via an external tool appear to have been broken in https://github.com/instructure/canvas-lms/commit/8cdf400ba720623d8d2c This commit changes the UI to again send the comment to the server, and changes the server-side code to process the comment. The server side code has two possible data paths: * With InstFS: include the comment in the JWT we send (in capture_params) to InstFS. When InstFS is done it hits FilesController#api_capture. Now it include comment -- so we now take the comment and pass it into SubmitHomeworkService which submits it. * Without InstFS: pass the comment in when making the asynchronous job in SubmitHomeworkService.submit_job() in this case, though. Note: File uploads using an external tool appear to not work at all (?) using Assignments 2. This fix is for "classic" Assignments. Also, I can get file uploads using an external tool for group assignments to work at all, locally or production. It was supposedly working as of b55cf587. Someone else should check and we can create another ticket for that apparently separate issue. I did test that the "comment" is now getting through to the call to SubmitHomeworkService. flag=none closes PLAT-4390 Test plan: - If running locally, disable Assignments 2 by editing config/feature_flags/meeseeks_release_flags.yml and commenting out the hardcoded "environments: development: state: on" config under "assignments_2_student" - You may need to run `node_modules/bin/.webpack` or `rails canvas:compile_assets` to compile the coffeescript. - Install an LTI tool such as Box or Google Drive which allows file upload. - Make an assignment that accepts file upload - As a student, submit an assignment by choosing a file to upload with the LTI tool. After choosing a file, add a comment and submit. - Start asynchronous jobs if running Canvas locally. - Previously, the assignment would be submitted with no comment. Now, once submitted, the attachment should show up on the right side of the assignment page for the student. Under this the comment should appear. - Submit again, this time with no comment, and check that no comment is added. - InstFS team will help test this for the InstFS route. - Test external tool file submission for group assignments on production (or beta) and we can create another ticket if that isn't working. Change-Id: Ie0bbacae1e732518aae46017f72be8a72f567510 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/221096 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Product-Review: Evan Battaglia <ebattaglia@instructure.com> Reviewed-by: Marc Phillips <mphillips@instructure.com> QA-Review: Jonathan Featherstone <jfeatherstone@instructure.com>
2019-12-17 10:34:56 +08:00
def submit(eula_agreement_timestamp, comment)
start!
if @attachment
opts = {
submission_type: "online_upload",
submitted_at: @progress.created_at,
attachments: [@attachment],
eula_agreement_timestamp:,
comment:
}
@progress.context.submit_homework(@progress.user, opts)
end
end
def start!
progress_start!(@progress)
AttachmentUploadStatus.pending!(@attachment)
end
def success!
progress_success!(@progress, @attachment)
AttachmentUploadStatus.success!(@attachment)
end
def failed!(error)
progress_failed!(@progress, error)
AttachmentUploadStatus.failed!(@attachment, error)
failure_email if @attachment
end
def failure_email
display_name = @attachment.display_name
assignment_name = @progress.context.name
body = "Your file, #{display_name}, failed to upload to your " \
"Canvas assignment, #{assignment_name}. Please re-submit to " \
"the assignment or contact your instructor if you are no " \
"longer able to do so."
message = OpenStruct.new(
from_name: "notifications@instructure.com",
subject: "Submission upload failed: #{assignment_name}",
to: @progress.user.email,
body:
)
queue_email(message)
end
private
def progress_start!(progress)
unless progress.running?
progress.start
progress.save!
end
end
def progress_success!(progress, attachment)
progress.reload
progress.set_results("id" => attachment.id) if attachment
progress.complete!
end
def progress_failed!(progress, message)
progress.reload
progress.message = message
progress.save!
progress.fail
end
def queue_email(message)
Delayed::Job.enqueue(EmailWorker.new(message))
end
end
end