Permalink
Browse files

Fixed crashing on not found record. Basic 3 method (country_name, cou…

…ntry_code, continent_code) works with IP and host. Added logotype and tests.
  • Loading branch information...
1 parent 5b76fd2 commit 4f4e2ad7ae33b3e71f79dcf70e0db4ca92cdc34d @bbkr committed Apr 1, 2012
Showing with 100 additions and 11 deletions.
  1. +9 −0 META.info
  2. +20 −2 README.md
  3. +49 −9 lib/GeoIP.pm
  4. BIN logotype/logo_32x32.png
  5. +22 −0 t/basic.t
View
@@ -0,0 +1,9 @@
+{
+ "name" : "GeoIP",
+ "version" : "0.1",
+ "description" : "GeoIP MaxMind library interface",
+ "author" : "Pawel Pabian",
+ "authority" : "bbkr",
+ "depends" : [ "NativeCall" ],
+ "source-url" : "git://github.com/bbkr/GeoIPerl6.git"
+}
View
@@ -22,12 +22,30 @@ sudo port install libgeoip GeoLiteCity
use GeoIP;
my $g = GeoIP.new;
-say $g.country_code_by_addr('91.192.78.63');
+say $g.country_code( '91.192.78.63' );
+say $g.country_name( '91.192.78.63' );
+say $g.continent_code( '91.192.78.63' );
```
-If everything is installed correctly it should print ```PL```.
+If everything is installed correctly it should print:
+```
+PL
+Poland
+EU
+```
+
+Using host names is also allowed:
+
+```perl
+say $g.country_code( 'bbkr.org' );
+```
##TODO
Everything :)
+
+* other operating systems
+* paid databases
+* fetching whole record
+* consistent interface
View
@@ -1,16 +1,56 @@
-class GeoIP;
-
use NativeCall;
-has OpaquePointer $!db;
+class GeoIP is repr('CPointer');
+
+# initialize database
+sub GeoIP_new ( Int ) returns GeoIP is native( '/opt/local/lib/libGeoIP.dylib' ) { * }
+sub GeoIP_set_charset (GeoIP, Int ) returns Int is native( '/opt/local/lib/libGeoIP.dylib' ) { * }
+
+# HACK: obtain ID as intermediate level for calls
+# because currently NativeCall segfaults on NULL pointers
+sub GeoIP_id_by_addr ( GeoIP, Str ) returns Int is native( '/opt/local/lib/libGeoIP.dylib' ) { * }
+sub GeoIP_id_by_name ( GeoIP, Str ) returns Int is native( '/opt/local/lib/libGeoIP.dylib' ) { * }
-sub GeoIP_new ( Int ) returns OpaquePointer is native( '/opt/local/lib/libGeoIP.dylib' ) { * }
-sub GeoIP_country_code_by_addr ( OpaquePointer, Str ) returns Str is native( '/opt/local/lib/libGeoIP.dylib' ) { * }
+sub GeoIP_code_by_id( Int ) returns Str is native( '/opt/local/lib/libGeoIP.dylib' ) { * }
+sub GeoIP_country_name_by_id( GeoIP, Int ) returns Str is encoded('utf8') is native( '/opt/local/lib/libGeoIP.dylib' ) { * };
+sub GeoIP_name_by_id( Int ) returns Str is native( '/opt/local/lib/libGeoIP.dylib' ) { * };
+sub GeoIP_continent_by_id( Int ) returns Str is native( '/opt/local/lib/libGeoIP.dylib' ) { * };
-submethod BUILD {
- $!db = GeoIP_new( 0 );
+method new ( ) {
+ my $g = GeoIP_new( 0 );
+
+ # GeoIPCharset.GEOIP_CHARSET_UTF8 == 1
+ GeoIP_set_charset( $g, 1 );
+
+ return $g;
}
-method country_code_by_addr ( Str $ip ){
- return GeoIP_country_code_by_addr( $!db, $ip );
+# avoid "_by_id"" or "_by_addr" suffixes from GeoIP.h
+# and detect type using awesome Perl 6 signatures later
+multi method id ( Str $ip where /^\d+\.\d+\.\d+\.\d+$/ ) {
+ return GeoIP_id_by_addr( self, $ip );
}
+multi method id ( Str $host ) {
+ return GeoIP_id_by_name( self, $host );
+}
+
+method country_code ( $location ) {
+ my $id = self.id( $location );
+
+ return unless $id;
+ return GeoIP_code_by_id( $id );
+}
+
+method country_name ( $location ) {
+ my $id = self.id( $location );
+
+ return unless $id;
+ return GeoIP_country_name_by_id( self, $id );
+}
+
+method continent_code ( $location ) {
+ my $id = self.id( $location );
+
+ return unless $id;
+ return GeoIP_continent_by_id( $id );
+}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
@@ -0,0 +1,22 @@
+BEGIN { @*INC.unshift('lib') }
+
+use Test;
+use GeoIP;
+
+plan( 9 );
+
+my $g;
+
+lives_ok { $g = GeoIP.new }, 'initialize database';
+
+is $g.country_code( 'perl.org' ), 'US', 'country_code found by host';
+is $g.country_code( '207.171.7.63' ), 'US', 'country_code found by ip';
+ok not $g.country_code( '0.0.0.0').defined, 'country_code missing';
+
+is $g.country_code( 'perlgeek.de' ), 'DE', 'country_code found by host';
+is $g.country_name( '213.95.10.24' ), 'Germany', 'country_name found ';
+ok not $g.country_name( '0.0.0.0').defined, 'country_name missing';
+
+is $g.continent_code( '91.192.78.63' ), 'EU', 'continent_code found by ip';
+ok not $g.country_name( '0.0.0.0').defined, 'continent_code missing';
+

0 comments on commit 4f4e2ad

Please sign in to comment.