| 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 |
1
1
1
1
1
59
59
312
312
59
59
59
1
41
38
38
17
21
21
38
38
1
2
2
36
36
36
2
1
1
1
1
1
18
18
1
| /*
* oy
*
* Copyright(c) 2013 Artur Cistov
* MIT Licensed
*/
var csv = require('csv');
var tt = require('timeTraveller');
var Parser = module.exports = {};
Parser.TYPES = [
{ name: 'admin', match: /^Entered and exited|^Topped-up|^Season ticket/ },
{ name: 'bus', match: /^Bus journey, route ([\d]*)$/ },
{ name: 'rail', match: /\[National Rail\]$/ },
{ name: 'overground', match: /\[London Overground\]$/ },
{ name: 'no_touchin', match: /^\[No touch-in\]$/ },
{ name: 'no_touchout', match: /^\[No touch-out\]$/ },
{ name: 'underground', match: /(^[\w\s()&,]*$|\[London Underground\]$)/ }
];
Parser.checkType = function(text) {
var typeName = '', i, type;
for(i = 0; i < this.TYPES.length; i++) {
type = this.TYPES[i];
if(text.match(type.match)) {
typeName = type.name;
break;
}
}
return typeName;
};
Parser.parseRow = function(row) {
if( row[0] && row[0] === 'Note' || !(row instanceof Array) ) { return null; }
var startDate = new Date(Date.parse(row[1] + ' ' + row[2])),
endDate = row[3] ? new Date(Date.parse(row[1] + ' ' + row[3])) : null,
duration = endDate ? new tt.TimeSpan(endDate, startDate) : new tt.TimeSpan(startDate, startDate),
description = (row[4] || '').trim(),
descriptionData = description.split(' to '),
from = {},
to = {},
journey;
if(descriptionData.length === 1) {
from = { text: description, type: this.checkType(descriptionData[0]) };
} else {
from = { text: descriptionData[0], type: this.checkType(descriptionData[0]) };
to = { text: descriptionData[1], type: this.checkType(descriptionData[1]) };
}
journey = {
note: row[0],
date: row[1],
startTime: row[2],
startDate: startDate,
endTime: row[3] || null,
endDate: endDate,
duration: duration,
description: description,
charge: Number(row[5] || 0),
credit: Number(row[6] || 0),
balance: Number(row[7] || 0),
to: to,
from: from
};
return journey;
};
Parser.getCSVData = function(input, cb) {
var rows = [];
csv()
.from(input)
.transform(function(row) {
row.unshift(row.pop());
return row;
})
.on('record', function(row) {
rows.push(row);
})
.on('end', function() {
cb(null, rows);
})
.on('error', cb);
};
Parser.parse = function(input, cb) {
var journeys = [];
this.getCSVData(input, function(err, rows) {
Iif(err) { return cb(err); }
rows.forEach(function(row) {
var journey = Parser.parseRow(row);
journeys.push(journey);
});
cb(null, journeys);
});
};
|