Tags:
geolocation1Add my vote for this tag twiki_application1Add my vote for this tag create new tag
, view all tags

Free Geolocation Lookup - Where is This Website or IP Address?

2012-08-14 - 05:57:11 by PeterThoeny in Applications
What is TWiki?
A leading open source enterprise wiki and web application platform used by 50,000 small businesses, many Fortune 500 companies, and millions of people.
MOVED TO... Learn more.
This blog post has two purposes:
  1. Free application to find the geolocation (geographical location) of an Internet domain name or an IP (Internet Protocol) address. Multiple addresses can be specified.
  2. How-to: This application uses TWiki's GeoLookupPlugin and some SpreadSheetPlugin magic to provide real-time lookup of addresses. Scroll down to learn how this works; this is a good learning opportunity for TWiki application developers.

IP Address / Domain Name(s)
Lookup For City Region Country Phone Area Code Longitude Latitude Map Map
54.205.223.200 Ashburn VA USA 703 -77.4838 39.0335 View map

View Larger Map

How this works:

Each website has an IP address. For example, when you enter http://twiki.org/ in your browser, it does a DNS (Domain Name Service) lookup to find its the IP address of that domain. It then sends a request to that IP address to return the website content.

There are databases that map IP addresses to physical locations. This is used for geoloction. There are various use cases, such as fraud detection, ad serving, traffic analytics, content customization, proxy detection, and more.

TWiki has a GeoLookupPlugin that can be used to retrieve geolocation by IP address or domain name. This includes latitude/longitude, city, region, country name and code, postal code, metropolitan code and telephone area code. The plugin uses free geolocation data provided by MaxMind.

Here is a TWiki specific example: To lookup the geolocation of your device (using IP address 54.205.223.200) you type %GEOLOOKUP{%REMOTE_ADDR%}% in a TWiki page, which returns Ashburn, VA, USA.

The geolocation lookup form on top of this page uses an HTML form. Here is a simplified version:

Code:

#GeoLookup
<form action="%SCRIPTURL{view}%/%WEB%/%TOPIC%#GeoLookup">
IP Address:
<input type="text" name="addr" value="%URLPARAM{
   "addr" default="%REMOTE_ADDR%" }%" />
<input type="submit" value="Lookup" />
</form>

Geolocation:
%GEOLOOKUP{%URLPARAM{ "addr" default="%REMOTE_ADDR%" }%}%
Renders as:

IP Address:

Geolocation: Ashburn, VA, USA

The HTML form action is %SCRIPTURL{view}%/%WEB%/%TOPIC%#GeoLookup", which points back to the anchor named "#GeoLookup" on the current page. That anchor is defined just above the form, e.g. we conveniently scroll back to the form when we submit the form.

The HTML form has an input field named "addr". The value is initialized with the URL parameter of the same name, e.g. after submitting the form, the IP address is shown in the input field. In case the URL parameter is missing, a default is used. The default is the IP address of the remote user, e.g. the device the user is using to look at this page.

Below the HTML form we place the GEOLOOKUP variable of the GeoLookupPlugin. Again, the IP address of the remote user is used in case the URL parameter named "addr" is missing, e.g. the location of the user's device is shown by default.

The geolocation lookup form on top of this page is more complex. It accepts multiple IP addresses & domains, it shows a table with the resulting geolocation of each address specified, and a Google map shows the location of the first IP address. In addition, the user input is sanitized so that we can reliably lookup multiple addresses. The next section explains the details.

Advanced TWiki Application programming:

First we create a sanitized list of the addresses, and assign it to a SpreadSheetPlugin variable. For example, %CALCULATE{$SET(ip, %REMOTE_ADDR%)}% assigns the IP address of the remote user to a variable called ip, which can later be retrieved with the $GET(ip) spreadsheet function. The actual sanitation is a real monster formula, shown here spaced out with indentation for clarity - please note that the SpreadSheetPlugin does not support newlines with indentation:

