Getting data out of a JSON Response in Rails 3 - ruby-on-rails

So I am trying to pull tweets off of Twitter at put them into a rails app (Note because this is an assignment I can't use the Twitter Gem) and I am pretty confused.
I can get the tweets I need in the form of a JSON string but I'm not sure where to go from there. I know that the Twitter API call I'm making returns a JSON array with a bunch of Tweet objects but I don't know how to get at the tweet objects. I tried JSON.parse but was still unable to get the required data out (I'm not sure what that returns). Here's the code I have so far, I've made it pretty clear with comments/strings what I'm trying for. I'm super new to Rails, so this may be way off for what I'm trying to do.
def get_tweets
require 'net/http'
uri = URI("http://search.twitter.com/search.json?q=%23bieber&src=typd")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
case response
when Net::HTTPSuccess then #to get: text -> "text", date: "created_at", tweeted by: "from_user", profile img url: "profile_img_url"
JSON.parse(response.body)
# Here I need to loop through the JSON array and make n tweet objects with the indicated fields
t = Tweet.new(:name => "JSON array item i with field from_user", :text "JSON array item i with field text", :date => "as before" )
t.save
when Net::HTTPRedirection then
location = response['location']
warn "redirected to #{location}"
fetch(location, limit - 1)
else
response.value
end
end
Thanks!

The JSON.parse method returns a ruby hash or array representing the json object.
In your case, the Json is parsed as a hash, with the "results" key (inside that you have your tweets), and some meta data: "max_id", "since_id", "refresh_url", etc. Refer to twitter documentation for a description on the fields returned.
So again with your example it would be:
parsed_response = JSON.parse(response.body)
parsed_response["results"].each do |tweet|
t = Tweet.new(:name => tweet["from_user_name"], :text => tweet["text"], :date => tweet["created_at"])
t.save
end

Related

How to update a couchdb document with Ruby

I have a Rails application with MYSQL backend. Upon saving data in MYSQL, it pushes some data to Couchdb using curl commands. However, I am unable to update that very same document. I dont know how query from couchdb and use _rev id to update. Here is how am creating and pushing a couchdb document.
require 'net/http'
require 'uri'
require 'json'
def push_to_couchdb
url = URI.parse("http://127.0.0.1:5984/m5fcash/100")
request = Net::HTTP::Put.new(url)
request.body = JSON.dump({
"fname" => "fname",
"lanme" => "lname",
"type" => "demo",
"facility" => "spectre"
})
req_options = {
use_ssl: url.scheme == "https",
}
response = Net::HTTP.start(url.hostname, url.port, req_options) do |http|
http.request(request)
end
end
This is how am trying to query the document and extract its _rev id
def get_couch_doc
uri = URI.parse("http://127.0.0.1:5984/m5fcash/100")
response = Net::HTTP.get_response(uri)
raise response.inspect
end
I expect raise response.inspect to gove a couchdb document from which I will exctract a _rev id. But all I get is #. How can I query a document in Ruby using curl??
It's not entirely clear to me from your code what you're trying to do, so I'll try to explain in general terms.
In order to read a specific document revsion, you need to use the rev=... query parameter. This is probably not what you want. In your get_couch_doc you can't have a request body. It looks like you're trying to fetch a document based on specific data in the body -- for this you need to create a secondary index, known as a view in CouchDB.
If you want to be able to query based on the lanme (maybe that should be lname?) field, you'd make a view where the map could look something like
function(doc) {
if (doc.lname) {
emit(doc.lname, null);
}
}
If you want to update a document, you need to do a PUT database/doc_id with the rev=.... query parameter on the URL.
CouchDB docs for the document API, and for views.

Rails Httparty JSON to params to save

