Pupulate Dom HTML fom JSON and coffeescript - javascript

I'm pretty new to coffee script.
I'm building a widget for Ubersicht
According to the documentation, I need to specify a command, an update interval and some style
So far, I have been able to tweak other existing widgets, but I've come to a roadblock when trying to create one of my own.
I want to iterate trhough a JSON array and populate a table.
I have tried following the example found here:
How to iterate through JSON hash with coffeescript
But I don't see what I'm doing wrong. The dom inspector throws an error saying there is an unexpected indent. I've been up all night trying to figure this out. Please help.
# ######################
# index.coffee
#######################
refreshFrequency: 5000
style: """
white1 = rgba(white,1)
white05 = rgba(white,0.5)
white02 = rgba(white,0.2)
black02 = rgba(black,0.2)
icon-size = 28px
//bottom 220px + 49
//right 0px
overflow hidden
#font-face
font-family Helvetica Neue
.user_data
color white1
white-space nowrap
width 176px
padding 8px 0
align-items center
display flex
.text,
font-size 8pt
font-weight 200
color white1
text-overflow ellipsis
"""
todayfile = '~/Desktop/today.txt'
command: "cat #{todayfile}"
render: -> """
<table class="user_data text"><br>
</table>
"""
update: (output, domEl) ->
dom = $(domEl)
data = JSON.parse output
alloc = data?.name?.user_name?.allocated_hours
for keys, values of data
text = '<tr><td>' + data.name[i] + '</td></tr>' + '<tr><td>' + data.user_name[i] + '</td></tr>' + '<tr><td>' + data.allocated_hours[i] + '</td></tr>'
dom.find(".user_data").innerHTML =
And the JSON file
{"results":[{"user_id":"63","user_name":"blueboy","name":" (Super Man)","allocated_hours":"7"},{"user_id":"510","user_name":"allblack","name":" (Batman)","allocated_hours":"7"},{"user_id":"418","user_name":"ladyinred","name":" (Wonder Woman)","allocated_hours":"8"}]}

refreshFrequency: 5000
This is not how you assign variables:
Variable assignment is with =, i.e. refreshFrequency = 5000
Assigning items in an Object is done with :, i.e.:
my_object =
refreshFrequency: 5000
You've repeated this error several times ;-) Note that you also use = for function assignment, so render: -> is also wrong and needs to be render = ->.
The indentation of your update function is off:
update: (output, domEl) ->
dom = $(domEl)
data = JSON.parse output
alloc = data?.name?.user_name?.allocated_hours
for keys, values of data
text = '<tr><td>' + data.name[i] + '</td></tr>' + '<tr><td>' + data.user_name[i] + '</td></tr>' + '<tr><td>' + data.allocated_hours[i] + '</td></tr>'
dom.find(".user_data").innerHTML =
Why is the line for keys, values of data on a new indentation level? The start of new block should never be on a new indentation level, only its contents.
Your script also ends abruptly with innerHTML =, which is incorrect.
Once I fixed the above errors, the file compiled ;-) This is, of course, no guarantee that it also does what you want ;-) I can't really make sense of the script, as such, and seems more like half a script...

Related

Extract data from Object Array

this is about image to text (OCR) converter using terrasect. Refering to a working codepen demo at here, I managed to extract the text using data.text in my code. May I ask how to extract the numbers (Highlighted in Green) which is 936 and 385 in my case? I have tried using data.html but does not work.
I will aprreciate any help I can get. You will have to upload an image with words for it to work since it is an OCR Reader.
Image with text:
https://i.ibb.co/gZLWbjC/dog.jpg
function result(data){
var r = $(".result");
console.log(data);
r.append(
"<div class='sixteen wide column output'>success" +
"<div class='ui message'><pre>" + data.text +"</pre></div>" +
"</div>"
);
}
You could use DOMParser to parse the HTML and then get the page_1 element and then get its title. After that, you could parse the title to get the numbers by selecting the numbers between bbox and ;, then you could take the third and fourth number.
Modify the function result(data) to this:
function result(data){
var r = $(".result");
const parser = new DOMParser();
const parsed = parser.parseFromString(data.html, 'text/html');
const firstOccurrence = parsed.getElementById('page_1').getAttribute('title');
const numbers = firstOccurrence.split('bbox ')[1].split(';')[0].split(' ');
console.log("green numbers:", numbers[2], numbers[3])
r.append(
"<div class='sixteen wide column output'>success" +
"<div class='ui message'><pre>" + data.text +"</pre></div>" +
"</div>"
);
}
Here is the working fork codepen.

Trying to email a PDF of a single Google Sheet [duplicate]

