55 строки
1.9 KiB
JavaScript
55 строки
1.9 KiB
JavaScript
'use strict'
|
|
|
|
const path = require('path')
|
|
const reader = require('@maxmind/geoip2-node').Reader
|
|
const AppConstants = require('./app-constants')
|
|
|
|
let locationDb, timestamp
|
|
|
|
async function openLocationDb () {
|
|
if (locationDb && isFresh()) return console.warn('Location database already open.')
|
|
|
|
try {
|
|
const dbPath = path.join(AppConstants.GEOIP_GEOLITE2_PATH, AppConstants.GEOIP_GEOLITE2_CITY_FILENAME)
|
|
locationDb = await reader.open(dbPath)
|
|
} catch (e) {
|
|
return console.warn('Could not open location database:', e.message)
|
|
}
|
|
|
|
timestamp = Date.now()
|
|
return true
|
|
}
|
|
|
|
async function readLocationData (ip, locales) {
|
|
let locationArr
|
|
|
|
if (!isFresh()) await openLocationDb()
|
|
|
|
try {
|
|
const data = locationDb.city(ip)
|
|
const countryName = data.country?.names[locales.find(locale => data.country?.names[locale])] // find valid locale key and return its value
|
|
const cityName = data.city?.names[locales.find(locale => data.city?.names[locale])]
|
|
const subdivisionName = data.subdivisions?.[0].isoCode
|
|
const subdivisionFiltered = /[A-z]{2,}/.test(subdivisionName) ? subdivisionName : null // return strings that are 2 or more letters, or null (avoid unfamiliar subdivisions like `E` or `09`)
|
|
|
|
locationArr = [cityName, subdivisionFiltered, countryName].filter(str => str) // [city name, state code, country code] with non-null items.
|
|
} catch (e) {
|
|
return console.warn('Could not read location from database:', e.message)
|
|
}
|
|
|
|
return {
|
|
shortLocation: locationArr.slice(0, 2).join(', '), // shows the first two location values from the ones available
|
|
fullLocation: locationArr.join(', ') // shows up to three location values from the ones available
|
|
}
|
|
}
|
|
|
|
function isFresh () {
|
|
if (Date.now() - timestamp < 259200000) return true // 1000ms * 60s * 60m * 24h * 3 elapsed time is less than 24hrs
|
|
return false
|
|
}
|
|
|
|
module.exports = {
|
|
openLocationDb,
|
|
readLocationData
|
|
}
|