#! /bin/env python
import httplib # Client-side mojo
import os.path # Removes cruft from program name
from sys import argv # Program name and MAC address fragments
import re # Zawinski sez, "Now we have two problems."
try: # Parse MAC address from command line
mac = ':'.join(argv[1:]) # Paste together whitespace-separated digits
mac = mac.split(':') # Tear 'em back apart into digits list
mac = ''.join(mac) # Paste 'em back together without ':'s
if len(mac) != 12: # Check for 12 digits left
raise SyntaxError # and raise Hell if not.
mac = int(mac, 16) # Convert result to 48-bit integer
except: # If something FUBAR,
N = os.path.basename(argv[0]) # Remove cruft from program name
quit("Usage: " # Issue usage message
"%s 01 23 45 67 89 AB -or- "
"%s 01:23:45:67:89:AB"%(N,N))
# Request is made with XML hairball. XML is "human readable". Riiiight....
request = """
beta
js.loki.com
%012X
-50
""" % mac
# Hammer XML into single-line. I'm not sure if this is needed, but example
# code (both in Ruby and using curl) did. See:
#
# http://coderrr.wordpress.com/2008/09/10/get-the-physical-location-of-
# wireless-router-from-its-mac-address-bssid/
#
# NOTE: A little experimentation indicates that at least *some* reformatting
# is required.
request = request.split() # List of lines in hairball
request = "".join( # Include spaces before attributes
[l if l.startswith('<') else # Paste together into one long line.
' '+l for l in request])
http = httplib.HTTPSConnection( # Open secure TCP connection to port
'api.skyhookwireless.com', 443) # 443 at Skyhook Wireless.
http.request('POST', '/wps2/location', # Ask politely for location of WAP
request, {'Content-Type':'text/xml'}) # with command-line-specified MAC
response = http.getresponse().read() # See if Skyhook has heard of it.
http.close() # Drop connection (needed?)
field = re.compile( # RE to extract ('foo', 'bar') from
r'<([^/][^ >]+)[^>]*>([^<]+)[^>]+>')# "...bar..."
result = dict(field.findall(response)) # Compose a dictionary of such fields
try:
print " Latitude: %+11s" % result["latitude"]
print "Longitude: %+11s" % result["longitude"]
print " Address:", result["street-number"], result["address-line"]
print " %s, %s %s" % (result["city"],
result["state"], result["postal-code"])
except:
print "Karl hasn't found you yet, Winston."
print " INGNORANCE IS STRENGTH!"