Skip to content

Instantly share code, notes, and snippets.

@loleg
Last active April 25, 2024 10:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loleg/76a2cd97f4acf07ce70663c47a3dd641 to your computer and use it in GitHub Desktop.
Save loleg/76a2cd97f4acf07ce70663c47a3dd641 to your computer and use it in GitHub Desktop.
A small Python script to generate certificates using an SVG template
#!/usr/bin/python
from xml.dom import minidom
import csv, os, re, string, subprocess
from argparse import ArgumentParser
import tempfile
# Create a SVG file with nodes having at least one of:
# name_black
# name_white
# Create a UTF-8 formatted comma-delim CSV with column:
# Name
parser = ArgumentParser(description='Generate certificates from a Dribdat participants list')
parser.add_argument("svg", help='SVG file with node(s) having a [name] ID and optional [extra]')
parser.add_argument("csv", help='CSV file with [name] and [username]/[filename] (and [teams]/[extra]) columns')
args = parser.parse_args()
tempdir = tempfile._get_default_tempdir()
tf = open(args.svg,'r')
xmldoc = minidom.parse(tf)
tf.close()
elements = xmldoc.getElementsByTagName('text')
def getText(nodelist):
rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc.append(node.data)
return ''.join(rc)
def setText(nodelist, value):
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
node.data = value
def setTspan(element, value):
els = element.getElementsByTagName('tspan')[0].childNodes
setText(els, value)
return getText(els)
# E.g. setTspans("CÉLINE DION")
""" Sets the name of the participant """
def setTspans(value, attrPrefix='name'):
for element in elements:
if element.hasAttribute('id') and element.getAttribute('id').startswith(attrPrefix):
setTspan(element, value)
def tidyName(st):
return ''.join(re.findall("[^" + string.whitespace + "]", st.title())).strip()
def generatePDF(p_name, p_filename, p_extra:dict=None):
setTspans(p_name)
setTspans(p_filename, 'filename')
if p_extra is not None:
for x in p_extra.keys():
setTspans(p_extra[x], x)
tempsvgfile = os.path.join(tempdir,'temp.svg')
tf = open(tempsvgfile, 'w')
xmldoc.writexml(tf)
tf.close()
completed = subprocess.run(['inkscape',
tempsvgfile,
'-o', r'output/' + p_filename + '.pdf',
'--export-type=pdf'])
if completed.stderr != None:
print ("stderr:" + str(completed.stderr))
print ("stdout:" + str(completed.stdout))
exit()
os.remove(tempsvgfile)
# Iterate through list
with open(args.csv, newline='') as f:
reader = csv.DictReader(f)
count = 0
for row in reader:
if 'fullname' in row and row['fullname'].strip():
p_name = row['fullname'].strip()
else:
p_name = row['name']
p_name = p_name.split('/')[0]
if 'filename' in row:
p_filename = row['filename']
elif 'username' in row:
p_filename = row['username']
else:
p_filename = tidyName(p_name)
print("Generating ...", p_name)
p_extra = {}
for pk in ['username', 'extra', 'score']:
if pk in row and row[pk]:
p_extra[pk] = row[pk].strip()
if 'teams' in row:
team1 = row['teams'].split(',')[0].strip()
p_extra['team'] = team1
generatePDF(p_name, p_filename, p_extra)
print("✓", p_filename)
count += 1
print("Done! %d certificates generated" % count)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment