How to download a file with nodeJS - javascript

I want to download an image file with nodeJS, by using an API, but the problem is the API link doesn't have .jpg file in the end, how do I do,
below is how I am trying
url = 'https://i.pravatar.cc/225'
const https = require('https')
const fs = require('fs');
result = https.get(url, (resp) => {
console.log('Result of response: ', resp)
fs.writeFileSync('apiResponse', resp)
console.log('Reached end!')
})
When I click the URL it shows the image in browser, how do make my program to write the file on hard-drive,

This code uploads several different pictures
const url = 'https://i.pravatar.cc/225'
const https = require('https')
const fs = require('fs');
for(let i=0; i<10; i++)
https.get(url, resp => resp.pipe(fs.createWriteStream(`./test_${i}.jpeg`)));

Just pipe response to file
const url = 'https://i.pravatar.cc/225'
const https = require('https')
const fs = require('fs');
https.get(url, resp => resp.pipe(fs.createWriteStream('./test.jpeg')));

please use this I have try with it and working fine you can rename the downloded file too.
const https = require("https");
const fs = require("fs");
const file = fs.createWriteStream("file.jpg");
const request = https.get("https://i.pravatar.cc/225", function(response) {
response.pipe(file);
});

Try download-file library
https://www.npmjs.com/package/download-file
Install : npm install download-file --save
var download = require('download-file')
var url = "http://i.imgur.com/G9bDaPH.jpg"
var options = {
directory: "./images/cats/",
filename: "cat.gif"
}
download(url, options, function(err){
if (err) throw err
console.log("meow")
})

Related

How to unzip file with Node.js

I need to zip and unzip file with Node.js but I have a problem.
const fs = require("fs");
const zlib = require('zlib');
function UnZip(zip, paths) {
var inp = fs.createReadStream("f:/test.zip");
var Exzip = zlib.createUnzip();
inp.pipe(Exzip).pipe("f:/");
}
Error:
TypeError: dest.on is not a function
Here is how you can do it with zlib module.
const fs = require('fs');
const zlib = require('zlib');
const fileContents = fs.createReadStream('file1.txt.gz');
const writeStream = fs.createWriteStream('file1.txt');
const unzip = zlib.createGunzip();
fileContents.pipe(unzip).pipe(writeStream);
Zipping the file
const archiver = require('archiver'),
archive = archiver('zip'),
fs = require('fs'),
output = fs.createWriteStream( 'mocks.zip');
archive.pipe(output);
// temp.txt file must be available in your folder where you
// are writting the code or you can give the whole path
const file_buffer = fs.readFileSync('temp.txt')
archive.append(file_buffer, { name: 'tttt.txt'});
archive.finalize().then((err, bytes) => {
if (err) {
throw err;
}
console.log(err + bytes + ' total bytes');
});
unzipping a file
const unzip = require('unzip'),
fs = require('fs');
fs.createReadStream('temp1.zip').pipe(unzip.Extract({ path: 'path' }))

file-type npm module returns null despite being called with buffer, what am I doing wrong?

I'm developing a website where users can upload video files to be stored in MongoDB. Before the files get uploaded and stored, I would like to check and validate the mimetype of the file. I would like to do that with help of a npm module, I have tried without success with file-type.
Link to file-type npm module: https://www.npmjs.com/package/file-type
I call the module with buffer of uploaded files (tested with mp4-files) but it returns null. Here is my code for the upload route:
'use strict';
const router = require('express').Router();
const VideoInfo = require('../../models/VideoInfo');
const VideoAmount = require('../../models/VideoAmount');
const path = require('path');
const Lib = require('../../lib/Lib');
const multer = require('multer');
const GridFsStorage = require('multer-gridfs-storage');
const fileType = require('file-type');
// Defines storage of files with validation
const storage = new GridFsStorage({
url: process.env.dbURL,
file: (req, file) => {
const data = [];
req.on('data', chunk => {
data.push(chunk);
});
req.on('end', () => {
const buffer = Buffer.concat(data);
const fType = fileType(buffer);
return new Promise((resolve, reject) => {
if (fType === null) {
return reject(new Error('Unsupported file format'));
}
if (fType.mime !== 'video/mp4' ||
fType.mime !== 'video/webm' ||
fType.mime !== 'video/ogg') {
return reject(new Error('Unsupported file format'));
}
if (!req.session.username) {
return reject(new Error('Unauthorized file upload attempt'));
}
// changes the file name before storing
const fileName =
Lib.make.randomString() + path.extname(file.originalname);
const fileInfo = {
filename: fileName,
bucketName: 'uploads'
};
resolve(fileInfo);
});
});
}
});
const upload = multer({ storage });
router.route('/upload')
.get((req, res) => {
// renders upload form, not really relevant
})
.post(upload.single('video'), async (req, res) => {
// file gets saved to DB with upload.single-function
});
module.exports = router;
What am I doing wrong?
The problem was that I wasn't getting the video file buffer.
What solved it was including busboy-body-parser in my app:
const busboyBodyParser = require('busboy-body-parser')
app.use(busboyBodyParser({
limit: '120mb'
}))
Then I could get the buffer from the request:
const fileContent = req.files.video
const buffer = fileContent.data
Then I could get the file type of the file by calling file-type with the buffer.

NodeJS - Send converted file to client side to download

