Converting a pdf to jpeg using Rmagick - ruby-on-rails

I am trying to convert a pdf to a jpeg image using Rmagick. I am running into some trouble with the following code:
pdf_link = "https://staging.shurpa.com/deliveries/BtrPsIxl/label.pdf"
file = Tempfile.new(['order', '.jpeg'])
p pdf_link
p file.path
im = ImageList.new(pdf_link)
puts "SUPP"
im.write(file.path.to_s)
I recieve this error:
"https://staging.shurpa.com/deliveries/BtrPsIxl/label.pdf"
"/var/folders/qm/yk_w5d9545j_6wqk6100dhjm0000gq/T/order20170706-43294-
15myct1.png"
Magick::ImageMagickError: unable to open file `/var/folders/qm/yk_w5d9545j_6wqk6100dhjm0000gq/T/magick-43294MCNyzIu4Oenn': No such file or directory # error/constitute.c/ReadImage/544from/Users/timnaughton/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rmagick-2.16.0/lib/rmagick_internal.rb:1616:in `read'
However the code works perfectly fine when I feed it this pdf_string:
"https://shippo-delivery-east.s3.amazonaws.com/b2a3e1cd070748cd80b492aa421832a3.pdf?Signature=nf6woycGiOydPI8eSnLcq3r0tEc%3D&Expires=1530816480&AWSAccessKeyId=AKIAJGLCC5MYLLWIG42A"

There appears to have been an issue with the service that was providing the pdf to me. The pdf was recently changed to a secure state and I needed to utilize access keys. This resulted in rmagick not being able to access the image file and returning the stated error.

Related

How to create movie screenshot by ffmpeg in an amazon S3 path

I tried to create using ffmpeg a video screenshot from a remote video url in heroku console. Below is how I generated a movie instance and can see also an empty ready to be written file at S3. But the last line movie.screenshot is not working and generates this error:
FFMPEG::Error: Failed encoding.Errors: no output file created
Here is the code
s3 = Aws::S3::Resource.new(region: 'us-west-1')
bucket = s3.bucket("ruby-sample-kb-#{SecureRandom.uuid}")
bucket.create
object = bucket.object('ex-vid-test-kb.jpg')
object.put(acl: "public-read-write")
path = object.public_url
movie = FFMPEG::Movie.new("https://www.googleapis.com/download/storage/v1/b/seppoav/o/3606137_51447286560__56BAF29C-05CB-4223-BAE6-655DF2236321.MOV?generation=1492780072394755&alt=media")
movie.screenshot(path, :seek_time => 2)
I also tried the following line just if it should be written via put. What am I missing here?
object.put(acl: "public-read", body: movie.screenshot(path, :seek_time => 2))
I ended up convincing myself that ffmpeg movie.screenshot won't work for remote url path. So I had to figure out a solution where I can create tempfile in heroku system although the tempfiles stay per dyno.
file = Tempfile.new [prefix, suffix], "#{Rails.root}/app/assets/images/video_screenshots"
movie.screenshot(file.path)
This worked Ok.

