Радослав Зелински (radek at pld-linux dot org) написал Perl-скрипт для геолокации псевдонимов в IRC-клиенте XChat:
Я написал простой плагин для поиска IP-адреса в Maxmind База данных поиска GeoIP, вы можете найти ее здесь: xchat-geo.pl .Инструкции по установке смотрите в «perldoc xchat-geo.pl».
Использование: /geo some_nickname
Выход: [17:33] ==> some_nickname |US San Francisco CA 37,7525 -122,3194 n=somenick@some.host
Оригинальное сообщение в блоге: www.radek.cc/2009/09/06/irc-xchat-geolocation-plugin/
Требуется установить:
- Perl
- одну из баз данных Maxmind GeoIP (некоторые бесплатны)
- модуль Maxmind Geo :: IP (его API для Perl)
- XChat с подключаемым интерфейсом сценариев Perl
xchat-geo.pl, получено 2012-03-06:
#!/usr/bin/perl -w
use strict;
use Geo::IP ();
our $VERSION = '0.04';
=head1 NAME
xchat-geo.pl - geolocation plugin for xchat
=head1 SYNOPSIS
perl -MCPAN -e 'install Geo::IP'
chmod +x xchat-geo.pl
mv xchat-geo.pl ~/.xchat/
# in xchat
/unload .xchat/xchat-geo.pl
/load .xchat/xchat-geo.pl
/geo some-nickname
=head1 DESCRIPTION
Usage:
/geo some_nickname
[17:33] ==> some_nickname | US San Francisco CA 37.7525 -122.3194
n=somenick@some.host
Provides a single C</geo> command, which attempts to lookup the IP address in
the maxmind GeoIP database.
Requires the Geo::IP module to be installed, along with the GeoIP City (or its
free GeoLite counterpart); see L<http://www.maxmind.com/app/ip-location> and
L<http://www.maxmind.com/app/geolitecity>.
On my machine, the installed databases look like this:
$ ls -l /usr/share/GeoIP
lrwxrwxrwx 1 root root 15 Sep 6 16:54 GeoIPCity.dat -> GeoLiteCity.dat
-rw-r--r-- 1 root root 877738 Sep 6 16:25 GeoIP.dat
-rw-r--r-- 1 root root 27711885 Sep 6 16:31 GeoLiteCity.dat
Released 2009-09-06
=head1 AUTHOR
Radoslaw Zielinski E<lt>radek@pld-linux.orgE<gt>
http://radek.cc/2009/09/06/irc-xchat-geolocation-plugin/
=head1 LICENSE
GPL v3
=cut
our $geo = Geo::IP->open_type( Geo::IP::GEOIP_CITY_EDITION_REV1 ) # Geo::IP::GEOIP_STANDARD
or die "can't load the GeoIP database";
Xchat::print('xchat geo starting');
Xchat::register( 'xchat geo', $VERSION, 'geo location for xchat', \&unload );
Xchat::hook_print( 'Join', \&Join, );
Xchat::hook_command( 'geo', sub { geo(@_); Xchat::EAT_ALL; }, );
# for debugging / plugin development
#Xchat::hook_command( 'xev', sub { eval $_[1][0]; Xchat::EAT_ALL; }, );
sub Join {
my ( $user, $channel, $host ) = @{ $_[0] };
my $r = record_from_ihost($host);
Xchat::printf( "-\x0311->\x03\t\x02%s \x0f\x0314(\x0311%s\x0314) \x03has joined %s [\x0308%s\x0f]",
$user, $host, $channel,
$r && ref $r
? join( ', ', map { defined $_ ? $_ : '' } $r->country_code, $r->city, $r->region, $r->postal_code, )
: '' );
return Xchat::EAT_XCHAT;
}
# /geo some_nickname
sub geo {
my ($cmd) = @_;
defined $cmd->[1] && length $cmd->[1]
or return Xchat::print('nick?');
my $user = Xchat::user_info( $cmd->[1] )
or return Xchat::print("no such nick $cmd->[1]");
my $r = record_from_ihost( $user->{host} )
or return;
return ref $r
? Xchat::print(
' ==> ' . join "\t", $user->{nick}, $r->country_code, $r->city, $r->region,
$r->latitude, $r->longitude, $r->postal_code, $user->{host}
)
: Xchat::print($r);
}
# input: nick and hostname, as reported by xchat
# - n=user@hostname
# - n=user@IP.address
# - n=user@some/freenode/cloak (useless)
# output: a string with error message or a Geo::IP record
sub record_from_ihost {
my $ihost = shift
or return;
( my $nick = $ihost ) =~ s/^.=|\@.*//g;
$ihost =~ /^ [^@]* \@ (?: ((?:\d{1,3}\.){3}\.\d{1,3}) | ([a-zA-Z\d_-]+\.[.a-zA-Z\d_-]+) ) (?: \s.* )? $/x
or return "no useful host for <$nick> -- $ihost";
my $r = ( $1 ? $geo->record_by_ip($1) : $geo->record_by_name($2) )
or return "no useful geo info for <$nick> -- $ihost " . ( $1 ? "1: $1" : "2: $2" );
return $r;
}
sub unload {
undef $geo;
Xchat::print('xchat geo exiting');
}
# vim: ts=4 sw=4 noet