create downloable file for mobile and desktop - javascript

I want to create a vCard in the frontend and to make it downloadable (by clicking a button) in a ReactJs Project. I use a NodeJS module called vcards-js that creates a string with the content of the desired vCard (v3.0). The thing I am struggling with is to make it downloadable (as .vcf file).
here is my code
const {fname,lname,phoneNumber,email,organisation,title}=req.body
const mycard=vcard()
mycard.firstName=fname
mycard.lastName=lname
mycard.phoneNumber=phoneNumber
mycard.email=email
mycard.organisation=organisation
mycard.title=title
// enter code here
console.log(mycard.getFormattedString(),"utf-8")
after console.log() i get vcard format data but how to get it downloadable ;
pls write the steps

I think your questions is answered here.
To translate this answer to your example, it would be something like this:
var textFile = null,
makeTextFile = function (text) {
var data = new Blob([text], {type: 'text/plain'});
// If we are replacing a previously generated file we need to
// manually revoke the object URL to avoid memory leaks.
if (textFile !== null) {
window.URL.revokeObjectURL(textFile);
}
textFile = window.URL.createObjectURL(data);
// returns a URL you can use as a href
return textFile;
};
// -------------
var create = document.getElementById('create');
create.addEventListener('click', function () {
var link = document.createElement('a');
link.setAttribute('download', 'XXXXX.vcf' /* set your vcf name here*/);
link.href = makeTextFile(
mycard.getFormattedString()
);
document.body.appendChild(link);
// wait for the link to be added to the document
window.requestAnimationFrame(function () {
var event = new MouseEvent('click');
link.dispatchEvent(event);
document.body.removeChild(link);
});
}, false);

