<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -124,6 +124,18 @@ def PhoneRelType(text):
   return &quot;http://schemas.google.com/g/2005#other&quot;
 
 
+def VcardPhoneType(phone_rel):
+  &quot;&quot;&quot;Given a phone rel type from PhoneRelType, returns the vcard type.&quot;&quot;&quot;
+  vcard_map = {
+    &quot;http://schemas.google.com/g/2005#mobile&quot;: &quot;CELL&quot;,
+    &quot;http://schemas.google.com/g/2005#home&quot;: &quot;HOME&quot;,
+    &quot;http://schemas.google.com/g/2005#work&quot;: &quot;WORK&quot;,
+  }
+  if phone_rel in vcard_map:
+    return vcard_map[phone_rel]
+  return &quot;OTHER&quot;
+
+
 def NewContactEntry(contact, group=None):
   &quot;&quot;&quot;Make a new GData Contact Entry from a submitted contact dict.
 
@@ -297,6 +309,32 @@ class MergeView(webapp.RequestHandler):
           cgi.escape(number[&quot;type&quot;]), cgi.escape(number[&quot;number&quot;])))
 
 
+class VCard(webapp.RequestHandler):
+  &quot;&quot;&quot;Get a vcard.&quot;&quot;&quot;
+
+  def get(self):
+    key = self.request.get('key')
+    if not key:
+      raise &quot;Missing argument 'key'&quot;
+    post_dump = models.PostDump.get(db.Key(key))
+    if not post_dump:
+      raise &quot;State lost?  Um, do it again.&quot;
+
+    contacts = simplejson.loads(post_dump.json)
+    self.response.headers['Content-Type'] = &quot;text/x-vcard; charset=UTF-8&quot;
+    self.response.headers['Content-Disposition'] = &quot;attachment; filename=\&quot;addressbooker.vcf\&quot;&quot;
+
+    for contact in contacts:
+      self.response.out.write(&quot;BEGIN:VCARD\n&quot;)
+      self.response.out.write(&quot;VERSION:3.0\n&quot;)
+      self.response.out.write(&quot;FN:%s\n&quot; % (contact[&quot;name&quot;] or &quot;&quot;))
+      for number in contact[&quot;numbers&quot;]:
+        self.response.out.write(&quot;TEL;type=%s:%s\n&quot; % (
+            VcardPhoneType(PhoneRelType(number[&quot;type&quot;])),
+            number[&quot;number&quot;]))
+      self.response.out.write(&quot;END:VCARD\n&quot;)
+
+
 class MergeGoogle(AddressBookerBaseHandler):
   &quot;&quot;&quot;Merge contacts into Google Contacts w/ Google Contacts API.&quot;&quot;&quot;
 
@@ -473,6 +511,7 @@ def main():
     ('/', AddressBooker),
     ('/submit', Submit),
     ('/menu', Menu),
+    ('/vcard', VCard),
     ('/gcontacts', MergeGoogle), 
     ('/view', MergeView), 
     ('/google72db3d6838b4c438.html', Acker),</diff>
      <filename>addressbooker.py</filename>
    </modified>
    <modified>
      <diff>@@ -3,8 +3,8 @@
 &lt;p&gt;What can I help you do with them?&lt;/p&gt;
 
 &lt;ul&gt;
-&lt;li&gt;&lt;a href=&quot;/view?key={{ key }}&quot;&gt;View them&lt;/a&gt;.
+&lt;li&gt;&lt;a href=&quot;/view?key={{ key|urlencode }}&quot;&gt;View them&lt;/a&gt;.
 &lt;li&gt;Export as CSV. (not done yet)&lt;/li&gt;
-&lt;li&gt;Export as vCard.  (not done yet)&lt;/li&gt;
-&lt;li&gt;&lt;a href=&quot;/gcontacts?key={{ key }}&quot;&gt;Merge into your Google Contacts&lt;/a&gt; for GMail, Android, etc.&lt;/li&gt;
+&lt;li&gt;&lt;a href=&quot;/vcard?key={{ key|urlencode }}&quot;&gt;Export as vCard.&lt;/a&gt; for OS X's Address Book, iPhone, etc.&lt;/li&gt;
+&lt;li&gt;&lt;a href=&quot;/gcontacts?key={{ key|urlencode }}&quot;&gt;Merge into your Google Contacts&lt;/a&gt; for GMail, Android, etc.&lt;/li&gt;
 &lt;/ul&gt;</diff>
      <filename>menu.html</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>bbce276e42957f8d21b9c7d10408e8abd11e4da0</id>
    </parent>
  </parents>
  <author>
    <name>Brad Fitzpatrick</name>
    <email>brad@danga.com</email>
  </author>
  <url>http://github.com/bradfitz/addressbooker/commit/71122ab1745ecc731ad495a5f852bf6f30a2319f</url>
  <id>71122ab1745ecc731ad495a5f852bf6f30a2319f</id>
  <committed-date>2008-11-30T23:27:00-08:00</committed-date>
  <authored-date>2008-11-30T23:27:00-08:00</authored-date>
  <message>vcard support from david recordon, modified slightly</message>
  <tree>eecc6ede3b0c09e86ba2bec05c3e90870508e515</tree>
  <committer>
    <name>Brad Fitzpatrick</name>
    <email>brad@danga.com</email>
  </committer>
</commit>
