Imagemagick no such file or directory error in Mac - ruby-on-rails

I'm using carrierwave to upload images from my rails app, and later pass that image to resque for resizing them in the background. The image gets uploaded properly. The problem when resque tries to resize it, mini_magick says that "No such file or directory"
This is my ImageController code which handles the upload
#create image and embed into story
def create
img_attr = params[:image]
img_attr[:media] = params[:image][:media].first if params[:image][:media].class == Array
image = Image.new img_attr
#story.images << image
if #story.save
Resque.enqueue(ImageQueue,image.id)
respond_to do |format|
format.json {
render :json => [image.to_jq_upload].to_json
}
end
else
render :json => [{:error => 'custom_failure'}], :status => 304
end
end
And this is my Resque code
class ImageQueue
#queue = :image_queue
def self.perform(image_id)
image = Image.find image_id
image.recreate_delayed_versions!
image.save
end
end
And the upload path is set here
def store_dir
"uploads/stories/#{model.viewable_id}/res"
end
This is the error stack that I get
No such file or directory - /uploads/stories/533d5b8756617390c0070000/res/636a8fe128.jpg
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/mini_magick-3.7.0/lib/mini_magick/image.rb:110:in `initialize'
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/mini_magick-3.7.0/lib/mini_magick/image.rb:110:in `open'
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/mini_magick-3.7.0/lib/mini_magick/image.rb:110:in `open'
/Users/skmvasu/repo/mangoweb/app/uploaders/image_uploader.rb:97:in `original_dimensions'
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/carrierwave-0.10.0/lib/carrierwave/uploader/processing.rb:84:in `block in process!'
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/carrierwave-0.10.0/lib/carrierwave/uploader/processing.rb:76:in `each'
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/carrierwave-0.10.0/lib/carrierwave/uploader/processing.rb:76:in `process!'
The weird thing is the same code works in my Linux box, and my production box which also runs Linux, but not on my new Mac. Is it a problem with ImageMagick? I'm installing it through Homebrew. I even tried uninstalling it and reinstalling it with source, but that didn't work either.
I'm not sure what I'm doing wrong here? Please help me solve this issue.

As per the error,
No such file or directory - /uploads/stories/533d5b8756617390c0070000/res/636a8fe128.jpg
Either 636a8fe128.jpg is not there at the given path i.e., /uploads/stories/533d5b8756617390c0070000/res or
/uploads/stories/533d5b8756617390c0070000/res one or all of the directories in this path are not there. I would recommend go to terminal and navigate through the path and see if it allows you to change directory till you reach res directory. If yes, then inside res directory do ls -l and see if the output shows 636a8fe128.jpg file.
UPDATE
Specify the full path including Rails.root:
def store_dir
"#{Rails.root}/public/uploads/stories/#{model.viewable_id}/res"
end
without #{Rails.root}/public/, path generated was /uploads/stories/533d5b8756617390c0070000/res/636a8fe128.jpg where the first / points to the root directory of the server.

Related

compile in Rails 6 Webpacker doesn't make changes to send_data with methods defined in model

I recently upgraded to Rails 6 with webpack. This is when I started to notice this issue. I have a send_data method in a controller that works with either a csv or pdf (Prawn) format. Currently experiencing this issue with a csv.
In development, I made a method for self.to_csv in models/user.rb and used it to download some data into a CSV file. I deployed the file to my production server. And downloaded the file there.
Then I made a change to the columns that would be printed in that file. I saw the changes immediately in development. I deployed these changes to production, but still get the old columns. I checked the files on the server and they have the updates.
In Rails 5, I would see these changes immediately in production, too. Is there a way I can speed the server along here? Re-cache the files? Etc.
Here are my files.
In controllers/users_controller.rb:
def index
respond_to do |format|
format.csv {
send_data User.all.to_csv
}
end
end
In models/user.rb:
def self.to_csv
attributes = %w{first_name last_name id}
CSV.generate(headers: true) do |csv|
csv << attributes
all.each do |obj|
csv << [obj.first_name, obj.last_name, obj.id]
end
end
end
I originally had it just print first and last name to the CSV. That's what I still get in production.
And here is my deployment pipeline:
$ yarn install --check-files
$ rails db:migrate
$ RAILS_ENV=production rails assets:precompile
$ touch tmp/restart.txt
Running Rails 6.0.2.2, Webpack 4.42.0, and Ruby 2.5.5 on Passenger. Hosted by Dreamhost.
This worked for me and was thanks to max's suggestion in the comments.
I placed a stale? block around the send_data line and when I made an update it showed up instantly.
The new controllers/users_controller.rb looks like this:
def index
#users = User.all
respond_to do |format|
format.csv {
if stale?(#users)
send_data #users.to_csv
end
}
end
end
This block came from here:
https://thoughtbot.com/blog/take-control-of-your-http-caching-in-rails

Rails - Serve static CSV file as assets in Development with Thin

I'm simply trying to write to a CSV file in dev with thin, but I am continually getting an error that says
No such file or directory - http://localhost:3000/assets/tplan_log.csv
However, my config looks like this:
development.rb
config.serve_static_assets = true
And my controller looks like this:
def csv
#this returns a valid path
log_path = view_context.asset_path 'plan_log.csv'
#error occurs here
CSV.open(log_path) do |csv|
csv << ["row","row1","row2"]
end
respond_to do |format|
format.js {render json: #diaggroup.errors, status: :unprocessable_entity}
end
end
Rails 3.2.12
Edit: To clarify, I'm looking for an answer on how to serve this file in development so that it is accessible. I know it's being served with asset pipeline, but there is no get method associated with it, so it's not able to be accessed.
This ended up being an issue with reference.
I was using a reference such as:
http://path/to/file.jpg
Rails wants:
/path/to/file.jpg

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'

Generate imagemagick / carrierwave thumbnails when they are requested

I am using the carrierwave gem with Rmagick in a Rails app. I've set up a new version in my uploader file:
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :preview do
process :resize_to_fill => [580, 350]
end
end
Of course, I included rmagick and carrierwave in my gemfile. Now I try to load the preview version of my images in my views:
#product.photos.first.image.preview
This does not give any errors, but loads a broken image. If I copy the url of the image, I get a routing error ('no route matches /path/to_my_imagesfolder/preview_image.png'). If I remove the preview method, the image loads properly.
What can the problem be? I thought maybe it was a permissions issue, but I set the uploads folder with 777 and it still fails.
Any ideas?
EDIT: I realized if I upload the images again the new versions are created. Is it possible to make Rmagick create them when they are requested (like TimThumb does in PHP) Or at least is there any command to batch create all the versions?
There must be a better way than uploading all the images...
You can use .recreate_versions!
For example:
Product.all.each do |product|
product.photos.each do |photo|
photo.recreate_versions!
end
end
I'd just use this: https://github.com/markevans/dragonfly

Delete a folder after the cucumber scenario

I have 2 cucumber scenarios that simulate paperclip image upload. I want to remove those folders again once scenarios are complete.
I have the following attachment folder structure:
:url => "/system/:attachment/:listing_id/:id/:style_:filename"
Paperclip automatically deletes the :id/:style_:filename folder but not the parent folder.
I have a the following in my listings controller (1 listing has many images) which works great to remove the image folder with the listing id when the listing is deleted. I need to simulate the same in Cucumber after the step is run.
def destroy
#listing = Listing.find(params[:id])
# if destroy was a success, remove the listing image folder
if #listing.destroy
end
require 'fileutils'
dir = Rails.root + '/system/photos/' + #listing.id.to_s()
FileUtils.rm_rf(dir)
respond_to do |format|
format.html { redirect_to(listings_url) }
format.xml { head :ok }
end
end
I could a) tell cucumber to delete the :listing_id folder name after running through the scenario or b) tell cucumber to delete the listing as the final step?
I've tried adding this to my cucumber env.rb file:
AfterStep('#paperclip') do
# This will only run before steps within scenarios tagged
# with #cucumis AND #sativus.
# delete folders that were created with paperclip during the test
require 'fileutils'
##listing.id = 55
#dir = Rails.root + '/system/photos/' + #listing.id.to_s()
dir = Rails.root + '/system/photos/55' # NOT WORKING
FileUtils.rm_rf(dir)
end
But that causes problems because 1) I don't know how to get the #listing.id from that scenario, and 2) even when I hardcode it (as above) it doesn't remove it.
Any thoughts?
Already a bit older, but as I just ran over the same issue myself here is what I did:
dir = Rails.root + 'images/'
dir.rmtree if dir.directory?
# or the short form, if you know the directory will be there
(Rails.root + 'images/').rmtree
So I guess the problem was your '/' at the beginning of the folder. At least for me it didn't work with that slash.
I would leave a comment, but don't have the points (or so I would assume) to do so.
There really is no reason that this shouldn't work. Have you confirmed that FileUtils.rm_rf(dir) does in fact remove the directory in the test environment?
You can test this in 'script/console test'.
You can hook into Cucumber's at_exit to remove any folders you like. I'm using the attached code in features/support/uploads_cleaner.rb.
# Removes uploaded files when all scenarios for the current test process
# are finished. Ready for parallel_tests, too.
require 'fileutils'
at_exit do
directory_name = "#{ Rails.env }#{ ENV['TEST_ENV_NUMBER'] }"
uploads_path = Rails.root.join('public/system', directory_name)
FileUtils.remove_dir(uploads_path) if uploads_path.directory?
end
Reposted from this makandra Card.

Resources