enable csv import using csv-parse module

This commit is contained in:
Devin Howard 2016-09-24 15:22:42 +08:00
parent 82b7c7e5ac
commit 40f89b1c61
3 changed files with 75 additions and 41 deletions

View file

@ -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
})
} }
} }

View file

@ -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)
} }
} }

View file

@ -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",