Skip to content

Instantly share code, notes, and snippets.

@JosephShering
Created November 1, 2017 23:53
Show Gist options
  • Save JosephShering/1cb85b7313cd7b3fd4cd251b608832b1 to your computer and use it in GitHub Desktop.
Save JosephShering/1cb85b7313cd7b3fd4cd251b608832b1 to your computer and use it in GitHub Desktop.
const request = require('request')
const xml2js = require('xml2js')
const json2csv = require('json2csv')
const zlib = require('zlib')
const unzip = require('unzip')
const AdmZip = require('adm-zip')
const zip = new require('node-zip');
const appID = `zu03iAaY4cdKd8iSHP6y`
const appCode = `9bWkk5oZyyE-ZIpp_xAUnA`
const submitURL = () => `https://batch.geocoder.cit.api.here.com/6.2/jobs
?action=run
&gen=8
&header=true
&indelim=%2C
&outdelim=%2C
&outcols=displayLatitude,displayLongitude
&outputCombined=false
&app_code=${appCode}
&app_id=${appID}`.replace(/\n/g, '')
const checkURL = (requestID) => `https://batch.geocoder.cit.api.here.com/6.2/jobs/${requestID}
?action=status
&app_id=${appID}
&app_code=${appCode}`.replace(/\n/g, '')
const getURL = (requestID) => `https://batch.geocoder.cit.api.here.com/6.2/jobs/${requestID}/result
?app_id=${appID}
&app_code=${appCode}`.replace(/\n/g, '')
const parser = new xml2js.Parser();
const headers = {
'Content-Type': 'text/plain'
}
function fetchResults(requestID) {
return new Promise((resolve, reject) => {
request({ url: getURL(requestID), headers: { 'Content-Type': 'application/zip' }}, (err, resp, respBody) => {
if(err) {
reject(err)
return false
}
if(resp.statusCode !== 200) {
reject(err)
return false
}
resolve(respBody)
})
})
}
function checkStatus(requestID) {
return new Promise((resolve, reject) => {
request({ url: checkURL(requestID), headers }, (err, resp, respBody) => {
if(err) {
reject(err)
return false
}
if(resp.statusCode !== 200) {
reject(err)
return false
}
resolve(respBody)
})
})
}
function timeoutCheckStatus(requestID) {
return new Promise((resolve, reject) => {
const interval = setInterval(() => {
checkStatus(requestID)
.then(parseXml)
.then(getStatus)
.then(status => {
if(status === 'completed') {
resolve(requestID)
clearInterval(interval)
}
})
.catch(reject)
}, 3000)
})
}
function submitLocations(body) {
return new Promise((resolve, reject) => {
request.post({ url: submitURL(), body, headers}, (err, resp, respBody) => {
if(err) {
reject(err)
return false
}
if(resp.statusCode !== 200) {
reject(err)
return false
}
resolve(respBody)
})
})
}
function createRequestBody(jobs) {
const locations = jobs.map((job, index) => {
const strIndex = `${index}`
return {
recId: job.id,
searchText: `${job.company} ${job.cityState}`,
country: 'USA'
}
})
const fields = ['recId', 'searchText', 'country'];
return json2csv({ data: locations, fields }).replace(/"/g, '')
}
function parseXml(xml) {
return new Promise((resolve, reject) => {
parser.parseString(xml, (err, res) => {
if(err) {
reject(err)
return false
}
resolve(res)
})
})
}
function unzipResult(resp) {
return new Promise((resolve, reject) => {
const zipped = zip(resp, {base64: true, checkCRC32: true})
resolve(zipped.files)
})
}
function getStatus(parsedXml) {
return new Promise((resolve, reject) => {
try {
resolve(parsedXml['ns2:SearchBatch']['Response'][0]['Status'][0])
} catch(ex) {
reject(ex)
}
})
}
function getRequestID(parsedXml) {
return new Promise((resolve, reject) => {
try {
resolve(parsedXml['ns2:SearchBatch']['Response'][0]['MetaInfo'][0]['RequestId'][0])
} catch(ex) {
reject(ex)
}
})
}
module.exports = {
createRequestBody,
submitLocations,
checkStatus,
parseXml,
getRequestID,
timeoutCheckStatus,
getStatus,
fetchResults,
unzipResult
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment