Parsing Hashie::Mash output to Json in ruby - ruby

I'm getting user input in JSON format for an API created using grape. In a particular parameter, I'm giving an array of JSON in the following format.
"personal" : {
"details" : {
"firstname" :"nagalakshmi",
"lastname" : "n"
}
}
When I tried to print "personal" attribute it is showing like below
#<Hashie::Mash details=#<Hashie::Mash firstname="nagalakshmi" lastname="n">>
Is there any way to parse the attribute to json format?

I was able to do it using to_json

I also got this same object as params with Grape.
Hashie::Mash
params: #<Hashie::Mash data=#<Hashie::Mash attributes=#<Hashie::Mash title="Ember Hamster"> type="pictures">>
If you are using Rails We can convert into ruby hash as following:
params.to_hash
gives
{"data"=>{"type"=>"pictures", "attributes"=>{"title"=>"Ember Hamster"}}}

Related

Retrive additional tag info in json response

When i use get method on the below bright cove api to retrive video meta data, it generates json response with some fields.
"https://cms.api.brightcove.com/v1/accounts/510000340001/videos?sort=-updated_at&limit=1&offset=0"
How do we get additional tags which are not included, say for example 'category' field in the output json response?
I tried to append below in url and api does not detect.
?custom_field=category
If the video has a value set for that field, it will be present in the custom_fields object as below. If the field is empty, it will not be included for that video.
{
"name": "A video",
...
"custom_fields": {
"category": "something"
}
}

Elasticsearch Multi Get working through curl, but no results are returned through Java API

I am running elasticsearch 2.3.4, but the syntax does not seem to have changed in 5.x.
Multiget over curl is working just fine. Here is what my curl looks like:
curl 'localhost:9200/_mget' -d '{
"docs" : [
{
"_index" : "logs-2017-04-30",
"_id" : "e72927c2-751c-4b33-86de-44a494abf78f"
}
]
}'
And when I want to pull the "message" field off that response, I use this request:
curl 'localhost:9200/_mget' -d '{
"docs" : [
{
"_index" : "logs-2017-04-30",
"_id" : "e72927c2-751c-4b33-86de-44a494abf78f",
"fields" : ["message"]
}
]
}'
Both of the above queries return the log and information that I am looking for.
But when I try to translate it to Java like this:
MultiGetRequestBuilder request = client.prepareMultiGet();
request.add("logs-2017-04-30", null, "e72927c2-751c-4b33-86de-44a494abf78f");
MultiGetResponse mGetResponse = request.get();
for (MultiGetItemResponse itemResponse : mGetResponse.getResponses()) {
GetResponse response = itemResponse.getResponse();
logger.debug("Outputing object: " + ToStringBuilder.reflectionToString(response));
}
I appear to be getting null objects back. When I try to grab the message field off the null-looking GetResponse object, nothing is there:
GetField field = response.getField("message"); <--- returns null
What am I doing wrong? doing a rest call to elasticsearch proves the log exists, but my Java call is wrong somehow.
The documentation page for the Java multi get completely skips over the extra syntax required to retrieve data beyond the _source field. Just like the REST API, doing a multi get with the minimum information required to locate a log gets very limited information about it. In order to get specific fields from a log in a multi get call through the Java API, you must pass in a MultiGetRequest.Item to the builder. This item needs to have the fields you want specified in it before you execute the request.
Here is the code change (broken into multiple lines for clarity) that results in the fields I want being present when I make the query:
MultiGetRequestBuilder request = client.prepareMultiGet();
MultiGetRequest.Item item = new MultiGetRequest.Item("logs-2017-04-30", "null", "e72927c2-751c-4b33-86de-44a494abf78f");
item.fields("message");
request.add(item);
MultiGetResponse mGetResponse = request.get();
Now I can ask for the field I specified earlier:
GetField field = response.getField("message");

Scraping, My Query Parameters Are Wrong

