├── AutoConfig.bat ├── AutoConfig.ps1 ├── CanvasDataAuth_Schema.cdconfig ├── CanvasDataAuth_Tables.cdconfig ├── CanvasDataDL_Schema_Latest.cdconfig ├── CanvasDataDL_Tables_Latest.cdconfig ├── CanvasDataLevel1_042417_1330.sql ├── CanvasDataStore_042417_1332.sql ├── DownloadLatestSchemaAndTables.bat ├── README.md ├── SampleConfigurationInputs.txt └── mods.bat /AutoConfig.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set /p configdir= Node.js Path: 3 | set /p APIS= Canvas Data API Secret: 4 | set /p APIK= Canvas Data API Key: 5 | set /p dldir= Download Path: 6 | set /p cdsvr= Server Name: 7 | set /p cdusr= Server User: 8 | set /p cdpw= Server USR PW: 9 | powershell -ExecutionPolicy ByPass -File "%configdir%"/AutoConfig.ps1 "%configdir%" "%APIS%" "%APIK%" "%dldir%" "%cdsvr%" "%cdusr%" "%cdpw%" 10 | pause 11 | cd "%configdir%" 12 | ren *.cdconfig *.js -------------------------------------------------------------------------------- /AutoConfig.ps1: -------------------------------------------------------------------------------- 1 | $configdir=$args[0] 2 | $APIS=$args[1] 3 | $APIK=$args[2] 4 | $dldir=$args[3] 5 | $cdsvr=$args[4] 6 | $cdusr=$args[5] 7 | $cdpw=$args[6] 8 | 9 | $configfiles = Get-ChildItem $configdir\*.cdconfig -rec 10 | foreach ($file in $configfiles) 11 | { 12 | (get-content $file) | 13 | foreach-object {$_ -replace "IRSECRETREPLACEME", $APIS} | 14 | foreach-object {$_ -replace "IRKEYREPLACEME", $APIK} | 15 | foreach-object {$_ -replace "IRCDDLDIRREPLACEME", $dldir} | 16 | foreach-object {$_ -replace "IRCDSVRREPLACEME", $cdsvr} | 17 | foreach-object {$_ -replace "IRCDSVRUSRREPLACEME", $cdusr} | 18 | foreach-object {$_ -replace "IRCDSVRUSRPWREPLACEME", $cdpw} | 19 | set-content $file 20 | } -------------------------------------------------------------------------------- /CanvasDataAuth_Schema.cdconfig: -------------------------------------------------------------------------------- 1 | //Adding necessary node modules 2 | var querystring = require('querystring'); 3 | var https = require('https'); 4 | var dateFormat = require('dateformat'); 5 | var crypto = require('crypto'); 6 | var url = require('url'); 7 | 8 | //Declaring and assembling pieces for HMAC auth 9 | var date = Date(); 10 | var timestamp = dateFormat(date, "ddd, d mmm yyyy H:MM:ss Z"); 11 | 12 | //Insert your CanvasAPI API Secret 13 | var secret = 'IRSECRETREPLACEME'; 14 | 15 | //Insert your CanvasAPI API Key 16 | var key = 'IRKEYREPLACEME'; 17 | 18 | var opts = { 19 | method: 'GET', 20 | host: 'portal.inshosteddata.com', 21 | path: 'https://portal.inshosteddata.com/api/schema/latest' 22 | }; 23 | var HMAC_ALG = 'sha256'; 24 | 25 | //Assembling Canvas Data Auth credentials 26 | var apiAuth = module.exports = { 27 | buildMessage: function(secret, timestamp, reqOpts) { 28 | var urlInfo = url.parse(reqOpts.path, true) 29 | var sortedParams = Object.keys(urlInfo.query).sort(function(a, b) { 30 | return a.localeCompare(b) 31 | }) 32 | var sortedParts = [] 33 | for (var i = 0; i < sortedParams.length; i++) { 34 | var paramName = sortedParams[i] 35 | sortedParts.push(paramName + '=' + urlInfo.query[paramName]) 36 | } 37 | var parts = [ 38 | reqOpts.method.toUpperCase(), 39 | reqOpts.host || '', 40 | reqOpts.contentType || '', 41 | reqOpts.contentMD5 || '', 42 | urlInfo.pathname, 43 | sortedParts.join('&') || '', 44 | timestamp, 45 | secret 46 | ] 47 | return parts.join('\n') 48 | }, 49 | buildHmacSig: function(secret, timestamp, reqOpts) { 50 | var message = apiAuth.buildMessage(secret, timestamp, reqOpts) 51 | var hmac = crypto.createHmac(HMAC_ALG, new Buffer(secret)) 52 | hmac.update(message) 53 | return hmac.digest('base64') 54 | } 55 | } 56 | 57 | var HMACSig = apiAuth.buildHmacSig(secret, timestamp, opts); 58 | var Auth = 'HMACAuth ' + key; 59 | 60 | 61 | //Preparing HTTP headers for Canvas Data get request 62 | var GETheaders = { 63 | 'Authorization' : Auth+':'+HMACSig, 64 | 'Date' : timestamp 65 | }; 66 | 67 | var optionsget = { 68 | headers: GETheaders, 69 | host : 'portal.inshosteddata.com', // here only the domain name 70 | // (no http/https !) 71 | port : 443, 72 | // this is the endpoint for the latest data dump 73 | path : 'https://portal.inshosteddata.com/api/schema/latest', //the rest of the url with parameters if needed 74 | method : 'GET' // do GET 75 | }; 76 | 77 | 78 | //This function (with the necessary callback) is where we return the object containing our URL(s) for table(s) 79 | var CanvasDataAPICall = function(input, cb) { 80 | 81 | getCall = function(response) { 82 | var data = []; 83 | response.setEncoding('utf8'); 84 | response.on('data', function (chunk) { 85 | data.push(chunk) 86 | }); 87 | response.on('end', function () { 88 | var result = JSON.parse(data.join('')) 89 | cb(result); 90 | }); 91 | } 92 | var req = https.request(optionsget, getCall); 93 | req.end(); 94 | 95 | } 96 | 97 | module.exports = CanvasDataAPICall; 98 | -------------------------------------------------------------------------------- /CanvasDataAuth_Tables.cdconfig: -------------------------------------------------------------------------------- 1 | //Adding necessary node modules 2 | var querystring = require('querystring'); 3 | var https = require('https'); 4 | var dateFormat = require('dateformat'); 5 | var crypto = require('crypto'); 6 | var url = require('url'); 7 | 8 | //Declaring and assembling pieces for HMAC auth 9 | var date = Date(); 10 | var timestamp = dateFormat(date, "ddd, d mmm yyyy H:MM:ss Z"); 11 | 12 | //Insert your CanvasAPI API Secret 13 | var secret = 'IRSECRETREPLACEME'; 14 | 15 | //Insert your CanvasAPI API Key 16 | var key = 'IRKEYREPLACEME'; 17 | 18 | var opts = { 19 | method: 'GET', 20 | host: 'portal.inshosteddata.com', 21 | path: 'https://portal.inshosteddata.com/api/account/self/file/latest' 22 | }; 23 | var HMAC_ALG = 'sha256'; 24 | 25 | //Assembling Canvas Data Auth credentials 26 | var apiAuth = module.exports = { 27 | buildMessage: function(secret, timestamp, reqOpts) { 28 | var urlInfo = url.parse(reqOpts.path, true) 29 | var sortedParams = Object.keys(urlInfo.query).sort(function(a, b) { 30 | return a.localeCompare(b) 31 | }) 32 | var sortedParts = [] 33 | for (var i = 0; i < sortedParams.length; i++) { 34 | var paramName = sortedParams[i] 35 | sortedParts.push(paramName + '=' + urlInfo.query[paramName]) 36 | } 37 | var parts = [ 38 | reqOpts.method.toUpperCase(), 39 | reqOpts.host || '', 40 | reqOpts.contentType || '', 41 | reqOpts.contentMD5 || '', 42 | urlInfo.pathname, 43 | sortedParts.join('&') || '', 44 | timestamp, 45 | secret 46 | ] 47 | return parts.join('\n') 48 | }, 49 | buildHmacSig: function(secret, timestamp, reqOpts) { 50 | var message = apiAuth.buildMessage(secret, timestamp, reqOpts) 51 | var hmac = crypto.createHmac(HMAC_ALG, new Buffer(secret)) 52 | hmac.update(message) 53 | return hmac.digest('base64') 54 | } 55 | } 56 | 57 | var HMACSig = apiAuth.buildHmacSig(secret, timestamp, opts); 58 | var Auth = 'HMACAuth ' + key; 59 | 60 | 61 | //Preparing HTTP headers for Canvas Data get request 62 | var GETheaders = { 63 | 'Authorization' : Auth+':'+HMACSig, 64 | 'Date' : timestamp 65 | }; 66 | 67 | var optionsget = { 68 | headers: GETheaders, 69 | host : 'portal.inshosteddata.com', // here only the domain name 70 | // (no http/https !) 71 | port : 443, 72 | // this is the endpoint for the latest data dump 73 | path : 'https://portal.inshosteddata.com/api/account/self/file/latest', //the rest of the url with parameters if needed 74 | method : 'GET' // do GET 75 | }; 76 | 77 | 78 | //This function (with the necessary callback) is where we return the object containing our URL(s) for table(s) 79 | var CanvasDataAPICall = function(input, cb) { 80 | 81 | getCall = function(response) { 82 | var data = []; 83 | response.setEncoding('utf8'); 84 | response.on('data', function (chunk) { 85 | data.push(chunk) 86 | }); 87 | response.on('end', function () { 88 | var result = JSON.parse(data.join('')) 89 | cb(result); 90 | }); 91 | } 92 | var req = https.request(optionsget, getCall); 93 | req.end(); 94 | 95 | } 96 | 97 | module.exports = CanvasDataAPICall; 98 | -------------------------------------------------------------------------------- /CanvasDataDL_Schema_Latest.cdconfig: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var https = require('https'); 3 | //var json2csv = require('json2csv'); 4 | var CanvasDataAPICall = require('./CanvasDataAuth_Schema.js'); 5 | var sql = require("seriate"); 6 | var datetime = new Date(); 7 | var datetimeSimple = (datetime.getMonth() + 1) + '-' + datetime.getDate() + '-' + datetime.getFullYear(); 8 | 9 | var request = require('request'); 10 | 11 | var schKey=[]; 12 | var schVal=[]; 13 | 14 | var download = function(uri, filename, callback){ 15 | request.head(uri, function(err, res, body){ 16 | 17 | var r = request(uri).pipe(fs.createWriteStream(filename)); 18 | r.on('close', callback); 19 | 20 | }); 21 | }; 22 | 23 | JSON.flatten = function(data) { 24 | var flattenResult = {}; 25 | function recurse (cur, prop) { 26 | if (Object(cur) !== cur) { 27 | flattenResult[prop] = cur; 28 | } else if (Array.isArray(cur)) { 29 | for(var i=0, l=cur.length; i Open > File. In the dialog box, find/highlight the CanvasDataStore_mmddyy_hhmm.sql ... file in the CDV scripts. The script should open in a New Query window. Click Execute (F5). 114 | * (N.B. The “Warning! The maximum key length is 900 bytes. …” error message is expected. It doesn’t affect the installation and we’re working on eliminating it.) 115 | * Open the CanvasDataStore database to confirm that tables have installed. 116 | 117 | ### Step 9 – Run the datafile download and database loading 118 | 119 | * Open SQL Server Management Studio 120 | * In the ObjectExplorer open the CanvasDataStore database and go to CanvasDataStore/Programmability/Stored Procedures 121 | * Right-click on dbo.CanvasData_General_DownloadSchemaAndTables and click “Execute Stored Procedure…”. This process accesses Canvas API endpoints to download the current Canvas Data table schema. It also downloads all the actual Canvas Data data, which is packaged in comma-delimited text files. This can take up to an hour or more. 122 | * Right-click on dbo.CanvasData_General_TableBuild and click “Execute Stored Procedure…”. This process creates tables to hold the data according to the latest schema. Then it loads all the datafiles into import tables. Finally it transfers all the data to production tables and builds indexes on them to aid searching. This process can take several hours depending on the amount of data in your instance. 123 | 124 | ### Step 10 - Set up SQL Server Agent Jobs 125 | 126 | SQL Server Agent is a scheduler system that can run processes automatically. 127 | 128 | * Open SQL Server Agent 129 | * Right-click on Jobs and select New Job 130 | * Enter the following info: 131 | * General/Name 132 | * Steps - click on New: 133 | * Step Name 134 | * Database - change to CanvasDataStore 135 | * In Command window - "EXEC dbo.CanvasData_General_DownloadSchemaAndTables" 136 | * Click OK 137 | * Schedules - click on New: 138 | * Name 139 | * Frequency - "Daily" 140 | * Daily frequency - 1:00 AM 141 | * Click OK 142 | 143 | Repeat this process to create a job for dbo.CanvasData_General_TableBuild at 2:00 AM 144 | 145 | 146 | ### Step 11 – Create CanvasDataLevel1 database in SQL Server 147 | 148 | CanvasDataLevel1 is a SQL Server database that contains views to query Canvas Data. These views all draw on data in the CanvasDataStore database. (CanvasDataLevel1 doesn't store any data of its own.) 149 | 150 | You need to install CanvasDataLevel1 after you've successfully downloaded your Canvas Data into CanvasDataStore. Otherwise the install will fail. 151 | 152 | Open SQL Server Management Studio 153 | * In the ObjectExplorer click on Connect and select your database engine that you installed 154 | * In the database engine, right-click on Databases and select New Database 155 | * In Database Name enter “CanvasDataLevel1” and click OK (Leave all other settings as default. You must use this name because it is hard-coded into all the scripts.) 156 | * Right-click on Databases and click Refresh to make sure CanvasDataLevel has appeared 157 | * In the top menu click on File > Open > File. In the dialog box, find/highlight the CanvasDataLevel1_mmddyy_hhmm.sql ... file in the CDV scripts. The script should open in a New Query window. Click Execute (F5). 158 | * Open the CanvasDataLevel1 database to confirm that the views have installed. 159 | 160 | ### Contributing 161 | 162 | 163 | ### Credits 164 | 165 | [Bill Jones](https://www.linkedin.com/in/wirjones525/) 166 | 167 | [Andrew Anders](https://www.linkedin.com/in/andrew-a-54108) 168 | 169 | ### Licensing 170 | -------------------------------------------------------------------------------- /SampleConfigurationInputs.txt: -------------------------------------------------------------------------------- 1 | Node.js Path: 2 | (The Node.js installer will ask you where you want to install the files. Accept the default, which is C:\Program Files\nodejs. You will need to copy a number of files into this folder in a later step.) 3 | 4 | Canvas Data API Secret: 5 | (These can be found in your Canvas Data Portal page. You find this in your main Canvas account left-hand menu. Copy the credentials string right off the webpage.) 6 | 7 | Canvas Data API Key: 8 | (These can be found in your Canvas Data Portal page. You find this in your main Canvas account left-hand menu. Copy the credentials string right off the webpage.) 9 | 10 | Downloaded Files path: 11 | (For example: C:/CanvasDataDownload. Be mindful of the forward slash here) 12 | 13 | Server Name: MyCampus 14 | (This is the name of your SQL Server instance. In the SQL Server Management Studio ObjectExplorer, right-click on the main server and select Properties. The server name is the first variable shown.) 15 | 16 | Server User: Foo 17 | 18 | Server USR PW: Bar 19 | (During SQL Server installation you will create a password for a default server account, usually called "sa". You can use this account/password, or you can create a different one to use with CanvasDataViewer in the Security/Logins folder.) 20 | -------------------------------------------------------------------------------- /mods.bat: -------------------------------------------------------------------------------- 1 | cd "C:\Program Files\nodejs" 2 | npm install filesystem && npm install https && npm install async && npm install seriate && npm install request && npm install querystring && npm install dateformat && npm install crypto && npm install url 3 | pause --------------------------------------------------------------------------------