#! /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!"