How to customize version filename in Carrierwave? - ruby-on-rails

I have a strange issue. I am trying to use master branch of carrierwave with Rails 3.2.xx project. I need to customize filenames of the versions. But when I add full_filename method in the version block, my original file also gets reduced to the dimensions specified for version.
When I remove full_filename method, it all works as expected, but thumb filename has thumb_ prefix which I don't want.
Is there a new way to customize version filenames. I have been using this way successfully in 0.10.0 and before.
Below is my uploader. This is a generated uploader with store_dir overrides.
class TestUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
# storage :file
storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fit => [200, 200]
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}/#{version_name}"
end
def full_filename(for_file = model.logo.file)
super(for_file).sub(version_name.to_s + '_', '')
end
end
end
Any ideas? All I need to do is to remove version_name part from its filename, since I am saving the versions in separate folders. I searched through Wiki and internet, but couldn't find a new way of doing this.

Add an initializer carrierwave.rb and mokeypatch the gem with:
module CarrierWave
module Uploader
module Versions
private
# Use original file name instead of prepending version name
# Can't overload in app's uploader class because `super` already has
# the version name
def full_filename(for_file)
directory = version_name.to_s
# if you want the original version in a sub-directory also
# directory = (version_name || 'original').to_s
File.join(directory, super(for_file))
end
end
end
end
Also, leave off the store_dir and full_filename methods from the versions.

Related

Carrierwave Uploader specify Version directory using same file name for Rails 5

I want to use the same file name but a different directory for a version of my uploaded file.
upload file imageName.jpg should create
uploads/drawing/2018/imageName.jpg #which is the original file
uploads/thumbs/2018/imageName.jpg #a 120 x 100 scaled version of the original file
In my:
class DrawingUploader < CarrierWave::Uploader::Base
I override the store_dir method, which correctly stores my downloaded file, imageName.jpg in uploads/drawings/2018
def store_dir
"uploads/drawings/2018"
end
Then I create a thumbnail version and I want to specify the file name so that it is the same as the original (without "thumb" added to it) and a directory for it. The file name works with full_filename but store_dir doesn't.
version :thumb do
process resize_to_fit: [120, 100]
def store_dir (for_file = model.drawing.file)
"uploads/thumbs/2018"
end
def full_filename (for_file = model.drawing.file)
"imageName.jpg"
end
end
This stores a 120x100 file at uploads/drawings/2018/imageName.jpg
It is still using the store_dir (drawings not thumbs) defined before version.
More info from my tests:
if the file uploads/drawings/2018/imageName.jpg already exists when uploader is called, the store_dir defined in version works correctly, and places the file in uploads/thumbs/2018/imageName.jpg
if versions only uses full_filename, but I include the path for the specified file name it places that path inside of the path last used by uploader so:
version :thumb do
process resize_to_fit: [120, 100]
def full_filename (for_file = model.drawing.file)
"uploads/thumbs/2018/imageName.jpg"
end
end
creates a file at uploads/drawings/2018/uploads/thumbs/2018/imageName.jpg
and if I try to make the path relative it correctly creates the directories but never writes the version file -- the folders are simply empty
version :thumb do
process resize_to_fit: [120, 100]
def store_dir (for_file = model.drawing.file)
"../../uploads/thumbs/2018"
end
def full_filename (for_file = model.drawing.file)
"imageName.jpg"
end
end
creates an empty directory at uploads/drawings/2018 the file imageName.jpg is not written
It appears to be a carrierwave issue with caching. I found this hack which was super helpful: https://github.com/carrierwaveuploader/carrierwave/issues/1861
What I used follows:
def store_dir
if version_name
#dirName = "thumbs"
else
#dirName = "drawings"
end
"uploads/#{#dirName}/2018"
end
def filename
"newImage.jpg" if original_filename.present?
end
def full_filename(for_file)
if model.new_record?
super(for_file)
else
for_file
end
end
# Create different versions of your uploaded files:
version :thumb do
process resize_to_fit: [120, 100]
end

Carrierwave upload and extract zip before save rails4

I want to upload a zip file contains documents and after uploading it to server I want to extract those on server.
I have used Carrierwave Gem to upload zip file code is below for that :
class AttachmentUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
%w(zip)
#%w(pdf doc htm html docx)
end
end
No what I want to know that which Gem can help me to achieve the extraction part and where that code will be placed in this uploader class or anywhere else.. I'm very new to this rails stuff so if this question require anything more pls do let me know.