Rails 4.5 Ruby 2.3.1
I am getting json from an API and trying to store the following into a model CLrates
1. timestamp as unix time (date)
2. Currency_code (string)
3. quote (decimal monetary value)
I can use the following in irb after parsing the json and know how to get the elements individually using: response["quotes"]. How can I generate params to be saved in the model above when the body is as follows:
irb(main):036:0> puts response.body
{
"success":true,
"terms":"https:\/\/xxxxx.com\/terms",
"privacy":"https:\/\/xxxxx.com\/privacy",
"timestamp":1504817289,
"source":"USD",
"quotes":{
"USDAED":3.672703,
"USDAFN":68.360001,
"USDCUC":1,
"USDCUP":26.5,
"USDCVE":91.699997,
"USDCZK":21.718701,
............ many more lines removed for brevity
"USDZWL":322.355011
}
I can do this using a separate associated model but have very little idea how to create the params to save to a single table.
The following links got me to this point and well worth a read if you need info on httparty GET (client):
1. http://www.rubydoc.info/github/jnunemaker/httparty/HTTParty/
2. http://eric-price.net/blog/rails-api-wrapper/
3. https://www.driftingruby.com/episodes/playing-with-json
The class and method in lib/clayer.rb:
class clayer
include HTTParty
format :json
read_timeout 10
def self.get_quotes
response = HTTParty.get('http://www.nnnnnnn.net/api/live?
access_key=nnnnnnnnnn&format=1')
end
end
I used irb as I am still learning how to run this through rails c. This will be called in the controller and saved however need to work out how to get the params from the json
Thanks for the help
OK: after digging I think I am on the right track
I get the response["QUOTES"], loop through them and build the params required saving each at the end of the loop
rates = response["QUOTES"]
rates.each do |k,v|
clrate = Realtimerates.new
clrate.date = response["timestamp"]
clrate.countrycode = "#{k}"
clrate.price = "#{v}"
clrate.save
end
Going to give this a whirl
In model
class Realtimerate < ActiveRecord::Base
include HTTParty
format :json
read_timeout 5
def self.get_cl_rates
response = HTTParty.get('http://www.mmmmm.net/api/live?access_key="key"&format=1')
rates = response["quotes"]
rates.each do |k,v|
create!(
date: Time.at(response["timestamp"]),
country_code: "#{k}",
price: "#{v}")
end
end
end
In the controller:
def index
Realtimerate.get_cl_rates
#realtimerates = Realtimerate.all
end
This is working and shows latest GET.
You already have a hash in your response.body. All you need to do now is to assign the relevant key-value to your model's attributes. e.g.
clrate = ClRate.new
res = response.body
clate.time = res["timestamp"]
...
clate.save

How can I parse subpages of another website in Rails?

I'm creating a third-party web application of Last.fm and I'm having an issue with getting info about certain artist from them.
I have a method that parses data about some #{artist} from JSON:
artists_helper.rb
require 'net/http'
require 'json'
module ArtistsHelper
def about(artist)
artist = "?"
url = "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=#{artist}&api_key=f5cb791cfb2ade77749afcc97b5590c8&format=json"
uri = URI(url)
response = Net::HTTP.get(uri)
JSON.parse(response)
end
end
If I change '?' to the artist name in that method I can successfully parse info about artist from JSON file of that artist. But for when I go the page e.g. http://localhost:3000/artists/Wild+Nothing I need the method 'about(artist)' to get the value 'Wild+Nothing' and parse the data for Wild Nothing from Last.fm's JSON file.
How can I tell the method 'about' that what stands after http://localhost:3000/artists/ is the required value?
In the routes, have a get route name that accepts a variable
get 'artists/:name', to: 'artists#about'
In the artists controller, have an about function:
def about
artist = params[:name]
url = "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=#{artist}&api_key=f5cb791cfb2ade77749afcc97b5590c8&format=json"
uri = URI(url)
response = Net::HTTP.get(uri)
response = JSON.parse(response)
render json: response
end
and we are good to go to display the json on the view.
If you need the param in the helper, just pass params[:name] to the helper as a parameter.
about(param[:name]) #wherever you are calling this method in the controller or view
def about(artist)
url = "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=#{artist}&api_key=f5cb791cfb2ade77749afcc97b5590c8&format=json"
uri = URI(url)
response = Net::HTTP.get(uri)
JSON.parse(response)
end

Can you get tweets by hashtag or username with V1.1

I need a little help with my search query for Twitter's API V1.1. I'm wanting to get all tweets that either have the username #dewsly or include the hashtag #dewsly. Right now it seems to be doing an "AND" so it's only bringing back tweets that have the hashtag #dewsly and are from the user #dewsly.
What should my query be to change it to an "OR"?
?q=#dewsly+from:dewsly
I am assuming You are using ruby then you simply wite this code and get tweets
consumer = OAuth::Consumer.new(consumer_key,consumer_secet,{ :site => "http://api.twitter.com",
:scheme => :header
})
token_hash = { :oauth_token =>your_access_token,:oauth_token_secret =>your_secret}
user_access_token = OAuth::AccessToken.from_hash(consumer, token_hash)
If you new with twitter keys then simply go https://dev.twitter.com and create new app and get all keys
request_url = "http://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=#{user_screen_name}"
request_url =URI.encode(request_url)
response = access_token.request(:get, request_url)
body = response.body
search = JSON.parse(body)

Problems with MailChimp API in Ruby Error Code: -90

I am using the following code in my MailChimp Controller to submit simple newsletter data. When It is sent I receive the following error as a "Method is not exported by this server -90" I have attached my controller code below. I am using this controller for a simple newsletter signup form. (Name, Email)
class MailchimpController < ApplicationController
require "net/http"
require "uri"
def subscribe
if request.post?
mailchimp = {}
mailchimp['apikey'] = 'f72328d1de9cc76092casdfsd425e467b6641-us2'
mailchimp['id'] = '8037342dd1874'
mailchimp['email_address'] = "email#gmail.com"
mailchimp['merge_vars[FNAME]'] = "FirstName"
mailchimp['output'] = 'json'
uri = URI.parse("http://us2.api.mailchimp.com/1.3/?method=listSubscribe")
response = Net::HTTP.post_form(uri, mailchimp)
mailchimp = ActiveSupport::JSON.decode(response.body)
if mailchimp['error']
render :text => mailchimp['error'] + "code:" + mailchimp['code'].to_s
elsif mailchimp == 'true'
render :text => 'ok'
else
render :text => 'error'
end
end
end
end
I highly recommend the Hominid gem: https://github.com/tatemae-consultancy/hominid
The problem is that Net::HTTP.post_form is not passing the "method" GET parameter. Not being a big ruby user, I'm not certain what the actual proper way to do that with Net::HTTP is, but this works:
require "net/http"
data="apikey=blahblahblah"
response = nil
Net::HTTP.start('us2.api.mailchimp.com', 80) {|http|
response = http.post('/1.3/?method=lists', data)
}
p response.body
That's the lists() method (for simplicity) and you'd have to build up (and urlencode your values!) your the full POST params rather than simply providing the hash.
Did you take a look at the many gems already available for ruby?
http://apidocs.mailchimp.com/downloads/#ruby
The bigger problem, and main reason I'm replying to this, is that your API Key is not obfuscated nearly well enough. Granted I'm used to working with them, but I was able to guess it very quickly. I would suggest immediately going and disabling that key in your account and then editing the post to actually have completely bogus data rather than anything close to the correct key. The list id on the other hand, doesn't matter at all.
You'll be able to use your hash if you convert it to json before passing it to Net::HTTP. The combined code would look something like:
mailchimp = {}
mailchimp['apikey'] = 'APIKEYAPIKEYAPIKEYAPIKEY'
mailchimp['id'] = '8037342dd1874'
mailchimp['email_address'] = "email#gmail.com"
mailchimp['merge_vars[FNAME]'] = "FirstName"
mailchimp['output'] = 'json'
response = nil
Net::HTTP.start('us2.api.mailchimp.com', 80) {|http|
response = http.post('/1.3/?method=listSubscribe', mailchimp.to_json)
}

Resources