How to download multiple audio filles in JsZip - javascript

I want to download all audio files from folder but this code only download last file in folder.
var element = document.getElementById("songs");
var audionum = element.getElementsByTagName('audio').length;
var zipcounter = 0;
var zip = new JSZip();
var zipName = 'Test.zip';
for(var i = 0; i < audionum; i++){
var audiosrc = document.getElementsByTagName('source')[i].getAttribute("src");
var audiosrcsplit = audiosrc.split('/')[1];
// loading a file and add it in a zip file
JSZipUtils.getBinaryContent(audiosrc, function (err, data) {
if(err) {
throw err; // or handle the error
}
zip.file(audiosrcsplit, data, {binary:true});
zipcounter++;
if (zipcounter == audionum) {
zip.generateAsync({type:'blob'}).then(function(content) {
saveAs(content, zipName);
});
}
});
}

For ES6 , you can try replacing var with let (block scope).
If you are making use of ES5 then, try something like below.
var element = document.getElementById("songs");
var audionum = element.getElementsByTagName('audio').length;
var zipcounter = 0;
var zip = new JSZip();
var zipName = 'Test.zip';
function addToZip(audiosrc, audiosrcsplit) {
JSZipUtils.getBinaryContent(audiosrc, function (err, data) {
if (err) {
throw err; // or handle the error
}
zip.file(audiosrcsplit, data, {
binary: true
});
zipcounter++;
if (zipcounter == audionum) {
zip.generateAsync({
type: 'blob'
}).then(function (content) {
saveAs(content, zipName);
});
}
});
}
for (var i = 0; i < audionum; i++) {
var audiosrc = document.getElementsByTagName('source')[i].getAttribute("src");
var audiosrcsplit = audiosrc.split('/')[1]; // loading a file and add it in a zip file
addToZip(audiosrc, audiosrcsplit);
}

Related

Javascript: How to encrypt a zip file with RSA

I'm using Cryptico to handle RSA encryption for chat but I'm running into trouble trying to encrypt a zip file after construction. I see the constructed file in the console. The console shows an encrypted string of the file but returns blank after decryption in the console.
Note: my decryption method works properly with text and base64
$(document).on("change", "#chatImage", function() {
var rid = $(this).closest(".chat").data("id");
var files = this.files;
var zip = new JSZip();
for (var i = 0; i < files.length; i += 1) {
var file = files[i];
zip.file(file.name, file);
console.log("added", file.name);
// console.log(file);
}
var eImgArray = {};
$.ajax({
url : ajax_object.ajax_url,
type : 'post',
data : {
action: 'get_room_member_keys',
rid : rid,
},
beforeSend: function() {
},
success: function(html) {
var pubKeys = $.parseJSON(html);
$.each( pubKeys, function( key, value ) {
var imgEncrypt = cryptico.encrypt(file, value);
var imgSrc = imgEncrypt.cipher;
eImgArray[key] = imgSrc;
});
var strImgArray = JSON.stringify(eImgArray);
$("#chatFormCont input[name=image_data]").val(strImgArray);
var foo = $("#chatFormCont input[name=image_data]").val();
// console.log(foo);
},
});
zip.generateAsync({type: "blob"}).then(function(content) {
function show_all_images(relpath, file) {
if (file.dir) {
return file.forEach(show_all_images);
}
var img = $("#chatImagePreview");
file.async("blob").then(function(blob) {
var src = window.URL.createObjectURL(blob);
img.attr("src", src);
});
}
new JSZip.loadAsync(content).then(zip => zip.forEach(show_all_images));
});
});

How to add an attachement to an email (not stored in file disk)

