|
|
|
const fetch = require('cross-fetch'),
|
|
|
|
fs = require('fs'),
|
|
|
|
YAML = require('yaml'),
|
|
|
|
|
|
|
|
outFile = './cache/geo.yaml'
|
|
|
|
|
|
|
|
let object,
|
|
|
|
yaml,
|
|
|
|
result,
|
|
|
|
relayUrls = fs.readFileSync('./relays.yaml', 'utf8'),
|
|
|
|
geoCache = fs.readFileSync('./cache/geo.yaml', 'utf8'),
|
|
|
|
continents = fs.readFileSync('./cache/continents.json', 'utf8')
|
|
|
|
|
|
|
|
const getDns = async function(relay){
|
|
|
|
let dns
|
|
|
|
await fetch(`https://1.1.1.1/dns-query?name=${relay.replace('wss://', '')}`, { headers: { 'accept': 'application/dns-json' } })
|
|
|
|
.then(response => response.json())
|
|
|
|
.then((data) => { dns = data.Answer ? data.Answer : false })
|
|
|
|
.catch(err => //console.log('./scripts/geo.js', err))
|
|
|
|
return dns
|
|
|
|
}
|
|
|
|
|
|
|
|
const delay = async function(ms) {
|
|
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
|
|
}
|
|
|
|
|
|
|
|
const getIp = async function(dns){
|
|
|
|
let ip;
|
|
|
|
if(dns)
|
|
|
|
ip = dns[dns.length-1].data
|
|
|
|
return ip
|
|
|
|
}
|
|
|
|
|
|
|
|
const getGeo = async function(ip) {
|
|
|
|
let geo
|
|
|
|
await fetch(`http://ip-api.com/json/${ip}`, { headers: { 'accept': 'application/dns-json' } })
|
|
|
|
.then(response => response.json())
|
|
|
|
.then((data) => { geo = data })
|
|
|
|
.catch(err => console.error('./scripts/geo.js', err))
|
|
|
|
return geo;
|
|
|
|
}
|
|
|
|
|
|
|
|
const getContinent = function(countryCode) {
|
|
|
|
return JSON.parse(continents)
|
|
|
|
.filter( c => c.country_code == countryCode )
|
|
|
|
.map( cont => {
|
|
|
|
return {
|
|
|
|
continentCode: cont.continent_code,
|
|
|
|
continentName: cont.continent_name
|
|
|
|
}
|
|
|
|
})[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
const query = async function(){
|
|
|
|
|
|
|
|
const relays = YAML.parse(relayUrls).relays.reverse(),
|
|
|
|
result = YAML.parse(geoCache).geo || {}
|
|
|
|
|
|
|
|
for (const relay of relays) {
|
|
|
|
await delay(1000).then(async () => {
|
|
|
|
//console.log('getting relay geo', relay)
|
|
|
|
|
|
|
|
let dns, ip, geo
|
|
|
|
|
|
|
|
dns = await getDns(relay).catch()
|
|
|
|
ip = await getIp(dns).catch()
|
|
|
|
geo = await getGeo(ip).catch()
|
|
|
|
|
|
|
|
if(geo)
|
|
|
|
geo = Object.assign(geo, getContinent(geo.countryCode))
|
|
|
|
|
|
|
|
if(geo && dns)
|
|
|
|
geo.dns = dns[dns.length-1]
|
|
|
|
|
|
|
|
if(geo && geo.status == 'success') {
|
|
|
|
delete geo.status
|
|
|
|
result[relay] = geo
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!geo)
|
|
|
|
console.warn('api was mean, no geo for', relay)
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
const run = async function(){
|
|
|
|
result = await query()
|
|
|
|
object = { geo: result }
|
|
|
|
yaml = new YAML.Document()
|
|
|
|
yaml.contents = object
|
|
|
|
// //console.log(object)
|
|
|
|
fs.writeFile(outFile, yaml.toString(), (err) => {
|
|
|
|
if (err) return console.error('./scripts/geo.js', err);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
run()
|
|
|
|
|