How to format json in a file using Groovy - json

I have a question in regards to formatting a file so that it displays a Json output to the correct format.
At the moment the code I have below imports a json into a file but when I open the file, it displays the json in a single line (word wrap unticked) like so:
{"products":[{"type":null,"information":{"description":"Hotel Parque La Paz (One Bedroom apartment) (Half Board) [23/05/2017 00:00:00] 7 nights","items":{"provider Company":"Juniper","provider Hotel ID":"245","provider Hotel Room ID":"200"}},"costGroups":[{"name":null,"costLines":[{"name":"Hotel Cost","search":null,"quote":234.43,"quotePerAdult":null,"quotePerChild":null}
I want to format the json in the file so that it looks like actual json formatting like so:
{
"products": [
{
"type": null,
"information": {
"description": "Hotel Parque La Paz (One Bedroom apartment) (Half Board) [23/05/2017 00:00:00] 7 nights",
"items": {
"provider Company": "Juniper",
"provider Hotel ID": "245",
"provider Hotel Room ID": "200"
}
},
"costGroups": [
{
"name": null,
"costLines": [
{
"name": "Hotel Cost",
"search": null,
"quote": 234.43,
"quotePerAdult": null,
"quotePerChild": null
}
Virtually each header has its own line to contain its values.
What is the best way to implement this to get the correct json formatting within the file?
Below is the code:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def dataFolder = groovyUtils.projectPath +"//Log Data//"
def response = testRunner.testCase.getTestStepByName("GET_Pricing{id}").getProperty("Response").getValue();
def jsonFormat = (response).toString()
def fileName = "Logged At - D" +date+ " T" +time+ ".txt"
def logFile = new File(dataFolder + fileName)
// checks if a current log file exists if not then prints to logfile
if(logFile.exists())
{
log.info("Error a file named " + fileName + "already exisits")
}
else
{
logFile.write "Date Stamp: " +date+ " " + time + "\n" + jsonFormat //response

If you have a modern version of groovy, you can do:
JsonOutput.prettyPrint(jsonFormat)

Related

Pulling specific Parent/Child JSON data with Python

I'm having a difficult time figuring out how to pull specific information from a json file.
So far I have this:
# Import json library
import json
# Open json database file
with open('jsondatabase.json', 'r') as f:
data = json.load(f)
# assign variables from json data and convert to usable information
identifier = data['ID']
identifier = str(identifier)
name = data['name']
name = str(name)
# Collect data from user to compare with data in json file
print("Please enter your numerical identifier and name: ")
user_id = input("Numerical identifier: ")
user_name = input("Name: ")
if user_id == identifier and user_name == name:
print("Your inputs matched. Congrats.")
else:
print("Your inputs did not match our data. Please try again.")
And that works great for a simple JSON file like this:
{
"ID": "123",
"name": "Bobby"
}
But ideally I need to create a more complex JSON file and can't find deeper information on how to pull specific information from something like this:
{
"Parent": [
{
"Parent_1": [
{
"Name": "Bobby",
"ID": "123"
}
],
"Parent_2": [
{
"Name": "Linda",
"ID": "321"
}
]
}
]
}
Here is an example that you might be able to pick apart.
You could either:
Make a custom de-jsonify object_hook as shown below and do something with it. There is a good tutorial here.
Just gobble up the whole dictionary that you get without a custom de-jsonify and drill down into it and make a list or set of the results. (not shown)
Example:
import json
from collections import namedtuple
data = '''
{
"Parents":
[
{
"Name": "Bobby",
"ID": "123"
},
{
"Name": "Linda",
"ID": "321"
}
]
}
'''
Parent = namedtuple('Parent', ['name', 'id'])
def dejsonify(json_str: dict):
if json_str.get("Name"):
parent = Parent(json_str.get('Name'), int(json_str.get('ID')))
return parent
return json_str
res = json.loads(data, object_hook=dejsonify)
print(res)
# then we can do whatever... if you need lookups by name/id,
# we could put the result into a dictionary
all_parents = {(p.name, p.id) : p for p in res['Parents']}
lookup_from_input = ('Bobby', 123)
print(f'found match: {all_parents.get(lookup_from_input)}')
Result:
{'Parents': [Parent(name='Bobby', id=123), Parent(name='Linda', id=321)]}
found match: Parent(name='Bobby', id=123)

python writing into json files witout overwriting

How can I write into a JSON file without overwriting things?
like
file.json contains
{
"today date" : {
"sec": 04
"min": 10
}
}
I want to add info the next time I open this like
{
"today date" : {
"sec": 04
"min": 10
}
"other day": {
"sec": "other"
"min": "other min"
}
}
so add data without overwriting the data that was before.
Thank you for your help!
If you're treating the json as text, it's easy to insert the new data into the existing file.
newdata = """"other day": {
"sec": "other"
"min": "other min"
}"""
jsonfile = 'data.json'
# read current json file
with open(jsonfile,'r') as f:
curdata = f.read().strip()
# merge new data
fulldata = curdata[0:-1].strip() + ",\n" + newdata + "\n}"
# write full data
with open(jsonfile,'w') as f:
f.write(fulldata)

How do you print multiple key values from sub keys in a .json file?

Im pulling a list of AMI ids from my AWS account and its being written into a json file.
The json looks basically like this:
{
"Images": [
{
"CreationDate": "2017-11-24T11:05:32.000Z",
"ImageId": "ami-XXXXXXXX"
},
{
"CreationDate": "2017-11-24T11:05:32.000Z",
"ImageId": "ami-aaaaaaaa"
},
{
"CreationDate": "2017-10-24T11:05:32.000Z",
"ImageId": "ami-bbbbbbb"
},
{
"CreationDate": "2017-10-24T11:05:32.000Z",
"ImageId": "ami-cccccccc"
},
{
"CreationDate": "2017-12-24T11:05:32.000Z",
"ImageId": "ami-ddddddd"
},
{
"CreationDate": "2017-12-24T11:05:32.000Z",
"ImageId": "ami-eeeeeeee"
}
]
}
My code looks like this so far after gathering the info and writing it to a .json file locally:
#writes json output to file...
print('writing to response.json...')
with open('response.json', 'w') as outfile:
json.dump(response, outfile, ensure_ascii=False, indent=4, sort_keys=True, separators=(',', ': '))
#Searches file...
print('opening response.json...')
with open("response.json") as f:
file_parsed = json.load(f)
The next part im stuck on is how to iterate through the file and print only the CreationDate and ImageId values.
print('printing CreationDate and ImageId...')
for ami in file_parsed['Images']:
#print ami['CreationDate'] #THIS WORKS
#print ami['ImageId'] #THIS WORKS
#print ami['CreationDate']['ImageId']
The last line there gives me this no matter how I have tried it: TypeError: string indices must be integers
My desired output is something like this:
2017-11-24T11:05:32.000Z ami-XXXXXXXX
Ultimately what im looking to do is then iterate through lines that are a certain date or older and deregister those AMIs. So would I be converting these to a list or a dict?
Pretty much not a programmer here so dont drown me.
TIA
You have almost parsed the json but for the desired output you need to concatenate the 'CreationDate' and 'ImageId' like this:
for ami in file_parsed['Images']:
print(ami['CreationDate'] + " "+ ami['ImageId'])
CreationDate evaluates to a string. So you can only take numerical indices of a string which is why ['CreationDate']['ImageId'] leads to a TypeError. Your other two commented lines, however, were correct.
To check if the date is older, you can make use of the datetime module. For instance, you can take the CreationDate (which is a string), convert it to a datetime object, create your own based on what that certain date is, and compare the two.
Something to this effect:
def checkIfOlder(isoformat, targetDate):
dateAsString = datetime.strptime(isoformat, '%Y-%m-%dT%H:%M:%S.%fZ')
return dateAsString <= targetDate
certainDate = datetime(2017, 11, 30) # Or whichever date you want
So in your for loop:
for ami in file_parsed['Images']:
creationDate = ami['CreationDate']
if checkIfOlder(creationDate, certainDate):
pass # write code to deregister AMIs here
Resources that would benefit would be Python's datetime documentation and in particular, the strftime/strptime directives. HTH!

compare input to fields in a json file in ruby

I am trying to create a function that takes an input. Which in this case is a tracking code. Look that tracking code up in a JSON file then return the tracking code as output. The json file is as follows:
[
{
"tracking_number": "IN175417577",
"status": "IN_TRANSIT",
"address": "237 Pentonville Road, N1 9NG"
},
{
"tracking_number": "IN175417578",
"status": "NOT_DISPATCHED",
"address": "Holly House, Dale Road, Coalbrookdale, TF8 7DT"
},
{
"tracking_number": "IN175417579",
"status": "DELIVERED",
"address": "Number 10 Downing Street, London, SW1A 2AA"
}
]
I have started using this function:
def compare_content(tracking_number)
File.open("pages/tracking_number.json", "r") do |file|
file.print()
end
Not sure how I would compare the input to the json file. Any help would be much appreciated.
You can use the built-in JSON module.
require 'json'
def compare_content(tracking_number)
# Loads ENTIRE file into string. Will not be effective on very large files
json_string = File.read("pages/tracking_number.json")
# Uses the JSON module to create an array from the JSON string
array_from_json = JSON.parse(json_string)
# Iterates through the array of hashes
array_from_json.each do |tracking_hash|
if tracking_number == tracking_hash["tracking_number"]
# If this code runs, tracking_hash has the data for the number you are looking up
end
end
end
This will parse the JSON supplied into an array of hashes which you can then compare to the number you are looking up.
If you are the one generating the JSON file and this method will be called a lot, consider mapping the tracking numbers directly to their data for this method to potentially run much faster. For example,
{
"IN175417577": {
"status": "IN_TRANSIT",
"address": "237 Pentonville Road, N1 9NG"
},
"IN175417578": {
"status": "NOT_DISPATCHED",
"address": "Holly House, Dale Road, Coalbrookdale, TF8 7DT"
},
"IN175417579": {
"status": "DELIVERED",
"address": "Number 10 Downing Street, London, SW1A 2AA"
}
}
That would parse into a hash, where you could much more easily grab the data:
require 'json'
def compare_content(tracking_number)
json_string = File.read("pages/tracking_number.json")
hash_from_json = JSON.parse(json_string)
if hash_from_json.key?(tracking_number)
tracking_hash = hash_from_json[tracking_number]
else
# Tracking number does not exist
end
end

i got empty value when print json key in lua code

this is the json response plus "\x00" in the end from server :
{
"STATUS": [{
"STATUS":"S",
"When":1470180059,
"Code":11,
"Msg":"Summary",
"Description":"nsgminer 0.9.2"
}],"SUMMARY": [{
"Elapsed":2061,
"MHS av":0.00,
"Found Blocks":0,
"Getworks":76,
"Accepted":0,
"Rejected":0,
"Hardware Errors":0,
"Utility":0.00,
"Discarded":209,
"Stale":0,
"Get Failures":3,
"Local Work":293,
"Remote Failures":0,
"Network Blocks":14,
"Total MH":0.0000,
"Work Utility":0.00,
"Difficulty Accepted":0.00000000,
"Difficulty Rejected":0.00000000,
"Difficulty Stale":0.00000000,
"Best Share":0
}],
"id":1
}\x00
i want to use the json in lua code :
local output = stdnse.output_table()
local json_string = tostring(result:sub(1, -2))
local pos, value = json.parse(json_string)
output["Description"] = value["STATUS"][0]["Description"]
return output
when i print it out, i got null value
i solve that with covert json to string and convert string into json table
local pos, value = json.parse(tostring(json_string))
output["Description"] = value["STATUS"][1]["Description"]