Created
April 25, 2010 22:21
-
-
Save patrick99e99/378778 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 Contact < ActiveRecord::Base | |
with_options :dependent => :destroy do |parent| | |
parent.has_many :phones | |
parent.has_many :emails | |
parent.has_many :addresses | |
parent.has_one :photo | |
parent.has_one :user | |
end | |
accepts_nested_attributes_for :emails, :allow_destroy => true, :reject_if => lambda {|email| email["address"].blank? } | |
accepts_nested_attributes_for :phones, :allow_destroy => true, :reject_if => lambda {|phone| phone["number"].blank? } | |
accepts_nested_attributes_for :addresses, :allow_destroy => true, :reject_if => lambda {|address| address["street_1"].blank? } | |
validates_presence_of :first_name | |
validates_presence_of :last_name | |
... |
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 Photo < ActiveRecord::Base | |
belongs_to :photo_album | |
belongs_to :contact | |
belongs_to :access_level | |
acts_as_fleximage | |
.... |
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
def import | |
@card = Vpim::Vcard.decode(self.data).first | |
get_data | |
# find the contact if it already exists by email | |
@email = Email.find_by_address(@emails) | |
if @email | |
update_contact | |
else | |
create_contact | |
end | |
process_associations | |
end | |
private | |
def update_contact | |
@contact = @email.contact | |
@contact.update_attributes(contact_attributes) | |
end | |
def contact_attributes | |
{:url => @url, | |
:notes => @notes, | |
:birthday => @birthday} | |
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) | |
@phones = @card.telephones.map {|p| remove_newlines(p)} | |
@streets = @card.addresses.map {|a| remove_newlines(a.street)} | |
@emails = @card.emails.map {|e| remove_newlines(e.to_s.downcase)} | |
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. | |
p = Phone.create(:label => get_label(phone), :number => remove_newlines(phone.to_s)) | |
@contact.phones << p | |
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. | |
e = Email.create(:label => get_label(email), :address => remove_newlines(email.to_s.downcase)) | |
@contact.emails << e | |
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') | |
description = "User photo" | |
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, | |
: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 |
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
require 'spec_helper' | |
describe Vcard do | |
describe "importing a vcard" do | |
Vcard.delete_all | |
Region.delete_all | |
Region.create!(:name => "CA", :country_id => 237) | |
def mock_country | |
@country = mock_model(Country, {:id => 237, :name => "United States"}) | |
Country.stub!(:find_by_name).with("United States").and_return(@country) | |
end | |
context "it has a birthday, url and an invalid address" do | |
before(:all) do | |
card_data = File.read(RAILS_ROOT + "/spec/fixtures/vcard/kirk_no_photo.vcf") | |
@vcard = Vcard.create!(:data => card_data) | |
end | |
before(:each) do | |
Contact.all.map(&:destroy) | |
mock_country | |
# could not get this to work... | |
# | |
# photo_content = File.read(RAILS_ROOT + "/spec/fixtures/vcard/image/kirk.jpg") | |
# @photo = mock_model(Photo, {:image_file_string => photo_content}) | |
# Photo.should_receive(:create).and_return(@photo) | |
end | |
it "should update an existing contact when an email is found" do | |
@contact = Contact.create!(:first_name => "James", :last_name => "Kirk") | |
@contact.emails << Email.create!(:address => 'kirk@enterprise.com') | |
@vcard.import | |
@contact.reload | |
@contact.birthday.should_not be_blank | |
@contact.url.should_not be_blank | |
# because I could not get the photo to work in the spec.. | |
# @contact.photo.should == @photo | |
end | |
it "should create a new contact when an email is not found" do | |
@vcard.import | |
Contact.find_by_first_name_and_last_name("James", "Kirk").should_not be_nil | |
end | |
it "should not create an address if the state cannot be found" do | |
@vcard.import | |
Contact.last.addresses.should be_blank | |
end | |
end | |
context "it has 3 valid phones, addresses, and emails" do | |
before(:all) do | |
mock_country | |
card_data = File.read(RAILS_ROOT + "/spec/fixtures/vcard/felds_no_photo.vcf") | |
@vcard = Vcard.create!(:data => card_data) | |
@vcard.import | |
end | |
it "should create 3 new addresses" do | |
Contact.last.addresses.count.should == 3 | |
end | |
it "should create 3 new phones" do | |
Contact.last.phones.count.should == 3 | |
end | |
it "should create 3 new emails" do | |
Contact.last.emails.count.should == 3 | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment