I am new to API's and backend development in general and have been trying for a few hours now to figure out how to do something simple like call the current bitcoin market price into my Rails app.
I tried referencing http://blockchain.info/ticker with the following code in my model
require 'rest-client'
require 'json'
base_url = "http://blockchain.info/ticker"
response = RestClient.get base_url
data = JSON.load response
cool = data[0]["CNY"]
#test = JSON.pretty_generate cool
and then put this in my view
<%= #test %>
I know this is way off but I'm at a loss and figured I would see if someone could provide a good resource or maybe get me going in the right direction. Many thanks
Dude, its all working good.
Replace data[0]["CNY"] with data["CNY"], thats all.
To get more handle, execute these lines 1 by 1 in irb,
Just like this,
1.9.3p385 :001 > require 'rest-client'
=> true
1.9.3p385 :002 > require 'json'
=> true
1.9.3p385 :004 > base_url = "http://blockchain.info/ticker"
=> "http://blockchain.info/ticker"
1.9.3p385 :005 > response = RestClient.get base_url
1.9.3p385 :006 > data = JSON.load response
1.9.3p385 :007 > cool = data["CNY"]
=> {"15m"=>5519.13613, "last"=>5519.13613, "buy"=>5578.16433, "sell"=>5853.54832, "24h"=>5616.47, "symbol"=>"¥"}
1.9.3p385 :008 > #test = JSON.pretty_generate cool
=> "{\n \"15m\": 5519.13613,\n \"last\": 5519.13613,\n \"buy\": 5578.16433,\n \"sell\": 5853.54832,\n \"24h\": 5616.47,\n \"symbol\": \"¥\"\n}"
1.9.3p385 :009 > p #test
"{\n \"15m\": 5519.13613,\n \"last\": 5519.13613,\n \"buy\": 5578.16433,\n \"sell\": 5853.54832,\n \"24h\": 5616.47,\n \"symbol\": \"¥\"\n}"
=> "{\n \"15m\": 5519.13613,\n \"last\": 5519.13613,\n \"buy\": 5578.16433,\n \"sell\": 5853.54832,\n \"24h\": 5616.47,\n \"symbol\": \"¥\"\n}"
I would recommend you use httparty which makes sending requests much simpler.
With regards to your example, you could do
require 'httparty'
require 'json'
base_url = "http://blockchain.info/ticker"
response = HTTParty.get(base_url)
data = JSON.parse(response.body)
data.each_pair do |ticker, stats|
pp "Ticker: #{ticker} - 15m: #{stats['15m']}"
end
Obviously I am pp (printing) out a string just to show the data. You would actually render the data in the view if you were to do a real implementation.
Related
I have a rails app with chat. In the chat for the messages I use rinku gem to recognize links which works well. On the top of this I would like to save the links as message.link without the rest of the text around it from the message.body.
So for example in the code below the user sent the message.body "hi there www.stackoverflow.com" and I would like to save only the "www.stackoverflow.com" as message.link. How can I do that?
view
<p><%= find_links(message.body) %></p>
controller
def find_links(message_body)
Rinku.auto_link(message_body, mode=:all, 'target="_blank"', skip_tags=nil).html_safe
end
it will appear in the DOM as:
<p>hey there http://stackoverflow.com/</p>
and will appear in the db as message.body:
"hey there http://stackoverflow.com/"
UPDATE:
messages controller
require "uri"
def create
.....
if message.save
link = URI.extract(message.body)
update_attribute(message.link = link)
end
You need regular expression to identify URLs from text. Try following regular expression:
/(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/
Working demo: http://rubular.com/r/bHQdFHZYFH
2.1.2 :001 > str = "hey hi hello www.google.com https://stackoverflow.com http://tech-brains.blogspot.in"
2.1.2 :002 > regexp = /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/
2.1.2 :003 > str.scan(regexp)
=> [["www.google.com"], ["https://stackoverflow.com"], ["http://tech-brains.blogspot.in"]]
You can use Ruby code:
2.0.0-p247 :001 > require "uri"
=> true
2.0.0-p247 :002 > URI.extract("hey there http://stackoverflow.com/")
=> ["http://stackoverflow.com/"]
Hope it helps!
Weird question tag but still wanted to ask because even though it looks easy no matter what I've tried I could not accomplish
I'm trying to parse duration between to points from a URL given by Google Maps directions API. Thanks an answer I've received from here I was able to capture the JSON object and get to the duration object however no matter what I did I could not get the inner values "text" or "value" from the "duration" attribute.
Here is the response;
{
"text" : "6 mins",
"value" : 373
}
And here is the code I've written in rails
#request = Net::HTTP.get(URI.parse('http://maps.googleapis.com/maps/api/directions/json?origin=40.983204,29.0216549&destination=40.99160908659266,29.02334690093994&sensor=false'))
hash = JSON.parse #request
duration = hash['routes'][0]['legs'][0]['duration']
respond_to do |format|
format.html {render :index}
format.json {render json: duration}
end
Note: Of course, the [0] and ['text'] methods have been tried.
As a first thing you need to define duration as an instance variable to have it available in your views (if this is where you need to use it)
#duration = hash['routes'][0]['legs'][0]['duration']
duration["text"] and duration["value"] didn't work?
1.9.3p194 :001 > require 'net/http'
=> true
1.9.3p194 :002 > require 'json'
=> true
1.9.3p194 :003 > #request = Net::HTTP.get(URI.parse('http://maps.googleapis.com/maps/api/directions/json?origin=40.983204,29.0216549&destination=40.99160908659266,29.02334690093994&sensor=false'));
1.9.3p194 :004 > hash = JSON.parse #request;
1.9.3p194 :005 > duration = hash['routes'][0]['legs'][0]['duration']
=> {"text"=>"6 mins", "value"=>373}
1.9.3p194 :006 > duration["text"]
=> "6 mins"
1.9.3p194 :007 > duration["value"]
=> 373
I know to get a simple page I do:
require 'net/http'
source = Net::HTTP.get('example.com', '/index.html')
But how do I make a post from a form and get the page that returns the results of the data submitted? Is it possible?
According to Net::HTTP doc you can do
res = Net::HTTP.post_form("example.com/index.html", 'q' => 'ruby', 'max' => '50')
puts res.body
see http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html#method-c-post_form
An really easy way is to use the resttclient gem:
require 'rest_client'
result = RestClient.post 'http://example.com/resource', :param1 => 'one'
I'm very new to ruby and trying some basic stuff. When I send HTTP request to the server using:
curl -v -H "Content-Type: application/json" -X GET -d "{"myrequest":"myTest","reqid":"44","data":{"name":"test"}}" localhost:8099
My server sees JSON data as "{myrequest:myTest,reqid:44,data:{name:test}}"
But when I send the request using the following ruby code:
require 'net/http'
#host = 'localhost'
#port = '8099'
#path = "/posts"
#body = ActiveSupport::JSON.encode({
:bbrequest => "BBTest",
:reqid => "44",
:data =>
{
:name => "test"
}
})
request = Net::HTTP::Post.new(#path, initheader = {'Content-Type' =>'application/json'})
request.body = #body
response = Net::HTTP.new(#host, #port).start {|http| http.request(request) }
puts "Response #{response.code} #{response.message}: #{response.body}"
It sees it as "{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\" test\"}}" and server is unable to parse it. Perhaps there are some extra options I need to set to send request from Ruby to exclude those extra characters?
Can you please help. Thanks in advance.
What you are doing on the shell produces invalid JSON. Your server should not accept it.
$echo "{"myrequest":"myTest","reqid":"44","data":{"name":"test"}}"
{myrequest:myTest,reqid:44,data:{name:test}}
This is JSON with unescaped keys and values, will NEVER work. http://jsonlint.com/
If your server accept this "sort of kind of JSON" but does not accept the second one in your example your server is broken.
My server sees JSON data as "{myrequest:myTest,reqid:44,data:{name:test}}"
Your server sees a string. When you will try to parse it into JSON it will produce an error or garbage.
It sees it as "{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\" test\"}}"
No this is how it's printed via Ruby's Object#inspect. You are printing the return value of inspect somewhere and then trying to judge whether it's valid JSON - it is not, since this string you've pasted in is made to be pasted into the interactive ruby console (irb) or into a ruby script, and it contains builtin escapes. You need to see your JSON string raw, just print the string instead of inspecting it.
I think your server is either broken or not finished yet, your curl example is broken and your ruby script is correct and will work once the server is fixed (or finished). Simply because
irb(main):002:0> JSON.parse("{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\" test\"}}")
# => {"bbrequest"=>"BBTest", "reqid"=>"44", "data"=>{"name"=>" test"}}
Your problem is something other than the existence of escape characters in the string. Those are not put in by the code you show, but by irb or .inspect. If you put in a simple puts #body in your code (or in a Rails context, logger.debug #body), you'll see this. Here's an irb session showing the difference:
ruby-1.9.2-p180 :002 > require 'active_support'
=> true
ruby-1.9.2-p180 :003 > json = ActiveSupport::JSON.encode({
ruby-1.9.2-p180 :004 > :bbrequest => "BBTest",
ruby-1.9.2-p180 :005 > :reqid => "44",
ruby-1.9.2-p180 :006 > :data =>
ruby-1.9.2-p180 :007 > {
ruby-1.9.2-p180 :008 > :name => "test"
ruby-1.9.2-p180 :009?> }
ruby-1.9.2-p180 :010?> })
=> "{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\"test\"}}"
ruby-1.9.2-p180 :013 > puts json
{"bbrequest":"BBTest","reqid":"44","data":{"name":"test"}}
=> nil
In any case, the best way to do json encoding in Rails is not to call ActiveSupport::JSON.encode directly, but rather override as_json in your model or use the serializable_hash feature. This will make your code cleaner as well. See the top answers to this stackoverflow question for details.
I wish to make my code a little more readable by calling #rando on any array and retrieve a random element (rando because a rand() method already exists and I don't want there to be any confusion).
So I opened up the class and wrote a method:
class Array
def rando
self[ rand(length) ]
end
end
This seems far too straightforward.
When I open up irb, and type arr = %w(hi bye) and then arr.rando I get either hi or bye back. That's expected. However, in my rails console, when I do the same thing, I get ArgumentError: wrong number of arguments (1 for 0)
I've been tracing Array up the rails chain and can't figure it out. Any idea?
FWIW, I'm using rails 2.3.11 and ruby 1.8.7
Works fine in my case :
Loading development environment (Rails 3.0.3)
ruby-1.9.2-p180 :001 > class Array
ruby-1.9.2-p180 :002?> def rando
ruby-1.9.2-p180 :003?> self[ rand(length) ]
ruby-1.9.2-p180 :004?> end
ruby-1.9.2-p180 :005?> end
=> nil
ruby-1.9.2-p180 :006 > arr = %w(hi bye)
=> ["hi", "bye"]
ruby-1.9.2-p180 :007 > arr.rando
=> "bye"