I have the following in my view:
<%= image_tag (url_for(:controller => 'app_images', :action => 'picture')) %>
The corresponding controller action is:
def picture
image = AppImage.create(:path => ("portrait3.jpeg"))
image.set_file_from_path
portrait = Magick::Image::from_blob(image.file)[0]
send_data portrait.to_blob, :type => "image/jpeg", :disposition => "inline"
end
And the model method for set_file_from_path is
def set_file_from_path
image = Magick::Image::from_blob(open(self.path).read)[0]
if image.rows > 400
resized = image.scale(400 * image.columns / image.rows, 400)
else
resized = image
end
self.file = resized.to_blob
end
For some reason, this image_tag doesn't render in Heroku, but renders locally, and I have the "portrait3.jpeg" file in my app/assets/images folder.
EDIT: I realized that I used create in heroku without actually connecting to S3 or anything else, which may not work as heroku doesn't allow for storage of a database on its servers I believe. I changed it to new and it still doesn't work.
So I did a few dumb things. Firstly, I forgot to require RMagick in the controller, and secondly I needed to do heroku run rake db:migrate.
Related
I having a big issue here. I really tried, but I can't solve this problem by myself, so I hope people can help me here.
Before talk about my problem, I must say I'm using Paperclip and IMGKit in my Project, but I think the problem is with Paperclip.
I create a Rails Task to take snapshots from the home page of some sites. Sometime ago everything is working fine, but now everything goes down. I import my real database from Heroku to localhost (without any images and migrations of paperclip), run the migrations, delete all old files from 'public/system' and run my task again (to take snapshot of all websites).
So, now I have:
The paths and original images are generated, but when I try to load them in View, this just show as a broken image.
Paperclip doesn't generate the path and converted images of :styles.
Sites that don't have image, I can see my default image correctly.
ImageMagick seems to be working, I try convert some images and worked like a charm.
Let's take a look at the code. Assume that I'm running a task that will perform this task to all sites in my database. The sites are called "items" in my architecture.
Development.rb
#config/environments/development.rb
# "which convert" give me this path
Paperclip.options[:command_path] = "/usr/local/bin/"
Item.rb (model)
My task just call "object.save" of every site in the DB, so my code starts on before_save.
has_attached_file :image,
:styles => { :small => "200x147#" },
:convert_options => { :small => "-quality 75 -strip" },
:default_url => '/images/:style/bitcoin-earth.jpg'
before_save :generate_data
def generate_data
self.image = get_image(self.id, self.url_original)
end
# Take snapshot of the website
def get_image(filename, link)
kit = IMGKit.new(link.to_s, :quality => 100, :width => 1024, :height => 768)
file = Tempfile.new(["template_#{filename}", 'png'], 'tmp',
:encoding => 'ascii-8bit')
file.write(kit.to_img(:png))
file.flush
return file
end
View
<%= image_tag store.image.url %>
Gemfile
gem "paperclip"
If I try to run rake paperclip:refresh:missing_styles, the task finish very fast without any error. But if I try to run rake paperclip:refresh CLASS=Item I got:
Image Paperclip::Errors::NotIdentifiedByImageMagickError
And yes, I already search for it and I didn't found a solution for my case.
A little tip?
When I "inspect element" in my project and try to see the source of the item image, I saw:
http://localhost:3000/public/system/items/images/000/000/216/original/template_21620140109-14507-1c0yszzpng?1389305824
But if I go to my project folder, I just see a image called template_21620140109-21209-1yls03opng. Note that doesn't exist any "?1389305824" there. See the image above.
Well, I think that's it. What can be the problem? I really need solve this issue, please, help me :/
[ Edited on Jan 10, 2013 ]
Item.rb (model):
before_save :generate_data
def generate_data
file = File.open(get_image(self.id, self.url_original))
self.image = file
file.close
end
def get_image(filename, link)
kit = IMGKit.new(link.to_s, :quality => 100,
:width => 1024, :height => 768)
file = Tempfile.new(["template_#{filename}", '.png'], 'tmp',
:encoding => 'ascii-8bit')
file.write(kit.to_img(:png))
file.flush
return file
end
Now I don't have any error on console while getting images and saving on DB, but Paperclip still don't generate my :styles. When I go to log/development.log, I can see this error, but I don't know what I can do to solve:
Command :: file -b --mime 'tmp/template_24320140110-17577-80zj1c.png'
Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/template_24320140110-17577-80zj1c20140110-17577-mqa2q3.png[0]'
[paperclip] An error was received while processing: #<Paperclip::Errors::NotIdentifiedByImageMagickError: Paperclip::Errors::NotIdentifiedByImageMagickError>
I think we're getting closer, please, keep helping me :)
I think your problem is here:
template_21620140109-14507-1c0yszzpng?1389305824 #-> should have .png (not a valid image)
Image
This might not be the problem, but maybe you could streamline your method to exclude the temporary file:
# Take snapshot of the website
def get_image(filename, link)
kit = IMGKit.new(link.to_s, :quality => 100, :width => 1024, :height => 768)
file = kit.to_file("system/temp/template_#{filename}")
return file
end
I think the issue is that ImageMagick is not being passed a "real" file, and consequently you're getting the unrecognized image issues
I'm using this gem to use Prawn to create a PDF: https://github.com/Whoops/prawn-rails
However, I can't seem to figure out how to add an image. I've tried pdf.image "path/to/img.jpg but it would say the file is not a recognized format.
I've also looked into this on page 101: http://prawn.majesticseacreature.com/manual.pdf , but it doesn't work.
This is happening in the views:
prawn_document() do |pdf|
pdf.image "#{Rails.root}/public/logo.gif"
end
This throws:
Prawn::Errors::UnsupportedImageType at /admin/purchases/6188.pdf
image file is an unrecognised format
Same happens for a .jpg image
I would do something like this.
gem 'prawn'
bundle install
In your controller.
def controller_method
pdf = Prawn::Document.new
begin
pdf_file_path = "#{Rails.root}/public/output"
full_doc = "#{Rails.root}/public/something.png"
pdf.image full_doc
pdf.start_new_page
pdf.render_file pdf_file_path
rescue Prawn::Errors::UnsupportedImageType
flash[:notice] = "Image unsupported"
redirect_to '/handle'
end
end
Adding an image is easy enough.
def download
#document = Document.find(params[:id])
tmp_file = Tempfile.new(Digest::MD5.hexdigest(rand(12).to_s))
pdf = Prawn::Document.generate(tmp_file.path, :margin => 0, :page_size => "A4", :skip_page_creation => true) do |posting|
posting.start_new_page
posting.image #document.user.logo.path
send_data posting.render, :filename => "whatever.pdf", :type => "application/pdf"
end
end
Obviously #document.user.logo.path could be a literal path, that's just a Paperclip attachment in this case.
UPDATE
If it's a literal path you might need to do something like this:
require "open-uri"
def download
...
posting.image File.open("/path/to/image.jpg")
...
end
It seems the latest prawn (version 1.0.0) has changed. You'll get
undefined method `image=' for #<Prawn::Document
if you try and apply something to pdf.image.
This worked for me:
img = "#{Rails.root}/public/my_lovely_image.png"
Prawn::Document.new(background: img)
I have seen a number of close problems, but have not been able to find a solution to get solve my problem. I am using Ruby 1.9.3 with Rails 3.2.13.
I am using Prawn to generate a PDF, and I a logo to appear. The logo is found without a problem in the development environment, but fails in the production environment, which is on Heroku.
In my controller I have:
def generate_risk_pdf(risk)
Prawn::Document.new do
image "#{Rails.root}/app/assets/images/logo-print.png", :scale => 0.75 if Rails.env.development?
image "#{ActionController::Base.helpers.asset_path('logo-print.png')}", :scale => 0.75 if Rails.env.production?
move_down 2
formatted_text [{:text => Exercise Australia", :styles => [:bold], :size => 20}]
font_size 6
bounding_box([bounds.right - 150, bounds.bottom], :width => 240, :height => 20) do
text "Copyright: Exercise Australia, #{Date.today.year}"
end
end.render
end
The Heroku logs have
ArgumentError (/assets/logo-print-5b6da7bd4012d953bc1bc749cf934d91.png not found):
app/controllers/single_entries_controller.rb:309:in `block in generate_risk_pdf'
Which corresponds to the line above with Rails.env.production?
If I append the URL to /assets/logo-print-5b6da7bd4012d953bc1bc749cf934d91.png the image file exists.
If I remove that line, it works (minus the logo).
Please note this is not only failing for Prawn, but even when I tried to use an image inline for an email.
Please help, I'm tearing my hair out!
Added: Serving from public works- but it is not my preferred solution.
Try add this to:
rails.root/config/environments/produciton.rb
config.serve_static_assets = true
config.assets.compile = true
A combination of both methods worked for me :
image "#{Rails.root}/app/assets#{ActionController::Base.helpers.asset_path('images/logo-print.png')}"
UPDATE 2
i use nokogiri to download content and images to a rails app. For this, i write the script/scraping.rb file:
require 'open-uri'
page_url = "<site_url>"
url = "<page_of_site_url>"
b = Nokogiri::HTML(open(url))
b.css(".col").each do |item|
img_url = item.at(".field-content a img")['src'].split('?')[0]
root_img_url = URI.join(page_url,img_url).to_s
file = File.open(File.join(Rails.root, 'app', 'assets', 'images', File.basename(root_img_url)), 'wb') do |f|
f.write(open(root_img_url).read)
end
Book.create(
:cover => File.basename(root_img_url),
:title => item.at_css(".views-field-title a").text,
:onsaledate => item.at_css(".date-display-single")['content'])
end
end
then i run the script in the terminal:
rails runner script/scraping.rb
Seconds later, i have my database with the content info, and the images in the folder assets/images.
Thanks to #JoshLewis for his interest and special thanks to #mario_chavez for his help.
Is there a recommended technique for migrating a large set of paperclip S3 images to a new :url and :path format?
The reason for this is because after upgrading to rails 3.1, new versions of thumbs are not being shown after cropping (previously cached version is shown). This is because the filename no longer changes (since asset_timestamp was removed in rails 3.1). I'm using :fingerprint in the url/path format, but this is generated from the original, which doesn't change when cropping.
I was intending to insert :updated_at in the url/path format, and update attachment.updated_at during cropping, but after implementing that change all existing images would need to be moved to their new location. That's around half a million images to rename over S3.
At this point I'm considering copying them to their new location first, then deploying the code change, then moving any images which were missed (ie uploaded after the copy), but I'm hoping there's an easier way... any suggestions?
I had to change my paperclip path in order to support image cropping, I ended up creating a rake task to help out.
namespace :paperclip_migration do
desc 'Migrate data'
task :migrate_s3 => :environment do
# Make sure that all of the models have been loaded so any attachments are registered
puts 'Loading models...'
Dir[Rails.root.join('app', 'models', '**/*')].each { |file| File.basename(file, '.rb').camelize.constantize }
# Iterate through all of the registered attachments
puts 'Migrating attachments...'
attachment_registry.each_definition do |klass, name, options|
puts "Migrating #{klass}: #{name}"
klass.find_each(batch_size: 100) do |instance|
attachment = instance.send(name)
unless attachment.blank?
attachment.styles.each do |style_name, style|
old_path = interpolator.interpolate(old_path_option, attachment, style_name)
new_path = interpolator.interpolate(new_path_option, attachment, style_name)
# puts "#{style_name}:\n\told: #{old_path}\n\tnew: #{new_path}"
s3_copy(s3_bucket, old_path, new_path)
end
end
end
end
puts 'Completed migration.'
end
#############################################################################
private
# Paperclip Configuration
def attachment_registry
Paperclip::AttachmentRegistry
end
def s3_bucket
ENV['S3_BUCKET']
end
def old_path_option
':class/:id_partition/:attachment/:hash.:extension'
end
def new_path_option
':class/:attachment/:id_partition/:style/:filename'
end
def interpolator
Paperclip::Interpolations
end
# S3
def s3
AWS::S3.new(access_key_id: ENV['S3_KEY'], secret_access_key: ENV['S3_SECRET'])
end
def s3_copy(bucket, source, destination)
source_object = s3.buckets[bucket].objects[source]
destination_object = source_object.copy_to(destination, {metadata: source_object.metadata.to_h})
destination_object.acl = source_object.acl
puts "Copied #{source}"
rescue Exception => e
puts "*Unable to copy #{source} - #{e.message}"
end
end
Didn't find a feasible method for migrating to a new url format. I ended up overriding Paperclip::Attachment#generate_fingerprint so it appends :updated_at.