Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: EACCES, open #11

Closed
doubletaketech opened this issue Jan 2, 2015 · 10 comments
Closed

Error: EACCES, open #11

doubletaketech opened this issue Jan 2, 2015 · 10 comments

Comments

@doubletaketech
Copy link

Any idea why I might be getting this error?

Exception while invoking method 'reportBatch' Error: EACCES, open '/app-storage/MeterBatchReport.pdf'
at Object.Future.wait (/mnt/data/2/node_modules/fibers/future.js:326:15)
at Object.writeFileFiber (packages/meteor/helpers.js:119:1)
at PDFDocument.writeSync (packages/pascoual:pdfkit/pdfkitWrapper.js:34:1)
at [object Object].Meteor.methods.reportBatch (app/server/server.js:33:13)
at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1599:1)
at packages/ddp/livedata_server.js:648:1
at [object Object]..extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
at packages/ddp/livedata_server.js:647:1
at [object Object].
.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
at [object Object]._.extend.protocol_handlers.method (packages/ddp/livedata_server.js:646:1)

below is my server-side code

reportBatch:function(dataUrl){
        var fs = Npm.require('fs');
        var path = Npm.require('path');

        var doc = new PDFDocument({size: 'A4', margin: 50});
        var buffer = new Buffer(dataUrl.split(",")[1], 'base64');

        doc.image(buffer, 10, 10);
        var dirPath = process.env.CLOUD_DIR;
        var filename = '/MeterBatchReport.pdf';
        var filepath = path.join(dirPath, filename);
        console.log(filepath);
        doc.writeSync(filepath);

    }
@pascoual
Copy link
Owner

pascoual commented Jan 2, 2015

You cannot use npm.require outside of package code.
Please, follow the Quick start guide.

@doubletaketech
Copy link
Author

After talking to Modulus.io, it was an permissions issue on their cloud.

How would I modify the above function to return the pdf directly back to client without writing it to the server? I just need to generate the pdf and send it back. I don't need it store in the file system anyway.

Thanks,
Don

@doubletaketech
Copy link
Author

I tried this

reportBatch:function(dataUrl){

        var doc = new PDFDocument({size: 'A4', margin: 50});
        var stream = doc.pipe(blobStream());
        var buffer = new Buffer(dataUrl.split(",")[1], 'base64');

        doc.image(buffer, 10, 10);

       return doc.outputSync() ;


    }

But, what is the format of the doc.outputSync() ? I need to convert it to dataUrl when it gets to the client so I can open it

client result

Meteor.call('reportBatch',dataUrl, function (error, result) {

                    if(!error){
                        console.log('pdf generated')


                        window.open(result, '_blank');
                    }


                });

@doubletaketech
Copy link
Author

I basically can't use the Route option because I need to pass a dataUrl to the server and use it to produce the PDF. That is why I need to use Meteor.call. I just don't know how to return the PDF to the client via Meteor.call function.

Writing the pdf to the server doesn't work on my cloud server at Modulus.io because apparently pdfkit needs special permissions.

Any way to convert doc.outputSync() to a dataUrl? Then I can just return it. It looks like it doc.outputSync() is a ArrayBuffer or something and I'm having trouble converting it.

If you can help, that would be great.

Thanks,
Don

@pascoual
Copy link
Owner

pascoual commented Jan 4, 2015

Two solution :

Best regards,
Pascoual

@doubletaketech
Copy link
Author

Thank you pascoual.

I just tried arrayBufferToBlob

 Meteor.call('reportBatch',dataUrl, function (error, result) {
                    var blob = blobUtil.arrayBufferToBlob(result, 'application/pdf');
                    saveAs(blob,'report.pdf');
                });

results is from the server doc.outputSync() .
I guess FileSaver doesn't like the Promise output from blobUtil because it throws this error ...
TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided
Can't find any help for this error on google.
I think this is getting close though.

I tried jsPDF before trying your pdfkit. Problem with it was it wouldn't produce more than one page height when using addImage. My goal is to create a PDF from a canvas image dataUrl that is more than one page height. I spent several days trying to get jsPDF to work, but to no avail.

I'm hoping pdfkit output will convert the dataUrl into a PDF without cropping it to one letter size page.

@doubletaketech
Copy link
Author

got beyond the error by using .then

var blob = blobUtil.arrayBufferToBlob(result, 'application/pdf').then(function (blob) {
                        saveAs(blob,'report.pdf')
                    }).catch(function (err) {
                        console.log(err)
                    });

unfortunately, the saved PDF just says "Failed To Load PDF document.".

here is my full server and client code
client - coverts html to dataUrl

'click .pdfDownload':function(evt,tmpl){

        var element = $('#report');

        html2canvas(element, {
            onrendered: function(canvas) {

                var dataUrl = canvas.toDataURL('image/jpeg');

                Meteor.call('reportBatch',dataUrl, function (error, result) {

                    var blob = blobUtil.arrayBufferToBlob(result, 'application/pdf').then(function (blob) {
                        saveAs(blob,'report.pdf')
                    }).catch(function (err) {
                        console.log(err)
                    });

                });

            }
        });

    }

server

Meteor.methods({

    reportBatch:function(dataUrl){
        var doc = new PDFDocument({size: 'A4', margin: 50});
        var buffer = new Buffer(dataUrl.split(",")[1], 'base64');
        doc.image(buffer, 10, 10);
        var ab = doc.outputSync();
        return  ab;
    }
})

@wallslide
Copy link

I return a base64 encoded PDF from a meteor method for my own Meteor application. I started out using this package、but ended up using the npm package pdfkit directly, because I wanted access to the pipe() function. Maybe there is some way to get access to that in this Meteor package?

The advantage to doing this through a meteor method for myself is because I get access to authentication information (this.userId) within the server-side meteor method's context.

//Code that I wrote as a custom meteor package 
var base64 = Npm.require('base64-stream');
var Future = Npm.require('fibers/future');
var PDFDocument = Npm.require('pdfkit');

somePDFGeneratingFunction(){
  var doc = new PDFDocument({...});
  //create the pdf with various commands (doc.text, doc.rect, etc)

  var future = new Future();
  var finalString = "";
  var stream = doc.pipe(base64.encode());
  doc.end();
  stream.on('data', function(chunk){
    finalString += chunk;
  });

  stream.on('end', Meteor.bindEnvironment(function(){
    future.return(finalString);
  }));

  return future.wait();
}
//inside a meteor method
Meteor.methods({
  'reports.generatePDF': function(){
    return somePDFGeneratingFunction();
  }
});
//on the web browser
Meteor.call('reports.generatePDF', function(err, res){
  window.open("data:application/pdf;base64, " + res);
});

@Maxhodges
Copy link

I work with @wallslide. Here's a sample of the base64 output:
https://gist.github.com/Maxhodges/3bb6edd525f3e6213f3e

copy all the gist content and paste into your browser address bar. Voilà!

@pascoual
Copy link
Owner

pascoual commented Oct 6, 2015

This package will stick to 0.4.3.
A new package with PDFKit 0.7.1 will come.

Closing...

@pascoual pascoual closed this as completed Oct 6, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants