#!/usr/bin/env python

# Code almost completely taken from https://code.google.com/p/geolocate-cli/
# by 2010 Francis Markham
#
# Turned into single simple python command by Paul Wouters <pwouters@redhat.com>
#
# This program is free software: you can redistribute it and/or modify it 
# under the terms of the GNU General Public License as published by 
# the Free Software Foundation, either version 3 of the License, or 
# (at your option) any later version. This program is distributed in the 
# hope that it will be useful, but WITHOUT ANY WARRANTY; without 
# even the implied warranty of MERCHANTABILITY or FITNESS FOR 
# A PARTICULAR PURPOSE. See the GNU General Public License 
# for more details. You should have received a copy of the GNU General 
# Public License along with this program. If not, see <http://www.gnu.org/licenses/>. 

import dbus, sys, os
import urllib2
import argparse
try:
    import json
except ImportError:
    import simplejson as json 


def main():
	parser = argparse.ArgumentParser(description="geome verbose or not")
	parser.add_argument('-q', '--quiet', action='store_true',help='quiet mode, only prints lat and long')
	parser.add_argument('-s', '--silent', action='store_true',help='quiet mode, only prints lat and long')
	parser.add_argument('-v', '--version', action='store_true',help='show version and exit')
	args = parser.parse_args(sys.argv[1:])

	if args.version:
		sys.exit("geome: version 1.1")
	if args.silent or args.quiet:
		verbose = False
	else:
		verbose = True
	printLocation(verbose)

def printLocation(verbose):

	__NM_DEVICE_TYPE_802_11_WIRELESS = 2
	url = "https://www.google.com/loc/json"
	useragent = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.8) Gecko/20110405 Fedora/1x Firefox/3.5"

	devices = ""
	try:
		bus = dbus.SystemBus()
		nm = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager')
		devices = nm.GetDevices()
	except:
		pass

	aps = []
	for path in devices:
		device = bus.get_object('org.freedesktop.NetworkManager', path)
		device_props = dbus.Interface(device, dbus_interface='org.freedesktop.DBus.Properties')
		props = device_props.GetAll("org.freedesktop.NetworkManager.Device")

		# Different magic seems to be required on different versions of networkmanager
		try:
			devtype = props["DeviceType"]
		except KeyError:
			devtype = device.Get("org.freedesktop.NetworkManager.Device", 'DeviceType')

		if devtype != __NM_DEVICE_TYPE_802_11_WIRELESS:
	                    continue

		access_points = device.GetAccessPoints()

		for network_path in access_points:
			if not network_path:
				# No active network
				continue
			network = bus.get_object('org.freedesktop.NetworkManager', network_path)
			network_props = dbus.Interface(network, dbus_interface='org.freedesktop.DBus.Properties')
			ssid = network_props.Get("org.freedesktop.NetworkManager.AccessPoint", "Ssid", byte_arrays=True)
			mac = network_props.Get("org.freedesktop.NetworkManager.AccessPoint", "HwAddress")
			sig_str = network_props.Get("org.freedesktop.NetworkManager.AccessPoint", "Strength")
			aps.append({"ssid": str(ssid), "mac": str(mac), "signal_strength": int(sig_str)})


	post_str = "{\"version\":\"1.1.0\", \"request_address\":\"true\", \"wifi_towers\":["
	if not aps:
		post_str += '{} '

	for ap in aps:
		ap_strs = []
		pairs = []
		if 'ssid' in ap:
			pairs.append("\"ssid\":\"%s\"" % ap['ssid'])
		if 'mac' in ap:
			pairs.append("\"mac_address\":\"%s\"" % ap['mac'])
		if 'signal_strength' in ap:
			pairs.append("\"signal_strength\":\"%d\"" % ap['signal_strength'])
		ap_strs.append('{' + ','.join(pairs) + '}')
		post_str += ','.join(ap_strs)
		post_str += ","
	post_str = post_str[:-1] + "]}"

	req = urllib2.Request(url, post_str, {'User-agent' : useragent })
	u = urllib2.urlopen(req)
	result = json.loads(u.read())
	if result:
		r = {}
		r['lat'] = result['location']['latitude']
		r['long'] = result['location']['longitude']
		r['accuracy'] = result['location']['accuracy']
		if result['location'].has_key('address'):
			for (key, val) in result['location']['address'].items():
				r[key] = val
		if verbose == True:
			print json.dumps(r)
		else:
			print "%s,%s"%(r['lat'], r['long'])

if __name__ == "__main__":
        main()

