Why am I getting an encoding error with vpim in rails 2?
I get the following error:
Vpim::InvalidEncodingError (email@email.net):
2011-06-07T01:37:06+00:00 app[web.1]: .bundle/gems/ruby/1.8/gems/vpim-0.695/lib/vpim/field.rb:110:in `decode0'
It has worked fine for开发者_C百科 other vcards. And the data looks right -- it should be an email:
Here is a sample vcard that blows up when there's an email...what I"ve done to fix it is manually remove the second email, but that's a pain:
BEGIN:VCARD
VERSION:2.1
N:Roberts;Paul;;;
FN:Paul Roberts
ORG:Sonoma Technology Inc
TITLE:EVP Business Dev/Chief Scientific Officer
TEL;WORK;VOICE:707-665-9900
TEL;WORK;FAX:707-665-9800
ADR;WORK;ENCODING=QUOTED-PRINTABLE:;;1455 N McDowell Blvd Suite D;Petaluma;CA;94954;USA
LABEL;WORK;ENCODING=QUOTED-PRINTABLE:1455 N McDowell Blvd Suite D=0D=0APetaluma, CA 94954=0D=0AUSA
URL:http://www.sonomatech.com
URL:http://www.sonomatech.com
EMAIL;PREF;INTERNET:paul@sonomatech.com
paul@sonomatech.com
NOTE;ENCODING=QUOTED-PRINTABLE:=0D=0A Data provided by Lead411, http://www.lead411.com/=0D=0A =0D=0A
END:VCARD
Here's my controller using paperclip and vpim:
68 unless @contact.vcard.path.blank?
69
70 paperclip_vcard = File.new(@contact.vcard.path)
71
72 # try to scrub the vcard
73 scrub_vcf(paperclip_vcard)
74
75 @vcard = Vpim::Vcard.decode(paperclip_vcard).first
76 @contact.title = @vcard.title
77 @contact.email = @vcard.email
78 @contact.first_name = @vcard.name.given
79 @contact.last_name = @vcard.name.family
80 @contact.phone = @vcard.telephones[0]
81 @contact.fax = @vcard.telephones[1]
82
83 @contact.address.street1 = @vcard.address.street
84 @contact.address.city = @vcard.address.locality
85 @contact.address.state = @vcard.address.region
86 @contact.address.zip = @vcard.address.postalcode
87 @contact.company_name = @vcard.org.fetch(0)
88
89 end
You need to look at how your Vcards are being created; the second email on line 14 isn't a valid property definition, which is what's causing the parser to screw up (and which is why it parses successfully if you manually delete it).
You can read about the property definition in Section 2 in the Vcard 2.1 specification (the RTF version–which is far more readable–is available here).
From the information you provided, this doesn't look like a problem with Vpim on the decoding side, but rather how your Vcards are created. If you're creating the Vcards yourself, I'd take a look at your encoding logic. If you're receiving them from outside sources, then you might want to write some custom scrubbing logic to get rid of improper property definitions, so you don't have to manually remove them yourself.
You should be able to do this quite easily with a quick regex check on each line:
def scrub_vcf(vcard)
line_arr = File.readlines(vcard)
line_arr.delete_if { |line| line.match(/^.+\:.+$/).nil? }
File.open(vcard, "w") do |f|
line_arr.each{|line| f.puts(line)}
end
end
# use the scrubbed vcf with vpim
Of course, it would probably be quicker to keep this in an array rather than writing it back out to a file, FYI.
Hope that helps.
UPDATE: If you don't want to keep the file, you can return a string, which Vpim can decode instead of a file:
def scrub_vcf(vcard)
line_arr = File.readlines(vcard)
line_arr.delete_if { |line| line.match(/^.+\:.+$/).nil? }
return line_arr.join
end
# use the scrubbed vcf with vpim #=> Vpim::Vcard.decode(scrub_vcf(vcard))
Note that I ran into problems with using a String with Vpim::Vcard.decode
when running ruby 1.9.x, due to the fact that the String
class no longer has an each
method. Ruby 1.8.7 works fine, though. Vpim looks like it hasn't been upgraded since 2008/2009, so it's probably not been upgraded for use with ruby 1.9.x.
UPDATE AGAIN: Here's a version of Vpim updated for use with ruby 1.9.x (fixes precisely the issue I ran into earlier): https://github.com/sam-github/vpim
精彩评论