How to convert thumbnail generation rule from paperclip to carrierwave - paperclip

I am migrating from Paperclip to Carrierwave. Here I am trying to convert the processing commands for thumbnail generations:
has_attached_file :image,
styles: {
thumb: '220x140#',
big: '620x600>',
no_proportion: '255x162!'
},
convert_options: {
all: '-strip',
thumb: '-delete 1--1',
no_proportion: '-delete 1--1'
}
I am planning to use MiniMagick. I got that I convert from 220x140# to resize_to_fill(220,140), but I am not sure how to convert all the other commands.
P.S. It would be better if I can reuse the existing ImageMagick commands and parameters, even for resizing (i.e. not using built-in helper resizer).

I have done the following. However I am not sure if it is totally equivalent.
process :strip
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fill => [220,140]
end
version :mobile do
process :resize_to_fill => [320,210]
end
version :mobile_small do
process :resize_to_fill => [256,168]
end
version :big do
process :resize_to_limit => [620,600]
end
version :groupbuy_ad do
process :resize_to_fill => [96,60]
end
version :email do
process :resize_to_fill => [125,125]
end
version :widget_165 do
process :resize_to_fill => [165,105]
end
version :widget_100 do
process :resize_to_fill => [100,64]
end
version :no_proportion do
process :resize => '255x162!'
end
def strip
manipulate! do |img|
img.strip
img = yield(img) if block_given?
img
end
end
def resize(dimension)
manipulate! do |img|
img.resize dimension
img = yield(img) if block_given?
img
end
end
def get_first_frame
manipulate! do |img|
img = img.delete '1--1'
end
end

Related

Carrierwave not resizing images on S3

On development, it's correctly creating a resized version of original image and storing both of them, but on s3, it's just uploading 2 identical versions without any kind of modification (apart from renaming it). There are no exceptions shown anywhere. Any idea where the problem might be?
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => 'AWS',
:aws_access_key_id => 'a',
:aws_secret_access_key => 'a',
:region => "us-west-1"
}
config.fog_directory = 'a'
end
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
def store_dir
"images/#{model.id}"
end
version :normalized do
process :resize_to_limit => [450,450]
end
def extension_white_list
%w(jpg jpeg gif png)
end
if Sinatra::Base.development?
storage :file
else
storage :fog
end
end
Although there were no errors, running "convert -version" on production machine revealed that imagemagick was not installed. Installation fixed the issue.

Rails+carrierwave: default thumb for msword content type

