I am unable to read multiple rows from xlsx file - node.js

I am trying to read multiple rows from xlsx file. My xlsx sheet contains various details one of which is an FTP directory, password detail.
Each row contains a different FTP directory.
I am able to read, fetch and retrieve the data from FTP if only one row is mentioned in the sheet
but as soon as I add an extra row to be read it starts showing promise error,
Below is my code
dataJson1 is the excel sheet(JSON)
for (let i = 0; i < dataJson1.length; i++) {
dir = dataJson1[i]['FTP DIR'];
subfolder = dataJson1[i]['Sub Folder'];
ftpPath = dir + subfolder;
host = dataJson1[i]['FTP IP'];
user = dataJson1[i]['FTP Username'];
password = dataJson1[i]['FTP Password'];
ticketStatus = dataJson1[i]['Status']
console.log("FTP LOCATION:" + ftpPath + "\n" + "HOSTNAME:" + host + "\n" + "USERNAME:" + user + "\n" + "PASSWORD:" + password + "\n")
//Reading the list of directories present in the FTP location
console.log("value of i" + i);
///////////
if (ticketStatus == true) {
if (!ftp) {
ftp = new PromiseFtp();
}
const ftpPromise = ftp.connect({
host: host, user: user,
password: password
}).then(function (serverMessage) {
console.log('Server message: ' + serverMessage)
//console.log("value of i" + i)
return ftp.list(ftpPath);
}).then(function (list) {
console.log('Directory listing:');
var dirList = (list)
console.log(dirList)
console.log("Number of directories:" + dirList.length)
var jsondirString = JSON.stringify(dirList)
var datadirJson1 = JSON.parse(jsondirString)
for (var j = 0; j < dirList.length; j++) {
//console.log(datadirJson1[j]['name'])
ticketName.push(datadirJson1[j]['name'])
//console.log(ftpTime)
ftpTime.push(datadirJson1[j]['date'])
}
return ftp.end();
});
promises.push(ftpPromise)
}//status check ends
}//Loop ends here
Promise.all(promises).then(arrayOfResults => {
console.log(ticketName);
var ticketNameArr = [];
for (let i = 0; i < ticketName.length; i++) {
let ticketNameIs = ticketName[i];
let ftpTimeIs = ftpTime[i]
let ticketDetail = ticketApp(ticketNameIs, ftpTimeIs);
Promise.all(ticketDetail).then(function (values) {
//console.log(values);
ticketNameArr.push({
// FtpTime: values[0].ftpTime,
Date: values[0].ftpTime,
TicketName: ticketNameIs,
//Add Dynamic folder column----
In_Input_Location: values[0].ticketStatusInput,
Input_Time: values[0].mtime,
In_Result_Location: values[1].ticketStatusResult,
Result_Time: values[1].mtime,
//Will help in preparing comments
CallAPi: values[3].apiStatus,
ReportStatus: values[3].reportStatus,
Comment: values[4].Comment,
Status: values[5].ticketStatus
// LogStatus: values[2].logStatus,
// LogCreateTime: values[2].birthtime,
// LogModifiedTime: values[2].mtime,
});
if (ticketNameArr.length == ticketName.length) {
//uncomment below command if sheet is blank then comment back
// ws = XLSX.utils.sheet_add_json(ws, ticketNameArr,{origin:0, skipHeader:false});
//comment below command if sheet is blank then uncomment
ws = XLSX.utils.sheet_add_json(ws, ticketNameArr, { origin: -1, skipHeader: true });
//
let wsRemDup = removeDuplicate(ws)
console.log("Unique Data", wsRemDup)
//OverWriting Unique data
wb.Sheets[first_sheet_name] = XLSX.utils.json_to_sheet(wsRemDup);
XLSX.writeFile(wb, 'DailyTicketSatus.xlsx')
// respond.render('result', { "ticketNameArr": ticketNameArr });
respond.render('index', { "ticketNameArr": ticketNameArr });
}
});
}
})
})```

I would suggest using the async/await syntax for this task, it's easier to read and you can ensure that the ftp.end() call is complete before proceeding to the next ftp host. This is probably the reason why the original code is failing to process more than one row.
async function runFTPJob(dataJson1) {
let promises = [];
for (let i = 0; i < dataJson1.length; i++) {
dir = dataJson1[i]['FTP DIR'];
subfolder = dataJson1[i]['Sub Folder'];
ftpPath = dir + subfolder;
host = dataJson1[i]['FTP IP'];
user = dataJson1[i]['FTP Username'];
password = dataJson1[i]['FTP Password'];
ticketStatus = dataJson1[i]['Status']
console.log("Getting row:", i);
console.log("FTP LOCATION:" + ftpPath + "\n" + "HOSTNAME:" + host + "\n" + "USERNAME:" + user + "\n" + "PASSWORD:" + password + "\n")
//Reading the list of directories present in the FTP location
if (ticketStatus == true) {
if (!ftp) {
ftp = new PromiseFtp();
}
try {
let ftpPromise = ftp.connect({ host, user, password });
promises.push(ftpPromise);
let serverMessage = await ftpPromise;
console.log('Server message: ' + serverMessage)
let dirList = await ftp.list(ftpPath);
console.log('Directory listing:', dirList);
console.log("Number of directories:" + dirList.length)
for (let dirEntry of dirList) {
ticketName.push(dirEntry.name);
ftpTime.push(dirEntry.date);
}
await ftp.end();
} catch (e) {
console.error("An error occurred accessing ftp site:", e.message);
}
}//status check ends
}//Loop ends here``
return promises;
}
function processTickets() {
console.log(ticketName);
var ticketNameArr = [];
for (let i = 0; i < ticketName.length; i++) {
let ticketNameIs = ticketName[i];
let ftpTimeIs = ftpTime[i]
let ticketDetail = ticketApp(ticketNameIs, ftpTimeIs);
Promise.all(ticketDetail).then(function (values) {
//console.log(values);
ticketNameArr.push({
// FtpTime: values[0].ftpTime,
Date: values[0].ftpTime,
TicketName: ticketNameIs,
//Add Dynamic folder column----
In_Input_Location: values[0].ticketStatusInput,
Input_Time: values[0].mtime,
In_Result_Location: values[1].ticketStatusResult,
Result_Time: values[1].mtime,
//Will help in preparing comments
CallAPi: values[3].apiStatus,
ReportStatus: values[3].reportStatus,
Comment: values[4].Comment,
Status: values[5].ticketStatus
// LogStatus: values[2].logStatus,
// LogCreateTime: values[2].birthtime,
// LogModifiedTime: values[2].mtime,
});
if (ticketNameArr.length == ticketName.length) {
//uncomment below command if sheet is blank then comment back
// ws = XLSX.utils.sheet_add_json(ws, ticketNameArr,{origin:0, skipHeader:false});
//comment below command if sheet is blank then uncomment
ws = XLSX.utils.sheet_add_json(ws, ticketNameArr, { origin: -1, skipHeader: true });
//
let wsRemDup = removeDuplicate(ws)
console.log("Unique Data", wsRemDup)
//OverWriting Unique data
wb.Sheets[first_sheet_name] = XLSX.utils.json_to_sheet(wsRemDup);
XLSX.writeFile(wb, 'DailyTicketSatus.xlsx')
// respond.render('result', { "ticketNameArr": ticketNameArr });
respond.render('index', { "ticketNameArr": ticketNameArr });
}
});
}
}
( async() => {
await runFTPJob(dataJson1);
processTickets();
})();

Related

how to use npm cli-progress in ssh2-sftp-client

i have a project with npm ssh2-sftp-client to download files from remote server,so i want to display downloading progress displaying in console.Downloading files works fine, but i do not know how to use cli-progress to display downloading progress while the files are downloading .
function getConnect(ip, name, pwd, remotepath, localpath) {
const sftp = new SftpClient();
sftp.connect({
host: ip,
port: 22,
username: name,
password: pwd
}).then(async () => {
const files = await sftp.list(remotepath, '.');
for (var j = 0; j < files.length; j++) {
var e =files[j];
await sftp.fastGet(remotepath + "/" + e.name, localpath + "\\" + e.name);
}
});
I have revised, hopefully it will be better
function getConnect(ip, name, pwd, remotepath, localpath) {
const sftp = new SftpClient();
sftp.connect({
host: ip,
port: 22,
username: name,
password: pwd
}).then(async () => {
const files = await sftp.list(remotepath, '.');
for (var j = 0; j < files.length; j++) {
var e =files[j];
//=================================================
const Throttle = require('throttle');
const progress = require('progress-stream');
const throttleStream = new Throttle(1); // create a "Throttle " instance that reads at 1 bps
const progressStream = progress({
length: e.size,
time: 100, // ms
});
progressStream.on('progress', (progress) => {
process.stdout.write("\r" + " [" +e.name+"] downloaded ["+progress.percentage.toFixed(2)+"%]");
});
const outStream = createWriteStream(localpath);
throttleStream.pipe(progressStream).pipe(outStream);
try {
await sftp.get(remotepath + "/" + e.name, throttleStream, { autoClose: false });
} catch {
console.log('sftp error', e);
} finally {
await sftp.end();
}
}
}
}
i followed the suggestion from #Abbas Agus Basari like:
await sftp.fastGet(secondPath + "/" + e.name, localPath + "\\" + e.name, {
step: step=> {
const percent = Math.floor((step / e.size) * 100);
process.stdout.write("\r" + "【"+e.name+"】downloaded【"+percent+'%】');
}
});
and run like:
[1]: https://i.stack.imgur.com/97sRi.png
i downloaded two files from remote server ,but the console only could see one file 100%,the other stopped at 59%

Edit a JSON object

I retrieved a JSON object from a local database, I want to edit a value (invItems) and add a new value to it (filed[filed.invItems]), then upload it back to the database, but it does not seem to work (the JSON does not seem to change)
async function invPut(itemID, message) {
var filed = await frenzyDB.getKey(id + "_invcache");
console.log("Before: " + filed)
newInvItems = filed.invItems + 1;
filed.invItems = newInvItems;
filed[filed.invItems] = itemID;
console.log("After: " + filed);
await frenzyDB.addKey(id + "_invcache", filed)
}
Console Output:
Before: {"invItems":0}
After: {"invItems":0}
It shows no errors, but the JSON doesnt change. Am I doing something wrong? If so, what can I do to fix it?
Thanks for all your help!
Notes:
frenzyDB is just a javascript file that deals with a standard REPL.it Database
Code of frenzyDB:
const Database = require("#replit/database")
const db = new Database()
async function addKey(key, value) {
await db.set(key, value).then(() => {return;});
}
async function getKey(key) {
return await db.get(key).then(value => {return value;});
}
function listAllKeys() {
db.list().then(keys => {return keys;});
}
async function hasKey(key) {
var keys = await listAllKeys();
if (keys.includes(key)) {
return true;
} else {
return false;
}
}
async function removeKey(key) {
await db.delete(key).then(() => {return;});
}
module.exports = {
addKey,
getKey,
listAllKeys,
hasKey,
removeKey
};
Edit: Latest code:
async function invPut(itemID, message) {
await init(message.author.id);
var filed = await frenzyDB.getKey(message.author.id + "_invcache");
console.log(filed)
const result = {};
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log(result);
frenzyDB.addKey(message.author.id + "_invcache", result)
message.reply("A **"+ itemIDs[itemID].name + "** was placed in your inventory");
return true;
}
EDIT 2: Latest Console Output:
{ '4': 3, invItems: 5 }
{ '5': 3, invItems: 6 }
Any help will be appreciated!
Thanks
Try this
// Demo Data
const itemID = 10;
var filed = { "invItems" : 0 };
// Real function
console.log("Before: " + JSON.stringify(filed));
const result = {};
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log("After: " + JSON.stringify(result));
The result I get is
Before: {"invItems":0}
After: {"0":10,"invItems":1}
You would then of course use result to store the data away in the DB.
async function invPut(itemID, message) {
// Typo?
var filed = await frenzyDB.getKey(itemID + "_invcache");
console.log("Before: " + filed)
const result = {};
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log("After: " + result);
// Typo?
await frenzyDB.addKey(itemID + "_invcache", result)
}
Answer Edit:
const result = { ...filed };
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log(JSON.stringify(result));
maybe this will help you
const json = fs.readFileSync(`${__dirname}/data/data.json`, "utf-8");
const inputData = JSON.parse(json);
inputData.push({input: 'front'}) // creates new element for data.json
-------------------------------------------
array.push({front: 'front', back: 'back'});

How to migrate SSE chat node express to node hapi

I was testing a SSE node express chat in localhost.It was working perfectly. I was including a chat_server in a demo with hapijs as modular server...and it complain about the express syntax. How can I migrate the code to the right syntax in hapijs?
I am trying to solve changing writeHead and write methods because it's complaing about and adding stream package after searching answers in internet.
/*
* Request handlers
*/
function handleGetChat(req, res) {
console.log('handleGetChat received.');
// res(chatStream).code(200).type('text/event-stream').header('Connection', 'keep-alive').header('Cache-Control','no-cache');
// chatStream.write('\n');
(function(clientId) {
clients[clientId] = res;
clientNames[clientId] = req.params.name;
console.log('name {$req.params.name}');
req.on("close", () => {
delete clients[clientId];
actUserName = "";
sendText(clientNames[clientId] + " disconnected!", false);
delete clientNames[clientId];
});
})(++clientId);
sendText(req.params.name + " connected!", false);
let allMates = "";
for (cliId in clientNames) {
allMates += `${clientNames[cliId]}`;
if (cliId < clientId) allMates += " ";
}
sendText(`logged in [${allMates}]`, false);
}
let sendText = (text, showUserName = true) => {
for (clientId in clients) {
allMates += `${clientNames[cliId]}`;
if (cliId < clientId) allMates += " ";
}
sendText(logged in [${allMates}], false);
}
let sendText = (text, showUserName = true) => {
for (clientId in clients) {
let data = "";
let date = new Date();
let timestamp = `[${date.getHours()}:${date.getMinutes()}]`;
if (showUserName) {
data = `data: ${timestamp} <${actUserName}> ${text}\n\n`;
} else {
data = `data: ${timestamp} ${text}\n\n`;
}
//chatStream.push('data: ' + "\n\n");
}
};
function handleWriteChat(req, res) {
actUserName = req.body.name;
sendText(req.body.text);
res.json({ success: true });
}
The commented lines in the code above are the lines with syntax error in hapi. I was already changing the originals write and writeHead with chatstream.

Problem with findOne() in sequelize node.js

I have a problem with node.js and sequelize findOne(). I want to find new students, that I want to add to the DB (var novi), and the ones that already exist, I just want to update their field (var stari). Everything works as expected, only when I want to return JSON with how many new students I added to the DB, and how many are updated, values of stari and novi, go back to 0, but the counting is good, I checked. I know the problem is with asynchronous call, but I don't know how to fix.
app.post('/student', function(req,res) {
var imeGodine = req.body['godina'];
//POMOĆNE SKRIPTE BitBucket.js i citanjeGodina.js
var broj = 0;
var stari = 0;
var novi = 0;
db.godina.findOne({where:{nazivGod:req.body.godina}}).then(god => {
var studenti = req.body.studenti;
db.student.count().then (ranijeStudenata => {
for(var i = 0; i<studenti.length; i++) {
var ime = studenti[i].imePrezime;
var ind = studenti[i].index;
db.student.findOne({where:{index :studenti[i].index}}).then(stud => {
if (stud == null) {
novi++;
db.student.create({imePrezime:ime, index : ind}).then(noviStudent => {
god.addStudenti(noviStudent);
});
}
else if (stud != null) {
stari++;
god.addStudenti(stud);
}
});
broj++;
}
var brojNovih = broj - ranijeStudenata; //ne koristi se, ali možda hoće
res.set("Content-Type", "application/json");
res.status(200).send(JSON.stringify({message: "Dodano je " + novi + " novih studenata i upisano " + stari + " na godinu " + imeGodine}));
});
});
});
Picture of code
You can use async/await to do counting in a synchronous way.
'use strict';
app.post('/student', async function (req, res) {
var imeGodine = req.body['godina'];
var {studenti} = req.body;
var broj = 0;
var stari = 0;
var novi = 0;
let god = await db.godina.findOne({where: {nazivGod: req.body.godina}});
let ranijeStudenata = await db.student.count(); // ranijeStudenata not used?
for (var i = 0; i < studenti.length; i++) {
var ime = studenti[i].imePrezime;
var ind = studenti[i].index;
let stud = await db.student.findOne({where: {index: studenti[i].index}});
if (stud === null) {
novi++;
let noviStudent = await db.student.create({imePrezime: ime, index: ind});
god.addStudenti(noviStudent);
} else if (stud !== null) {
stari++;
god.addStudenti(stud);
}
broj++;
}
return res.status(200).send({
message: "Dodano je " + novi + " novih studenata i upisano " + stari + " na godinu " + imeGodine
});
});

RecordRTC upload video to node js server

I am using RecordRTC from recording webrtc meeting. After implementing recording, when I test this application if both client are on the same system then its working fine. When I test this application on different system it isn't working fine and meeting is not recorded.
Here this is my code from stop recording client side.
recordRTC.stopRecording(function (videoURL) {
console.log('recordRTC.stopRecording Function inside');
SelectedFile = recordRTC.getBlob();
$('#uploadForm').append('#attachmentFileId', recordRTC.getBlob());
StartUpload();
});
var FReader;
var Name = "Meeting" + "_" + Date.now() + ".webm";
function StartUpload()
{
FReader = new FileReader();
FReader.onload = function (evnt)
{
socket.emit('Upload', { 'Name': Name, Data: evnt.target.result });
}
socket.emit('Start', { 'Name': Name, 'Size': SelectedFile.size });
}
socket.on('MoreData', function (data)
{
var Place = data['Place'] * 524288; //The Next Blocks Starting Position
var NewFile; //The Variable that will hold the new Block of Data
if (SelectedFile.webkitSlice)
NewFile = SelectedFile.webkitSlice(Place, Place + Math.min(524288, (SelectedFile.size - Place)));
else
NewFile = SelectedFile.slice(Place, Place + Math.min(524288, (SelectedFile.size - Place)));
FReader.readAsBinaryString(NewFile);
});
Server Side Code
I get this from here.
socket.on('Start', function (data) { //data contains the variables that we passed through in the html file
var Name = data['Name'];
Files[Name] = { //Create a new Entry in The Files Variable
FileSize : data['Size'],
Data : "",
Downloaded : 0
}
var Place = 0;
try{
var Stat = fs.statSync('Temp/' + Name);
if(Stat.isFile())
{
Files[Name]['Downloaded'] = Stat.size;
Place = Stat.size / 524288;
}
}
catch(er){} //It's a New File
fs.open("Temp/" + Name, 'a', 0755, function(err, fd){
if(err)
{
console.log(err);
}
else
{
Files[Name]['Handler'] = fd; //We store the file handler so we can write to it later
socket.emit('MoreData', { 'Place' : Place, Percent : 0 });
}
});
});
socket.on('Upload', function (data){
var Name = data['Name'];
Files[Name]['Downloaded'] += data['Data'].length;
Files[Name]['Data'] += data['Data'];
if(Files[Name]['Downloaded'] == Files[Name]['FileSize']) //If File is Fully Uploaded
{
fs.write(Files[Name]['Handler'], Files[Name]['Data'], null, 'Binary', function(err, Writen){
var input = fs.createReadStream("Temp/" + Name);
var output = fs.createWriteStream("Video/" + Name);
//util.pump(readableStream, writableStream, [callback])
//Deprecated: Use readableStream.pipe(writableStream)
input.pipe(output);
input.on("end", function() {
console.log("end");
fs.unlink("Temp/" + Name, function ()
{ //This Deletes The Temporary File
console.log("unlink this file:",Name );
//socket.emit('Done', {'Image' : 'Video/' + Name + '.jpg'});
});
});
});
}
else if(Files[Name]['Data'].length > 10485760){ //If the Data Buffer reaches 10MB
fs.write(Files[Name]['Handler'], Files[Name]['Data'], null, 'Binary', function(err, Writen){
Files[Name]['Data'] = ""; //Reset The Buffer
var Place = Files[Name]['Downloaded'] / 524288;
var Percent = (Files[Name]['Downloaded'] / Files[Name]['FileSize']) * 100;
socket.emit('MoreData', { 'Place' : Place, 'Percent' : Percent});
});
}
else
{
var Place = Files[Name]['Downloaded'] / 524288;
var Percent = (Files[Name]['Downloaded'] / Files[Name]['FileSize']) * 100;
socket.emit('MoreData', { 'Place' : Place, 'Percent' : Percent});
}
});
If both clients are on same machine/system its working fine, but if both clients are on different system then meeting is not recorded.

Resources