1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- #!/usr/bin/env python
- import logging
- import os
- import tempfile
- from zlib import adler32
- from subprocess import Popen, PIPE
- from pelican import logger
- def generate_uml_image(path, plantuml_code, imgformat):
- tf = tempfile.NamedTemporaryFile(delete=False)
- tf.write('@startuml\n'.encode('utf8'))
- tf.write(plantuml_code.encode('utf8'))
- tf.write('\n@enduml'.encode('utf8'))
- tf.flush()
- logger.debug("[plantuml] Temporary PlantUML source at "+(tf.name))
- if imgformat == 'png':
- imgext = ".png"
- outopt = "-tpng"
- elif imgformat == 'svg':
- imgext = ".svg"
- outopt = "-tsvg"
- else:
- logger.error("Bad uml image format '"+imgformat+"', using png")
- imgext = ".png"
- outopt = "-tpng"
- # make a name
- name = tf.name+imgext
- # build cmd line
- cmdline = ['plantuml', '-o', path, outopt, tf.name]
- try:
- logger.debug("[plantuml] About to execute "+" ".join(cmdline))
- p = Popen(cmdline, stdout=PIPE, stderr=PIPE)
- out, err = p.communicate()
- except Exception as exc:
- raise Exception('Failed to run plantuml: %s' % exc)
- else:
- if p.returncode == 0:
- # diagram was correctly generated, we can remove the temporary file (if not debugging)
- if not logger.isEnabledFor(logging.DEBUG):
- os.remove(tf.name)
- # renaming output image using an hash code, just to not pollute
- # output directory with a growing number of images
- name = os.path.join(path, os.path.basename(name))
- newname = os.path.join(path, "%08x" % (adler32(plantuml_code.encode()) & 0xffffffff))+imgext
- if os.path.exists(newname):
- os.remove(newname)
- os.rename(name, newname)
- return 'images/' + os.path.basename(newname)
- else:
- # the temporary file is still available as aid understanding errors
- raise RuntimeError('Error calling plantuml: %s' % err)
|