X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=data%2Frbot%2Fplugins%2Fgeoip.rb;h=615511728df524469571276977a16965ac1579f7;hb=16336b4a240a4265d1f2df1e30d7b68d3a924287;hp=0eb4eed4bd9ca65b1939ca64fa4ebf3ada799912;hpb=5604d4bfb78ff357997bcce0ee3fd010cf7d9c8d;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git
diff --git a/data/rbot/plugins/geoip.rb b/data/rbot/plugins/geoip.rb
index 0eb4eed4..61551172 100755
--- a/data/rbot/plugins/geoip.rb
+++ b/data/rbot/plugins/geoip.rb
@@ -9,22 +9,42 @@
#
# Resolves the geographic locations of users (network-wide) and IP addresses
-module GeoIP
- GEO_IP = "http://www.geoiptool.com/en/?IP="
+module ::GeoIP
+ class InvalidHostError < RuntimeError; end
+
+ GEO_IP_PRIMARY = "http://lakka.kapsi.fi:40086/lookup.yaml?host="
+ GEO_IP_SECONDARY = "http://www.geoiptool.com/en/?IP="
+ HOST_NAME_REGEX = /^[a-z0-9\-]+(?:\.[a-z0-9\-]+)*\.[a-z]{2,4}/i
+
REGEX = {
:country => %r{Country:.*? (.*?)}m,
:region => %r{Region:.*?(.*?)}m,
- :city => %r{City:.*?
(.*?) | }m
+ :city => %r{City:.*?(.*?) | }m,
+ :lat => %r{Latitude:.*?(.*?) | }m,
+ :lon => %r{Longitude:.*?(.*?) | }m
}
+ def self.valid_host?(hostname)
+ hostname =~ HOST_NAME_REGEX ||
+ hostname =~ Resolv::IPv4::Regex && (hostname.split(".").map { |e| e.to_i }.max <= 255)
+ end
+
def self.resolve(hostname)
- res = {}
- raw = Irc::Utils.bot.httputil.get_response(GEO_IP+hostname)
- raw = raw.decompress_body(raw.raw_body)
+ raise InvalidHostError unless valid_host?(hostname)
- REGEX.each { |key, regex| res[key] = Iconv.conv('utf-8', 'ISO-8859-1', raw.scan(regex).to_s) }
+ yaml = Irc::Utils.bot.httputil.get(GEO_IP_PRIMARY+hostname)
- return res
+ if yaml
+ return YAML::load(yaml)
+ else
+ res = {}
+ raw = Irc::Utils.bot.httputil.get_response(GEO_IP_SECONDARY+hostname)
+ raw = raw.decompress_body(raw.raw_body)
+
+ REGEX.each { |key, regex| res[key] = Iconv.conv('utf-8', 'ISO-8859-1', raw.scan(regex).to_s) }
+
+ return res
+ end
end
end
@@ -64,15 +84,16 @@ class GeoIpPlugin < Plugin
# need to see if the whois reply was invoked by this plugin
return unless @stack.has_nick?(nick)
+ if m.target
+ msg = host2output(m.target.host, m.target.nick)
+ else
+ msg = "no such user on "+@bot.server.hostname.split(".")[-2]
+ end
@stack[nick].each do |source|
- if m.target
- @bot.say source, host2output(m.target.host, m.target.nick)
- else
- @bot.say source, "no such user on "+@bot.server.hostname.split(".")[-2]
- end
+ @bot.say source, msg
end
- @stack.clear(m.whois[:nick])
+ @stack.clear(nick)
end
def geoip(m, params)
@@ -91,24 +112,29 @@ class GeoIpPlugin < Plugin
end
# input is a host name or an IP
- if params[:input] =~ /[a-z0-9\-]+(?:\.[a-z0-9\-]+)*\.[a-z]{2,4}/i ||
- params[:input] =~ Resolv::IPv4::Regex
- m.reply host2output(params[:input])
+ if GeoIP::valid_host?(params[:input])
+ m.reply host2output(params[:input])
# assume input is a nick
- else
+ elsif params[:input] !~ /\./
nick = params[:input].downcase
@stack[nick] << m.replyto
@bot.whois(nick)
+ else
+ m.reply "invalid input"
end
end
end
def host2output(host, nick=nil)
- geo = GeoIP::resolve(host)
+ return "127.0.0.1 could not be res.. wait, what?" if host == "127.0.0.1"
+
+ begin
+ geo = GeoIP::resolve(host)
- if geo[:country].empty?
+ raise if geo[:country].empty?
+ rescue GeoIP::InvalidHostError, RuntimeError
return _("#{nick ? "#{nick}'s location" : host} could not be resolved")
end
@@ -119,7 +145,7 @@ class GeoIpPlugin < Plugin
res << " %{city}," % {
:city => geo[:city]
- } unless geo[:city].empty?
+ } unless geo[:city].to_s.empty?
res << " %{country}" % {
:country => geo[:country]
@@ -127,11 +153,11 @@ class GeoIpPlugin < Plugin
res << " (%{region})" % {
:region => geo[:region]
- } unless geo[:region].empty? || geo[:region] == geo[:city]
+ } unless geo[:region].to_s.empty? || geo[:region] == geo[:city]
return res
end
end
plugin = GeoIpPlugin.new
-plugin.map "geoip [:input]", :action => 'geoip'
\ No newline at end of file
+plugin.map "geoip [:input]", :action => 'geoip', :thread => true