Parse multi level JSON from URL - json

All.
I found this script which is rather promising for what I am trying to do.
It works great with the hardcoded XML script.
However, I need to parse the file itself from an external URL.
Thank You.
Contents of the example file.
{"icestats":{"admin":"admin","host":"192.168.2.203","location":"Radio","server_id":"Icecast 2.4.4","server_start":"Mon, 24 May 2021 16:54:10 +0000","server_start_iso8601":"2021-05-24T16:54:10+0000","source":{"audio_info":"channels=2;samplerate=44100;bitrate=256","channels":2,"genre":"various","listener_peak":3,"listeners":2,"listenurl":"http://192.168.2.203:8000/RadioOne","samplerate":44100,"server_description":"Unspecified description","server_name":"RadioOne","server_type":"audio/mpeg","stream_start":"Mon, 24 May 2021 21:59:34 +0000","stream_start_iso8601":"2021-05-24T21:59:34+0000","title":"KISS - Hide Your Heart","dummy":null}}}
Example of the linked file. (This is an example of the URL file, in the real-world URL, it will be my domain name, with the file attached to it. This file cannot be removed from the location it is at, it is sitting on another server in the network.)
http://192.168.2.203:8000/status-json.xsl
Full script (This will run and show the hardcoded XML tree without any modifications to the file)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Parse Nested JSON Data in JavaScript</title>
</head>
<body>
<script>
/* Storing multi-line JSON string in a JS variable
using the new ES6 template literals */
var json = '{"icestats":{"admin":"admin","host":"192.168.2.203","location":"Radio","server_id":"Icecast 2.4.4","server_start":"Mon, 24 May 2021 16:54:10 +0000","server_start_iso8601":"2021-05-24T16:54:10+0000","source":{"audio_info":"channels=2;samplerate=44100;bitrate=256","channels":2,"genre":"various","listener_peak":3,"listeners":2,"listenurl":"http://192.168.2.203:8000/RadioOne","samplerate":44100,"server_description":"Unspecified description","server_name":"RadioOne","server_type":"audio/mpeg","stream_start":"Mon, 24 May 2021 21:59:34 +0000","stream_start_iso8601":"2021-05-24T21:59:34+0000","title":"KISS - Hide Your Heart","dummy":null}}}';
// This is the link to the file; the file contents are what is above.
//var json = "http://192.168.2.203:8000/status-json.xsl";
// Converting JSON object to JS object
var obj = JSON.parse(json);
// Define recursive function to print nested values
function printValues(obj) {
for(var k in obj) {
if(obj[k] instanceof Object) {
printValues(obj[k]);
} else {
document.write(obj[k] + "<br>");
};
}
};
printValues(obj);
document.write("<hr>");
document.write(obj["icestats"]["source"]["title"]);
</script>
</body>
</html>
When I run the script with the URL link only, I get the following error.
Uncaught SyntaxError: Unexpected token h in JSON at position 0
at JSON.parse (<anonymous>)
at music2.asp:18
Which points to this line.
var obj = JSON.parse(json);

This code was provided for me and it works great.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Zvonko *</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<script>
// fetch the JSON data from your URL:
jQuery.get( "http://localhost:8000/status-json.xsl" , showData, "json" );
function showData(data){
// no need to Converting JSON string to JS object
// jQuery converted it for you
//var obj = JSON.parse(data);
printValues(data);
document.write("_______________________________");
if(data["icestats"] && data["icestats"]["source"]){
document.write(data["icestats"]["source"]["title"]);
// This next line, I use to pass a variable to an input field to submit to the database.
$(".myid").val(data["icestats"]["source"]["title"]);
}
// Converting your JSON string from top to JS object
var jsonobj = JSON.parse(yourJson);
printValues(jsonobj);
document.write("_______________________________");
if(jsonobj["icestats"] && data["icestats"]["source"]){
document.write(jsonobj["icestats"]["source"]["title"]);
}
}
// Define recursive function to print nested values
function printValues(obj) {
for(var k in obj) {
if(obj[k] instanceof Object) {
printValues(obj[k]);
} else {
document.write(k + ": " + obj[k]);
};
}
};
</script>
</body>
</html>
<form action="Send.asp" method="post">
<input type="text" name="Title" class="myid" style="border:1px double #000;">
<input type="submit" name="Submit">
</form>
Thanks to, Zvonko, for the code, on another side.
This one is completed.

