Module GeoIP2 is available in Perl 6 ecosystem. This is Pure Perl so no additional C libraries are required.
Name should end with *.mmdb
instead of *.dat
-
typically GeoLite2-City.mmdb
is free and GeoIP2-City.mmdb
is paid one.
There are no separate IPv4/IPv6 databases like in GeoIP v1.
Examples for MacOS, Ubuntu and Arch and are here.
Old:
use GeoIP::City;
my $geo = GeoIP::City.new;
say $geo.locate( '8.8.8.8' );
say $geo.locate( '2001:4860:4860::8888' );
New:
use GeoIP2;
my $geo = GeoIP2.new( path => '/somewhere/GeoLite2-City.mmdb' );
say $geo.locate( ip => '8.8.8.8' );
say $geo.locate( ip => '2001:4860:4860:0:0:0:0:8888' );
Note:
- Doesn't matter how you got your database - direct download form MaxMind, using geoipupdate tool or using software repository packages - you have to know its path to give it to the constructor. There is no hardcoded "default" path like in libgeoip C library.
- IP is changed from positional to named param.
- Compressed form of IPv6 with
::
is Not Yet Implemented. You have to replace::
with correct amount of0
sections yourself. Sorry!
GeoIP2 returns more complex result. Here is how to map new structure to old one:
my %new-result = $geo.locate( ip => '8.8.8.8' );
my %old-reuslt = (
# gone, see https://dev.maxmind.com/geoip/geoip2/whats-new-in-geoip2/#Area_Code
'area_code' => Nil,
'city' => %new-result{ 'city' }{ 'names' }{ 'en' },
'continent_code' => %new-result{ 'continent' }{ 'code' },
'country' => %new-result{ 'country' }{ 'names' }{ 'en' },
'country_code' => %new-result{ 'country' }{ 'iso_code' },
# whatever it was - it's gone
'dma_code' => Nil,
# will be returned as IEEE754 Num
# you should probably apply some sane rounding
# like: %new-result{ 'location' }{ 'latitude' }.round(0.00001)
'latitude' => %new-result{ 'location' }{ 'latitude' },
'longitude' => %new-result{ 'location' }{ 'longitude' },
'postal_code' => %new-result{ 'postal' }{ 'code' },
# regions are now returned as an optional array of subdivisions
# for example first item may be voivodship, second item may be county, etc.
# what you want is probably the most specific subdivision which is last item of the array.
'region' => %new-result{ 'subdivisions' } ??
%new-result{ 'subdivisions' }[ * - 1 ]{ 'names' }{ 'en' } !! Nil,
'region_code' => %new-result{ 'subdivisions' } ??
%new-result{ 'subdivisions' }[ * - 1 ]{ 'iso_code' } !! Nil,
'time_zone' => %new-result{ 'location' }{ 'time_zone' }
);
GeoIP2 gives new possibilities for City database:
- translated names
- is in European Union flag
- accuracy radius for latitude / longitude
- country that IP is registered in
But you are not limited to that. Unlike GeoIP v1, GeoIPv2 module is an universal reader for all MaxMind databases.
Check this test to see what informations can be extracted from which database.