Ruby Sinatra - How to capture post json data and save to file - ruby

How do I capture a Json data from POST route and save it to file? I have simple ruby sinatra code as below.
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
require 'json'
post '/' do
values = JSON.parse(request.env["rack.input"].read)
# How do I save "values" of JSON to file..
end

Try this
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
require 'json'
post '/' do
values = JSON.parse(request.env["rack.input"].read)
File.open('file.txt', 'w') { |file| file.write(values) }
end

To write file in ruby you can use:
File.open('/your/path/file', 'w') { |file| file.write(values) }

Related

`open_http': 500 Internal Server Error (OpenURI::HTTPError)

I'm trying to parse a url but keep having this 500. Any suggestion please?
require 'open-uri'
require 'json'
require 'csv'
url = 'https://gist.githubusercontent.com/gregclermont/ca9e8abdff5dee9ba9db/raw/
7b2318efcf8a7048f720bcaff2031d5467a4a2c8/users.json'
encoded_url = URI.encode(url)
open(encoded_url) do |stream|
quote = JSON.parse(stream.read)
puts quote
end
require 'open-uri'
require 'json'
url = 'https://gist.githubusercontent.com/gregclermont/ca9e8abdff5dee9ba9db/raw/7b2318efcf8a7048f720bcaff2031d5467a4a2c8/users.json'
open(url) { |f| JSON.parse(f.read) }
Works fine for me.

How do you open StringIO in Ruby?

I have a Sinatra application with the following main.rb:
require 'bundler'
Bundler.require
get '/' do
##p = Pry.new
haml :index
end
post '/' do
code = params[:code]
$stdout = StringIO.new
##p.eval(code)
output = $stdout.string
$stdout = STDOUT
output_arr = []
output.each_line('\n') { |line| output_arr << line }
output_arr[1]
binding.pry
end
When I hit the binding.pry at the bottom to see if output contains any output, it seems like the IO stream is not closed, as I can't get anything to show up in the console.
However if I try to call open on StringIO.new, I receive an NoMethodError - private method 'open' called.
I am requiring 'stringio' in a config.ru file, and I've also tried requiring it in the main.rb file:
config.ru:
require 'stringio'
require './main'
run Sinatra::Application
I'm not sure if this is related but something interesting that I've noticed is that, in irb, if I require 'pry' before requiring stringio, then it returns false, otherwise it returns true.
This makes me wonder if Sinatra is including Pry from my Gemfile before loading the config.ru. Could that be the problem? Not sure how to solve this.

Printing to file from Ruby pp

I'm parsing a JSON file in Ruby and want to output the results using pp to a file. How can I do that? Here's the code I'm trying:
require 'rubygems'
require 'json'
require 'pp'
json = File.read('players.json')
plyrs = JSON.parse(json)
File.open('plyrs.txt', 'a') { |fo| pp page, fo }
require "rubygems" is redundant in Ruby >= 1.9.
require "json"
require "pp"
plyrs = JSON.load("players.json")
File.open("plyrs.txt", "a"){|io| io.write(plyrs.pretty_inspect)}
Try this
require 'rubygems'
require 'json'
require 'pp'
json = File.read('players.json')
plyrs = JSON.parse(json)
File.open('plyrs.txt', 'a') { |file| file.write(pp plyrs) }
More info available at the ruby documentation

Save Webscraped data

I am trying to scrape a website. I am able to scrape data from that website. I am having trouble saving the data from the scrape to yaml file that I have included
My Code:
require 'rubygems'
require 'open-uri'
require 'hpricot'
article = []
doc = open("http://www.cmegroup.com/trading/interest-rates/cleared-otc/irs.html"{|f| Hpricot(f) }
(doc/"/html/body/div/div/div/div/table/").each do |article|
puts "#{article.inner_html}"
end
File.open('test.yaml', 'w') { |f|
f <<article.to_yaml
}
First you are missing a closing parenthesis for the open call (a ) right before the block starts).
When you add that you'll notice that you'll get a NoMethodError (undefined method 'to_yaml' for []:Array). To fix that you have to require 'yaml', which pulls in the monkey-patches for the Array class. After that you'll notice that your yaml file is empty, because you never put anything into article. Here's a fixed version:
require 'rubygems'
require 'open-uri'
require 'hpricot'
require 'yaml'
articles = []
url = "http://www.cmegroup.com/trading/interest-rates/cleared-otc/irs.html"
doc = open(url) {|f| Hpricot(f) }
(doc/"/html/body/div/div/div/div/table/").each do |article|
articles << article.inner_html
end
File.open('test.yaml', 'w') { |f| f << articles.to_yaml }

Retrieve contents of URL as string

For tedious reasons to do with Hpricot, I need to write a function that is passed a URL, and returns the whole contents of the page as a single string.
I'm close. I know I need to use OpenURI, and it should look something like this:
require 'open-uri'
open(url) {
# do something mysterious here to get page_string
}
puts page_string
Can anyone suggest what I need to add?
You can do the same without OpenURI:
require 'net/http'
require 'uri'
def open(url)
Net::HTTP.get(URI.parse(url))
end
page_content = open('http://www.google.com')
puts page_content
Or, more succinctly:
Net::HTTP.get(URI.parse('http://www.google.com'))
The open method passes an IO representation of the resource to your block when it yields. You can read from it using the IO#read method
open([mode [, perm]] [, options]) [{|io| ... }]
open(path) { |io| data = io.read }
require 'open-uri'
open(url) do |f|
page_string = f.read
end
See also the documentation of IO class
I was also very confused what to use for better performance and speedy results. I ran a benchmark for both to make it more clear:
require 'benchmark'
require 'net/http'
require "uri"
require 'open-uri'
url = "http://www.google.com"
Benchmark.bm do |x|
x.report("net-http:") { content = Net::HTTP.get_response(URI.parse(url)).body if url }
x.report("open-uri:") { open(url){|f| content = f.read } if url }
end
Its result is:
user system total real
net-http: 0.000000 0.000000 0.000000 ( 0.097779)
open-uri: 0.030000 0.010000 0.040000 ( 0.864526)
I'd like to say that it depends on what your requirement is and how you want to process.
To make code a little clearer, the OpenURI open method will return the value returned by the block, so you can assign open's return value to your variable. For example:
xml_text = open(url) { |io| io.read }
Starting with Ruby 3.0, calling URI.open via Kernel#open has been removed, so instead call URI.open directly:
require 'open-uri'
page_string = URI.open(url, &:read)
Try the following instead:
require 'open-uri'
content = URI(your_url).read
require 'open-uri'
open(url) {|f| #url must specify the protocol
str = f.read()
}

Resources