from django.conf import settings def update_render(sender, instance, signal, *args, **kwargs): """Renders an object's .png representation using LaTeX and puts it in the right directory. Requires latex, dvipng, etc""" import os, shutil, tempfile, subprocess def call_command_in_dir(app, args, targetdir): cwd = os.getcwd() try: os.chdir(targetdir) p = subprocess.Popen(app + ' ' + ' '.join(args), shell=True) sts = os.waitpid(p.pid, 0) # FIXME -- should we raise an exception of status is non-zero? finally: # Restore working directory os.chdir(cwd) rawlatex = instance.latex dstdir = settings.MEDIA_ROOT + instance.renderdir dstfile = "%s.png" % instance.id dst = "%s" % instance.id prologue = "" latex_template = r''' \documentclass[12pt]{article} \pagestyle{empty} %(prologue)s \begin{document} $$%(raw)s$$ \end{document} ''' max_pages = 1 MAX_RUN_TIME = 5 # seconds latex = "latex" dvipng = "dvipng" latex_args = ("--interaction=nonstopmode", "%s.tex") dvipng_args = ("-q", "-bgTransparent", "-Ttight", "--noghostscript", "-l%s" % max_pages, "%s.dvi") tex = latex_template % { 'raw': rawlatex, 'prologue': prologue } tmpdir = tempfile.mkdtemp() try: data = open("%s/%s.tex" % (tmpdir, dst), "w") data.write(tex) data.close() args = list(latex_args) args[-1] = args[-1] % dst res = call_command_in_dir(latex, args, tmpdir) if not res is None: # FIXME need to return some sort of error return [] args = list(dvipng_args) args[-1] = args[-1] % dst res = call_command_in_dir(dvipng, args, tmpdir) if not res is None: # FIXME need to return some sort of error return [] if os.access("%s/%s1.png" % (tmpdir, dst), os.R_OK): shutil.copyfile("%s/%s1.png" % (tmpdir, dst), dstdir + dstfile) finally: # FIXME do some tidy up here instance.render = instance.renderdir + dstfile shutil.rmtree(tmpdir)