-
Notifications
You must be signed in to change notification settings - Fork 2
Under the Hood
AMPS works with an enhanced Learning Registry node implementation. So far the only enhancements done to a node is:
-
Add an additional custom CouchDB map/reduce view.
-
Modify NGINX configuration to allow public read access to that view.
function(doc) {
// Only look at resource data envelopes with inline resource_data
if (doc.doc_type == "resource_data" && doc.resource_data && doc.resource_locator) {
// Use E4X to try and parse resource_data as XML. Then assume a Dublin Core Terms
// namespace to search for the <dct:conformsTo> which usually contains alignment
// to standards information. If the exists some elements anywhere in the payload,
// emit and use envelope resource_locator as means for mapping resource to standard.
try {
var nsdl = eval(doc.resource_data);
var dct = new Namespace("http://purl.org/dc/terms/");
var stds = nsdl..dct::conformsTo
for (idx in stds) {
emit([doc.resource_locator, stds[idx].toString()],null);
}
} catch (error) {
log("error:"+error);
}
}
}
This could be expanded upon to add more ways of processing the resource_data to incorporate other methods of storing alignment data within envelope records.
function(doc) {
// Only look at envelopes that are paradata.
if (doc.doc_type == "resource_data" && doc.resource_data_type == "paradata" &&
doc.resource_data && doc.resource_locator) {
try {
// determine if paradata envelope is of type LR Paradata 1.0
var res = doc.resource_data;
var action = res.verb.action;
var isparadata = false;
for (var i=0; i < doc.payload_schema.length; i++) {
if (doc.payload_schema[i] === "LR Paradata 1.0") {
try {
if (res.content) {
isparadata = true;
}
break;
} catch (e0) {}
}
}
// If this is paradata that we expect we need to link all relevant URL's found
// as keys, however ensure that no two duplicate keys are emitted to save space.
if (isparadata) {
var emitted = {};
emit([doc.resource_locator, action, res.content], null);
emitted[doc.resource_locator] = true;
try {
if (!emitted[res.verb.context.id]) {
emit([res.verb.context.id, action, res.content],null);
emitted[res.verb.context.id] = true;
}
} catch (e1) {}
try {
if (!emitted[res.object.id]) {
emit([res.object.id, action, res.content],null);
emitted[res.object.id] = true;
}
} catch (e1) {}
}
} catch (error) {
log("error:"+error);
}
}
}
This could be expanded to focus more on specific kinds of paradata, like purely only paradata regarding alignment to standards. Some paradata records have differing resource_urls from the object.id; this is usually when the resource engaged with is the same resource as the canonical resource_url but located or embedded at a different URL. Adding both URL's allows us to also crosswalk a relationship from a copy to the original resource.
For this demo, I was working with the folks at Jes & Co, hence this is currently focused on incorporating their added data. This could be easily expanded upon to use other sources without much effort.
function queryJesAndCo(id, asn) {
var baseUrl = 'http://asn.jesandco.org/api/1/taxon';
// Using Lawnchair here to be friendly to guys at Jes & Co. Anything we query from them
// we cache so we don't have to waste resources and look it up again, since their resources
// if they exist should be relatively static.
var lc = Lawnchair(function(){});
lc.get(asn, function(keyExists){
if (keyExists && keyExists.value.statementNotation != "") {
chrome_mustache("std", keyExists.value, function(html) {
if (html && html != "") {
$("div#learnreg-"+id+" div.data").append(html);
lc.get("opt_.learning-registry.standards", function(obj){
if (obj && obj.value) {
$("div#learnreg-"+id+".hidden").removeClass("hidden");
} else {
$("div#learnreg-"+id).addClass("hidden");
}
});
// console.log("cached data for: "+id+" "+html);
}
});
} else {
// Since the service we're using with Jes & Co is alpha - the data is mapped
// slightly differently - so if we find a scheme://purl.org/ASN, change it to
// scheme://asn.jesandco.org
var aurl = asn.replace("//purl.org/ASN", "//asn.jesandco.org");
console.log(aurl);
var data = {
"uri": aurl
};
// Handle the response from Jes & Co here. Essentially there are a few
// shortcuts taken here, like educationLevel - the value returned should
// technically be resolved via RDF - which is possible, but for now, since
// most will recognize the numerical educationLevel out of the URI, we cheat
// and just take that.
var callback = function(response, status, jqXHR) {
var jesurl = aurl;
var info = {
"identifier": asn,
"category": "",
"educationLevel": [],
"standard":[],
"statementNotation":[]
}
try {
var statement = response[jesurl];
// Try finding the umbrella category that the standard belongs to.
// Could be Common Core, but could be any other standard as well.
try {
var isPartOf = statement["http://purl.org/dc/terms/isPartOf"]
for (var i=0; i<isPartOf.length; i++) {
var asn_id = isPartOf[i].value.replace(/^.*\//, "");
if (asn_id.match(/^D[A-Z0-9]+$/)) {
var doc = response[isPartOf[i].value];
try {
info["category"] = doc["http://purl.org/dc/elements/1.1/title"][0].value;
} catch (e1) {
try {
info["category"] = doc["http://purl.org/dc/terms/description"][0].value;
} catch (e2) { }
}
}
}
} catch (e) { }
function value(obj) {
return obj.value;
}
function strip(url) {
try {
return url.value.replace(/^.*\//, '');
} catch (Error) {
return "";
}
}
// Try getting the actual standard info out of the response
try {
info["standard"] = statement["http://purl.org/dc/terms/description"].map(value);
} catch (e) { }
try {
info["educationLevel"] = statement["http://purl.org/dc/terms/educationLevel"].map(strip);
} catch (e) { }
try {
info["statementNotation"] = statement["http://purl.org/ASN/schema/core/statementNotation"].map(value);
} catch (e) { }
// info.category = info.category.map(strip).join(", ");
info.standard = info.standard.join(", ");
info.educationLevel = info.educationLevel.join(", ");
info.statementNotation = info.statementNotation.join(", ");
} catch (Error) {
console.log(Error);
}
// Save it using Lawnchair, keyed by the ASN URL, so if we come across it again
// on another resource, we don't have pester Jes & Co's service again.
Lawnchair(function() {
this.save({"key":asn, "value":info});
});
// We're going to get a bit snobbish. Not all the alignment information has
// statement notations. Since this is currently important to us, we're going to
// discard anything that's currently missing that.
if (info.statementNotation != "") {
chrome_mustache("std", info, function(html) {
if (html && html != "") {
$("div#learnreg-"+id+" div.data").append(html);
// console.log("data for: "+id+" "+html);
}
});
}
}
data["callback"] = "foo";
var params = {
"url": baseUrl,
"dataType": "json",
"data": data,
"success": callback,
"cache": false,
"jsonp": "callback"
};
chrome_ajax(params);
}
});
}
As noted this only is using Jes & Co ASNs. It's been observed that other alignment data does exist in the LR, however it doesn't use Jes & Co ASNs. One example is Florida CPALMS, whose alignement information is contained as free text within the Dublin Core Terms <dct:conformsTo> element. Sany other ones, some have added in, the FL folks, have “free text” that describe the standard.