Permalink
Browse files

Big thanks to giannichiappetta for fixes for gmail import

  • Loading branch information...
1 parent 8069551 commit d3d3b4c39e639f8c72c755e57f0d9f05b78d9441 Lucas Carlson committed Oct 28, 2009
Showing with 34 additions and 24 deletions.
  1. +1 −0 README
  2. +1 −1 contacts.gemspec
  3. +7 −2 lib/contacts/base.rb
  4. +25 −21 lib/contacts/gmail.rb
View
1 README
@@ -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.
View
@@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = "contacts"
- s.version = "1.0.16"
+ s.version = "1.0.17"
s.date = "2009-05-06"
s.summary = "A universal interface to grab contact list information from various providers including Yahoo, Gmail, Hotmail, and Plaxo."
s.email = "lucas@rufy.com"
View
@@ -5,6 +5,7 @@
require "zlib"
require "stringio"
require "thread"
+require "erb"
class Contacts
TYPES = {}
@@ -19,7 +20,7 @@ def initialize(login, password)
end
def connect
- raise AuthenticationError, "Login and password must not be nil, login: #{@login.inspect}, password: #{@password.inspect}" if @login.nil? || @password.nil?
+ raise AuthenticationError, "Login and password must not be nil, login: #{@login.inspect}, password: #{@password.inspect}" if @login.nil? || @login.empty? || @password.nil? || @password.empty?
real_connect
end
@@ -92,10 +93,14 @@ def open_http(url)
http
end
+ def cookie_hash_from_string(cookie_string)
+ cookie_string.split(";").map{|i|i.split("=", 2).map{|j|j.strip}}.inject({}){|h,i|h[i[0]]=i[1];h}
+ end
+
def parse_cookies(data, existing="")
return existing if data.nil?
- cookies = existing.split(";").map{|i|i.split("=", 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, ';')
View
@@ -9,36 +9,40 @@ def self.parse(i)
require 'json/add/rails'
end
+class Hash
+ def to_query_string
+ u = ERB::Util.method(:u)
+ map { |k, v|
+ u.call(k) + "=" + u.call(v)
+ }.join("&")
+ end
+end
+
class Contacts
class Gmail < Base
URL = "https://mail.google.com/mail/"
LOGIN_URL = "https://www.google.com/accounts/ServiceLoginAuth"
- LOGIN_REFERER_URL = "https://www.google.com/accounts/ServiceLogin?service=mail&passive=true&rm=false&continue=http%3A%2F%2Fmail.google.com%2Fmail%3Fui%3Dhtml%26zy%3Dl&ltmpl=yj_blanco&ltmplcache=2&hl=en"
+ LOGIN_REFERER_URL = "https://www.google.com/accounts/ServiceLogin?service=mail&passive=true&rm=false&continue=http%3A%2F%2Fmail.google.com%2Fmail%2F%3Fui%3Dhtml%26zy%3Dl&bsv=zpwhtygjntrz&scc=1&ltmpl=default&ltmplcache=2"
CONTACT_LIST_URL = "https://mail.google.com/mail/contacts/data/contacts?thumb=true&show=ALL&enums=true&psort=Name&max=10000&out=js&rf=&jsx=true"
PROTOCOL_ERROR = "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"
def real_connect
- postdata = "ltmpl=yj_blanco"
- postdata += "&continue=%s" % CGI.escape(URL)
- postdata += "&ltmplcache=2"
- postdata += "&service=mail"
- postdata += "&rm=false"
- postdata += "&ltmpl=yj_blanco"
- postdata += "&hl=en"
- postdata += "&Email=%s" % CGI.escape(login)
- postdata += "&Passwd=%s" % CGI.escape(password)
- postdata += "&rmShown=1"
- postdata += "&null=Sign+in"
+ postdata = {
+ "Email" => login,
+ "Passwd" => password,
+ "PersistentCookie" => "yes",
+ "asts" => "",
+ "rmShown" => "1",
+ "signIn" => CGI.escape("Sign in")
+ }
- time = Time.now.to_i
- time_past = Time.now.to_i - 8 - rand(12)
- cookie = "GMAIL_LOGIN=T#{time_past}/#{time_past}/#{time}"
-
- data, resp, cookies, forward, old_url = post(LOGIN_URL, postdata, cookie, LOGIN_REFERER_URL) + [LOGIN_URL]
-
- cookies = remove_cookie("GMAIL_LOGIN", 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["GALX"] = cookie_hash_from_string(cookies)["GALX"]
- if data.index("Username and password do not match") || data.index("New to Gmail? It's free and easy")
+ data, resp, cookies, forward, old_url = post(LOGIN_URL, postdata.to_query_string, cookies, LOGIN_REFERER_URL) + [LOGIN_REFERER_URL]
+
+ if data.index("Username and password do not match")
raise AuthenticationError, "Username and password do not match"
elsif data.index("The username or password you entered is incorrect")
raise AuthenticationError, "Username and password do not match"
@@ -65,7 +69,7 @@ def parse(data, options)
data.gsub!(/ &&&END&&&$/, '')
data.gsub!(/\t/, ' ') # tabs in the note field cause errors with JSON.parse
data.gsub!(/[\t\x00-\x1F]/, " ") # strip control characters
-
+
@contacts = JSON.parse(data)['Body']['Contacts'] || {}
# Determine in which format to return the data.

0 comments on commit d3d3b4c

Please sign in to comment.