#!/usr/bin/env python
# requires: python-vobject
# license: Creative Commons Zero

import warnings
from optparse import OptionParser

parser = OptionParser(description="""Converts a vcard file (on stdin) to CSV (on stdout).
Vcards without GEO fields are ignored. If the NOTES field contains 'gps-uncertain',
then ' ?' is appended to the name. CSV fields are name, latitude, and longitude.""")

(options, args) = parser.parse_args()

import vobject, csv, os, sys

def tuplekey(tuple):
 """Return lowercase string of tuple's first item.

 >>> ttuple = ('Doe, John', 10, -10)
 >>> tuplekey(ttuple)
 'doe, john'
 """
 return tuple[0].lower()

points = []
for vcard in vobject.readComponents(sys.stdin):
 try:
  geolist = vcard.geo_list
 except AttributeError:
  pass
 else:
  for geo in geolist:
   name = vcard.n.value.family + ', ' + vcard.n.value.given
   try:
    types = '_' + ','.join(sorted(geo.params['TYPE']))
   except KeyError:
    types = ''
   try:
    note = vcard.note.value
   except AttributeError:
    uncertain = ''
   else:
    if 'gps-uncertain' in note.lower():
     uncertain = ' ?'
    else:
     uncertain = ''
   desc = name + types + uncertain
   lat, lon = geo.value.replace('geo:','').replace('+','').split(';')
   points.append((desc, lat, lon),)

points.sort(key=tuplekey)

twriter = csv.writer(sys.stdout, delimiter=',', quoting=csv.QUOTE_MINIMAL, escapechar='\\')
twriter.writerow(('name', 'latitude', 'longitude'))
for record in points:
 twriter.writerow((record[0], record[1], record[2]))