%CALCULATE{
  $SET(ip, 
    $TRANSLATE(
      $SUBSTITUTE(
        $TRIM(
          $SUBSTITUTE(
            $SUBSTITUTE(
              $TRANSLATE(
                %URLPARAM{ "ip" default="%REMOTE_ADDR%" }%,
                $n$comma;"',
                $sp$sp$sp$sp$sp
              ),
              https?://,,,r
            ),
            /([^ ]*|$),,,r
          )
        ),
        [ ],;_,,r
      ),
      ;_,
      $comma$sp
    )
  )
}%
Reading this inside out:

  • We get the value of the URL parameter named ip, defaulting it to the remote user's IP address - it may contain multiple addresses separated by space or comma-space.
  • Using $TRANSLATE() we convert newlines, commas, semicolons and quotes into spaces.
  • Using $SUBSTITUTE() we remove http:// and https:// domain prefixes, if any.
  • Using $SUBSTITUTE() again we remove any trailing URL path from the domain name, if any.
  • Using $TRIM() we trim away multiple spaces between addresses.
  • Using $SUBSTITUTE() with a regular expression, we convert each space into ;_ (semi-colon and underscore). The end goal is actually a comma-space delimited list; we can't do this directly because $SUBSTITUTE() accepts a variable number of parameters.
  • Using $TRANSLATE() we convert all ;_ sequences into comma-space.
  • Using $SET() we assign the comma-space delimited list to a variable named ip, to be used in the HTML input field, the results table, and the Google map.

The HTML input field looks like this:

<input type="text" name="ip" value="%ENCODE{ "%CALCULATE{$GET(ip)}%" type="entity" }%" size="90" id="ip" class="twikiInputField" />

The value of the input field named "ip" is initialized with the entity-encoded value of the spreadsheet variable ip we initialized earlier. It needs to be entity-encoded.

Now on to generating the results table with the geolocation lookup. The table is generated dynamically with a spreadsheet formula. Here it is, indented again for clarifiction:

%CALCULATE{
  $LISTJOIN(
    $n,
    $LISTMAP(
      $NOP(%)GEOLOOKUP{
        "$item"
        format="| $item | $city | $region | $country_name
          | $area_code | $longitude | $latitude
          | <a href='http://maps.google.com/maps?
          q=$latitude%2c$longitude&amp;z=12&amp;source=embed'>
          View map</a> |"
      }$NOP(%),
      $GET(ip)
    )
  )
}%
Reading this inside out:

  • Using $GET(ip) we retrieve the comma separated list of IP addresses - this could also be a single address.
  • Using $LISTMAP() we apply a function to each element in the list. In our case we do a %GEOLOOKUP{}% with each $item, and format the output into a table row. We have to delay the lookup so that it is executed once per item, not one time before the spreadsheet calculation. This delay is induced by escaping the % percent sign with $NOP(%).
  • Using $LISTJOIN() we convert the comma list (of table rows) into a newline separated list, one for each table row, e.g. we convert the list into table rows.

Finally we embed a Google map into the page. Initially we retrieve the first element of the list, then we calculate the latitude and longitude of that address. We use this to compose the source URL of the iframe:

Get Involved!
TWiki is an open source project with 10+ years of history, built by a team of volunteers from around the world, and used by millions of people in over 100 countries. The community is focusing on building the best collaboration platform for the workplace. We invite you to get involved!
%CALCULATE{
  $SET(
    ll,
    %GEOLOOKUP{
      "%CALCULATE{
        $LISTITEM(
          1,
          $GET(ip)
        )
      }%"
      format="$latitude,$longitude"
    }%
  )
}%
<iframe
  width="700"
  height="400"
  frameborder="0"
  scrolling="no"
  marginheight="0"
  marginwidth="0"
  src="http://maps.google.com/maps?
    q=%ENCODE{%CALCULATE{$GET(ll)}%}%
    &amp;z=12&amp;output=embed">
</iframe>
Reading this inside out:

  • Using $GET(ip) we retrieve the comma separated list of IP addresses - this could also be a single address.
  • Using $LISTITEM() we pick the first element (e.g. IP address) of the list.
  • The resulting address is passed into GEOLOOKUP, and formatted to $latitude,$longitude, e.g. we get a comma separated list of latitude and longitude.
  • Using $SET() we assign the resulting latitude and longitude to a variable named ll
  • In the iframe src parameter, we compose the URL by URL-encoding the ll variable we defined earlier.

That's it. Now you learned some advanced TWiki application programming. I hope this was useful. I am looking forward to getting feedback.

-- PeterThoeny, founder TWiki.org - 2012-08-13

Related:

Comments

.

Edit | Attach | Watch | Print version | History: r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r2 - 2012-08-14 - PeterThoeny
 

Twitter Delicious Facebook Digg Google Bookmarks E-mail LinkedIn Reddit StumbleUpon    
  • Help
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.