Remove slash from string in ruby on rails - ruby-on-rails

I need to remove "\" from below string
{\"MACAddress\":\"74:5E:78\",\"DeviceName\":\"Connected_Device\"}
Response should be
{"MACAddress":"74:5E:78","DeviceName":"Connected_Device"}
I need to check if string includes "\n",i need to add validation to remove "\"
Can you please help how to handle this in rails?
Currently i am using httpparty below code
reqType = params['reqType']
payLoadData = params['payLoadData']
p "PAYLOAD DATA-------------- #{payLoadData}"
if reqType == "post"
start = Time.now
url=params['url']
body_param= device
p "payLoadData-------------- #{body_param}"
response = HTTParty.post(url,
:body => body_param,
:headers => {'Content-Type' => 'application/json','User-Agent'=> 'Auto',"Authorization" => 'Basic=='})
result_hash["response"].push({"body": response.body.to_s, "response_time": response_time.to_s})
result_hash["status"].push(response.code)

JSON.parse("{\"MACAddress\":\"74:5E:78\",\"DeviceName\":\"Connected_Device\"}")
It should do the trick

The response that you get from your Ajax call is a hash in JSON format.
Just use a JSON parser to translate the JSON string into a Ruby hash:
require 'json'
pay_load = params['payLoadData']
device = JSON.parse(pay_load)
device['MACAddress']
#=> "74:5E:78"
device['DeviceName']
#=> "Connected_Device"
When you just want to output the hash a simple puts device or a <%= device %> (depending on your context) should work. Because in both cases to_s is called on the hash internally.

Related

What is the type of this string and how to convert it to hash?

I passing ransack params from page to page. Initially params looks like hash
{"processed_at_gteq_datetime"=>"2021-08-01", "processed_at_lteq_datetime"=>"2021-09-14", "status_eq"=>"processed"}
But after sending this params to another page, it becomes a string and takes the following type:
"{\"processed_at_gteq_datetime\"=>\"2021-08-01\", \"processed_at_lteq_datetime\"=>\"2021-09-14\", \"status_eq\"=>\"processed\"}"
And in this form, I cannot use them for searching.
How i can convert this string:
"{\"processed_at_gteq_datetime\"=>\"2021-08-01\", \"processed_at_lteq_datetime\"=>\"2021-09-14\", \"status_eq\"=>\"processed\"}"
to hash?
I tried
JSON.parse my_params
But it doesn't work with this string
JSON::ParserError Exception: 767: unexpected token at '{"processed_at_gteq_datetime"=>"2021-08-01", "processed_at_lteq_datetime"=>"2021-09-14", "status_eq"=>"processed"}'
I guess you are passing parameters from page to page using either a link or a redirect.
If you want to keep those params as such, you have to pass them to the path helper:
link_to other_page_path(ransack_hash)
# => /other_page?processed_at_gteq_datetime=2021-08-01&processed_at_lteq_datetime=2021-09-14&status_eq=processed
and similar constructs. This
link_to other_page_path(q: ransack_hash)
# => /other_page?q[processed_at_gteq_datetime]=2021-08-01&q[processed_at_lteq_datetime]=2021-09-14&q[status_eq]=processed
will nest the params so that you can then retrieve in the other controller with
ransack_params = params[:q]
The reason this doesn't work:
JSON.parse("{\"foo\"=>\"bar\"}")
is because it's not valid Json. for valid JSON you need to replace the ruby => operator with the javascript : operator. You can do this with a ruby string manipulation.
string = "{\"foo\"=>\"bar\"}"
json = string.gsub(/=>/,':')
JSON.parse(json)

How to convert a hash to JSON without the converted string being full of backslashes

I am converting a hash to JSON using to_json, but the converted string is full of backslashes. If I use puts, it shows the correct string but if I pass in a HTTP::NET request.body, the string is full of backslashes.
data = {"a" => "b", "c" => "d", "e" => "f"}
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(uri.path, {'Content-Type' =>'application/json',
'Authorization' => "xyz")
req.body = data.to_json
res = http.request(req)
req.body is sending:
"{\"a\":\"b\",\"c\":\"d\",\"e\":\"f\"}"
My request is failing because of this.
I need to send data as
"{"a" => "b", "c" => "d", "e" => "f"}"
in the request body.
It seems like you are confused about the actual content of the string. The backslashes are part of the string representation, and are not actually in the string.
Take for example '"' a single character ". When you enter this into irb the output will be:
s = '"'
#=> "\""
From the result "\"" the starting " and ending " mark the begin and ending of the string while \" is an escaped double quote, and represents a single ". The reason this double quote is escaped is because you want Ruby to interpret it as an " character, not as the end of the string.
You can view the actual contents of the string without escape characters by printing it to the console.
puts s
# "
#=> nil
Here you can see that there is no backslash in the contents of the string.
The same applies for your to_json call, which returns a string:
data = {"a" => "b", "c" => "d", "e" => "f"}
json = data.to_json
#=> "{\"a\":\"b\",\"c\":\"d\",\"e\":\"f\"}"
puts json
# {"a":"b","c":"d","e":"f"}
#=> nil
Like you can see there are no backslashes in the contents of the string, only in the string representation.
You can handle this problem with two solutions: Either you can parse the JSON where you want to use it, or you can also send parsed JSON from Ruby code.
req.body = JSON.parse(data.to_json)
It will return the result like:
{"a"=>"b", "c"=>"d", "e"=>"f"}
It depends on you where you want to parse your data. If you want to parse on the frontend just use jQuery's JSON parse function.
Try as_json which might be more appropriate given what you're attempting. This is a good explanation of which to use and when. as_json will produce unescaped json.
Totally understand that the slash is an accepted escape on the string, but there are applications that do not accept it IE Amazon Connect.
req.body = JSON.parse(data.to_json)
Works perfectly.

Encoding parameters with multiple duplicate keys

I seem to be having the same problem as this chap here
I want to encode some parameters (for the import.io api). Effectively:
params = {
:input => "webpage/url:http://www.example.com",
:input => "keywords:some+keywords"
}
But that won't work, so I think this is the right approach:
params = { :input => ["webpage/url:http://www.example.com", "keywords:some+keywords"] }
and I want it to output
params.to_query
=> "input=webpage%2Furl%3Ahttp%3A%2F%2Fwww.example.com%2Fsome-id&input=keywords%3Asome%2Bkeywords"
unfortunately, I get
"input%5B%5D=webpage%2Furl%3Ahttp%3A%2F%2Fwww.example.com%2Fsome-id&input%5B%5D=keywords%3Asome%2Bkeywords"
It's adding [] after the input, which I believe is standard behaviour. How can I stop it doing it?
To clarify, what is the ruby or 'rails way' of dealing with url parameters that require duplicate keys?
Ran into a similar issue, there's a helpful post here Ruby Hash with duplicate keys? but briefly
params = {}.compare_by_identity
params['input'] = "webpage/url:http://www.example.com"
params['input'.dup] = "keywords:some+keywords"
then
params.to_query
returns
"input=keywords%3Asome%2Bkeywords&input=webpage%2Furl%3Ahttp%3A%2F%2Fwww.example.com"
Some characters in a url have special importance to the processing of the url: they are reserved, like keywords in a programming language. See Which characters make a URL invalid?
If you try to use these as the name or value of a parameter, it will break the uri and you'll get hard to predict results like you're seeing.
The answer is to URI escape the string, which will replace special characters with their encoded version. Rails will automatically unescape them when it gets the the request, so you don't need to worry about it.
You can escape them manually, but the best way, if you have them as a hash already, is to call .to_param on the hash.
params = { :input => ["webpage/url:http://www.example.com", "keywords:some+keywords"] }
=> {:input=>["webpage/url:http://www.example.com", "keywords:some+keywords"]}
params.to_param
=> "input%5B%5D=webpage%2Furl%3Ahttp%3A%2F%2Fwww.example.com&input%5B%5D=keywords%3Asome%2Bkeywords"

How do I encode the & symbol for batch requests?

I have a Facebook batch request that looks like this:
https://graph.facebook.com/?access_token=ACCESS_TOKEN&batch=[{"method": "GET", "relative_url": "search?q=EMAIL#ADDRESS.COM&type=user"}]
Sending this across the wire returns:
{"error"=>0, "error_description"=>"batch parameter must be a JSON array"}
If I remove the &type=user, it works fine (sends back an empty data array). I am absolutely certain that Facebook is not parsing the & character correctly. I read online somewhere that I could try encoding the & symbol to %26, however using that replacement seems to instead do a query for "EMAIL#ADDRESS.COM%26type=user". If you reverse the order of the parameters, you will see what I mean.
Any ideas how I can get the batch request parser on Facebook to recognize the & symbol without filing a bug report that will never be fixed?
EDIT:
I am using URI.encode. Here is the exact code:
queries = email_array.map { |email| { :method => "GET", :relative_url => "search?q=#{email}&type=user" } }
route = "https://graph.facebook.com/?access_token=#{token}&batch=#{URI.encode(queries.to_json)}"
res = HTTParty.post(route)
After actually playing around with this some more, I managed to reproduce the same behavior, even with a careful check and double-check that I was following the api specs correctly. This looks like a bug in facebook's batch method -- it doesn't understand ampersands in param values correctly.
Don't use a string literal to construct the json. Use to_json, like below. (Also, as an aside, don't use {} notation across more than one line, use do/end).
queries = []
email_array.each do |email|
queries << {:method => 'GET', :relative_url => "search?q=#{email}&type=user"}
end
route = "https://graph.facebook.com/?access_token=#{token}&batch=#{URI.encode(queries.to_json)}"
res = HTTParty.post(route)
Also, you can use Array#map to simply the code, like this:
queries = email_array.map { |email| {:method => 'GET', :relative_url => "search?q=#{email}&type=user"} }
route = "https://graph.facebook.com/?access_token=#{token}&batch=#{URI.encode(queries.to_json)}"
res = HTTParty.post(route)
EDIT: below is my original answer before the question was edited, for reference.
Try properly url encoding the whole parameter:
https://graph.facebook.com/?access_token=ACCESS_TOKEN&batch=[%7B%22method%22:%20%22GET%22,%20%22relative_url%22:%20%22search?q=EMAIL#ADDRESS.COM&type=user%22%7D]
In practice, you'd use URI.encode from the uri library to do this. Example:
irb(main):001:0> require 'uri'
=> true
irb(main):002:0> URI.encode('[{"method": "GET", "relative_url": "search?q=EMAIL#ADDRESS.COM&type=user"}]')
=> "[%7B%22method%22:%20%22GET%22,%20%22relative_url%22:%20%22search?q=EMAIL#ADDRESS.COM&type=user%22%7D]"
Or even better, use to_json to create your json string in the first place. Example:
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'json'
=> true
irb(main):003:0> require 'uri'
=> true
irb(main):004:0> URI.encode([{:method => 'GET', :relative_url => 'search?q=EMAIL#ADDRESS.COM&type=user'}].to_json)
=> "[%7B%22method%22:%22GET%22,%22relative_url%22:%22search?q=EMAIL#ADDRESS.COM&type=user%22%7D]"
If this helps anyone, when my AdSet batch update failed because there was an "&" in one of the interests name:
{u'id': u'6003531450398', u'name': u'Dolce & Gabbana'}
I learned that the name can be anything, and as long as the id is correct, FB will populate the name itself.

Parsing a document in a table

How do I parse a document in a table and send it across as a JSON file to another db.
Detailed Desc:
I have crawled and taken data into a table from websites using anemone. I need to now parse it and transfer it as a JSON file to another server. I think, I will have to first convert the document in the table into nokogiri document which can be parsed and converted to json file. Any idea how can I convert the doc into nokogiri document or if anyone has any other idea to parse it and send it as a json file ?
Nokogiri is your best bet for the HTML parsing, but as for converting it to JSON you're on your own from what I can tell.
Once you have it parsed via Nokogiri it shouldn't be terribly hard to extract the elements you need and generate JSON that represents them. What you're doing isn't a very common task, so you'll have to bridge the gap between Nokogiri and whichever gem you're using to generate the JSON.
Okay I found the answer long time back, I basically made use of REST to send message form one application to another, i sent it across as a hash. And the obvious one, I used nokogiri for parsing the table.
def post_me
#page_hash = page_to_hash
res = Net::HTTP.post_form(URI.parse('http://127.0.0.1:3007/element_data/save.json'),#page_hash)
end
For sending the hash from one application to another using net/http.
def page_to_hash
require 'rubygems'
require 'nokogiri'
require 'open-uri'
require 'domainatrix'
#page = self.page.sub(/^<!DOCTYPE html(.*)$/, '<!DOCTYPE html>')
hash={}
doc = Nokogiri::HTML(self.page)
doc.search('*').each do |n|
puts n.name
end
Using Nokogiri for parsing the page table in my model. page table had the whole body of a webpage.
file_type = []
file_type_data=doc.xpath('//a/#href[contains(. , ".pdf") or contains(. , ".doc")
or contains(. , ".xls") or contains(. , ".cvs") or contains(. , ".txt")]')
file_type_data.each do |href|
if href[1] == "/"
href = "http://" + website_url + href
end
file_type << href
end
file_type_str = file_type.join(",")
hash ={:head => head,:title => title, :body => self.body,
:image => images_str, :file_type => file_type_str, :paragraph => para_str, :description => descr_str,:keyword => key_str,
:page_url=> self.url, :website_id=>self.parent_request_id, :website_url => website_url,
:depth => self.depth, :int_links => #int_links_arr, :ext_links => #ext_links_arr
}
A simple parsing example and how i formed my hash.

Resources