<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -39,6 +39,7 @@ See the examples/ directory.
 * Britt Selvitelle from Twitter (mailto:anotherbritt@gmail.com) - http://twitter.com
 * Tony Targonski from GigPark (mailto:tony@gigpark.com) - http://gigpark.com
 * Waheed Barghouthi from Watwet (mailto:waheed.barghouthi@gmail.com) - http://watwet.com
+* Glenn Sidney from Glenn Fu (mailto:glenn@glennfu.com) - http://glennfu.com
 
 This library is released under the terms of the BSD.
 </diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 Gem::Specification.new do |s|
   s.name = &quot;contacts&quot;
-  s.version = &quot;1.0.16&quot;
+  s.version = &quot;1.0.17&quot;
   s.date = &quot;2009-05-06&quot;
   s.summary = &quot;A universal interface to grab contact list information from various providers including Yahoo, Gmail, Hotmail, and Plaxo.&quot;
   s.email = &quot;lucas@rufy.com&quot;</diff>
      <filename>contacts.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -5,6 +5,7 @@ require &quot;uri&quot;
 require &quot;zlib&quot;
 require &quot;stringio&quot;
 require &quot;thread&quot;
+require &quot;erb&quot;
 
 class Contacts
   TYPES = {}
@@ -19,7 +20,7 @@ class Contacts
     end
     
     def connect
-      raise AuthenticationError, &quot;Login and password must not be nil, login: #{@login.inspect}, password: #{@password.inspect}&quot; if @login.nil? || @password.nil?
+      raise AuthenticationError, &quot;Login and password must not be nil, login: #{@login.inspect}, password: #{@password.inspect}&quot; if @login.nil? || @login.empty? || @password.nil? || @password.empty?
       real_connect
     end
     
@@ -92,10 +93,14 @@ class Contacts
       http
     end
     
+    def cookie_hash_from_string(cookie_string)
+      cookie_string.split(&quot;;&quot;).map{|i|i.split(&quot;=&quot;, 2).map{|j|j.strip}}.inject({}){|h,i|h[i[0]]=i[1];h}
+    end
+    
     def parse_cookies(data, existing=&quot;&quot;)
       return existing if data.nil?
 
-      cookies = existing.split(&quot;;&quot;).map{|i|i.split(&quot;=&quot;, 2).map{|j|j.strip}}.inject({}){|h,i|h[i[0]]=i[1];h}
+      cookies = cookie_hash_from_string(existing)
       
       data.gsub!(/ ?[\w]+=EXPIRED;/,'')
       data.gsub!(/ ?expires=(.*?, .*?)[;,$]/i, ';')</diff>
      <filename>lib/contacts/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,36 +9,40 @@ else
   require 'json/add/rails'
 end
 
+class Hash
+  def to_query_string
+    u = ERB::Util.method(:u)
+    map { |k, v|
+      u.call(k) + &quot;=&quot; + u.call(v)
+    }.join(&quot;&amp;&quot;)
+  end
+end
+
 class Contacts
   class Gmail &lt; Base
     URL                 = &quot;https://mail.google.com/mail/&quot;
     LOGIN_URL           = &quot;https://www.google.com/accounts/ServiceLoginAuth&quot;
-    LOGIN_REFERER_URL   = &quot;https://www.google.com/accounts/ServiceLogin?service=mail&amp;passive=true&amp;rm=false&amp;continue=http%3A%2F%2Fmail.google.com%2Fmail%3Fui%3Dhtml%26zy%3Dl&amp;ltmpl=yj_blanco&amp;ltmplcache=2&amp;hl=en&quot;
+    LOGIN_REFERER_URL   = &quot;https://www.google.com/accounts/ServiceLogin?service=mail&amp;passive=true&amp;rm=false&amp;continue=http%3A%2F%2Fmail.google.com%2Fmail%2F%3Fui%3Dhtml%26zy%3Dl&amp;bsv=zpwhtygjntrz&amp;scc=1&amp;ltmpl=default&amp;ltmplcache=2&quot;
     CONTACT_LIST_URL    = &quot;https://mail.google.com/mail/contacts/data/contacts?thumb=true&amp;show=ALL&amp;enums=true&amp;psort=Name&amp;max=10000&amp;out=js&amp;rf=&amp;jsx=true&quot;
     PROTOCOL_ERROR      = &quot;Gmail has changed its protocols, please upgrade this library first. If that does not work, dive into the code and submit a patch at http://github.com/cardmagic/contacts&quot;
     
     def real_connect
