Why does OpenURI treat files under 10kb in size as StringIO?
When one does network programming, you allocate a buffer of a reasonably large size and send and read units of data which will fit in the buffer. However, when dealing with files (or sometimes things called BLOBs) you cannot assume that the data will fit into your buffer. So, you need special handling for these large streams of data.
(Sometimes the units of data which fit into the buffer are called packets. However, packets are really a layer 4 thing, like frames are at layer 2. Since this is happening a layer 7, they might better be called messages.)
For replies larger than 10K, the open-uri library is setting up the extra overhead to write to a stream objects. When under the StringMax size, it just includes the string in the message, since it knows it can fit in the buffer.
Why does Ruby open-uri's open return a StringIO in my unit test, but a FileIO in my controller?
The code responsible for this is in the Buffer class in open-uri. It starts by creating a StringIO object and only creates an actual temp file in the local filesystem when the data exceeds a certain size (10 KB).
I assume that whatever data your test is loading is small enough to be held in a StringIO and the images you are using in the actual application are large enough to warrant a TempFile. The solution is to use methods which are common to both classes, in particular the read method, with MiniMagick::Image#from_blob:
temp_image = MiniMagick::Image.from_blob(open(self.public_filename, &:read))
Sinatra, Twitter, and StringIO
I faced with same issue but using Rails.
Problem is in size of image: if size of image is less than 10kb then open(photo_url)
will give you StringIO
object, if size is more then 10kb then - File
object which is saved in tmp/
folder. File
object respond's to to_io
method and StringIO
object doesn't.
What you can do - create file in tmp
folder from your file, and then use this this file for posting to TW.
For example:
img = open(url)
if img.is_a?(StringIO)
ext = File.extname(url)
name = File.basename(url, ext)
Tempfile.new([name, ext])
else
img
end
Write StringIO to Tempfile
You're super close:
file.binmode
file.write stringIo.read
open(url)
is just opening the stream for reading. It doesn't actually read the data until you call .read
on it (which you can then pass in to file.write
).
Add image from URL to Excel with Axlsx
Try using read
to pull the contents into a tempfile and use that location:
t = Tempfile.new('my_image')
t.binmode
t.write image.read
t.close
ws.add_image(:image_src => t.path, ...
Related Topics
Check If String Contains Any Substring in an Array in Ruby
Rendering File with Mime Type in Rails
Accepts_Nested_Attributes_For Rails 4 Is Not Deleting
How Would I Go About Programmatically Interacting with VSt(I) Plugins to Synthesize Audio
How to Get Ruby to Parse Time as If It Were in a Different Time Zone
Rvm Install: Ruby Installation Error
Define_Method: How to Dynamically Create Methods with Arguments
How to Define a Ruby Singleton Method Using a Block
Using Yield Inside Define_Method in Ruby
How to Authorize a Google Service Account Without the Default Credentials File
Constants or Class Variables in Ruby
Use Global or Constant Variable in Ruby/Rails