Rob van der Linde

Open Source Software Developer

Posts filed under Python

Opening up my Django based CMS

Posted on October 23, 2012 by: Rob van der Linde
Filed under: Django, Open Source, Python
Tags: django, cms, opensource, rvcms

Today I have finally decided to open up my Django based CMS (rvcms) as open source, using a BSD type license.

I created this CMS a while ago as a need for a CMS that runs on top of Django, but since then other (much better) content management systems for Django have been released, such as Django-CMS and Mezzanine.

Although my CMS is a bit rough around the edges, I am still not giving up on it entirely. I do like aspects of my CMS, it's simple, it's lightweight and it works well enough to use on most sites.

The only thing still missing is documentation on how to install it or use it, sorry, but there is a setup.py script now at least so you can install the CMS in a virtualenv, which is only a start.

The requirements for the CMS at this stage are Django 1.3, but I am planning to get it back upto scratch and working with Django 1.4 and give it a bit of a cleanup. The rest of the requirements are all listed in setup.py.

In the long run however, I am looking into writing a new CMS using the Pyramid web framework, which I have come to love over the last year or so, but still keep this CMS going for existing sites for a while.

The CMS source code is located on Bitbucket.

Kiwi Pycon 2011 is over

Posted on August 28, 2011 by: Rob van der Linde
Filed under: Events, Python
Tags: python, event, pycon

I just came back from the last day of Kiwi Pycon 2011. I really enjoyed the event, the talks have been really good and there were a lot of people to meet, there were over 150 people at the event in total. I have taken some photos, located in my all new Django gallery, although there are not a lot of them and they aren't really that good.

More photos are available on Flickr from other people, and you may also want to check out #kiwipycon2011 on twitter. The next Kiwi Pycon is going to be in Dunedin in 2012, hopefully I can make it there next year.

Upcoming Tour of Weta Datacenter

Posted on August 14, 2011 by: Rob van der Linde
Filed under: Events, Python
Tags: python, event, weta, datacenter

I got an email Friday morning, that I had been successful in the draw for a tour of the Weta Digital datacenter, by registering early for the Kiwi Pycon 2011 conference. There are only 8 places for this tour, and were drawn from the first 100 early registrations.

I am very excited about going to this event, it is the day before the Kiwi Pycon conference starts. The email states that the Weta Digital datacenter is often cited as the largest collection of data processing power in New Zealand, and Python is at the heart of the operation, how cool is that!

I am really looking forward to this event, as well as the Kiwi Pycon, which is only two weeks away now.

LaTeX and Django

Posted on August 11, 2011 by: Rob van der Linde
Filed under: Django, Python
Tags: latex, pdf, python, django

In the last week, I have been learning how to use LaTeX, a markup style language used to create professional documents. I have been using Texmaker on Linux, an excellent cross-platform LaTeX editor. I thought it would be pretty cool to generate PDF documents from a Django view using the pdflatex command line app, and using the Django template engine for adding dynamic content to .tex files before rendering them to PDF.

Here is the code I wrote that does this, it renders the LaTeX template to a string first. It then uses tempfile.mkstemp() to generate a unique temporary file name for use for the generated PDF file, mkstemp returns both the filename and a file descriptor to the temporary file. When we load the contents of the PDF file into a string, we should use os.fdopen() with this file descriptor, rather than just use open(), which is the proper way to work with temporary files.

When we run pdflatex, we pipe the rendered .tex template to stdin, so we don't have to save it to disk. Unfortunately, pdflatex cannot return a generated PDF over stdout the same way and it only saves a PDF to disk, which is why we have to use the temporary file method.

After the PDF is rendered, we load ithe PDF file and return it as an attachment over the response. We then delete any temporary files created, including the PDF file.

import os
from subprocess import Popen, PIPE
from tempfile import mkstemp
 
from django.http import HttpResponse, Http404
from django.template.loader import render_to_string
from django.template import RequestContext
 
def render_latex(request, template, dictionary, filename):
    # render latex template and vars to a string
    latex = render_to_string(template, dictionary, context_instance=None)
 
    # create a unique temorary filename
    fd, path = mkstemp(prefix="latex_", suffix=".pdf")
    folder, fname = os.path.split(path)
    jobname, ext = os.path.splitext(fname)  # jobname is just the filename without .pdf, it's what pdflatex uses
 
    # for the TOC to be built, pdflatex must be run twice, on the second run it will generate a .toc file
    for i in range(2):
        # start pdflatex, we can send the tex file from stdin, but the output file can only be saved to disk, not piped to stdout unfortunately/
        process = Popen(["pdflatex", "-output-directory", folder, "-jobname", jobname], stdin=PIPE, stdout=PIPE)  # piping stdout suppresses output messages
        process.communicate(latex)
 
    # open the temporary pdf file for reading.
    try:
        pdf = os.fdopen(fd, "rb")
        output = pdf.read()
        pdf.close()
    except OSError:
        raise Http404("Error generating PDF file")  # maybe we should use an http  500 here, 404 makes no sense
 
    # generate the response with pdf attachment
    response = HttpResponse(mimetype="application/pdf")
    response["Content-Disposition"] = "attachment; filename=" + filename
    response.write(output)
 
    # delete the pdf from temp directory, and other generated files ending on .aux and .log
    for ext in (".pdf", ".aux", ".log", ".toc", ".lof", ".lot", ".synctex.gz"):
        try:
            os.remove(os.path.join(folder, jobname) + ext)
        except OSError:
            pass
 
    # return the response
    return response
 
#### Actual Usage ####
 
def someview(request):
    return render_latex(request, "reports/test.tex", {"foo": "bar"}, filename="latex_test.pdf")