Related

Parsing Html Page with Dart

I m trying to parse the following entry in an HTTP get request.
In the body, you see a script tag with a function call where I need to have access to the JSON inside the HTML tag.
<!DOCTYPE html>
<html translate="no">
<head></head>
<body>
<script>
$(function() {
intranet.list.frontend.init({
gridDataAndConfiguration: {
"Here is a big Json - WANTED"
},
},
});
</script>
</body>
</html>
Up to now, I don't parse the HTML with any Dart specific parsing method like
"parse" from package:html/parser.dart. That attempt was successful in searching for all the "script" tags inside the HTML DOM, but unfortunately, I did not find or showed the JSON or function call inside the referred script Tag!
The question is, how to access the JSON in the given HTML Page using Dart?
Solution :
RegExp re = RegExp(r'\[\{.*?\}\]');
var parsedHtml = parse(htmlText);
var allScripts = parsedHtml.getElementsByTagName('script');
for (int i = 0; i < allScripts.length; i++) {
if (allScripts[i].innerHtml.contains(startString)) {
Iterable<String> result =
re.allMatches(allScripts[i].innerHtml).map((m) => m[0]);
List<dynamic> jsonParsed = [];
for (var match in result) jsonParsed.add(jsonDecode(match));
Thanks for your answer & help.

How to get clean json from wikipedia API

I want to get the result from a wikipedia page https://en.wikipedia.org/wiki/February_2 as JSON.
I tried using their API: https://en.wikipedia.org/w/api.php?action=parse&page=February_19&prop=text&formatversion=2&format=json
Though it is giving it as Json format. The content is HTML. I want only the content.
I need a way to get clean result.
If you want plain text without markup, you have first to parse the JSON object and then extract the text from the HTML code:
function htmlToText(html) {
let tempDiv = document.createElement("div");
tempDiv.innerHTML = html;
return tempDiv.textContent || tempDiv.innerText || "";
}
const url = 'https://en.wikipedia.org/w/api.php?action=parse&page=February_19&prop=text&format=json&formatversion=2&origin=*';
$.getJSON(url, function(data) {
const html = data['parse']['text'];
const plainText = htmlToText(html);
const array = [...plainText.matchAll(/^\d{4} *–.*/gm)].map(x=>x[0]);
console.log(array);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Update: I edited the code above according to the comment below. Now the function extracts all the list items putting them into an array.
I guess by clean you mean the source wikitext. In that case you can use the revisions module:
https://en.wikipedia.org/w/api.php?action=query&titles=February_2&prop=revisions&rvprop=content&formatversion=2&format=json
See API:Get the contents of a page and API:Revisions for more info.

How to only send HTTP response as plain text (HTML) [duplicate]

This question already has answers here:
What is the difference between client-side and server-side programming?
(3 answers)
Closed 2 years ago.
I need to implement a calculator on my webpage, which will receive some arguments in the url and is supposed to return just the result, nothing else.
Example:
http://example.com/calc/?x=244&y=123&op=plus
I wrote a program using HTML and JavaScript which returns the correct result and prints it on the webpage.
This prints the result.
But the client doesn't just receive the result, but the whole html & script. Does anyone know how I can send only the result to the client?
Edit: If this cannot be done with HTMP and JS, how else?
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
function calculate(url) {
// ...
}
let url = window.location.href;
document.write(parseInt(calculate(url)));
</script>
</body>
</html>
Desired result: 367 is returned to the HTTP client
Actual result: < !DOCTYPE html> .... ...... is returned to the HTTP client
Try the following
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
function calculate (url_string) {
try {
var url = new URL(url_string);
var x = parseInt(url.searchParams.get("x"));
var y = parseInt(url.searchParams.get("y"));
switch(url.searchParams.get("op")){
case "plus": return x + y;
// add more cases here
}
} catch(e){}
}
let url = window.location.href;
document.write(parseInt(calculate(url)));
</script>
</body>
</html>

How to create resuable showModalDialog() in Google App Script?

I have ModalDialog that prompts for user date range selection in order to generate the appropriate info. I have several menu items that uses the same prompt so I want to reuse the ModalDialog.
// Available method
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Options for Menu Item N');
// What I hope is available
SpreadsheetApp.getUI().showModalDialog(htmlOutput, 'Options for Menu Item N', userdataN); // pseudocode
// inside HTML
var userdata = Script.host.environment // pseudocode do something with userdata in HTML
However, the showModalDialog() function does not allow me to pass any user data to the html so I have no way to identify which menu item I need to return the user selection to.
How can I create a reusable ModelDialog in this case?
EDIT:
I realized I can write the environment variable value in a sheet and then later from the HTML retrieve the value, but is there a cleaner way to do it?
You could either pass the user data object as a property of the HtmlTemplate object and use scriptlet syntax (see this answer) or do string interpolation. Personally, I prefer the latter option over using Google's built-in template engine. It's slower but much more flexible.
Suppose we have an HTML page called 'app' in the script editor
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>{{global.app}}</h1>
<div id=container>
<ul>
<li>{{name}}</li>
<li>{{email}}</li>
<li>{{age}}</li>
</ul>
Created by {{global.author}}.
</div>
</body>
</html>
You can call HtmlService methods to serve the template as a string.
//serve HTML template as a string
function getTemplateAsString(filename) {
return HtmlService.createTemplateFromFile(filename).getRawContent();
}
You can then pass the html string to the interpolation function:
var config = {
app: "My app",
author: "me"
};
function interpolateString(htmlString, params) {
//Add global variables to the template
for (var configKey in config) {
if (config.hasOwnProperty(configKey)) {
htmlString = htmlString.replace("{{global." + configKey + "}}", config[configKey]);
}
}
//Insert page-specific parameters
for (var paramsKey in params) {
if (params.hasOwnProperty(paramsKey)) {
htmlString = htmlString.replace("{{" + paramsKey + "}}", params[paramsKey]);
}
}
return htmlString;
}
For the last step, you create the HtmlTemplate object from the resulting string and call the 'evaluate()' method on it. Calling evaluate returns a valid HtmlOutput object instance that you can pass to UI methods
var template = HtmlService.createTemplate(htmlString);
ui.showModalDialog(template.evaluate(), "My dialog");

Mustache.js iterate over all arrays

I'm still busy trying to setup a JSON file to a HTML website. So if the json changes the changes are dynamically loaded in the HTML. Till this far i'm able to retreive the content and even request some content. But not everything that i want because the markup from the JSON is a bit weird.
Because of the cross-site protection I was not able to do a JSOP request directly, so i solved that with a little trick i saw somewhere. I've created a test.php that simply does:
That way I circumvent the cross-site protection, and everything works well. Only problem is that I can't iterate over all the arrays that i want. Currently i'm using the following script to do a JSOP call and get the data. And the output is a nice description between the <li></li>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<ul id="episodes">
</ul>
<script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.7.0/mustache.min.js"></script>
<script src="http://ps3scenefiles.com/json/handlebars.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script id="episodes-template" type="text/template">
<li>{{description}}</li>
</script>
<script>
$(function() {
$.getJSON('http://ps3scenefiles.com/json/test.php', function(data) {
var template = $('#episodes-template').html();
var info = Mustache.to_html(template, data);
$('#episodes').html(info);
});
});
</script>
</body>
</html>
But when you open the link to the JSON (http://ps3scenefiles.com/json/test.php), you see that the Episodes array has another array with just numbers. How can i create a list like
Episode: 1
Id:13605 Active:true Lang:en Link: url
Id:16525 Active:true Lang:ru Link: url
Episode: 2
Id:14854 Active:true Lang:en Link: url
Id:19445 Active:true Lang:ru Link: url
So to be clear, how can i do a mustache (or handlebars) templating to make it look like the example?
You can use Handlebars helper as mentioned in this answer
Here is a fiddle without styling, that prints out the data you expect (sort of, not all fields).
Here is the helper function -
Handlebars.registerHelper('eachkeys', function(context, options) {
var fn = options.fn, inverse = options.inverse;
var ret = "";
var empty = true;
for (key in context) { empty = false; break; }
if (!empty) {
for (key in context) {
ret = ret + fn({ 'key': key, 'value': context[key]});
}
} else {
ret = inverse(this);
}
return ret;
});