Forum How do I...?

Dynamic Images

jsgarvin
We've got some dynamically generated images (pie charts and some graphs) on most of our pages that we need to include in the pdfs. However, prince only shows that alt text for the image tag. Static images seem to work fine.

How does Prince try to retrieve dynamic images images? I'm not seeing at hits in the server logs for the images when the page is generated, so.... any help would be appreciated.
mikeday
It uses curl to retrieve images from HTTP and HTTPS URLs. Is Prince emitting any error messages regarding the images?
jsgarvin
Yes, this is what appears in the log file...

Fri Aug 1 14:21:22 2008: /mnt/sdb1/workspace/classroom_solutions/public/charts/pie/67/image.png: warning: can't open input file: No such file or directory


Note, that the "/mnt/sdb1/workspace/classroom_solutions/public/" is where the static images are stored, but the "charts/pie/67/image.png" part is from the URL and meant to be interpreted by the web app to generate the image on the fly and serve it. It works fine in the browser, just not in Prince.

Also note, that this is a Ruby on Rails app, if that makes any difference to you.

Thanks.
mikeday
If the HTML document is not being retrieved from the server via a HTTP URL, then any relative path will be interpreted as a filename. You'll need to specify the base URL of the document as an appropriate HTTP URL, as if the document was being retrieved from the server, so that Prince can correctly resolve the image URLs.
jsgarvin
Oh, ok. I think I understand. The document is being passed into prince as STDIN. And now I see in the documentation a "--baseurl=URL" argument that can be passed. I assume that will tell prince where it can retrieve relative path images from. I'll try to test that here later today.


UPDATE
---------
Well, I tried to pass the --baseurl= argument and prince just hangs and doesn't write anything to it's log file. I also don't see any hits to the sever indicating that it's trying to retrieve any of the images referenced in the HTML. Thoughts and suggestions would be appreciated. Thanks.
mikeday
Try simplifying it down to see what is going wrong: make a very simple document with a single image using an absolute URL to the server, and try running it from the command-line (or GUI). If that works fine, change the URL to relative and run it from the command-line again but pass the document in via stdin and specify a reasonable base URL. If it's not working, please let me know which platform you are running on and which Prince package you installed.
jsgarvin
Ok, I've got it working with a simple html file from the command line, and I've been able to reproduce the hanging at the command line too.

We're using a version of the code that Subimage came up with...

http://sublog.subimage.com/articles/2008/02/05/prince-rb-update

which passes the '--silent - -o -' arguments.

When I add the '--silent -' arguments on my command line tests, I get the same 'hanging' behavior.

So, this works....

prince test.html --baseurl=http://localhost:3000/ -o test.pdf


And this hangs...

prince test.html --baseurl=http://localhost:3000/ -o test.pdf --silent -'


I don't see anything in the online prince documentation or the man page on what the --silent argument is supposed to do, but the Ruby code completely fails without it.
mikeday
I think the problem here is not the --silent argument (which hides error/warning messages) but the trailing "-", which instructs Prince to read an input document from the standard input stream. Since there is nothing coming in from standard input Prince will wait indefinitely. Try removing that and it should work:
prince test.html --baseurl=http://localhost:3000/ -o test.pdf --silent

or keep it and pipe the document in to standard input:
prince --baseurl=http://localhost:3000/ -o test.pdf --silent - < test.html
jsgarvin
Ok, yes, that solved the hanging at the command line and the dynamic images loaded into that PDF perfectly. But, it still hangs when run from the Rails application. In this case the app is communicating with prince via STDIN and STDOUT, so I need to leave the '-' in. Here's the command that's being run....

/usr/lib/prince/bin/prince --input=html --server --log=/mnt/sdb1/workspace/classroom_solutions/log/prince.log -s /mnt/sdb1/workspace/classroom_solutions/public/stylesheets/application_default_pdf.css -s /mnt/sdb1/workspace/classroom_solutions/public/stylesheets/teachers_default_pdf.css --baseurl=http://localhost:3000/ --silent - -o -


With the above it hangs, but if I just take out the
--baseurl=http://localhost:3000/
part, it does *not* hang and the pdf *does* get generated, but now the dynamically generated images don't load and all I see in the pdf is the alt attribute from the image tags.
mikeday
Strange, that really makes it sound as if the problem is coming from trying to retrieve the images. So it doesn't hang when you don't pass the --baseurl argument, but of course then you don't get the images. What if you don't pass the --baseurl argument, and you change the image links to absolute URLs? Is nothing at all showing up in the log file? Does it at least have the notification that Prince has started running?
jsgarvin
AhhhHA! I've got it. It boils down to the fact that Rails is single threaded and, since I was working on this in my development environment, I was only running one mongrel server. So, the initial request to the generate the PDF was tying up that mongrel and the subsequent requests for the images that prince was making were being queued up waiting for the initial request for the pdf to finish so the images could be served.... a virtual OK Corral standoff.

Once I fired up a second instance of mongrel on a different port and set the baseurl to point to it, things proceeded smoothly.

Thanks for your patience and helping me work through this.
mikeday
Ah, a deadlock situation, I should have thought of that. :D