I finally managed to get this working. Taavo's answer set me in the right direction but it didn't work as expected.
The main problem was that StringIO.new(icon_data) kept giving me a no implicit conversion of nil into string
error. After quite some digging I found that I needed to add original_filename
as an attribute to StringIO, but it has long since stopped accepting this without monkey patching the class. I found the solution to this problem from the Carrierwave wiki psge: How to: Upload from a string in Rails 3.
This now let me save the icon to the file-system but mysteriously, was not populating the Version.icon field with the reference (Version.apk was populated without any problems).
In the end, to get it working I had to get rid of the before_Save :assign_icon
callback and moved my code into the ApkUploader file.
My code looks something like this:
1) Created a new initializer that inherits from StringIO
config/initializers/stringiohax.rb
class AppSpecificStringIO < StringIO
attr_accessor :filepath
def initialize(*args)
super(*args[1..-1])
@filepath = args[0]
end
def original_filename
File.basename(filepath)
end
end
2) Mount Uploaders
app/models/version.rb
class Version < ActiveRecord::Base
mount_uploader :apk, ApkUploader
mount_uploader :icon, IconUploader
3) Extract data from APK and save icon attribute
app/models/version.rb
class ApkUploader < CarrierWave::Uploader::Base
include Sprockets::Rails::Helper
include CarrierWave::MimeTypes
require 'ruby_apk'
..
...
process :extract_apk_info
def store_dir
app = App.find(model.app_id)
studio_name = Studio.find(app.studio_id).slug
"uploads/#{studio_name}/#{app.id}/version_#{model.version_code}"
end
def extract_apk_info
apk = Android::Apk.new(model.apk.path.to_s)
manifest = apk.manifest
icons = apk.icon
icon_name = icons.keys.last
icon_data = icons.values.last
model.package_name = manifest.package_name
model.version_code = manifest.version_code
model.version_name = manifest.version_name
model.min_sdk_ver = manifest.min_sdk_ver
model.icon = AppSpecificStringIO.new(icon_name, icon_data)
end