-      postdata =  &quot;ltmpl=yj_blanco&quot;
-      postdata += &quot;&amp;continue=%s&quot; % CGI.escape(URL)
-      postdata += &quot;&amp;ltmplcache=2&quot;
-      postdata += &quot;&amp;service=mail&quot;
-      postdata += &quot;&amp;rm=false&quot;
-      postdata += &quot;&amp;ltmpl=yj_blanco&quot;
-      postdata += &quot;&amp;hl=en&quot;
-      postdata += &quot;&amp;Email=%s&quot; % CGI.escape(login)
-      postdata += &quot;&amp;Passwd=%s&quot; % CGI.escape(password)
-      postdata += &quot;&amp;rmShown=1&quot;
-      postdata += &quot;&amp;null=Sign+in&quot;
+      postdata = {
+        &quot;Email&quot; =&gt; login,
+        &quot;Passwd&quot; =&gt; password,
+        &quot;PersistentCookie&quot; =&gt; &quot;yes&quot;,
+        &quot;asts&quot; =&gt; &quot;&quot;,
+        &quot;rmShown&quot; =&gt; &quot;1&quot;,
+        &quot;signIn&quot; =&gt; CGI.escape(&quot;Sign in&quot;)
+      }
             
-      time =      Time.now.to_i
-      time_past = Time.now.to_i - 8 - rand(12)
-      cookie =    &quot;GMAIL_LOGIN=T#{time_past}/#{time_past}/#{time}&quot;
-      
-      data, resp, cookies, forward, old_url = post(LOGIN_URL, postdata, cookie, LOGIN_REFERER_URL) + [LOGIN_URL]
-      
-      cookies = remove_cookie(&quot;GMAIL_LOGIN&quot;, cookies)
+      # Get this cookie and stick it in the form to confirm to Google that your cookies work
+      data, resp, cookies, forward = get(LOGIN_REFERER_URL)
+      postdata[&quot;GALX&quot;] = cookie_hash_from_string(cookies)[&quot;GALX&quot;]
 
-      if data.index(&quot;Username and password do not match&quot;) || data.index(&quot;New to Gmail? It's free and easy&quot;)
+      data, resp, cookies, forward, old_url = post(LOGIN_URL, postdata.to_query_string, cookies, LOGIN_REFERER_URL) + [LOGIN_REFERER_URL]
+      
+      if data.index(&quot;Username and password do not match&quot;)
         raise AuthenticationError, &quot;Username and password do not match&quot;
       elsif data.index(&quot;The username or password you entered is incorrect&quot;)
         raise AuthenticationError, &quot;Username and password do not match&quot;
@@ -65,7 +69,7 @@ class Contacts
       data.gsub!(/ &amp;&amp;&amp;END&amp;&amp;&amp;$/, '')
       data.gsub!(/\t/, ' ') # tabs in the note field cause errors with JSON.parse
       data.gsub!(/[\t\x00-\x1F]/, &quot; &quot;) # strip control characters
-
+      
       @contacts = JSON.parse(data)['Body']['Contacts'] || {}
 
       # Determine in which format to return the data.</diff>
      <filename>lib/contacts/gmail.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>8069551c9308ca53e4340a95a406c504a76b6809</id>
    </parent>
  </parents>
  <author>
    <name>Lucas Carlson</name>
    <email>lucas@rufy.com</email>
  </author>
  <url>http://github.com/cardmagic/contacts/commit/d3d3b4c39e639f8c72c755e57f0d9f05b78d9441</url>
  <id>d3d3b4c39e639f8c72c755e57f0d9f05b78d9441</id>
  <committed-date>2009-10-28T11:50:53-07:00</committed-date>
  <authored-date>2009-10-28T11:50:53-07:00</authored-date>
  <message>Big thanks to giannichiappetta for fixes for gmail import</message>
  <tree>a01870d1505292b606d6126806f9ef7607957e7f</tree>
  <committer>
    <name>Lucas Carlson</name>
    <email>lucas@rufy.com</email>
  </committer>
</commit>