For almost a year we have been using the below code to export a Google Sheets sheet (held in theSheetName) to a PDF named as specified in InboundID.
This last week, one at a time various users can no longer produce the PDF. I get a failure at the line containing "var newFile = DriveApp.createFile(blob);" with the error being:
"Conversion from text/html to application/pdf failed."
And sure enough, the UrlFetchApp.fetch is returning HTML instead of a PDF. Again, only for some users. Does anyone have any thoughts as to why my users might be seeing this?
function sendPDFToDrive(theSheetName, InboundID)
{
var theSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var theSpreadsheetId = theSpreadSheet.getId();
var thisSheetId = theSpreadSheet.getSheetByName(theSheetName).getSheetId();
var url_base = theSpreadSheet.getUrl().replace(/edit$/,'');
var theOutFileName = "GASFILE_M_" + (Math.floor(Math.random() * 8997) + 1000) + '.pdf'
//export as pdf
var url_ext = 'export?exportFormat=pdf&format=pdf'
+ (thisSheetId ? ('&gid=' + thisSheetId) : ('&id=' + theSpreadsheetId))
// following parameters are optional...
+ '&size=A4' // paper size
+ '&scale=2' // 1= Normal 100% / 2= Fit to width / 3= Fit to height / 4= Fit to Page
+ '&portrait=true' // orientation, false for landscape
+ '&horizontal_alignment=CENTER' //LEFT/CENTER/RIGHT
+ '&fitw=true' // fit to width, false for actual size
+ '&sheetnames=false&printtitle=false&pagenumbers=false' //hide optional headers and footers
+ '&gridlines=true' // hide gridlines
+ '&printnotes=false' // don't show notes
+ '&fzr=true'; // repeat row headers (frozen rows) on each page
// Setup options
var options =
{
headers:
{
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
}
}
// Build the file
var response = UrlFetchApp.fetch(url_base + url_ext, options);
var blob = response.getBlob().setName(theOutFileName);
var folder = DriveApp.getFolderById("ABC123FooBarID");
var newFile = DriveApp.createFile(blob); //Create a new file from the blob
newFile.setName(InboundID + ".pdf"); //Set the file name of the new file
newFile.makeCopy(folder);
}
I was having this exact problem. After some debugging I saw that my URL was being created incorrectly.
My code was nearly identical to yours. Where I found the culprit was the following line:
var url_base = theSpreadSheet.getUrl().replace(/edit$/,'');
This was not actually clearing out the 'edit' to the end of the line like it had for years. I cannot say why this is, but the proof was in the logs. So, instead I crafted the url by hand:
var url = 'https://docs.google.com/spreadsheets/d/'+SpreadsheetApp.getActiveSpreadsheet().getId()+'/';
This seemed to solve the problem. This is not a perfect futureproof resolution, because if Google changes how the URLs are crafted, this will fail. But it works for now.
I hope this helps. You can send the url your code is creating to logs and check them to see if you have the same issue I did.
To expand on Jesse's accepted answer - the culprit is definitely in this line:
var url_base = theSpreadSheet.getUrl().replace(/edit$/,'');
The reason why the replace(/edit$/,'') call no longer clears out edit like before is because the URL returned by theSpreadSheet.getUrl() used to end with edit, but now returns a URL with additional parameters on the end - ouid=1111111111111111111111&urlBuilderDomain=yourdomain.com.
While rebuilding the URL entirely should also work, you can also patch the script with some small changes to the regular expression. Instead of looking for edit$ (meaning edit as the final characters in the string), you can look for edit + any additional characters like so:
var url_base = theSpreadSheet.getUrl().replace(/edit.*$/,'');
better also avoid using comma for the last property of the header pointing below:
-- 'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(), --

SPARX Enterprise Architect. Add Note to Diagram with formatted text using Scripting

I'm trying to add a note to a diagram with formatted text similar to the Diagram Properties
I tried
dgmElement.Notes = currentPackage.Elements.AddNew("","Text");
and
dgmElement.Notes = currentPackage.Elements.AddNew("", "Note");
dgmElement.Notes
= "Classification:" + "UNCLASSIFIED" + String.fromCharCode(13)
+ "Model Type: " + "SV1-SFFSESVSE SEASDEAER" + String.fromCharCode(13)
+ "Diagram Status:" + "APPPROVED" + String.fromCharCode(13)
+ "Date Modified: " + currentDiagram.ModifiedDate + String.fromCharCode(13) ;
but neither returns the desired format.
Both are possible. EA renders a note frame around a note. Text will appear without a frame.
Formatting like in the diagram properties can be achieved by adding tab chars. For "advanced" formatting like bold text you need to use the repository operations GetFieldFromFormat and GetFormatFromField (see the help) to convert the text from and to EA's internal memo format.
This is a Python example but you can probably translate it to your target language:
dia = rep.getDiagramByGUID("{81B59BAD-B22F-4375-AA73-C489958A3D6B}")
pck = rep.getPackageByID(dia.packageID)
text = pck.elements.addNew("", "Text")
text.notes = rep.getFieldFromFormat("TXT", "a\tb\r\nc\td")
# note the \r\n for a newline. Windoze
text.update
dobj = dia.diagramObjects.addNew("l=10;r=110;t=-20;b=-80", "") # coord. on diagram
dobj.elementID = text.elementId
dobj.update
rep.reloadDiagram (dia.diagramID)
In the above example the text could as well have been assigned directly to text.notes since it's a simple case. However, you could as well supply rtf or html this way and txt would be formatted regarding special chars.

