How to rename file while using express fileupload in node.js - node.js

I have file upload functionality and I am using express-fileupload module in node.js to upload file to local folder. I am explaining my existing code below.
const fileUpload = require('express-fileupload');
app.use(fileUpload({
createParentPath: true
}));
const avatar = req.files.file;
avatar.mv('./uploads/' + avatar.name);
Here I can upload the file to my upload folder but here I need to add the timestamp with the file name and then upload so that I can differentiate if any new file is coming with same name.

This code may help you
const path = require('path');
let target_file = req.files.target_file;
var file_name = new Date().getTime() +'_'+target_file.name;
// target_file.mv(path, callback)
target_file.mv(path.join(__dirname, 'uploads', file_name), (err) => {
if (err) throw err;
res.send('File Uploaded');
})

The code(by Elangovan Selvaraj) before this comment is absolutely correct.
I tried with:
const pdfUpload = req.files.documents;
const fileName = new Date().getTime() + '_' + pdfUpload.name;
const pdfPath = path.join(
__dirname,
'../public/uploads/hotels/kyc/' + `${fileName}`
);
await pdfUpload.mv(pdfPath);

Related

Node.js - using Multer How to Get Upload file's(Source file's) full path?

I want to get uploading file's full path, as dynamic like a image, in my node.js code.
I don't know what to do, I need your help
app.post('/upload', upload.single('userfile'), function(req, res){
var filename = __dirname +'/'+ req.file.path; //this is uploaded file path
var s = fs.ReadStream(filename);
s.on('data', function(data) {
shasum.update(data)
})
// making digest
s.on('end', function() {
var hash = shasum.digest('hex')
console.log("Hash : "+ hash + ' ' + filename)
res.send('Uploaded : ' + hash);
})
})
enter image description here
As I see from your comment, you are using local environment. Therefore the host will not lead to the full URL. So try removing the host.
So replace:
var filename = __dirname +'/'+ req.file.path;
With:
var filename = req.protocol + req.file.path;

Ionic native file transfer - File upload - Node js express server but req.files undefined

I am a beginner at ionic framework developing.
This is flow of my ionic app.
- Select image from folders and press "upload a picture" button.
- I used ionic-native-file transfer for uploading to Nodejs express server.
This is my code.
//ionic page
https://www.dropbox.com/s/k1nittp0p8t4ay3/item-create.rar?dl=0
//Node js source
https://www.dropbox.com/sh/0zd9ydk0uhhz5g7/AABIg9S7hV6XiIzrMTj8FKA2a?dl=0
Main Point:
app.post('/upload', function(req,res)) , uploadImage()
//ionic3-item.js
uploadImage() //When press upload button
{
const fileTransfer:FileTransferObject = this.transfer.create();
let option: FileUploadOptions = {
fileKey:'file',
fileName:'name.jpg',
mimeType:'image/jpeg'
};
fileTransfer.upload(this.fileurl, encodeURI("http://192.168.1.249:8080/upload"),option);
}
}
//This Node js server code.
//route/ index.js
module.exports = function(app, Article)
{
//Uploaded Article------------------This part -------------------------
app.post('/upload', function(req,res){
console.log(req.files);
});
}
But req.files is undefined.
I wonder how I can treat the uploaded files from ionic app.
Please help.
Thanks.
This is client source.
var name = "upload";
let option: FileUploadOptions = {
fileKey:'file',
mimeType:'audio/3gp',
httpMethod:'POST',
fileName:'user_step4#'+name
};
this.loader = this.loadingCtrl.create({
content:'登录中...',
});
this.loader.present();
const fileTransfer:FileTransferObject = this.transfer.create();
console.log('filename'+this.curfilename);
fileTransfer.upload(this.file.externalRootDirectory+this.curfilename, encodeURI(localStorage.getItem('GlobalIP')+"/upload"),option).then((result)=>
{
console.log('success');
}).catch(error=>{
this.loader.dismiss();
console.log('uploaderror');
console.log(error.message);
});
}
This is server code
var multer = require('multer');
var storage = multer.diskStorage({
destination:function(req, file, cb)
{
console.log('uploadpath:'+file.originalname);
var pathname = file.originalname.split('#');
console.log(file.originalname);
var path = pathname[0].replace('_','/');
console.log(path);
cb(null,'public/resources/'+path);
},filename:function(req,file,cb)
{
var pathname = file.originalname.split('#');
var filename = pathname[1];
console.log(filename);
if(filename!=undefined)
cb(null, filename);
}
});
//For multipart/form-data Uploading
var upload = multer({storage:storage});
app.post('/upload',upload.single('file'), function(req,res,next)
{
console.log("uploaded");
res.json({result:1});
});
Thanks for reading.