I'm on a website using Ruby and Mechanize to pass a POST query to a site. The query that gets to the site, based on firebug, looks like this
param.PrdNo=-1&param.Type=Prop&param.RequestType=Normal&param.PropParams%5B0%5D.CrId=Base-MLB+Su+Washington+Na%40Atlanta+Brave
The QUERY I pass in my ruby code is this
QUERY = { "param.PrdNo" => "-1",
"param.Type" => "Prop",
"param.RequestType" => "Normal",
"param.PropParams[0].CrId" => "Base-MLB+Su+Washington+Na#Atlanta+Brave"}
doc.agent.post(url, QUERY, content_type)
The logger prints out the following
D, [2014-08-10T14:46:24.844744 #15801] DEBUG -- : query: "param.PrdNo=-1&param.Type=Prop&param.RequestType=Normal&param.PropParams%5B0%5D.CrId=Base-MLB%2BSu%2BWashington%2BNa%40Atlanta%2BBrave"
How do I get my code to make a query that looks like the query from firebug?
You could post the string:
vars = "param.PrdNo=-1&param.Type=Prop&param.RequestType=Normal&param.PropParams%5B0%5D.CrId=Base-MLB+Su+Washington+Na%40Atlanta+Brave"
doc.agent.post url, vars, content_type
It will get sent as the raw post body.

How do I clean a JSON string with serialized formatting?

I tried to decode and parse the string that an API returns, however the syntax of the returned JSON object is weird.
I could just strip elements from the string, but was wondering what is the best way to clean up this JSON string and convert it to a Ruby hash?
"DataCallBack([
{
\"detail1\": \"result1\",
\"detail2\": \"result2\",
\"Attr1\": [
{
\"detail1\": \"result1\",
\"detail2\": \"result2\",
},
{...}
]
],
\"Attr2\": [
{
\"detail1\": \"result1\",
\"detail2\": \"result2\",
},
{...}
]
}
])"
Just request the data without the ?callback=DataCallBack in the query string, and you will probably get raw JSON that you can directly parse.
It's easy to strip the JSON from a JSONP response:
jsonp = 'DataCallBack([
{
"detail1": "result1",
"detail2": "result2",
"Attr1": [
{
"detail1": "result1",
"detail2": "result2"
}
],
"Attr2": [
{
"detail1": "result1",
"detail2": "result2"
}
]
}
])'
require 'json'
JSON.parse(jsonp[/{.+}/m])
# => {"detail1"=>"result1",
# "detail2"=>"result2",
# "Attr1"=>[{"detail1"=>"result1", "detail2"=>"result2"}],
# "Attr2"=>[{"detail1"=>"result1", "detail2"=>"result2"}]}
Your JSONP sample was mangled a bit, probably by trying to shorten it, so I cleaned it up to be valid JSON.
The pattern /{.+}/m tells the regular expression engine to find everything contained by the outermost curly braces, which is the JSON. The m flag tell the engine to treat the whole string, containing line-ends, as a long string, which is necessary when using . because it won't normally match line-ends. At that point you'll have the JSON content, so then it's a simple matter of parsing it back into a Ruby object.

Parsing HTTParty response

I'm using HTTParty to pull a list of a Facebook user's books but I'm having trouble parsing the response:
Facebook returns data this way:
{
"data": [
{
"name": "Title",
"category": "Book",
"id": "21192118877902",
"created_time": "2011-11-11T20:50:47+0000"
},
{
"name": "Title 2",
"category": "Book",
"id": "1886126860176",
"created_time": "2011-11-05T02:35:56+0000"
},
And HTTParty parses that into a ruby object. I've tried something like this (where ret is the response) ret.parsed_response and that returns the data array, but actually accessing the items inside returns a method not found error.
This is a sample of what HTTParty actually returns:
#<HTTParty::Response:0x7fd0d378c188 #parsed_response={"data"=>
[{"name"=>"Title", "category"=>"Book", "id"=>"21192111877902", "created_time"=>"2011-11-11T20:50:47+0000"},
{"name"=>"Title 2", "category"=>"Book", "id"=>"1886126860176", "created_time"=>"2011-11-05T02:35:56+0000"},
{"name"=>"Thought Patterns", "category"=>"Book", "id"=>"109129539157186", "created_time"=>"2011-10-27T00:00:16+0000"},
Do you have any code that is throwing an error? The parsed_response variable from the HTTParty response is a hash, not an array. It contains one key, "data" (the string, NOT the symbol). The value for the "data" key in the hash is an array of hashes, so you would iterate as such:
data = ret.parsed_response["data"]
data.each do |item|
puts item["name"]
puts item["category"]
puts item["id"]
# etc
end
Just an additional info - It's Not Always a default JSON response
HTTParty's result.response.body or result.response.parsed_response does not always have form of a Hash
It just depends generally on the headers which you are using in your request. For e.g., you need to specify Accept header with application/json value while hitting GitHub API, otherwise it simply returns as string.
Then you shall have to use JSON.parse(data) for same to convert the string response into Hash object.

Resources