Merge pull request #660 from metamaps/feature/csv
enable csv import using csv-parse module
This commit is contained in:
commit
1810faacbe
3 changed files with 75 additions and 41 deletions
|
@ -1,5 +1,8 @@
|
||||||
/* global Metamaps, $ */
|
/* global Metamaps, $ */
|
||||||
|
|
||||||
|
import parse from 'csv-parse'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
import Active from './Active'
|
import Active from './Active'
|
||||||
import GlobalUI from './GlobalUI'
|
import GlobalUI from './GlobalUI'
|
||||||
import Map from './Map'
|
import Map from './Map'
|
||||||
|
@ -33,6 +36,40 @@ const Import = {
|
||||||
self.handle(results)
|
self.handle(results)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleCSV: function (text, parserOpts = {}) {
|
||||||
|
var self = Import
|
||||||
|
|
||||||
|
const topicsRegex = /("?Topics"?)([\s\S]*)/mi
|
||||||
|
const synapsesRegex = /("?Synapses"?)([\s\S]*)/mi
|
||||||
|
let topicsText = text.match(topicsRegex)
|
||||||
|
if (topicsText) topicsText = topicsText[2].replace(synapsesRegex, '')
|
||||||
|
let synapsesText = text.match(synapsesRegex)
|
||||||
|
if (synapsesText) synapsesText = synapsesText[2].replace(topicsRegex, '')
|
||||||
|
|
||||||
|
// merge default options and extra options passed in parserOpts argument
|
||||||
|
const csv_parser_options = Object.assign({
|
||||||
|
columns: true, // get headers
|
||||||
|
relax_column_count: true,
|
||||||
|
skip_empty_lines: true
|
||||||
|
}, parserOpts)
|
||||||
|
|
||||||
|
const topicsPromise = $.Deferred()
|
||||||
|
parse(topicsText, csv_parser_options, (err, data) => {
|
||||||
|
if (err) topicsPromise.reject(err)
|
||||||
|
topicsPromise.resolve(data.map(row => self.lowercaseKeys(row)))
|
||||||
|
})
|
||||||
|
|
||||||
|
const synapsesPromise = $.Deferred()
|
||||||
|
parse(synapsesText, csv_parser_options, (err, data) => {
|
||||||
|
if (err) synapsesPromise.reject(err)
|
||||||
|
synapsesPromise.resolve(data.map(row => self.lowercaseKeys(row)))
|
||||||
|
})
|
||||||
|
|
||||||
|
$.when(topicsPromise, synapsesPromise).done((topics, synapses) => {
|
||||||
|
self.handle({ topics, synapses})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
handleJSON: function (text) {
|
handleJSON: function (text) {
|
||||||
var self = Import
|
var self = Import
|
||||||
results = JSON.parse(text)
|
results = JSON.parse(text)
|
||||||
|
@ -53,16 +90,6 @@ const Import = {
|
||||||
} // if
|
} // if
|
||||||
},
|
},
|
||||||
|
|
||||||
abort: function (message) {
|
|
||||||
console.error(message)
|
|
||||||
},
|
|
||||||
|
|
||||||
simplify: function (string) {
|
|
||||||
return string
|
|
||||||
.replace(/(^\s*|\s*$)/g, '')
|
|
||||||
.toLowerCase()
|
|
||||||
},
|
|
||||||
|
|
||||||
parseTabbedString: function (text) {
|
parseTabbedString: function (text) {
|
||||||
var self = Import
|
var self = Import
|
||||||
|
|
||||||
|
@ -235,30 +262,22 @@ const Import = {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
var synapse_created = false
|
// ensure imported topics have a chance to get a real id attr before creating synapses
|
||||||
topic1.once('sync', function () {
|
const topic1Promise = $.Deferred()
|
||||||
if (topic1.id && topic2.id && !synapse_created) {
|
topic1.once('sync', () => topic1Promise.resolve())
|
||||||
synapse_created = true
|
const topic2Promise = $.Deferred()
|
||||||
self.createSynapseWithParameters(
|
topic2.once('sync', () => topic2Promise.resolve())
|
||||||
synapse.desc, synapse.category, synapse.permission,
|
$.when(topic1Promise, topic2Promise).done(() => {
|
||||||
topic1, topic2
|
self.createSynapseWithParameters(
|
||||||
)
|
synapse.desc, synapse.category, synapse.permission,
|
||||||
} // if
|
topic1, topic2
|
||||||
})
|
)
|
||||||
topic2.once('sync', function () {
|
|
||||||
if (topic1.id && topic2.id && !synapse_created) {
|
|
||||||
synapse_created = true
|
|
||||||
self.createSynapseWithParameters(
|
|
||||||
synapse.desc, synapse.category, synapse.permission,
|
|
||||||
topic1, topic2
|
|
||||||
)
|
|
||||||
} // if
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
createTopicWithParameters: function (name, metacode_name, permission, desc,
|
createTopicWithParameters: function (name, metacode_name, permission, desc,
|
||||||
link, xloc, yloc, import_id, opts) {
|
link, xloc, yloc, import_id, opts = {}) {
|
||||||
var self = Import
|
var self = Import
|
||||||
$(document).trigger(Map.events.editedByActiveMapper)
|
$(document).trigger(Map.events.editedByActiveMapper)
|
||||||
var metacode = Metamaps.Metacodes.where({name: metacode_name})[0] || null
|
var metacode = Metamaps.Metacodes.where({name: metacode_name})[0] || null
|
||||||
|
@ -326,6 +345,28 @@ const Import = {
|
||||||
Metamaps.Mappings.add(mapping)
|
Metamaps.Mappings.add(mapping)
|
||||||
|
|
||||||
Synapse.renderSynapse(mapping, synapse, node1, node2, true)
|
Synapse.renderSynapse(mapping, synapse, node1, node2, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* helper functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
abort: function (message) {
|
||||||
|
console.error(message)
|
||||||
|
},
|
||||||
|
|
||||||
|
simplify: function (string) {
|
||||||
|
return string
|
||||||
|
.replace(/(^\s*|\s*$)/g, '')
|
||||||
|
.toLowerCase()
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// thanks to http://stackoverflow.com/a/25290114/5332286
|
||||||
|
lowercaseKeys: function(obj) {
|
||||||
|
return _.transform(obj, (result, val, key) => {
|
||||||
|
result[key.toLowerCase()] = val
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,11 +60,11 @@ const PasteInput = {
|
||||||
if (text.match(self.URL_REGEX)) {
|
if (text.match(self.URL_REGEX)) {
|
||||||
self.handleURL(text, coords)
|
self.handleURL(text, coords)
|
||||||
} else if (text[0] === '{') {
|
} else if (text[0] === '{') {
|
||||||
self.handleJSON(text)
|
Import.handleJSON(text)
|
||||||
} else if (text.match(/\t/)) {
|
} else if (text.match(/\t/)) {
|
||||||
self.handleTSV(text)
|
Import.handleTSV(text)
|
||||||
} else {
|
} else if (text.match(/","/)) {
|
||||||
// fail silently
|
Import.handleCSV(text)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -95,14 +95,6 @@ const PasteInput = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
|
||||||
|
|
||||||
handleJSON: function (text) {
|
|
||||||
Import.handleJSON(text)
|
|
||||||
},
|
|
||||||
|
|
||||||
handleTSV: function (text) {
|
|
||||||
Import.handleTSV(text)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
"babel-preset-es2015": "6.9.0",
|
"babel-preset-es2015": "6.9.0",
|
||||||
"babel-preset-react": "6.11.1",
|
"babel-preset-react": "6.11.1",
|
||||||
"backbone": "1.0.0",
|
"backbone": "1.0.0",
|
||||||
|
"csv-parse": "1.1.7",
|
||||||
"node-uuid": "1.2.0",
|
"node-uuid": "1.2.0",
|
||||||
"react": "15.3.0",
|
"react": "15.3.0",
|
||||||
"react-dom": "15.3.0",
|
"react-dom": "15.3.0",
|
||||||
|
|
Loading…
Reference in a new issue