- Install TinCanJS dependency using
npm install tincanjs
- Configure
to
andfrom
LRSs - Adjust statement "linting" (or empty completely)
- Execute with
node toFrom.js
-
-
Save brianjmiller/ef15ce14dd726ae2f558 to your computer and use it in GitHub Desktop.
Tin Can Statement Pipe Utility
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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