Geolocation with MaxMind's GeoIP and the geoip-city RubyGem
Ruby posted over 2 years ago by christian
Install GeoIP library
1 wget http://www.maxmind.com/download/geoip/api/c/GeoIP.tar.gz 2 tar -zxvf GeoIP.tar.gz 3 cd GeoIP 4 ./configure --prefix=/opt/GeoIP 5 make && sudo make install
Install the geoip-city gem
1 gem install geoip_city -- --with-geoip-dir=/opt/GeoIP
Test the bindings
1 curl -O http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz 2 gunzip GeoLiteCity.dat.gz
Fire up IRB and try the following code:
1 require 'rubygems' 2 require 'geoip_city' 3 db = GeoIPCity::Database.new('GeoLiteCity.dat') 4 result = db.look_up('192.143.34.23') 5 p result
Another option is to use hostip.info’s database, as described in this article.
Create a wrapper
1 require 'rubygems' 2 require 'geoip_city' 3 require 'ostruct' 4 5 class Location < OpenStruct 6 end 7 8 class GeoIP 9 class << self 10 DB = GeoIPCity::Database.new('GeoLiteCity.dat') 11 12 def lookup(ip) 13 if result = DB.look_up(ip) 14 location = Location.new 15 16 # 17 # {:country_code=>"FR", :country_code3=>"FRA", :country_name=>"France", :latitude=>46.0, :longitude=>2.0} 18 # 19 result.each do |key, val| 20 location.send "#{key}=", val 21 end 22 end 23 24 location 25 end 26 end 27 end
Add some Rails caching
Combined with the above code this will give you cached IP lookups:
1 class GeoIP 2 3 class << self 4 def lookup_with_caching(ip) 5 Rails.cache.fetch(ip, :expires_in => 1.month) do 6 lookup_without_caching(ip) 7 end 8 end 9 10 alias_method_chain :lookup, :caching 11 end 12 end
Alternatives
If you’re unable to install the C extension you might want to have a look at the geoip gem, which is a pure Ruby library that can read the MaxMind’s geoip database. It’s slower but easier to install: http://geoip.rubyforge.org/