nwaku/tools/networkmonitor/networkmonitor_utils.nim

53 lines
1.5 KiB
Nim
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:
{.push raises: [].}
import
std/[json,httpclient],
chronicles,
chronicles/topics_registry,
chronos,
stew/results
type
NodeLocation = object
country*: string
city*: string
lat*: string
long*: string
isp*: string
proc flatten*[T](a: seq[seq[T]]): seq[T] =
var aFlat = newSeq[T](0)
for subseq in a:
aFlat &= subseq
return aFlat
# using an external api retrieves some data associated with the ip
# TODO: use a cache
# TODO: use nim-presto's HTTP asynchronous client
proc ipToLocation*(ip: string,
client: Httpclient):
Future[Result[NodeLocation, string]] {.async.} =
# naive mechanism to avoid hitting the rate limit
# IP-API endpoints are now limited to 45 HTTP requests per minute
await sleepAsync(1400)
try:
let content = client.getContent("http://ip-api.com/json/" & ip)
let jsonContent = parseJson(content)
if $jsonContent["status"].getStr() != "success":
error "query failed", result=jsonContent
return err("query failed: " & $jsonContent)
return ok(NodeLocation(
country: jsonContent["country"].getStr(),
city: jsonContent["city"].getStr(),
lat: jsonContent["lat"].getStr(),
long: jsonContent["lon"].getStr(),
isp: jsonContent["isp"].getStr()
))
except:
error "failed to get the location for IP", ip=ip, error=getCurrentExceptionMsg()
return err("failed to get the location for IP '" & ip & "':" & getCurrentExceptionMsg())