How to edit this code to wait for a file fully uploaded with node.js? - node.js

Hi I am trying to download a file and when it downloads it first has the extension .tmp or .crdownload, then after it is fully downloaded the extension changes to whatever the correct extension is, for example .png. I want to wait until the file no longer has the extension .tmp or .crdownload and then save the new file path to a variable. How can I do this? I have looked here on Stack Overflow but it is not answering all my questions. This is a unique and specific question. That is what I have so far. I don't mind if you don't use this code as long as the resulting code waits for the extension to change and saves the path to a variable as a string.
Code:
var downloadanduploadpath = "C:/Users/user1/Downloads";
//ptc mean path to check. have differnt name so the variable name of the placeholder in the function call is not the same name as the variable name in the function
var ptc = downloadanduploadpath;
var pathtocheck = ptc;
var timetowaitforimagefiledownloaded = 5000;
var fs = require('fs');
//let dirToCheck = pathtocheck;
var filecheckerfiles = fs.readdirSync(pathtocheck);
var filecheckerlatestPath = `${pathtocheck}/${filecheckerfiles[0]}`;
var filecheckerlatestTimeStamp = fs.statSync(filecheckerlatestPath).mtime.getTime();
filecheckerfiles.forEach(filecheckerfile => {
var filecheckerpath = `${pathtocheck}/${filecheckerfile}`;
var filecheckertimeStamp = fs.statSync(filecheckerpath).mtime.getTime();
if (filecheckertimeStamp > filecheckerlatestTimeStamp) {
filecheckerlatestTimeStamp = filecheckertimeStamp;
lastdownloadedimagetimestamp = filecheckerlatestTimeStamp;
lastdownloadedimage = filecheckerpath;
}
});
//get the extention of the last downloaded image
var lastdownloadedimageextention = lastdownloadedimage.split(".").pop();
//"png" || "jpg" || "jpeg" || "gif" ||
//if the file is a .tmp the image is not fully downloaded. run code inside to wait for it to not be a tmp file showing that the image if fully downloaded
if((lastdownloadedimageextention == "tmp") || (lastdownloadedimageextention == "crdownload") ){
//Show the file path to the console
console.log(lastdownloadedimage);
//show file not fill downloaded message in console
console.log("Image not yet fully downloaded.");
//show preparing to wait message in console
console.log("Preparing to wait for full download.");
//get all the files in the folder directory/path
var filecheckerfindpathbytimestamp = fs.readdirSync(pathtocheck);
console.log("hi1");
//define variable to store the path of the last donwloaded image foudn by timestamp
var lastdownloadedimagefoundbytimestamppath;
console.log("hi2");
//use the timestamp as an index to get the last downloaded file and then check the file at this timestamp(the last downloaded image) and check its file path.
//using the timestamp as an image lets us check the file without using the name because the name changes from .tmp to .png for example, so we are unable to get the
//the file by its name because of this name , so we use the timestamp to specifc the file we want to check the extention of instead
//find path of the last downloaded file by using the time to find it
filecheckerfindpathbytimestamp.forEach(filecheckerfindpathbytimestampfile => {
var filecheckerfindpathbytimestamppath = `${pathtocheck}/${filecheckerfindpathbytimestampfile}`;
console.log("hi3");
var filecheckerfindpathbytimestamptimeStamp = fs.statSync(filecheckerfindpathbytimestamppath).mtime.getTime();
console.log("hi4");
if (filecheckerfindpathbytimestamptimeStamp == lastdownloadedimagetimestamp) {
console.log("hi5");
lastdownloadedimagefoundbytimestamppath = filecheckerfindpathbytimestamppath;
console.log("hi6");
}
});
console.log("hi7");
//keep checking the file that ends in .tmp untill it changes from .tmp . once the file is no longer endng in .tmp indicating that the file is
//fully downloaded this path that is looking for the fiel path including the .tmp will no longer be valid because of the file path becomeing .png for example
// that it has fully downloaded, and the file path will not return true because it is no longer valid with the .tmp extention.
//once this path is no longer valid we will know that the file has fully downloaded because that path no longer ends in .tmp. We can then end the while loop.
//because file if fully downloaded.
//
while(fs.existsSync(lastdownloadedimagefoundbytimestamppath) == true){
//while((fs.existsSync(lastdownloadedimage)) == true){
//Show the file path to the console
console.log(lastdownloadedimage);
//Wait code
//Wait on the image converting page
await page2.type('.jsoninputtextarea', " ", {delay:timetowaitforimagefiledownloaded});
//show waiting for file fully download message in console
console.log("Waiting for image to fully download.");
}
//create varaible to find path of the last downloaded file by using the time to find it now that it is fully downloaded
var filecheckerfindfullydownloadedfiletimestamp = fs.readdirSync(pathtocheck);
//find path of the last downloaded file by using the time to find it now that it is fully downloaded
filecheckerfindfullydownloadedfiletimestamp.forEach(filecheckerfindfullydownloadedfilefile => {
var filecheckerfindfullydownloadedfilepath = `${pathtocheck}/${filecheckerfindfullydownloadedfilefile}`;
console.log("hi8");
var filecheckerfindfullydownloadedfiletimeStamp = fs.statSync(filecheckerfindfullydownloadedfilepath).mtime.getTime();
console.log("hi9");
if (filecheckerfindfullydownloadedfiletimeStamp == lastdownloadedimagetimestamp) {
console.log("hi10");
lastdownloadedimagefoundbytimestamppath = filecheckerfindfullydownloadedfilepath;
console.log("hi11");
}
});
console.log("hi12");
//Set lastdownloaded image to the path the now ends in the file extention (example .png) now instead of .tmp
//
lastdownloadedimage = lastdownloadedimagefoundbytimestamppath;
}
//Remove the path the of the image so we only have image name and file type
//Before: C:/Users/edtec/Downloads/image.png After: image.png
lastdownloadedimage = lastdownloadedimage.replace(downloadanduploadpath, "");
//Return lastdownloadedimage
//return lastdownloadedimage;
//}
//lastdownloadedimage = getlastdownloadedimage(downloadanduploadpath);
//console.log(lastdownloadedimage);
console.log(lastdownloadedimage);

