Merge pull request #660 from metamaps/feature/csv

enable csv import using csv-parse module
This commit is contained in:
Devin Howard 2016-09-25 14:27:48 +08:00 committed by GitHub
commit 1810faacbe
3 changed files with 75 additions and 41 deletions

View file

@ -1,5 +1,8 @@
/* global Metamaps, $ */
import parse from 'csv-parse'
import _ from 'lodash'
import Active from './Active'
import GlobalUI from './GlobalUI'
import Map from './Map'
@ -33,6 +36,40 @@ const Import = {
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) {
var self = Import
results = JSON.parse(text)
@ -53,16 +90,6 @@ const Import = {
} // if
},
abort: function (message) {
console.error(message)
},
simplify: function (string) {
return string
.replace(/(^\s*|\s*$)/g, '')
.toLowerCase()
},
parseTabbedString: function (text) {
var self = Import
@ -235,30 +262,22 @@ const Import = {
return true
}
var synapse_created = false
topic1.once('sync', function () {
if (topic1.id && topic2.id && !synapse_created) {
synapse_created = true
// ensure imported topics have a chance to get a real id attr before creating synapses
const topic1Promise = $.Deferred()
topic1.once('sync', () => topic1Promise.resolve())
const topic2Promise = $.Deferred()
topic2.once('sync', () => topic2Promise.resolve())
$.when(topic1Promise, topic2Promise).done(() => {
self.createSynapseWithParameters(
synapse.desc, synapse.category, synapse.permission,
topic1, topic2
)
} // if
})
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,
link, xloc, yloc, import_id, opts) {
link, xloc, yloc, import_id, opts = {}) {
var self = Import
$(document).trigger(Map.events.editedByActiveMapper)
var metacode = Metamaps.Metacodes.where({name: metacode_name})[0] || null
@ -326,6 +345,28 @@ const Import = {
Metamaps.Mappings.add(mapping)
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)) {
self.handleURL(text, coords)
} else if (text[0] === '{') {
self.handleJSON(text)
Import.handleJSON(text)
} else if (text.match(/\t/)) {
self.handleTSV(text)
} else {
// fail silently
Import.handleTSV(text)
} else if (text.match(/","/)) {
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-react": "6.11.1",
"backbone": "1.0.0",
"csv-parse": "1.1.7",
"node-uuid": "1.2.0",
"react": "15.3.0",
"react-dom": "15.3.0",