Changeset 940264d1718b5a32d34ac82276a29f0cc1a51941
- Timestamp:
- 08/13/08 07:32:59
(3 months ago)
- Author:
- Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
- git-committer:
- Giuseppe Bilotta <giuseppe.bilotta@gmail.com> 1218598379 +0200
- git-parent:
[5604d4bfb78ff357997bcce0ee3fd010cf7d9c8d]
- git-author:
- Raine Virta <rane@kapsi.fi> 1218591091 +0300
- Message:
geoip plugin: new service for geoip-lookup along with some other enhancements
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r5604d4b |
r940264d |
|
| 11 | 11 | |
|---|
| 12 | 12 | module GeoIP |
|---|
| 13 | | GEO_IP = "http://www.geoiptool.com/en/?IP=" |
|---|
| | 13 | class InvalidHostError < RuntimeError; end |
|---|
| | 14 | |
|---|
| | 15 | GEO_IP_PRIMARY = "http://kapsi.fi:40086/lookup.yaml?host=" |
|---|
| | 16 | GEO_IP_SECONDARY = "http://www.geoiptool.com/en/?IP=" |
|---|
| | 17 | HOST_NAME_REGEX = /[a-z0-9\-]+(?:\.[a-z0-9\-]+)*\.[a-z]{2,4}/i |
|---|
| | 18 | |
|---|
| 14 | 19 | REGEX = { |
|---|
| 15 | 20 | :country => %r{Country:.*?<a href=".*?" target="_blank"> (.*?)</a>}m, |
|---|
| … | … | |
| 18 | 23 | } |
|---|
| 19 | 24 | |
|---|
| | 25 | def self.valid_host?(hostname) |
|---|
| | 26 | hostname =~ HOST_NAME_REGEX || |
|---|
| | 27 | hostname =~ Resolv::IPv4::Regex && (hostname.split(".").map { |e| e.to_i }.max <= 255) |
|---|
| | 28 | end |
|---|
| | 29 | |
|---|
| 20 | 30 | def self.resolve(hostname) |
|---|
| 21 | | res = {} |
|---|
| 22 | | raw = Irc::Utils.bot.httputil.get_response(GEO_IP+hostname) |
|---|
| 23 | | raw = raw.decompress_body(raw.raw_body) |
|---|
| | 31 | raise InvalidHostError unless valid_host?(hostname) |
|---|
| 24 | 32 | |
|---|
| 25 | | REGEX.each { |key, regex| res[key] = Iconv.conv('utf-8', 'ISO-8859-1', raw.scan(regex).to_s) } |
|---|
| | 33 | yaml = Irc::Utils.bot.httputil.get(GEO_IP_PRIMARY+hostname) |
|---|
| 26 | 34 | |
|---|
| 27 | | return res |
|---|
| | 35 | if yaml |
|---|
| | 36 | return YAML::load(yaml) |
|---|
| | 37 | else |
|---|
| | 38 | res = {} |
|---|
| | 39 | raw = Irc::Utils.bot.httputil.get_response(GEO_IP_SECONDARY+hostname) |
|---|
| | 40 | raw = raw.decompress_body(raw.raw_body) |
|---|
| | 41 | |
|---|
| | 42 | REGEX.each { |key, regex| res[key] = Iconv.conv('utf-8', 'ISO-8859-1', raw.scan(regex).to_s) } |
|---|
| | 43 | |
|---|
| | 44 | return res |
|---|
| | 45 | end |
|---|
| 28 | 46 | end |
|---|
| 29 | 47 | end |
|---|
| … | … | |
| 73 | 91 | end |
|---|
| 74 | 92 | |
|---|
| 75 | | @stack.clear(m.whois[:nick]) |
|---|
| | 93 | @stack.clear(nick) |
|---|
| 76 | 94 | end |
|---|
| 77 | 95 | |
|---|
| … | … | |
| 92 | 110 | |
|---|
| 93 | 111 | # input is a host name or an IP |
|---|
| 94 | | if params[:input] =~ /[a-z0-9\-]+(?:\.[a-z0-9\-]+)*\.[a-z]{2,4}/i || |
|---|
| 95 | | params[:input] =~ Resolv::IPv4::Regex |
|---|
| 96 | | m.reply host2output(params[:input]) |
|---|
| | 112 | if GeoIP::valid_host?(params[:input]) |
|---|
| | 113 | m.reply host2output(params[:input]) |
|---|
| 97 | 114 | |
|---|
| 98 | 115 | # assume input is a nick |
|---|
| 99 | | else |
|---|
| | 116 | elsif params[:input] !~ /\./ |
|---|
| 100 | 117 | nick = params[:input].downcase |
|---|
| 101 | 118 | |
|---|
| 102 | 119 | @stack[nick] << m.replyto |
|---|
| 103 | 120 | @bot.whois(nick) |
|---|
| | 121 | else |
|---|
| | 122 | m.reply "invalid input" |
|---|
| 104 | 123 | end |
|---|
| 105 | 124 | end |
|---|
| … | … | |
| 107 | 126 | |
|---|
| 108 | 127 | def host2output(host, nick=nil) |
|---|
| 109 | | geo = GeoIP::resolve(host) |
|---|
| | 128 | return "127.0.0.1 could not be res.. wait, what?" if host == "127.0.0.1" |
|---|
| 110 | 129 | |
|---|
| 111 | | if geo[:country].empty? |
|---|
| | 130 | begin |
|---|
| | 131 | geo = GeoIP::resolve(host) |
|---|
| | 132 | |
|---|
| | 133 | raise if geo[:country].empty? |
|---|
| | 134 | rescue GeoIP::InvalidHostError, RuntimeError |
|---|
| 112 | 135 | return _("#{nick ? "#{nick}'s location" : host} could not be resolved") |
|---|
| 113 | 136 | end |
|---|
| … | … | |
| 120 | 143 | res << " %{city}," % { |
|---|
| 121 | 144 | :city => geo[:city] |
|---|
| 122 | | } unless geo[:city].empty? |
|---|
| | 145 | } unless geo[:city].to_s.empty? |
|---|
| 123 | 146 | |
|---|
| 124 | 147 | res << " %{country}" % { |
|---|
| … | … | |
| 128 | 151 | res << " (%{region})" % { |
|---|
| 129 | 152 | :region => geo[:region] |
|---|
| 130 | | } unless geo[:region].empty? || geo[:region] == geo[:city] |
|---|
| | 153 | } unless geo[:region].to_s.empty? || geo[:region] == geo[:city] |
|---|
| 131 | 154 | |
|---|
| 132 | 155 | return res |
|---|