|
| 1 | +# |
| 2 | +# Copyright (C) 2012 Instructure, Inc. |
| 3 | +# |
| 4 | +# This file is part of Canvas. |
| 5 | +# |
| 6 | +# Canvas is free software: you can redistribute it and/or modify it under |
| 7 | +# the terms of the GNU Affero General Public License as published by the Free |
| 8 | +# Software Foundation, version 3 of the License. |
| 9 | +# |
| 10 | +# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY |
| 11 | +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR |
| 12 | +# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
| 13 | +# details. |
| 14 | +# |
| 15 | +# You should have received a copy of the GNU Affero General Public License along |
| 16 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | +# |
| 18 | + |
| 19 | +class OutcomesImportApiController < ApplicationController |
| 20 | + include Api::V1::Outcome |
| 21 | + |
| 22 | + before_filter :require_user, :require_account_context, |
| 23 | + :can_manage_global_outcomes, :has_api_config |
| 24 | + |
| 25 | + def available |
| 26 | + render json: list_of_available_guids |
| 27 | + end |
| 28 | + |
| 29 | + def create |
| 30 | + return render json: { error: "must specify a guid to import" } unless params[:guid] |
| 31 | + return unless valid_guid(params[:guid]) |
| 32 | + |
| 33 | + begin |
| 34 | + err_msg = "Import failed to queue" |
| 35 | + migration = AcademicBenchmark.import(Array(params[:guid])).first |
| 36 | + raise RuntimeError.new(err_msg) unless migration |
| 37 | + render json: { migration_id: migration.id, guid: params[:guid] } |
| 38 | + rescue StandardError => e |
| 39 | + render json: { error: "#{err_msg}: #{e.message}" } |
| 40 | + end |
| 41 | + end |
| 42 | + |
| 43 | + protected |
| 44 | + |
| 45 | + def can_manage_global_outcomes |
| 46 | + authorized_action(Account.site_admin, @current_user, :manage_global_outcomes) |
| 47 | + end |
| 48 | + |
| 49 | + def has_api_config |
| 50 | + err = "The AcademicBenchmark API is not configured" |
| 51 | + if !AcademicBenchmark.config |
| 52 | + render json: { error: "#{err} (needs api_key and api_url)" } |
| 53 | + return false |
| 54 | + elsif !AcademicBenchmark.config["api_key"] |
| 55 | + render json: { error: "#{err} (needs api_key)" } |
| 56 | + return false |
| 57 | + elsif !AcademicBenchmark.config["api_url"] |
| 58 | + render json: { error: "#{err} (needs api_url)" } |
| 59 | + return false |
| 60 | + end |
| 61 | + true |
| 62 | + end |
| 63 | + |
| 64 | + ## |
| 65 | + # valid guids can only contain hex digits (letters all upper case), |
| 66 | + # and must be separated between a '-' [8-4-4-4-12] |
| 67 | + # |
| 68 | + # example: A833C528-901A-11DF-A622-0C319DFF4B22 |
| 69 | + ## |
| 70 | + def valid_guid(guid) |
| 71 | + unless guid =~ /[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}/ |
| 72 | + render json: { error: "GUID is invalid" } |
| 73 | + return false |
| 74 | + end |
| 75 | + true |
| 76 | + end |
| 77 | + |
| 78 | + ## |
| 79 | + # Extract the national standards from the list of authorities |
| 80 | + # National Standards are also known as Common Core and NGSS |
| 81 | + ## |
| 82 | + def nat_stds_guid(authorities) |
| 83 | + authorities.find{|a| a["title"] == "National Standards"}["guid"] |
| 84 | + end |
| 85 | + |
| 86 | + def api_connection |
| 87 | + # The api credentials for accessing the Academic Benchmarks API |
| 88 | + # are stored in the database. This retrieves them |
| 89 | + config = AcademicBenchmark.config |
| 90 | + |
| 91 | + # create a new api connection. Note that this does not actually |
| 92 | + # make a request to the API |
| 93 | + AcademicBenchmark::Api.new(config["api_key"], base_url: config["api_url"]) |
| 94 | + end |
| 95 | + |
| 96 | + ## |
| 97 | + # get a list of all of the available authorities, |
| 98 | + # and sort them alphabetically by title. |
| 99 | + # |
| 100 | + # Academic Benchmarks authorities are generally State Standards, |
| 101 | + # although "National Statndards" is an authority which must be |
| 102 | + # browsed in order to retrieve specifics like NGSS and Common Core |
| 103 | + ## |
| 104 | + def retrieve_authorities(api) |
| 105 | + authorities = api.list_available_authorities.select { |a| a.key?("title") } |
| 106 | + authorities.sort{ |a, b| a["title"] <=> b["title"] } |
| 107 | + end |
| 108 | + |
| 109 | + def extract_common_core_and_ngss(api, nat_stds_guid) |
| 110 | + api.browse_guid(nat_stds_guid).first["itm"].first["itm"] |
| 111 | + end |
| 112 | + |
| 113 | + ## |
| 114 | + # Get a list of all of the available guids that users can import. |
| 115 | + # These can be passed to the `create` action |
| 116 | + ## |
| 117 | + def list_of_available_guids |
| 118 | + api = api_connection |
| 119 | + auth_list = retrieve_authorities(api) |
| 120 | + |
| 121 | + # prepend the common core and next gen science standards to the list |
| 122 | + auth_list.unshift(extract_common_core_and_ngss(api, nat_stds_guid(auth_list))) |
| 123 | + |
| 124 | + # append the UK standards to the end of the list and flatten it down |
| 125 | + auth_list.push(uk_guid(api)).flatten |
| 126 | + end |
| 127 | + |
| 128 | + # The UK standards are now available to us as well, |
| 129 | + def uk_guid(api) |
| 130 | + api.browse.find{ |a| a["title"] == "United Kingdom" } |
| 131 | + end |
| 132 | +end |
0 commit comments