I have not used vcard.js myself but by reading the README at github (https://github.com/enesser/vCards-js#on-the-web) you only redirect the user to the url of the endpoint where you generate the vcard. Something like this:
Nodejs:
var express = require('express');
var router = express.Router();
module.exports = function (app) {
app.use('/vcard', router);
};
router.get('/', function (req, res, next) {
var vCardsJS = require('vcards-js');
var vCard = vCardsJS();
// Create your vcard here
res.send(vCard.getFormattedString());
});
Front end:
window.location = "/vcard"

Related

Discord.js - 'Not a well formed URL' in embed

In Node.js, I'm trying to send an image as the thumbnail in the top right of an embed. But if I just put the url as it is into the embed.setThumbnail() function, the image loads forever or cannot be loaded. The url would be this one:
https://static-cdn.jtvnw.net/ttv-boxart/./Oddworld:%20Abe%27s%20Oddysee-140x180.jpg
I noticed that the special characters are making problems because urls without those work perfectly fine. So I tried to encode the url with
const querystring = require('querystring');
var boxart_url = 'https://static-cdn.jtvnw.net/ttv-boxart/./Oddworld:%20Abe%27s%20Oddysee-140x180.jpg';
const embed = new Discord.MessageEmbed();
embed.setThumbnail(querystring.stringify(boxart_url));
But this still gives me the same error. The same goes when I try to encode the filename in the url only or when I try to use querystring.escape(boxart_url). So do you know, how to encode the url? :)
Edit: As mentioned by Karizma, I tried to send the embed with just the url as the following:
const boxart_url = "https://static-cdn.jtvnw.net/ttv-boxart/./Oddworld:%20Abe%27s%20Oddysee-140x180.jpg";
const embeded = new Discord.MessageEmbed();
embeded.setThumbnail(boxart_url);
message.channel.send({embed: embeded});
The problem remains the same (https://imgur.com/a/swoSweH)
Edit: After some experimenting, I at least found, that the spaces are not the problem. It's the colon and apostrophy. I tried several stuff with this, like replacing the apostrophy with
var boxart_url = "https://static-cdn.jtvnw.net/ttv-boxart/./" + encodeURIComponent("Oddworld: Abe's Oddysee-140x180.jpg").replace(/'/g, '%23');
or different version of encodeURI() / encodeURIComponent() and I also tried to use a simple object as embed like
const embeded = {
thumbnail: {
url: boxart_url
}
}
but nothing worked so far.
Edit: I came across my own solution. I cannot retrieve the image from the url with the embeds so I download the image locally before and then use this image as attachment for the embed. This seems to work :) i'll share the code here in case somebody else has the same problem.
const request = require('request'); //depricated !
const fs = require('fs');
const directory = "../data/images/boxart/";
var download = function(url, filename, callback){
request.head(url, function(err, res, body){
request(url).pipe(fs.createWriteStream(filename)).on('close', callback);
});
};
download('https://static-cdn.jtvnw.net/ttv-boxart/./Oddworld:%20Abe%27s%20Oddysee-70x99.jpg', directory + 'oddysee.jpg', function(){
console.log('image downloaded');
});
let boxart_url = "data/images/boxart/oddysee.jpg"; // locally
const filename = boxart_url.substring( boxart_url.lastIndexOf('/') + 1 );
const file = new Discord.MessageAttachment(boxart_url);
const embeded = new Discord.MessageEmbed();
embeded.setThumbnail('attachment://'+filename);
message.channel.send({files: [file], embed: embeded});

Get Download Url after firebase's resize extension completed

This is what I am trying to achieve, implement the firebase's resize image extension, upload an image, then when the resize is completed, add that dowloadUrl's thumbs to a Cloud Firestore document. This question helps me, but still can not identify the thumbs and get the download URL, this is what am have been trying so far.
Note: I set my thumbnail to be at root/thumbs
const functions = require('firebase-functions');
const { Storage } = require('#google-cloud/storage');
const storage = new Storage();
exports.thumbsUrl = functions.storage.object().onFinalize(async object => {
const fileBucket = object.bucket;
const filePath = object.name;
const contentType = object.contentType;
if (fileBucket && filePath && contentType) {
console.log('Complete data');
if (!contentType.startsWith('thumbs/')) {
console.log('This is not a thumbnails');
return true;
}
console.log('This is a thumbnails');
} else {
console.log('Incomplete data');
return null;
}
});
Method 1 : Client Side
Don't change the access token when creating the thumbnail.
Edit the function from gcloud cloud function console
Go to the function code by clicking detailed usage stats
Then click on code
Edit the following lines
Redeploy the function again
// If the original image has a download token, add a
// new token to the image being resized #323
if (metadata.metadata.firebaseStorageDownloadTokens) {
// metadata.metadata.firebaseStorageDownloadTokens = uuidv4_1.uuid();
}
Fetch the uploaded image using getDownloadURLfunction
https://firebasestorage.googleapis.com/v0/b/<project_id>/o/<FolderName>%2F<Filename>.jpg?alt=media&token=xxxxxx-xxx-xxx-xxx-xxxxxxxxxxxxx
Because the access token will be similar
https://firebasestorage.googleapis.com/v0/b/<project_id>/o/<FolderName>%2Fthumbnails%2F<Filename>_300x300.jpg?alt=media&token=xxxxxx-xxx-xxx-xxx-xxxxxxxxxxxxx
Method 2: Server Side
Call this function after thumbnail is created
var storage = firebase.storage();
var pathReference = storage.ref('users/' + userId + '/avatar.jpg');
pathReference.getDownloadURL().then(function (url) {
$("#large-avatar").attr('src', url);
}).catch(function (error) {
// Handle any errors
});
you need to use filePath for checking the thumbs
if(filePath.startswith('thumbs/'){...}
contentType has the metadata of files like type of image and etc.
FilePath will have the full path.

How to save the downloadable file link in zombie.js

I am scrapping a website using node.js and zombie.js. I am facing an issue where in a file I have an anchor which holds the link to download a pdf file.
If I click it using browser.clickLink() function, the result that I get in console is beyond my understanding. Is there a way to save this pdf file and have its link like in php? I want to save it for further processing. Here is my test js code
var http = require('http');
var browser = require('zombie');
var assert = require('assert');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
//res.setHeader('Content-Type', 'text/plain');
//res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
var url = 'http://localhost/Node/HM_LandRegistry/downloadPdf.html'
browser.visit(url, function(error,browser) {
//browser.dump();
//console.log('browser.text (".link")', browser.text(".link"));
browser.clickLink("a.link");
browser.wait().then(function(){
console.log(browser.text());
browser.dump();
});
});
Here is something I found on google groups. It has solved my problem.
function getLinks(browser) {
var links = browser.querySelectorAll('.link');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href'); // returns an array. Use .toString() to get string only
});
}
Save the link