I want to open outlook with an attachement (zip) using Javascript.
It's working fine if the file in in some directory in the computer client.
this.sendEmail = function (zip) {
try {
var theApp = new ActiveXObject("Outlook.Application");
var objNS = theApp.GetNameSpace('MAPI');
var theMailItem = theApp.CreateItem(0); // value 0 = MailItem
theMailItem.to = ('test#gmail.com');
theMailItem.Subject = ('test');
theMailItem.Body = ('test');
theMailItem.Attachments.Add(zip);
theMailItem.display();
}
catch (err) {
alert(err.message);
}
};
But What I want to do is to add the file that I have alredy in memory
this.SenddZip = function (docDescription, fileName) {
var zip = new JSZip();
for (var i = 0; i < docDescription.length; i++) {
var doc = docDescription[i];
zip.file(doc.core_documenttitle + doc.core_fileextension, doc.fileBase64, { base64: true });
}
Utils.sendEmail(zip);
// Generate the zip file asynchronously
zip.generateAsync({ type: "blob" })
.then(function (content) {
// Force down of the Zip file
var name = "documents";
if (fileName) {
name = fileName;
}
// location.href = "data:application/zip;base64," + content;
saveAs(content, name + ".zip");
Utils.sendEmail(xxxxxxxx);
});
};
If their is no solution for this :
Is their a way to download the document without the confirmation dialog ?
saveAs ask always for confirmation before to store the file.
Thank you

node.js webtorrent collect all files by magnet link

I have not used node.js before.
Have a .txt file with list of magnet links.
Want to write a json file with list of all files contained in these links.
var WebTorrent = require('webtorrent');
var fs = require('fs');
var client = new WebTorrent();
var array = fs.readFileSync('yop.txt').toString().split("\n");
i = 0;
while (i < array.length) {
//console.log(array[i]);
var magnetURI = array[i];
n = 0;
client.add(magnetURI, function (torrent) {
torrent.files.forEach(function (file) {
//console.log( file.name)
jsonString = JSON.stringify({'book': file.name});
fs.appendFile("data.json", jsonString, function (err) {
if (err) {console.log(err);} else { n++ }
});
if (n == torrent.files.length) {i++ }
})
})
}
when run gives the following error
Sorry for such a terrible code.
var WebTorrent = require('webtorrent')
var fs = require('fs')
var stream = fs.createWriteStream("2.txt");
var client = new WebTorrent()
var array = fs.readFileSync('yop.txt').toString().split("\n");
i = 0;
function parseMagnet (uri){
var magnetURI = uri[i]
console.log(magnetURI)
client.add(magnetURI, function (torrent) {
torrent.files.forEach(function (file) {
writeStr = (uri[i]+ '\n'+ file.name+ '\n');
stream.write(writeStr);
console.log(file.name)
});
console.log('Done !')
console.log(i)
i += 1
parseMagnet(array);
client.remove(magnetURI);
})
}
parseMagnet(array)

base64 encoded image is corrupted when saved to disk

I am posting the base64 clipboard image to server (node) and I am saving the base64 to disk. For some reason the image is corrupted.
Client side logic of posting:
function sendData($http, clipboardImage) {
// $http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
// var imgData = JSON.stringify(clipboardImage);
//var data = {"imgdata" : clipboardImage};
var url = "http://localhost:3000/pad/img/";
$http({
method: 'POST',
url: url,
data: "data=" + clipboardImage
});
}
$("[ng-model='html']").delegate("p", "paste", function(event) {
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
console.log(JSON.stringify(items)); // will give you the mime types
// find pasted image among pasted items
var blob = null;
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") === 0) {
blob = items[i].getAsFile();
}
}
// load image if there is a pasted image
if (blob !== null) {
var reader = new FileReader();
reader.onload = function(e) {
sendData($http, e.target.result);
};
reader.readAsDataURL(blob);
}
});
Server logic:
app.post("/pad/img/", function(req, res) {
var imgB64Data = req.body.data;
var decodedImg = decodeBase64Image(imgB64Data);
var imageBuffer = decodedImg.data;
var type = decodedImg.type;
var extension = mime.extension(type);
var fileName = "image." + extension;
try {
fs.writeFile(fileName, imageBuffer, function(err) {
console.log(err);
});
} catch (err) {
console.error(err);
}
});
function decodeBase64Image(dataString) {
var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/),
response = {};
if (matches.length !== 3) {
return new Error('Invalid input string');
}
response.type = matches[1];
response.data = new Buffer(matches[2], 'base64');
return response;
}
The image is being saved successfully but it seems to be corrupted. Can you please point out what may be missing?
Have you tried explicitly setting the file encoding when calling fs.writeFile?
try {
fs.writeFile(fileName, imageBuffer, {encoding:'utf8'}, function(err) {
console.log(err);
});
} catch (err) {
console.error(err);
}
NodeJS Docs: fs.writeFile(filename, data\[, options\], callback)

