Skip to content

Instantly share code, notes, and snippets.

@brianjmiller

brianjmiller/README.md Secret

Last active Sep 14, 2020
Embed
What would you like to do?
Tin Can Statement Pipe Utility
  • Install TinCanJS dependency using npm install tincanjs
  • Configure to and from LRSs
  • Adjust statement "linting" (or empty completely)
  • Execute with node toFrom.js
var TinCan = require("tincanjs"),
source,
stream;
//TinCan.enableDebug();
source = new TinCan.LRS (
{
endpoint: "https://cloud.scorm.com/tc/public/",
username: "test",
password: "pass"
}
);
Stream = function () {
console.log("Stream.constructor");
};
Stream.prototype = {
fetchStatements: function (moreUrl) {
console.log("Stream.fetchStatements");
var self = this;
if (moreUrl !== null) {
source.moreStatements(
{
url: moreUrl,
callback: this.processStatementsResult.bind(this)
}
);
return;
}
source.queryStatements(
{
params: {
/*activity: {
id: ""
},
related_activities: true*/
},
callback: this.processStatementsResult.bind(this)
}
);
},
processStatementsResult: function (err, sr) {
console.log("Stream.processStatementsResult");
var i,
batch;
if (err !== null) {
console.log("Stream.processStatementsResult query/more failed: ", err, sr);
return;
}
if (sr.statements.length > 0) {
console.log("Stream.processStatementsResult - printing batch of statements: ", sr.statements.length);
this.printStatements(sr.statements);
}
console.log("Stream.processStatementsResult - more link: ", sr.more);
if (sr.more !== null) {
this.fetchStatements(sr.more);
}
},
printStatements: function (sts) {
console.log("Stream.printStatements");
var i;
for (i = 0; i < sts.length; i += 1) {
console.log(i, sts[i].id, sts[i].timestamp, sts[i].actor.mbox, sts[i].verb.id, sts[i].target.id);
}
}
};
stream = new Stream ();
stream.fetchStatements(null);
var TinCan = require("tincanjs"),
StatementPipe,
to,
from,
pipe,
BROWSER_EXT = "http://id.tincanapi.com/extension/browser-info",
totalSent = 0,
batch = 0;
//TinCan.enableDebug();
to = new TinCan.LRS (
{
endpoint: "https://cloud.scorm.com/tc/---/sandbox/",
username: "",
password: "",
allowFail: false
}
);
from = new TinCan.LRS (
{
endpoint: "https://cloud.scorm.com/tc/---/sandbox/",
username: "",
password: "",
version: "0.95",
allowFail: false
}
);
StatementPipe = function () {
//console.log("StatementPipe.constructor");
};
StatementPipe.prototype = {
fetchStatements: function (moreUrl) {
//console.log("StatementPipe.fetchStatements");
if (moreUrl !== null) {
from.moreStatements(
{
url: moreUrl,
callback: this.processStatementsResult.bind(this)
}
);
return;
}
from.queryStatements(
{
params: {
ascending: true
},
callback: this.processStatementsResult.bind(this)
}
);
},
lintStatements: function (sts) {
//console.log("StatementPipe.lintStatements", sts.length);
var i,
result = [];
for (i = 0; i < sts.length; i += 1) {
if (sts[i].context === null) {
console.log("StatementPipe.lintStatements - skipping (no context): ", sts[i].id);
continue;
}
if (sts[i].context.extensions === null) {
console.log("StatementPipe.lintStatements - skipping (no extensions): ", sts[i].id);
continue;
}
if (typeof sts[i].context.extensions.browser !== "undefined") {
sts[i].context.extensions[BROWSER_EXT] = sts[i].context.extensions.browser;
delete sts[i].context.extensions.browser;
}
result.push(sts[i]);
sts[i].authority = null;
}
return result;
},
processStatementsResult: function (err, sr) {
//console.log("StatementPipe.processStatementsResult");
var sts,
myBatch;
batch += 1;
myBatch = batch;
if (err !== null) {
console.log(myBatch + ": StatementPipe.processStatementsResult query/more failed: ", err, sr);
return;
}
if (sr.statements.length > 0) {
sts = this.lintStatements(sr.statements);
console.log(myBatch + ": StatementPipe.processStatementsResult - sending statements: ", sts.length);
if (sts.length > 0) {
totalSent += sts.length;
to.saveStatements(
sts,
{
callback: function (err, result) {
this.processSaveStatements(err, result, myBatch);
}.bind(this)
}
);
}
}
if (sr.more !== null) {
this.fetchStatements(sr.more);
}
},
processSaveStatements: function (err, result, batch) {
//console.log(batch + ": StatementPipe.processSaveStatements");
if (err !== null) {
console.log(batch + ": StatementPipe.processSaveStatements - failed to store statements: ", err, result.responseText);
console.log(batch + ": StatementPipe.processSaveStatements - failed to store statements, aborting ");
process.exit(1);
}
console.log(batch + ": StatementPipe.processSaveStatements statements saved");
}
};
pipe = new StatementPipe ();
pipe.fetchStatements(null);
@arvind02

This comment has been minimized.

Copy link

@arvind02 arvind02 commented Sep 2, 2020

Hello Brian
This gist is awesome and helped me a lot :)
Very small thing I just wanted to point out here. In list.js line no 64, the value of sr.more is not always null. Its sometimes "" or blank.
So might wants to update the condition.

Cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.