Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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
Add Comment
Please, Sign In to add comment