Geolocation script

I wrote this script in order to allow my TkWeather program to find the "local weather" wherever my laptop is connected to the internet via geolocation of the ISP providing me service. It first looks up the user’s true IP-address, then tries to determine his zip-code or city-state location. The best-guess zip-code is then returned.

#!/usr/bin/perl

=head1 NAME

geolocatezip.pl

=head1 SYNOPSIS

./geolocatezip.pl

=head1 DESCRIPTION

geolocatezip.pl attempts to first fetch the users current IP address, then uses that
to fetch the zipcode for that IP address using geolocation.  Failing that, it attempts
to fetch the city and state for the IP address and then uses a postal service site
to attempt to look up a zip-code for that city and state.  If multiple zip-codes are
returned, then the last one is returned.  The zip-code found is written to STDOUT.

The purpose of this program is for use by TkWeather in order to get the weather
hopefully for the location the user’s computer is actually in.  This is useful if
the user is a frequent traveler and using a laptop.

NOTE:  works for U.S., maybe Canada too; for now.

=cut

use LWP::Simple;

#SITE FOR LOOKING UP USER’S TRUE IP-ADDRESS:
my $ipSite = ‘http://www.ipinfodb.com/’;
#POSTAL SITE FOR LOOKING UP ZIP-CODES FOR CITY, STATE COMBINATIONS:
my $zipSite = "http://zip4.usps.com/zip4/zcl_1_results.jsp?visited=1&pagenumber=0&city=<city>&state=<state>&quot;;

my $html = LWP::Simple::get($ipSite);  #STEP 1:  FETCH IP AND IT’S CITY, STATE; OR ZIP:

if ($html =~ /\<li\>Zip or postal code\s*\:\s*([^\<]+)\<\/li\>/o) {
    $zip = 1;
    if ($zip =~ /\d\d\d\d\d/o) {   #IP INFO INCLUDES A VALID ZIP, RETURN THAT; WE’RE DONE!
        print $zip;
        exit(0);
    }
}
if ($html =~ m#\<li\>State\/Province\s*\:\s*([^\<]+)\<\/li\>#o) {  #EXTRACT THE STATE (SITE CURRENTLY RETURNS A FULL STATE NAME):
    $state = $1;
    my %stateHash = (
            ‘TEXAS’ => ‘TX’,
            ‘ALABAMA’ => ‘AL’,
            ‘ALASKA’ => ‘AK’,
            ‘ALBERTA’ => ‘AB’,
            ‘ARIZONA’ => ‘AZ’,
            ‘ARKANSAS’ => ‘AR’,
            ‘BRITISH COLUMBIA’ => ‘BC’,
            ‘CALIFORNIA’ => ‘CA’,
            ‘COLORADO’ => ‘CO’,
            ‘CONNECTICUT’ => ‘CT’,
            ‘DELAWARE’ => ‘DE’,
            ‘DISTRICT OF COLUMBIA’ => ‘DC’,
            ‘FLORIDA’ => ‘FL’,
            ‘GEORGIA’ => ‘GA’,
            ‘HAWAII’ => ‘HI’,
            ‘IDAHO’ => ‘ID’,
            ‘ILLINOIS’ => ‘IL’,
            ‘INDIANA’ => ‘IN’,
            ‘IOWA’ => ‘IA’,
            ‘KANSAS’ => ‘KS’,
            ‘KENTUCKY’ => ‘KY’,
            ‘LOUISIANA’ => ‘LA’,
            ‘MAINE’ => ‘ME’,
            ‘MANITOBA’ => ‘MB’,
            ‘MARYLAND’ => ‘MD’,
            ‘MASSACHUSETTS’ => ‘MA’,
            ‘MICHIGAN’ => ‘MI’,
            ‘MINNESOTA’ => ‘MN’,
            ‘MISSISSIPPI’ => ‘MS’,
            ‘MISSOURI’ => ‘MO’,
            ‘MONTANA’ => ‘MT’,
            ‘NEBRASKA’ => ‘NE’,
            ‘NEVADA’ => ‘NV’,
            ‘NEW BRUNSWICK’ => ‘NB’,
            ‘NEW HAMPSHIRE’ => ‘NH’,
            ‘NEW JERSEY’ => ‘NJ’,
            ‘NEW MEXICO’ => ‘NM’,
            ‘NEW YORK’ => ‘NY’,
            ‘NEWFOUNDLAND AND LABRADOR’ => ‘NF’,
            ‘NORTH CAROLINA’ => ‘NC’,
            ‘NORTH DAKOTA’ => ‘ND’,
            ‘NORTHWEST TERRITORIES’ => ‘NT’,
            ‘NOVA SCOTIA’ => ‘NS’,
            ‘OHIO’ => ‘OH’,
            ‘OKLAHOMA’ => ‘OK’,
            ‘ONTARIO’ => ‘ON’,
            ‘OREGON’ => ‘OR’,
            ‘PENNSYLVANIA’ => ‘PA’,
            ‘PRINCE EDWARD ISLAND’ => ‘PE’,
            ‘QUEBEC’ => ‘QC’,
            ‘RHODE ISLAND’ => ‘RI’,
            ‘SASKATCHEWAN’ => ‘SK’,
            ‘SOUTH CAROLINA’ => ‘SC’,
            ‘SOUTH DAKOTA’ => ‘SD’,
            ‘TENNESSEE’ => ‘TN’,
            ‘UTAH’ => ‘UT’,
            ‘VERMONT’ => ‘VT’,
            ‘VIRGINIA’ => ‘VA’,
            ‘WASHINGTON’ => ‘WA’,
            ‘WEST VIRGINIA’ => ‘WV’,
            ‘WISCONSIN’ => ‘WI’,
            ‘WYOMING’ => ‘WY’,
            ‘YUKON’ => ‘YT’
    );
    $state =~ tr/a-z/A-Z/;
    $state = $stateHash{$state}  if (defined $stateHash{$state});  #CONVERT STATE NAMES TO PROPER CODE:
}
if ($html =~ /\<li\>City\s*\:\s*([^\<]+)\<\/li\>/) {   #EXTRACT THE CITY:
    $city = $1;
}

if ($city && $state) {    #WE HAVE A VALID CITY, STATE – NOW TRY TO FETCH A ZIP-CODE:
    $zipSite =~ s/\<city\>/$city/g;
    $zipSite =~ s/\<state>/$state/g;
    $html = LWP::Simple::get($zipSite);
    while ($html =~ s!\<td valign\=\"top\" class\=\"main\" style\=\"background\:url\(images\/table_gray.gif\); padding\:5px 10px\;\" headers\=\"units\"\>\s*(\d+)!!s) {
        $zip = $1;
    }
    print $zip;
    exit(0);
}

print ”;
exit(1);   

__END__

 

Advertisements

Feel Free to Comment (Name/Email/Website optional):

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: