13 Commits

Author SHA1 Message Date
efarooqui
6c1e287148 Merge branch 'develop' of https://www.github.com/forensic-architecture/datasheet-server into feature/json-api-export 2021-03-01 16:06:52 -08:00
Ebrahem Farooqui
679407f421 adding env vars for test and lint 2021-03-01 16:05:16 -08:00
efarooqui
32f3f41a82 Minor comment; running new ci file for testing 2021-02-22 10:40:54 -08:00
Ebrahem Farooqui
3eebf811fb Incorrect syntax for unpacking head ref 2021-02-22 09:50:46 -08:00
Ebrahem Farooqui
be03a3983a Adding branch to checkout
Adding the correct branch to checkout with for workflow
2021-02-22 09:47:05 -08:00
efarooqui
b91068c346 Linting errors 2021-02-17 11:36:36 -08:00
efarooqui
d6512e2cde Replacing empty string with null 2021-02-17 11:33:39 -08:00
efarooqui
3e2b9f2a1d Redundant error message in copy file 2021-02-09 16:58:13 -08:00
efarooqui
3c391e5dfa Working error handling; refactored a bit but same functionality 2021-02-09 16:50:58 -08:00
efarooqui
7c963eb1d0 Working file export; need to test out error handling and flows 2021-02-09 15:38:54 -08:00
efarooqui
fb77e1c365 Adding fileDest to retrieveAll function in Controller 2021-02-08 18:37:11 -08:00
efarooqui
13a4b11259 New export route working to query all blueprints and add to one data object; need to write to file 2021-02-08 17:33:09 -08:00
efarooqui
7bafcb0343 Make new route in api instead of going through npm script; new retrieveAll call for controller 2021-02-08 11:49:43 -08:00
7 changed files with 75 additions and 3 deletions

View File

@@ -10,11 +10,16 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
- uses: actions/setup-node@v2-beta - uses: actions/setup-node@v2-beta
with: with:
node-version: '12' node-version: '12'
- run: npm install - run: npm install
- run: npm test - run: npm test
env:
CI: true
- run: npm run lint - run: npm run lint
env:
CI: true

View File

@@ -3,6 +3,7 @@
"version": "0.3.0", "version": "0.3.0",
"description": "Starter project for an ES6 RESTful Express API", "description": "Starter project for an ES6 RESTful Express API",
"main": "dist", "main": "dist",
"type": "module",
"scripts": { "scripts": {
"dev": "env NODE_ENV=development nodemon -w src --exec \"babel-node src\"", "dev": "env NODE_ENV=development nodemon -w src --exec \"babel-node src\"",
"build": "env NODE_ENV=production npx babel src -d dist", "build": "env NODE_ENV=production npx babel src -d dist",
@@ -26,6 +27,7 @@
"express": "^4.13.3", "express": "^4.13.3",
"express-graphql": "^0.6.12", "express-graphql": "^0.6.12",
"express-handlebars": "^4.0.4", "express-handlebars": "^4.0.4",
"file-system": "^2.2.2",
"googleapis": "^39.1.0", "googleapis": "^39.1.0",
"graphql": "^0.13.2", "graphql": "^0.13.2",
"morgan": "^1.8.0", "morgan": "^1.8.0",

View File

@@ -4,6 +4,7 @@ import copy from '../copy/en'
export default ({ config, controller }) => { export default ({ config, controller }) => {
let api = Router() let api = Router()
const fileDest = config.EXPORT_FILE_DEST || null
api.get('/', (req, res) => { api.get('/', (req, res) => {
res.json({ res.json({
@@ -22,6 +23,20 @@ export default ({ config, controller }) => {
}) })
}) })
api.get('/export', (req, res) => {
controller
.retrieveAll(fileDest)
.then(msg =>
res.json({
success: msg
})
)
.catch(err =>
res.status(404)
.send({ error: err.message, err })
)
})
api.get('/update', (req, res) => { api.get('/update', (req, res) => {
controller controller
.update() .update()

View File

@@ -1,6 +1,10 @@
export default { export default {
errors: { errors: {
update: 'The server could not update. Check your API credentials and internet connection and try again.', update: 'The server could not update. Check your API credentials and internet connection and try again.',
export: {
fileMissing: 'The server could not export. Check that you provided a file path to export to and try again.',
writeFailed: 'The server could not export the data to the file. There is an issue with the data format'
},
onlySheet: 'You cannot query a sheet directly. The URL needs to be in the format /:sheet/:tab/:resource.', onlySheet: 'You cannot query a sheet directly. The URL needs to be in the format /:sheet/:tab/:resource.',
onlyTab: 'You cannot query a tab directly. The URL needs to be in the format /:sheet/:tab/:resource.', onlyTab: 'You cannot query a tab directly. The URL needs to be in the format /:sheet/:tab/:resource.',
noSheet: sheet => `The sheet ${sheet} is not available in this server.`, noSheet: sheet => `The sheet ${sheet} is not available in this server.`,
@@ -9,6 +13,7 @@ export default {
modelLayer: prts => `Something went wrong at the model layer` modelLayer: prts => `Something went wrong at the model layer`
}, },
success: { success: {
update: 'All sheets updated' update: 'All sheets updated',
export: dest => `All resources exported to the file: ${dest}`
} }
} }

View File

@@ -1 +0,0 @@
CONFIG=../configs/timemap/grenfell/datasheet.config.js

View File

@@ -1,4 +1,5 @@
import copy from '../copy/en' import copy from '../copy/en'
import { exportToFile } from '../lib/util'
/** /**
* Controller * Controller
@@ -39,6 +40,37 @@ class Controller {
}) })
} }
// Controller function to retrieve all blueprints and export to user defined file location
retrieveAll (fileDest) {
if (!fileDest) return Promise.reject(new Error(copy.errors.export.fileMissing))
const indexedData = {}
const urls = []
const bps = this.blueprints()
return Promise.all(
bps.map(bp => {
const resource = Object.keys(bp.resources)[0]
urls.push(bp.urls[0])
return this.retrieve(bp.sheet.name, bp.name, resource)
})
).then(async results => {
if (results.every(res => res)) {
urls.forEach((item, idx) => {
indexedData[item] = results[idx]
})
try {
const message = await exportToFile(fileDest, indexedData)
return message
} catch (e) {
return Promise.reject(e)
}
} else {
throw new Error(copy.errors.export.writeFailed)
}
})
}
retrieve (sheet, tab, resource) { retrieve (sheet, tab, resource) {
if (this._sheetExists(sheet)) { if (this._sheetExists(sheet)) {
const fetcher = this.fetchers[sheet] const fetcher = this.fetchers[sheet]

View File

@@ -1,4 +1,6 @@
import R from 'ramda' import R from 'ramda'
import { promises as fs } from 'file-system'
import copy from '../copy/en'
/* eslint-disable */ /* eslint-disable */
String.prototype.replaceAll = function (search, replacement) { String.prototype.replaceAll = function (search, replacement) {
@@ -14,6 +16,18 @@ function camelize (str) {
}) })
} }
export async function exportToFile (fileDest, data) {
const stringifiedData = JSON.stringify(data, null, 2)
const filePath = `${fileDest}/export.json`
try {
await fs.writeFile(filePath, stringifiedData)
return copy.success.export(filePath)
} catch (err) {
throw new Error(copy.errors.export.writeFailed)
}
}
export const fmtObj = R.curry( export const fmtObj = R.curry(
( (
columnNames, columnNames,