Minimagick gem fails to convert multipage PDF to several png images

I am new to RoR and I'm trying to develop a slide sharing app through which users can upload and share a multipage PDFs containing a deck of slides (one slide per page). Viewers can then view these slides on a "show" page.
Behind the scenes I am trying to convert the multipage pdf into several .png files (1 pdf page -> 1.png file), and then display them in a carousel/slider fashion.
Here is my uploader:
# encoding: utf-8
class DocUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
# 'public/doc_uploads/'
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
process :filename
process :generate_png
def generate_png
pdf = MiniMagick::Image.new(self.file.path)
pdf.pages.each_with_index do |page, index|
page.write("page#{index}.png")
end
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(pdf)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename
'doc.pdf' if original_filename
end
end
When I try to upload a multipage pdf document, it throws me this error:
'identify /public/uploads/tmp/1443619784-406-3861/doc.pdf' failed with error: at the line pdf.pages.each_with_index do |page, index|
I have tried different solutions to converting the document, but none of them have worked for me so far. Why would a run of the mill .pdf file fail minimagick's validation? Is there anything I can do to avoid running into this issue? Any advice will be greatly appreciated!

Cannot access the pictures uploaded by Carrierwave versions in production environment

This is my Uploader:
class PhotoUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
process :resize_to_fit => [nil, 600]
version :thumb do
process :resize_to_fill => [150,150]
end
# Choose what kind of storage to use for this uploader:
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def cache_dir
"#{Rails.root}/tmp/uploads"
end
def extension_white_list
%w(jpg jpeg gif png)
end
def filename
if original_filename
#name ||= Digest::MD5.hexdigest(current_path)
"#{#name}.#{file.extension}"
end
end
end
In production.rb, I set config.serve_static_assets = false.
And I then deployed this project on a production server(Nginx + Passenger) using Capistrano. When I upload a picture, it will generate 2 copies under the /home/deploy/Gallary/current/public/uploads/picture/photo/ dir, just as following shows:
And I can access the first one through browser(because this one is the default file which Carrierwave generated), while the second one(generated by version :thumb) threw a exception just like this:
ActionController::RoutingError (No route matches [GET] "/uploads/picture/photo/49/thumb_6d9596c7449d3714eadb74b9c71beec2.jpg")
Actually this file thumb_6d9596c7449d3714eadb74b9c71beec2.jpg does exist in the dic right there.
So, what's wrong? And what should I do?
I had a similar problem. Found the answer in another thread.
So try this:
Server unable to find public folder in rails 3 production environment
Worked for me

CarrierWave with custom processor not registering

I am using carrierwave to upload a video then have a version called thumb with a custom processor that takes the video and creates a screenshot using streamio-ffmpeg. Both the video and the file are uploaded correctly but when calling uploader.url(:thumb) I get:
ArgumentError: Version thumb doesn't exist!
VideoUploader.rb
require 'carrierwave/processing/mime_types'
require 'streamio-ffmpeg'
class VideoUploader < CarrierWave::Uploader::Base
include CarrierWave::VideoConverter
include CarrierWave::MimeTypes
process :set_content_type
storage :file
version :thumb do
process :create_thumb
#def full_filename(for_file)
# "thumb_#{File.basename(for_file, File.extname(for_file))}.png"
#end
end
def create_thumb
cached_stored_file! if !cached?
movie = FFMPEG::Movie.new(current_path)
dirname = File.dirname(current_path)
thumb_path = "#{File.join(dirname, File.basename(path, File.extname(path)))}.png"
movie.screenshot(thumb_path, :seek_time => 5)
File.rename thumb_path, current_path
end
def file_identifier
model[:video]
end
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
return "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.user_id}/#{model.id}"
end
end
Then model.video_url(:thumb) returns the argument error. I am not sure what to do or why the version isn't registered any help would be great, thanks.
Fix
What contributed to the error was a mix of restarting the server but not restarting the rails console. Once i did this the Argument error went away but I was getting the wrong path. So i uncommented
def full_filename(for_file)
"thumb_#{File.basename(for_file, File.extname(for_file))}.png"
end
and used
[model].video.recreate_versions!
to correct any errors in the paths or naming schemes that could have occured
most likely some step in your create_thumb method is failing and thus the thumb is never created and has no URL. Are there any exceptions being thrown to your logs?
Perhaps you need to specify the FFMPEG binary location:
FFMPEG.ffmpeg_binary = '/usr/local/bin/ffmpeg'

Resources