- #!/usr/bin/env perl
- use strict;
- # use CGI;
- use DBI;
- use Geo::IP;
-
- # my ($page);
-
- # Database connection.
- my ($dsn) = "DBI:mysql:database=eprintstats;host=localhost";
- my ($user_name) = "eprintstatspriv";
- my ($password) = "AuldGrizzel";
- my ( $connect, $query, %types, %unmapped, $stat, $row, $num_rows, $vtype );
-
- # Geolocation database.
- my ($gi);
- my ($gidb) = '/usr/local/share/GeoIP/GeoLiteCity.dat';
-
- # Miscellaneous variable.
- my ( %cities, %IPs );
- my ($num_entries) = -1;
- my ($num_hits) = 0;
- my ( $ip, $count, $location );
- my ( $lat, $long, $city, $key ) = ( 0, 0, '', '' );
-
- # $page = new CGI;
- # print $page->header( -type => "text/xml", -Pragma => 'no-cache' );
- $num_entries = -1;#$page->param('top');
-
- $gi = Geo::IP->open( $gidb, GEOIP_STANDARD )
- or die "Unable to open GeoIP database $gidb\n";
-
- $connect = DBI->connect( $dsn, $user_name, $password, { RaiseError => 1 } );
-
- $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_entries > 0 ) ? " LIMIT $num_entries" : '' );
-
- $stat = $connect->prepare($query);
- $stat->execute();
- $num_rows = $stat->rows;
-
- if ( $num_rows > 0 )
- {
- $num_entries = $num_rows if ( $num_entries < 1 );
-
- while ( $row = $stat->fetchrow_hashref() )
- {
- $ip = $row->{'ip'};
- $count = $row->{'count'};
- $vtype = $row->{'view_type'};
-
- $IPs{$ip} = 1;
-
- $location = $gi->record_by_addr($ip);
-
- if ( defined($location) )
- {
- $lat = $location->latitude;
- $long = $location->longitude;
- $city = (
- ( $location->city eq '' )
- ? 'Unknown'
- : $location->city
- );
- $key = $city . " ($lat, $long)";
-
- if ( !defined( $cities{$key} ) )
- {
- $cities{$key}{'name'} = $city;
- $cities{$key}{'lat'} = $lat;
- $cities{$key}{'long'} = $long;
- $cities{$key}{'abstract'} = 0;
- $cities{$key}{'download'} = 0;
- }
- $cities{$key}{$vtype} += $count;
- $types{$vtype} += $count;
- }
- else
- {
- $unmapped{$vtype} += $count;
- }
- }
-
- # Need to wait until we have all the counts before writing the data out.
- print '<?xml version="1.0"?>' . "\n";
- print '<kml xmlns="http://earth.google.com/kml/2.0">' . "\n";
- print "<Document>\n<description>lotsa points</description>\n<name>Hits</name>\n";
-
- foreach $city ( keys %cities )
- {
- my ($maxcolor) = $cities{$city}{'download'} + $cities{$city}{'abstract'};
- my ($red) = round($cities{$city}{'download'} / $maxcolor * 255);
- my ($blue) = round($cities{$city}{'abstract'} / $maxcolor * 255);
- print '<Placemark>
- <description><![CDATA[<span style="color:red;">'
- . $cities{$city}{'download'}
- . ' downloads</span>, <span style="color:blue;">'
- . $cities{$city}{'abstract'}
- . ' abstracts</span>]]>
- </description>
- <name>'
- . $cities{$city}{'name'}
- . '</name>
- <Style>
- <IconStyle>
- <color>'
- . sprintf( 'c0%02x00%02x', $blue, $red )
- . '</color>
- <Icon>
- <href>root://icons/palette-4.png</href>
- <x>96</x>
- <y>128</y>
- <w>32</w>
- <h>32</h>
- </Icon>
- </IconStyle>
- </Style>
- <LookAt>
- <longitude>'
- . $cities{$city}{'long'}
- . '</longitude>
- <latitude>'
- . $cities{$city}{'lat'}
- . '</latitude>
- <range>540.68</range>
- <tilt>0</tilt>
- <heading>3</heading>
- </LookAt>
- <Point>
- <coordinates>'
- . $cities{$city}{'long'} . ','
- . $cities{$city}{'lat'}
- . ',0</coordinates>
- </Point>
- </Placemark>' . "\n";
- }
-
- print "</Document>\n</kml>\n";
- }
-
- $stat->finish();
- $connect->disconnect();
-
- sub round
- {
- my ($n) = shift;
- return int( $n + 0.5 * ( $n <=> 0 ) );
- }