mirror of
https://github.com/bellingcat/datasheet-server.git
synced 2026-06-09 20:08:32 +03:00
Compare commits
1 Commits
feature/ad
...
v0.5.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9eb6ea6e2 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,3 +14,4 @@ tags
|
||||
tags.lock
|
||||
tags.temp
|
||||
src/config.js
|
||||
src/local.config.js
|
||||
|
||||
@@ -53,7 +53,7 @@ Each Google Sheet being used as a as source requires a corresponding object in `
|
||||
See src/config.js for an example configuration sheet.
|
||||
|
||||
|
||||
## [Quickstart](#quickstart)
|
||||
## [Quickstart](#quickstart)
|
||||
Clone the repository to your local:
|
||||
```
|
||||
git clone https://www.github.com/forensic-architecture/datasheet-server
|
||||
|
||||
Binary file not shown.
1960
package-lock.json
generated
1960
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -26,15 +26,15 @@
|
||||
"express": "^4.13.3",
|
||||
"express-graphql": "^0.6.12",
|
||||
"express-handlebars": "^4.0.4",
|
||||
"googleapis": "^32.0.0",
|
||||
"googleapis": "^39.1.0",
|
||||
"graphql": "^0.13.2",
|
||||
"morgan": "^1.8.0",
|
||||
"mz": "^2.7.0",
|
||||
"node-fetch": "^2.3.0",
|
||||
"node-xlsx": "^0.15.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"object-hash": "^1.3.0",
|
||||
"ramda": "^0.25.0",
|
||||
"resource-router-middleware": "^0.6.0"
|
||||
"resource-router-middleware": "^0.6.0",
|
||||
"xlsx": "^0.16.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.1.2",
|
||||
|
||||
@@ -63,7 +63,10 @@ export default (data) => {
|
||||
structure.__flat.forEach(label => {
|
||||
deepRow[label] = baseRow[label]
|
||||
})
|
||||
if (deepRow['id'] && deepRow['id'] !== '') {
|
||||
if (!Object.keys(deepRow).every(k => (
|
||||
(deepRow[k] === '') ||
|
||||
(Array.isArray(deepRow[k]) && deepRow[k].length === 0)
|
||||
))) {
|
||||
output.push(deepRow)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import http from 'http'
|
||||
import path from 'path'
|
||||
import express from 'express'
|
||||
import initialize from './initialize'
|
||||
import middleware from './middleware'
|
||||
@@ -40,7 +41,7 @@ initialize(controller => {
|
||||
})
|
||||
)
|
||||
|
||||
app.use(express.static(__dirname + '/public'))
|
||||
app.use(express.static(path.join(__dirname, 'public')))
|
||||
|
||||
app.server.listen(process.env.PORT || 4040, () => {
|
||||
console.log('===========================================')
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import StoreJson from './models/StoreJson'
|
||||
import fetchers from './lib/Fetcher'
|
||||
import Controller from './lib/Controller'
|
||||
import config from './config'
|
||||
import R from 'ramda'
|
||||
|
||||
const isntNull = n => n !== null
|
||||
@@ -9,6 +8,13 @@ const filterNull = ls => R.filter(isntNull, ls)
|
||||
const flattenfilterNull = ls => filterNull(R.flatten(ls))
|
||||
let themFetchers
|
||||
|
||||
let config
|
||||
try {
|
||||
config = require('./local.config.js').default
|
||||
} catch (_) {
|
||||
config = require('./config.js').default
|
||||
}
|
||||
|
||||
export default callback => {
|
||||
return Promise.resolve().then(() => {
|
||||
return Object.keys(config).map(fType => {
|
||||
|
||||
@@ -5,9 +5,7 @@ function prefixedTabs (prefix, cfg) {
|
||||
const prf = key => cfg[key] ? `${prefix}_` : ''
|
||||
return {
|
||||
[`${prf('events')}export_events`]: BP.deeprows,
|
||||
[`${prf('categories')}export_categories`]: [BP.groups, BP.rows],
|
||||
[`${prf('filters')}export_filters`]: BP.tree,
|
||||
[`${prf('narratives')}export_narratives`]: BP.rows,
|
||||
[`${prf('associations')}export_associations`]: BP.deeprows,
|
||||
[`${prf('sources')}export_sources`]: BP.deepids,
|
||||
[`${prf('sites')}export_sites`]: BP.rows
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
// FetcherTwo class interfaces with Google Sheet, and saves to a specified db
|
||||
import { google } from 'googleapis'
|
||||
import R from 'ramda'
|
||||
import { createHash } from 'crypto'
|
||||
import { buildDesaturated } from './blueprinters'
|
||||
import {
|
||||
fmtName,
|
||||
fmtBlueprinterTitles,
|
||||
isFunction
|
||||
} from './util'
|
||||
import { createHash } from 'crypto'
|
||||
import R from 'ramda'
|
||||
import xlsx from 'node-xlsx'
|
||||
import fs from 'fs'
|
||||
|
||||
/* GsheetFetcher deps */
|
||||
import { google } from 'googleapis'
|
||||
/* LocalFetcher deps */
|
||||
import X from 'xlsx'
|
||||
|
||||
class Fetcher {
|
||||
constructor (db, name, bps) {
|
||||
@@ -138,7 +139,6 @@ class Fetcher {
|
||||
|
||||
/** Run on startup. Should be overridden if explicit auth is required **/
|
||||
authenticate (env) {
|
||||
console.log(`Connected to ${this.sheetName}. No explicit authentication required for ${this.type}s.`)
|
||||
return Promise.resolve(this)
|
||||
}
|
||||
}
|
||||
@@ -221,27 +221,22 @@ class GsheetFetcher extends Fetcher {
|
||||
}
|
||||
}
|
||||
|
||||
class XlsxFetcher extends Fetcher {
|
||||
class LocalFetcher extends Fetcher {
|
||||
constructor (db, name, bps, path) {
|
||||
super(db, name, bps)
|
||||
this.type = 'XLSX File'
|
||||
this.path = path
|
||||
this.isRemote = false
|
||||
|
||||
if (this.path.startsWith('https')) {
|
||||
this.isRemote = true
|
||||
}
|
||||
this.update().then(res =>
|
||||
console.log(`${res ? 'Successful' : 'Couldn\'t'} update ${name}`)
|
||||
)
|
||||
}
|
||||
|
||||
update () {
|
||||
const data = xlsx.parse(fs.readFileSync(this.path))
|
||||
data.forEach(tab => {
|
||||
const stringyData = tab.data.map(row =>
|
||||
row.map(d =>
|
||||
typeof (d) === 'number' ? d.toString() : d
|
||||
)
|
||||
)
|
||||
this.save(tab.name, stringyData)
|
||||
const wb = X.readFile(this.path)
|
||||
wb.SheetNames.forEach(name => {
|
||||
const sh = wb.Sheets[name]
|
||||
const csv = X.utils.sheet_to_csv(sh, { FS: '\t' })
|
||||
const ll = csv.split('\n').map(line => line.split('\t'))
|
||||
this.save(name, ll)
|
||||
})
|
||||
return Promise.resolve(true)
|
||||
}
|
||||
@@ -249,5 +244,7 @@ class XlsxFetcher extends Fetcher {
|
||||
|
||||
export default {
|
||||
'gsheets': GsheetFetcher,
|
||||
'xlsx': XlsxFetcher
|
||||
'xlsx': LocalFetcher,
|
||||
'ods': LocalFetcher,
|
||||
'local': LocalFetcher
|
||||
}
|
||||
|
||||
@@ -54,14 +54,7 @@ test('should launch', t => {
|
||||
})
|
||||
|
||||
const passUrls = [
|
||||
// /
|
||||
'/api/',
|
||||
// /blueprints
|
||||
'/api/blueprints',
|
||||
// /:sheet/:tab/:resource
|
||||
'/api/example/export_events/rows',
|
||||
// /:sheet/:tab/:resource/:frag
|
||||
'/api/example/export_events/rows/1'
|
||||
]
|
||||
|
||||
const failUrls = [
|
||||
@@ -77,6 +70,7 @@ passUrls.forEach(function (url) {
|
||||
.then(checkStatus)
|
||||
.then(res => res.json())
|
||||
.then(json => {
|
||||
console.info('JSON: ', json)
|
||||
t.pass()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user