为什么我在rails 2中使用vpim会出现编码错误?

Tim*_* T. 5 vcf-vcard ruby-on-rails

我收到以下错误:

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'
Run Code Online (Sandbox Code Playgroud)

它适用于其他vcards.数据看起来正确 - 它应该是一封电子邮件:

这是一个示例vcard,当有电子邮件时会爆炸...我已经做了修复它的手动删除第二封电子邮件,但这很痛苦:

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
Run Code Online (Sandbox Code Playgroud)

这是我的控制器使用paperclip和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
Run Code Online (Sandbox Code Playgroud)

nee*_*zer 4

您需要查看您的电子名片是如何创建的;第 14 行的第二封电子邮件不是有效的属性定义,这就是导致解析器出错的原因(这就是为什么如果您手动删除它,它会成功解析)。

\n\n

您可以阅读Vcard 2.1 规范第 2 节中的属性定义(RTF 版本\xe2\x80\x93 更具可读性\xe2\x80\x93 可在此处获取)。

\n\n

从您提供的信息来看,这看起来不像是Vpim解码方面的问题,而是您的 Vcard 创建方式的问题。如果您自己创建 Vcard,我会看看您的编码逻辑。如果您从外部来源接收它们,那么您可能需要编写一些自定义清理逻辑来删除不正确的属性定义,这样您就不必自己手动删除它们。

\n\n

您应该能够通过对每一行进行快速正则表达式检查来轻松完成此操作:

\n\n
def scrub_vcf(vcard)\n  line_arr = File.readlines(vcard)\n  line_arr.delete_if { |line| line.match(/^.+\\:.+$/).nil? }\n  File.open(vcard, "w") do |f| \n    line_arr.each{|line| f.puts(line)}\n  end\nend\n# use the scrubbed vcf with vpim\n
Run Code Online (Sandbox Code Playgroud)\n\n

当然,将其保存在数组中可能比将其写回到文件中更快,仅供参考。

\n\n

希望有帮助。

\n\n
\n\n

更新:如果您不想保留文件,您可以返回一个字符串,Vpim 可以解码该字符串而不是文件:

\n\n
def scrub_vcf(vcard)\n  line_arr = File.readlines(vcard)\n  line_arr.delete_if { |line| line.match(/^.+\\:.+$/).nil? }\n  return line_arr.join\nend\n# use the scrubbed vcf with vpim #=> Vpim::Vcard.decode(scrub_vcf(vcard))\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,在运行 ruby​​ 1.9.x 时,我遇到了使用 String with 的问题Vpim::Vcard.decode,因为该类String不再具有each方法。不过,Ruby 1.8.7 运行良好。Vpim 看起来自 2008/2009 年以来就没有升级过,所以它可能没有升级到与 ruby​​ 1.9.x 一起使用。

\n\n
\n\n

再次更新:这是更新后的 Vpim 版本,可与 ruby​​ 1.9.x 一起使用(准确修复了我之前遇到的问题): https: //github.com/sam-github/vpim

\n