Related

Problem with traversing file system using Node.js

I keep getting the error 'Error: ENOENT: no such file or directory, open 't1.txt''
when I run the function starting in the top-level directory pictured below.
I think it has to with 'fs.readFileSync()' attempting to read a file's contents from a directory different than the one fs is declared in, though I am not quite sure.
Picture of directory structure
/* the built-in Node.js 'fs' module is included in our program so we can work with the computer's file system */
const fs = require('fs');
// used to store the file contents of the files encountered
const fileContents = {};
/* stores the duplicate files as subarrays within the array, where the first element of the subarray is the duplicate file, and the second element is the original */
let duplicateFiles = [];
const traverseFileSystem = function (currentPath) {
// reads the contents of the current directory and returns them in an array
let files = fs.readdirSync(currentPath);
// for-in loop is used to iterate over contents of directory
for (let i in files) {
let currentFile = currentPath + '/' + files[i];
// retrieves the stats of the current file and assigns them to a variable
let stats = fs.statSync(currentFile);
// it's determined if the 'currentFile' is actually a file
if (stats.isFile()) {
/* if the file's contents are in the 'fileContents' object, then a new file has been encountered */
if(fileContents[fs.readFileSync(files[i])] === undefined) {
// the file's contents are set as the key, and the file path as the value
fileContents[fs.readFileSync(files[i])] = currentFile;
}
// otherwise, the file's contents already exist in the 'fileContents' object, which means a duplicate file has been found
else {
duplicateFiles.push([fileContents[fs.readFileSync(files[i])], currentFile]);
}
}
/* if the 'file' is actually a directory, traverseFileSystem() is called recursively on that directory */
else if (stats.isDirectory()) {
traverseFileSystem(currentFile);
}
}
return duplicateFiles;
};
You have fs.readFileSync(files[i]) which should be fs.readFileSync(currentFile) based on your code. Haven't confirmed your logic, but this should solve the error you are currently getting.

readdirSync cannot read encrypted home folder when accessing it directly

const fs = require("fs")
//const HOW = "/home/test/everything"
// const HOW = "/home/test/"
// This one fails. My home is encrypted and it cannot read directories, it gets the .Private file. I want to read files and directories in my home folder. But can't.
const HOW = "/home/test/folder/"
// This one works for some reason. It lists all the directories in the folder.
// const HOW = "folder"
// This one works as well
var list = walk(HOW)
console.log(list)
// How do I get contents of /home/test (which happens to be my home folder).
// I'm both root and "test" user of the computer.
I'd like to have walk() work on /home/test/.
The code that fails:
var walk = function(dir) {
var results = []
var list = fs.readdirSync(dir)
list.forEach(function(file) {
file = dir + '/' + file
var stat = fs.statSync(file)
if (stat && stat.isDirectory()) results = results.concat(walk(file))
else results.push(file)
})
return results
}
The exact line causing it (stack trace): var stat = fs.statSync(file)
The error is:
Error: ENOENT: no such file or directory, stat '/home/test/.Private/###############################################################'
Where # is an amount of letters whose importance to safety is unknown to me.
Node.js doesn't have a problem addressing any folder contained within my home folder, but cannot address the home folder itself. Neither my own account nor root account can get access to it.
I think you are adding an unnecessary /. Try changing
const HOW = "/home/test/folder/"
to
const HOW = "/home/test/folder"

Switch to what ever path is input nodejs