How can I get node.js to return data once all operations are complete

I am just learning server-side JavaScript so please bear with any glaring mistakes I've made.
I am trying to write a file parser that operates on HTML files in a directory and returns a JSON string once all files have been parsed. I started it with a single file and it works fine. it loads the resource from Apache running on the same machine, injects jquery, does the parsing and returns my JSON.
var request = require('request'),
jsdom = require('jsdom'),
sys = require('sys'),
http = require('http');
http.createServer(function (req, res) {
request({uri:'http://localhost/tfrohe/Car3E.html'}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var window = jsdom.jsdom(body).createWindow();
jsdom.jQueryify(window, 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js', function (window, jquery) {
// jQuery is now loaded on the jsdom window created from 'body'
var emps = {};
jquery("tr td img").parent().parent().each(function(){
var step = 0;
jquery(this).children().each(function(index){
if (jquery(this).children('img').attr('src') !== undefined) {
step++;
var name = jquery(this).parent().next().next().children('td:nth-child('+step+')').children().children().text();
var name_parts = name.split(",");
var last = name_parts[0];
var name_parts = name_parts[1].split(/\u00a0/g);
var first = name_parts[2];
emps[last + ",_" + first] = jquery(this).children('img').attr('src');
}
});
});
emps = JSON.stringify(emps);
//console.log(emps);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(emps);
});
} else {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("empty");
//console.log(response.statusCode);
}
});
}).listen(8124);
Now I am trying to extend this to using the regular file system (fs) and get all HTML files in the directory and parse them the same way and return a single combined JSON object once all files have been parsed. Here is what I have so far but it does not work.
var sys = require("sys"),
fs = require("fs"),
jsdom = require("jsdom"),
emps = {};
//path = '/home/inet/www/media/employees/';
readDirectory = function(path) {
fs.readdir(path, function(err, files) {
var htmlfiles = [];
files.forEach(function(name) {
if(name.substr(-4) === "html") {
htmlfiles.push(name);
}
});
var count = htmlfiles.length;
htmlfiles.forEach(function(filename) {
fs.readFile(path + filename, "binary", function(err, data) {
if(err) throw err;
window = jsdom.jsdom(data).createWindow();
jsdom.jQueryify(window, 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js', function (window, jquery) {
jquery("tr td img").parent().parent().each(function(){
var step = 0;
jquery(this).children().each(function(index){
if (jquery(this).children('img').attr('src') !== undefined) {
step++;
var empname = jquery(this).parent().next().next().children('td:nth-child('+step+')').children().children().text();
var name_parts = empname.split(",");
var last = name_parts[0];
var name_parts = name_parts[1].split(/\u00a0/g);
var first = name_parts[2]
emps[last + ",_" + first] = jquery(this).children('img').attr('src');
}
});
});
});
});
});
});
}
readDirectory('/home/inet/www/media/employees/', function() {
console.log(emps);
});
In this particular case, there are 2 html files in the directory. If i console.log(emps) during the htmlfiles.forEach() it shows me the results from the first file then the results for both files together the way I expect. how do I get emps to be returned to readDirectory so i can output it as desired?
Completed Script
After the answers below, here is the completed script with a httpServer to serve up the detail.
var sys = require('sys'),
fs = require("fs"),
http = require('http'),
jsdom = require('jsdom'),
emps = {};
var timed = setInterval(function() {
emps = {};
readDirectory('/home/inet/www/media/employees/', function(emps) {
});
}, 3600000);
readDirectory = function(path, callback) {
fs.readdir(path, function(err, files) {
var htmlfiles = [];
files.forEach(function(name) {
if(name.substr(-4) === "html") {
htmlfiles.push(name);
}
});
var count = htmlfiles.length;
htmlfiles.forEach(function(filename) {
fs.readFile(path + filename, "binary", function(err, data) {
if(err) throw err;
window = jsdom.jsdom(data).createWindow();
jsdom.jQueryify(window, 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js', function (window, jquery) {
var imagecount = jquery("tr td img").length;
jquery("tr td img").parent().parent().each(function(){
var step = 0;
jquery(this).children().each(function(index){
if (jquery(this).children('img').attr('src') !== undefined) {
step += 1;
var empname = jquery(this).parent().next().next().children('td:nth-child('+step+')').children().children().text();
var name_parts = empname.split(",");
var last = name_parts[0];
var name_parts = name_parts[1].split(/\u00a0/g);
var first = name_parts[2]
emps[last + ",_" + first] = jquery(this).children('img').attr('src');
}
});
});
count -= 1;
if (count <= 0) {
callback(JSON.stringify(emps));
}
});
});
});
});
}
var init = readDirectory('/home/inet/www/media/employees/', function(emps) {
});
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(JSON.stringify(emps));
}).listen(8124);
That sure is a lot of code a couple of mistakes.
You're never calling the callback function you supply to readDirectory
You need to keep track of the files you have parsed, when you parsed all of them, call the callback and supply the emps
This should work:
var sys = require("sys"),
fs = require("fs"),
jsdom = require("jsdom"),
//path = '/home/inet/www/media/employees/';
// This is a nicer way
function readDirectory(path, callback) {
fs.readdir(path, function(err, files) {
// make this local
var emps = {};
var htmlfiles = [];
files.forEach(function(name) {
if(name.substr(-4) === "html") {
htmlfiles.push(name);
}
});
// Keep track of the number of files we have parsed
var count = htmlfiles.length;
var done = 0;
htmlfiles.forEach(function(filename) {
fs.readFile(path + filename, "binary", function(err, data) {
if(err) throw err;
window = jsdom.jsdom(data).createWindow();
jsdom.jQueryify(window, 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js', function (window, jquery) {
jquery("tr td img").parent().parent().each(function(){
var step = 0;
jquery(this).children().each(function(index){
if (jquery(this).children('img').attr('src') !== undefined) {
step++;
var empname = jquery(this).parent().next().next().children('td:nth-child('+step+')').children().children().text();
var name_parts = empname.split(",");
var last = name_parts[0];
var name_parts = name_parts[1].split(/\u00a0/g);
var first = name_parts[2]
emps[last + ",_" + first] = jquery(this).children('img').attr('src');
}
});
});
// As soon as all have finished call the callback and supply emps
done++;
if (done === count) {
callback(emps);
}
});
});
});
});
}
readDirectory('/home/inet/www/media/employees/', function(emps) {
console.log(emps);
});
You seem to be doing this a tad wrong
readDirectory('/home/inet/www/media/employees/', function() {
console.log(emps);
});
But you've defined your function as:
readDirectory = function(path) {
Where is the callback argument? Try this:
readDirectory = function(path, callback) {
then under emps[last + ",_" + first] = jquery(this).children('img').attr('src'); put
callback.call(null, emps);
Your callback function will be called however many times your loop goes on for. If you want it to return all of them at once, you'll need to get a count of how many times the loop is going to run for, count up until that number then call your callback when the emps array is full of the data you need.

Categories