Save IO object to a file on Ruby - ruby

Im scraping a website using Celerity gem and I want to save an image but I dont know how to do it XD
With the next Celerity command I get an IO object
irb(main):260:0* image = #browser.image(:xpath, ".//*[#class='notdTop']/img").download
=> #<IO:0x277e07ae>
How can I save this object to a jpg file?? I tried this, but didnt work:
irb(main):261:0> image.flush
IOError: not opened for writing
but the IO object is not closed because I got this:
irb(main):264:0> image.closed?
=> false
Anyone can help me please?

Try:
image.save(filename)
http://rubydoc.info/gems/celerity/0.8.9/Celerity/Image#save-instance_method

Related

Download a GitHub file with Octokit::Client in Ruby

I am trying to download an XML file from GitHub via Octokit::Client in Ruby. This is in a Dangerfile, so I have access to the client via github.api.
I have got something working with the following code:
listing = client.contents('erik-allen/RepoName', :path => 'Root/Path')
download = open(listing[0].download_url)
I can then call Nokogiri::XML(download) and parse the XML with no issues.
However, it only works because it is the only file in the directory. It also does not feel like the correct way to do things.
I have tried a few other ways:
download = client.contents('erik-allen/RepoName', :path => 'Root/Path/File.xml')
That returned a Sawyer::Resource but I have yet to find a way to get any data from that. I tried combinations of .get.data and .data but neither worked. Calling Base64.decode64() on the result did not yield anything either.
I am suspecting I may need an "accept" header, but I am not sure how I would do that with Octokit::Client.
Does anyone have any suggestions. I would have assumed this would be a common task, but I can find no examples.
I was able to eventually figure things out. There is a content property on the Sawyer::Resource that gives the Base64 data. So the final solution is:
contents = client.contents('erik-allen/RepoName', :path => 'Root/Path/File.xml')
download = Base64.decode64(contents.content)
I can then call Nokogiri::XML(download) and parse the XML with no issues.

blobstore images get_serving_url

I am new to the Google App Engine and I am trying to use the Blobstore to store images that I want to display later on.
The image storage works fine. Now I want to dynamically change some images in my html code. Therefore I need a method of getting the images out of the blobstore and passing them. I am using Python. I found the get_serving_url-command, which seemed to be the perfect fit. Sadly, this causes an Error and I seem to be unable to fix it.
My basic code looks like this:
blob_key = "yu343mQ7kT4344N434ewQ=="
if blob_key:
blob_info = blobstore.get(blob_key)
if blob_info:
img = images.Image(blob_key=blob_key)
url = images.get_serving_url(blob_key)
...
Everytime the function gets called, I get the following Error in my Log Console.
File "C:\Program Files
(x86)\Google\google_appengine\google\appengine\ext\remote_api\remote_api_stub.py",
line 234, in _MakeRealSyncCall
raise pickle.loads(response_pb.exception())
AttributeError: 'ImagesNotImplementedServiceStub' object has no
attribute 'THREADSAFE'
I have no idea how to fix it or if I am doing something terribly wrong.
I am very grateful for your support! Thank you in advance!
Have a nice day
You probably need an instance of BlobKey so if you are getting blob_info successfully try:
img = images.Image(blob_key=blob_info.key())
url = images.get_serving_url(blob_info.key())

Ruby open-uri open method loses file extension opening images

