1

I want to parse the JSONP data and save that data into my data base .

I have my jsonp url lets say this >>http://a0.awsstatic.com/pricing/1/ec2/pricing-data-transfer-with-regions.min.js?callback=callback&_=1409722308446

Its not normal json object so how can i parse this json in ruby/ruby on rails and save the data into my database. I want to save the data in table having filed lets say region , name ,type, price .

What are the ways to do the same.

neo-code
  • 1,076
  • 10
  • 26

3 Answers3

3

JSONP is a work around for the same origin policy in client side JavaScript. It isn't required for processing data in Ruby. Firstly I would try to find the data available in plain JSON, without the callback.

If, however, that URL is absolutely the only one you can call for this data, then I would strip away the callback using a regular expression and then parse the plain JSON data.

If you have already loaded the contents of that file into a variable called jsonp, then something like this might work:

require 'net/http'
require 'json'
uri = URI.parse('http://a0.awsstatic.com/pricing/1/ec2/rhel-od.min.js?callback=callback&_=1409731896563')
jsonp = Net::HTTP.get(uri)
jsonp.gsub!(/^.*callback\(/, '') # removes the comment and callback function from the start of the string
jsonp.gsub!(/\);$/, '') # removes the end of the callback function
jsonp.gsub!(/(\w+):/, '"\1":')
hash = JSON.parse(jsonp)

then hash will have the parsed JSON from the response.

Please note, this code has no error handling and should be treated as a starting point for your final solution.

[edit] Added the third gsub to change the JavaScript style keys to JSON style keys. This works in this case because the keys all appear to be simple enough to fit that regex. [edit2] Added way to load the JSONP with Net::HTTP

philnash
  • 70,667
  • 10
  • 60
  • 88
  • in this case we have JSONP which contain valid js object and looks like: {attr: "val"}, but for transporting/parsing we need valid JSON not as js object but converted to string which should looks like: {"attr" : "val"} – Igor Guzak Sep 03 '14 at 10:18
  • Yes this is the issue when i parse it using jdata = JSON.load(open("http://a0.awsstatic.com/pricing/1/ec2/rhel-od.min.js?callback=callback&_=1409731896563")) it says JSON::ParserError: 795: unexpected token at 'callback – neo-code Sep 03 '14 at 10:39
  • Ah, @Mayank, I see. You will need to load that data using another method than JSON.load. I will edit my answer to show that too. – philnash Sep 03 '14 at 10:42
  • Thank you so much you are genius thats work..can you also suggest me that how can i save this data into data base ..as data is nested very deeply like for one region there are so many nested hash which all needs to save under that region.. – neo-code Sep 03 '14 at 10:57
  • @Mayank I can't really help much more, I don't know what your database set up is or what you plan to do with the data. You know have it in a usable ruby format, so I recommend experimenting with the data to find the best way to solve the problem you are working on. – philnash Sep 03 '14 at 11:00
  • I changed the second line to make the ending semicolon in JSONP optional `jsonp.gsub!(/\);?[\n]?$/, '') `. By default, Rails JSONP output does not have a semicolon – Leo May 13 '16 at 20:11
1

If what you're really trying to do is parse the Amazon price list JS file into Ruby, there is a better (read: safer--no evals) way to do it:

require 'net/http'
require 'json'

JSON.parse(
  Net::HTTP.get(
    URI.parse('http://a0.awsstatic.com/pricing/1/ec2/rhel-od.min.js')
  ).split('callback(')[1].sub(');', '').gsub(/(\w+):/, '"\1":')
)
Eric Herot
  • 388
  • 3
  • 6
0

As the data is as a raw JS object form, it's actually valid Ruby:

require 'json'
data = '{key: "value", key2: 33}'
obj = eval data
obj[:key]
#=> "value"
obj.to_json
# => "{\"key\":\"value\",\"key2\":33}" 

You must trust your source completely though - this would allow the running of abstract Ruby code if the data were tampered with - which could in turn run abstract command-line terminal code, using the back-tick operators. This could delete your hard drive for example.

A Fader Darkly
  • 3,516
  • 1
  • 22
  • 28
  • (1) JSON is not a subset of either Javascript or Ruby, they all use different rules for escaping "weird" characters. You thus can't savely eval it. (2) JSONP isn't even JSON. Instead it is JavaScript that is intended to be run inside the browser's javascript engine as a way to work around the same origin policy. – Holger Just Sep 03 '14 at 10:39
  • Thanks for the comment. The fact that it's using eval makes me twitch enough - adding escaping hell to the equation makes this a thoroughly unsuitable answer. The provided example in the question above (after cutting away header and footer) did convert however. – A Fader Darkly Sep 03 '14 at 10:44
  • Yeah, none of this is pretty, however it does seem to work. The first part of my answer is definitely to try to find the data available as JSON not JSONP. – philnash Sep 03 '14 at 10:48