mirror of
https://github.com/bellingcat/datasheet-server.git
synced 2026-06-08 03:18:33 +03:00
add support for single blueprinter in config
This commit is contained in:
@@ -88,7 +88,7 @@ Each Google Sheet being used as a as source requires a corresponding object in `
|
||||
| ------ | ----------- | ---- |
|
||||
| name | Used to refer to data served from this source | string |
|
||||
| id | The ID of the sheet in Google. (You can find it in the address bar when the Sheet is open in a browser. It is the string that follows 'spreadsheets/d/'). | string |
|
||||
| tabs | An object that maps each tab in the source to one or more Blueprinters. All of the Blueprinters in the [blueprinters folder](/lib/blueprinters) are available through a single import as at the top of [example.config.js](/src/example.config.js). <br> To correctly associate a Blueprinter, the object key needs to be _the tab name with all lowercase letters, and spaces replaced by a '-'_. For example, if the tab name in Google Sheets is 'Info About SHEEP', the object key should be 'info-about-sheep'. <br> More than one Blueprinter can be used per tab, if more than one representation is required for a single tab; in that case simply add a second Blueprinter in the array corresponding to the tab. <br> The value should be the Blueprinter function that you want to use for the data in that tab. See the example of a configuration object below. <br>TODO: no Blueprinter is used by default. | object |
|
||||
| tabs | An object that maps each tab in the source to one or more Blueprinters. All of the Blueprinters in the [blueprinters folder](/lib/blueprinters) are available through a single import as at the top of [example.config.js](/src/example.config.js). <br> To correctly associate a Blueprinter, the object key needs to be _the tab name with all lowercase letters, and spaces replaced by a '-'_. For example, if the tab name in Google Sheets is 'Info About SHEEP', the object key should be 'info-about-sheep'. <br> The value should be the Blueprinter function that you want to use for the data in that tab. If you require more than one endpoint for a single tab, you can support multiple blueprinters by making the item an array. See the example of a configuration object below. <br>TODO: no Blueprinter is used by default. | object |
|
||||
|
||||
###### Example Configuration Object
|
||||
```js
|
||||
@@ -104,8 +104,8 @@ export default {
|
||||
name: 'example',
|
||||
id: '1s-vfBR8Uy-B-TLO_C5Ozw4z-L0E3hdP8ohMV761ouRI',
|
||||
tabs: {
|
||||
'objects': [BP.byRow],
|
||||
'objectsB': [BP.byRow, BP.byID],
|
||||
'objects': BP.byRow,
|
||||
'fruit': [BP.byRow, BP.byID],
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
// FetcherTwo class interfaces with Google Sheet, and saves to a specified db
|
||||
import {google} from "googleapis";
|
||||
import {fmtSourceTitle, fmtBlueprinterTitles, deriveFilename, bp} from "./util";
|
||||
import {
|
||||
fmtSourceTitle,
|
||||
fmtBlueprinterTitles,
|
||||
deriveFilename,
|
||||
bp,
|
||||
isFunction
|
||||
} from "./util";
|
||||
import {byRow, byId} from "./blueprinters";
|
||||
import R from "ramda";
|
||||
|
||||
@@ -39,6 +45,23 @@ class Fetcher {
|
||||
*/
|
||||
this.sheets = google.sheets("v4");
|
||||
this.auth = null;
|
||||
|
||||
/**
|
||||
* saveBp is a curried function that takes in a title and
|
||||
* a blueprinter. NB: it sits here in the constructor as
|
||||
* I am not sure how to curry a class method with Ramda.
|
||||
*/
|
||||
this._saveBp = R.curry((tab, title, data, blueprinter) => {
|
||||
const saturatedBp = blueprinter(
|
||||
tab,
|
||||
this.sourceName,
|
||||
this.sourceId,
|
||||
data
|
||||
);
|
||||
const blueprint = bp(saturatedBp); // TODO: come up with better semantics.
|
||||
this.blueprints[title] = blueprint;
|
||||
return this.db.save(saturatedBp);
|
||||
});
|
||||
}
|
||||
|
||||
/** returns a Promise that resolves if access is granted to the account, and rejects otherwise. */
|
||||
@@ -96,19 +119,13 @@ class Fetcher {
|
||||
save(tab, data) {
|
||||
const title = fmtSourceTitle(tab);
|
||||
if (Object.keys(this.blueprinters).indexOf(title) > -1) {
|
||||
const blueprinters = this.blueprinters[title];
|
||||
const bpConfig = this.blueprinters[title];
|
||||
|
||||
return blueprinters.map(blueprinter => {
|
||||
const saturatedBp = blueprinter(
|
||||
tab,
|
||||
this.sourceName,
|
||||
this.sourceId,
|
||||
data
|
||||
);
|
||||
const blueprint = bp(saturatedBp); // TODO: come up with better semantics.
|
||||
this.blueprints[title] = blueprint;
|
||||
return this.db.save(saturatedBp);
|
||||
});
|
||||
if (isFunction(bpConfig)) {
|
||||
return this._saveBp(tab, title, data, bpConfig);
|
||||
} else {
|
||||
return bpConfig.map(this._saveBp(tab, title, data));
|
||||
}
|
||||
} else {
|
||||
// If it can't find a blueprinter for the tab title, default to byRow
|
||||
return this.db.save(byRow(tab, this.sourceName, this.sourceId, data));
|
||||
|
||||
@@ -85,3 +85,9 @@ export function bp(full) {
|
||||
});
|
||||
return blueprint;
|
||||
}
|
||||
|
||||
export function isFunction(functionToCheck) {
|
||||
return (
|
||||
functionToCheck && {}.toString.call(functionToCheck) === "[object Function]"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user