Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial ConversionFactory for fully configurable imports

  • Loading branch information...
commit b624bfc3cc3a5f492979410927d4698293b84c07 1 parent 7af2be3
@samluescher samluescher authored
View
202 api/import/conversion/index.js
@@ -1,5 +1,8 @@
var utils = require('../../../utils.js'),
- console = require('../../../ext-console.js');
+ console = require('../../../ext-console.js'),
+ _ = require('cloneextend');
+
+var ARRAY_SEPARATORS = /[,;]/;
var ConversionError = function(msg) {
this.message = msg;
@@ -16,5 +19,200 @@ this.convertModel = function(fromModel, converter, toModel) {
return false;
}
}
- return new toModel(doc);
+ var m = new toModel(doc);
+ return m;
+}
+
+function isValidDate(d) {
+ if ( Object.prototype.toString.call(d) !== "[object Date]" )
+ return false;
+ return !isNaN(d.getTime());
}
+
+var Cast = {
+ Number: function(value, options) {
+ var num = Number(value);
+ if (!isNaN(num) && (!options.ignoreZero || num != 0)) {
+ return num;
+ }
+ },
+ String: function(value, options) {
+ if (value != undefined) {
+ var str = '' + value;
+ if (!options.ignoreEmpty || value != '') {
+ return str;
+ }
+ }
+ },
+ Array: function(value, options) {
+ if (value != undefined) {
+ if (!Array.isArray(value)) {
+ return [value];
+ } else {
+ return value;
+ }
+ }
+ },
+ Date: function(value, options) {
+ if ((Array.isArray(value) && value.length == 3) || typeof(value) == 'string') {
+ date = new Date(value);
+ if (isValidDate(date)) {
+ return date;
+ }
+ }
+ }
+}
+
+var FieldType = {
+ Number: function(fromFields, options) {
+ var fromFields = Cast.Array(fromFields);
+ var l = fromFields.length;
+ var options = options || {};
+ return function() {
+ for (var i = 0; i < l; i++) {
+ var num = Cast.Number(this.get(fromFields[i]), options);
+ if (num != undefined) {
+ if (options.min != undefined && num < options.min) {
+ return new ConversionError('Ignoring low number: ' + num);
+ } else if (options.max != undefined && num > options.max) {
+ return new ConversionError('Ignoring high number:' + num);
+ } else {
+ return num;
+ }
+ }
+ }
+ };
+ },
+ Array: function(fromFields, options) {
+ var fromFields = Cast.Array(fromFields);
+ var l = fromFields.length;
+ var cast = options.cast ? Cast[options.cast] : null;
+ var options = options || {};
+ return function() {
+ var arr = [];
+ for (var i = 0; i < l; i++) {
+ var v = this.get(fromFields[i]);
+ if (typeof v == 'string' && l == 1) {
+ if (v != undefined) {
+ arr = Cast.Array(v.split(ARRAY_SEPARATORS));
+ if (arr) {
+ var al = arr.length;
+ for (j = 0; j < al; j++) {
+ arr[j] = cast(arr[j], options);
+ }
+ return arr;
+ }
+ }
+ } else {
+ arr.push(!cast ? v : cast(v, options));
+ }
+ }
+ return arr;
+ };
+ },
+ Date: function(fromFields, options) {
+ var fromFields = Cast.Array(fromFields);
+ var l = fromFields.length;
+ var options = options || {};
+ return function() {
+ var date;
+ if (l == 1) {
+ date = Cast.Date(this.get(fromFields[0]), options);
+ } else {
+ var numbers = [];
+ for (var i = 0; i < l; i++) {
+ numbers[i] = Cast.Number(this.get(fromFields[i]), options);
+ }
+ date = Cast.Date(numbers);
+ }
+ if (date) {
+ if (!options.ignoreFuture || date <= new Date()) {
+ return date;
+ } else {
+ return new ConversionError('Ignoring future date: ' + date);
+ }
+ }
+ };
+ },
+ String: function(fromFields, options) {
+ var fromFields = Cast.Array(fromFields);
+ var l = fromFields.length;
+ var options = options || {};
+ return function() {
+ var strings = {};
+ for (var i = 0; i < l; i++) {
+ var str = Cast.String(this.get(fromFields[i]), options);
+ if (str != undefined) {
+ if (!options.format) {
+ return str;
+ } else if (options.ignoreEmpty && str == '') {
+ return new ConversionError('Ignoring empty string');
+ } else {
+ strings[fromFields[i]] = str;
+ }
+ }
+ }
+ if (options.format) {
+ return options.format.format(strings);
+ }
+ };
+ },
+ LngLat: function(fromFields, options) {
+ var options = options || {};
+ var arrayOptions = _.cloneextend(options, {
+ cast: 'Number',
+ ignoreZero: false
+ });
+ var toArray = FieldType.Array(fromFields, arrayOptions);
+ return function() {
+ var arr = toArray.call(this);
+ if (arr && arr.length == 2) {
+ if (!options.ignoreZero || (arr[0] != 0 && arr[1] != 0)) {
+ return arr;
+ } else {
+ console.warn('Ignoring LngLat [0,0]');
+ }
+ }
+ }
+ },
+ LatLng: function(fromFields, options) {
+ var toLngLat = FieldType.LngLat(fromFields, options);
+ return function() {
+ var arr = toLngLat.call(this);
+ if (arr) {
+ return [arr[1], arr[0]];
+ }
+ }
+ }
+}
+
+/**
+Initializes a converter object based on field definitions, which look like the
+following:
+
+fieldDefs = {
+ '<to-field-name>': {
+ 'type': 'Number|String|Array|Date',
+ 'fromFields': '<from-field-name>'|['<field1>', '<field2>', '...'],
+ 'options': { // all are optional
+ 'min': <Number>, // for Number
+ 'max': <Number>, // for Number
+ 'ignoreEmpty': <Boolean>, // for Number
+ 'igoreZero': <Boolean>, // for String
+ 'ignoreFuture': <Boolean>, // for Date
+ 'cast': '<field-type>' // for Array elements
+ }
+ },
+ // ...
+}
+*/
+this.ConverterFactory = function(fieldDefs) {
+ var converter = {
+ fields: {}
+ };
+ for (var toField in fieldDefs) {
+ var d = fieldDefs[toField];
+ converter.fields[toField] = FieldType[d.type](d.fromFields, d.options);
+ }
+ return converter;
+}
View
1  api/import/conversion/point/base.js
@@ -134,3 +134,4 @@ this.fields = {
return null;
}
};
+
View
22 server.js
@@ -39,8 +39,6 @@ app.configure(function() {
app.set('views', path.join(application_root, "views"));
});
-utils.connectDB();
-
var API = require('./api');
new API(app);
@@ -157,16 +155,18 @@ app.get(/^\/([a-zA-Z0-9\-\_]+)(\/(globe|map|setup)(:[^\/]*)?)?(\/[0-9\-\.,]*)?$/
});
-// Load templates and start listening
+// Connect DB, load templates and start listening
-utils.loadFiles(['public/base.html'], __dirname, function(err, contents) {
- if (err) {
- throw err;
- } else {
- templates = contents;
- app.listen(port, "0.0.0.0");
- console.success('Web server running at http://0.0.0.0:' + port + "/");
- }
+utils.connectDB(function() {
+ utils.loadFiles(['public/base.html'], __dirname, function(err, contents) {
+ if (err) {
+ throw err;
+ } else {
+ templates = contents;
+ app.listen(port, "0.0.0.0");
+ console.success('Web server running at http://0.0.0.0:' + port + "/");
+ }
+ });
});
process.on('uncaughtException', function(err) {
View
2  utils.js
@@ -33,7 +33,7 @@ exports.connectDB = function(callback, exitProcessOnError)
* "%(foo)s, %(bar)s!".format({foo: 'Hello', bar: 'world'})
*/
String.prototype.format = function(replacements) {
- return this.replace(/\%\(([a-z0-9_]+)\)(s|i)/ig, function(match, name, type) {
+ return this.replace(/\%\((.+?)\)(s|i)/ig, function(match, name, type) {
return typeof replacements[name] != 'undefined'
? replacements[name]
: match;
Please sign in to comment.
Something went wrong with that request. Please try again.