Created
April 27, 2010 21:46
-
-
Save patrick99e99/381384 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Vcard < ActiveRecord::Base | |
def import | |
@card = Vpim::Vcard.decode(self.data).first | |
get_data | |
find_contact | |
if @contact | |
update_contact | |
else | |
create_contact | |
end | |
process_associations | |
end | |
private | |
def update_contact | |
@contact.update_attributes(contact_attributes) | |
end | |
def contact_attributes | |
{:url => @url, | |
:notes => @notes, | |
:birthday => @birthday} | |
end | |
def find_contact | |
@card = Vpim::Vcard.decode(self.data).first | |
[find_by_emails, find_by_phones].each do |method| | |
contact_found = method | |
return if contact_found | |
end | |
end | |
def find_by_emails | |
emails = @card.emails.map {|e| remove_newlines(e.to_s.downcase)} | |
email = Email.find_by_address(emails) | |
@contact = email.contact if email | |
end | |
def find_by_phones | |
phones = @card.telephones.map {|p| remove_newlines(p)} | |
phone = Phone.find_by_number(phones) | |
@contact = phone.contact if phone | |
end | |
def create_contact | |
@contact = Contact.create(contact_attributes.merge(:first_name => @first_name, | |
:last_name => @last_name)) | |
end | |
def process_associations | |
card_emails | |
card_phones | |
card_addresses | |
card_photo | |
end | |
def get_data | |
@first_name = @card.name.given.blank? ? nil : remove_newlines(@card.name.given.capitalize) | |
@last_name = @card.name.family.blank? ? nil : remove_newlines(@card.name.family.capitalize) | |
@first_name = @card.name.fullname if (@first_name.nil? && @last_name.nil? && !@card.name.fullname.blank?) | |
@birthday = @card.birthday.blank? ? nil : @card.birthday | |
@url = @card.url.blank? ? nil : remove_newlines(@card.url.uri.gsub("\\","")) | |
@notes = @card.note.blank? ? nil : remove_newlines(@card.note) | |
end | |
def card_addresses | |
street_numbers = @contact.addresses.map(&:street_1).map(&:numbers_only) | |
@card.addresses.each do |@address| | |
# don't bother saving the address if there is no region (state) | |
# assume that if the contact currently has an address with the same numbers that this address is already stored | |
unless @address.region.blank? || street_numbers.include?(@address.street.numbers_only) | |
@country = get_country || Country.find_by_name("United States") | |
region = get_region | |
next if region.nil? | |
# labels retrieved from the vcard are only home or work.. custom does not work. | |
@contact.addresses << Address.create(:country_id => @country.id, | |
:region_id => region.id, | |
:street_1 => remove_newlines(@address.street), | |
:street_2 => remove_newlines(@address.pobox), | |
:city => remove_newlines(@address.locality), | |
:postal_code => remove_newlines(@address.postalcode), | |
:label => get_label(@address)) | |
end | |
end | |
end | |
def get_country | |
if !@address.country.blank? | |
card_country = @address.country.gsub(".","") | |
countries = Country.all | |
country_attributes = [:name, :official_name, :alpha_2_code, :alpha_3_code] | |
find_in_list(countries, country_attributes, card_country) | |
end | |
end | |
def get_region | |
# best way I could deal with nev. => nev | |
card_region = (@address.region.last == "." ? @address.region.chop : @address.region) | |
regions_for_country = Region.find_all_by_country_id(@country.id) | |
region_attributes = [:name, :abbreviation, :abbrev2, :abbrev3] | |
find_in_list(regions_for_country, region_attributes, card_region) | |
end | |
def find_in_list(records, attributes, to_find) | |
# a better way of doing Country.all.find {|c| [c.name, c.official_name].compact.map(&:downcase).include?(to_find.downcase) } | |
records.find {|r| attributes.map{|a| r.send(a)}.compact.map(&:downcase).include?(to_find.downcase) } | |
end | |
def card_phones | |
@card.telephones.each do |phone| | |
# phone is something like: #<Vpim::Vcard::Telephone: "123-456-7890", pref, work | |
# doing phone.to_s will extract just the number | |
unless @contact.phones.map(&:number).map(&:numbers_only).include?(phone.to_s.numbers_only) | |
# labels retrieved from the vcard are only home or work.. custom does not work. | |
@contact.phones << Phone.create(:label => get_label(phone), :number => remove_newlines(phone.to_s)) | |
end | |
end | |
end | |
def card_emails | |
@card.emails.each do |email| | |
# email is something like: #<Vpim::Vcard::Email: "test@yahoo.com", pref, home | |
# doing email.to_s will extract just the email address | |
unless @contact.emails.map(&:address).map(&:downcase).include?(email.to_s.downcase) | |
# labels retrieved from the vcard are only home or work.. custom does not work. | |
@contact.emails << Email.create(:label => get_label(email), :address => remove_newlines(email.to_s.downcase)) | |
end | |
end | |
end | |
def card_photo | |
unless @card.photos.size.zero? | |
if @contact.photo.nil? | |
photo_album = PhotoAlbum.find_or_create_by_name_with_access_level('users', 'admin') | |
access = AccessLevel.find_by_name('public') | |
@contact.photo = Photo.create(:image_file_string => @card.photos.first, | |
:contact_id => @contact.id, | |
:name => "#{@contact.first_name} #{@contact.last_name}".strip, | |
:description => "User photo", | |
:access_level_id => access.id, | |
:photo_album_id => photo_album.id, | |
:server_format => "JPEG") | |
end | |
end | |
end | |
def get_label(obj) | |
obj.location.blank? ? nil : remove_newlines(obj.location).gsub("-","").strip | |
end | |
def remove_newlines(obj) | |
obj.to_s.gsub("\n", " ") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment