I'm trying to display an image from the database that was imported by paperclip. I have tried several things but I keep getting an error message that "File not found".
Here is what I have in my prawn config file:
def show_sample
id_sample = Rails.root + #id_card_design.picture.url(:large).sub!(/\?.+\Z/, '')
image id_sample, at: [0,900], height: 161, width: 250
move_down 20
end
I tried the following to strip off the ?12345676 but it still doesn't work.
.sub!(/\?.+\Z/, '')
Try using picture.path instead of picture.url
Related
I want to use the Shrine gem to upload video files, transcode, & generate thumbnails from the video.
I am trying to convert Erik Dahlstrand's Shrine-Rails-example from photos to videos. I am having trouble creating the video uploader. I based this code on Video isn't of allowed type (allowed types: video/mp4), Shrine, Rails
require "streamio-ffmpeg"
class VideoUploader < Shrine
ALLOWED_TYPES = %w[video/mp4 video/quicktime video/x-msvideo video/mpeg]
plugin :processing
plugin :versions
plugin :determine_mime_type
plugin :cached_attachment_data
plugin :remove_attachment
plugin :add_metadata
plugin :validation_helpers
plugin :derivation_endpoint, prefix: "derivations/video"
add_metadata do |io, context|
movie = Shrine.with_file(io) { |file| FFMPEG::Movie.new(file.path) }
{ "duration" => movie.duration,
"bitrate" => movie.bitrate,
"resolution" => movie.resolution,
"frame_rate" => movie.frame_rate }
end
movie.screenshot("video_thumb_007.jpg", seek_time: 5, resolution: '320x240')
metadata_method :duration
Attacher.validate do
validate_max_size 100.megabyte, message: "is too large (max is 100 MB)"
validate_mime_type_inclusion ALLOWED_TYPES
end
end
I get this error:
/var/folders/mm/_j8x4k2176jcv31zvbc497_c0000gp
/T/shrine20190607-24438-4f3jz2.m4v: No such file or directory
and in fact, there is no file in that location. So where is the file stored while waiting for upload??
Also, using the demo to upload photos to AWS (production env), the objects are stored in the bucket in a folder called 'photos'. Shrine uses the table name to name the folder apparently. Is possible to create alternative & nested folder names?
Thank you - seems like an amazing gem! Trying to understand it better!
Thx
Further delving into the documentation, I was able to solve this problem with only one remaining question - is it possible to control which folders in the AWS bucket the original and thumbs are uploaded to? Thx
Solution:
require "streamio-ffmpeg"
require "tempfile"
class VideoUploader < ImageUploader
plugin :add_metadata
plugin :validation_helpers
plugin :processing
plugin :versions
plugin :delete_raw
add_metadata do |io, context|
movie = Shrine.with_file(io) { |file| FFMPEG::Movie.new(file.path) }
{ "duration" => movie.duration,
"bitrate" => movie.bitrate,
"resolution" => movie.resolution,
"frame_rate" => movie.frame_rate
}
end
process(:store) do |io, context|
versions = {original: io}
io.download do |original|
screenshot1 = Tempfile.new(["screenshot1", ".jpg"], binmode: true)
screenshot2 = Tempfile.new(["screenshot2", ".jpg"], binmode: true)
screenshot3 = Tempfile.new(["screenshot3", ".jpg"], binmode: true)
screenshot4 = Tempfile.new(["screenshot4", ".jpg"], binmode: true)
movie = FFMPEG::Movie.new(original.path)
movie.screenshot(screenshot1.path, seek_time: 5, resolution: '640x480')
movie.screenshot(screenshot2.path, seek_time: 10, resolution: '640x480')
movie.screenshot(screenshot3.path, seek_time: 15, resolution: '640x480')
movie.screenshot(screenshot4.path, seek_time: 20, resolution: '640x480')
[screenshot1, screenshot2, screenshot3, screenshot4].each(&:open) # refresh file descriptors
versions.merge!(screenshot1: screenshot1, screenshot2: screenshot2, screenshot3: screenshot3, screenshot4: screenshot4)
end
versions
end
Attacher.validate do
validate_max_size 100.megabyte, message: "is too large (max is 100 MB)"
validate_mime_type_inclusion ALLOWED_TYPES
end
end
In rails 5.2, I have a model using has_many_attached :images. I would like to send out an email that includes all associated images as attachments.
My mailer method currently looks like:
def discrepancy_alert(asset_discrepancy_id, options={})
#asset_discrepancy = AssetDiscrepancy.find asset_discrepancy_id
#asset_discrepancy.images.each_with_index do |img,i|
attachments["img_#{ i }"] = File.read(img)
end
mail to: 'noone#gmail.com', subject: "email subject"
end
obviously, File.read does not work here because img is not a path, it is a blob. I have not been able to find any info on this in the docs
Question One:
Is there a rails method for attaching a blob like this?
I can use the following instead:
#asset_discrepancy.images.each_with_index do |img,i|
attachments["img_#{ i }"] = img.blob.download
end
Question Two:
the download method could use a log of RAM, is this usage ill advised?
It seems, with the addition of ActiveStorage, that rails mailers would have some new methods for interaction between the two....I have not seen anything in the docs. All the mailer attachments[] examples use paths to a local file.
in app/mailers/mailer.rb:
if #content.image.attached?
#filename = object.id.to_s + object.image.filename.extension_with_delimiter
if ActiveStorage::Blob.service.respond_to?(:path_for)
attachments.inline[#filename] = File.read(ActiveStorage::Blob.service.send(:path_for, object.image.key))
elsif ActiveStorage::Blob.service.respond_to?(:download)
attachments.inline[#filename] = object.image.download
end
end
in mailer view:
if #filename
image_tag(attachments[#filename].url)
else
image_tag(attachments['placeholder.png'].url)
end
This worked for me in production using Amazon S3.
in mailer view:
if #object.images
#object.images.each do |image|
path = "https://www.example.com" + Rails.application.routes.url_helpers.rails_blob_path(image, only_path: true)
<img src="<%=path%>">
end
end
Here is the working solution for active storage url in email template. I have seen the images visible in gmail. You can use "rails_blob_url". This works for file stored in aws s3.
mailer.rb
....
#image_url = Rails.application.routes.url_helpers.rails_blob_url(blob),
....
mailer view file
<img src="<%= #image_url %>">
Using: Rails 4.2, Prawn, Paperclip, DelayedJobs via ActiveJobs, Heroku.
I have a PDF that is very large and needs to be handled in the background. Inside a custom Job I want to create it, upload it to S3, and then email the user with a url when its ready. I facilitate this via a PdfUpload model.
Is there anything wrong with my approach/code? Im using File.open() as outlined in examples I found, but this seems to be the root of my error ( TypeError: no implicit conversion of FlightsWithGradesReport into String ).
class PdfUpload < ActiveRecord::Base
has_attached_file :report,
path: "schools/:school/pdf_reports/:id_:style.:extension"
end
/pages_controller.rb
def flights_with_grades_report
flash[:success] = "The report you requested is being generated. An email will be sent to '#{ current_user.email }' when it is ready."
GenerateFlightsWithGradesReportJob.perform_later(current_user.id, #rating.id)
redirect_to :back
authorize #rating, :reports?
end
/ the job
class GenerateFlightsWithGradesReportJob < ActiveJob::Base
queue_as :generate_pdf
def perform(recipient_user_id, rating_id)
rating = Rating.find(rating_id)
pdf = FlightsWithGradesReport.new( rating.id )
pdf_upload = PdfUpload.new
pdf_upload.report = File.open( pdf )
pdf_upload.report_processing = true
pdf_upload.report_file_name = "report.pdf"
pdf_upload.report_content_type = "application/pdf"
pdf_upload.save!
PdfMailer.pdf_ready(recipient_user_id, pdf_upload.id)
end
end
This results in an error:
TypeError: no implicit conversion of FlightsWithGradesReport into String
Changing this:
pdf_upload.report = File.open( pdf )
to this:
pdf_upload.report = StringIO.new(pdf.render)
fixed my problem.
I have this in my code:
size=128,128
#app.route('/',methods=['GET','POST'])
def upload():
print request.method
if request.method == 'POST':
file = request.files['image']
im = Image.open(file)
im.resize(size)
im.save("test.png","PNG")
f=open("test.png",'r')
conn = tinys3.Connection('AKIAI2GPQ','fAQxDLbvZcqhXvjd',tls=True)
conn.upload(im,f,"snappie.watermarks")
print "got file"
return redirect("https://www.google.com")
return render_template('index.html')
hopefully you can see that I am trying to handle the file upload from request.files, resize it, and then upload that to amazon s3. However right now its getting hung up on the conn.upload(im,f,"snappie.watermarks") line.
This is the error:
File "/home/alex/snappie/web/server.py", line 25, in upload
conn.upload(im,f,"snappie.watermarks")
File "/usr/local/lib/python2.7/dist-packages/tinys3/connection.py", line 152, in upload
return self.run(r)
File "/usr/local/lib/python2.7/dist-packages/tinys3/connection.py", line 233, in run
return self._handle_request(request)
File "/usr/local/lib/python2.7/dist-packages/tinys3/connection.py", line 255, in _handle_request
return request.run()
File "/usr/local/lib/python2.7/dist-packages/tinys3/request_factory.py", line 147, in run
headers['Content-Type'] = self.content_type or mimetypes.guess_type(self.key)[0] or 'application/octet-stream'
File "/usr/lib/python2.7/mimetypes.py", line 298, in guess_type
return _db.guess_type(url, strict)
File "/usr/lib/python2.7/mimetypes.py", line 114, in guess_type
scheme, url = urllib.splittype(url)
File "/usr/lib/python2.7/urllib.py", line 1074, in splittype
match = _typeprog.match(url)
TypeError: expected string or buffer
Apparently its having issues with one of those 3 arguments but I am not sure which one? I am also not sure I am handling the file correctly. Do I need to save the image and then re-open it in order to upload it to amazon s3? I do this because all the tinys3 examples do so, but my file is already open so perhaps its redundant?
It looks like your image argument might be mixed up. Here's the signature we want:
conn.upload(key, local_file, bucket)
tinys3 expects a string value for the key and an open file-like object for local_file. Try the following:
conn.upload("test.png", f, "snappie.watermarks")
I am working with Prawn to generate a pdf, I have to insert an image in a cell of a table.
My code is like this:
image = "path to file"
subject = [["FORMATIVE I "," SUMATIVE ","GRAPH"],
[formative_1,sumative, {:image => image}]
]
table subject
But, I get an error which says:
prawn/table/cell.rb:127:in `make': Content type not recognized: nil (ArgumentError)
How can I resolve this? Any help is greatly appreciated.
Cheers!
In the current version of Prawn 0.12.0 it is not possible to embed images in a Prawn::Table, but this feature seems to be under way, see here. At the moment you have to write your own table, something like
data = [[{:image => "red.png"},{:text => "Red"}],
[{:image => "blue.png"},{:text => "Blue"}]]
data.each_with_index do |row,i|
row.each_with_index do |cell,j|
bounding_box [x_pos,y_pos], :width => cell_width, :height => cell_height do
image(cell[:image], ...) if cell[:image].present?
text_box(cell[:text], ...) if cell[:text].present?
end
x_pos = (x_pos + cell_width)
end
y_pos = (y_pos - cell_height)
end
Prawn in version 0.12.0 doesn't give the possibility to insert image in a cell. Look at this for further information. It works on the next version 1.0.0.rc1. Just change your version. You can also use the tricky way, but I advise you not to do so.
The manual is available here.
The commit and explanation for that feature from the author. Here