Ruby read remote file to stream - ruby

I need to save a remote file a cloud storage server,so I must read this file to a file stream,I found this article :
Open an IO stream from a local file or url
the answer is :
require 'open-uri'
file_contents = open('local-file.txt') { |f| f.read }
web_contents = open('http://www.stackoverflow.com') {|f| f.read }
But the web_contents is not right.Then I compare this action to a custom local file upload,which format is ASCII-8BIT,the format is not same.so How can I get the correct stream from remote file .

Seems all right to me:
require 'open-uri'
web_contents = open('http://www.stackoverflow.com') {|f| f.read }
out_file = File.expand_path("~/Desktop/out.html")
File.open(out_file, "w") do |f|
f.puts web_contents
end

Related

rubyzip: open zip, modify it temporary, send to client

i want to temporary modify a zip file and send the changed file to the client.
right now i create a file stream and send it:
require 'zip'
zip_stream = Zip::OutputStream.write_buffer do |zip|
zip.put_next_entry 'new_folder/file'
zip.print "some text"
end
zip_stream.rewind
send_data zip_stream.read, type: 'application/zip', disposition: 'attachment', filename: 'thing.zip'
i dont get how i can open a existing zip in the filesystem and put additional file in it and send it without saving it do the disk.
can you give me a hint?
in the end i did it like this:
require 'zip'
zip_stream = Zip::OutputStream.write_buffer do |new_zip|
existing_zip = Zip::File.open('existing.zip')
existing_zip.entries.each do |e|
new_zip.put_next_entry(e.name)
new_zip.write e.get_input_stream.read
end
new_zip.put_next_entry 'new_file'
new_zip.print "text"
end
Check this https://github.com/rubyzip/rubyzip
require 'rubygems'
require 'zip'
folder = "Users/me/Desktop/stuff_to_zip"
input_filenames = ['image.jpg', 'description.txt', 'stats.csv']
zipfile_name = "/Users/me/Desktop/archive.zip"
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
input_filenames.each do |filename|
# Two arguments:
# - The name of the file as it will appear in the archive
# - The original file, including the path to find it
zipfile.add(filename, File.join(folder, filename))
end
zipfile.get_output_stream("myFile") { |f| f.write "myFile contains just this" }
end

Copy CSV content to another CSV

I'm trying to copy the content of a CSV file to another one.
First attempt:
FileUtils.cp(source_file, target_file)
Second attempt:
CSV.open(target_file, "w") {|file| file.truncate(0) }
CSV.open(target_file, "a+") do |csv|
CSV.foreach(source_file, :headers => true) do |row|
csv << row
end
end
Third attempt:
CSV.open(target_file, "w") {|file| file.truncate(0) }
File.open(source_file, "rb") do |input|
File.open(target_file, "wb") do |output|
while buff = input.read(4096)
output.write(buff)
end
end
end
Nothing is happening. What am I doing wrong?
When I run from Terminal cp source_file target_file, the target file is correctly created/copied. But in my app it is just creating the target_file, without any content.

Ruby,CSV and pdf's

So I am converting urls into images and downloading them into a document. The file can be an .jpg or .pdf. I can successfully download the pdf and there is something on the pdf (in form of memory) but when I try to open the pdf, adobe reader does not recognize it and deem it broken.
Here is a link to one of the URLs - http://www.finfo.se/www.artdb.finfo.se/cgi-bin/lankkod.dll/lev?knr=7770566&art=001317514&typ=PI
And here is the code =>
require 'open-uri'
require 'tempfile'
require 'uri'
require 'csv'
DOWNLOAD_DIR = "#{Dir.pwd}/PI/"
CSV_FILE = "#{Dir.pwd}/konvertera4.csv"
def downloadFile(id, url, format)
begin
open("#{DOWNLOAD_DIR}#{id}.#{format}", "w") do |file|
file << open(url).read
puts "Successfully downloaded #{url} to #{DOWNLOAD_DIR}#{id}.#{format}"
end
rescue Exception => e
puts "#{e} #{url}"
end
end
CSV.foreach(CSV_FILE, headers: true, col_sep: ";") do |row|
puts row
next unless row[0] && row[1]
id = row[0]
format = row[1].match(/PI\.(.+)$/)&.captures.first
puts format
#format = "pdf"
#format = row[1].match(/BD\.(.+)$/)&.captures.first
url = row[1].gsub ".pdf", ""
downloadFile(id, url, format)
end
Try using wb instead of w:
open("#{DOWNLOAD_DIR}#{id}.#{format}", "wb")