Replace array-mapped variables with the actual variable name/string?

I am trying to edit a Greasemonkey/jQuery script. I can't post the link here.
The code is obfuscated and compressed with minify.
It starts like this:
var _0x21e9 = ["\x67\x65\x74\x4D\x6F\x6E\x74\x68", "\x67\x65\x74\x55\x54\x43\x44\x61\x74\x65", ...
After "decoding" it, I got this:
var _0x21e9=["getMonth","getUTCDate","getFullYear", ...
It is a huge list (500+ ). Then, it has some variables like this:
month = date[_0x21e9[0]](), day = date[_0x21e9[1]](), ...
_0x21e9[0] is getMonth, _0x21e9[1] is getUTCDate, etc.
Is it possible to replace the square brackets with the actual variable name? How?
I have little knowledge in javascript/jQuery and can not "read" the code the way it is right now.
I just want to use some functions from this huge script and remove the others I do not need.
Update: I tried using jsbeautifier.org as suggested here and in the duplicated question but nothing changed, except the "indent".
It did not replace the array variables with the decoded names.
For example:
jsbeautifier still gives: month = date[_0x21e9[0]]().
But I need: month = date["getMonth"]().
None of the online deobfuscators seem to do this, How can I?
Is there a way for me to share the code with someone, at least part of it? I read I can not post pastebin, or similar here. I can not post it the full code here.
Here is another part of the code:
$(_0x21e9[8] + vid)[_0x21e9[18]]();
[8] is "." and [18] is "remove". Manually replacing it gives a strange result.
I haven't seen any online deobfuscator that does this yet, but the principle is simple.
Construct a text filter that parses the "key" array and then replaces each instance that that array is referenced, with the appropriate array value.
For example, suppose you have a file, evil.js that looks like this (AFTER you have run it though jsbeautifier.org with the Detect packers and obfuscators? and the Unescape printable chars... options set):
var _0xf17f = ["(", ")", 'div', "createElement", "id", "log", "console"];
var _0x41dcx3 = eval(_0xf17f[0] + '{id: 3}' + _0xf17f[1]);
var _0x41dcx4 = document[_0xf17f[3]](_0xf17f[2]);
var _0x41dcx5 = _0x41dcx3[_0xf17f[4]];
window[_0xf17f[6]][_0xf17f[5]](_0x41dcx5);
In that case, the "key" variable would be _0xf17f and the "key" array would be ["(", ")", ...].
The filter process would look like this:
Extract the key name using text processing on the js file. Result: _0xf17f
Extract the string src of the key array. Result:
keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]';
In javascript, we can then use .replace() to parse the rest of the JS src. Like so:
var keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]';
var restOfSrc = "var _0x41dcx3 = eval(_0xf17f[0] + '{id: 3}' + _0xf17f[1]);\n"
+ "var _0x41dcx4 = document[_0xf17f[3]](_0xf17f[2]);\n"
+ "var _0x41dcx5 = _0x41dcx3[_0xf17f[4]];\n"
+ "window[_0xf17f[6]][_0xf17f[5]](_0x41dcx5);\n"
;
var keyArray = eval (keyArrayStr);
//-- Note that `_0xf17f` is the key name we already determined.
var keyRegExp = /_0xf17f\s*\[\s*(\d+)\s*\]/g;
var deObsTxt = restOfSrc.replace (keyRegExp, function (matchStr, p1Str) {
return '"' + keyArray[ parseInt(p1Str, 10) ] + '"';
} );
console.log (deObsTxt);
if you run that code, you get:
var _0x41dcx3 = eval("(" + '{id: 3}' + ")");
var _0x41dcx4 = document["createElement"]("div");
var _0x41dcx5 = _0x41dcx3["id"];
window["console"]["log"](_0x41dcx5);
-- which is a bit easier to read/understand.
I've also created an online page that takes JS source and does all 3 remapping steps in a slightly more automated and robust manner. You can see it at:
jsbin.com/hazevo
(Note that that tool expects the source to start with the "key" variable declaration, like your code samples do)
#Brock Adams solution is brilliant, but there is a small bug: it doesn't take into account simple quoted vars.
Example:
var _0xbd34 = ["hello ", '"my" world'];
(function($) {
alert(_0xbd34[0] + _0xbd34[1])
});
If you try to decipher this example, it will result on this:
alert("hello " + ""my" world")
To resolve this, just edit the replacedSrc.replace into #Brock code:
replacedSrc = replacedSrc.replace (nameRegex, function (matchStr, p1Str) {
var quote = keyArry[parseInt (p1Str, 10)].indexOf('"')==-1? '"' : "'";
return quote + keyArry[ parseInt (p1Str, 10) ] + quote;
} );
Here you have a patched version.
for (var i = 0; i < _0x21e9.length; i++) {
var funcName = _0x21e9[i];
_0x21e9[funcName] = funcName;
}
this will add all the function names as keys to the array. allowing you to do
date[_0x21e9["getMonth"]]()

