【问题标题】:Unzip binary email attachment解压缩二进制电子邮件附件
【发布时间】:2014-10-21 23:32:33
【问题描述】:

我在 Rails 应用程序中有一个后台作业,它生成一个大的 CSV 文件并将其作为电子邮件的附件发送。为了管理电子邮件的大小,我在附加 CSV 之前对其进行压缩。这很好用;我们正在开发 Letter Opener,我可以打开压缩附件并读取数据。我正在使用“rubyzip”gem 进行压缩。

诀窍似乎是在测试它。使用 rspec,我可以验证邮件是否有附件,并且附件的类型是application/x-zip-encoded,这一切都很好。不过,我想做的是解压缩附件并验证测试中的数据,但事实证明这更加困难。附件是 Mail::Part 类型的对象。如果我调用附件part,我可以使用part.body.raw_sourcepart.body.encodedpart.decode_body 从中获取数据。 (第一个和第三个是相同的。)part.body.encoding 告诉我身体是二进制的。当我尝试将数据提供给 Zip::InputStream 对象(使用 Zip::InputStream.open(part.body.raw_source) 或任何其他数据方法)时,我会得到类似 ArgumentError: string contains null byte 的信息。

如何打开此附件并在 rspec 中读取其数据?我有一种预感,我需要在这里某处进行解码。

错误look a lot like this question,但那里也没有答案。

【问题讨论】:

  • 我可能会误解,但听起来您想验证 gem 正在做它应该做的事情。如果是这种情况,您不应该这样做。您不应该编写测试来覆盖其他人的库。他们应该有自己的测试,如果没有,你可以为项目贡献测试,或者找到一个已经过正确测试的库。
  • 看起来是这样的,不是吗。我认为我的目标更多是验证附加到电子邮件的数据是否应该附加,而这样做的方法是解压缩数据并检查它;我在解压缩步骤上卡住了。

标签: ruby ruby-on-rails-3 zip email-attachments


【解决方案1】:

这里的解决方案不太理想,但它确实有效。我必须使用邮件库将附件写入文件,然后使用Zip::File 提取原始数据并进行验证。

it 'has a ZIP attachment' do
  additional_fields = ["student_identifiers"]

  expect(message.attachments.size).to eq(1)
  message.attachments.first.tap do |zip|
    expect(zip.content_type).to eq('application/x-zip-compressed')
    tmpfile_name = "tmp/#{zip.filename}"
    File.open(tmpfile_name, "w+b", 0644) { |f| f.write zip.decoded }
    csv = Zip::File.open(tmpfile_name) do |zip_file|
      entry = zip_file.glob('*.csv').first
      entry.get_input_stream.read
    end
    csv.split("\n").tap do |rows|
      expect(rows.size).to be(2)
      rows.each do |row|
        expect(CSV.parse_line(row).size).to eq(dimensions_count)
      end
    end
    File.delete(tmpfile_name)
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多