I`m use Rails 3.2.11+Carrierwave.
help please, how to set the default thumb for a specific content type, such as .doc or .docx?
Default thumb placed in /public/assets - thumb_for_doc.jpg
my uploader:
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
#include CarrierWave::MiniMagick
include CarrierWave::MimeTypes
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
def store_dir
"uploads/order_#{model.order.id}" unless model.order.nil?
end
process :set_content_type
version :pdf, :if => :pdf? do
process :cover
process :resize_to_fit => [100, 100]
process :convert => :jpg
def full_filename (for_file = model.source.file)
super.chomp(File.extname(super)) + '.jpg'
end
end
version :msword, :if => :msword? do
#????
end
version :thumb, :if => :image? do
process :resize_to_limit => [100, 100]
end
def filename
if model.document_specification_id
document_specification = Lists::DocumentSpecification.find_by_id(model.document_specification_id)
margins = Lists::PrintMargin.find_by_id(document_specification.print_margin_id).margin
paper_type = Lists::PaperType.find_by_id(Lists::PaperSpecification.find_by_id(document_specification.paper_specification_id).paper_type_id).paper_type
paper_size = Lists::PaperSize.find_by_id(Lists::PaperSpecification.find_by_id(document_specification.paper_specification_id).paper_size_id).size
"#{secure_token}_PP_#{paper_size.parameterize}_#{paper_type.parameterize}_#{model.quantity}_#{margins.parameterize}.#{file.extension}" if original_filename.present?
else
"#{secure_token}_PP_not_set_spesification.#{file.extension}" if original_filename.present?
end
end
def cover
manipulate! do |frame, index|
frame if index.zero? # take only the first page of the file
end
end
protected
def secure_token
var = :"##{mounted_as}_secure_token"
model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.hex(4))
end
def image?(file)
file.content_type.start_with? 'image'
end
def pdf?(file)
file.content_type.start_with? 'application/pdf'
end
def msword?(file)
file.content_type.start_with? 'application/msword'
end
end
thanks!

Manually upload and save files in Carrierwave

I have a directory of existing files which I need to migrate into my rails app as part of a legacy migration. Essentially I need to upload these files manually and save a new record for them in the database. I haven't quite found the proper way to do this. Currently I have the following in a rake task:
#attachments.each do |attachment|
begin
new_attachment = Attachment.new
#attachment_file_path = "/home/username/Attachments/" + attachment.Filename
file = File.open(#attachment_file_path)
new_attachment[:file] = new_attachment.file.store!(file)
# Map old record fields to new
new_attachment.attributes = {
:project_id => attachment.ProjectID,
:name => attachment.Description,
:user_id => attachment.UserId,
:created_at => attachment.CreatedDate,
:updated_at => attachment.LastModifiedDate
}
new_attachment.save!
puts "Attachment added successfully "
rescue => error
puts "Error migrating Attachment: #{error}"
end
end
attachment.rb
class Attachment < ActiveRecord::Base
mount_uploader :file, FileUploader
end
uploader:
class FileUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
include CarrierWave::MimeTypes
process :set_content_type
storage :fog
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
%w(jpg jpeg gif png pdf doc docx txt)
end
version :thumb do
process resize_to_fit: [152, nil]
end
def default_url
ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
end
protected
def image?(new_file)
if new_file.content_type == nil
return false
else
new_file.content_type.include? 'image'
end
end
end
This does not work currently. The file never gets uploaded, and occasionally I get the following error:
Failed to manipulate with rmagick, maybe it is not an image? Original Error: no decode delegate for this image format
In this instance, the file is a '.doc' file.
What is the correct way to open a local file and upload it manually via Carrierwave?
Any help is appreciated.
Try this
#attachments.each do |attachment|
begin
options = {
:project_id => attachment.ProjectID,
:name => attachment.Description,
:user_id => attachment.UserId,
:created_at => attachment.CreatedDate,
:updated_at => attachment.LastModifiedDate,
:file => File.new(File.join("/home/username/Attachments/",attachment.Filename))
}
new_attachment = Attachment.new(options)
new_attachment.save!
puts "Attachment added successfully "
rescue => error
puts "Error migrating Attachment: #{error}"
end
end
Perhaps that would do for you as carrierwave would internally call store! for you
Question?
Failed to manipulate with rmagick, maybe it is not an image? Original Error: no decode delegate for this image format
Not sure what are you trying to over here because you have define an image? method which is not specified in condition also is that something that you want the content_type to be only present for image file
if no perhaps only the process call would work
process :set_content_type
if yes then perhaps you have to do something like this
process :set_content_type , :if => :image?
def image?(new_file)
%w(jpg jpeg gif).include?(new_file.extension)
end
Hope this help
EDIT based upon the comment
try this just used the condition same logic
version :thumb ,:if => image? do
// your code
end

Using a Carrierwave custom process I'm not able to access the model.id (multi-page PDF)

The idea is, I want to convert a PDF to an image per page. I've tried other methods which are on Stackoverflow but to no avail. Below is my uploader file.
Uploader
class PdfUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
#//TODO - Remove converted images when deleting an entry, maybe? if needed?
storage :file
#//TODO - Add images into the same folder. model.id can't be accessed in a custom process.
def store_dir
"#{Rails.root}/public/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def cache_dir
"#{Rails.root}/public/uploads/#{model.class.to_s.underscore}/#{mounted_as}/tmp"
end
def extension_white_list
%w(pdf)
end
def filename
super.chomp(File.extname(super)) + '.png'
end
version :pages do
process :create_pages
process convert: 'png'
end
process convert: 'png'
version :thumb do
process :cover
process :resize_to_fill => [200, 200, Magick::CenterGravity]
process convert: 'png'
end
def cover
manipulate! do |frame, index|
frame if index.zero?
end
end
def create_pages
manipulate! do |frame, index|
frame.write("#{store_dir}/#{index}.png")
end
end
end
The PDF will get converted to images for each page. But it will not recognize the model.id and store it in that folder. Instead it will store in the directory above that.
I've tried the adding the following to force the making of the folder, but it doesn't seem to know the model.id through a little bit of testing?
Tried to Make Dir
def create_pages
Dir.mkdir(store_dir) unless File.exists?(store_dir)
manipulate! do |frame, index|
frame.write("#{store_dir}/#{index}.png")
end
end
Help would be much appreciated, I've been stuck on this for a while and had to leave it for a couple of days out of frustration.
Thank you in advance.
This is most likely because you are saving your images with frame.write before the model itself is saved, and therefore also before an ID has been assigned.
Have a look at this answer for a potential solution: Carrierwave : error with model.id in the store_path

Sinatra render a ruby file

How to render a ruby file (which in my case returns a pdf document) for example:
get "/pdf" do
#locals = {some_locals_hash}
headers({'Content-Type' => 'application/pdf',
'Content-Description' => 'File Transfer',
'Content-Transfer-Encoding' => 'binary',
'Content-Disposition' => "attachment;filename=\"test.pdf\"",
'Expires' => '0',
'Pragma' => 'public'})
ruby :test, :layout => false, :locals => #locals
end
I know Tilt does not have ruby template. For now I put all content in a *.haml file like:
-# PDF file description
:ruby
pdf = Prawn::Document.new(
... docs settings)
... docs content
end
= pdf.render()
and I render it with haml :template ...etc...
Truth is, I only need this for syntax highlighting, my editor does not properly highlight embedded ruby code in haml files :(. So if it's to complicated don't bother...
I managed with a Tilt template
module Tilt
class RubyTemplate < Template
def prepare
end
def evaluate(scope, locals, &block)
super(scope, locals, &block)
end
def precompiled_template(locals)
data.to_str
end
end
register 'rb', RubyTemplate
end
and with a helper method
helpers do
def ruby(*args)
render(:rb, *args)
end
end
I't sure this is the best way, but at least is working :)

Resources