Extract JavaScript String from HTML page with Java - javascript

I want to get the value of a particular Javascript variable hard-coded in a html page. Visit the test-case with the following instructions:
Go to the website : http://www.headphonezone.in/
Open console
Type : Shopify.theme
Output is : Object {name: "Retina", id: 8528293, theme_store_id: 601, role: "main"}
Type : Shopify.theme.theme_store_id
Output is : 601
The above response comes from the script given below, which is present in all the Shopify stores.
<script>
//<![CDATA[
var Shopify = Shopify || {};
Shopify.shop = "headphone-zone.myshopify.com";
Shopify.theme = {"name":"Retina","id":8528293,"theme_store_id":601,"role":"main"};
//]]>
</script>
How to write a java code to get the value of Shopify.theme.theme_store_id field and store it?

Get the html page as a String (see this post)
Detect the "Shopify.theme" keyword with a regex:
.
String patternString = "Shopify.theme\\s*=\\s*.*theme_store_id\\"\\:(\\d+)";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
String themeStoreId;
while (matcher.find()) {
themeStoreId = matcher.group(1);
}

Related

How to apply regular expression for Javascript

I am trying to get message log from Azure application Insight like this
az monitor app-insights --app [app id] --analystics-query [condition like specific message id]
Then I got a message like this
"message": [
"Receiving message: {"type":"CTL","traceId":"f0d11b3dbf27b8fc57ac0e40c4ed9e48","spanId":"a5508acb0926fb1a","id":{"global":"GLkELDUjcRpP4srUt9yngY","caller":null,"local":"GLkELDUisjnGrSK5wKybht"},"eventVersion":"format version","timeStamp":"2021-10-01T14:55:59.8168722+07:00","eventMetadata":{"deleteTimeStamp":null,"ttlSeconds":null,"isFcra":null,"isDppa":true,"isCCPA":true,"globalProductId":null,"globalSubProductId":null,"mbsiProductId":null},"eventBody":{"sys":"otel","msg":"Testing Centralized Event Publisher with App1 (using logback)","app":{"name":"otel","service":"postHouse","status":"status name","method":"POST","protocol":"HTTP","resp_time_ms":"250","status_code":"4"},}}"
] }
So that I would like to apply Regular Expression for this message to get only the message from {"type.....to "status_code":"4"},}} and also convert it to JSON format
I have code like this in my .js file
Then('extract json from {string}', function(message){
message = getVal(message, this);
const getmess = message.match(/{(.*)}/g);
const messJson = JSON.parse(getmess);
console.log(messJson);
})
But it doesn't work for me
SyntaxError: Unexpected token \ in JSON at position 1
How can I apply this in my code on Javascript? Thank you so much for your help
Try this. But keep in mind, that current regex is binded with provided program output syntax. If output will be different in wrapper structure, this regex might not work any more.
// Text from app
const STDOUT = `
"message": [ "Receiving message: {"type":"CTL","traceId":"f0d11b3dbf27b8fc57ac0e40c4ed9e48","spanId":"a5508acb0926fb1a","id":{"global":"GLkELDUjcRpP4srUt9yngY","caller":null,"local":"GLkELDUisjnGrSK5wKybht"},"eventVersion":"format version","timeStamp":"2021-10-01T14:55:59.8168722+07:00","eventMetadata":{"deleteTimeStamp":null,"ttlSeconds":null,"isFcra":null,"isDppa":true,"isCCPA":true,"globalProductId":null,"globalSubProductId":null,"mbsiProductId":null},"eventBody":{"sys":"otel","msg":"Testing Centralized Event Publisher with App1 (using logback)","app":{"name":"otel","service":"postHouse","status":"status name","method":"POST","protocol":"HTTP","resp_time_ms":"250","status_code":"4"},}}"
] }
`;
// Match JSON part string
let JSONstr = /.*\[\s*\"Receiving message:\s*(.*?)\s*\"\s*]\s*}\s*$/.exec(STDOUT)[1];
// Remove trailing comma(s)
JSONstr = JSONstr.replace(/^(.*\")([^\"]+)$/, (s, m1, m2) => `${m1}${m2.replace(/\,/, "")}`);
// Convert to object
const JSONobj = JSON.parse(JSONstr);
// Result
console.log(JSONobj);
Try this one:
/.*?({"type":.*?,"status_code":"\d+"\})/
When used in Javascript, the part covered by the parentheses counts as Group 1, i.e.,:
const messJson = JSON.parse(message.match(/.*?({"type":.*?,"status_code":"\d+"\})/)[1]);
Reference here: https://regexr.com/66mf2

ctx in ANTLR4 javascript visitor

Using ANTLR4 v4.8
I am in the process of writing transpiler exploring use of ANTLR (javascript target with visitor).
Grammar -> lex/parse is fine and I now sit on parse tree.
Grammar
grammar Mygrammar;
/*
* parser rules
*/
progm : stmt+;
stmt
: progdecl
| print
;
progdecl : PROGDECLKW ID '..';
print : WRITEKW STRLIT '..';
/*
* lexer rules
*/
PROGDECLKW : 'DECLAREPROGRAM';
WRITEKW : 'PRINT';
// Literal
STRLIT : '\'' .*? '\'' ;
// Identifier
ID : [a-zA-Z0-9]+;
// skip
LINE_COMMENT : '*' .*? '\n' -> skip;
TERMINATOR : [\r\n]+ -> skip;
WS : [ \t\n\r]+ -> skip;
hw.mg
***************
* Hello world
***************
DECLAREPROGRAM hw..
PRINT 'Hello World!'..
index.js
...
const myVisitor = require('./src/myVisitor').myVisitor;
const input = './src_sample/hw.mg';
const chars = new antlr4.FileStream(input);
...
parser.buildParseTrees = true;
const myVisit = new myVisitor();
myVisit.visitPrint(parser.print());
Use of visitor didn't seem straightforward, and this SO post helps to an extent.
On use of context. Is there a good way to track ctx, when I hit each node?
Using myVisit.visit(tree) as starting context is fine. When I start visiting each node, using non-root context
myVisit.visitPrint(parser.print()) throws me error.
Error:
PrintContext {
parentCtx: null,
invokingState: -1,
ruleIndex: 3,
children: null,
start: CommonToken {
source: [ [MygrammarLexer], [FileStream] ],
type: -1,
channel: 0,
start: 217,
together with exception: InputMismatchException [Error]
I believe it is because children is null instead of being populated.
Which, in turn, is due to
line 9:0 mismatched input '<EOF>' expecting {'DECLAREPROGRAM', 'PRINT'}
Question:
Is above the only way to pass the context or am I doing this wrong?
If the use is correct, then I incline towards looking at reporting this as bug.
edit 17.3 - added grammar and source
When you invoke parser.print() but feed it the input:
***************
* Hello world
***************
DECLAREPROGRAM hw..
PRINT 'Hello World!'..
it will not work. For print(), the parser expects input like this PRINT 'Hello World!'... For the entire input, you will have to invoke prog() instead. Also, it is wise to "anchor" your starting rule with the EOF token which will force ANTLR to consume the entire input:
progm : stmt+ EOF;
If you want to parse and visit an entire parse tree (using prog()), but are only interested in the print node/context, then it is better to use a listener instead of a visitor. Check this page how to use a listener: https://github.com/antlr/antlr4/blob/master/doc/javascript-target.md
EDIT
Here's how a listener works (a Python demo since I don't have the JS set up properly):
import antlr4
from playground.MygrammarLexer import MygrammarLexer
from playground.MygrammarParser import MygrammarParser
from playground.MygrammarListener import MygrammarListener
class PrintPreprocessor(MygrammarListener):
def enterPrint_(self, ctx: MygrammarParser.Print_Context):
print("Entered print: `{}`".format(ctx.getText()))
if __name__ == '__main__':
source = """
***************
* Hello world
***************
DECLAREPROGRAM hw..
PRINT 'Hello World!'..
"""
lexer = MygrammarLexer(antlr4.InputStream(source))
parser = MygrammarParser(antlr4.CommonTokenStream(lexer))
antlr4.ParseTreeWalker().walk(PrintPreprocessor(), parser.progm())
When running the code above, the following will be printed:
Entered print: `PRINT'Hello World!'..`
So, in short: this listener accepts the entire parse tree of your input, but only "listens" when we enter the print parser rule.
Note that I renamed print to print_ because print is protected in the Python target.

TinyMce 4 util.i18n.translate() usage

I try since hours and using the (very less helpful API documentation :S) to get translation for my plugin working.
tinymce.translate('Cut'); // returns Ausschneiden for de
So far, so good.
tinymce.translate('myplugin.test'); // returns myplugin.test
I checked tinymce.i18n.data and can see through inspector that it contains the data I added with
tinymce.addI18n('de.myplugin', {
"test": 'test label'
});
before.
This is probably something stupid but I can not figure it out.
UPDATE
I now add my own functionality to do it manually as I can not figure it out how to do it:
plugin_translate = function(val) {
return (eval('tinymce.i18n.data.' + tinymce.settings.language + '.' + val) != undefined)
? eval('tinymce.i18n.data.' + tinymce.settings.language + '.' + val)
: val;
}
And my plugin/langs/de.js looks like this
tinymce.addI18n('de', { 'plugin': { "title" : 'Titel' }});
This doesn't look right but at the moment it works until someone enlighten me.
Translations are registered using tinymce.addI18n(langCode, translationMap) or tinymce.util.I18n.add(langCode, translationMap).
The first parameter is a language code like "en", "en_US" or "de". This should be the same value used for the language init property. Note that you should not include the plugin prefix here.
The second parameter is a map of translation-key to translation pairs. The translations can take positional arguments like {0} and {1}. You should prefix your keys with your plugin name to avoid naming clashes. For example:
{
"myplugin.test": "test label",
"myplugin.greeting": "Hello {0}, you are welcome"
}
So combining all those parts together you might register English and German translations like:
tinymce.addI18n("en", {
"myplugin.title": "My Plugin",
"myplugin.greeting": "Hello {0}, you are welcome"
});
tinymce.addI18n("de", {
"myplugin.title": "Mein Plugin",
"myplugin.greeting": "Hallo {0}, du bist willkommen"
});
Then to use the translation call tinymce.translate(translationKey) which returns the translated string. For a string without arguments you can just pass the same key you used in the map. For example:
var title = tinymce.translate("myplugin.title");
If your translation has parameters you have to wrap the key up in an array. For example:
var name = getName(); // get the name from the user
var greeting = tinymce.translate(["myplugin.greeting", name]);
If for some reason you need to override the translation you can provide an object with a raw string. For example:
var name = getName(); // get the name from the user
var key = name === "James" ? {"raw": "Go away!"} : ["myplugin.greeting", name];
var greeting = tinymce.translate(key);

json converting characters to random charaters

Hi i have email address in my database e.g "abc#yahoo.co.in" and when I retrieve it i am getting the same on my controller as well before returning that object to client but when i alert that value on my java script page, "#" is converting to some random characters and not giving proper display. How can i solve this.?
server code :
enter code here
public AppUser findById(#FormParam("employeeId") String eId ){
int id=Integer.parseInt(eId);
AppUser appUser=null;
appUser= evaluatorService.findById(id);
return appUser;
}
while debugging appUser it is giving me proper data.
my client side code :
$.ajax({
type : 'GET',
url : 'rest/evaluator/fetchEvaluatorById',
data : {
'employeeId' : employeeId
},
success : function(data) {
$('#evaluatorDetailEdit').dialog({
width: 400,
height: 400,
});
alert(data.email);
$('#employeeId').val(data.employeeId);
$('#name').val(data.name);
$('#lastName').val(data.lastName);
$('#email').val(data.email);
}
});
There is some hacky jquery-workaround - maybe there are better solutions, but this should work:
var original = "#";
alert("Original: " + original);
// Hacky jquery-workaround:
// 1. pasting encoded text as html in a "virtual" textarea and
// 2. get the decoded text:
var decoded = $('<textarea/>').html(original).text();
alert("Decoded: " + decoded);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
According to your comment, every # are change to #.
In fact, # is the HTML entity to represent the character #.
You should convert (HTML entity decode) the character on your server.
For example, in PHP, just call this function on your email strings: http://php.net/manual/en/function.html-entity-decode.php

Javascript ADO recordset open method not working

I have the following code in an html page in a Javascript tag:
var adOpenDynamic = 2
var adLockOptimistic = 3
var conn_str = 'Provider=Microsoft.Jet.OLEDB.4.0; Data Source=G:/path_to_myDB.mdb'
var conn = new ActiveXObject("ADODB.Connection")
conn.open(conn_str)
and this is a the beginning of a function that is called from the onload event of the html :
var PassNbrAppel = new Array();
var i=1
var rsPass = new ActiveXObject("ADODB.Recordset")
SQLpass = 'SELECT Avis.[Numéro Passerelle], Count(Avis.[Numéro Passerelle]) AS [CompteDeNuméro Passerelle] FROM Avis WHERE (((Avis.[Date Appel])>#10/19/2011# And (Avis.[Date Appel])<#11/07/2011#) AND (Avis.[Numéro Passerelle] IS NOT NULL)) GROUP BY Avis.[Numéro Passerelle] ORDER BY Val(Avis.[Numéro Passerelle]);'
rsPass.open(SQLpass, conn, adOpenDynamic, adLockOptimistic)
rs2arr(rsPass,arrPass)
rs.close()
I get the following error message (translated from french): "no value given for one or more of the required parameters" and the line number is pointing to rsPass.open(SQLpass, conn, adOpenDynamic, adLockOptimistic)
I keep on re-checking to see if there is a mistake in the code but I can't seem to find anything wrong...
I took bits of code from here
The problem was the special characters in my SQL statement. Instead of trying to make it work with the "é" I changed the feild names so they dont have special characters. So much for French pride...

Categories