I'm using ruby 1.9.2 along with Rails 3.1.4 and Paperclip 2.4.5.
My issue is trying to save a paperclip attachment from a URI loses the file extension and saves the file without one resulting in issues with things like fancybox that require an extension.
Some example code:
uri = "http://featherfiles.aviary.com/2012-06-13/bbe5f0de1/0c5a672b88ea47ecb4631ac173e27430.png"
open(uri)
#=> #<File:/var/folders/zc/d69gxhzx10x_bvjrkqgyjgxr0000gn/T/open-uri20120613-27204-i6cldv>
Because there is no extension on the temp file paperclip is saving the file without one resulting in issues.
Has anyone run into this issue? I've seen multiple answers about using paperclip to store images from a URI but none seem to address the same problem we're running
Don't use the temporary file! It's there as a placeholder as the file is read from the port, and should be considered a private resource for OpenURI. Instead, use open(url).read and work with the resulting content by saving it.
Do something like:
require 'uri'
require 'open-uri'
url = 'http://www.iana.org/domains/example/index.html'
filename = File.basename(URI.parse(url).path)
File.open(filename, 'wb') do |fo|
fo.write(open(url).read)
end
Temporarily spooling to disk during an operation, especially a network operation, is common. Once the file's content has been accumulated, then it is available to be passed off to the app. read is blocking, so your code will stop there until the file is returned to you. Then you can play with it.
Extension isn't important for temporary file, but if you want use this file in code or save to another place. You can do it:
temp_file = open(params[:url])
def temp_file.original_filename; File.basename(base_uri.path); end
Now, you can save this temporary file to permanent space or use it in code; Original filename will be used automatically.
Im not sure if this will help in your case, but I was noticing similar issues in my project.
The issue turned out to be not caused by Paperclip nor open-uri, but the receiver of the paperclip file (in my case Spree Commerce). Check that you are assigning the paperclip object to the right object, and that it is being interpreted correctly.
The fix that worked for me was to change:
#product.images << Spree::Image.create({
:attachment => open(image_url)
}, :without_protection => true)
to
#product.master.images << Spree::Image.create({
:attachment => open(image_url)
}, :without_protection => true)
Good luck with your issue
Have you inclued the :extension in your path/url option?
For example:
has_attached_file :image,
...
:url => '/images/highlights/:id_partition/:style_:id.:extension',
:path => ':rails_root/files/images/highlights/:id_partition/:style_:id.:extension'
This will probably solve your problem.
You can force an extension there, but I don't think that's recommended.
Update – Paperclip can do this on its own!
Posted by Aditya Sanghi (thanks a lot!):
current_comments.pictures.create!(file: URI.parse(image_url))
Although keep in mind, that you still need to handle 500, 404, etc
errors (Paperclip can raise them).
Thanks to: https://mensfeld.pl/2013/12/rails-paperclip-open-uri-downloading-files-from-the-internet-and-saving-them-with-paperclip/
Yes, it is a problem but we can get around this with fancybox.
In the link tag(for image) add :type => 'image'
- #images.each do |image|
= link_to image_tag(image.attachment.url), image.attachment.url, class: "fancybox", type: 'image'
By specifying 'type', Fancybox overrides the type as image
https://groups.google.com/forum/?fromgroups=#!topic/fancybox/QgjquBCLynU

Convert file upload contents to a binary file without saving (Rails)

I have a rails 3 app where I am using the 'face' gem to reference the Face.com API. The api method takes a parameter of the form:
:file => File.new(path_to_file, 'rb')
which works.
I am trying to change the flow of the app so that the file can be uploaded via a form, do some work with RMagick and then make the API call, all without saving the file to disk.
I can generate the RMagick 'Image' with
image = Magick::Image.from_blob(upload_image_field.read)
I can then manipulate the file with RMagick and even save the results into the database with:
self.data = image.to_blob #normally 'upload_image_field.read' if not using RMagick
My problem is that I can't change the image file (or the blob) into something that the API will recognize (without saving it to disk and then referencing the file on disk).
For example using this in the API method fails:
:file => image.to_blob
How do I convert he blob into the same format as
File.new(path_to_file, 'rb')
Thanks
OK, I could be wrong on this one... but I wanted to dig this up. Unfortunately, you just have to live with saving it as a file. The reason is because the API makes an HTTP POST. Unfortunately, this needs to be a file.
References from: [https://github.com/rociiu/face/tree/master/lib/face]:
recognition.rb:
def faces_detect(opts={})
opts.assert_valid_keys(:urls, :file, :detector, :attributes, :callback, :callback_url)
make_request(:faces_detect, opts)
end
utils.rb:
def make_request(api_method, opts={})
....
response = JSON.parse( RestClient.post(API_METHODS[ api_method ], opts.merge(api_crendential)).body )
....
end
So, why is it a problem to save to a file then?

RMagick with a direct form submitted Image from Sinatra

I am trying to do something quite simple using Sinatra and RMagick.
Take a image, through a simple form
file upload
Use RMagick to resize it
Then store it in a database for
persistence (irrelevant)
But after going through the RDocs and endless head banging testing
I can't seem to get the form image to a RMagick object cleanly.
This is the horrible thing that is currently working for me:
def image_resize(img_data)
filecount = rand
writer = File.new("/tmp/#{filecount}.jpg", "w")
writer.puts(img_data)
writer.close
resized_image = Magick::ImageList.new("/tmp/#{filecount}.jpg").first
resized_image.crop_resized!(100,100, Magick::NorthGravity)
resized.format = 'jpeg'
resized_image.to_blob
end
#call the method with my form image data
image_resize(params[:image][:tempfile].read)
So how do I do the obvious right thing and just stick my form image data straight into a RMagick object without having to write and read the disk.
I have tried various ways of reading in Magick::Image and ImageLists but have only got an abundance of errors barfed at me.
Thanks for any kind of direction
-1.2.
You need to get the path from the tempfile and pass that to Magick::Image’s read.
Here’s an example:
post "/upload-photo" do
image = Magick::Image.read(params[:image][:tempfile].path)[0]
image.crop_resized! 100, 100, Magick::CenterGravity
store_image_data image.to_blob
redirect "/done"
end
Or you can read straight from the ActionDispatch::Http::UploadedFile like so:
image = Magick::Image.from_blob(params[:image].read)

Resources