2016-02-07 08:56:03 +00:00
|
|
|
/*
|
|
|
|
* Example tab-separated input:
|
|
|
|
* Some fields will be ignored
|
|
|
|
*
|
|
|
|
* id name metacode desc link user.name permission synapses
|
|
|
|
* 1 topic1 Catalyst admin commons 1->7
|
|
|
|
* 2 topic2 Event admin commons
|
|
|
|
* 5 topic Action admin commons
|
|
|
|
* 6 topic6 Action admin commons 6->7
|
|
|
|
* 7 topic7 Action admin commons 7->8 7<-6 7<-1
|
|
|
|
* 8 topic8 Action admin commons 8<-7
|
|
|
|
*/
|
|
|
|
|
|
|
|
Metamaps.Import = {
|
2016-02-14 14:39:29 +00:00
|
|
|
topicWhitelist: [
|
|
|
|
'name', 'metacode', 'description', 'link', 'permission'
|
2016-02-07 08:56:03 +00:00
|
|
|
],
|
2016-02-14 14:39:29 +00:00
|
|
|
synapseWhitelist: [
|
|
|
|
'desc', 'description', 'category', 'topic1', 'topic2', 'permission'
|
|
|
|
],
|
2016-02-07 08:56:03 +00:00
|
|
|
|
|
|
|
init: function() {
|
|
|
|
var self = Metamaps.Import;
|
|
|
|
$('body').bind('paste', function(e) {
|
|
|
|
var text = e.originalEvent.clipboardData.getData('text/plain');
|
|
|
|
|
2016-02-14 14:39:29 +00:00
|
|
|
var results = self.parseTabbedString(text);
|
|
|
|
var topics = results.topics;
|
|
|
|
var synapses = results.synapses;
|
|
|
|
|
|
|
|
if (topics.length > 0 || synapses.length > 0) {
|
|
|
|
if (confirm("Are you sure you want to create " + topics.length +
|
|
|
|
" new topics and " + synapses.length + " new synapses?")) {
|
|
|
|
self.importTopics(topics);
|
|
|
|
self.importSynapses(synapses);
|
|
|
|
}//if
|
2016-02-07 08:56:03 +00:00
|
|
|
}//if
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2016-02-14 14:39:29 +00:00
|
|
|
abort: function(message) {
|
|
|
|
console.error(message);
|
2016-02-07 08:56:03 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
parseTabbedString: function(text) {
|
|
|
|
var self = Metamaps.Import;
|
|
|
|
|
|
|
|
// determine line ending and split lines
|
|
|
|
var delim = "\n";
|
|
|
|
if (text.indexOf("\r\n") !== -1) {
|
|
|
|
delim = "\r\n";
|
|
|
|
}//if
|
|
|
|
|
2016-02-14 14:39:29 +00:00
|
|
|
var STATES = {
|
|
|
|
UNKNOWN: 0,
|
|
|
|
TOPICS_NEED_HEADERS: 1,
|
|
|
|
SYNAPSES_NEED_HEADERS: 2,
|
|
|
|
TOPICS: 3,
|
|
|
|
SYNAPSES: 4,
|
|
|
|
};
|
2016-02-07 08:56:03 +00:00
|
|
|
|
2016-02-14 14:39:29 +00:00
|
|
|
// state & lines determine parser behaviour
|
|
|
|
var state = STATES.UNKNOWN;
|
|
|
|
var lines = text.split(delim);
|
|
|
|
var results = { topics: [], synapses: [] }
|
|
|
|
var topicHeaders = [];
|
|
|
|
var synapseHeaders = [];
|
2016-02-07 08:56:03 +00:00
|
|
|
|
2016-02-14 14:39:29 +00:00
|
|
|
lines.forEach(function(line_raw, index) {
|
|
|
|
var line = line_raw.split(' '); // tab character
|
|
|
|
var noblanks = line.filter(function(elt) {
|
|
|
|
return elt !== "";
|
2016-02-07 08:56:03 +00:00
|
|
|
});
|
2016-02-14 14:39:29 +00:00
|
|
|
switch(state) {
|
|
|
|
case STATES.UNKNOWN:
|
|
|
|
if (noblanks.length === 0) {
|
|
|
|
state = STATES.UNKNOWN;
|
|
|
|
break;
|
|
|
|
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'topics') {
|
|
|
|
state = STATES.TOPICS_NEED_HEADERS;
|
|
|
|
break;
|
|
|
|
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'synapses') {
|
|
|
|
state = STATES.SYNAPSES_NEED_HEADERS;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
state = STATES.TOPICS_NEED_HEADERS;
|
|
|
|
// FALL THROUGH - if we're not sure what to do, pretend
|
|
|
|
// we're on the TOPICS_NEED_HEADERS state and parse some headers
|
|
|
|
|
|
|
|
case STATES.TOPICS_NEED_HEADERS:
|
|
|
|
if (noblanks.length < 2) {
|
|
|
|
return self.abort("Not enough topic headers on line " + index);
|
|
|
|
}
|
|
|
|
topicHeaders = line.map(function(header, index) {
|
|
|
|
return header.toLowerCase().replace('description', 'desc');
|
|
|
|
});
|
|
|
|
state = STATES.TOPICS;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATES.SYNAPSES_NEED_HEADERS:
|
|
|
|
if (noblanks.length < 2) {
|
|
|
|
return self.abort("Not enough synapse headers on line " + index);
|
|
|
|
}
|
|
|
|
synapseHeaders = line.map(function(header, index) {
|
|
|
|
return header.toLowerCase().replace('description', 'desc');
|
|
|
|
});
|
|
|
|
state = STATES.SYNAPSES;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATES.TOPICS:
|
|
|
|
if (noblanks.length === 0) {
|
|
|
|
state = STATES.UNKNOWN;
|
|
|
|
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'topics') {
|
|
|
|
state = STATES.TOPICS_NEED_HEADERS;
|
|
|
|
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'synapses') {
|
|
|
|
state = STATES.SYNAPSES_NEED_HEADERS;
|
|
|
|
} else {
|
|
|
|
var topic = {};
|
|
|
|
line.forEach(function(field, index) {
|
|
|
|
var header = topicHeaders[index];
|
|
|
|
if (self.topicWhitelist.indexOf(header) === -1) return;
|
|
|
|
topic[header] = field;
|
|
|
|
if (header === 'x' || header === 'y') {
|
|
|
|
topic[header] = parseInt(topic[header]);
|
|
|
|
}//if
|
|
|
|
});
|
|
|
|
results.topics.push(topic);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATES.SYNAPSES:
|
|
|
|
if (noblanks.length === 0) {
|
|
|
|
state = STATES.UNKNOWN;
|
|
|
|
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'topics') {
|
|
|
|
state = STATES.TOPICS_NEED_HEADERS;
|
|
|
|
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'synapses') {
|
|
|
|
state = STATES.SYNAPSES_NEED_HEADERS;
|
|
|
|
} else {
|
|
|
|
var synapse = {};
|
|
|
|
line.forEach(function(field, index) {
|
|
|
|
var header = synapseHeaders[index];
|
|
|
|
if (self.synapseWhitelist.indexOf(header) === -1) return;
|
|
|
|
synapse[header] = field;
|
|
|
|
if (header === 'topic1' || header === 'topic2') {
|
|
|
|
synapse[header] = parseInt(header);
|
|
|
|
}//if
|
|
|
|
});
|
|
|
|
results.synapses.push(synapse);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return self.abort("Invalid state while parsing import data. " +
|
|
|
|
"Check code.");
|
|
|
|
}
|
2016-02-07 08:56:03 +00:00
|
|
|
});
|
2016-02-14 14:39:29 +00:00
|
|
|
|
2016-02-07 08:56:03 +00:00
|
|
|
return results;
|
|
|
|
},
|
|
|
|
|
|
|
|
|
2016-02-14 14:39:29 +00:00
|
|
|
importTopics: function(parsedTopics) {
|
|
|
|
var self = Metamaps.Import;
|
|
|
|
|
|
|
|
// up to 25 topics: scale 100
|
|
|
|
// up to 81 topics: scale 200
|
|
|
|
// up to 169 topics: scale 300
|
|
|
|
var scale = Math.floor((Math.sqrt(parsedTopics.length) - 1) / 4) * 100;
|
|
|
|
if (scale < 100) scale = 100;
|
|
|
|
var autoX = -scale;
|
|
|
|
var autoY = -scale;
|
|
|
|
|
|
|
|
parsedTopics.forEach(function(topic) {
|
|
|
|
var x, y;
|
|
|
|
if (topic.x && topic.y) {
|
|
|
|
x = topic.x;
|
|
|
|
y = topic.y;
|
|
|
|
} else {
|
|
|
|
x = autoX;
|
|
|
|
y = autoY;
|
|
|
|
autoX += 50;
|
|
|
|
if (autoX > scale) {
|
|
|
|
autoY += 50;
|
|
|
|
autoX = -scale;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.createTopicWithParameters(
|
|
|
|
topic.name, topic.metacode, topic.permission,
|
|
|
|
topic.desc, topic.link, x, y, topic.id
|
|
|
|
);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
importSynapses: function(parsedSynapses) {
|
|
|
|
var self = Metamaps.Import;
|
|
|
|
|
|
|
|
parsedSynapses.forEach(function(synapse) {
|
|
|
|
self.createSynapseWithParameters(
|
|
|
|
synapse.desc, synapse.category, synapse.permission,
|
|
|
|
synapse.topic1, synapse.topic2
|
|
|
|
);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
createTopicWithParameters: function(name, metacode_name, permission, desc,
|
|
|
|
link, xloc, yloc, import_id) {
|
|
|
|
$(document).trigger(Metamaps.Map.events.editedByActiveMapper);
|
2016-02-07 08:56:03 +00:00
|
|
|
var metacode = Metamaps.Metacodes.where({name: metacode_name})[0] || null;
|
|
|
|
if (metacode === null) return console.error("metacode not found");
|
|
|
|
|
|
|
|
var topic = new Metamaps.Backbone.Topic({
|
|
|
|
name: name,
|
|
|
|
metacode_id: metacode.id,
|
|
|
|
permission: permission || Metamaps.Active.Map.get('permission'),
|
|
|
|
desc: desc,
|
2016-02-14 14:39:29 +00:00
|
|
|
link: link,
|
|
|
|
import_id: import_id
|
2016-02-07 08:56:03 +00:00
|
|
|
});
|
|
|
|
Metamaps.Topics.add(topic);
|
|
|
|
|
|
|
|
var mapping = new Metamaps.Backbone.Mapping({
|
|
|
|
xloc: xloc,
|
|
|
|
yloc: yloc,
|
|
|
|
mappable_id: topic.cid,
|
|
|
|
mappable_type: "Topic",
|
|
|
|
});
|
|
|
|
Metamaps.Mappings.add(mapping);
|
|
|
|
|
2016-02-07 09:51:01 +00:00
|
|
|
// this function also includes the creation of the topic in the database
|
2016-02-14 14:39:29 +00:00
|
|
|
Metamaps.Topic.renderTopic(mapping, topic, true, true);
|
|
|
|
|
|
|
|
Metamaps.Famous.viz.hideInstructions();
|
|
|
|
},
|
|
|
|
|
|
|
|
createSynapseWithParameters: function(description, category, permission,
|
|
|
|
node1_id, node2_id) {
|
|
|
|
var topic1 = Metamaps.Topics.where({import_id: node1_id});
|
|
|
|
var topic2 = Metamaps.Topics.where({import_id: node2_id});
|
|
|
|
var node1 = topic1.get('node');
|
|
|
|
var node2 = topic2.get('node');
|
|
|
|
// TODO check if topic1 and topic2 were sucessfully found...
|
|
|
|
|
|
|
|
var synapse = new Metamaps.Backbone.Synapse({
|
|
|
|
desc: description,
|
|
|
|
category: category,
|
|
|
|
permission: permission,
|
|
|
|
node1_id: node1_id,
|
|
|
|
node2_id: node2_id,
|
|
|
|
});
|
|
|
|
|
|
|
|
var mapping = new Metamaps.Backbone.Mapping({
|
|
|
|
mappable_type: "Synapse",
|
|
|
|
mappable_id: synapse.cid,
|
|
|
|
});
|
|
|
|
|
|
|
|
Metamaps.Synapse.renderSynapse(mapping, synapse, node1, node2, true);
|
2016-02-07 08:56:03 +00:00
|
|
|
},
|
|
|
|
};
|