Auto Generating PDF Covers on file upload with Django and ImageMagick
Note: This used to be on my tumblr which I shut down a bit ago. So if it looks familiar, it is.
Python Thumbnailing of a PDF
The following are simple instructions on creating a thumbnail from an uploaded PDF using ImageMagick. Our project calls ImageMagick as a terminal command from within a Django Project.
I was developing on an iMac running OSXv10.6 (Snow Leopard), additionally we had a developer on a MacBook Pro running OSXv10.7 (Lion), and our production environment running Fedora release 14 (Laughlin).
First, grab a PDF off the internet if you don’t have one handy. (I’ve been debugging some PayPal lately and happened to have the url for this readily available)
Next, test to make sure you can make a thumbnail from that PDF.
In this command we are making a 222px wide thumbnail of the th, or first, page of the supplied PDF. The thumbnail is saved as the output file test.png.
If everything looks good at this point lets get it integrated into your django project.
Integration into Django
Requirement: A user should be able to upload a PDF to a model and a thumbnail should be generated and saved into a separate thumbnail field on that model instance.
An Example Model
You will notice that most of the magic is happening in the overridden save and post save methods of my Pdf class. Firstly, In my overridden save method I set up the field value for the thumbnail. It is the relative url to the image from my MEDIA_ROOT variable.
I then add hook into the post_save signal. Using signals is necessary in this instance, because prior to the save function being run, the document hasn’t been moved into the expected upload location, and therefore the convert command will fail. Inside the post_save signal, run the thumbnailing command against the system using popen. Originally, I set this up using os.system, however I quickly realized that I needed more debugging information than was returned.
The Django Admin
Above is a pretty simple ModelAdmin, with a overridden widget on the thumbnail field of the ModelForm.
And the custom Widget: AdminPdfThumnailWidget
this is pretty straight forward, it takes an AdminFileWidget and replaces the render output with an <img> tag