Last active
December 18, 2015 19:19
-
-
Save xarg/5832519 to your computer and use it in GitHub Desktop.
Fix Capsule CRM addresses using Google Geocoding API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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