| |
---|
| | use GD; |
---|
| | use Geo::IP; |
---|
| | use Geo::Proj4; |
---|
| | |
---|
| | |
---|
| | my ($start_sec, $start_micro) = gettimeofday; |
---|
| | my ( $start_sec, $start_micro ) = gettimeofday; |
---|
| | my ($start_time) = ( $start_sec * 1000 ) + round( $start_micro / 1000 ); |
---|
| | |
---|
| | my ($page); |
---|
| | |
---|
| | my ($dsn) = "DBI:mysql:database=eprintstats;host=localhost"; |
---|
| | my ($dsn) = "DBI:mysql:database=eprintstats;host=localhost"; |
---|
| | my ($user_name) = "eprintstatspriv"; |
---|
| | my ($password) = "AuldGrizzel"; |
---|
| | my ($connect, $query, %types, $stat, $row, $num_rows, $vtype); |
---|
| | my ($password) = "AuldGrizzel"; |
---|
| | my ( $connect, $query, %types, %unmapped, $stat, $row, $num_rows, $vtype ); |
---|
| | |
---|
| | my ($mapimage, $mapimagefile); |
---|
| | my ($red, $white, $black, $blue); |
---|
| | my ($width, $height); |
---|
| | my ( $mapimage, $mapimagefile ); |
---|
| | my ( $red, $white, $black, $blue ); |
---|
| | my ( $width, $height ); |
---|
| | |
---|
| | my ($gi, $proj); |
---|
| | my ( $gi, $proj ); |
---|
| | my ($gidb) = '/usr/local/share/GeoIP/GeoLiteCity.dat'; |
---|
| | |
---|
| | my ($x_offset) = 16986796.16; |
---|
| | my ($y_offset) = 8615499.05; |
---|
| | my ($max_x) = $x_offset * 2; |
---|
| | my ($max_y) = $y_offset * 2; |
---|
| | my (%cities); |
---|
| | my ($num_IPs) = 100; |
---|
| | my ($num_hits) = 0; |
---|
| | my ($ip, $count, $location); |
---|
| | my ($city, $lat, $long, $x, $y); |
---|
| | |
---|
| | my ($max_x) = $x_offset * 2; |
---|
| | my ($max_y) = $y_offset * 2; |
---|
| | my ( %cities, %IPs ); |
---|
| | my ($num_entries) = -1; |
---|
| | my ($num_hits) = 0; |
---|
| | my ( $ip, $count, $location ); |
---|
| | my ( $city, $lat, $long, $x, $y ); |
---|
| | |
---|
| | $page = new CGI; |
---|
| | print $page->header( -type=>"image/jpeg", -Pragma=>'no-cache' ); |
---|
| | print $page->header( -type => "image/jpeg", -Pragma => 'no-cache' ); |
---|
| | $num_entries = $page->param('top'); |
---|
| | |
---|
| | $gi = Geo::IP->open( $gidb, GEOIP_STANDARD ) |
---|
| | or die "Unable to open GeoIP database $gidb\n"; |
---|
| | or die "Unable to open GeoIP database $gidb\n"; |
---|
| | |
---|
| | $proj = Geo::Proj4->new( proj => "robin", ellps => "sphere", lon_0 => 10 ) |
---|
| | or die "parameter error: " . Geo::Proj4->error . "\n"; |
---|
| | or die "parameter error: " . Geo::Proj4->error . "\n"; |
---|
| | |
---|
| | $width = $page->param('width'); |
---|
| | $height = $page->param('height'); |
---|
| | $width = $page->param('width'); |
---|
| | $height = $page->param('height'); |
---|
| | $mapimagefile = "map_${width}x${height}.png"; |
---|
| | $mapimage = GD::Image->newFromPng( $mapimagefile, 1 ); |
---|
| | $white = $mapimage->colorAllocate( 255, 255, 255 ); |
---|
| | $black = $mapimage->colorAllocate( 0, 0, 0 ); |
---|
| | $red = $mapimage->colorAllocate( 255, 0, 0 ); |
---|
| | $blue = $mapimage->colorAllocate( 0, 0, 255 ); |
---|
| | $mapimage = GD::Image->newFromPng( $mapimagefile, 1 ); |
---|
| | $white = $mapimage->colorAllocate( 255, 255, 255 ); |
---|
| | $black = $mapimage->colorAllocate( 0, 0, 0 ); |
---|
| | $red = $mapimage->colorAllocate( 255, 0, 0 ); |
---|
| | $blue = $mapimage->colorAllocate( 0, 0, 255 ); |
---|
| | |
---|
| | $connect = DBI->connect( $dsn, $user_name, $password, { RaiseError => 1 } ); |
---|
| | |
---|
| | $types{'download'} = $types{'abstract'} = 0; |
---|
| | $query = |
---|
| | "SELECT ip, view_type, COUNT(*) AS count |
---|
| | $types{'download'} = $types{'abstract'} = 0; |
---|
| | $unmapped{'download'} = $unmapped{'abstract'} = 0; |
---|
| | $query = "SELECT ip, view_type, COUNT(*) AS count |
---|
| | FROM view |
---|
| | GROUP BY ip, view_type |
---|
| | ORDER BY count DESC" . |
---|
| | ( $num_IPs > 0 ? " LIMIT $num_IPs" : '' ); |
---|
| | ORDER BY count DESC" . ( ( $num_entries > 0 ) ? " LIMIT $num_entries" : '' ); |
---|
| | |
---|
| | $stat = $connect->prepare( $query ); |
---|
| | $stat = $connect->prepare($query); |
---|
| | $stat->execute(); |
---|
| | $num_rows = $stat->rows; |
---|
| | |
---|
| | if ( $num_rows > 0 ) |
---|
| | { |
---|
| | $num_IPs = $num_rows if ( $num_IPs < 1 ); |
---|
| | |
---|
| | $num_entries = $num_rows if ( $num_entries < 1 ); |
---|
| | |
---|
| | while ( $row = $stat->fetchrow_hashref() ) |
---|
| | { |
---|
| | $ip = $row->{'ip'}; |
---|
| | $ip = $row->{'ip'}; |
---|
| | $count = $row->{'count'}; |
---|
| | $vtype = $row->{'view_type'}; |
---|
| | |
---|
| | $location = $gi->record_by_addr( $ip ); |
---|
| | |
---|
| | if ( defined( $location ) ) |
---|
| | |
---|
| | $IPs{$ip} = 1; |
---|
| | |
---|
| | $location = $gi->record_by_addr($ip); |
---|
| | |
---|
| | if ( defined($location) ) |
---|
| | { |
---|
| | $lat = $location->latitude; |
---|
| | $lat = $location->latitude; |
---|
| | $long = $location->longitude; |
---|
| | $city = $location->city; |
---|
| | ($x, $y) = $proj->forward( $lat, $long ); |
---|
| | $x = round(($x + $x_offset) / $max_x * $width); |
---|
| | $y = round(($y_offset - $y) / $max_y * $height); |
---|
| | ( $x, $y ) = $proj->forward( $lat, $long ); |
---|
| | $x = round( ( $x + $x_offset ) / $max_x * $width ); |
---|
| | $y = round( ( $y_offset - $y ) / $max_y * $height ); |
---|
| | |
---|
| | $city = "Unknown ($lat, $long)" if ( $city eq '' ); |
---|
| | |
---|
| | if ( !defined( $cities{$city} ) ) |
---|
| | { |
---|
| | $cities{$city}{'count'} = 0; |
---|
| | $cities{$city}{'lat'} = $lat; |
---|
| | $cities{$city}{'long'} = $long; |
---|
| | |
---|
| | $mapimage->filledRectangle( $x - 1, $y - 1, $x + 1, $y + 1, ( $vtype eq 'download' ? $red : $blue ) ); |
---|
| | $cities{$city}{'lat'} = $lat; |
---|
| | $cities{$city}{'long'} = $long; |
---|
| | |
---|
| | $mapimage->filledRectangle( $x - 1, $y - 1, $x + 1, $y + 1, |
---|
| | ( ( $vtype eq 'download' ) ? $red : $blue ) ); |
---|
| | } |
---|
| | $cities{$city}{'count'} += $count; |
---|
| | $types{$vtype} += $count; |
---|
| | |
---|
| | $types{$vtype} += $count; |
---|
| | |
---|
| | $cities{$city}{'x'} = $x; |
---|
| | $cities{$city}{'y'} = $y; |
---|
| | } |
---|
| | else |
---|
| | { |
---|
| | $unmapped{$vtype} += $count; |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | |
---|
| | $stat->finish(); |
---|
| | $connect->disconnect(); |
---|
| | |
---|
| | $mapimage->string( gdSmallFont, 3, 3, "$types{'download'} downloads", $red ); |
---|
| | $mapimage->string( gdSmallFont, 3, 15, "$types{'abstract'} abstracts", $blue ); |
---|
| | $mapimage->string( gdSmallFont, 3, 27, 'from ' . scalar( keys %cities ) . ' cities', $black ); |
---|
| | $mapimage->string( gdSmallFont, 3, 39, "($num_rows IP addresses)", $black ); |
---|
| | |
---|
| | $mapimage->string( gdSmallFont, |
---|
| | 3, 3, |
---|
| | "$types{'download'} downloads" |
---|
| | . ( |
---|
| | ( $unmapped{'download'} > 0 ) |
---|
| | ? " (+$unmapped{'download'} unmappable)" |
---|
| | : '' |
---|
| | ), |
---|
| | $red |
---|
| | ); |
---|
| | $mapimage->string( gdSmallFont, |
---|
| | 3, 15, |
---|
| | "$types{'abstract'} abstracts" |
---|
| | . ( |
---|
| | ( $unmapped{'abstract'} > 0 ) |
---|
| | ? " (+$unmapped{'abstract'} unmappable)" |
---|
| | : '' |
---|
| | ), |
---|
| | $blue |
---|
| | ); |
---|
| | $mapimage->string( gdSmallFont, 3, 27, |
---|
| | 'from ' . scalar( keys %cities ) . ' cities', $black ); |
---|
| | $mapimage->string( gdSmallFont, 3, 39, |
---|
| | '(' . scalar( keys %IPs ) . ' IP addresses)', $black ); |
---|
| | |
---|
| | my ( $finish_sec, $finish_micro ) = gettimeofday(); |
---|
| | my ($finish_time) = ( $finish_sec * 1000 ) + round( $finish_micro / 1000 ); |
---|
| | $mapimage->string( gdSmallFont, 3, $height - 15, 'Generated in ' . ( $finish_time - $start_time ) . ' ms', $black ); |
---|
| | $mapimage->string( gdSmallFont, 3, |
---|
| | $height - 15, |
---|
| | 'Generated in ' . ( $finish_time - $start_time ) . ' ms', |
---|
| | $black ); |
---|
| | |
---|
| | binmode( STDOUT ); |
---|
| | binmode(STDOUT); |
---|
| | |
---|
| | print $mapimage->jpeg(); |
---|
| | |
---|
| | |
---|
| | sub round |
---|
| | { |
---|
| | my ($n) = shift; |
---|
| | return int( $n + .5 * ($n <=> 0) ); |
---|
| | return int( $n + 0.5 * ( $n <=> 0 ) ); |
---|
| | } |
---|
| | |
---|
|