mirror of
https://github.com/waku-org/nwaku.git
synced 2025-02-07 20:45:12 +00:00
53 lines
1.5 KiB
Nim
53 lines
1.5 KiB
Nim
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()) |