canvas-lms/app/controllers/outcomes_import_api_control...

139 lines
4.4 KiB
Ruby

#
# Copyright (C) 2015 - 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/>.
#
class OutcomesImportApiController < ApplicationController
include Api::V1::Outcome
include Api::V1::ContentMigration
before_action :require_user, :can_manage_global_outcomes, :has_api_config
def available
render json: AcademicBenchmark.list_of_available_guids
end
def create
return render json: { error: "must specify a guid to import" } unless params[:guid]
begin
err_msg = "Invalid parameters"
options = valid_options(params)
valid_guid(params[:guid])
err_msg = "Import failed to queue"
# AcademicBenchmark.queue_migration_for_guid can raise Canvas::Migration::Error
migration = AcademicBenchmark.import(params[:guid], options)
if migration
render json: { migration_id: migration.id, guid: params[:guid] }
else
render json: { error: err_msg }
end
rescue StandardError => e
render json: { error: "#{err_msg}: #{e.message}" }
end
end
def migration_status
return render json: { error: "must specify a migration id" } unless params[:migration_id]
begin
cm = ContentMigration.find(params[:migration_id])
cm_issues = cm.migration_issues
cmj = content_migration_json(cm, @current_user, session)
cmj[:migration_issues] = migration_issues_json(cm_issues, cm, @current_user, session)
render json: cmj
rescue ActiveRecord::RecordNotFound => e
render json: { error: "no content migration matching id #{params[:migration_id]}" }
end
end
protected
def can_manage_global_outcomes
authorized_action(Account.site_admin, @current_user, :manage_global_outcomes)
end
def has_api_config
err = AcademicBenchmark.check_config
if err.nil?
true
else
render json: { error: "The AcademicBenchmark API is not configured #{err}" }
false
end
end
##
# valid guids can only contain hex digits (letters all upper case),
# and must be separated between a '-' [8-4-4-4-12]
#
# example: A833C528-901A-11DF-A622-0C319DFF4B22
##
def valid_guid(guid)
unless guid =~ /[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}/i
raise "GUID is invalid: #{guid}"
end
end
def parse_int(value)
Integer value
rescue
raise "invalid value, must be integer: #{value}"
end
def valid_options(hash)
options = {}
if hash.key? :calculation_method
options[:calculation_method] = parse_calculation_method hash[:calculation_method]
options[:calculation_int] = parse_calculation_int options[:calculation_method], hash[:calculation_int]
end
options[:mastery_points] = parse_int hash[:mastery_points] if hash.key? :mastery_points
options[:points_possible] = parse_int hash[:points_possible] if hash.key? :points_possible
unless hash[:ratings].nil?
raise "ratings expected to be an array" unless hash[:ratings].is_a?(Array)
options[:ratings] = hash[:ratings].map {|r| parse_rating(r)}
end
options
end
def parse_calculation_method(value)
unless LearningOutcome.valid_calculation_method?(value)
raise "invalid calculation_method: #{value}"
end
value
end
def parse_calculation_int(calc_method, value)
int = value.nil? ? nil : parse_int(value)
unless LearningOutcome.valid_calculation_int?(int, calc_method)
raise "invalid calculation_int: #{value}"
end
int
end
def parse_rating(rating)
if rating.nil? || !rating.is_a?(ActionController::Parameters)
raise "invalid ratings value: #{rating}"
end
if rating[:description].nil? || !rating[:description].is_a?(String)
raise "invalid description value: #{rating[:description]}"
end
{ :description => rating[:description], :points => parse_int(rating[:points]) }
end
end