diff --git a/xmrnodes/cli.py b/xmrnodes/cli.py index 736eb12..29c9681 100644 --- a/xmrnodes/cli.py +++ b/xmrnodes/cli.py @@ -5,12 +5,11 @@ from time import sleep import geoip2.database import arrow import requests -import click from flask import Blueprint from urllib.parse import urlparse from xmrnodes.helpers import determine_crypto, is_onion, is_i2p, make_request -from xmrnodes.helpers import retrieve_peers, rw_cache, get_highest_block +from xmrnodes.helpers import retrieve_peers, rw_cache, get_highest_block, get_geoip from xmrnodes.models import Node, HealthCheck, Peer from xmrnodes import config @@ -176,7 +175,6 @@ def validate(): is_ssl = node.url.startswith("https://") nettype = r.json()["nettype"] crypto = determine_crypto(node.url) - logging.info("success") if nettype in ["mainnet", "stagenet", "testnet"]: node.nettype = nettype node.available = True @@ -187,7 +185,17 @@ def validate(): node.crypto = crypto node.is_tor = is_onion(node.url) node.is_i2p = is_i2p(node.url) + if not node.is_tor and not node.is_i2p: + geoip = get_geoip(node.url) + node.country_name = geoip.country.name + node.country_code = geoip.country.iso_code + node.city = geoip.city.name + node.postal = geoip.postal.code + node.lat = geoip.location.latitude + node.lon = geoip.location.longitude + logging.info(f"found geo data for {node.url} - {node.country_code}, {node.country_name}, {node.city}") node.save() + logging.info("success") else: logging.info("unexpected nettype") except requests.exceptions.ConnectTimeout: @@ -203,7 +211,7 @@ def validate(): logging.info("http error, 4xx or 5xx") node.delete_instance() except Exception as e: - logging.info("failed for reasons unknown") + logging.info(f"failed for reasons unknown: {e}") node.delete_instance() diff --git a/xmrnodes/helpers.py b/xmrnodes/helpers.py index 3c60a76..d14487e 100644 --- a/xmrnodes/helpers.py +++ b/xmrnodes/helpers.py @@ -3,7 +3,9 @@ import socket import pickle from os import path +import geoip2.database from requests import get as r_get +from urllib.parse import urlparse from levin.section import Section from levin.bucket import Bucket from levin.ctypes import * @@ -157,3 +159,11 @@ def get_highest_block(nettype, crypto): return highest.last_height else: return 0 + + +def get_geoip(ip_or_dns): + host = urlparse(ip_or_dns).netloc.split(':')[0] + resolved = socket.gethostbyname(host) + host = host if resolved == host else resolved + with geoip2.database.Reader("./data/GeoLite2-City.mmdb") as reader: + return reader.city(host) \ No newline at end of file diff --git a/xmrnodes/models.py b/xmrnodes/models.py index dce9f6d..672e09d 100644 --- a/xmrnodes/models.py +++ b/xmrnodes/models.py @@ -22,6 +22,12 @@ class Node(Model): last_height = IntegerField(null=True) crypto = CharField(null=True) donation_address = CharField(null=True) + country_name = CharField(null=True) + country_code = CharField(null=True) + city = CharField(null=True) + postal = IntegerField(null=True) + lat = FloatField(null=True) + lon = FloatField(null=True) datetime_entered = DateTimeField(default=datetime.utcnow) datetime_checked = DateTimeField(default=None, null=True) datetime_failed = DateTimeField(default=None, null=True)