How to create a file inside a folder? - javascript

I have
fileUploadPath="d:/downloads";
and
entry.name='155ce0e4-d763-4153-909a-407dc4e328d0/63690689-e183-46ae-abbe-bb4ba5507f1a_MULTI_0_3/output/res2/res2.fcs';
when try to create res2.fcs file with following above path it shows gives me error, why it is not creating the folder structure?
code:
data.entries.forEach(entry => {
console.log(entry.name);
if (fs.existsSync(fileUploadPath)) {
var sourceFilePath = fileUploadPath + '/' + entry.name;
if (!fs.existsSync(sourceFilePath)) {
fs.mkdir(sourceFilePath, {recursive: true }, (err) => {if (err) {
console.log("Failed :" + err);
} else {
const fstream = fs.createWriteStream(require('path').format({dir: fileUploadPath, base: entry.name })); fstream.write('fileContent');
fstream.end();
fstream.on("finish", f => {
console.log(f)
});
fstream.on("error", e => {
console.log(e)
});
}
});
} else {
console.log('d');
}
} else {
console.log('ssss')
}
})
error:
[Error: ENOENT: no such file or directory, open 'D:\downloads\626a69d18d2468c5082fc6e1\MULTI_1_2022-04-28_11-00-38\output\res1\res1.fcs'] {
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'D:\\downloads\\626a69d18d2468c5082fc6e1\\MULTI__2022-04-28_11-00-38\\output\\res1\\res1.fcs'

you're passing file path to .mkdir instead of folder, so you should first create a folder, and then write the file
(as you're creating a folder that has the same name as the file, you should've got EISDIR error, instead of this one, which also says the file write didn't work)
use path.dirname to extract folder and pass it to .mkdir:
// require path module at the top of the script
const path = require('path');
fs.mkdir(path.dirname(sourceFilePath), { recursive: true }, (err) => {
//...

Related

zip and download folders to local using nodejs

How to zip and download folder from D:/downloads path. As a 1st step, I was able to create a folder inside 'downloads' with dummy content. As a next step I want to zip and download that folder.
async downloadFolder(selectedProduct) {
try {
let completeZip = await this.jobService.zipBlobs(selectedProduct.path, this.role).toPromise();
if(completeZip['status']=='success'){
let download = await this.jobService.downloadBlobs(selectedProduct.path, this.role).toPromise();
console.log(download)
}
} catch (error) {
console.log(error);
}
}
API:
Once file is written , I want to zip that folder and download that folder to local but nothing happens
exports.zipBlobs = async function (req, res) {
var userrole = req.body.userrole;
var path = req.body.path;
fileUploadPath="d:/downloads";
blobService.listBlobsSegmentedWithPrefix(containerName, path, null, (err, data) => {
if (err) {
reject(err);
} else {
data.entries.forEach(entry => {
console.log(entry.name);//'155ce0e4-d763-4153-909a-407dc4e328d0/63690689-e183-46ae-abbe-bb4ba5507f1a_MULTI_0_3/output/res2/res2.fcs';
if (fs.existsSync(fileUploadPath)) {
var sourceFilePath = fileUploadPath +'/'+entry.name ;
if (!fs.existsSync(sourceFilePath)) {
fs.mkdir(require('path').dirname(sourceFilePath), { recursive: true }, (err) => {
if (err) {
console.log("Failed :" + err);
}
else{
console.log('folder created,create file');
const fstream = fs.createWriteStream(sourceFilePath);
fstream.write('fileContent');
fstream.end();
fstream.on("finish", f => {
console.log('finish',f) ;
});
fstream.on("error", e => {
console.log('error',e);
});
}
});
}else{
console.log('folders already exists,create file');
const fstream = fs.createWriteStream(sourceFilePath);
fstream.write('fileContent');
fstream.end();
fstream.on("finish", f => {
console.log('finish',f) ;
});
fstream.on("error", e => {
console.log('error',e);
});
}
}else{
console.log('downloads folder does not exists!')
}
});
}
});
}
API to zip and download folder :
exports.downloadFolders = async function (req, res) {
var userrole = req.body.userrole;
var path = req.body.path;
try {
const folderpath = 'D:\downloads\622b6a148a813f18b8b2de81';
require('child_process').execSync(`zip -r archive *`, {
cwd: folderpath
});
// does not create zip, neither downloads
res.download(folderpath + '/archive.zip');
return;
}catch(error_1) {
res.status(200).json({
status: error_1
});
return;
}
}
In Javascript strings, backslashes must be doubled:
const folderpath = 'D:\\downloads\\622b6a148a813f18b8b2de81';
Without doubling them, you effectively get
const folderpath = 'D:downloads22b6a148a813f18b8b2de81'
because '\d' === 'd' and '\6' is a non-printable character.
You can also write the result of zip to the standard output and pipe it into the response object:
res.set("Content-Disposition", "attachment;filename=archive.zip");
require("child_process").exec("zip -r - *", {
cwd: folderpath
}).stdout.pipe(res);
This is something I used in one of my projects where I needed the whole directory downloaded as zip:
require the following library:
const zipdir = require('zip-dir')
Then, when you need to download the zip, call it as follows:
zipdir(
'D:/downloads/622b6a148a813f18b8b2de81',
{ saveTo: 'D:/downloads/622b6a148a813f18b8b2de81/archive.zip' },
(err, buffer) => {
if (err) throw err;
console.log('New zip file created!');
}
);
Following is the API signature:
app.get('/api/zip', function (req, res) {
//create new zip
zipdir(
'D:/downloads/622b6a148a813f18b8b2de81',
{ saveTo: 'D:/downloads/622b6a148a813f18b8b2de81/archive.zip' },
(err, buffer) => {
if (err) throw err;
console.log('New zip file created!');
res.download('D:/downloads/622b6a148a813f18b8b2de81/archive.zip');
}
);
});

How to create a json file which has name contains slashes >> Uncaught Error: ENOENT: no such file or directory, open './global/sites.json'

I want to create a folder (if folder does not exist) called
alexadata and create a json file under this folder which contains 'data' and named with slashes like global/sites.json , else
just want to create this json file into the alexadata folder. But both
of two status, I have an error Uncaught Error: ENOENT: no such file
or directory, open './global/sites.json' where if(err) return
err; line. If folder does not exist, then it is created but json
file is not created and gives this error. How can I fix this issue?
Please help me. Thank you in advance.
jsToJSON: async (data) => {
try {
let url = await page.url();
const code = await page.evaluate(() => {
return {
code: document.querySelector('#alx-content > div.row-fluid.TopSites.AlexaTool.padding20 > section.page-product-top > div > section > div.Foldering > div.each.current > a').innerText.toLowerCase()
}
});
const fields = ['rank', 'name', 'url', 'last_update'];
const json2csvParser = new Json2csvParser({ fields });
var _path = path.join(__dirname,'alexadata');
if (!fs.existsSync("alexadata")) {
fs.mkdir("alexadata", (err) => {
if (err) return err;
fs.writeFileSync(`./${code.code}/sites.json`, JSON.stringify(data), 'utf-8', (err) => {
if (err) return err;
console.log("Directory and File Saved ");
});
});
} else {
fs.writeFile(path.join(_path, `/${code.code}/sites.json`), JSON.stringify(data), 'utf-8', (err) => {
if (err) return err;
console.log("Directory and File Saved ");
});
}
} catch (error) {
console.log(error)
}
}

Get created file's path from SaveFileDialog in electron

I am trying to store my created file's path after using SaveFileDialog, here is my code:
let path;
dialog.showSaveDialog((fileName) => {
if (fileName === undefined){
console.log("You didn't save the file");
return;
}
fs.writeFile(fileName, text, (err) => {
if(err){
alert("An error ocurred creating the file "+ err.message)
}
alert("The file has been succesfully saved");
});
});
What I want to happen is that after the user creates the file he would enter file's path in the variable path, is it even possible?
you can use the sync version of dialog.showSaveDialog. with the sync version no need for you to declare the path variable without intializing it
let path = dialog.showSaveDialog( {
title: "Save file",
filters: [ { name:"png pictures", ext: [ "png" ] } ], // what kind of files do you want to see when this box is opend
defaultPath: app.getPath("document") // the default path to save file
});
if ( ! path ) {
// path is undefined
return;
}
fs.writeFile( path , text , ( err , buf ) => {
if ( err )
return alert("saved");
return alert("not saved");
});
or the async version
dialog.showSaveDialog( {
title: "Save file",
filters: [ { name:"png pictures", ext: [ "png" ] } ], // what kind of files do you want to see when this box is opend, ( users will be able to save this kind of files )
defaultPath: app.getPath("document") // the default path to save file
}, ( filePath ) => {
if ( ! filePath ) {
// nothing was pressed
return;
}
path = filePath;
fs.writeFile( path , text , ( err , buf ) => {
if ( err )
return alert("saved");
return alert("not saved");
});
});
this worked for me:
const { dialog } = require('electron')
dialog.showSaveDialog({
title: "Save file"
}).then((filePath_obj)=>{
if (filePath_obj.canceled)
console.log("canceled")
else
console.log('absolute path: ',filePath_obj.filePath);
});
You are almost there. You need to wait for the result of the dialog through the callback. Check the docs.
So something like:
let path;
function saveProjectAs(text) {
var options = {
title: "Save project as ",
message: "Save project as ",
nameFieldLabel: "Project Name:",
// defaultPath: directory to show (optional)
}
dialog.showSaveDialog(mainWindow, options, saveProjectAsCallback);
function saveProjectAsCallback(filePath) {
// if user pressed "cancel" then `filePath` will be null
if (filePath) {
// check for extension; optional. upath is a node package.
if (upath.toUnix(upath.extname(filePath)).toLowerCase() != ".json") {
filePath = filePath + ".json"
}
path = filePath;
fs.writeFile(path, text, (err) => {
if(err){
alert("An error ocurred creating the file "+ err.message)
}
alert("The file has been succesfully saved");
});
}
}
}

Express app with EJS template giving Error: Failed to lookup view "/id" in views directory "/home/USER/Desktop/scholarship-app/views"

I am trying to render the request url for id in my express app and getting the following error
Error: Failed to lookup view "/id" in views directory "/home/USER/Desktop/scholarship-app/views"
here my part of my express app code
app.get('/phd/:id', function(req, res) {
var pdhID = parseInt(req.params.id, 10);
var query = req.query;
console.log('console: ' + pdhID + 'query: ' + query);
db.scholarship.findAll({
where: pdhID
}).then(function(scholarship) {
if (scholarship != null) {
if (query.hasOwnProperty('format') && query.format === 'json') {
return res.json(scholarship);
} else {
var data_scholarship = JSON.stringify(scholarship);
console.log("rendering the scholarship page" + data_scholarship );
//error
return res.render('/id', {
title: data_scholarship.title,
css_path: '/public/css/styles.css',
keywords: 'phd position, shoclarships for sciences',
menu_bar_arr: menu_bar_arr,
menu_bar_link: menu_bar_link,
current_page: 'about-us',
menu_bar_lindx: menu_bar_arr.length - 1,
data_scholarship: data_scholarship,
error: 0
});
}
} else {
return res.render('id', {
error: '404'
});
}
}, function(err) {
return res.render('id', {
msg: 'could cnt open the file',
error: 1
});
});
});
My id.ejs file is located # path /home/USER/Desktop/scholarship-app/views, still it giving me the error.
It will be great if some one can help it the error. My other view in the same directory is getting render properly
Remove extra / from your id in return res.render('/id',{....})

Uploading files using Skipper with Sails.js v0.10 - how to retrieve new file name

I am upgrading to Sails.js version 0.10 and now need to use Skipper to manage my file uploads.
When I upload a file I generate a new name for it using a UUID, and save it in the public/files/ folder (this will change when I've got this all working but it's good for testing right now)
I save the original name, and the uploaded name + path into a Mongo database.
This was all quite straightforward under Sails v0.9.x but using Skipper I can't figure out how to read the new file name and path. (Obviously if I could read the name I could construct the path though so it's really only the name I need)
My Controller looks like this
var uuid = require('node-uuid'),
path = require('path'),
blobAdapter = require('skipper-disk');
module.exports = {
upload: function(req, res) {
var receiver = blobAdapter().receive({
dirname: sails.config.appPath + "/public/files/",
saveAs: function(file) {
var filename = file.filename,
newName = uuid.v4() + path.extname(filename);
return newName;
}
}),
results = [];
req.file('docs').upload(receiver, function (err, files) {
if (err) return res.serverError(err);
async.forEach(files, function(file, next) {
Document.create({
name: file.filename,
size: file.size,
localName: // ***** how do I get the `saveAs()` value from the uploaded file *****,
path: // *** and likewise how do i get the path ******
}).exec(function(err, savedFile){
if (err) {
next(err);
} else {
results.push({
id: savedFile.id,
url: '/files/' + savedFile.localName
});
next();
}
});
}, function(err){
if (err) {
sails.log.error('caught error', err);
return res.serverError({error: err});
} else {
return res.json({ files: results });
}
});
});
},
_config: {}
};
How do I do this?
I've worked this out now and thought I'd share my solution for the benefit of others struggling with similar issues.
The solution was to not use skipper-disk at all but to write my own custom receiver. I've created this as a Sails Service object.
So in file api/services/Uploader.js
// Uploader utilities and helper methods
// designed to be relatively generic.
var fs = require('fs'),
Writable = require('stream').Writable;
exports.documentReceiverStream = function(options) {
var defaults = {
dirname: '/dev/null',
saveAs: function(file){
return file.filename;
},
completed: function(file, done){
done();
}
};
// I don't have access to jQuery here so this is the simplest way I
// could think of to merge the options.
opts = defaults;
if (options.dirname) opts.dirname = options.dirname;
if (options.saveAs) opts.saveAs = options.saveAs;
if (options.completed) opts.completed = options.completed;
var documentReceiver = Writable({objectMode: true});
// This `_write` method is invoked each time a new file is received
// from the Readable stream (Upstream) which is pumping filestreams
// into this receiver. (filename === `file.filename`).
documentReceiver._write = function onFile(file, encoding, done) {
var newFilename = opts.saveAs(file),
fileSavePath = opts.dirname + newFilename,
outputs = fs.createWriteStream(fileSavePath, encoding);
file.pipe(outputs);
// Garbage-collect the bytes that were already written for this file.
// (called when a read or write error occurs)
function gc(err) {
sails.log.debug("Garbage collecting file '" + file.filename + "' located at '" + fileSavePath + "'");
fs.unlink(fileSavePath, function (gcErr) {
if (gcErr) {
return done([err].concat([gcErr]));
} else {
return done(err);
}
});
};
file.on('error', function (err) {
sails.log.error('READ error on file ' + file.filename, '::', err);
});
outputs.on('error', function failedToWriteFile (err) {
sails.log.error('failed to write file', file.filename, 'with encoding', encoding, ': done =', done);
gc(err);
});
outputs.on('finish', function successfullyWroteFile () {
sails.log.debug("file uploaded")
opts.completed({
name: file.filename,
size: file.size,
localName: newFilename,
path: fileSavePath
}, done);
});
};
return documentReceiver;
}
and then my controller just became (in api/controllers/DocumentController.js)
var uuid = require('node-uuid'),
path = require('path');
module.exports = {
upload: function(req, res) {
var results = [],
streamOptions = {
dirname: sails.config.appPath + "/public/files/",
saveAs: function(file) {
var filename = file.filename,
newName = uuid.v4() + path.extname(filename);
return newName;
},
completed: function(fileData, next) {
Document.create(fileData).exec(function(err, savedFile){
if (err) {
next(err);
} else {
results.push({
id: savedFile.id,
url: '/files/' + savedFile.localName
});
next();
}
});
}
};
req.file('docs').upload(Uploader.documentReceiverStream(streamOptions),
function (err, files) {
if (err) return res.serverError(err);
res.json({
message: files.length + ' file(s) uploaded successfully!',
files: results
});
}
);
},
_config: {}
};
I'm sure it can be improved further but this works perfectly for me.
The uploaded file object contains all data you need:
req.file('fileTest').upload({
// You can apply a file upload limit (in bytes)
maxBytes: maxUpload,
adapter: require('skipper-disk')
}, function whenDone(err, uploadedFiles) {
if (err) {
var error = { "status": 500, "error" : err };
res.status(500);
return res.json(error);
} else {
for (var u in uploadedFiles) {
//"fd" contains the actual file path (and name) of your file on disk
fileOnDisk = uploadedFiles[u].fd;
// I suggest you stringify the object to see what it contains and might be useful to you
console.log(JSON.stringify(uploadedFiles[u]));
}
}
});

Categories

Resources