Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Geo-IPinfo/MANIFEST
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
Changes
lib/Geo/IPinfo.pm
lib/Geo/IPinfoLite.pm
lib/Geo/IPinfoCore.pm
lib/Geo/Details.pm
lib/Geo/DetailsLite.pm
lib/Geo/DetailsCore.pm
Makefile.PL
MANIFEST This list of files
ignore.txt
t/00-load.t
t/01-usage.t
t/02-usage-lite.t
t/03-usage-core.t
t/cache-hit.t
t/manifest.t
t/pod-coverage.t
Expand Down
149 changes: 149 additions & 0 deletions Geo-IPinfo/lib/Geo/DetailsCore.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package Geo::DetailsCore;

use 5.006;
use strict;
use warnings;

# Helper package for Geo data
package Geo::DetailsCore::Geo {
use strict;
use warnings;

sub new {
my $class = shift;
my $data = shift || {};
bless $data, $class;
return $data;
}

sub city { return $_[0]->{city}; }
sub region { return $_[0]->{region}; }
sub region_code { return $_[0]->{region_code}; }
sub country { return $_[0]->{country}; }
sub country_code { return $_[0]->{country_code}; }
sub continent { return $_[0]->{continent}; }
sub continent_code { return $_[0]->{continent_code}; }
sub latitude { return $_[0]->{latitude}; }
sub longitude { return $_[0]->{longitude}; }
sub timezone { return $_[0]->{timezone}; }
sub postal_code { return $_[0]->{postal_code}; }

# Enriched fields
sub country_name { return $_[0]->{country_name}; }
sub is_eu { return $_[0]->{is_eu}; }
sub country_flag { return $_[0]->{country_flag}; }
sub country_flag_url { return $_[0]->{country_flag_url}; }
sub country_currency { return $_[0]->{country_currency}; }
sub continent_info { return $_[0]->{continent_info}; }
}

# Helper package for AS data
package Geo::DetailsCore::AS {
use strict;
use warnings;

sub new {
my $class = shift;
my $data = shift || {};
bless $data, $class;
return $data;
}

sub asn { return $_[0]->{asn}; }
sub name { return $_[0]->{name}; }
sub domain { return $_[0]->{domain}; }
sub type { return $_[0]->{type}; }
}

# Main package
package Geo::DetailsCore;

sub new {
my $class = shift;
my $data = shift;
my $key = shift // '';

# If $data is a hash reference, process and bless it
if ( ref($data) eq 'HASH' ) {
# Convert nested geo and as to blessed objects
if ( exists $data->{geo} && ref($data->{geo}) eq 'HASH' ) {
$data->{geo} = Geo::DetailsCore::Geo->new($data->{geo});
}
if ( exists $data->{as} && ref($data->{as}) eq 'HASH' ) {
$data->{as} = Geo::DetailsCore::AS->new($data->{as});
}

bless $data, $class;
return $data;
}

# If $data is a plain string, create a new hash reference
my $self = { $key => $data };
bless $self, $class;
return $self;
}

sub TO_JSON {
my ($self) = @_;
return {%$self};
}

sub ip { return $_[0]->{ip}; }
sub geo { return $_[0]->{geo}; }
sub as { return $_[0]->{as}; }
sub is_anonymous { return $_[0]->{is_anonymous}; }
sub is_anycast { return $_[0]->{is_anycast}; }
sub is_hosting { return $_[0]->{is_hosting}; }
sub is_mobile { return $_[0]->{is_mobile}; }
sub is_satellite { return $_[0]->{is_satellite}; }
sub bogon { return $_[0]->{bogon}; }

sub all {
return $_[0];
}

1;
__END__

=head1 NAME

Geo::DetailsCore - Module to represent details of an IP returned by the Core API

=head1 SYNOPSIS

use Geo::DetailsCore;

my $data = {
ip => '8.8.8.8',
geo => {
city => 'Mountain View',
country => 'United States',
country_code => 'US',
},
as => {
asn => 'AS15169',
name => 'Google LLC',
},
is_anycast => 1,
};

my $details = Geo::DetailsCore->new($data);
print $details->ip; # Output: 8.8.8.8
print $details->geo->city; # Output: Mountain View
print $details->as->name; # Output: Google LLC

=head1 DESCRIPTION

Geo::DetailsCore represents details of an IP returned by the IPinfo Core API.

=head1 AUTHOR

IPinfo <support@ipinfo.io>

=head1 COPYRIGHT AND LICENSE

Copyright (c) 2025 IPinfo

Licensed under the Apache License, Version 2.0.

=cut
Loading
Loading