2021-11-19 23:06:30 +03:00
"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 ] ) ] ;
2022-01-19 22:51:36 +03:00
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.
2021-11-19 23:06:30 +03:00
} 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 ,
} ;