i want log my user command
function saveLog (nick, command) {
var file = 'log/' + nick + '.log';
var datetime = '[' + getDateTime() + '] ';
var text = datetime + command + '\r\n';
fs.writeFile(file, text, function (err) {
if (err) return console.log(err);
console.log(text);
});
}
the function i made is fine, but
it didnt save the log in new line, its just replace text / rewrite the file.
whats im missing ?
thanks
fs.writeFile writes a WHOLE NEW file. What your are looking for is fs.appendFile which will make the file if it doesn't exist and append to it. Documentation here.
function saveLog (nick, command) {
var file = 'log/' + nick + '.log';
var datetime = '[' + getDateTime() + '] ';
var text = datetime + command + '\r\n';
fs.appendFile(file, text, function (err) {
if (err) return console.log(err);
console.log('successfully appended "' + text + '"');
});
}
Related
Good day StackOverflow, I am currently integrating a credit check SOAP API, I was given some sample code without a package.json file, so I have no idea as to the development environment. Here is the sample code I was given:
var request = require('request');
var fs = require('fs');
var bsplit = require('buffer-split');
//process.env.http_proxy = 'http://host:port';
var xmlData = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webServices/">' +
'<soapenv:Header/>' +
'<soapenv:Body>' +
' <web:DoNormalEnquiryStream>' +
' <request>' +
' <pUsrnme>*****</pUsrnme>' +
' <pPasswrd>*****</pPasswrd>' +
' <pVersion>1.0</pVersion>' +
' <pOrigin>QA-SOAPUI</pOrigin>' +
' <pOrigin_Version>1.0</pOrigin_Version>' +
' <pInput_Format>XML</pInput_Format>' +
' <pTransaction>' +
' <![CDATA[<Transactions>' +
' <Search_Criteria>' +
' <CS_Data>Y</CS_Data>' +
' <CPA_Plus_NLR_Data>Y</CPA_Plus_NLR_Data>' +
' <Deeds_Data>N</Deeds_Data>' +
' <Directors_Data>N</Directors_Data>' +
' <Identity_number></Identity_number>' +
' <Surname></Surname>' +
' <Forename></Forename>' +
' <Forename2/>' +
' <Forename3/>' +
' <Gender>M</Gender>' +
' <Passport_flag>N</Passport_flag>' +
' <DateOfBirth>19820914</DateOfBirth>' +
' <Address1></Address1>' +
' <Address2></Address2>' +
' <Address3/><Address4/>' +
' <PostalCode></PostalCode>' +
' <HomeTelCode/>' +
' <HomeTelNo/>' +
' <WorkTelCode/>' +
' <WorkTelNo/>' +
' <CellTelNo/>' +
' <ResultType>JPDF2</ResultType>' +
' <RunCodix>N</RunCodix>' +
' <Adrs_Mandatory>N</Adrs_Mandatory>' +
' <Enq_Purpose>12</Enq_Purpose>' +
' <Run_CompuScore>N</Run_CompuScore>' +
' <ClientConsent>Y</ClientConsent>' +
' </Search_Criteria>' +
' </Transactions>]]>' +
' </pTransaction>' +
' </request>' +
' </web:DoNormalEnquiryStream>' +
' </soapenv:Body>' +
' </soapenv:Envelope>';
request({
url: "api.myapiurl.com/soap-api",
encoding:null,
method: "POST",
headers: {
"content-type": "text/xml"
},
body: xmlData
}, function (error, response, body){
var delim = new Buffer('--uuid');
var result = bsplit(body,delim);
var attBuffs = [];
var attBuffsStartIndex = [];
for(var i = 0; i < result.length; i++){
if(result[i].toString().indexOf("Content-Type: application/octet-stream") > 0){
attBuffs.push(result[i]);
var trimmedString = result[i].toString();
attBuffsStartIndex.push(trimmedString.indexOf("Content-Transfer-Encoding: binary")+37);
}
}
fs.open('JsonFile.json', 'w', function (err, fd) {
if (err) {
throw 'error opening file: ' + err;
}
fs.write(fd, attBuffs[0], attBuffsStartIndex[0], attBuffs[0].length - attBuffsStartIndex[0], null, function (err) {
if (err) throw 'error writing file: ' + err;
fs.close(fd, function () {
console.log('JSON File written to file');
})
});
});
fs.open('PdfFile.pdf', 'w', function (err, fd) {
if (err) {
throw 'error opening file: ' + err;
}
fs.write(fd, attBuffs[1], attBuffsStartIndex[1], attBuffs[1].length - attBuffsStartIndex[1], null, function (err) {
if (err) throw 'error writing file: ' + err;
fs.close(fd, function () {
console.log('PDF File written to file');
})
});
});
});
I am having some difficulty getting this code to run. I thought it might need the [RequireJS API], but after doing some research I strongly believe it's actually the Request HTTP Client. I really struggling to get this sample code running. Any assistance would be greatly appreciated!
Addition
I am aware that this is it requires nodejs. But I have not been able to figure out how to progress from there.
Addition
If anyone is interested native node modules such as net, fs etc are not meant to be run from a browser, so this code will not work anyway.
1. Create a project directory
mkdir ~/projects/credit
(If ~/projects doesn't exist, create it with mkdir ~/projects first or create the new directory wherever you want.)
2. Change to the new directory
cd ~/projects/credit
2. Create a file for your sample code
touch sample.js
3. Paste in your sample code in the sample.js file
4. Install the request and buffer-split packages
npm install request buffer-split
This should generate a package.json file in your new project directory, along with the node_modules directory with the installed modules.
5. Run the file
Assuming you have Node installed...
node sample.js
I want to modify some cells in a CSV file and first read the file and get the data of the part I want. However there is a problem when it saves in that it flattens the rows and also turns the ; characters into , also adding an extra comma to the line I modify.
How can I modify and save a certain cell's data?
var fs = require('fs');
var parse = require('csv-parse');
var parser = parse({delimiter: ';'}, function(err, data){
var row0 = '' + data[0];
var index = row0.split(',')[0];
data[0] = index + ';' + 'Modified Cell Here' + ',' + row0.split(',')[2];
fs.writeFile("./Sample.csv", data, function(err) { if(err) { return console.log(err); }});
console.log(data);
});
fs.createReadStream(__dirname+'/Sample.csv').pipe(parser);
The Sample.csv is:
0;123,abc
1;456,efg
2;789,hij
In the modified Sample.csv it returns as:
0;Modified Cell Here,abc,1,456,efg,2,789,hij
I was expecting this:
0;Modified Cell Here,abc
1;456,efg
2;789,hij
I suspect you could join the array back with a newline before writing
snip::
data[0] = index + ';' + 'Modified Cell Here' + ',' + row0.split(',')[2];
var outputData = data.join('\n') ;
fs.writeFile("./Sample.csv", outputData, function(err) { if(err) { return console.log(err); }});
::snip
I've a following situation:
I've an appendToFile() function that I wrote:
function appendToFile(text, file) {
(function (e) {
freeze();
FileUtils.readAsText(file)
.done(function (data) {
console.log("File data: " + data);
console.log("File text: " + e);
var text = data + e;
FileUtils.writeText(file, text, true)
.done(function () {
console.log("File saved. Text: " + text);
unfreeze();
//window.alert("File saved. Text: " + text);
})
.fail(function (err) {
console.error(err);
window.alert(err);
});
})
.fail(function (err) {
console.error(err);
});
})(text);
}
This function needs to append some text to a file. It is called from this function:
function processAttrs(clazz) {
//window.alert("Hello" + clazz.name + " " + clazz.length);
var file = FileSystem.getFileForPath("/Users/XXX/" + clazz.name + ".txt");
createFile(file, function () {
for (var i=0; i<clazz.attributes.length; i++) {
var attr = clazz.attributes[i];
var text = "private " + attr.type + " " + attr.name + "\n";
appendToFile(text, file);
}
});
}
The problem is that FileUtils.readAsText(file) is called asynchronously, so some lines that need to be written to a file get lost.
freeze() and unfreeze() are just empty functions where I thought about implementing something to stop and resume the code execution, but this mechanism doesn't seem to exist in Javascript.
I thought about using a callback as I did with createFile(file) function. The problem is that I don't know what to pass in as a callback function since the code execution is inside the for loop.
I could think of the solution without the for loop, and handling the flow manually using callbacks, but I don't like it. There have to be a more elegant solution
There is couple approaches to solve this problem. You can use async/await
so you can "block" your loop
function appendToFile(text, file) {
return new Promise((resolve, reject) => {
(function (e) {
//...
})(text);
});
}
async function processAttrs(clazz) {
//window.alert("Hello" + clazz.name + " " + clazz.length);
var file = FileSystem.getFileForPath("/Users/XXX/" + clazz.name + ".txt");
createFile(file, async function () {
for (var i=0; i<clazz.attributes.length; i++) {
var attr = clazz.attributes[i];
var text = "private " + attr.type + " " + attr.name + "\n";
const result = await appendToFile(text, file);
}
});
}
Or some kind of promise waterfall like shown here Is Node.js native Promise.all processing in parallel or sequentially?
Change your code and use the async/await syntax, like this.
async function appendToFile(text, file) {
try {
freeze();
var data = await FileUtils.readAsText(file)
console.log("File data: " + data);
console.log("File text: " + text);
var text = data + text;
await FileUtils.writeText(file, text, true)
console.log("File saved. Text: " + text);
unfreeze();
return;
} catch (e) {
console.log('Error', e)
}
}
function processAttrs(clazz) {
var file = FileSystem.getFileForPath("/Users/XXX/" + clazz.name + ".txt");
createFile(file, async function () {
for (var attr of clazz.attributes) {
var text = "private " + attr.type + " " + attr.name + "\n";
await appendToFile(text, file) //This will stop the loop until each file is completed
}
})
}
I have my selenium test set up to take screenshots, but they are not saving to the directory which I have specified. Can anybody show me what I am missing?
Here is how I am configuring the screenshots in the test:
function writeScreenshot(data, name) {
var fs = require('fs');
name = name || 'ss.png';
var screenshotPath = mkdirp(configuration.readSettings('screenshotDirectory') + fileNameURL + "/", function(err){});
fs.writeFileSync(screenshotPath + name, data, 'base64');
};
and then I take the screenshot:
driver.takeScreenshot().then(function(data) {
var screenshotFile = os + '_' + osVersion + '_' + browser + '_' + browserVersion + '.png';
writeScreenshot(data, screenshotFile);
});
The screenshots end up being saved instead in the projects root directory and with the file name preceded by 'undefined'. (ex. undefinedWindows_8_chrome_46.png)
It does, however, create the folders shown here: var screenshotPath = mkdirp(configuration.readSettings('screenshotDirectory') + fileNameURL + "/", function(err){});
So why is this happening?
mkdirp() is an async method. That is why you pass a callback. You will need to change your code to something like the following:
function writeScreenshot(data, name) {
var fs = require('fs');
name = name || 'ss.png';
var screenshotPath = configuration.readSettings('screenshotDirectory') + fileNameURL + "/";
mkdirp(screenshotPath, function(err){
if (err) {
// something else happened while creating the dir. You decide what to do
return;
}
// Otherwise (if dir was created)
fs.writeFileSync(screenshotPath + name, data, 'base64');
});
};
mkdirp() function is asynchronous - it creates a directory and returns nothing - this is why you having that leading undefined in the filename.
Save the file in the callback:
var screenshotPath = configuration.readSettings('screenshotDirectory') + fileNameURL + "/";
mkdirp(screenshotPath, function (err) {
if (!err) {
fs.writeFileSync(screenshotPath + name, data, 'base64');
} else {
// handle error
}
});
Or, synchronously create the directory and write to it this way:
var screenshotPath = configuration.readSettings('screenshotDirectory') + fileNameURL + "/";
if (mkdirp.sync(screenshotPath)) {
fs.writeFileSync(screenshotPath + name, data, 'base64');
}
I have a function that defines a variable and I would like to use the value in the next function. Each function has it's own query. I think I either need to combine the queries into one function, of which I don't know how to do or setup a global variable with the first query so it can be referenced in the second function.
I've been reading that global variables and they say they're not a good practice. Can someone help me with how to reuse a variable from one function to the next or combine the two queries else another JS method I should consider?
google.setOnLoadCallback(queryValue1);
function queryValue1 () {
var query2 = new google.visualization.Query('https://spreadsheets.google.com/spreadsheet/tq?range=A2:A17&key=0AhCv9Xu_eRnSdFNhSzNQUFd3b1ZfRHgtQURINFpzeGc&gid=9');
query2.send(function (response) {
if (response.isError()) {
alert('Error in query2: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data1 = response.getDataTable();
// fetch the data from range cell (row, column) into the span "bx"
for (var z = 0; z <= 15; z++) {
document.getElementById('a' + (z + 22)).innerHTML = data1.getValue(z, 0);
}
});
}
google.setOnLoadCallback(queryValue3);
function queryValue3 () {
var query3 = new google.visualization.Query('https://spreadsheets.google.com/spreadsheet/tq?range=B2:B17&key=0AhCv9Xu_eRnSdFNhSzNQUFd3b1ZfRHgtQURINFpzeGc&gid=10');
query3.send(function (response) {
if (response.isError()) {
alert('Error in query3: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data3 = response.getDataTable();
var m1 = data3.getValue(0, 0);
var red22 = "<span style='color:#ff0000' ";
var yellow22 = "<span style='color:#FF9900' ";
var green22 = "<span style='color:#009900' ";
if (m1 <= 70)
{
m1 = red22;
}
else if (71 === m1 && m1 <= 89)
{
m1 = yellow22;
}
else if (m1 >=90)
{
m1 = green22;
}
console.log ("m1= " + m1)
var m1 = (m1 + a22 + "</span>");
console.log ("m1= " + m1)
});
}
Thank you...
As it is, your making two essentially parallel asynchronous network calls (the Query.send() calls). There's no telling which one is going to return first (or if one will fail), so relying in one callback on data from the other is unreliable and a bad idea, no matter whether you use a global variable or something else.
I think you probably just want to chain the two asynchronous calls, so try something of this shape:
google.setOnLoadCallback(queryValue1);
function queryValue1 () {
var query2 = new google.visualization.Query('https://spreadsheets.google.com/spreadsheet/tq?range=A2:A17&key=0AhCv9Xu_eRnSdFNhSzNQUFd3b1ZfRHgtQURINFpzeGc&gid=9');
query2.send(function (response) {
if (response.isError()) {
alert('Error in query2: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
// Get the data you want to pass to query3 here
// var query3Data = ...
queryValue3(query3Data);
});
}
function queryValue3(passedData) {
var query3 = new google.visualization.Query('https://spreadsheets.google.com/spreadsheet/tq?range=B2:B17&key=0AhCv9Xu_eRnSdFNhSzNQUFd3b1ZfRHgtQURINFpzeGc&gid=10');
query3.send(function (response) {
if (response.isError()) {
alert('Error in query3: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
// Do something with passedData here
// ...
});
}
So don't start the second query until the first one returned.