Lets assume you have installed an electron app and you are asked to input the path to your current project. You might do something like: ~/Documents/projectName.
How do I, in node take that input and check if it exists, specifically if you entered in the path as shown above?
the reason for this is that I want to see if A) the path exists and B) if theres a specific file there (I'll be using path.join(dirEntered, fileName.extension).
Is there a way to do what I want? I see chdir but that changes where the working directory is. which I guess would be fine but doing:
process.chdir('~/Documents') Shows: no such file or directory, uv_chdir(…)
I want to avoid having the user to enter the full absolute path of their project. That seems "bad to me". And uploading their project isn't necessary, Im reading a single file (so theres no need for upload here).
Any ideas?
Is it possible to tap into the cli commands and take this input feed it there and get the result? Or is that over kill?
Here's an idea how to solve it. If the path starts with a tilde, it replaces that tilde with the full home directory of the current user. It then uses fs.stat to see if the given path actually exists.
const fs = require("fs");
const os = require("os");
var path = "~/Documents";
if (path.indexOf("~") === 0) {
path = os.homedir() + path.substring(1);
}
fs.stat(path, (err, stats) => {
if (!err) {
// document or path exists
if (stats.isFile()) {
console.log("Path " + path + " is a file");
} else if (stats.isDirectory()) {
console.log("Path " + path + " is a directory");
}
} else {
// document or path does not exist
}
});

pdfmake does not include fonts / text in node.js

I have a problem with pdfmake. I would like to generate a PDF on a node.js server. I would like to load data from a database and draw a nice table and simply save it to a folder.
var pdfMakePrinter = require('pdfmake/src/printer');
...
var fonts = {
Roboto: {
normal: './fonts/Roboto-Regular.ttf',
bold: './fonts/Roboto-Medium.ttf',
italics: './fonts/Roboto-Italic.ttf',
bolditalics: './fonts/Roboto-Italic.ttf'
}
};
var PdfPrinter = require('pdfmake/src/printer');
var printer = new PdfPrinter(fonts);
var docDefinition = {
content: [
'First paragraph',
'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'
]
};
var pdfDoc = printer.createPdfKitDocument(docDefinition);
pdfDoc.pipe(fs.createWriteStream('pdf/basics.pdf')).on('finish', function () {
res.send(true);
});
The generated PDF is empty. If I add an image, it is inserted well. But no font is included. The path of the fonts (which are given in the sample) is right.
Has anyone an idea, why no fonts are embedded and how this can be done in node.js? There are no valid samples on the pdfmake documentation.
After some debugging, I found out, that the app crashes in fontWrapper.js in this funktion:
FontWrapper.prototype.getFont = function(index){
if(!this.pdfFonts[index]){
var pseudoName = this.name + index;
if(this.postscriptName){
delete this.pdfkitDoc._fontFamilies[this.postscriptName];
}
this.pdfFonts[index] = this.pdfkitDoc.font(this.path, pseudoName)._font; <-- Crash
if(!this.postscriptName){
this.postscriptName = this.pdfFonts[index].name;
}
}
return this.pdfFonts[index];
};
Does anyone have an idea?
TTF is not issue in your case you can use any font to generate a PDF on a node.js server.
inside pdfmake
TTFFont.open = function(filename, name) {
var contents;
contents = fs.readFileSync(filename);
return new TTFFont(contents, name);
};
on contents = fs.readFileSync(filename); this line
fs can't read file on given path
as per This conversation you have to put your fonts at root folder,
but problem is when we create font object we gives root path and this path is not working for fs.readFileSync this line so you have to exact path of font
add process.cwd().split('.meteor')[0] befor font path
I have created example for same functionality please this below link
https://github.com/daupawar/MeteorAsyncPdfmake

Check uploaded file extension in Sails js

How we can check uploaded file extension in sails js?
I tried on skipper and multer but have no result.
any suggestion?
You should use saveAs options for each file before saving.
var md5 = require('md5');
module.exports = {
testUpload:function(req,res){
// setting allowed file types
var allowedTypes = ['image/jpeg', 'image/png'];
// skipper default upload directory .tmp/uploads/
var allowedDir = "../../assets/images";
// don not define dirname , use default path
req.file("uploadFiles").upload({
saveAs:function(file, cb) {
var d = new Date();
var extension = file.filename.split('.').pop();
// generating unique filename with extension
var uuid=md5(d.getMilliseconds())+"."+ extension;
// seperate allowed and disallowed file types
if(allowedTypes.indexOf(file.headers['content-type']) === -1) {
// save as disallowed files default upload path
cb(null,uuid);
}else{
// save as allowed files
cb(null,allowedDir+"/"+uuid);
}
}
},function whenDone(err,files){
return res.json({
files:files,
err:err
});
});
}
}
Just get uploaded files array and check last chunk of string after dot.
req.file('file').upload({
maxBytes: 2000000,
dirname: 'uploadFolder'
}, function (error, files) {
if (error) return sails.log.error(error);
// You have files array, so you can do this
files[0].fd.split('.').pop(); // You get extension
}
What is going on here? When upload is finished you will get array of files with their filenames. You can get data from that array and see where this file is located (full path).
The last thing is splitting string by dots and get last item from the array with pop() method.

Resources