nodejs variable scope issue

I have a nodejs route where I am trying to download a url as mp3 using npm-youtube-dl. I have a download directory that I watch with chokidar for files being added and when a file is added I save the link to the file and after the download finishes I call a function that's supposed to respond with the download URL using res.download. When the sendURL function is called the url that I can clearly see has been saved before is undefined when I console.log it... Any idea what i'm doing wrong here/how I can fix this? i'm guessing it's a js variable scope issue?
my code:
var express = require('express');
var router = express.Router();
var yt = require('youtube-dl');
var fs = require('fs');
var path = require('path');
var chokidar = require('chokidar');
var downloadPath = '';
var watcher = chokidar.watch('./downloads', {
ignored: '/^[^.]+$|\.(?!(part)$)([^.]+$)/',
persistent: true
});
watcher.on('add', function(path) {
console.log('added: ', path);
this.downloadPath = path;
console.log('saved', this.downloadPath);
});
/*
router.get('/', function(req, res, next) {
next();
});
*/
router.get('/', function(req, res) {
var url = 'https://soundcloud.com/astral-flowers-music/bella-flor';
var options = ['-x', '--audio-format', 'mp3', '-o', './downloads/%(title)s.%(ext)s'];
var video = yt.exec(url, options, {}, function exec(err, output) {
if (err) { throw err; }
console.log(output.join('\n'));
sendUrl();
});
function sendUrl() {
console.log(this.downloadPath);
//res.download(this.downloadPath);
}
});
module.exports = router;
You're misusing this. If you want to use the downloadPath variable in your functions, remove the this. from in front of them. this.downloadPath looks for a property called downloadPath on an object referenced by this, which is different from your module-global variable.
More: How does the "this" keyword work?
Even with that, you're relying on your add callback having been called before any client requests your / route, and you're returning the last value assigned to downloadPath by that add callback. I don't know enough about what you're doing to know whether that's correct, but the lack of coordination seems problematic.

Scraping JavaScript-generated website with Node.js [duplicate]

This question already has answers here:
How can I scrape pages with dynamic content using node.js?
(5 answers)
Closed last month.
When I parse a static html page, my node.js app works well. However, when the url is a JavaScript-generated page, the app doesn't work. How can I scrape a JavaScript-generated web page?
My app.js
var express = require('express'),
fs = require('fs'),
request = require('request'),
cheerio = require('cheerio'),
app = express();
app.get('/scrape', function( req, res ) {
url = 'http://www.apache.org/';
request( url, function( error, response, html ) {
if( !error ) {
var $ = cheerio.load(html);
var title, release, rating;
var json = { title : "" };
$('body').filter(function() {
var data = $(this);
title = data.find('.panel-title').text();
json.title = title;
})
}
fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
console.log( 'File successfully written! - Check your project directory for the output.json file' );
});
// Finally, we'll just send out a message to the browser reminding you that this app does not have a UI.
res.send( 'Check your console!' );
});
});
app.listen('8081');
console.log('Magic happens on port 8081');
exports = module.exports = app;
Cheerio won't execute the javascript on the page as it's just made for parsing plain HTML.
I'd suggest a different approach using something like PhantomJS: http://phantomjs.org/

Categories

Resources