i am building a nodejs application built using nodejs and express.
the application basically works as a REST URL Calls. front end is written in angularjs.
currently i have to built an application which can play sound and display its text. for simplicity purpose we have extracted the text from the wav file and placed it inside another folder.
In one folder we have a collection of wav files running into thousands and in another folder on same level we have a text files containing all the text
WAV (FOLDER)
TEXT (FOLDER)
Under WAV folder i have a file
2044197581O0140602 - zIgnacio, Ohmar.wav
Under Text Folder i have the same file containing its speect text
2044197581O0140602-zIgnacio,Ohmar.txt
This is exact filename. The problem is that i have to built a system so that all these files can be displayed on the front end . and while playing its text should be shown.(timing is not important here).
I an using nodejs. i know that i cannot upload thousands file from front end. so it has to be done from back end.
can there be a where i can merge both these files into meaningful JSON JS objects and also return the Object URL using nodejs.
Please suggest any good way to handle this architecture using nodejs
I have written this
function FolderReaderMerger(path,pathToMerge,cb)
{
log("Reading File/Folder");
fs.readdir(path, function(err, files1)
{
fs.readdir(pathToMerge, function(err, files2)
{
log(files1);
log(files2);
var obj ={};
obj.wav = (files1);
obj.wavText = (files2);
cb(obj);
});
});
}
but i need to convert wav file conplete path as a URL and add it to JSON. sp that i can hit that url and play that file browser side. any help
TO call above function
FolderReaderMerger(WAV,TEXT,function(res)
{
log("COMBINED FILES");
log(res);
log(res.length);
global.combined = res;
});
And a get URL
app.get("/api/getCombinedFiles",function(req,res)
{
res.send(global.combined);
});
I am able to get the list of files from both folder. But i need to play the audio files on the client side
I had been able to come up with this. i send the file using teh URL sendFile="some file" and then the node checks for that file. if successful i start getting the stream on my client side and i put it directly into video src. But i need morecontrol over this. such as when user click on certain timeline so that i can directly start strweaming from there.
app.get is used to get the location of the folder where i store the files.
used just express and nodejs
function FolderReaderMerger(path,pathToMerge,cb)
{
log("Reading File/Folder To Combine : ");
fs.readdir(path, function(err, audio)
{
fs.readdir(pathToMerge, function(err, audioText)
{
var obj ={};
global.list.audio =audio;
global.list.audioText =audioText;
obj.audio = audio;
obj.audioText = audioText;
cb(obj);
});
});
}
app.get("/audio",function(req,resp)
{
log("App Audio File Serv : ");
var playFile = req.param("playFile");
var filePath = {};
filePath.status =false;
if(playFile!=undefined)
{
log("Params File : "+playFile);
/* log("Requested URL : "+req.url);
log("Total Audio Files : "+global.list.audio.length);*/
var i =0;
while(i!=global.list.audio.length)
{
if(playFile==global.list.audio[i])
{
log("File Found : "+playFile);
//get files location
log(app.get("audioPath")+playFile);
filePath.status = true;
var filePath = app.get("audioPath")+playFile;
log("FILE PATH : "+filePath);
var stat = fs.statSync(filePath);
log(stat);
log(stat.size);
resp.writeHead(200, {
'Content-Type': 'audio/mpeg',
'Content-Length': stat.size
});
var readStream = fs.createReadStream(filePath);
// We replaced all the event handlers with a simple call to readStream.pipe()
log("Streaming.......");
readStream.pipe(resp);
}
else
{
log("Requested Resource Not Found");
}
i+=1;
}
//readStream = fs.createReadStream(app.get("audioPath"));
}
else
{
log("Requested Params Not Found");
resp.send(filePath);
}
});
http.listen(app.get("PORT"),function()
{
consolelog("--------------------------------------------------------");
console.log("Server Started On PORT: "+app.get("PORT"));
console.log("All NPM Initialized");
console.log("Please Wait Checking Connection Status...");
console.log("--------------------------------------------------------");
});
ANy help would be appreciated.
Related
I can get an SVG file downloaded, additionally, I can display svg files as you would normally within an image tag. I do not know how to access the folder location for downloads or the wgt-private folder so I may download images to a client's watch and then use the downloaded version.
I'm sure my file is downloading as I've console logged on successful download and when I list the items in the directory the file shows up.
Placing downloads/[filename] or wgt-private/[filename] does not appear to work as these are virtual file locations however I've no idea how to access these files within the application without using the filesystem methods.
Download:
var download_obj = new tizen.DownloadRequest('someFile.svg', 'wgt-private');//Hidden the actual location however this file does display when enterting the whole file location
tizen.download.start(download_obj, {
onprogress: function(id, receivedSize, totalSize) {
console.log(id);
console.log(receivedSize);
console.log(totalSize);
},
onpaused: function(id) {
console.log(id);
},
oncanceled: function(id) {
console.log(id);
},
oncompleted: function(id, fullPath) {
console.log(id);
console.log(fullPath);
},
onfailed: function(id, error) {
console.log(id);
console.log(JSON.stringify(error));
}
});
Full path comes out as: wgt-private/someFile.svg
Doesn't display as displays a file error in the console on all attempts.
I understand that your questions relates to how to show the image downloaded with tizen.download API in html img tag.
I can see two workarounds that could help you with it:
You can use filesystem API (which you would like to avoid), BUT since 5.0 there is a method which needs no additional privileges and I hope it will match your needs - FileSystemManager.toURI(). It just gets the path to file (returned by download API) and returns the full URI, able to be used in img.
I noticed that download to non-public directories on the device, download API returns the 'hidden' path which uses virtual root, but when downloading to public directory as 'downloads', the full path is returned and it works for img as well.
If both of above is not acceptable for you, I am afraid that the only alternative is to use regular tizen.filesystem API and resolve the path from download API and then use File.toURI() function to get the path.
var link = "http://techslides.com/demos/samples/sample.jpg"
var download_obj = new tizen.DownloadRequest(link, 'wgt-private');//Hidden the actual location however this file does display when enterting the whole file location
tizen.download.start(download_obj, {
oncompleted: function(id, fullPath) {
console.log("completed " + id + " : " + fullPath);
tizen.filesystem.resolve(fullPath, (s)=>{console.log("Resovled full path: " + s.toURI())}, (e) => {console.log(e)})
},
onfailed: function(id, error) {
console.log("failed " + id);
console.log(JSON.stringify(error));
}
});
You can find the proper web sample app: new Tizen project - Sample - Mobile 4.0 - Web application - Content - Download Manager
Open index.html and replace https://www.sample-videos.com/video/mkv/720/big_buck_bunny_720p_10mb.mkv with your file address.
I am attempting to zip the contents of two directories and download the resulting .zip file. One directory contains .txt files and the other .jpg. I am using archiver to zip the files and running the express framework on node js. I am inclined to think that the problem exists in the download step, as the resulting zipped file that is created in the project root expands as expected, however when the file is downloaded, I get an "Error 2 - No such file or directory."
app.get('/download',function(req, res){
zipFile = new Date() + "-Backup.zip";
var output = fs.createWriteStream(__dirname +"/backups/"+ zipFile);
var archive = archiver('zip');
output.on('close', function() {
console.log(archive.pointer() + ' total bytes');
console.log('archiver has been finalized and the output file descriptor has closed.');
});
archive.on('error', function(err) {
throw err;
});
archive.pipe(output);
var files1 = fs.readdirSync(__dirname+'/posts');
var files2 = fs.readdirSync(__dirname+'/uploads');
for(var i = 0; i< files1.length; i++){
archive.append(fs.createReadStream(__dirname+"/posts/"+files1[i]), { name: files1[i] });
}
for(var i = 0; i< files2.length; i++){
archive.append(fs.createReadStream(__dirname+"/uploads/"+files2[i]), { name: files2[i] });
}
archive.finalize();
res.download(__dirname + "/backups/" + zipFile, zipFile);
});
zipFile is a global variable.
The on 'close' logs fire properly and no errors occur, but the file will not open after being downloaded. Is there an issue with response headers or something else I am unaware of?
Thanks for the help.
I solved my own problem using node-zip as the archive utility.
var zip = require('node-zip')(); // require the node-zip utility
var fs = require('fs'); // I use fs to read the directories for their contents
var zipName = "someArbitraryName.zip"; // This just creates a variable to store the name of the zip file that you want to create
var someDir = fs.readdirSync(__dirname+"/nameOfDirectoryToZip"); // read the directory that you would like to zip
var newZipFolder = zip.folder('nameOfDirectoryToZip'); // declare a folder with the same name as the directory you would like to zip (we'll later put the read contents into this folder)
//append each file in the directory to the declared folder
for(var i = 0; i < someDir.length,i++){
newZipFolder.file(someDir[i], fs.readFileSync(__dirname+"/nameOfDirectoryToZip/"+someDir[i]),{base64:true});
}
var data = zip.generate({base64:false,compression:'DEFLATE'}); //generate the zip file data
//write the data to file
fs.writeFile(__dirname +"/"+ zipName, data, 'binary', function(err){
if(err){
console.log(err);
}
// do something with the new zipped file
}
Essentially, what is happening can broken down into 3 steps:
Use fs to read the contents of a directory that you would like to zip.
Use zip.folder to declare the folder, then use zip.file to append files to that directory. I just used a for loop to iteratively add each file in the directory that was read in step 1.
Use zip.generate to create the .zip file data, and write it to file using fs.
The resulting file can be downloaded or whatever you would like to do with it. I have seen no issues using this method.
If you want to zip more than one directory, just repeat steps 1 and 2 before you zip.generate, creating a new zip.folder for each directory.
Just use
archive.on("finish",function(){
res.download(__dirname + "/backups/" + zipFile);
})
I want add all MP3 files into a list in JavaScript.
and set one Song after another as
var foo=new Sound("/Users/alexw/Music/test.mp3",100,true);
You can't access data files from your file system via Javascript, it's a security issue
https://en.wikipedia.org/wiki/JavaScript#Security
EDIT:
to access files there's 2 solution:
using a custom DLL (for ex. made with C# in Internet Explorer) you can load via javascript that list your computer files
using a local web service (for ex. made with Node.js) to list your files and stream them if you want online
I use node walk, it works!
function getAllFilesFromFolder(){
var walk = require('walk');
var files = [];
// Walker options
var walker = walk.walk("/Users/alexw/Music", { followLinks: false });
walker.on('file', function(root, stat, next) {
// Add this file to the list of files
files.push(root + '/' + stat.name);
next();
});
walker.on('end', function() {
console.log(files);
});
}
I'm building a web app using Node.JS that at the very least should allow users to to upload excel spreadsheets (.xlsx) and then using an excel parser (currently using node-xlsx - https://www.npmjs.org/package/node-xlsx), I want to be able to find this file, parse it, and print its contents to the console. So far, I have the file uploaded and stored, but am having trouble specifying the file path my app should search down.
I believe my troubles are that I am trying to do this on the server-side, and I am telling my app to search through a users directory for this file when it does not have access.
Here is example code:
var fullfile;
app.post('/upload', function (request, response) {
var fstream;
request.pipe(request.busboy);
request.busboy.on('file', function (fieldname, file, filename) {
console.log('Uploading: ' + filename);
fstream = fs.createWriteStream('./storedFiles/' + filename);
file.pipe(fstream);
fstream.on('close', function () {
response.redirect('success');
console.log('Uploaded to ' + fstream.path);
fullfile=fstream.name;
var obj = xlsx.parse(__dirname + fullfile);
console.log(obj);
});
});
});
This produces the error:
return binding.open(pathmodule._makelong(path) stringtoflags(flags) mode)
error: ENOENT, no such file or directory 'C\Users(file path on my local machine here)
Can anyone point out a way of doing this that I am missing? it has to do with fs methods I feel.
Thank you
First of all, don't use the filename that user provided when saving the file - you will get duplicates and it could be a security risk (in general, never trust user provided data). Just use your own value instead - it is more standard to use your own naming convention to prevent duplicates or to use a tmp file provided by the OS.
To solve your issue, try:
Requiring path at the top of your file:
var path = require('path');
and changing the value of fullfile to:
fullfile = path.join(__dirname,fstream.path)
then pass fullfile to xlsx.parse:
var obj = xlsx.parse(fullfile);
I have a js program in which I would like to build a link to a file in a specific directory. However, the js program does not know if the file will be .html, .xls .doc or .docx or others. All it knows is the directory and the first part of the filename. I have control of that directory and there will only be one file there with that first part.
Is there anyway to do this?
No. You can try these different file endings and check if the server returns something or a 404 instead. Otherwise you have the implement some logic on the server to check the directory.
This is not a good practice and I am not recommending it, but sure it can be done: Live demo (click).
//list each file name you want to find
var files = ['some-file', 'some-other-file'];
//list possible extensions
var exts = ['html', 'doc'];
//iterate each file name
$.each(files, function(index, file) {
//attempt to get the file
//pass a copy of the "exts" array so that each function can "shift" through it
getFile(file, exts.slice());
});
function getFile(file, exts) {
//the filename to try (added extension)
var newFile = file+'.'+exts.shift();
//try to get the file
$.get(newFile).then(function(data) {
//found the file - do something with the contents
foo(data);
}, function() {
//file not found
//if there are any extensions left to try
if (exts.length) {
//try again (will shift to next extension)
getFile(file, exts);
}
});
}
function foo(data) {
var div = document.createElement('div');
div.textContent = data;
document.body.appendChild(div);
}
Only with javascript you can't access any files because security reasons reference here,
but you can create an ActiveX for Internet Explorer only.