| @@ -20,8 +20,10 @@ | |||||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| # SOFTWARE. | # 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 | from earwigbot.commands import Command | ||||
| @@ -40,10 +42,6 @@ class Geolocate(Command): | |||||
| self.logger.warn(log.format(self.name)) | self.logger.warn(log.format(self.name)) | ||||
| def process(self, data): | def process(self, data): | ||||
| if not data.args: | |||||
| self.reply(data, "Please specify an IP to lookup.") | |||||
| return | |||||
| if not self.key: | if not self.key: | ||||
| msg = 'I need an API key for http://ipinfodb.com/ stored as \x0303config.commands["{0}"]["apiKey"]\x0F.' | 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"]' | 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)) | self.logger.error(log.format(self.name)) | ||||
| return | 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] | 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" | 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() | country = res["countryName"].title() | ||||
| region = res["regionName"].title() | region = res["regionName"].title() | ||||
| @@ -72,3 +84,17 @@ class Geolocate(Command): | |||||
| msg = "{0}, {1}, {2} ({3}, {4}), UTC {5}" | msg = "{0}, {1}, {2} ({3}, {4}), UTC {5}" | ||||
| geo = msg.format(country, region, city, latitude, longitude, utcoffset) | geo = msg.format(country, region, city, latitude, longitude, utcoffset) | ||||
| self.reply(data, geo) | 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 | |||||