Combine multer and tinypng API in node

does anyone know how to use tinyPNG's API with multer? The docs seem deceptively simple:
var source = tinify.fromFile("unoptimized.jpg");
source.toFile("optimized.jpg");
though there's no clear indication of where this is meant to go, especially in something as convoluted as this:
var storage = multer.diskStorage(
{
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
//use date to guarantee name uniqueness
callback(null, file.originalname + '-' + Date.now());
}
}
);
//.any() allows multiple file uploads
var upload = multer({ storage : storage}).any()
app.post('/api/photo', function(req,res){
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
Where am I meant to "intercept" the file uploaded by multer so that I can compress it with tinyPNG?
Thanks in advance for the help!
Use following basic sample that changes uploaded photo/gallery files:
// Import express and multer.
var express = require('express');
var multer = require('multer');
// Setup upload.
var upload = multer({ dest: 'uploads/' });
var multipleFiles = upload.fields([{ name: 'photo', maxCount: 1 },
{ name: 'gallery', maxCount: 8 }]);
// Setup tinify.
var tinify = require("tinify");
tinify.key = "YOUR_API_KEY";
// Get request handler for '/' path.
var app = express();
app.get('/', function (req, res) {
res.setHeader("Content-Type", "text/html");
res.end(
"<form action='/api/photo' method='post' enctype='multipart/form-data'>" +
"<input type='file' name='photo' />" +
"<input type='file' name='gallery' multiple/>" +
"<input type='submit' />" +
"</form>"
);
});
// Upload file handler with '/api/photo' path.
app.post('/api/photo', multipleFiles, function (req, res) {
req.files['gallery'].forEach(function(file) {
// Your logic with tinify here.
var source = tinify.fromFile(file.path);
source.toFile(file.path + "_optimized.jpg");
});
res.end("UPLOAD COMPLETED!");
});
Feel free to change express middleware how you need it, just make sure you use upload.fields and authenticate using tinify.key = "YOUR_API_KEY";
https://github.com/expressjs/multer
https://tinypng.com/developers/reference/nodejs#compressing-images
I recently worked out a similar problem for myself using the tinify package and found the docs to be somewhat lacking.
I have a Vue front end collecting file uploads from the user using vue2dropzone. These are sent to a node / Express back end.
I have a need to compress the file and upload it to an S3 instance without storing on disk. That means using multer memory storage.
As a result there won’t be an ability to use tinify.fromFile() as there is no file stored locally.
In my images middleware:
Const multer = require(“multer”);
const tinify = require("tinify");
tinify.key = "your_key";
exports.singleFile = multer({ storage: multer.memoryStorage() }).fields([{ name: "file", maxCount: 1 }]);
exports.uploadCompImage = async (req, res, next) => {
try {
const fileName = `${req.params.name}${path.extname(req.files.file[0].originalname)}`;
const source = tinify.fromBuffer(req.files.file[0].buffer);
source.store({
service: "s3",
aws_access_key_id: "your_id",
aws_secret_access_key: "your_key
region: "your_region",
headers: {
"Cache-Control": "public"
},
path: `your_bucket/your_folder/${fileName}`
});
return res.status(200).send(`path_to_file/${fileName}`)
} catch (err) {
console.log(err);
next(err);
}
}
Then in my routes file:
Const images = require(“../middleware/images”);
// skipped several lines for brevity
productRouter
.route("/images/:name")
.post(images.singleFile, images.uploadCompImage)
This process creates a multer singleFile upload to memoryStorage, making the file available at req.files.file[0] (req.files[“file”] because I specified “file” as the name in multer fields, loop through this array if uploading multiple).
After setting that up I get the file name, set the source by using tinify to read from req.files.file[0].buffer as a buffer.
Then I set the source to my s3 instance and send back a public link to the file.
Hopefully this answer helps you. I could definitely see altering the process to change where the file goes or even write it to disk by altering the multer options.

how to write binary string to file in nodejs?

I have a http request as follow(python code):
data = open("/tmp/ibus.tar.gz", 'rb').read()
resp = requests.post(url="http://192.168.1.156:3000/upload", data=data, headers={'Content-Type': 'application/octet-stream'})
print resp.text
now I implement this request with nodejs as follow:
router.post('/', function(req, res, next) {
var b = req.body.file;
fs.writeFile("/tmp/upload.tgz", b, "binary", function(err) {
if (err) return console.log(err);
console.log("file is saved");
return res.send({"status": 200});
})
});
but I test the /tmp/upload.tgz with tar zxf /tmp/upload.tgz, got error as follow:
tar: Unrecognized archive format
tar: Error exit delayed from previous errors.
req.body.file is undefined because express doesn't handle file upload. You have to use another package to handle the upload. You're also using requests the wrong way:
# use an object
data = { 'test': open(path + "test.gz", 'rb') }
# use files as identifier, not data
resp = requests.post("http://localhost:3000/upload", files = data)
print resp.text
For example, using multer
var fs = require('fs');
var multer = require('multer');
// specify a folder to put the temporary files
var upload = multer({ dest: __dirname + '/uploads' });
// 'test' is the identifier used in the python side, it's not random
router.post('/upload', upload.single('test'), function (req, res, next) {
var file = req.file;
console.log(file);
// at this point, the file is inside the tmp folder, now you can:
// make a copy
var src = fs.createReadStream(file.path);
var dest = fs.createWriteStream(__dirname + '/upload.gz');
src.pipe(dest);
// or move it
fs.renameSync(file.path, __dirname + '/upload.gz');
res.send('ok');
});

In Multer 1.0 how do you get event callbacks to work?

I am trying to get rename and onFileUploadComplete to call their console log but it never does, it does however call my console in post, which is giving me a string of a file that is not there.
var express = require("express");
var multer = require("multer");
var Excel = require("exceljs");
var router = express.Router();
var fs = require('fs');
var doneUpload = false;
var displayResults = [];
var Excelfile;
router.use(multer({ dest: "./uploads/",
rename: function (fieldname, filename) {
console.log("Filename: "+filename);
return new Date().getTime() + filename;
},
onFileUploadComplete: function (file) {
saveFile = file;
console.log("onFileUploadComplete ");
doneUpload = true;
}
}).single("excelFile"));
router.get("/", function(req, res){
res.sendFile(__dirname + "/index.html");
});
router.post("/api/fileupload" ,function(req, res){
Excelfile = req.file.path;
console.log(typeof Excelfile);
res.render("results", {
displayResults: displayResults
});
});
module.exports = router;
Thanks in advance.My ultimate goal is to have a file I can pass into excel JS and currently it is saying the file is not in the correct string format. I suspect because the file is being renamed to the long string of numbers "uploads/7ab48192a1c548a3dce3b9d74cad6592" which is never pointing to an actual file. I further suspect this because I ran typeof and it is does give me back a string - just not one pointing to a file, especially if onFileUploadComplete never gets fired telling me the file is uploaded?
The usage for Multer has changed.
These callbacks would not work. Have a look at these links:
https://github.com/expressjs/multer
multer callbacks not working ?

Resources