How to download an image file via HTTP into a temp file?

I've found good examples of NET::HTTP for downloading an image file, and I've found good examples of creating a temp file. But I don't see how I can use these libraries together. I.e., how would the creation of the temp file be worked into this code for downloading a binary file?
require 'net/http'
Net::HTTP.start("somedomain.net/") do |http|
resp = http.get("/flv/sample/sample.flv")
open("sample.flv", "wb") do |file|
file.write(resp.body)
end
end
puts "Done."
There are more api-friendly libraries than Net::HTTP, for example httparty:
require "httparty"
url = "https://upload.wikimedia.org/wikipedia/commons/thumb/9/91/DahliaDahlstarSunsetPink.jpg/250px-DahliaDahlstarSunsetPink.jpg"
File.open("/tmp/my_file.jpg", "wb") do |f|
f.write HTTParty.get(url).body
end
require 'net/http'
require 'tempfile'
require 'uri'
def save_to_tempfile(url)
uri = URI.parse(url)
Net::HTTP.start(uri.host, uri.port) do |http|
resp = http.get(uri.path)
file = Tempfile.new('foo', Dir.tmpdir, 'wb+')
file.binmode
file.write(resp.body)
file.flush
file
end
end
tf = save_to_tempfile('http://a.fsdn.com/sd/topics/transportation_64.png')
tf # => #<File:/var/folders/sj/2d7czhyn0ql5n3_2tqryq3f00000gn/T/foo20130827-58194-7a9j19>
I like to use RestClient:
file = File.open("/tmp/image.jpg", 'wb' ) do |output|
output.write RestClient.get("http://image_url/file.jpg")
end
Though the answers above work totally fine, I thought I would mention that it is also possible to just use the good ol' curl command to download the file into a temporary location. This was the use case that I needed for myself. Here's a rough idea of the code:
# Set up the temp file:
file = Tempfile.new(['filename', '.jpeg'])
#Make the curl request:
url = "http://example.com/image.jpeg"
curlString = "curl --silent -X GET \"#{url}\" -o \"#{file.path}\""
curlRequest = `#{curlString}`
If you like to download a file using HTTParty you can use the following code.
resp = HTTParty.get("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png")
file = Tempfile.new
file.binmode
file.write(resp.body)
file.rewind
Further, if you want to store the file in ActiveStorage refer below code.
object.images.attach(io: file, filename: "Test.png")

Zipping an existing file with Rubyzip

I would like to use rubyzip to archive "zip" an existing file:
c:\textfile.txt
to
textfile.zip
I know how to add a stream to a text file:
require 'zip/zip'
Zip::ZipFile.open("mp.zip", Zip::ZipFile::CREATE) {
|zipfile|
zipfile.get_output_stream("text.txt") { |f| f.puts "Creating text file" }
}
but not how to add an existing file to a zip. Thanks for your help
This reads in the source file and writes it 1mb at a time to the zipfile.
I've been using something very similar in production for some time now.
require 'zip/zip'
Zip::ZipFile.open("mp.zip", Zip::ZipFile::CREATE) do |zipfile|
zipfile.get_output_stream("text.txt") do |out_file|
File.open("text.txt") do |in_file|
while blk = in_file.read(1024**2)
out_file << blk
end
end
end
end
Hope this answers your question.

Resources