mirror of
https://github.com/bellingcat/datasheet-server.git
synced 2026-06-12 21:38:32 +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 |
|
| 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 |
|
| 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
|
###### Example Configuration Object
|
||||||
```js
|
```js
|
||||||
@@ -104,8 +104,8 @@ export default {
|
|||||||
name: 'example',
|
name: 'example',
|
||||||
id: '1s-vfBR8Uy-B-TLO_C5Ozw4z-L0E3hdP8ohMV761ouRI',
|
id: '1s-vfBR8Uy-B-TLO_C5Ozw4z-L0E3hdP8ohMV761ouRI',
|
||||||
tabs: {
|
tabs: {
|
||||||
'objects': [BP.byRow],
|
'objects': BP.byRow,
|
||||||
'objectsB': [BP.byRow, BP.byID],
|
'fruit': [BP.byRow, BP.byID],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
// FetcherTwo class interfaces with Google Sheet, and saves to a specified db
|
// FetcherTwo class interfaces with Google Sheet, and saves to a specified db
|
||||||
import {google} from "googleapis";
|
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 {byRow, byId} from "./blueprinters";
|
||||||
import R from "ramda";
|
import R from "ramda";
|
||||||
|
|
||||||
@@ -39,6 +45,23 @@ class Fetcher {
|
|||||||
*/
|
*/
|
||||||
this.sheets = google.sheets("v4");
|
this.sheets = google.sheets("v4");
|
||||||
this.auth = null;
|
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. */
|
/** returns a Promise that resolves if access is granted to the account, and rejects otherwise. */
|
||||||
@@ -96,19 +119,13 @@ class Fetcher {
|
|||||||
save(tab, data) {
|
save(tab, data) {
|
||||||
const title = fmtSourceTitle(tab);
|
const title = fmtSourceTitle(tab);
|
||||||
if (Object.keys(this.blueprinters).indexOf(title) > -1) {
|
if (Object.keys(this.blueprinters).indexOf(title) > -1) {
|
||||||
const blueprinters = this.blueprinters[title];
|
const bpConfig = this.blueprinters[title];
|
||||||
|
|
||||||
return blueprinters.map(blueprinter => {
|
if (isFunction(bpConfig)) {
|
||||||
const saturatedBp = blueprinter(
|
return this._saveBp(tab, title, data, bpConfig);
|
||||||
tab,
|
} else {
|
||||||
this.sourceName,
|
return bpConfig.map(this._saveBp(tab, title, data));
|
||||||
this.sourceId,
|
}
|
||||||
data
|
|
||||||
);
|
|
||||||
const blueprint = bp(saturatedBp); // TODO: come up with better semantics.
|
|
||||||
this.blueprints[title] = blueprint;
|
|
||||||
return this.db.save(saturatedBp);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
// If it can't find a blueprinter for the tab title, default to byRow
|
// 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));
|
return this.db.save(byRow(tab, this.sourceName, this.sourceId, data));
|
||||||
|
|||||||
@@ -85,3 +85,9 @@ export function bp(full) {
|
|||||||
});
|
});
|
||||||
return blueprint;
|
return blueprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isFunction(functionToCheck) {
|
||||||
|
return (
|
||||||
|
functionToCheck && {}.toString.call(functionToCheck) === "[object Function]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user