1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
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)
|