eval javascript function IE6 taking long time

I have the below chunk of code. I've debugged through and located the snippet that is causing a long delay in IE6.
Basically the code loops through a document converting it to XML and sending to a PDF. On Ubuntu and Firefox 4 it takes 3 seconds. On IE it can take up to 40 seconds regularly.
/**
* This function builds up the XML to be saved to the DM.
*/
function getXMLToSave(){
var text="<workbook><sheet><name>Adv4New</name>";
//show_props(document.adv4.row10col1, "document.adv4.row10col1");
for(i=1;i<157;i++){
text = text + "<row number='" + i + "'>";
for(j=1;j<=7;j++){
text = text + "<col ";
//alert(eval('document.adv4.row'+i+'col'+j+'.readonly'));
try{
text = text + "number='" + j + "' label='" + eval('document.adv4.row'+i+'col'+j+'.className')+ "'";
}
catch (e) {
text = text + "number='" + j + "' label=''";
}
try {
if(eval('document.adv4.row'+i+'col'+j).readOnly)
text = text + " type='readonly'";
else
text = text + " type=''";
}
catch (e) {
text = text + " type=''";
}
try {
text = text + " color='" + eval('document.adv4.row'+i+'col'+j+'.style.color') + "'";
}
catch (e) {
text = text + " color=''";
}
text = text + ">";
try {
// don't wrap in a CDATA (like previously), but run cleanNode
// this fixes html entities
var content = eval('document.adv4.row'+i+'col'+j+'.value');
text = text + cleanNode(content);
}
catch (e) {
text = text + "0";
}
text = text + "</col>";
}
text = text + "</row>";
}
text = text + "</sheet></workbook>";
return text;
}
I believe its the eval function causing the delay in IE6. Is there a neat solution to fix this. Thanks very much
Why are you using eval in the firts place?
eval('document.adv4.row'+i+'col'+j+'.style.color')
Use bracket notation!
document.adv4["row"+i+"col"+j].style.color
You don't need eval() at all:
text = text + "number='" + j + "' label='" + document.adv4['row' + i + 'col' + j].className + "'";
Also, in IE6 (but not in newer browsers), building up large strings by repeatedly adding more content is really, really slow. It was way faster in that browser to build up strings by creating an array of substrings and then joining them all together when finished with all the pieces.
Don't use eval EVAL is EVIL. Having said that, you really shouldn't care about IE6: Even MS doesn't support it any longer, why should you bother?
Anyhow, change all eval calls like:
eval('document.adv4.row'+i+'col'+j+'.value');
to
document.adv4['row' + i + 'col' + j].value;
To access the elements directly. Remember that Nodes are objects, so their properties can be accessed either using the dot-notation (foo.bar) or the "associative array" notation: foo['bar'], the latter being very useful when you need the value of a variable to access properties
Don't use eval - period. The eval() should be renamed to evil(). There is almost no situation where you really need to use the eval function.
In this case you can use document.getElementById() to find a DOM node with a specific id.
It's likely that it's all the string concatentation that makes it slow. Each time you add something to the text, it will copy all the previous text into a new string.
Newer browsers have optimised code for this special case, so for them the impact is less.
Instead of concatenating strings like this:
text = text + "something";
use an array instead:
var text = [];
then add items to the array using the push method:
text.push("<workbook><sheet><name>Adv4New</name>");
Finally just join the strings together:
return text.join('');
One solution could be generating a color array (or maybe an object if you need it) and then using it.
But then, ask yourself the question "Should I really support IE6?"

Categories

Resources