diff --git a/diagrams.py b/diagrams.py
deleted file mode 100644
index 3afcc93..0000000
--- a/diagrams.py
+++ /dev/null
@@ -1,315 +0,0 @@
-from subprocess import Popen, PIPE
-import sys
-from sys import platform
-from os.path import expanduser
-from pathlib import Path
-import os.path
-import zlib
-import re
-import json
-
-
-class Example(object):
- """ Example handling """
-
- @staticmethod
- def get(generator):
- scriptdir = os.path.dirname(os.path.abspath(__file__))
- example = scriptdir + "/../web/examples/example.%s" % generator
- if os.path.isfile(example):
- txt = Path(example).read_text()
- else:
- txt = "no example for %s found" % generator
- return txt
-
-
-class Command(object):
- """ a command to be run using the shell environment """
-
- def __init__(self, cmd, versionOption="--version", timeout=5, debug=False):
- """ construct me """
- self.cmd = cmd
- self.timeout = timeout
- self.versionOption = versionOption
- self.cmdpath = None
- self.debug = debug
-
- def call(self, args):
- """ call me with the given args"""
- return self.docall(self.cmdpath, self.cmd, args)
-
- def callalias(self, alias, args):
- """ call me with the given args"""
- #print ("callalias cmdpath %s\nalias %s\nargs %s" % (self.cmdpath, alias, args), file=sys.stderr)
- return self.docall(self.cmdpath, alias, args)
-
- def docall(self, cmdpath, cmd, args):
- """ call with a specific path and command"""
- cmdline = "%s%s %s" % (cmdpath, cmd, str(args))
- if self.debug:
- print ("calling %s" % cmdline, file=sys.stderr)
- process = Popen(cmdline, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
- try:
- stdout, stderr = process.communicate(timeout=self.timeout)
- if self.debug:
- if stdout is not None:
- print ("stdout: %s" % stdout.decode('utf-8'), file=sys.stderr)
- if stderr is not None:
- print ("stderr: %s" % stderr.decode('utf-8'), file=sys.stderr)
- return stdout, stderr
- except Exception:
- process.kill()
- return None, None
-
- def check(self):
- cmdpaths = []
- # do we know the cmdpath?
- if self.cmdpath is None:
- # no we need to try multiple options in a specific order
- # prio #1: $HOME/bin
- home = expanduser("~")
- cmdpaths.append(home + "/bin/")
- # prio #2: e.g. Macports
- if platform == "darwin":
- cmdpaths.append("/opt/local/bin/")
- # prio #3: default path / no path
- # no path - use default PATH
- cmdpaths.append("")
- else:
- # we know the valid path
- cmdpaths.append(self.cmdpath)
- for cmdpath in cmdpaths:
- stdout, stderr = self.docall(cmdpath, self.cmd, self.versionOption)
- stdoutTxt = None
- stderrTxt = None
- if stdout is not None:
- stdoutTxt = stdout.decode("utf-8")
- if stderr is not None:
- stderrTxt = stderr.decode("utf-8")
- if not "not found" in stderrTxt and not "No such file or directory" in stderrTxt:
- self.cmdpath = cmdpath
- return stdoutTxt, stderrTxt
- return None, None
-
-
-class Generators(object):
- generatorDict = {}
- """ the available generators """
-
- @staticmethod
- def get(generator):
- if len(Generators.generatorDict) is 0:
- for gen in Generators.generators():
- Generators.generatorDict[gen.id] = gen
- gen = None
- if generator in Generators.generatorDict:
- gen = Generators.generatorDict[generator]
- return gen
-
- @staticmethod
- def generatorIdForAlias(alias):
- for gen in Generators.generators():
- if alias in gen.aliases:
- return gen.id
- return None
-
- @staticmethod
- def generators():
- scriptdir = os.path.dirname(os.path.abspath(__file__))
- for plantumlpath in [".", ".."]:
- plantumljar = scriptdir + "/" + plantumlpath + "/plantuml.jar";
- if os.path.isfile(plantumljar):
- break;
- if plantumljar is None:
- raise Exception("plantuml.jar not found in %s or .. of it", scriptdir)
- #else
- gens = [
- Generator("graphviz", "GraphViz", "dot", "-V", logo="https://graphviz.gitlab.io/_pages/Resources/app.png", url="https://www.graphviz.org/",
- aliases=[ 'dot', 'neato', 'twopi', 'circo', 'fdp', 'sfdp', 'patchwork', 'osage' ],
- defaultType='png',
- outputTypes=['dot', 'xdot', 'ps', 'pdf', 'svg', 'fig', 'png', 'gif', 'jpg', 'json', 'imap', 'cmapx']
- ),
- Generator("mscgen", "Mscgen", "mscgen", "", logo="http://www.mcternan.me.uk/mscgen/img/msc-sig.png", url="http://www.mcternan.me.uk/mscgen/", defaultType='png', outputTypes=['png', 'eps', 'svg', 'ismap']),
- Generator("plantuml", "PlantUML", "java -jar " + plantumljar, "-version", aliases=['plantuml'],
- logo="https://useblocks.com/assets/img/posts/plantuml_logo.png",
- url="https://plantuml.com",
- defaultType='png',
- download="http://sourceforge.net/projects/plantuml/files/plantuml.jar/download",
- outputTypes=['png', 'svg', 'eps', 'pdf', 'vdx', 'xmi', 'scxml', 'html', 'txt', 'utxt',
- 'latex', 'latex:nopreamble'])
- ]
- return gens
-
-
-class GenerateResult(object):
-
- def __init__(self, crc32, outputType, path, stdout, stderr):
- """ construct me """
- self.crc32 = crc32;
- self.outputType = outputType;
- self.path = path;
- self.stdout = stdout
- self.stderr = stderr
-
- def errMsg(self):
- """ decode my stdout and stderr to an error message"""
- msg = ""
- if self.stdout is not None:
- msg = msg + self.stdout.decode('utf-8')
- if self.stderr is not None:
- msg = msg + self.stderr.decode('utf-8')
- return msg
-
- def asHtml(self):
- """ return me as HTML"""
- url = '/render/%s/%s' % (self.outputType, self.crc32)
- if self.outputType in ['gif', 'jpg', 'png', 'svg']:
- return "
" % url;
- elif self.outputType in ['pdf']:
- return "" % url;
- else:
- return "%s %s" % (url, self.outputType, self.crc32)
-
- def isValid(self):
- """ check if i am valid"""
- valid = os.path.isfile(self.path) and not self.errMsg()
- return valid
-
- def asJson(self, baseurl):
- """ return my result as JSON for the Mediawiki diagrams extension"""
- errMsg=self.errMsg();
- if errMsg:
- jsonTxt="""{
- "error": "generating %s failed",
- "message": %s
- }""" % (self.outputType,json.dumps(errMsg))
- else:
- jsonTxt = """{
- "diagrams": {
- "png": {
- "url": "%s/png/%s.png"
- }
- }
-}""" % (baseurl,self.crc32)
- return jsonTxt
-
-
-class Generator(object):
- """ a diagram generator """
-
- @staticmethod
- def getOutputDirectory():
- home = expanduser("~")
- outputDir = home + "/.diagrams/"
- if not os.path.isdir(outputDir):
- os.mkdir(outputDir);
- return outputDir
-
- def __init__(self, genid, name, cmd, versionOption, logo=None, url=None, download=None, defaultType=None, aliases=None, outputTypes=None, debug=False):
- """ construct me """
- self.id = genid
- self.name = name
- self.cmd = cmd
- self.gencmd = None
- self.logo = logo
- self.url = url
- self.htmlInfo = None
- self.download = download
- self.versionOption = versionOption;
- if aliases is None:
- self.aliases = [cmd]
- else:
- self.aliases = aliases
- self.defaultType = defaultType
- self.selectedType = defaultType
- self.outputTypes = outputTypes
- self.debug = debug
- pass
-
- def getHtmlInfo(self):
- """ get info on this generator to be displayed via HTML"""
- # cache the info since getVersion is a costly process
- if self.htmlInfo is None:
- version = self.getVersion()
- self.htmlInfo = "
" % (self.url, self.name, version, self.logo)
- return self.htmlInfo
-
- def check(self):
- """ check my version"""
- self.gencmd = Command(self.cmd, self.versionOption, debug=self.debug)
- return self.gencmd.check()
-
- def getVersion(self):
- stdOutText, stdErrText = self.check()
- if stdOutText is None:
- stdOutText = ''
- if stdErrText is None:
- stdErrText = ''
- outputText = stdOutText + stdErrText
- found = re.search(r'version.*[,)]', outputText)
- if found:
- version = found.group()
- else:
- # actually an error message
- version = outputText
- # invalidate gencmd
- self.gencmd = None
- return version
-
- @staticmethod
- def getHash(txt):
- hashValue = zlib.crc32(txt.encode()) & 0xffffffff
- hashId = hex(hashValue)
- #print ("txt %s\nhashValue %s\nhashId %s" % (txt, hashValue, hashId), file=sys.stderr)
- return hashId
-
- def wrap(self,txt):
- """ wraot the given text"""
- if self.id == "plantuml":
- txt="@startuml\n%s\n@enduml\n" % txt
- return txt
-
- def generate(self, alias, txt, outputType, renderer, useCached=True):
- """ generate """
- txt=self.wrap(txt)
- hashId = Generator.getHash(txt)
- inputPath = "%s%s.%s" % (Generator.getOutputDirectory(), hashId, 'txt')
- stdout = None
- stderr = None
- if not (os.path.isfile(inputPath) and useCached):
- text_file = open(inputPath, "wt", encoding='utf-8')
- try:
- if self.debug:
- print ("txt %s" % txt, file=sys.stderr)
- text_file.write("%s" % txt)
- except Exception as e:
- print ("exception %s" % e, file=sys.stderr)
- finally:
- text_file.close()
- outputPath = "%s%s.%s" % (Generator.getOutputDirectory(), hashId, outputType)
- if os.path.isfile(outputPath) and useCached:
- if self.debug:
- print ("cached %s #%s from %s" % (outputType, hashId, outputPath), file=sys.stderr)
- #else:
- if True:
- if self.debug:
- print ("generating %s #%s to %s" % (outputType, hashId, outputPath), file=sys.stderr)
- if self.id == "graphviz":
- args = "-T%s %s -o %s" % (outputType, inputPath, outputPath)
- if len(renderer) != 0: #exists and not empty
- alias = renderer
- else:
- alias = "dot"
- #print ("renderer %s\nalias %s" % (renderer, alias), file=sys.stderr)
- elif self.id == "mscgen":
- args = "-T%s -i %s -o %s" % (outputType, inputPath, outputPath)
- elif self.id == "plantuml":
- args = "-charset UTF-8 -t%s %s" % (outputType, inputPath)
- alias = "java -jar /var/diagrams/plantuml.jar"
- else:
- print ("unknown generator %s" % self.id, file=sys.stderr)
- if self.gencmd is None:
- self.check()
- stdout, stderr = self.gencmd.callalias(alias, args)
- result = GenerateResult(hashId, outputType, outputPath, stdout, stderr)
- return result