GOAL: Allow the user to download a PDF
Background: The below code generates a car.pdf file and stores it into the main project's directory when localhost:3000/ is loaded. This is great because I want to find a Car by id in the database, generate a handlebars template, pass the data from Car into it, and generate a PDF from the compiled HTML
Issue: Instead of saving the PDF to the main project's directory, I want it to download to the user's computer.
How can I do this?
Here is my code. I am using the NPM package: html-pdf
helpers/export-helper.js
const fs = require('fs');
const pdf = require('html-pdf');
const Handlebars = require('handlebars');
const { Car } = require('./../models/car');
var writePDF = (res) => {
Car.findById({_id: '58857e256b639400110897af'})
.then((car) => {
var source = fs.readFileSync(__dirname + '/templates/car.handlebars', 'utf8');
var template = Handlebars.compile(source);
var file = template(car);
pdf.create(file, { format: 'Letter' })
.toFile('./car.pdf', (err, res) => {
if (err) return console.log(err);
console.log(res); // { filename: '/app/businesscard.pdf' }
});
})
.catch((errors) => {
console.log(errors);
});
};
module.exports = { writePDF };
routes/home.js
const express = require('express');
const router = express.Router();
const { writePDF } = require('./../helpers/export-helpers');
router.get('/', (req, res) => {
writePDF();
});
module.exports = router;
You should use res.download for this. Like so
router.get('/', (req, res) => {
res.download('car.pdf');
});
https://expressjs.com/en/api.html#res.download
You have to pipe the created pdf with response to client side.

Cannot save a remote image with node.js and request

I want to save an image with node.js and the request library. So far I have this simple code:
var request = require('request');
var fs = require('fs');
request('http://upload.wikimedia.org/wikipedia/commons/8/8c/JPEG_example_JPG_RIP_025.jpg', function(error, response, body)
{
// further logic that decides
// whether or not the image will be saved
fs.writeFile('downloaded.jpg', body, function(){});
});
But it doesn't work. The image always arrives corrupt. I assume it's an encoding error but I cannot figure out how to fix this.
var request = require('request'),
fs = require('fs'),
url = 'http://upload.wikimedia.org/wikipedia/commons/8/8c/JPEG_example_JPG_RIP_025.jpg';
request(url, {encoding: 'binary'}, function(error, response, body) {
fs.writeFile('downloaded.jpg', body, 'binary', function (err) {});
});
var fs = require('fs'),
request = require('request'),
url='http://upload.wikimedia.org/wikipedia/commons/8/8c/JPEG_example_JPG_RIP_025.jpg';
request(url).pipe(fs.createWriteStream('downloaded.jpg'));
Here's how I did it using stream and pipe, (I was using express but you may not need that)
var express = require('express');
var app = express();
var filesystem = require('fs');
var https = require('https');
var download = function(url, dest, cb) {
var file = filesystem.createWriteStream(dest);
var request = https.get(url, function(httpResponse) {
httpResponse.pipe(file);
file.on('finish', function() {
console.log("piping to file finished")
file.close(cb); // close() is async, call cb after close completes.
});
}).on('error', function(err) { // Handle errors
filesystem.unlink(dest); // Delete the file async. (But we don't check the result)
if (cb) cb(err.message);
});
};
app.get('/image', (req, res) => {
download('https://lastfm-img2.akamaized.net/i/u/64s/15cc734fb0e045e3baac02674d2092d6.png',
'porcupine.png',
() => {console.log("downloaded to porcupine.png")})
})
When I run using node server.js and hit the url localhost:3000/image, it will download and save the file to porcupine.png in the base directory.

nodejs load file

I want to load test.txt with nodejs.
var fs = require('fs');
fs.readFile('./test.txt', function (err, data) {
if (err) {
throw err;
}
console.log(data);
});
The path of the server is C:\server\test\server.js. The test.txt is located in the same directory, but I get this error: Error: ENOENT, no such file or directory 'C:\Users\User\test.txt'
Paths in Node are resolved relatively to the current working directory. Prefix your path with __dirname to resolve the path to the location of your Node script.
var fs = require('fs');
fs.readFile( __dirname + '/test.txt', function (err, data) {
if (err) {
throw err;
}
console.log(data.toString());
});
With Node 0.12, it's possible to do this synchronously now:
var fs = require('fs');
var path = require('path');
// Buffer mydata
var BUFFER = bufferFile('../test.txt');
function bufferFile(relPath) {
return fs.readFileSync(path.join(__dirname, relPath)); // zzzz....
}
fs is the file system. readFileSync() returns a Buffer, or string if you ask.
fs correctly assumes relative paths are a security issue. path is a work-around.
To load as a string, specify the encoding:
return fs.readFileSync(path,{ encoding: 'utf8' });
You should use __dirname to get the directory name the file is located instead of the current working directory:
fs.readFile(__dirname + "/test.txt", ...);
Use path and fs:
const fs = require("fs");
const pth = require("path");
Sync:
let data = fs.readFileSync(pth.join(__dirname,"file.txt"));
console.log(data + "");
A-Sync:
fs.readFile(pth.join(__dirname,"file.txt"), (err, data) => {
console.log(data + "");
});
And that; If you need to read the file continuously and send it to the client and the file size is not large, you may be able to keep a copy of it:
const exp = require("express");
const app = exp();
const fs = require("fs");
const pth = require("path");
let file = "";
app.get("/file", (q, r) => {
if (file === "")
file = fs.readFileSync(pth.join(__dirname,"file.txt")) + "";
r.writeHead(200, { "Content-Type": "text/plain" });
r.write(file);
r.end();
});
so if it is in the same directory just do this
fs.readFile(__dirname+'/foo.txt',function(e,d){console.log(d)})
If it's in same directory it should work. I have tested with the same code, with a file name.txt and it's working fine:
var fs = require('fs');
fs.readFile('./test.txt', function (err, data) {
if (err) {
throw err;
}
console.log(data.toString());
});

Categories