Skip to content

Instantly share code, notes, and snippets.

@xarg
Last active December 18, 2015 19:19
Show Gist options
  • Save xarg/5832519 to your computer and use it in GitHub Desktop.
Save xarg/5832519 to your computer and use it in GitHub Desktop.
Fix Capsule CRM addresses using Google Geocoding API
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Using google geocoding API try to fix addresses in capsule
"""
import sys
import argparse
import requests
import urllib
import logging
import json
logging.basicConfig()
logger = logging.getLogger(__file__)
logger.setLevel(logging.INFO)
GEOCODING_API_URL = "http://maps.googleapis.com/maps/api/geocode/json?address=%s&sensor=false"
CAPSULE_API_URL = ""
CAPSULE_API_KEY = ""
def fetch_addresses(party):
"""Go to the google api and fetch a new address """
results = []
addresses = party['contacts']['address']
if isinstance(addresses, dict):
addresses = [addresses]
for address in addresses:
street = address.get('street', "").encode('utf-8')
city = address.get('city', "").encode('utf-8')
region = address.get('state', "").encode('utf-8')
postal_code = address.get('zip', "").encode('utf-8')
country = address.get('country', "").encode('utf-8')
if street:
street = street.replace("\r", "")
# try first with the whole street
query = "%s %s %s %s %s" % (street, city, region, postal_code, country)
query = urllib.quote(query, safe="")
r = requests.get(GEOCODING_API_URL % query)
adata = r.json()
if adata['status'] != 'ZERO_RESULTS':
results.extend(adata['results'])
street_pieces = street.split("\n")
if len(street_pieces) > 1:
for piece in street_pieces:
piece = piece.strip()
if piece:
query = "%s %s %s %s %s" % (street, city, region, postal_code, country)
query = urllib.quote(query, safe="")
r = requests.get(GEOCODING_API_URL % urllib.quote(piece, safe=""))
adata = r.json()
if adata['status'] == 'ZERO_RESULTS':
continue
results.extend(adata['results'])
return results
def print_addreses(addresses):
for i, address in enumerate(addresses):
if 'formatted_address' in address:
print "%d. %s" % (i, address['formatted_address'])
def print_party(party):
"""Given a person structure print some information about it """
print "Capsule URL: " + CAPSULE_API_URL + "/party/" + party['id']
print "Edit URL: " + CAPSULE_API_URL + "/party/%s/edit" % party['id']
print "-" * 10 + "Original Addresses" + "-" * 10
addresses = party['contacts']['address']
if isinstance(addresses, dict):
addresses = [addresses]
for address in addresses:
if 'street' in address and address['street'].strip():
print "\n**Street**\n\n %s" % address['street']
if 'city' in address:
print "\n**City**\n %s" % address['city']
if 'state' in address:
print "\n**Region**\n %s" % address['state']
if 'zip' in address:
print "\n**Postal Code**\n %s" % address['zip']
if 'country' in address:
print "\n**Country**\n %s" % address['country']
def _update_address(new_address, address):
for comp in new_address['address_components']:
if 'street_number' in comp['types']:
address['street'] = comp['long_name'] + " " + address['street']
if 'route' in comp['types']:
address['street'] += comp['long_name']
if 'locality' in comp['types']:
address['city'] = comp['long_name']
if 'administrative_area_level_2' in comp['types']:
address['state'] = comp['long_name']
if 'country' in comp['types']:
address['country'] = comp['long_name']
if 'postal_code' in comp['types']:
address['zip'] = comp['long_name']
return address
def update_org(s, org, address):
"""Update address for the organisation. This will add a new address to the contact. Keeping the original intact"""
data = {
"organisation": {
"contacts": {
"address": {
"street": "",
"city": "",
"state": "",
"zip": "",
"country": "",
}
}
}
}
data["organisation"]["contacts"]["address"] = _update_address(address, data["organisation"]["contacts"]["address"])
r = s.put(CAPSULE_API_URL + '/api/organisation/%s' % org['id'],
data=json.dumps(data))
if r.status_code in (200, 201):
print "Done."
else:
print "Failed!"
sys.exit(0)
def update_person(s, person, address):
"""Update address for the person. This will add a new address to the contact. Keeping the original intact"""
data = {
"person": {
"contacts": {
"address": {
"street": "",
"city": "",
"state": "",
"zip": "",
"country": "",
}
}
}
}
data["person"]["contacts"]["address"] = _update_address(address, data["person"]["contacts"]["address"])
r = s.put(CAPSULE_API_URL + '/api/person/%s' % person['id'], data=json.dumps(data))
if r.status_code in (200, 201):
print "Done."
else:
print "Failed!"
sys.exit(0)
def main(s):
parser = argparse.ArgumentParser(description='Update addresses in Capsule CRM using Google Geocoding API')
parser.add_argument('start', metavar='start', type=int, help='Start range')
parser.add_argument('limit', metavar='limit', type=int, help='Limit')
args = parser.parse_args()
start = args.start
limit = args.limit
# get some people and organisation
print "Fetching parties from %s to %s" % (start, start+limit)
r = s.get(CAPSULE_API_URL + "/api/party?start=%d&limit=%d" % (start, limit))
pdata = r.json()
persons = pdata['parties']['person']
organisations = pdata['parties']['organisation']
print "\n++++Organisations++++\n"
for org in organisations:
if 'contacts' in org and 'address' in org['contacts']:
new_addresses = fetch_addresses(org)
if new_addresses:
print "=" * 10 + "Possible addresses" + "=" * 10 + "\n"
print_addreses(new_addresses)
print "\n" + "=" * 10 + "Original info" + "=" * 10 + "\n"
print_party(org)
print "\n" + "=" * 20 + "\n"
print "Choose an option (or hit Enter to skip):"
address_index = raw_input()
try:
address_index = int(address_index)
except:
print "---- Skipped\n"
continue
print "Updating address..."
update_org(s, org, new_addresses[address_index])
print "\n++++Persons++++\n"
for person in persons:
if 'contacts' in person and 'address' in person['contacts']:
new_addresses = fetch_addresses(person)
if new_addresses:
print "=" * 10 + "Possible addresses" + "=" * 10 + "\n"
print_addreses(new_addresses)
print "\n" + "=" * 10 + "Original info" + "=" * 10 + "\n"
print_party(person)
print "\n" + "=" * 20 + "\n"
print "Choose an option (or hit Enter to skip):"
address_index = raw_input()
try:
address_index = int(address_index)
except:
print "---- Skipped\n"
continue
print "Updating address..."
update_person(s, person, new_addresses[address_index])
print "Finished updating range. Start: %s Limit: %s" % (start, limit)
if __name__ == '__main__':
s = requests.Session()
s.auth = (CAPSULE_API_KEY, "x")
s.headers.update({"Accept": "application/json"})
s.headers.update({"Content-type": "application/json"})
main(s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment