@mountainpass/addressr 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/lib/ci/build.js +6 -3
- package/lib/ci/pipeline.js +12 -13
- package/lib/client/elasticsearch.js +13 -27
- package/lib/controllers/Addresses.js +0 -10
- package/lib/controllers/Default.js +2 -3
- package/lib/deploy/create-deployment-archive.js +0 -7
- package/lib/loader.js +0 -8
- package/lib/server.js +0 -6
- package/lib/service/DefaultService.js +3 -10
- package/lib/service/address-service.js +90 -258
- package/lib/service/printVersion.js +0 -8
- package/lib/service/setLinkOptions.js +0 -2
- package/lib/src/server2.js +0 -6
- package/lib/src/waycharterServer.js +1 -19
- package/lib/swagger.js +16 -35
- package/lib/utils/stream-down.js +6 -14
- package/lib/utils/writer.js +2 -9
- package/lib/version.js +1 -1
- package/package.json +2 -2
|
@@ -13,74 +13,41 @@ exports.searchForAddress = searchForAddress;
|
|
|
13
13
|
exports.loadGnaf = loadGnaf;
|
|
14
14
|
exports.getAddress = getAddress;
|
|
15
15
|
exports.getAddresses = getAddresses;
|
|
16
|
-
|
|
17
16
|
var _debug = require("debug");
|
|
18
|
-
|
|
19
17
|
var _debug2 = _interopRequireDefault(_debug);
|
|
20
|
-
|
|
21
18
|
var _directoryExists = require("directory-exists");
|
|
22
|
-
|
|
23
19
|
var _directoryExists2 = _interopRequireDefault(_directoryExists);
|
|
24
|
-
|
|
25
20
|
var _fs = require("fs");
|
|
26
|
-
|
|
27
21
|
var _fs2 = _interopRequireDefault(_fs);
|
|
28
|
-
|
|
29
22
|
var _got = require("got");
|
|
30
|
-
|
|
31
23
|
var _got2 = _interopRequireDefault(_got);
|
|
32
|
-
|
|
33
24
|
var _httpLinkHeader = require("http-link-header");
|
|
34
|
-
|
|
35
25
|
var _httpLinkHeader2 = _interopRequireDefault(_httpLinkHeader);
|
|
36
|
-
|
|
37
26
|
var _papaparse = require("papaparse");
|
|
38
|
-
|
|
39
27
|
var _papaparse2 = _interopRequireDefault(_papaparse);
|
|
40
|
-
|
|
41
28
|
var _path = require("path");
|
|
42
|
-
|
|
43
29
|
var _path2 = _interopRequireDefault(_path);
|
|
44
|
-
|
|
45
30
|
var _stream = require("stream");
|
|
46
|
-
|
|
47
31
|
var _stream2 = _interopRequireDefault(_stream);
|
|
48
|
-
|
|
49
32
|
var _unzipStream = require("unzip-stream");
|
|
50
|
-
|
|
51
33
|
var _unzipStream2 = _interopRequireDefault(_unzipStream);
|
|
52
|
-
|
|
53
34
|
var _elasticsearch = require("../client/elasticsearch");
|
|
54
|
-
|
|
55
35
|
var _streamDown = require("../utils/stream-down");
|
|
56
|
-
|
|
57
36
|
var _streamDown2 = _interopRequireDefault(_streamDown);
|
|
58
|
-
|
|
59
37
|
var _setLinkOptions = require("./setLinkOptions");
|
|
60
|
-
|
|
61
38
|
var _keyv = require("keyv");
|
|
62
|
-
|
|
63
39
|
var _keyv2 = _interopRequireDefault(_keyv);
|
|
64
|
-
|
|
65
40
|
var _keyvFile = require("keyv-file");
|
|
66
|
-
|
|
67
41
|
var _crypto = require("crypto");
|
|
68
|
-
|
|
69
42
|
var _crypto2 = _interopRequireDefault(_crypto);
|
|
70
|
-
|
|
71
43
|
var _globPromise = require("glob-promise");
|
|
72
|
-
|
|
73
44
|
var _globPromise2 = _interopRequireDefault(_globPromise);
|
|
74
|
-
|
|
75
45
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
76
|
-
|
|
77
46
|
/* eslint-disable eslint-comments/disable-enable-pair */
|
|
78
|
-
|
|
79
47
|
/* eslint-disable security/detect-non-literal-regexp */
|
|
80
|
-
|
|
81
48
|
/* eslint-disable security/detect-object-injection */
|
|
82
|
-
|
|
83
49
|
/* eslint-disable security/detect-non-literal-fs-filename */
|
|
50
|
+
|
|
84
51
|
const fsp = _fs2.default.promises;
|
|
85
52
|
var logger = (0, _debug2.default)('api');
|
|
86
53
|
var error = (0, _debug2.default)('error');
|
|
@@ -90,37 +57,26 @@ const cache = new _keyv2.default({
|
|
|
90
57
|
})
|
|
91
58
|
});
|
|
92
59
|
const PAGE_SIZE = process.env.PAGE_SIZE || 8;
|
|
93
|
-
|
|
94
60
|
function getCoveredStates() {
|
|
95
61
|
const covered = process.env.COVERED_STATES || '';
|
|
96
|
-
|
|
97
62
|
if (covered == '') {
|
|
98
63
|
return [];
|
|
99
64
|
} else {
|
|
100
65
|
return covered.split(',');
|
|
101
66
|
}
|
|
102
67
|
}
|
|
103
|
-
|
|
104
68
|
const COVERED_STATES = getCoveredStates();
|
|
105
|
-
const ONE_DAY_S = 60
|
|
106
|
-
/*sec*/
|
|
107
|
-
* 60
|
|
108
|
-
/*min*/
|
|
109
|
-
* 24;
|
|
110
|
-
/*hours*/
|
|
69
|
+
const ONE_DAY_S = 60 /*sec*/ * 60 /*min*/ * 24; /*hours*/
|
|
111
70
|
|
|
112
71
|
const ONE_DAY_MS = 1000 * ONE_DAY_S;
|
|
113
72
|
const THIRTY_DAYS_MS = ONE_DAY_MS * 30;
|
|
114
73
|
const ES_INDEX_NAME = process.env.ES_INDEX_NAME || 'addressr';
|
|
115
|
-
|
|
116
74
|
async function dropIndex() {
|
|
117
75
|
await (0, _elasticsearch.dropIndex)(global.esClient);
|
|
118
76
|
}
|
|
119
|
-
|
|
120
77
|
async function clearAddresses() {
|
|
121
78
|
await (0, _elasticsearch.initIndex)(global.esClient, true);
|
|
122
79
|
}
|
|
123
|
-
|
|
124
80
|
async function setAddresses(addr) {
|
|
125
81
|
await clearAddresses();
|
|
126
82
|
const indexingBody = [];
|
|
@@ -143,39 +99,36 @@ async function setAddresses(addr) {
|
|
|
143
99
|
confidence: structurted.structurted.confidence
|
|
144
100
|
});
|
|
145
101
|
});
|
|
146
|
-
|
|
147
102
|
if (indexingBody.length > 0) {
|
|
148
103
|
await sendIndexRequest(indexingBody);
|
|
149
|
-
}
|
|
104
|
+
}
|
|
105
|
+
// addresses = addr;
|
|
150
106
|
// empty index
|
|
151
107
|
// then index the provided addresses
|
|
152
|
-
//logger(await searchForAddress('657 The Entrance Road')); //'2/25 TOTTERDE'; // 'UNT 2, BELCONNEN';);
|
|
153
108
|
|
|
154
|
-
|
|
155
|
-
|
|
109
|
+
//logger(await searchForAddress('657 The Entrance Road')); //'2/25 TOTTERDE'; // 'UNT 2, BELCONNEN';);
|
|
110
|
+
}
|
|
156
111
|
|
|
112
|
+
// need to try proxying this to modify the headers if we want to use got's cache implementation
|
|
157
113
|
|
|
114
|
+
// SEE https://data.gov.au/data/dataset/19432f89-dc3a-4ef3-b943-5326ef1dbecc
|
|
158
115
|
const GNAF_PACKAGE_URL = process.env.GNAF_PACKAGE_URL || 'https://data.gov.au/api/3/action/package_show?id=19432f89-dc3a-4ef3-b943-5326ef1dbecc';
|
|
159
|
-
|
|
160
116
|
async function fetchPackageData() {
|
|
161
|
-
const packageUrl = GNAF_PACKAGE_URL;
|
|
162
|
-
|
|
117
|
+
const packageUrl = GNAF_PACKAGE_URL;
|
|
118
|
+
// See if we have the value in cache
|
|
163
119
|
const cachedResponse = await cache.get(packageUrl);
|
|
164
120
|
logger('cached gnaf package data', cachedResponse);
|
|
165
121
|
let age = 0;
|
|
166
|
-
|
|
167
122
|
if (cachedResponse !== undefined) {
|
|
168
123
|
cachedResponse.headers['x-cache'] = 'HIT';
|
|
169
124
|
const created = new Date(cachedResponse.headers.date);
|
|
170
125
|
logger('created', created);
|
|
171
126
|
age = Date.now() - created;
|
|
172
|
-
|
|
173
127
|
if (age <= ONE_DAY_MS) {
|
|
174
128
|
return cachedResponse;
|
|
175
129
|
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
130
|
+
}
|
|
131
|
+
// cached value was older than one day, so go fetch
|
|
179
132
|
try {
|
|
180
133
|
const response = await _got2.default.get(packageUrl);
|
|
181
134
|
logger('response.isFromCache', response.fromCache);
|
|
@@ -196,27 +149,23 @@ async function fetchPackageData() {
|
|
|
196
149
|
cachedResponse.headers['warning'] = '110 custom/1.0 "Response is Stale"';
|
|
197
150
|
return cachedResponse;
|
|
198
151
|
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
|
|
152
|
+
}
|
|
153
|
+
// otherwise, throw the original network error
|
|
202
154
|
throw error_;
|
|
203
155
|
}
|
|
204
156
|
}
|
|
205
|
-
|
|
206
157
|
const GNAF_DIR = process.env.GNAF_DIR || `target/gnaf`;
|
|
207
|
-
|
|
208
158
|
async function fetchGnafFile() {
|
|
209
159
|
const response = await fetchPackageData();
|
|
210
|
-
const pack = JSON.parse(response.body);
|
|
211
|
-
|
|
212
|
-
const dataResource = pack.result.resources.find(r => r.state === 'active' && r.mimetype === 'application/zip');
|
|
160
|
+
const pack = JSON.parse(response.body);
|
|
161
|
+
// id as of 16/07 for zip is 4b084096-65e4-4c8e-abbe-5e54ff85f42f
|
|
162
|
+
const dataResource = pack.result.resources.find(r => r.state === 'active' && r.mimetype === 'application/zip');
|
|
213
163
|
|
|
164
|
+
// id as of 16/07/2019 for zip is 4b084096-65e4-4c8e-abbe-5e54ff85f42f
|
|
214
165
|
logger('dataResource', JSON.stringify(dataResource, undefined, 2));
|
|
215
166
|
logger('url', dataResource.url);
|
|
216
167
|
logger('headers', JSON.stringify(response.headers, undefined, 2));
|
|
217
|
-
|
|
218
168
|
const basename = _path2.default.basename(dataResource.url);
|
|
219
|
-
|
|
220
169
|
logger('basename', basename);
|
|
221
170
|
const complete_path = GNAF_DIR;
|
|
222
171
|
const incomplete_path = `${complete_path}/incomplete`;
|
|
@@ -234,20 +183,19 @@ async function fetchGnafFile() {
|
|
|
234
183
|
}, error_ => {
|
|
235
184
|
if (error_) reject(error_);else resolve();
|
|
236
185
|
});
|
|
237
|
-
});
|
|
238
|
-
|
|
186
|
+
});
|
|
187
|
+
// see if the file exists already
|
|
239
188
|
try {
|
|
240
189
|
await new Promise((resolve, reject) => {
|
|
241
190
|
_fs2.default.access(destination, _fs2.default.constants.R_OK, error_ => {
|
|
242
191
|
if (error_) reject(error_);else resolve();
|
|
243
192
|
});
|
|
244
|
-
});
|
|
245
|
-
|
|
193
|
+
});
|
|
194
|
+
// it does exist, so don't bother trying to download it again
|
|
246
195
|
return destination;
|
|
247
196
|
} catch {
|
|
248
197
|
// file doesn't exist, so we need to download it.
|
|
249
198
|
logger('Starting G-NAF download');
|
|
250
|
-
|
|
251
199
|
try {
|
|
252
200
|
await (0, _streamDown2.default)(dataResource.url, `${incomplete_path}/${basename}`, dataResource.size);
|
|
253
201
|
await fsp.rename(`${incomplete_path}/${basename}`, destination);
|
|
@@ -259,19 +207,15 @@ async function fetchGnafFile() {
|
|
|
259
207
|
}
|
|
260
208
|
}
|
|
261
209
|
}
|
|
262
|
-
|
|
263
210
|
async function unzipFile(file) {
|
|
264
211
|
const extname = _path2.default.extname(file);
|
|
265
|
-
|
|
266
212
|
const basenameWithoutExtention = _path2.default.basename(file, extname);
|
|
267
|
-
|
|
268
213
|
const incomplete_path = `${GNAF_DIR}/incomplete/${basenameWithoutExtention}`;
|
|
269
214
|
const complete_path = `${GNAF_DIR}/${basenameWithoutExtention}`;
|
|
270
215
|
const exists = await (0, _directoryExists2.default)(complete_path);
|
|
271
|
-
|
|
272
216
|
if (exists) {
|
|
273
|
-
logger('directory exits. Skipping extract', complete_path);
|
|
274
|
-
|
|
217
|
+
logger('directory exits. Skipping extract', complete_path);
|
|
218
|
+
// already extracted. Move along.
|
|
275
219
|
return complete_path;
|
|
276
220
|
} else {
|
|
277
221
|
await new Promise((resolve, reject) => {
|
|
@@ -281,16 +225,13 @@ async function unzipFile(file) {
|
|
|
281
225
|
if (error_) reject(error_);else resolve();
|
|
282
226
|
});
|
|
283
227
|
});
|
|
284
|
-
|
|
285
228
|
const readStream = _fs2.default.createReadStream(file);
|
|
286
|
-
|
|
287
229
|
logger('before pipe');
|
|
288
230
|
let prom = new Promise((resolve, reject) => {
|
|
289
231
|
readStream.pipe(_unzipStream2.default.Parse()).pipe(_stream2.default.Transform({
|
|
290
232
|
objectMode: true,
|
|
291
233
|
transform: function (entry, encoding, callback) {
|
|
292
234
|
const entryPath = `${incomplete_path}/${entry.path}`;
|
|
293
|
-
|
|
294
235
|
if (entry.isDirectory) {
|
|
295
236
|
_fs2.default.mkdir(entryPath, {
|
|
296
237
|
recursive: true
|
|
@@ -305,7 +246,6 @@ async function unzipFile(file) {
|
|
|
305
246
|
});
|
|
306
247
|
} else {
|
|
307
248
|
const dirname = _path2.default.dirname(entryPath);
|
|
308
|
-
|
|
309
249
|
_fs2.default.mkdir(dirname, {
|
|
310
250
|
recursive: true
|
|
311
251
|
}, error_ => {
|
|
@@ -320,7 +260,6 @@ async function unzipFile(file) {
|
|
|
320
260
|
callback(error_);
|
|
321
261
|
return;
|
|
322
262
|
}
|
|
323
|
-
|
|
324
263
|
if (stats != undefined && stats.size === entry.size) {
|
|
325
264
|
// no need to extract again. Skip
|
|
326
265
|
logger('skipping extract for', entryPath);
|
|
@@ -357,120 +296,95 @@ async function unzipFile(file) {
|
|
|
357
296
|
});
|
|
358
297
|
});
|
|
359
298
|
}
|
|
360
|
-
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// function cleanProperty(p, v) {
|
|
361
302
|
// v !== '' && {
|
|
362
303
|
// [p]: v,
|
|
363
304
|
// };
|
|
364
305
|
// }
|
|
365
306
|
|
|
366
|
-
|
|
367
307
|
function levelTypeCodeToName(code, context, address) {
|
|
368
308
|
const found = context['Authority_Code_LEVEL_TYPE_AUT_psv'].find(entry => entry.CODE === code);
|
|
369
|
-
|
|
370
309
|
if (found) {
|
|
371
310
|
return found.NAME;
|
|
372
311
|
}
|
|
373
|
-
|
|
374
312
|
error(`Unknown Level Type Code: '${code}'`);
|
|
375
313
|
error({
|
|
376
314
|
address
|
|
377
315
|
});
|
|
378
316
|
return;
|
|
379
317
|
}
|
|
380
|
-
|
|
381
318
|
function flatTypeCodeToName(code, context, address) {
|
|
382
319
|
const found = context['Authority_Code_FLAT_TYPE_AUT_psv'].find(entry => entry.CODE === code);
|
|
383
|
-
|
|
384
320
|
if (found) {
|
|
385
321
|
return found.NAME;
|
|
386
322
|
}
|
|
387
|
-
|
|
388
323
|
error(`Unknown Flat Type Code: '${code}'`);
|
|
389
324
|
error({
|
|
390
325
|
address
|
|
391
326
|
});
|
|
392
327
|
return;
|
|
393
328
|
}
|
|
394
|
-
|
|
395
329
|
function streetTypeCodeToName(code, context) {
|
|
396
330
|
const found = context['Authority_Code_STREET_TYPE_AUT_psv'].find(entry => entry.CODE === code);
|
|
397
|
-
|
|
398
331
|
if (found) {
|
|
399
332
|
return found.NAME;
|
|
400
333
|
}
|
|
401
|
-
|
|
402
334
|
error(`Unknown Street Type Code: '${code}'`);
|
|
403
335
|
return;
|
|
404
336
|
}
|
|
405
|
-
|
|
406
337
|
function streetClassCodeToName(code, context) {
|
|
407
338
|
const found = context['Authority_Code_STREET_CLASS_AUT_psv'].find(entry => entry.CODE === code);
|
|
408
|
-
|
|
409
339
|
if (found) {
|
|
410
340
|
return found.NAME;
|
|
411
341
|
}
|
|
412
|
-
|
|
413
342
|
error(`Unknown Street Class Code: '${code}'`);
|
|
414
343
|
return;
|
|
415
344
|
}
|
|
416
|
-
|
|
417
345
|
function localityClassCodeToName(code, context) {
|
|
418
346
|
const found = context['Authority_Code_LOCALITY_CLASS_AUT_psv'].find(entry => entry.CODE === code);
|
|
419
|
-
|
|
420
347
|
if (found) {
|
|
421
348
|
return found.NAME;
|
|
422
349
|
}
|
|
423
|
-
|
|
424
350
|
error(`Unknown Locality Class Code: '${code}'`);
|
|
425
351
|
return;
|
|
426
352
|
}
|
|
427
|
-
|
|
428
353
|
function streetSuffixCodeToName(code, context) {
|
|
429
354
|
const found = context['Authority_Code_STREET_SUFFIX_AUT_psv'].find(entry => entry.CODE === code);
|
|
430
|
-
|
|
431
355
|
if (found) {
|
|
432
356
|
return found.NAME;
|
|
433
357
|
}
|
|
434
|
-
|
|
435
358
|
error(`Unknown Street Suffix Code: '${code}'`);
|
|
436
359
|
return;
|
|
437
360
|
}
|
|
438
|
-
|
|
439
361
|
function geocodeReliabilityCodeToName(code, context) {
|
|
440
362
|
const found = context['Authority_Code_GEOCODE_RELIABILITY_AUT_psv'].find(entry => entry.CODE === code);
|
|
441
|
-
|
|
442
363
|
if (found) {
|
|
443
364
|
return found.NAME;
|
|
444
365
|
}
|
|
445
|
-
|
|
446
366
|
error(`Unknown Geocode Reliability Code: '${code}'`);
|
|
447
367
|
return;
|
|
448
368
|
}
|
|
449
|
-
|
|
450
369
|
function geocodeTypeCodeToName(code, context) {
|
|
451
370
|
const found = context['Authority_Code_GEOCODE_TYPE_AUT_psv'].find(entry => entry.CODE === code);
|
|
452
|
-
|
|
453
371
|
if (found) {
|
|
454
372
|
return found.NAME;
|
|
455
373
|
}
|
|
456
|
-
|
|
457
374
|
error(`Unknown Geocode Type Code: '${code}'`);
|
|
458
375
|
return;
|
|
459
376
|
}
|
|
460
|
-
|
|
461
377
|
function levelGeocodedCodeToName(code, context) {
|
|
462
378
|
const found = context['Authority_Code_GEOCODED_LEVEL_TYPE_AUT_psv'].find(entry => entry.CODE === code);
|
|
463
|
-
|
|
464
379
|
if (found) {
|
|
465
380
|
return found.NAME;
|
|
466
381
|
}
|
|
467
|
-
|
|
468
382
|
error(`Unknown Geocoded Level Type Code: '${code}' in:\n${JSON.stringify(context['Authority_Code_GEOCODED_LEVEL_TYPE_AUT_psv'], undefined, 2)}`);
|
|
469
383
|
return;
|
|
470
384
|
}
|
|
471
|
-
|
|
472
385
|
function mapLocality(l, context) {
|
|
473
|
-
return {
|
|
386
|
+
return {
|
|
387
|
+
...(l.LOCALITY_NAME !== '' && {
|
|
474
388
|
name: l.LOCALITY_NAME
|
|
475
389
|
}),
|
|
476
390
|
...(l.LOCALITY_CLASS_CODE !== '' && {
|
|
@@ -481,9 +395,9 @@ function mapLocality(l, context) {
|
|
|
481
395
|
})
|
|
482
396
|
};
|
|
483
397
|
}
|
|
484
|
-
|
|
485
398
|
function mapStreetLocality(l, context) {
|
|
486
|
-
return {
|
|
399
|
+
return {
|
|
400
|
+
...(l.STREET_NAME !== '' && {
|
|
487
401
|
name: l.STREET_NAME
|
|
488
402
|
}),
|
|
489
403
|
...(l.STREET_TYPE_CODE !== '' && {
|
|
@@ -506,10 +420,8 @@ function mapStreetLocality(l, context) {
|
|
|
506
420
|
})
|
|
507
421
|
};
|
|
508
422
|
}
|
|
509
|
-
|
|
510
423
|
function mapGeo(geoSite, context, geoDefault) {
|
|
511
424
|
let foundDefault = false;
|
|
512
|
-
|
|
513
425
|
if (geoSite && geoDefault) {
|
|
514
426
|
geoSite.forEach(geo => {
|
|
515
427
|
if (geo.GEOCODE_TYPE_CODE === geoDefault[0].GEOCODE_TYPE_CODE && geo.LATITUDE === geoDefault[0].LATITUDE && geo.LONGITUDE === geoDefault[0].LONGITUDE) {
|
|
@@ -520,28 +432,23 @@ function mapGeo(geoSite, context, geoDefault) {
|
|
|
520
432
|
}
|
|
521
433
|
});
|
|
522
434
|
}
|
|
523
|
-
|
|
524
435
|
const sites = geoSite ? geoSite.map(geo => {
|
|
525
436
|
if (geo.BOUNDARY_EXTENT !== '') {
|
|
526
437
|
console.log('be', geo);
|
|
527
438
|
throw new Error('encounterd geo.BOUNDARY_EXTENT');
|
|
528
439
|
}
|
|
529
|
-
|
|
530
440
|
if (geo.PLANIMETRIC_ACCURACY !== '') {
|
|
531
441
|
console.log('pa', geo);
|
|
532
442
|
throw new Error('encounterd geo.PLANIMETRIC_ACCURACY');
|
|
533
443
|
}
|
|
534
|
-
|
|
535
444
|
if (geo.ELEVATION !== '') {
|
|
536
445
|
console.log('e', geo);
|
|
537
446
|
throw new Error('encounterd geo.ELEVATION');
|
|
538
447
|
}
|
|
539
|
-
|
|
540
448
|
if (geo.GEOCODE_SITE_NAME !== '') {
|
|
541
449
|
console.log('gsn', geo);
|
|
542
450
|
throw new Error('encounterd geo.GEOCODE_SITE_NAME');
|
|
543
451
|
}
|
|
544
|
-
|
|
545
452
|
return {
|
|
546
453
|
default: geo.default || false,
|
|
547
454
|
...(geo.GEOCODE_TYPE_CODE !== '' && {
|
|
@@ -586,105 +493,88 @@ function mapGeo(geoSite, context, geoDefault) {
|
|
|
586
493
|
}) : [];
|
|
587
494
|
return sites.concat(def);
|
|
588
495
|
}
|
|
589
|
-
|
|
590
496
|
function mapToSla(fla) {
|
|
591
497
|
return fla.join(', ');
|
|
592
|
-
}
|
|
593
|
-
|
|
498
|
+
}
|
|
594
499
|
|
|
500
|
+
// eslint-disable-next-line complexity
|
|
595
501
|
function mapToMla(s) {
|
|
596
502
|
const fla = [];
|
|
597
|
-
|
|
598
503
|
if (s.level) {
|
|
599
504
|
fla.push(`${s.level.type.name || ''} ${s.level.prefix || ''}${s.level.number || ''}${s.level.suffix || ''}`);
|
|
600
505
|
}
|
|
601
|
-
|
|
602
506
|
if (s.flat) {
|
|
603
507
|
fla.push(`${s.flat.type.name || ''} ${s.flat.prefix || ''}${s.flat.number || ''}${s.flat.suffix || ''}`);
|
|
604
508
|
}
|
|
605
|
-
|
|
606
509
|
if (s.buildingName) {
|
|
607
510
|
fla.push(s.buildingName);
|
|
608
511
|
}
|
|
609
|
-
|
|
610
512
|
if (fla.length === 3) {
|
|
611
513
|
fla[1] = `${fla[0]}, ${fla[1]}`;
|
|
612
514
|
fla.shift();
|
|
613
515
|
}
|
|
614
|
-
|
|
615
516
|
let number = '';
|
|
616
|
-
|
|
617
517
|
if (s.lotNumber && s.number === undefined) {
|
|
618
518
|
number = `LOT ${s.lotNumber.prefix || ''}${s.lotNumber.number || ''}${s.lotNumber.suffix || ''}`;
|
|
619
519
|
} else if (s.number) {
|
|
620
520
|
number = `${s.number.prefix || ''}${s.number.number || ''}${s.number.suffix || ''}`;
|
|
621
|
-
|
|
622
521
|
if (s.number.last) {
|
|
623
522
|
number = `${number}-${s.number.last.prefix || ''}${s.number.last.number || ''}${s.number.last.suffix || ''}`;
|
|
624
523
|
}
|
|
625
524
|
}
|
|
626
|
-
|
|
627
525
|
const streetType = s.street.type ? ` ${s.street.type.name}` : '';
|
|
628
526
|
const streetSuffix = s.street.suffix ? ` ${s.street.suffix.name}` : '';
|
|
629
527
|
const street = `${s.street.name}${streetType}${streetSuffix}`;
|
|
630
528
|
fla.push(`${number} ${street}`);
|
|
631
529
|
fla.push(`${s.locality.name} ${s.state.abbreviation} ${s.postcode}`);
|
|
632
|
-
|
|
633
530
|
if (fla.length > 4) {
|
|
634
531
|
logger('FLA TOO LONG', fla, s);
|
|
635
532
|
throw new Error('FLA TOO LONG');
|
|
636
533
|
}
|
|
637
|
-
|
|
638
534
|
return fla;
|
|
639
|
-
}
|
|
640
|
-
|
|
535
|
+
}
|
|
641
536
|
|
|
537
|
+
// eslint-disable-next-line complexity
|
|
642
538
|
function mapToShortMla(s) {
|
|
643
539
|
const fla = [];
|
|
644
|
-
|
|
645
540
|
if (s.level) {
|
|
646
541
|
fla.push(`${s.level.type.code || ''}${s.level.prefix || ''}${s.level.number || ''}${s.level.suffix || ''}`);
|
|
647
542
|
}
|
|
648
|
-
|
|
649
543
|
let number = '';
|
|
650
|
-
|
|
651
544
|
if (s.flat) {
|
|
652
545
|
number = `${s.flat.prefix || ''}${s.flat.number || ''}${s.flat.suffix || ''}/`;
|
|
653
546
|
}
|
|
654
|
-
|
|
655
547
|
if (s.lotNumber && s.number === undefined) {
|
|
656
548
|
number = `${number}${s.lotNumber.prefix || ''}${s.lotNumber.number || ''}${s.lotNumber.suffix || ''}`;
|
|
657
549
|
} else {
|
|
658
550
|
number = `${number}${s.number.prefix || ''}${s.number.number || ''}${s.number.suffix || ''}`;
|
|
659
|
-
|
|
660
551
|
if (s.number.last) {
|
|
661
552
|
number = `${number}-${s.number.last.prefix || ''}${s.number.last.number || ''}${s.number.last.suffix || ''}`;
|
|
662
553
|
}
|
|
663
554
|
}
|
|
664
|
-
|
|
665
555
|
const streetType = s.street.type ? ` ${s.street.type.name}` : '';
|
|
666
556
|
const streetSuffix = s.street.suffix ? ` ${s.street.suffix.code}` : '';
|
|
667
557
|
const street = `${s.street.name}${streetType}${streetSuffix}`;
|
|
668
558
|
fla.push(`${number} ${street}`);
|
|
669
559
|
fla.push(`${s.locality.name} ${s.state.abbreviation} ${s.postcode}`);
|
|
670
|
-
|
|
671
560
|
if (fla.length > 4) {
|
|
672
561
|
logger('FLA TOO LONG', fla, s);
|
|
673
562
|
throw new Error('FLA TOO LONG');
|
|
674
563
|
}
|
|
675
|
-
|
|
676
564
|
return fla;
|
|
677
|
-
}
|
|
678
|
-
|
|
565
|
+
}
|
|
679
566
|
|
|
567
|
+
// eslint-disable-next-line complexity
|
|
680
568
|
function mapAddressDetails(d, context, i, count) {
|
|
681
569
|
const streetLocality = context.streetLocalityIndexed[d.STREET_LOCALITY_PID];
|
|
682
570
|
const locality = context.localityIndexed[d.LOCALITY_PID];
|
|
683
571
|
const geoSite = context.geoIndexed ? context.geoIndexed[d.ADDRESS_SITE_PID] : undefined;
|
|
684
572
|
const geoDefault = context.geoDefaultIndexed ? context.geoDefaultIndexed[d.ADDRESS_DETAIL_PID] : undefined;
|
|
685
573
|
const hasGeo = d.LEVEL_GEOCODED_CODE != '' && (geoSite !== undefined && geoSite.length > 0 || geoDefault !== undefined && geoDefault.length > 0);
|
|
686
|
-
const rval = {
|
|
687
|
-
|
|
574
|
+
const rval = {
|
|
575
|
+
...(d.LEVEL_GEOCODED_CODE != '' && hasGeo && {
|
|
576
|
+
geocoding: {
|
|
577
|
+
...(d.LEVEL_GEOCODED_CODE !== '' && {
|
|
688
578
|
level: {
|
|
689
579
|
code: d.LEVEL_GEOCODED_CODE,
|
|
690
580
|
name: levelGeocodedCodeToName(d.LEVEL_GEOCODED_CODE, context)
|
|
@@ -695,11 +585,13 @@ function mapAddressDetails(d, context, i, count) {
|
|
|
695
585
|
})
|
|
696
586
|
}
|
|
697
587
|
}),
|
|
698
|
-
structured: {
|
|
588
|
+
structured: {
|
|
589
|
+
...(d.BUILDING_NAME !== '' && {
|
|
699
590
|
buildingName: d.BUILDING_NAME
|
|
700
591
|
}),
|
|
701
592
|
...((d.NUMBER_FIRST_PREFIX !== '' || d.NUMBER_FIRST !== '' || d.NUMBER_FIRST_SUFFIX !== '') && {
|
|
702
|
-
number: {
|
|
593
|
+
number: {
|
|
594
|
+
...(d.NUMBER_FIRST_PREFIX !== '' && {
|
|
703
595
|
prefix: d.NUMBER_FIRST_PREFIX
|
|
704
596
|
}),
|
|
705
597
|
...(d.NUMBER_FIRST !== '' && {
|
|
@@ -709,7 +601,8 @@ function mapAddressDetails(d, context, i, count) {
|
|
|
709
601
|
suffix: d.NUMBER_FIRST_SUFFIX
|
|
710
602
|
}),
|
|
711
603
|
...((d.NUMBER_LAST_PREFIX !== '' || d.NUMBER_LAST !== '' || d.NUMBER_LAST_SUFFIX !== '') && {
|
|
712
|
-
last: {
|
|
604
|
+
last: {
|
|
605
|
+
...(d.NUMBER_LAST_PREFIX !== '' && {
|
|
713
606
|
prefix: d.NUMBER_LAST_PREFIX
|
|
714
607
|
}),
|
|
715
608
|
...(d.NUMBER_LAST !== '' && {
|
|
@@ -723,7 +616,8 @@ function mapAddressDetails(d, context, i, count) {
|
|
|
723
616
|
}
|
|
724
617
|
}),
|
|
725
618
|
...((d.LEVEL_TYPE_CODE !== '' || d.LEVEL_NUMBER_PREFIX !== '' || d.LEVEL_NUMBER !== '' || d.LEVEL_NUMBER_SUFFIX !== '') && {
|
|
726
|
-
level: {
|
|
619
|
+
level: {
|
|
620
|
+
...(d.LEVEL_TYPE_CODE !== '' && {
|
|
727
621
|
type: {
|
|
728
622
|
code: d.LEVEL_TYPE_CODE,
|
|
729
623
|
name: levelTypeCodeToName(d.LEVEL_TYPE_CODE, context, d)
|
|
@@ -741,7 +635,8 @@ function mapAddressDetails(d, context, i, count) {
|
|
|
741
635
|
}
|
|
742
636
|
}),
|
|
743
637
|
...((d.FLAT_TYPE_CODE !== '' || d.FLAT_NUMBER_PREFIX !== '' || d.FLAT_NUMBER !== '' || d.FLAT_NUMBER_SUFFIX !== '') && {
|
|
744
|
-
flat: {
|
|
638
|
+
flat: {
|
|
639
|
+
...(d.FLAT_TYPE_CODE !== '' && {
|
|
745
640
|
type: {
|
|
746
641
|
code: d.FLAT_TYPE_CODE,
|
|
747
642
|
name: flatTypeCodeToName(d.FLAT_TYPE_CODE, context, d)
|
|
@@ -768,7 +663,8 @@ function mapAddressDetails(d, context, i, count) {
|
|
|
768
663
|
postcode: d.POSTCODE
|
|
769
664
|
}),
|
|
770
665
|
...((d.LOT_NUMBER_PREFIX !== '' || d.LOT_NUMBER !== '' || d.LOT_NUMBER_SUFFIX !== '') && {
|
|
771
|
-
lotNumber: {
|
|
666
|
+
lotNumber: {
|
|
667
|
+
...(d.LOT_NUMBER_PREFIX !== '' && {
|
|
772
668
|
prefix: d.LOT_NUMBER_PREFIX
|
|
773
669
|
}),
|
|
774
670
|
...(d.LOT_NUMBER !== '' && {
|
|
@@ -791,12 +687,10 @@ function mapAddressDetails(d, context, i, count) {
|
|
|
791
687
|
};
|
|
792
688
|
rval.mla = mapToMla(rval.structured);
|
|
793
689
|
rval.sla = mapToSla(rval.mla);
|
|
794
|
-
|
|
795
690
|
if (rval.structured.flat != undefined) {
|
|
796
691
|
rval.smla = mapToShortMla(rval.structured);
|
|
797
692
|
rval.ssla = mapToSla(rval.smla);
|
|
798
693
|
}
|
|
799
|
-
|
|
800
694
|
if (count) {
|
|
801
695
|
if (i % Math.ceil(count / 100) === 0) {
|
|
802
696
|
logger('addr', JSON.stringify(rval, undefined, 2));
|
|
@@ -808,10 +702,8 @@ function mapAddressDetails(d, context, i, count) {
|
|
|
808
702
|
logger(`${i} rows`);
|
|
809
703
|
}
|
|
810
704
|
}
|
|
811
|
-
|
|
812
705
|
return rval;
|
|
813
706
|
}
|
|
814
|
-
|
|
815
707
|
async function loadAddressDetails(file, expectedCount, context, {
|
|
816
708
|
refresh = false
|
|
817
709
|
} = {}) {
|
|
@@ -824,14 +716,12 @@ async function loadAddressDetails(file, expectedCount, context, {
|
|
|
824
716
|
chunk: function (chunk, parser) {
|
|
825
717
|
parser.pause();
|
|
826
718
|
const items = [];
|
|
827
|
-
|
|
828
719
|
if (chunk.errors.length > 0) {
|
|
829
720
|
error(`Errors reading '${file}': ${chunk.errors}`);
|
|
830
721
|
error({
|
|
831
722
|
errors: chunk.errors
|
|
832
723
|
});
|
|
833
724
|
}
|
|
834
|
-
|
|
835
725
|
const indexingBody = [];
|
|
836
726
|
chunk.data.forEach(row => {
|
|
837
727
|
const item = mapAddressDetails(row, context, actualCount, expectedCount);
|
|
@@ -855,7 +745,6 @@ async function loadAddressDetails(file, expectedCount, context, {
|
|
|
855
745
|
confidence: structured.structured.confidence
|
|
856
746
|
});
|
|
857
747
|
});
|
|
858
|
-
|
|
859
748
|
if (indexingBody.length > 0) {
|
|
860
749
|
sendIndexRequest(indexingBody, undefined, {
|
|
861
750
|
refresh
|
|
@@ -881,7 +770,8 @@ async function loadAddressDetails(file, expectedCount, context, {
|
|
|
881
770
|
// },
|
|
882
771
|
complete: function () {
|
|
883
772
|
logger('Address details loaded', context.state, expectedCount || '');
|
|
884
|
-
resolve();
|
|
773
|
+
resolve();
|
|
774
|
+
// global.esClient.indices
|
|
885
775
|
// .refresh({
|
|
886
776
|
// index: ['addressr'],
|
|
887
777
|
// })
|
|
@@ -904,12 +794,13 @@ async function loadAddressDetails(file, expectedCount, context, {
|
|
|
904
794
|
}
|
|
905
795
|
});
|
|
906
796
|
});
|
|
907
|
-
|
|
908
797
|
if (expectedCount !== undefined && actualCount != expectedCount) {
|
|
909
798
|
error(`Error loading '${file}'. Expected '${expectedCount}' rows, got '${actualCount}'`);
|
|
910
799
|
} else {
|
|
911
800
|
logger(`loaded '${actualCount}' rows from '${file}'`);
|
|
912
|
-
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// const BATCH_SIZE = 4096;
|
|
913
804
|
// const batches = Math.ceil(details.length / BATCH_SIZE);
|
|
914
805
|
// for (let j = 0; j < batches; j++) {
|
|
915
806
|
// logger(`INDEXING... batch ${j} of ${batches}`);
|
|
@@ -943,9 +834,7 @@ async function loadAddressDetails(file, expectedCount, context, {
|
|
|
943
834
|
// }
|
|
944
835
|
// }
|
|
945
836
|
//await searchForAddress('657 The Entrance Road'); //'2/25 TOTTERDE'; // 'UNT 2, BELCONNEN';);
|
|
946
|
-
|
|
947
837
|
}
|
|
948
|
-
|
|
949
838
|
async function searchForAddress(searchString, p, pageSize = PAGE_SIZE) {
|
|
950
839
|
// const searchString = '657 The Entrance Road'; //'2/25 TOTTERDE'; // 'UNT 2, BELCONNEN';
|
|
951
840
|
const searchResp = await global.esClient.search({
|
|
@@ -954,7 +843,8 @@ async function searchForAddress(searchString, p, pageSize = PAGE_SIZE) {
|
|
|
954
843
|
from: (p - 1 || 0) * pageSize,
|
|
955
844
|
size: pageSize,
|
|
956
845
|
query: {
|
|
957
|
-
bool: {
|
|
846
|
+
bool: {
|
|
847
|
+
...(searchString && {
|
|
958
848
|
should: [{
|
|
959
849
|
multi_match: {
|
|
960
850
|
fields: ['sla', 'ssla'],
|
|
@@ -1003,12 +893,11 @@ async function searchForAddress(searchString, p, pageSize = PAGE_SIZE) {
|
|
|
1003
893
|
logger('hits', JSON.stringify(searchResp.body.hits, undefined, 2));
|
|
1004
894
|
return searchResp;
|
|
1005
895
|
}
|
|
1006
|
-
|
|
1007
896
|
async function sendIndexRequest(indexingBody, initialBackoff = Number.parseInt(process.env.ADDRESSR_INDEX_BACKOFF || '30000'), {
|
|
1008
897
|
refresh = false
|
|
1009
898
|
} = {}) {
|
|
1010
|
-
let backoff = initialBackoff;
|
|
1011
|
-
|
|
899
|
+
let backoff = initialBackoff;
|
|
900
|
+
// eslint-disable-next-line no-constant-condition
|
|
1012
901
|
for (let count = 0; true; count++) {
|
|
1013
902
|
try {
|
|
1014
903
|
const resp = await global.esClient.bulk({
|
|
@@ -1016,9 +905,9 @@ async function sendIndexRequest(indexingBody, initialBackoff = Number.parseInt(p
|
|
|
1016
905
|
body: indexingBody,
|
|
1017
906
|
timeout: process.env.ADDRESSR_INDEX_TIMEOUT || '300s'
|
|
1018
907
|
});
|
|
1019
|
-
|
|
1020
908
|
if (resp.errors || resp.body && resp.body.errors) {
|
|
1021
|
-
throw resp;
|
|
909
|
+
throw resp;
|
|
910
|
+
// // error(resp);
|
|
1022
911
|
// // error(resp.items[0].index);
|
|
1023
912
|
// error(`backing off for ${backoff}ms`);
|
|
1024
913
|
// // parser.pause();
|
|
@@ -1031,18 +920,17 @@ async function sendIndexRequest(indexingBody, initialBackoff = Number.parseInt(p
|
|
|
1031
920
|
// });
|
|
1032
921
|
// backoff = Math.max(10000, backoff * 2);
|
|
1033
922
|
// continue;
|
|
1034
|
-
}
|
|
923
|
+
}
|
|
924
|
+
// if (paused) {
|
|
1035
925
|
// error(`resuming`);
|
|
1036
926
|
// parser.resume();
|
|
1037
927
|
// }
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
928
|
return;
|
|
1041
929
|
} catch (error_) {
|
|
1042
930
|
error('Indexing error', JSON.stringify(error_, undefined, 2));
|
|
1043
|
-
error(`backing off for ${backoff}ms`);
|
|
931
|
+
error(`backing off for ${backoff}ms`);
|
|
932
|
+
// parser.pause();
|
|
1044
933
|
// paused = true;
|
|
1045
|
-
|
|
1046
934
|
await new Promise(resolve => {
|
|
1047
935
|
// eslint-disable-next-line no-undef
|
|
1048
936
|
setTimeout(() => {
|
|
@@ -1056,7 +944,6 @@ async function sendIndexRequest(indexingBody, initialBackoff = Number.parseInt(p
|
|
|
1056
944
|
}
|
|
1057
945
|
}
|
|
1058
946
|
}
|
|
1059
|
-
|
|
1060
947
|
async function getStateName(abbr, file) {
|
|
1061
948
|
return await new Promise((resolve, reject) => {
|
|
1062
949
|
_papaparse2.default.parse(_fs2.default.createReadStream(file), {
|
|
@@ -1072,7 +959,6 @@ async function getStateName(abbr, file) {
|
|
|
1072
959
|
});
|
|
1073
960
|
});
|
|
1074
961
|
}
|
|
1075
|
-
|
|
1076
962
|
function mapAuthCodeTableToSynonymList(table) {
|
|
1077
963
|
return table.filter(type => {
|
|
1078
964
|
return type.CODE !== type.NAME;
|
|
@@ -1080,7 +966,6 @@ function mapAuthCodeTableToSynonymList(table) {
|
|
|
1080
966
|
return `${type.CODE} => ${type.NAME}`;
|
|
1081
967
|
});
|
|
1082
968
|
}
|
|
1083
|
-
|
|
1084
969
|
function buildSynonyms(context) {
|
|
1085
970
|
//example synonym format [
|
|
1086
971
|
// 'SUPER, super, superannuation',
|
|
@@ -1093,14 +978,11 @@ function buildSynonyms(context) {
|
|
|
1093
978
|
const synonyms = [...streetTypes, ...flatTypes, ...levelTypes, ...streetSuffixTypes];
|
|
1094
979
|
return synonyms;
|
|
1095
980
|
}
|
|
1096
|
-
|
|
1097
981
|
const {
|
|
1098
982
|
readdir
|
|
1099
983
|
} = require('fs').promises;
|
|
1100
|
-
|
|
1101
984
|
async function getFiles(currentDir, baseDir) {
|
|
1102
985
|
const dir = _path2.default.resolve(baseDir, currentDir);
|
|
1103
|
-
|
|
1104
986
|
logger(`reading ${dir} (${currentDir} in ${baseDir})`);
|
|
1105
987
|
const dirents = await readdir(dir, {
|
|
1106
988
|
withFileTypes: true
|
|
@@ -1111,11 +993,9 @@ async function getFiles(currentDir, baseDir) {
|
|
|
1111
993
|
}));
|
|
1112
994
|
return Array.prototype.concat(...files);
|
|
1113
995
|
}
|
|
1114
|
-
|
|
1115
996
|
function countFileLines(filePath) {
|
|
1116
997
|
return new Promise((resolve, reject) => {
|
|
1117
998
|
const readStream = _fs2.default.createReadStream(filePath, 'utf-8');
|
|
1118
|
-
|
|
1119
999
|
let lines = 0;
|
|
1120
1000
|
let last = undefined;
|
|
1121
1001
|
readStream.on('data', function (chunk) {
|
|
@@ -1126,7 +1006,6 @@ function countFileLines(filePath) {
|
|
|
1126
1006
|
if (last !== '\n') {
|
|
1127
1007
|
++lines;
|
|
1128
1008
|
}
|
|
1129
|
-
|
|
1130
1009
|
resolve(lines);
|
|
1131
1010
|
});
|
|
1132
1011
|
readStream.on('error', function (err) {
|
|
@@ -1134,15 +1013,14 @@ function countFileLines(filePath) {
|
|
|
1134
1013
|
});
|
|
1135
1014
|
});
|
|
1136
1015
|
}
|
|
1137
|
-
|
|
1138
1016
|
async function loadGnafData(directory, {
|
|
1139
1017
|
refresh = false
|
|
1140
1018
|
} = {}) {
|
|
1141
1019
|
const countsFile = `${directory}/Counts.csv`;
|
|
1142
1020
|
let countsFileExists = await fileExists(countsFile);
|
|
1143
1021
|
let filesCounts = {},
|
|
1144
|
-
|
|
1145
|
-
|
|
1022
|
+
files = [];
|
|
1023
|
+
// before may21 there was a counts file
|
|
1146
1024
|
if (countsFileExists) {
|
|
1147
1025
|
filesCounts = await loadFileCounts(countsFile);
|
|
1148
1026
|
files = Object.keys(filesCounts);
|
|
@@ -1150,53 +1028,46 @@ async function loadGnafData(directory, {
|
|
|
1150
1028
|
} else {
|
|
1151
1029
|
// may21 was missing the counts file
|
|
1152
1030
|
files = await getFiles('.', directory);
|
|
1153
|
-
|
|
1154
1031
|
for (const file of files) {
|
|
1155
1032
|
const lines = await countFileLines(`${directory}/${file}`);
|
|
1156
1033
|
filesCounts[file] = lines - 1;
|
|
1157
|
-
}
|
|
1034
|
+
}
|
|
1035
|
+
// const contentsFile = `${directory}/Contents.txt`
|
|
1158
1036
|
// const contentsFileExists = await fileExists(contentsFile)
|
|
1159
1037
|
// if (contentsFileExists) {
|
|
1160
1038
|
// files = await loadFileContents(contentsFile)
|
|
1161
1039
|
// } else {
|
|
1162
1040
|
// throw new Error(`Cannot file '${countsFile}' or '${contentsFile}'`)
|
|
1163
1041
|
// }
|
|
1164
|
-
|
|
1165
1042
|
}
|
|
1166
|
-
|
|
1167
1043
|
const loadContext = {};
|
|
1168
|
-
await loadAuthFiles(files, directory, loadContext, filesCounts);
|
|
1169
|
-
|
|
1044
|
+
await loadAuthFiles(files, directory, loadContext, filesCounts);
|
|
1045
|
+
// loadContext now contains all the auth files, so we can build the synonyms
|
|
1170
1046
|
const synonyms = buildSynonyms(loadContext);
|
|
1171
1047
|
await (0, _elasticsearch.initIndex)(global.esClient, process.env.ES_CLEAR_INDEX || false, synonyms);
|
|
1172
1048
|
const addressDetailFiles = files.filter(f => f.match(/ADDRESS_DETAIL/) && f.match(/\/Standard\//));
|
|
1173
1049
|
logger('addressDetailFiles', addressDetailFiles);
|
|
1174
|
-
|
|
1175
1050
|
for (const detailFile of addressDetailFiles) {
|
|
1176
1051
|
const state = _path2.default.basename(detailFile, _path2.default.extname(detailFile)).replace(/_.*/, '');
|
|
1177
|
-
|
|
1178
1052
|
if (COVERED_STATES.length === 0 || COVERED_STATES.includes(state)) {
|
|
1179
1053
|
loadContext.state = state;
|
|
1180
1054
|
loadContext.stateName = await loadState(files, directory, state);
|
|
1181
1055
|
logger('Loading streets', state);
|
|
1182
1056
|
const streetLocality = await loadStreetLocality(files, directory, state);
|
|
1183
1057
|
loadContext.streetLocalityIndexed = {};
|
|
1184
|
-
|
|
1185
1058
|
for (const sl of streetLocality) {
|
|
1186
1059
|
loadContext.streetLocalityIndexed[sl.STREET_LOCALITY_PID] = sl;
|
|
1187
1060
|
}
|
|
1188
|
-
|
|
1189
1061
|
logger('Loading suburbs', state);
|
|
1190
1062
|
const locality = await loadLocality(files, directory, state);
|
|
1191
1063
|
loadContext.localityIndexed = {};
|
|
1192
|
-
|
|
1193
1064
|
for (const l of locality) {
|
|
1194
1065
|
loadContext.localityIndexed[l.LOCALITY_PID] = l;
|
|
1195
1066
|
}
|
|
1196
|
-
|
|
1197
1067
|
if (process.env.ADDRESSR_ENABLE_GEO) {
|
|
1198
1068
|
loadContext.geoIndexed = {};
|
|
1199
|
-
await loadSiteGeo(files, directory, state, loadContext, filesCounts);
|
|
1069
|
+
await loadSiteGeo(files, directory, state, loadContext, filesCounts);
|
|
1070
|
+
// logger('indexing site geos', state, geo.length);
|
|
1200
1071
|
// for (let index = 0; index < geo.length; index++) {
|
|
1201
1072
|
// if (index % 10000 === 0) {
|
|
1202
1073
|
// logger(`${(index / geo.length) * 100.0}%`);
|
|
@@ -1214,14 +1085,12 @@ async function loadGnafData(directory, {
|
|
|
1214
1085
|
} else {
|
|
1215
1086
|
logger(`Skipping geos. set 'ADDRESSR_ENABLE_GEO' env var to enable`);
|
|
1216
1087
|
}
|
|
1217
|
-
|
|
1218
1088
|
await loadAddressDetails(`${directory}/${detailFile}`, filesCounts[detailFile], loadContext, {
|
|
1219
1089
|
refresh
|
|
1220
1090
|
});
|
|
1221
1091
|
}
|
|
1222
1092
|
}
|
|
1223
1093
|
}
|
|
1224
|
-
|
|
1225
1094
|
async function fileExists(countsFile) {
|
|
1226
1095
|
try {
|
|
1227
1096
|
await fsp.access(countsFile, _fs2.default.constants.F_OK);
|
|
@@ -1231,7 +1100,6 @@ async function fileExists(countsFile) {
|
|
|
1231
1100
|
return false;
|
|
1232
1101
|
}
|
|
1233
1102
|
}
|
|
1234
|
-
|
|
1235
1103
|
async function loadFileCounts(countsFile) {
|
|
1236
1104
|
const filesCounts = {};
|
|
1237
1105
|
await new Promise((resolve, reject) => {
|
|
@@ -1245,7 +1113,6 @@ async function loadFileCounts(countsFile) {
|
|
|
1245
1113
|
errors: row.errors
|
|
1246
1114
|
});
|
|
1247
1115
|
}
|
|
1248
|
-
|
|
1249
1116
|
const psvFile = row.data.File.replace(/\\/g, '/').replace(/\.zip$/, '.psv');
|
|
1250
1117
|
filesCounts[psvFile] = row.data.Count;
|
|
1251
1118
|
},
|
|
@@ -1262,15 +1129,12 @@ async function loadFileCounts(countsFile) {
|
|
|
1262
1129
|
logger('filesCounts', filesCounts);
|
|
1263
1130
|
return filesCounts;
|
|
1264
1131
|
}
|
|
1265
|
-
|
|
1266
1132
|
async function loadFileContents(contentsFile) {
|
|
1267
1133
|
const contents = await fsp.readFile(contentsFile);
|
|
1268
1134
|
return contents.toString().split('\n').map(line => line.trim());
|
|
1269
1135
|
}
|
|
1270
|
-
|
|
1271
1136
|
async function loadState(files, directory, state) {
|
|
1272
1137
|
const stateFile = files.find(f => f.match(new RegExp(`${state}_STATE_psv`)));
|
|
1273
|
-
|
|
1274
1138
|
if (stateFile === undefined) {
|
|
1275
1139
|
error(`Could not find state file '${state}_STATE_psv.psv'`);
|
|
1276
1140
|
return;
|
|
@@ -1279,10 +1143,8 @@ async function loadState(files, directory, state) {
|
|
|
1279
1143
|
return name;
|
|
1280
1144
|
}
|
|
1281
1145
|
}
|
|
1282
|
-
|
|
1283
1146
|
async function loadStreetLocality(files, directory, state) {
|
|
1284
1147
|
const localityFile = files.find(f => f.match(new RegExp(`${state}_STREET_LOCALITY_psv`)));
|
|
1285
|
-
|
|
1286
1148
|
if (localityFile === undefined) {
|
|
1287
1149
|
error(`Could not find street locality file '${state}_STREET_LOCALITY_psv.psv'`);
|
|
1288
1150
|
return [];
|
|
@@ -1302,10 +1164,8 @@ async function loadStreetLocality(files, directory, state) {
|
|
|
1302
1164
|
});
|
|
1303
1165
|
}
|
|
1304
1166
|
}
|
|
1305
|
-
|
|
1306
1167
|
async function loadLocality(files, directory, state) {
|
|
1307
1168
|
const localityFile = files.find(f => f.match(new RegExp(`${state}_LOCALITY_psv`)));
|
|
1308
|
-
|
|
1309
1169
|
if (localityFile === undefined) {
|
|
1310
1170
|
error(`Could not find locality file '${state}_LOCALITY_psv.psv'`);
|
|
1311
1171
|
return [];
|
|
@@ -1325,11 +1185,9 @@ async function loadLocality(files, directory, state) {
|
|
|
1325
1185
|
});
|
|
1326
1186
|
}
|
|
1327
1187
|
}
|
|
1328
|
-
|
|
1329
1188
|
async function loadSiteGeo(files, directory, state, loadContext, filesCounts) {
|
|
1330
1189
|
logger('Loading site geos');
|
|
1331
1190
|
const geoFile = files.find(f => f.match(new RegExp(`${state}_ADDRESS_SITE_GEOCODE_psv`)));
|
|
1332
|
-
|
|
1333
1191
|
if (geoFile === undefined) {
|
|
1334
1192
|
error(`Could not find address site geocode file '${state}_ADDRESS_SITE_GEOCODE_psv.psv'`);
|
|
1335
1193
|
return [];
|
|
@@ -1342,7 +1200,6 @@ async function loadSiteGeo(files, directory, state, loadContext, filesCounts) {
|
|
|
1342
1200
|
delimiter: '|',
|
|
1343
1201
|
chunk: function (chunk, parser) {
|
|
1344
1202
|
parser.pause();
|
|
1345
|
-
|
|
1346
1203
|
if (chunk.errors.length > 0) {
|
|
1347
1204
|
error(`Errors reading '${directory}/${geoFile}': ${chunk.errors}`);
|
|
1348
1205
|
error({
|
|
@@ -1355,15 +1212,12 @@ async function loadSiteGeo(files, directory, state, loadContext, filesCounts) {
|
|
|
1355
1212
|
logger(`${Math.floor(count / expectedCount * 100)}% (${count}/ ${expectedCount})`);
|
|
1356
1213
|
}
|
|
1357
1214
|
}
|
|
1358
|
-
|
|
1359
1215
|
const g = row;
|
|
1360
|
-
|
|
1361
1216
|
if (loadContext.geoIndexed[g.ADDRESS_SITE_PID] === undefined) {
|
|
1362
1217
|
loadContext.geoIndexed[g.ADDRESS_SITE_PID] = [g];
|
|
1363
1218
|
} else {
|
|
1364
1219
|
loadContext.geoIndexed[g.ADDRESS_SITE_PID].push(g);
|
|
1365
1220
|
}
|
|
1366
|
-
|
|
1367
1221
|
count += 1;
|
|
1368
1222
|
});
|
|
1369
1223
|
parser.resume();
|
|
@@ -1380,11 +1234,9 @@ async function loadSiteGeo(files, directory, state, loadContext, filesCounts) {
|
|
|
1380
1234
|
});
|
|
1381
1235
|
}
|
|
1382
1236
|
}
|
|
1383
|
-
|
|
1384
1237
|
async function loadDefaultGeo(files, directory, state, loadContext, filesCounts) {
|
|
1385
1238
|
logger('Loading default geos');
|
|
1386
1239
|
const geoFile = files.find(f => f.match(new RegExp(`${state}_ADDRESS_DEFAULT_GEOCODE_psv`)));
|
|
1387
|
-
|
|
1388
1240
|
if (geoFile === undefined) {
|
|
1389
1241
|
error(`Could not find address site geocode file '${state}_ADDRESS_DEFAULT_GEOCODE_psv.psv'`);
|
|
1390
1242
|
return [];
|
|
@@ -1397,7 +1249,6 @@ async function loadDefaultGeo(files, directory, state, loadContext, filesCounts)
|
|
|
1397
1249
|
delimiter: '|',
|
|
1398
1250
|
chunk: function (chunk, parser) {
|
|
1399
1251
|
parser.pause();
|
|
1400
|
-
|
|
1401
1252
|
if (chunk.errors.length > 0) {
|
|
1402
1253
|
error(`Errors reading '${directory}/${geoFile}': ${chunk.errors}`);
|
|
1403
1254
|
error({
|
|
@@ -1410,15 +1261,12 @@ async function loadDefaultGeo(files, directory, state, loadContext, filesCounts)
|
|
|
1410
1261
|
logger(`${Math.floor(count / expectedCount * 100)}% (${count}/ ${expectedCount})`);
|
|
1411
1262
|
}
|
|
1412
1263
|
}
|
|
1413
|
-
|
|
1414
1264
|
const g = row;
|
|
1415
|
-
|
|
1416
1265
|
if (loadContext.geoDefaultIndexed[g.ADDRESS_DETAIL_PID] === undefined) {
|
|
1417
1266
|
loadContext.geoDefaultIndexed[g.ADDRESS_DETAIL_PID] = [g];
|
|
1418
1267
|
} else {
|
|
1419
1268
|
loadContext.geoDefaultIndexed[g.ADDRESS_DETAIL_PID].push(g);
|
|
1420
1269
|
}
|
|
1421
|
-
|
|
1422
1270
|
count += 1;
|
|
1423
1271
|
});
|
|
1424
1272
|
parser.resume();
|
|
@@ -1435,21 +1283,17 @@ async function loadDefaultGeo(files, directory, state, loadContext, filesCounts)
|
|
|
1435
1283
|
});
|
|
1436
1284
|
}
|
|
1437
1285
|
}
|
|
1438
|
-
|
|
1439
1286
|
async function loadAuthFiles(files, directory, loadContext, filesCounts) {
|
|
1440
1287
|
const authCodeFiles = files.filter(f => f.match(/Authority Code/));
|
|
1441
1288
|
logger('authCodeFiles', authCodeFiles);
|
|
1442
|
-
|
|
1443
1289
|
for (const authFile of authCodeFiles) {
|
|
1444
1290
|
const contextKey = _path2.default.basename(authFile, _path2.default.extname(authFile));
|
|
1445
|
-
|
|
1446
1291
|
await new Promise((resolve, reject) => {
|
|
1447
1292
|
_papaparse2.default.parse(_fs2.default.createReadStream(`${directory}/${authFile}`), {
|
|
1448
1293
|
delimiter: '|',
|
|
1449
1294
|
header: true,
|
|
1450
1295
|
complete: function (results) {
|
|
1451
1296
|
loadContext[contextKey] = results.data;
|
|
1452
|
-
|
|
1453
1297
|
if (filesCounts) {
|
|
1454
1298
|
if (results.data.length != filesCounts[authFile]) {
|
|
1455
1299
|
error(`Error loading '${directory}/${authFile}'. Expected '${filesCounts[authFile]}' rows, got '${results.data.length}'`);
|
|
@@ -1467,10 +1311,8 @@ async function loadAuthFiles(files, directory, loadContext, filesCounts) {
|
|
|
1467
1311
|
});
|
|
1468
1312
|
});
|
|
1469
1313
|
}
|
|
1470
|
-
|
|
1471
1314
|
logger('AUTH', loadContext);
|
|
1472
1315
|
}
|
|
1473
|
-
|
|
1474
1316
|
async function loadGnaf({
|
|
1475
1317
|
refresh = false
|
|
1476
1318
|
} = {}) {
|
|
@@ -1479,27 +1321,23 @@ async function loadGnaf({
|
|
|
1479
1321
|
logger('Data dir', unzipped);
|
|
1480
1322
|
const contents = await fsp.readdir(unzipped);
|
|
1481
1323
|
logger('Data dir contents', contents);
|
|
1482
|
-
|
|
1483
1324
|
if (contents.length == 0) {
|
|
1484
1325
|
throw new Error(`Data dir '${unzipped}' is empty`);
|
|
1485
1326
|
}
|
|
1486
|
-
|
|
1487
1327
|
const gnafDir = await (0, _globPromise2.default)('**/G-NAF/', {
|
|
1488
1328
|
cwd: unzipped
|
|
1489
1329
|
});
|
|
1490
1330
|
console.log(gnafDir);
|
|
1491
|
-
|
|
1492
1331
|
if (gnafDir.length === 0) {
|
|
1493
1332
|
throw new Error(`Cannot find 'G-NAF' directory in Data dir '${unzipped}'`);
|
|
1494
1333
|
}
|
|
1495
|
-
|
|
1496
1334
|
const mainDirectory = _path2.default.dirname(`${unzipped}/${gnafDir[0].slice(0, -1)}`);
|
|
1497
|
-
|
|
1498
1335
|
logger('Main Data dir', mainDirectory);
|
|
1499
1336
|
await loadGnafData(mainDirectory, {
|
|
1500
1337
|
refresh
|
|
1501
1338
|
});
|
|
1502
1339
|
}
|
|
1340
|
+
|
|
1503
1341
|
/**
|
|
1504
1342
|
* Get Addresses
|
|
1505
1343
|
* returns detailed information about a specific address
|
|
@@ -1507,8 +1345,6 @@ async function loadGnaf({
|
|
|
1507
1345
|
* addressId String ID of the address.
|
|
1508
1346
|
* returns Address
|
|
1509
1347
|
**/
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
1348
|
async function getAddress(addressId) {
|
|
1513
1349
|
try {
|
|
1514
1350
|
const jsonX = await global.esClient.get({
|
|
@@ -1516,7 +1352,8 @@ async function getAddress(addressId) {
|
|
|
1516
1352
|
id: `/addresses/${addressId}`
|
|
1517
1353
|
});
|
|
1518
1354
|
logger('jsonX', jsonX);
|
|
1519
|
-
const json = {
|
|
1355
|
+
const json = {
|
|
1356
|
+
...jsonX.body._source.structured,
|
|
1520
1357
|
sla: jsonX.body._source.sla
|
|
1521
1358
|
};
|
|
1522
1359
|
logger('json', json);
|
|
@@ -1525,10 +1362,9 @@ async function getAddress(addressId) {
|
|
|
1525
1362
|
link.set({
|
|
1526
1363
|
rel: 'self',
|
|
1527
1364
|
uri: `/addresses/${addressId}`
|
|
1528
|
-
});
|
|
1529
|
-
|
|
1365
|
+
});
|
|
1366
|
+
// TODO: store hash in address
|
|
1530
1367
|
const hash = _crypto2.default.createHash('md5').update(JSON.stringify(json)).digest('hex');
|
|
1531
|
-
|
|
1532
1368
|
return {
|
|
1533
1369
|
link,
|
|
1534
1370
|
json,
|
|
@@ -1536,7 +1372,6 @@ async function getAddress(addressId) {
|
|
|
1536
1372
|
};
|
|
1537
1373
|
} catch (error_) {
|
|
1538
1374
|
error('error getting record from elastic search', error_);
|
|
1539
|
-
|
|
1540
1375
|
if (error_.body.found === false) {
|
|
1541
1376
|
return {
|
|
1542
1377
|
statusCode: 404,
|
|
@@ -1561,6 +1396,7 @@ async function getAddress(addressId) {
|
|
|
1561
1396
|
}
|
|
1562
1397
|
}
|
|
1563
1398
|
}
|
|
1399
|
+
|
|
1564
1400
|
/**
|
|
1565
1401
|
* Get List of Addresses
|
|
1566
1402
|
* returns a list of addresses matching the search string
|
|
@@ -1569,8 +1405,6 @@ async function getAddress(addressId) {
|
|
|
1569
1405
|
* p Integer page number (optional)
|
|
1570
1406
|
* returns List
|
|
1571
1407
|
**/
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
1408
|
async function getAddresses(url, swagger, q, p = 1) {
|
|
1575
1409
|
try {
|
|
1576
1410
|
const foundAddresses = await searchForAddress(q, p);
|
|
@@ -1582,7 +1416,8 @@ async function getAddresses(url, swagger, q, p = 1) {
|
|
|
1582
1416
|
title: `${swagger.path.get.operationId} API Docs`,
|
|
1583
1417
|
type: 'text/html'
|
|
1584
1418
|
});
|
|
1585
|
-
const sp = new URLSearchParams({
|
|
1419
|
+
const sp = new URLSearchParams({
|
|
1420
|
+
...(q !== undefined && {
|
|
1586
1421
|
q
|
|
1587
1422
|
}),
|
|
1588
1423
|
...(p !== 1 && {
|
|
@@ -1596,16 +1431,17 @@ async function getAddresses(url, swagger, q, p = 1) {
|
|
|
1596
1431
|
});
|
|
1597
1432
|
link.set({
|
|
1598
1433
|
rel: 'first',
|
|
1599
|
-
uri: `${url}${q === undefined ? '' : '?'}${new URLSearchParams({
|
|
1434
|
+
uri: `${url}${q === undefined ? '' : '?'}${new URLSearchParams({
|
|
1435
|
+
...(q !== undefined && {
|
|
1600
1436
|
q
|
|
1601
1437
|
})
|
|
1602
1438
|
}).toString()}`
|
|
1603
1439
|
});
|
|
1604
|
-
|
|
1605
1440
|
if (p > 1) {
|
|
1606
1441
|
link.set({
|
|
1607
1442
|
rel: 'prev',
|
|
1608
|
-
uri: `${url}${q === undefined && p == 2 ? '' : '?'}${new URLSearchParams({
|
|
1443
|
+
uri: `${url}${q === undefined && p == 2 ? '' : '?'}${new URLSearchParams({
|
|
1444
|
+
...(q !== undefined && {
|
|
1609
1445
|
q
|
|
1610
1446
|
}),
|
|
1611
1447
|
...(p > 2 && {
|
|
@@ -1614,22 +1450,20 @@ async function getAddresses(url, swagger, q, p = 1) {
|
|
|
1614
1450
|
}).toString()}`
|
|
1615
1451
|
});
|
|
1616
1452
|
}
|
|
1617
|
-
|
|
1618
1453
|
logger('TOTAL', foundAddresses.body.hits.total.value);
|
|
1619
1454
|
logger('PAGE_SIZE * p', PAGE_SIZE * p);
|
|
1620
1455
|
logger('next?', foundAddresses.body.hits.total.value > PAGE_SIZE * p);
|
|
1621
|
-
|
|
1622
1456
|
if (foundAddresses.body.hits.total.value > PAGE_SIZE * p) {
|
|
1623
1457
|
link.set({
|
|
1624
1458
|
rel: 'next',
|
|
1625
|
-
uri: `${url}?${new URLSearchParams({
|
|
1459
|
+
uri: `${url}?${new URLSearchParams({
|
|
1460
|
+
...(q !== undefined && {
|
|
1626
1461
|
q
|
|
1627
1462
|
}),
|
|
1628
1463
|
p: p + 1
|
|
1629
1464
|
}).toString()}`
|
|
1630
1465
|
});
|
|
1631
1466
|
}
|
|
1632
|
-
|
|
1633
1467
|
const responseBody = mapToSearchAddressResponse(foundAddresses);
|
|
1634
1468
|
logger('responseBody', JSON.stringify(responseBody, undefined, 2));
|
|
1635
1469
|
const linkTemplate = new _httpLinkHeader2.default();
|
|
@@ -1642,7 +1476,6 @@ async function getAddresses(url, swagger, q, p = 1) {
|
|
|
1642
1476
|
};
|
|
1643
1477
|
} catch (error_) {
|
|
1644
1478
|
error('error querying elastic search', error_);
|
|
1645
|
-
|
|
1646
1479
|
if (error_.body && error_.body.error && error_.body.error.type === 'index_not_found_exception') {
|
|
1647
1480
|
return {
|
|
1648
1481
|
statusCode: 503,
|
|
@@ -1667,7 +1500,6 @@ async function getAddresses(url, swagger, q, p = 1) {
|
|
|
1667
1500
|
}
|
|
1668
1501
|
}
|
|
1669
1502
|
}
|
|
1670
|
-
|
|
1671
1503
|
function mapToSearchAddressResponse(foundAddresses) {
|
|
1672
1504
|
return foundAddresses.body.hits.hits.map(h => {
|
|
1673
1505
|
return {
|