SankeySheets/scripts/ServerWatcher.js
2016-10-14 12:10:59 +01:00

136 lines
3.8 KiB
JavaScript

/**
* used to expose memebers of a namespace
* @param {string} namespace name
* @param {method} method name
*/
function exposeRun (namespace, method , argArray ) {
var func = (namespace ? this[namespace][method] : this[method])
if (argArray && argArray.length) {
return func.apply(this,argArray);
}
else {
return func();
}
}
/**
* simulate binding with apps script
* various changes server side can be watched for server side
* and resolved client side
* @constructor SeverBinder
*/
var ServerWatcher = (function (ns) {
/**
* polled every now and again to report back on changes
* @param {object} watch instructions on what to check
* @retun {object} updated status
*/
ns.poll = function (watch) {
// get the active stuff
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getActiveSheet();
var aRange = ss.getActiveRange();
// first select the sheet .. given or active
var s = watch.domain.sheet ? ss.getSheetByName(watch.domain.sheet) : sh;
// if the scope is "sheet", then it will always be the datarange used
if (watch.domain.scope === "Sheet") {
var r = s.getDataRange();
}
// the scope is range - if there's a given range use it - otherwise use the datarange on the selected sheet
else if (watch.domain.scope === "Range") {
var r = (watch.domain.range ? sh.getRange(watch.domain.range) : sh).getDataRange();
}
// regardless of any other settings always use the active range
else if (watch.domain.scope === "Active") {
var r = aRange;
}
// otherwise its a mess up
else {
throw 'scope ' + watch.domain.scope + ' is not valid scope - should be Sheet, Range or Active';
}
// start building the result
var pack = {
checksum:watch.checksum,
changed:{},
dataSource:{
id:ss.getId(),
sheet:sh.getName(),
range:r.getA1Notation(),
dataRange:sh.getDataRange().getA1Notation()
}
};
// get data if requested
if (watch.rules.data) {
// see if filters are being respected
if (watch.domain.applyFilters && watch.domain.property === "Values") {
var v = new SheetsMore()
.setAccessToken(ScriptApp.getOAuthToken())
.setId(SpreadsheetApp.getActiveSpreadsheet().getId())
.enableFilterViews(false)
.applyFiltersToData()
.getValues(r);
// but we just want the filteredvalues
var values = v.filteredValues;
}
else {
var values = r['get'+watch.domain.property]();
}
var cs = Utils.keyDigest(values);
pack.changed.data = cs !== pack.checksum.data;
if (pack.changed.data) {
pack.data = values;
pack.checksum.data = cs;
}
}
// provide sheets if requested
if (watch.rules.sheets) {
var sheets = ss.getSheets().map(function(d) { return d.getName(); });
var cs = Utils.keyDigest(sheets);
pack.changed.sheets = cs !== pack.checksum.sheets;
if (pack.changed.sheets) {
pack.sheets = sheets;
pack.checksum.sheets = cs;
}
}
// provide active if requested
if (watch.rules.active) {
var a = {
id:ss.getId(),
sheet:sh.getName(),
range:aRange.getA1Notation(),
dataRange:sh.getDataRange().getA1Notation(),
dimensions: {
numRows : aRange.getNumRows(),
numColumns : aRange.getNumColumns(),
rowOffset : aRange.getRowIndex(),
colOffset : aRange.getColumn()
}
}
var cs = Utils.keyDigest (a);
pack.changed.active = cs !== pack.checksum.active;
if (pack.changed.active) {
pack.active = a;
pack.checksum.active = cs;
}
}
return pack;
};
return ns;
})(ServerWatcher || {});