forked from lykmapipo/xls2xform
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
153 lines (123 loc) · 4.03 KB
/
index.js
File metadata and controls
153 lines (123 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
'use strict';
//dependencies
var path = require('path');
var _ = require('lodash');
var fs = require('fs');
var async = require('async');
var shell = require('python-shell');
var tmp = require('tmp');
tmp.setGracefulCleanup();
function fileExists(path, done) {
fs.stat(path, function(error) {
if (error) {
error = new Error('No such file or directory');
done(error);
} else {
done();
}
});
}
function normalizenResponseError(response) {
//normalize response
response =
_.isArray(response) ? _.first(response) : response;
//reference response code
var code = response.code || 999;
//reference row
var row;
//reference response messsage
var message = response && response.message ? response.message : '';
//process no type error
if (message.search(/Question with no type/g) > 0) {
//obtain row information
row = _.first(message.match(/\[.*?\]/g));
if (row) {
row = row.replace(/\[(.*?)\]/g, '$1');
row = row.replace(/row/g, '').replace(/:/g, '').trim();
}
//process question
var question =
message.replace(/Question with no type./g, '')
.replace(/\[.*?\]/g, '').replace(/u'/g, '"')
.replace(/'/g, '"').trim();
//parse question
question = JSON.parse(question);
//prepare message
message =
'Question with name ' + question.name + ' at row ' + row + ' has no associated type.';
}
//process Invalid question name error
if (message.search(/Invalid question name/g) > 0) {
//obtain row information
row = _.first(message.match(/\[.*?\]/g));
if (row) {
row = row.replace(/\[(.*?)\]/g, '$1');
row = row.replace(/row/g, '').replace(/:/g, '').trim();
}
//parse message
message =
message.replace(/\[(.*?)\]/g, '$1').replace(/row/, '')
.replace(/\d/g, '').replace(/:/, '')
.replace(/Names/, ' at row ' + row + '.Names').trim();
}
//process choices option with no name
if (_.startsWith(message, 'On the choices sheet there') || code === 101) {
//reset message
if (code === 101) {
message = _.first(response.warnings);
}
//obtain list
var list = _.first(message.match(/\[.*?\]/g));
if (list) {
list = list.replace(/\[(.*?)\]/g, '$1').split(':')[1].trim();
}
//parse message
message =
message.replace(/\[(.*?)\]/g, '')
.replace(/ there is a /, ', list ' + list + ' has an ').trim();
}
//if its error response
if (code !== 100) {
return new Error(message);
}
//else do nothing
else {
return null;
}
}
module.exports = function(xlsFormPath, done) {
//check if XLSForm path provided
if (!xlsFormPath || _.isFunction(xlsFormPath)) {
done = xlsFormPath;
var error = new Error('No XLSForm path provided');
done(error);
}
//continue with conversion
else {
//generate temp output path in os temporary directory
var outputPath = tmp.fileSync(Date.now() * (Math.random() * 9));
async.waterfall([
//validate if path exists
function xlsFormExists(next) {
fileExists(xlsFormPath, next);
},
//convert
function convert(next) {
shell.run('xls2xform.py', {
mode: 'json',
scriptPath: path.join(__dirname, 'python'),
args: [xlsFormPath, outputPath.name]
}, next);
},
//process response
function respond(response, next) {
var error = normalizenResponseError(response);
if (error) {
next(error);
} else {
fs.readFile(outputPath.name, 'utf-8', next);
}
}
], done);
}
};