|
|
@@ -20,8 +20,10 @@ |
|
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
|
|
# SOFTWARE. |
|
|
|
|
|
|
|
import json |
|
|
|
import urllib2 |
|
|
|
from json import loads |
|
|
|
from socket import (AF_INET, AF_INET6, error as socket_error, gethostbyname, |
|
|
|
inet_pton) |
|
|
|
from urllib2 import urlopen |
|
|
|
|
|
|
|
from earwigbot.commands import Command |
|
|
|
|
|
|
@@ -40,10 +42,6 @@ class Geolocate(Command): |
|
|
|
self.logger.warn(log.format(self.name)) |
|
|
|
|
|
|
|
def process(self, data): |
|
|
|
if not data.args: |
|
|
|
self.reply(data, "Please specify an IP to lookup.") |
|
|
|
return |
|
|
|
|
|
|
|
if not self.key: |
|
|
|
msg = 'I need an API key for http://ipinfodb.com/ stored as \x0303config.commands["{0}"]["apiKey"]\x0F.' |
|
|
|
log = 'Need an API key for http://ipinfodb.com/ stored as config.commands["{0}"]["apiKey"]' |
|
|
@@ -51,10 +49,24 @@ class Geolocate(Command): |
|
|
|
self.logger.error(log.format(self.name)) |
|
|
|
return |
|
|
|
|
|
|
|
if data.args: |
|
|
|
address = data.args[0] |
|
|
|
else: |
|
|
|
try: |
|
|
|
address = gethostbyname(data.host) |
|
|
|
except socket_error: |
|
|
|
msg = "your hostname, \x0302{0}\x0F, is not an IP address!" |
|
|
|
self.reply(data, msg.format(data.host)) |
|
|
|
return |
|
|
|
address = data.args[0] |
|
|
|
if not self.is_ip(address): |
|
|
|
msg = "\x0302{0}\x0F is not an IP address!" |
|
|
|
self.reply(data, msg.format(address)) |
|
|
|
return |
|
|
|
|
|
|
|
url = "http://api.ipinfodb.com/v3/ip-city/?key={0}&ip={1}&format=json" |
|
|
|
query = urllib2.urlopen(url.format(self.key, address)).read() |
|
|
|
res = json.loads(query) |
|
|
|
query = urlopen(url.format(self.key, address)).read() |
|
|
|
res = loads(query) |
|
|
|
|
|
|
|
country = res["countryName"].title() |
|
|
|
region = res["regionName"].title() |
|
|
@@ -72,3 +84,17 @@ class Geolocate(Command): |
|
|
|
msg = "{0}, {1}, {2} ({3}, {4}), UTC {5}" |
|
|
|
geo = msg.format(country, region, city, latitude, longitude, utcoffset) |
|
|
|
self.reply(data, geo) |
|
|
|
|
|
|
|
def is_ip(self, address): |
|
|
|
"""Return ``True`` if the input is an IP address, else ``False``. |
|
|
|
|
|
|
|
This tests for IPv4 and IPv6 using :py:func:`socket.inet_pton`. |
|
|
|
""" |
|
|
|
try: |
|
|
|
inet_pton(AF_INET, address) |
|
|
|
except socket_error: |
|
|
|
try: |
|
|
|
inet_pton(AF_INET6, address) |
|
|
|
except socket_error: |
|
|
|
return False |
|
|
|
return True |