Harshit Laddha
Harshit Laddha

Reputation: 2124

checking if busboy finish event has already occured or not

I have a form in which I am expected to do some file processing which takes some time, so I want that finish event executes only after the processing is complete, right now node is processing the file and while it is processing the file and executes commands node if finds finish event it fires it. so, how do i make sure that the finish event is fired only after processing of all files.

busboy.on('file', function(fieldname, file, filename,transferEncoding,mimeType) {
        var fName = uuid.v4();
        var fileext = filename.substr(filename.lastIndexOf('.') + 1);
        var filepath = path.normalize(__dirname + '/../../');
        var fstream = fs.createWriteStream(filepath+'/server/uploads/'+fName+'.'+fileext);
        var uploadFileCompletion = file.pipe(fstream);
        uploadFileCompletion.on('finish',function(){
            console.log('uploaded now');
            var cmd = 'libreoffice --headless --convert-to pdf --outdir '+ filepath + 'server/uploads ' + filepath + 'server/uploads/' + fName + '.' + fileext;
            exec(cmd, function(error,stdout,stderr){
                sys.puts(stdout);
                var encryptCmd = 'java -jar server/uploads/pdfbox-app-1.8.6.jar Encrypt -canAssemble false -canExtractContent false -canExtractForAccessibility false ' +
                    '-canModify false -canModifyAnnotations false -canPrint false -canPrintDegraded false server/uploads/' + fName + '.' + 'pdf'
                    + ' ' + 'server/uploads/' +fName + '.' + 'pdf';
                exec(encryptCmd, function(error,stdout,stderr){
                    fs.unlink(filepath+'server/uploads/'+fName + '.' + fileext, function(){
                        console.log("removed " +filepath+'server/uploads/'+fName + '.' + fileext);
                        actualFileName.push(filename);
                        storedFileName.push(fName+'.'+'pdf');
                    });
                });

            });
        });
    });
    busboy.on('field', function(fieldname, val, valTruncated,keyTruncated) {
        noteData = JSON.parse(val);
    });
    busboy.on('finish',function(){
        noteData.uploader = req.user.username;
        noteData.actualFileName = actualFileName;
        noteData.storedFileName = storedFileName;
        noteData.noteId = uuid.v4();
        Campusnotes.create(noteData,function(err,note){
            if(err){
                res.status(400);
                return res.send({reason:err.toString()});
            }
            console.log('finish');
            res.status(200);
            res.end();
        })
    });

now the console log for this is as follows -

finish
uploaded now
convert /home/unknown/public_html/campustop/server/uploads/8465f9a9-d6b7-4d53-8cb5-a8dbf3aed6a5.odt -> /home/unknown/public_html/campustop/server/uploads/8465f9a9-d6b7-4d53-8cb5-a8dbf3aed6a5.pdf using writer_pdf_Export

removed /home/unknown/public_html/campustop/server/uploads/8465f9a9-d6b7-4d53-8cb5-a8dbf3aed6a5.odt

indicating that the finish event is getting fired again and again

Upvotes: 0

Views: 970

Answers (1)

mscdex
mscdex

Reputation: 106736

You could try something like:

var files = 0;
busboy.on('file', function(fieldname, file, filename,transferEncoding,mimeType) {
  ++files;
  var fName = uuid.v4();
  var fileext = filename.substr(filename.lastIndexOf('.') + 1);
  var filepath = path.normalize(__dirname + '/../../');
  var fstream = fs.createWriteStream(filepath+'/server/uploads/'+fName+'.'+fileext);
  file.pipe(fstream).on('finish',function() {
    console.log('uploaded now');
    var cmd = 'libreoffice --headless --convert-to pdf --outdir '+ filepath + 'server/uploads ' + filepath + 'server/uploads/' + fName + '.' + fileext;
    exec(cmd, function(error,stdout,stderr) {
      console.log(stdout);
      var encryptCmd = 'java -jar server/uploads/pdfbox-app-1.8.6.jar Encrypt -canAssemble false -canExtractContent false -canExtractForAccessibility false ' +
          '-canModify false -canModifyAnnotations false -canPrint false -canPrintDegraded false server/uploads/' + fName + '.' + 'pdf'
          + ' ' + 'server/uploads/' +fName + '.' + 'pdf';
      exec(encryptCmd, function(error,stdout,stderr) {
        fs.unlink(filepath+'server/uploads/'+fName + '.' + fileext, function() {
          console.log("removed " +filepath+'server/uploads/'+fName + '.' + fileext);
          actualFileName.push(filename);
          storedFileName.push(fName+'.'+'pdf');
        });
      });
      --files;
      onFinish();
    });
  });
});
busboy.on('field', function(fieldname, val, valTruncated,keyTruncated) {
  noteData = JSON.parse(val);
});
busboy.on('finish', onFinish);

function onFinish() {
  if (!busboy.writable && files === 0) {
    noteData.uploader = req.user.username;
    noteData.actualFileName = actualFileName;
    noteData.storedFileName = storedFileName;
    noteData.noteId = uuid.v4();
    Campusnotes.create(noteData,function(err,note){
      if (err){
        res.status(400);
        return res.send({reason:err.toString()});
      }
      console.log('finish');
      res.status(200);
      res.end();
    });
  }
}

On an unrelated note, you should probably do some sanitizing/checking of the filename, someone could be malicious and use something like '../../../../../../../../../etc/passwd' (I'm not sure if createWriteStream() resolves/normalizes the path given to it or not).

Upvotes: 2

Related Questions