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