-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
115 lines (103 loc) · 3.18 KB
/
index.js
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
"use strict";
const fs = require("fs");
const csv = require("csv");
const path = require("path");
const async = require("async");
const request = require("request");
const prompt = require('prompt-sync')();
const client = new require('postcodesio-client')();
const argv = require('minimist')(process.argv);
const DEFAULT_SCHEMA = ["postcode", "longitude", "latitude"];
const onError = error => {
console.log(`An error occurred: ${error.message}`);
process.exit(1);
};
// Detect input file
const inputFile = argv.i;
if (!inputFile) {
let message = `
Please specify an input CSV file with the -i flag.
Please include postcode searches in the first column
`;
return onError(new Error(message));
}
const fullInputPath = path.resolve(inputFile);
try {
fs.statSync(inputFile)
} catch (e) {
let message = `Unable to find input file ${inputFile} (${fullInputPath})`
onError(new Error(message));
}
// Detect output file
const ouputFile = argv.o;
if (!ouputFile) {
let message = `
Please specify an output CSV file with the -o flag
`;
return onError(new Error(message));
}
const fullOutputPath = path.resolve(ouputFile);
// Detect Schema
let outputSchema = DEFAULT_SCHEMA;
const SCHEMA = argv.s;
if (SCHEMA) {
console.log("Custom CSV output schema detected");
outputSchema = SCHEMA.split(",");
}
// Detect postcode index
let postcodeColumnIndex = 0;
const COL_INDEX = argv.c;
if (COL_INDEX) {
console.log(`Custom CSV postcode column detected: ${COL_INDEX}`);
postcodeColumnIndex = parseInt(COL_INDEX, 10);
}
if (isNaN(postcodeColumnIndex)) {
let message = `
Invalid postcode column index specified
`;
onError(new Error(message));
}
// Get confirmation from user to proceed
console.log(`\nYou are about to initiate a script to lookup postcodes at: \n${fullInputPath}`);
console.log(`The output will be written as CSV to: \n${fullOutputPath}`);
console.log(`The output CSV schema will be: \n${outputSchema.join(", ")}\n`)
const confirmation = prompt("Type 'yes' to continue: ");
if (!confirmation.match(/yes/i)) {
console.log("You have opted to abort the script");
process.exit(0);
}
// Start retrieving data
const data = [];
fs.createReadStream(inputFile, { encoding: "utf8" })
.pipe(csv.parse({ delimiter: "," }))
.on("data", row => data.push(row[postcodeColumnIndex]))
.on("error", onError)
.on("end", () => {
console.log(`Loaded ${data.length} postcodes`);
console.log("Please wait while results are being retrieved from the API...");
let count = 0;
const toRow = (postcode, data) => {
return outputSchema.map(attr => {
if (attr === "postcode") return postcode;
if (data === null) return null;
return data[attr];
});
};
async.mapLimit(data, 5, (postcode, callback) => {
client.lookup(postcode, (error, result) => {
count += 1;
if (count > 0 && count % 10000 === 0) {
console.log(`${count} postcodes retrieved`);
}
return callback(error, toRow(postcode, result));
});
}, (error, output) => {
if (error) return onError(error);
csv.stringify(output, (error, data) => {
if (error) return onError(error);
fs.writeFileSync(ouputFile, data, { encoding: "utf8" });
console.log(`Completed retrieval. Results written to ${fullOutputPath}`);
process.exit(0);
});
});
});