Carrierwave上传后解压缩RAR文件

时间:2015-02-10 00:52:01

标签: ruby-on-rails upload carrierwave rar compression

我实际上寻找的建议不仅仅是关于如何在上传后解压缩RAR / ZIP文件的纯编码答案,同时保持最大的数据完整率。

这是我的问题:我的应用程序的用户正在上传由Adobe Edge生成的文件(我们将其用于动画广告),这些文件采用RAR格式。要上传文件,这真的很微不足道。这是我的上传者:

class MediaUploader < CarrierWave::Uploader::Base
  storage :file

  def store_dir
    "uploads/#{ model.class.to_s.underscore }/#{ mounted_as }/#{ ScatterSwap.hash(model.id) }"
  end

  def extension_white_list
    %w(jpg jpeg gif png rar zip)
  end

  def filename
    "#{ secure_token }.#{ file.extension }" if original_filename.present?
  end

  protected

  def secure_token
    var = :"@#{ mounted_as }_secure_token"
    model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
  end
end

现在,就我而言,RAR文件实际上并不是我正在使用的文件。我需要的是档案中包含的文件。这些文件通常看起来像这样:

- edge_includes
|
- images
|
- js
|
| ADS_1234_988x160_edge.js
| ADS_1234_988x160_edgeActions.js
| ADS_1234_988x160.an
| ADS_1234_988x160.html

从上面的例子中,我需要将对ADS_1234_988x160.html文件的引用存储在数据库中。

为此目的,我将使用Carrierwave回调以便:

after :store, :uncompress_and_update_reference

def uncompress_and_update_reference(file)
  # uncompress and update reference
end
  • 解压缩档案(可能使用rubyzip
  • 获取ADS_1234_988x160.html
  • 的路径
  • 更新数据库中的引用

有没有更好的方法来处理它?如何处理故障或网络错误?欢迎任何想法。

1 个答案:

答案 0 :(得分:0)

我有类似的问题:zip已上传,但不应存储,只能解压缩内容。我通过实施专用存储解决了它。类似的东西:

class MyStorage
  class App < CarrierWave::Storage::Abstract
    def store!(file)
      # invoked when file is moved from cache into store
      # unzip and update db here
    end

    def retrieve!(identifier)
      MyZipFile.new(identifier)
    end
  end
end

class MyZipFile
  def initialize(identifier)
    @identifier = identifier
  end

  def path
    file.path
  end

  def delete
    # delete unzipped files
  end

  def file
    @file ||= zip_file
  end

  def zip_file
    # create zip file somewhere in tmp dir
  end
end
# in uploader file
storage MyStorage
storage :my_storage

如果使用符号,则需要在carrierwave config中定义:

CarrierWave.configure do |config|
  config.storage_engines.merge!(my_storage: 'MyStorage')
end