Refactor svgtemplate into a neat context class SVGTemplate

This commit is contained in:
Daniel Molkentin 2019-08-02 00:10:49 +02:00
parent b6e3ef39e8
commit a057183666
2 changed files with 52 additions and 46 deletions

View file

@ -6,9 +6,8 @@ import re
import glob import glob
import shutil import shutil
import errno import errno
import logging
import subprocess import subprocess
import svgtemplate from svgtemplate import SVGTemplate
from lxml import etree from lxml import etree
from urllib.request import urlopen from urllib.request import urlopen
from wand.image import Image from wand.image import Image
@ -18,10 +17,6 @@ fps = 25
debug = True debug = True
args = None args = None
cssutils.ser.prefs.lineSeparator = ' '
cssutils.log.setLevel(logging.FATAL)
def loadProject(projectname): def loadProject(projectname):
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), projectname)) sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), projectname))
return __import__(projectname) return __import__(projectname)
@ -131,10 +126,10 @@ def cachedRenderFrame(frame, frameNr, task, cache):
elif not skip_rendering: elif not skip_rendering:
cache[frame] = frameNr cache[frame] = frameNr
svgstr = svgtemplate.open(task) with SVGTemplate(task) as svg:
svgstr = svgtemplate.replacetext(svgstr, task) svg.replacetext()
svgstr = svgtemplate.transform(svgstr, frame, task) svg.transform(frame)
svgfile = svgtemplate.write(svgstr, task) svgfile = svg.write()
outfile = '{0}/.frames/{1:04d}.png'.format(task.workdir, frameNr) outfile = '{0}/.frames/{1:04d}.png'.format(task.workdir, frameNr)
renderFrame(svgfile, task, outfile) renderFrame(svgfile, task, outfile)
@ -144,9 +139,9 @@ def cachedRenderFrame(frame, frameNr, task, cache):
def rendertask_image(task): def rendertask_image(task):
svgstr = svgtemplate.open(task) with SVGTemplate(task) as svg:
svgstr = svgtemplate.replacetext(svgstr, task) svg.replacetext()
svgfile = svgtemplate.write(svgstr, task) svgfile = svg.write()
renderFrame(svgfile, task, task.outfile) renderFrame(svgfile, task, task.outfile)
def rendertask_video(task): def rendertask_video(task):

View file

@ -1,43 +1,54 @@
# vim: tabstop=4 shiftwidth=4 expandtab # vim: tabstop=4 shiftwidth=4 expandtab
import builtins import builtins
import cssutils import cssutils
import logging
import os import os
from lxml import etree from lxml import etree
from xml.sax.saxutils import escape as xmlescape from xml.sax.saxutils import escape as xmlescape
def open(task): cssutils.ser.prefs.lineSeparator = ' '
with builtins.open(os.path.join(task.workdir, task.infile), 'r') as fp: cssutils.log.setLevel(logging.FATAL)
return fp.read()
def replacetext(svgstr, task): class SVGTemplate:
for key in task.parameters.keys(): def __init__(self, task):
svgstr = svgstr.replace(key, xmlescape(str(task.parameters[key]))) self.task = task
return svgstr
def transform(svgstr, frame, task): def __enter__(self):
parser = etree.XMLParser(huge_tree=True) with builtins.open(os.path.join(self.task.workdir, self.task.infile), 'r') as fp:
svg = etree.fromstring(svgstr.encode('utf-8'), parser) self.svgstr = fp.read()
# apply the replace-pairs to the input text, by finding the specified xml-elements by their id and modify their css-parameter the correct value return self
for replaceinfo in frame:
(id, type, key, value) = replaceinfo
for el in svg.findall(".//*[@id='" + id.replace("'", "\\'") + "']"):
if type == 'style':
style = cssutils.parseStyle(el.attrib['style'] if 'style' in el.attrib else '')
style[key] = str(value)
el.attrib['style'] = style.cssText
elif type == 'attr':
el.attrib[key] = str(value)
elif type == 'text':
el.text = str(value)
# if '$subtitle' in task.parameters and task.parameters['$subtitle'] == '':
# child = svg.findall(".//*[@id='subtitle']")[0]
# child.getparent().remove(child)
return etree.tostring(svg, encoding='unicode')
def write(svgstr, task): def write(self):
# open the output-file (named ".gen.svg" in the workdir) # open the output-file (named ".gen.svg" in the workdir)
outfile = os.path.join(task.workdir, '.gen.svg') outfile = os.path.join(self.task.workdir, '.gen.svg')
with builtins.open(outfile, 'w') as fp: with builtins.open(outfile, 'w') as fp:
# write the generated svg-text into the output-file # write the generated svg-text into the output-file
fp.write(svgstr) fp.write(self.svgstr)
return outfile return outfile
def replacetext(self):
for key in self.task.parameters.keys():
self.svgstr = self.svgstr.replace(key, xmlescape(str(self.task.parameters[key])))
def transform(self, frame):
parser = etree.XMLParser(huge_tree=True)
svg = etree.fromstring(self.svgstr.encode('utf-8'), parser)
# apply the replace-pairs to the input text, by finding the specified xml-elements by their id and modify their css-parameter the correct value
for replaceinfo in frame:
(id, type, key, value) = replaceinfo
for el in svg.findall(".//*[@id='" + id.replace("'", "\\'") + "']"):
if type == 'style':
style = cssutils.parseStyle(el.attrib['style'] if 'style' in el.attrib else '')
style[key] = str(value)
el.attrib['style'] = style.cssText
elif type == 'attr':
el.attrib[key] = str(value)
elif type == 'text':
el.text = str(value)
# if '$subtitle' in task.parameters and task.parameters['$subtitle'] == '':
# child = svg.findall(".//*[@id='subtitle']")[0]
# child.getparent().remove(child)
self.xmlstr = etree.tostring(svg, encoding='unicode')
def __exit__(self, exception_type, exception_value, traceback):
pass