lib/omnicontacts/importer/gmail.rb in omnicontacts-0.3.4 vs lib/omnicontacts/importer/gmail.rb in omnicontacts-0.3.5
- old
+ new
@@ -11,21 +11,30 @@
def initialize *args
super *args
@auth_host = "accounts.google.com"
@authorize_path = "/o/oauth2/auth"
@auth_token_path = "/o/oauth2/token"
- @scope = "https://www.google.com/m8/feeds"
+ @scope = "https://www.google.com/m8/feeds https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/userinfo.profile"
@contacts_host = "www.google.com"
@contacts_path = "/m8/feeds/contacts/default/full"
@max_results = (args[3] && args[3][:max_results]) || 100
+ @self_host = "www.googleapis.com"
+ @profile_path = "/oauth2/v1/userinfo"
end
def fetch_contacts_using_access_token access_token, token_type
+ fetch_current_user(access_token, token_type)
contacts_response = https_get(@contacts_host, @contacts_path, contacts_req_params, contacts_req_headers(access_token, token_type))
contacts_from_response contacts_response
end
+ def fetch_current_user access_token, token_type
+ self_response = https_get(@self_host, @profile_path, contacts_req_params, contacts_req_headers(access_token, token_type))
+ user = current_user(self_response, access_token, token_type)
+ set_current_user user
+ end
+
private
def contacts_req_params
{'max-results' => @max_results.to_s, 'alt' => 'json'}
end
@@ -36,38 +45,165 @@
def contacts_from_response response_as_json
response = JSON.parse(response_as_json)
return [] if response['feed'].nil? || response['feed']['entry'].nil?
contacts = []
+ return contacts if response.nil?
response['feed']['entry'].each do |entry|
# creating nil fields to keep the fields consistent across other networks
- contact = {:id => nil, :first_name => nil, :last_name => nil, :name => nil, :email => nil, :gender => nil, :birthday => nil, :profile_picture=> nil, :relation => nil}
+
+ contact = { :id => nil,
+ :first_name => nil,
+ :last_name => nil,
+ :name => nil,
+ :emails => nil,
+ :gender => nil,
+ :birthday => nil,
+ :profile_picture=> nil,
+ :relation => nil,
+ :addresses => nil,
+ :phone_numbers => nil,
+ :dates => nil,
+ :company => nil,
+ :position => nil
+ }
contact[:id] = entry['id']['$t'] if entry['id']
if entry['gd$name']
gd_name = entry['gd$name']
contact[:first_name] = normalize_name(entry['gd$name']['gd$givenName']['$t']) if gd_name['gd$givenName']
contact[:last_name] = normalize_name(entry['gd$name']['gd$familyName']['$t']) if gd_name['gd$familyName']
contact[:name] = normalize_name(entry['gd$name']['gd$fullName']['$t']) if gd_name['gd$fullName']
contact[:name] = full_name(contact[:first_name],contact[:last_name]) if contact[:name].nil?
end
- contact[:email] = entry['gd$email'][0]['address'] if entry['gd$email']
+ contact[:emails] = []
+ entry['gd$email'].each do |email|
+ if email['rel']
+ split_index = email['rel'].index('#')
+ contact[:emails] << {:name => email['rel'][split_index + 1, email['rel'].length - 1], :email => email['address']}
+ elsif email['label']
+ contact[:emails] << {:name => email['label'], :email => email['address']}
+ end
+ end if entry['gd$email']
+
+ # Support older versions of the gem by keeping singular entries around
+ contact[:email] = contact[:emails][0][:email] if contact[:emails][0]
contact[:first_name], contact[:last_name], contact[:name] = email_to_name(contact[:name]) if !contact[:name].nil? && contact[:name].include?('@')
- contact[:first_name], contact[:last_name], contact[:name] = email_to_name(contact[:email]) if contact[:name].nil? && contact[:email]
+ contact[:first_name], contact[:last_name], contact[:name] = email_to_name(contact[:emails][0][:email]) if contact[:name].nil? && contact[:emails][0][:email]
#format - year-month-date
- if entry['gContact$birthday']
- birthday = entry['gContact$birthday']['when'].split('-')
- contact[:birthday] = birthday_format(birthday[2], birthday[3], nil) if birthday.size == 4
- contact[:birthday] = birthday_format(birthday[1], birthday[2], birthday[0]) if birthday.size == 3
- end
+ contact[:birthday] = birthday(entry['gContact$birthday']['when']) if entry['gContact$birthday']
+
# value is either "male" or "female"
contact[:gender] = entry['gContact$gender']['value'] if entry['gContact$gender']
- contact[:relation] = entry['gContact$relation']['rel'] if entry['gContact$relation']
+ if entry['gContact$relation']
+ if entry['gContact$relation'].is_a?(Hash)
+ contact[:relation] = entry['gContact$relation']['rel']
+ elsif entry['gContact$relation'].is_a?(Array)
+ contact[:relation] = entry['gContact$relation'].first['rel']
+ end
+ end
+
+ contact[:addresses] = []
+ entry['gd$structuredPostalAddress'].each do |address|
+ if address['rel']
+ split_index = address['rel'].index('#')
+ new_address = {:name => address['rel'][split_index + 1, address['rel'].length - 1]}
+ elsif address['label']
+ new_address = {:name => address['label']}
+ end
+
+ new_address[:address_1] = address['gd$street']['$t'] if address['gd$street']
+ new_address[:address_1] = address['gd$formattedAddress']['$t'] if new_address[:address_1].nil? && address['gd$formattedAddress']
+ if new_address[:address_1].index("\n")
+ parts = new_address[:address_1].split("\n")
+ new_address[:address_1] = parts.first
+ # this may contain city/state/zip if user jammed it all into one string.... :-(
+ new_address[:address_2] = parts[1..-1].join(', ')
+ end
+ new_address[:city] = address['gd$city']['$t'] if address['gd$city']
+ new_address[:region] = address['gd$region']['$t'] if address['gd$region'] # like state or province
+ new_address[:country] = address['gd$country']['code'] if address['gd$country']
+ new_address[:postcode] = address['gd$postcode']['$t'] if address['gd$postcode']
+ contact[:addresses] << new_address
+ end if entry['gd$structuredPostalAddress']
+
+ # Support older versions of the gem by keeping singular entries around
+ if contact[:addresses][0]
+ contact[:address_1] = contact[:addresses][0][:address_1]
+ contact[:address_2] = contact[:addresses][0][:address_2]
+ contact[:city] = contact[:addresses][0][:city]
+ contact[:region] = contact[:addresses][0][:region]
+ contact[:country] = contact[:addresses][0][:country]
+ contact[:postcode] = contact[:addresses][0][:postcode]
+ end
+
+ contact[:phone_numbers] = []
+ entry['gd$phoneNumber'].each do |phone_number|
+ if phone_number['rel']
+ split_index = phone_number['rel'].index('#')
+ contact[:phone_numbers] << {:name => phone_number['rel'][split_index + 1, phone_number['rel'].length - 1], :number => phone_number['$t']}
+ elsif phone_number['label']
+ contact[:phone_numbers] << {:name => phone_number['label'], :number => phone_number['$t']}
+ end
+ end if entry['gd$phoneNumber']
+
+ # Support older versions of the gem by keeping singular entries around
+ contact[:phone_number] = contact[:phone_numbers][0][:number] if contact[:phone_numbers][0]
+
+ if entry['gContact$website'] && entry['gContact$website'][0]["rel"] == "profile"
+ contact[:id] = contact_id(entry['gContact$website'][0]["href"])
+ contact[:profile_picture] = image_url(contact[:id])
+ else
+ contact[:profile_picture] = image_url_from_email(contact[:email])
+ end
+
+ if entry['gContact$event']
+ contact[:dates] = []
+ entry['gContact$event'].each do |event|
+ if event['rel']
+ contact[:dates] << {:name => event['rel'], :date => birthday(event['gd$when']['startTime'])}
+ elsif event['label']
+ contact[:dates] << {:name => event['label'], :date => birthday(event['gd$when']['startTime'])}
+ end
+ end
+ end
+
+ if entry['gd$organization']
+ contact[:company] = entry['gd$organization'][0]['gd$orgName']['$t'] if entry['gd$organization'][0]['gd$orgName']
+ contact[:position] = entry['gd$organization'][0]['gd$orgTitle']['$t'] if entry['gd$organization'][0]['gd$orgTitle']
+ end
+
contacts << contact if contact[:name]
end
- contacts.uniq! {|c| c[:email] || c[:name]}
+ contacts.uniq! {|c| c[:email] || c[:profile_picture] || c[:name]}
contacts
+ end
+
+ def image_url gmail_id
+ return "https://profiles.google.com/s2/photos/profile/" + gmail_id if gmail_id
+ end
+
+ def current_user me, access_token, token_type
+ return nil if me.nil?
+ me = JSON.parse(me)
+ user = {:id => me['id'], :email => me['email'], :name => me['name'], :first_name => me['given_name'],
+ :last_name => me['family_name'], :gender => me['gender'], :birthday => birthday(me['birthday']), :profile_picture => image_url(me['id']),
+ :access_token => access_token, :token_type => token_type
+ }
+ user
+ end
+
+ def birthday dob
+ return nil if dob.nil?
+ birthday = dob.split('-')
+ return birthday_format(birthday[2], birthday[3], nil) if birthday.size == 4
+ return birthday_format(birthday[1], birthday[2], birthday[0]) if birthday.size == 3
+ end
+
+ def contact_id(profile_url)
+ id = (profile_url.present?) ? File.basename(profile_url) : nil
+ id
end
end
end
end