blurts-server/ip-location-service.js

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
}