%# BEGIN BPS TAGGED BLOCK {{{ %# %# COPYRIGHT: %# %# This software is Copyright (c) 1996-2026 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) %# %# %# LICENSE: %# %# This work is made available to you under the terms of Version 2 of %# the GNU General Public License. A copy of that license should have %# been provided with this software, but in any event can be snarfed %# from www.gnu.org. %# %# This work is distributed in the hope that it will be useful, but %# WITHOUT ANY WARRANTY; without even the implied warranty of %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU %# General Public License for more details. %# %# You should have received a copy of the GNU General Public License %# along with this program; if not, write to the Free Software %# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA %# 02110-1301 or visit their web page on the internet at %# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. %# %# %# CONTRIBUTION SUBMISSION POLICY: %# %# (The following paragraph is not intended to limit the rights granted %# to you to modify and distribute this software under the terms of %# the GNU General Public License and is only of importance to you if %# you choose to contribute your changes and enhancements to the %# community by submitting them to Best Practical Solutions, LLC.) %# %# By intentionally submitting any modifications, corrections or %# derivatives to this work, or any other work intended for use with %# Request Tracker, to Best Practical Solutions, LLC, you confirm that %# you are the copyright holder for those contributions and you grant %# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, %# royalty-free, perpetual, license to use, copy, create derivative %# works based on those contributions, and sublicense and distribute %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} <& /RTIR/Elements/Header, Title => $title &> <& /Elements/Tabs &>
<&| /Widgets/TitleBox, title => $title, class => 'ipinfo', &>

<%perl>
$SavedContent .= $ipinfo_results . "\n";
$m->out( $ipinfo_results );

    
% if ($TicketObj and $SavedContent) { % my $url = RT::IR->HREFTo( % "Tools/Lookup.html?" % . $m->comp( % '/Elements/QueryString', % ticket => $ticket, % q => $q, % ) % );
% }
<%init> # IPinfo only works with IP addresses use Regexp::Common qw(net); unless ($q =~ /^($RE{net}{IPv4})$/ or $q =~ /^($RE{net}{IPv6})$/) { Abort(loc('IPinfo accepts only IPv4 or IPv6 IP addresses for lookups.')); } my $title = loc("IPinfo lookup for '[_1]'", $q); my $token = RT->Config->Get('LookupIPinfoToken'); my ($ipinfo_results, $TicketObj, $SavedContent); # Set a sensible order for the default info available for all IPinfo plans my @ipinfo_order = qw( ip hostname org city postal region country_name continent timezone longitude latitude ); my $required_module = RT::StaticUtil::RequireModule('Geo::IPinfo'); if ( $required_module && $token ) { RT->Logger->debug('Running Geo::IPinfo lookup'); if ($ticket) { $TicketObj = LoadTicket($ticket); } my $ipinfo = Geo::IPinfo->new($token); my $ip_details; if ( $q =~ /^($RE{net}{IPv6})$/ ) { $ip_details = $ipinfo->info_v6($q); } else { $ip_details = $ipinfo->info($q); } if ( $ip_details ) { foreach my $core_field ( @ipinfo_order ) { if ( exists $ip_details->{$core_field} ) { my $label = ucfirst($core_field); # Special cases $label = 'IP' if $core_field eq 'ip'; $label = 'Country Name' if $core_field eq 'country_name'; if ( $core_field eq 'continent' ) { $ipinfo_results .= loc($label) . ': ' . Encode::decode( 'UTF-8', $ip_details->{$core_field}{'name'} ) . ' (' . Encode::decode( 'UTF-8', $ip_details->{$core_field}{'code'} ) . ")\n"; } else { $ipinfo_results .= loc($label) . ': ' . Encode::decode( 'UTF-8', $ip_details->{$core_field} ) . "\n"; } delete $ip_details->{$core_field}; } } # IPinfo returns more data with higher paid plans, so if we have anything # remaining, dump it to the screen. if ( keys %$ip_details ) { $ipinfo_results .= "\nAdditional Data:\n\n"; } foreach my $more_data ( sort keys %$ip_details ) { # IPinfo seems to only have one layer of extra data if ( ref $ip_details->{$more_data} eq 'HASH' ) { $ipinfo_results .= loc(ucfirst($more_data)) . ':' . "\n"; foreach my $data_detail ( sort keys %{$ip_details->{$more_data}} ) { $ipinfo_results .= ' ' . loc( ucfirst($data_detail) ) . ': ' . Encode::decode( 'UTF-8', $ip_details->{$more_data}{$data_detail} ) . "\n"; } } else { $ipinfo_results .= loc( ucfirst($more_data) ) . ': ' . Encode::decode( 'UTF-8', $ip_details->{$more_data} ) . "\n"; } } } else { RT->Logger->error('Error calling IPinfo: ' . $ipinfo->error_msg); $ipinfo_results .= loc('Error calling IPinfo') . ': ' . $ipinfo->error_msg; } } else { RT->Logger->warn('Install the module Geo::IPinfo to use the IPinfo lookup tool') unless $required_module; RT->Logger->warn('IPinfo lookups require a token from IPinfo.io to be set with the config option LookupIPinfoToken') unless $token; return; } <%args> $ticket => undef $q => ''