Prawn PDF: how to add images uploaded with dragonfly - ruby-on-rails

I like to generate PDF-Files which also includes images uploaded by the user. The prawn gem works so far, and can also embed images located in the file system.
My problem is that I want to include user uploaded images, and where these images are stored will probably change in the future (from file system to some cloud service).
I use the dragonfly gem for handling the images, this uses rack to access the images and sometimes process them on the fly.
Now the simpliest idea does not work
(with report being my object and spot_image my image field)
image report.spot_image
no implicit conversion of #<Class:0x007fc07ecf1110> into String
I tried also to open the file via http with open-uri. This should work, but it blocks on my development machine, I think because the development rails server is single threaded:
image_path = report.spot_image.remote_url
image_url = "#{view.request.protocol}\#view.request.host_with_port}
/#{image_path.sub(/^\//,"")}"
image open(image_url) # timeout in development-mode
It may probably work in production, but even then it does a needless http-request. Can I ask dragonfly (or rack) directly for the image? prawn uses duck-typing and needs some object that responds to read and rewind as image.

I found relevant documentation about dragonfly file handling. The following did not work:
The report.spot_image.data method returns the image data as string, but prawn recognizes the data as path instead of as image data. The dragonfly tempfile method returns a closed temporary file, but prawn does not recognize that it can open it.
I had success with the file method, which returns an open file handle. It is unclear if prawn is closing this file than. So I used the block-style method to make sure the file is closed:
report.spot_image.file do |f|
image f
end
This works so far. (not yet tested with cloud storage)

Related

Processing file before upload using ActiveStorage

How would I process a file before it's uploaded using activestorage. I need to be able to modify an svg file's content before it actually gets uploaded to S3. Can't seem to find any callbacks.
There is no way to do this natively with ActiveStorage. It's the major drawback with using ActiveStorage.
As far as I know, the only way to modify an upload is to create a variant of the original upload after it is created...which creates a (completely different) variant image based on the image that was originally uploaded.
ActiveStorage is easy to setup but, after using it with a few applications, Carrierwave..etc seem like better options.
In addition, if you want to upload in a background job, ActiveStorage is a pain.

Local file upload: File.open or StringIO

My application allows a user to upload an image and then create different versions of that image (e.g. aligned and cropped with another image). The intermediate step is that I need to copy the uploaded file to another object and process it. The easiest way to do this is to upload it locally.
From the carrierwave wiki, they suggest using a modified version of StringIO.
On the carreirwave readme, they also suggest using File.open (something like obj.image=File.open('path_to_file').
I've also found references to using fixture_file_upload from ActionDispatch::TestProcess (usually in testing, but I'm unsure why it is restricted to that environment).
Can anyone give me a good explanation on the pros and cons (if any) of using these methods?
Thanks.
I just discovered one major difference, at least in the context of carrierwave. If you use carrierwave with the move_to_cache option set to true and mount your upload column with File.open, the file given to File.open will be moved, while with StringIO, it won't.

Rails' Paperclip gem POSTing instead of PUTting when uploading .zip file

I've got a form (Rails 3.2.8, Paperclip 3.1.4) with two Paperclip attachments for a model with two has_attached_files. One is meant to be an image, the other a generic file, usually a .zip file.
Everything works fine so long as I don't try to upload a .zip file. Uploading a .zip file of any size (original was 80 MB but tried 3 MB to see if it was a size issue) causes the form to POST instead of PUT and Rails throws a routing error.
The form method is POST but has the Rails' hidden _method value set to 'put', which works fine and does cause a PUT when I'm not trying to upload .zip files.
The form does have the enctype 'multipart' bit set correctly.
Any idea what could be causing this?
The file sounds large. Double check that the actual params are making it into the request. I get this on local as well depending on the size of the files.
The effect I've seen is that rails would basically get no params. Since a PUT is actually a post with a hidden element, rails would see only the POST since params are dropped.
I am actually not sure what is causing this. I think it may be the local webserver, so you may need to configure nginx or something. This never happens to me on heroku or anything, but always on local if the file is big enough.
Also note, webrick has a really really small size of the request payload limitation. So don't use that. Use "thin" as it is a really easy replacement.

Which plugins/gems should I use to dynamically generate thumbnails on-the-fly in Rails 3?

So, the thing is. I'm building my first rails app which reads images from a directory and it's subdirs. Now, I want to generate dynamic thumbnails of those images. But I don't want to fill up that directory with the thumbnail images. I was thinking of caching these thumbs separately for each user in temporary directory.
Oh, and, I would also need the dimensions of the images for some css magic.
What plugins/gems/... should I use to accomplish this?
You should rmagick coupled with Paperclip. In this way you can specify the dimensions (and many other attributes of the images), and make thumbnails on the fly.
On top of this, I would also add in delayed_job which will background the process of the images so if any of them are provided by the client, they won't have to wait for it to complete client-side.
rMagick : http://github.com/rmagick/rmagick
Paperclip: http://github.com/thoughtbot/paperclip
delayed_job: http://github.com/collectiveidea/delayed_job

Using Paperclip to Process .tga (targa) Files

I've run into an annoying problem with Paperclip. Paperclip is working fine for uploading jpg/gif files but it's choking on .targa files with the error "not recognized by identify”. Just to confirm, it's working 100% with jpg/gif/png files and I have imagemagick installed and working, this error only occurs with .tga files.
The general process for paperclip is:
User uploads a file
Tempfile is created containing the contents of that file
The identify command is run on the Tempfile to get the width/height of the image.
With jpg/png/gif files, identify can run on file without needing a valid extension (eg .jpg) to be able to recognise the file type. However, when identifying a .tga file, it requires the ".tga" extension in the file name.
The problem is this:
When Paperclip creates the temp file, it creates with a name similar to: stream.0.1. Because this tempfile lacks the .tga extension, the identify command can not parse the dimensions of the image, thus causing the "not recognized by identify”.
I'm not sure how to go about fixing this, the best idea I can come up with is to use the regular File.new command rather than Tempfile.new to create the temporary file with a random name but the correct file extension. This would require also patching in custom code to remove the Files after processing has been done rather than relying on Ruby's inbuilt ability to delete tempfiles after use.
Does anybody have some ideas on the best method I could go about fixing this?
This was a bug in Paperclip and has been fixed. More details can be found here:
http://groups.google.com/group/paperclip-plugin/browse_thread/thread/7fd7a8d7bab696a7

Resources