I want to make my rails app read qr codes but an error that undefined method `read' for #<ChunkyPNG::Image:> occurred

p ZBar::Image.from_jpeg(qrcode_tag("hello")).process
def qrcode_tag(text)
qr = ::RQRCode::QRCode.new(text).as_png
image = Magick::Image.from_blob((qr).read).first
image.format = 'JPEG'
return image
end
As I know, RQRCode doesn't support png file type, so I tried to convert a qr code that its file type is png to jpeg then an error that I indicated occurred.
ChunkyPNG::Image does not provide a read method. You probably want to call to_datastream on it. See the documentation of the chunky_png gem: http://www.rubydoc.info/github/wvanbergen/chunky_png/ChunkyPNG/Image

retrieve carrierwave file uploaded to Amazon S3

Using Rails 3.2, carrier wave, and recently switched to store on Amazon S3. My setup and uploads are all working fine.
1. I have image_uploader.rb to upload and store images. Displaying them all works fine
2. I have file_uploader.rb to upload and store files. I've even taken it a step further to upload ZIP files and extract a version so that both the ZIP file and TXT files are stored in the correct place on S3.
My problem is I run a method on the TXT file. In the past, I used storage :file
With that I was able to:
Dir.chdir("public/uploads/")
import_file = Dir['*.TXT'].first
f = File.new(import_file)
Now, that I'm using storage :fog I can't get seem to retrieve/File.new/Open the file.
I see the file with the usual commands:
#upload1.team_file # stored file
#upload1.team_file.url # url
#upload1.team_file_url(:data_file).to_s # version created
I've been pouring through all kinds of very limited leads on retrieving and/or opening the file, but everything I try seems to return errors, such as:
Errno::ENOENT: No such file or directory - https://teamfiles.s3.amazonaws.com/data_files…
Thoughts on the difference here of retrieving and USING a file from AmazonS3? Thanks!
Pulling from multiple threads, APIs, etc. I'm answering my own question with what I've found. I welcome any corrections or improvements:
To retrieve carrierwave files uploaded to AmazonS3, you have to understand that open(#upload.file_url) or File.open(#upload.file_url) does NOT open the file, it only opens the PATH to the file. (ref: Ruby OpenURI )
I use: open_uri_url = open(#upload.file_url)
You then have to find the specific file in that path that you want. For me, I then find a ZIP file that was uploaded to AmazonS3 and Extract the specific file within the ZIP file that I want with a unique *.ABC extension:
zip_content_file = Zip::File.open(open_uri_url).map{|content| content if content.to_s.split('.').last == "ABC"}.compact.first
Now, from here, where to extract to?? I create a unique directory in the Rails tmp directory to extract the file to, use it and then delete the directory:
tmp_directory = "tmp/extracts/#{#upload.parent_id}/"
FileUtils.mkdir_p(tmp_directory) unless File.directory?(tmp_directory)
extract = zip_content_file.extract(tmp_directory + content_file.to_s)
Now with found from the AmazonS3 stored ZIP file and extracted, I can open, read, etc:
f = File.new(tmp_directory + extract.to_s)
I hope this helps with Carrierwave, AmazonS3, ZIP files and using them once uploaded.

Spring API for Uploading Files (MultiPart) interprets contentType of images as application/octet-stream

Uploading files(images,..) with Spring API(MultiPartFile) works fine on localhost.
However after deployement on Linux Server , the console shows that Spring API interprets contentType of file uploaded such as application/octet-stream .,
at java.io.FileOutputStream.<init>(FileOutputStream.java:209)
at java.io.FileOutputStream.<init>(FileOutputStream.java:160)
at org.apache.commons.fileupload.disk.DiskFileItem.write(DiskFileItem.java:449)
at com.myproject.utils.upload.FileUploadUtil.uploadFile(FileUploadUtil.java:64)
at com.myproject.utils.GenericFileUploadService$_upload_closure1.doCall(GenericFileUploadService.groovy:56)
at com.myproject.utils.GenericFileUploadService.upload(GenericFileUploadService.groovy:53)
at com.myproject.utils.GenericFileUploadService.upload(GenericFileUploadService.groovy:63)
... 7 more
org.springframework.web.multipart.commons.CommonsMultipartFile#1723bb6
content.AssetService File instance : org.springframework.web.multipart.commons.CommonsMultipartFile#1723bb6
println contentType =application/octet-stream
Hence , when i use ImagikImage to convert the uploaded file to thumbnail , i get the following error :
`org.im4java.core.CommandException: org.im4java.core.CommandException: convert: unable to open image
/var/lib/tomcat7/myproject/ROOT/media/5/34: # error/blob.c/OpenBlob/2587.
knowing that the image should be saved normally in the following path
/var/lib/tomcat7/myproject/ROOT/media/5/34.png
i found this configuration and i don't know its efficiency:
grails.web.disable.multipart=true
your file upload form should have an attribute enctype='multipart/form-data', if it doesn't, file contents can be treated as if they were unicode characters and your image files would get corrupted

ruby reading files from S3 with open-URI

I'm having some problems reading a file from S3. I want to be able to load the ID3 tags remotely, but using open-URI doesn't work, it gives me the following error:
ruby-1.8.7-p302 > c=TagLib2::File.new(open(URI.parse("http://recordtemple.com.s3.amazonaws.com/music/745/original/The%20Stranger.mp3?1292096514")))
TypeError: can't convert Tempfile into String
from (irb):8:in `initialize'
from (irb):8:in `new'
from (irb):8
However, if i download the same file and put it on my desktop (ie no need for open-URI), it works just fine.
c=TagLib2::File.new("/Users/momofwombie/Desktop/blah.mp3")
is there something else I should be doing to read a remote file?
UPDATE: I just found this link, which may explain a little bit, but surely there must be some way to do this...
Read header data from files on remote server
Might want to check out AWS::S3, a Ruby Library for Amazon's Simple Storage Service
Do an AWS::S3:S3Object.find for the file and then an use about to retrieve the metadata
This solution assumes you have the AWS credentials and permission to access the S3 bucket that contains the files in question.
TagLib2::File.new doesn't take a file handle, which is what you are passing to it when you use open without a read.
Add on read and you'll get the contents of the URL, but TagLib2::File doesn't know what to do with that either, so you are forced to read the contents of the URL, and save it.
I also noticed you are unnecessarily complicating your use of OpenURI. You don't have to parse the URL using URI before passing it to open. Just pass the URL string.
require 'open-uri'
fname = File.basename($0) << '.' << $$.to_s
File.open(fname, 'wb') do |fo|
fo.print open("http://recordtemple.com.s3.amazonaws.com/music/745/original/The%20Stranger.mp3?1292096514").read
end
c = TagLib2::File.new(fname)
# do more processing...
File.delete(fname)
I don't have TagLib2 installed but I ran the rest of the code and the mp3 file downloaded to my disk and is playable. The File.delete would clean up afterwards, which should put you in the state you want to be in.
This solution isn't going to work much longer. Paperclip > 3.0.0 has removed to_file. I'm using S3 & Heroku. What I ended up doing was copying the file to a temporary location and parsing it from there. Here is my code:
dest = Tempfile.new(upload.spreadsheet_file_name)
dest.binmode
upload.spreadsheet.copy_to_local_file(:default_style, dest.path)
file_loc = dest.path
...
CSV.foreach(file_loc, :headers => true, :skip_blanks => true) do |row|}
This seems to work instead of open-URI:
Mp3Info.open(mp3.to_file.path) do |mp3info|
puts mp3info.tag.artist
end
Paperclip has a to_file method that downloads the file from S3.

Resources