From 58e8ea1a6d1ee6e2f1878b4bbf2041ac368aee70 Mon Sep 17 00:00:00 2001 From: Mathew Biddle <8480023+MathewBiddle@users.noreply.github.com> Date: Thu, 4 May 2023 17:00:37 -0400 Subject: [PATCH 01/10] adding certificate maker --- certificate/bin/make_certificate.py | 38 + certificate/bin/templates/cert_template.svg | 2966 +++++++++++++++++++ 2 files changed, 3004 insertions(+) create mode 100644 certificate/bin/make_certificate.py create mode 100644 certificate/bin/templates/cert_template.svg diff --git a/certificate/bin/make_certificate.py b/certificate/bin/make_certificate.py new file mode 100644 index 0000000..266f7e4 --- /dev/null +++ b/certificate/bin/make_certificate.py @@ -0,0 +1,38 @@ +from jinja2 import Environment, FileSystemLoader +# import argparse +import json +import os +import shutil +import sys + +def write_svg_cert(template, config): + root = os.path.dirname(os.path.abspath(__file__)) + #root = path to output directory + fname = config['name']['first_name']+'_'+config['name']['last_name']+'_'+config['date']+'.svg' + filename = os.path.join(root, 'certs', fname) + with open(filename, 'w') as fh: + fh.write(template.render(configs = config)) +def load_template(): + root = os.path.dirname(os.path.abspath(__file__)) + templates_dir = os.path.join(root, 'templates') + env = Environment( loader = FileSystemLoader(templates_dir) ) + template = env.get_template('cert_template.svg') + return template + +def write_templates(config): + # filename = parse_args() + template = load_template() + write_svg_cert(template, config) + +def main(config): + write_templates(config) + + +if __name__ == '__main__': + + config = {'name': {'first_name': 'matt', + 'last_name' : 'biddle'}, + 'date': '2023-05-19', + } + + main(config) \ No newline at end of file diff --git a/certificate/bin/templates/cert_template.svg b/certificate/bin/templates/cert_template.svg new file mode 100644 index 0000000..d2245a0 --- /dev/null +++ b/certificate/bin/templates/cert_template.svg @@ -0,0 +1,2966 @@ + + + +image/svg+xmlThis certificate has been awarded for successfully completing the basicdata skills training run by Data Carpentry.The recipient was introduced to core computational skills needed fordata management and analysis.Recipient: {{configs.name.first_name}} {{configs.name.last_name}}Date of Award: {{configs.date}}Certified by: Workshop Hosts +Certificate of Achievement + \ No newline at end of file From a1a5cf35e4d44878eb016d592eda20a703884d85 Mon Sep 17 00:00:00 2001 From: Mathew Biddle <8480023+MathewBiddle@users.noreply.github.com> Date: Thu, 4 May 2023 17:02:58 -0400 Subject: [PATCH 02/10] adding info on running new script --- certificate/README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/certificate/README.md b/certificate/README.md index 678f0a6..d12ac5e 100644 --- a/certificate/README.md +++ b/certificate/README.md @@ -1,5 +1,14 @@ # Certificates for The Carpentries +To create the certificate, run: +```bash +python make_certificate.py +``` + +In `make_certificate.py` edit `config` for the persons name and date of the workshop. + + +## Historical information: There are two ways to build certificates from this repo, one depends on the python package cairosvg which in turn depends on cairo development libraries being installed. To use this method, use `bin/certificates.py` to build certificates. @@ -10,4 +19,3 @@ To build certificates this way, you can run: jinja2 swc-attendance.svg -D name="Firstname Lastname" -D date="Nov. 6, 2017" -D instructor="Some Instructor Name" > lastname_firstname.svg svg2pdf lastname_firstname.svg ``` - From 058d32fff0e514446ff730ccbf506f8cf5c7236a Mon Sep 17 00:00:00 2001 From: Mathew Biddle <8480023+MathewBiddle@users.noreply.github.com> Date: Fri, 5 May 2023 10:47:27 -0400 Subject: [PATCH 03/10] cleaning up imports and running black --- certificate/bin/make_certificate.py | 47 +++++++++++++++++------------ 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/certificate/bin/make_certificate.py b/certificate/bin/make_certificate.py index 266f7e4..bfd0230 100644 --- a/certificate/bin/make_certificate.py +++ b/certificate/bin/make_certificate.py @@ -1,38 +1,45 @@ -from jinja2 import Environment, FileSystemLoader -# import argparse -import json import os -import shutil -import sys +from jinja2 import Environment, FileSystemLoader + def write_svg_cert(template, config): root = os.path.dirname(os.path.abspath(__file__)) - #root = path to output directory - fname = config['name']['first_name']+'_'+config['name']['last_name']+'_'+config['date']+'.svg' - filename = os.path.join(root, 'certs', fname) - with open(filename, 'w') as fh: - fh.write(template.render(configs = config)) + # root = path to output directory + fname = ( + config["name"]["first_name"] + + "_" + + config["name"]["last_name"] + + "_" + + config["date"] + + ".svg" + ) + filename = os.path.join(root, "certs", fname) + with open(filename, "w") as fh: + fh.write(template.render(configs=config)) + + def load_template(): root = os.path.dirname(os.path.abspath(__file__)) - templates_dir = os.path.join(root, 'templates') - env = Environment( loader = FileSystemLoader(templates_dir) ) - template = env.get_template('cert_template.svg') + templates_dir = os.path.join(root, "templates") + env = Environment(loader=FileSystemLoader(templates_dir)) + template = env.get_template("cert_template.svg") return template + def write_templates(config): # filename = parse_args() template = load_template() write_svg_cert(template, config) + def main(config): write_templates(config) -if __name__ == '__main__': - - config = {'name': {'first_name': 'matt', - 'last_name' : 'biddle'}, - 'date': '2023-05-19', - } +if __name__ == "__main__": + config = { + "name": {"first_name": "matt", "last_name": "biddle"}, + "date": "2023-05-19", + } - main(config) \ No newline at end of file + main(config) From 063bada2dc187cbe01da307a7ee2d979781cd8bc Mon Sep 17 00:00:00 2001 From: Mathew Biddle <8480023+MathewBiddle@users.noreply.github.com> Date: Fri, 5 May 2023 11:37:35 -0400 Subject: [PATCH 04/10] cleaning up certificate creating simple example adding process for creating template --- certificate/README.md | 16 + certificate/bin/make_certificate.py | 4 +- certificate/bin/makecert.sh | 22 - certificate/bin/templates/cert_template.svg | 2966 ----------------- certificate/bin/templates/certificate.svg | 68 + certificate/dc-attendance.svg | 2966 ----------------- certificate/lc-attendance.svg | 2092 ------------ certificate/requirements.txt | 3 - certificate/swc-attendance.svg | 3227 ------------------- 9 files changed, 86 insertions(+), 11278 deletions(-) delete mode 100644 certificate/bin/makecert.sh delete mode 100644 certificate/bin/templates/cert_template.svg create mode 100644 certificate/bin/templates/certificate.svg delete mode 100644 certificate/dc-attendance.svg delete mode 100644 certificate/lc-attendance.svg delete mode 100644 certificate/requirements.txt delete mode 100644 certificate/swc-attendance.svg diff --git a/certificate/README.md b/certificate/README.md index d12ac5e..e09df3a 100644 --- a/certificate/README.md +++ b/certificate/README.md @@ -8,6 +8,22 @@ python make_certificate.py In `make_certificate.py` edit `config` for the persons name and date of the workshop. +## Create the template certificate.svg + +1. Using https://app.diagrams.net/ design the certificate. +1. Include the jinja template variables where the information should be replaced. + 1. The appicants first name will replace the variable `{{configs.name.first_name}}` in the svg file. +1. Save the image as `svg` + 1. File > Export as > SVG... + 2. Set the size to `Diagram` + 3. Check `Include a copy of my diagram` + 4. Check `Embed Images` + 5. Leave `Text Settings` as `Default` + 6. Leave `Links` as `Automatic` + 7. Select `Export` and save to `certificate/bin/templates/certificate.svg` + +`make_certificate.py` will pick up the template and insert the appropriate information from the `config` variable. + ## Historical information: There are two ways to build certificates from this repo, one depends on the python package cairosvg which in turn depends on cairo development libraries being installed. To use this method, use `bin/certificates.py` to build certificates. diff --git a/certificate/bin/make_certificate.py b/certificate/bin/make_certificate.py index bfd0230..be6e619 100644 --- a/certificate/bin/make_certificate.py +++ b/certificate/bin/make_certificate.py @@ -22,7 +22,7 @@ def load_template(): root = os.path.dirname(os.path.abspath(__file__)) templates_dir = os.path.join(root, "templates") env = Environment(loader=FileSystemLoader(templates_dir)) - template = env.get_template("cert_template.svg") + template = env.get_template("certificate.svg") return template @@ -38,7 +38,7 @@ def main(config): if __name__ == "__main__": config = { - "name": {"first_name": "matt", "last_name": "biddle"}, + "name": {"first_name": "Mathew", "last_name": "Biddle"}, "date": "2023-05-19", } diff --git a/certificate/bin/makecert.sh b/certificate/bin/makecert.sh deleted file mode 100644 index a441567..0000000 --- a/certificate/bin/makecert.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -if [[ $# -eq 0 ]]; -then - echo "makecert.sh " -fi - -# Check for jinja2 -command -v jinja2 >/dev/null 2>&1 || { echo >&2 "This scripts requires jinja2-cli but it's not installed. Install with `pip install jinja2-cli`. Aborting."; exit 1; } -# Check for svg2pdf -command -v svg2pdf>/dev/null 2>&1 || { echo >&2 "This script requires svg2pdf, a part of svglib. Install with `pip install svgilib`. Aborting."; exit 1; } - -source_svg=${1} -context=${2} -certout_pdf=${3} -certout_svg=${certout_pdf/.pdf/.svg} - -jinja2 ${source_svg} ${context} > ${certout_svg} # fill template - -svg2pdf ${certout_svg} # convert to PDF - - diff --git a/certificate/bin/templates/cert_template.svg b/certificate/bin/templates/cert_template.svg deleted file mode 100644 index d2245a0..0000000 --- a/certificate/bin/templates/cert_template.svg +++ /dev/null @@ -1,2966 +0,0 @@ - - - -image/svg+xmlThis certificate has been awarded for successfully completing the basicdata skills training run by Data Carpentry.The recipient was introduced to core computational skills needed fordata management and analysis.Recipient: {{configs.name.first_name}} {{configs.name.last_name}}Date of Award: {{configs.date}}Certified by: Workshop Hosts -Certificate of Achievement - \ No newline at end of file diff --git a/certificate/bin/templates/certificate.svg b/certificate/bin/templates/certificate.svg new file mode 100644 index 0000000..bc70472 --- /dev/null +++ b/certificate/bin/templates/certificate.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + Certificate of Participation + + + + + + Certificate of Participati... + + + + + + + + + + + This certifies that + + {{configs.name.first_name}} {{configs.name.last_name}} + + successfully participated in the2023 Marine + Biological Data Mobilization Workshop + + + + + + This certifies that... + + + + + + + + Text is not SVG - cannot display + + + \ No newline at end of file diff --git a/certificate/dc-attendance.svg b/certificate/dc-attendance.svg deleted file mode 100644 index 88a5382..0000000 --- a/certificate/dc-attendance.svg +++ /dev/null @@ -1,2966 +0,0 @@ - - - -image/svg+xmlThis certificate has been awarded for successfully completing the basicdata skills training run by Data Carpentry.The recipient was introduced to core computational skills needed fordata management and analysis.Recipient: {{name}}Date of Award: {{date}}Certified by: {{instructor}} -Certificate of Achievement - \ No newline at end of file diff --git a/certificate/lc-attendance.svg b/certificate/lc-attendance.svg deleted file mode 100644 index 4a23182..0000000 --- a/certificate/lc-attendance.svg +++ /dev/null @@ -1,2092 +0,0 @@ - -image/svg+xmlThis certificate has been awarded for successfully completing a Library Carpentryworkshop. The recipient was introduced to core software and data skillsto work with library and information-related data.Recipient: {{name}}Date of Award: {{date}}Certified by: {{instructor}} - -Certificate of Achievement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/certificate/requirements.txt b/certificate/requirements.txt deleted file mode 100644 index 3ef89d8..0000000 --- a/certificate/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -jinja2 -jinja2-cli -svglib diff --git a/certificate/swc-attendance.svg b/certificate/swc-attendance.svg deleted file mode 100644 index 8fa7356..0000000 --- a/certificate/swc-attendance.svg +++ /dev/null @@ -1,3227 +0,0 @@ - - - -image/svg+xmlThis certificate has been awarded for successfully completing the basicsoftware skills training run by Software Carpentry.The recipient was introduced to core computational skills, includingtask automation, version control, and modular programming.Recipient: {{name}}Date of Award: {{date}}Certified by: {{instructor}} -Certificate of Achievement - From bf52f9966ec5956d1b2db95572902898f9e9735b Mon Sep 17 00:00:00 2001 From: Mathew Biddle <8480023+MathewBiddle@users.noreply.github.com> Date: Fri, 5 May 2023 11:40:08 -0400 Subject: [PATCH 05/10] removing unnecessary script --- certificate/bin/certificates.py | 196 -------------------------------- 1 file changed, 196 deletions(-) delete mode 100644 certificate/bin/certificates.py diff --git a/certificate/bin/certificates.py b/certificate/bin/certificates.py deleted file mode 100644 index f333386..0000000 --- a/certificate/bin/certificates.py +++ /dev/null @@ -1,196 +0,0 @@ -#!/usr/bin/env python3 - -''' -Generate a certificate from a template. - -* Requires the python package 'cairosvg' to be installed. - Please visit http://cairosvg.org/ for install instructions. -* Some systems may also need to have 'cairo' installed. - Please visit http://cairographics.org/download/ for the same. - -On a Mac, a typical command line is - -python bin/certificates.py \ - -b swc-instructor - -r $HOME/sc/certification/ \ - -u turing_alan - date='January 24, 1924' \ - instructor='Ada Lovelace' \ - name='Alan Turing' - -where: - - -b: BADGE_TYPE - -r: ROOT_DIRECTORY - -u: USER_ID - name=value: fill-ins for the template - -The script then looks for $(ROOT_DIRECTORY)/$(BADGE_TYPE).svg as a template -file, and creates $(ROOT_DIRECTORY)/$(BADGE_TYPE)/$(USER_ID).pdf as output. - -This script will also take a CSV file as input. The file must contain rows of: - - badge,trainer,user_id,new_instructor,email,date - -such as: - - swc-instructor,Grace Hopper,turing_alan,Alan Turing,alan@turing.org,2016-01-27 - -In this case, the command line invocation is: - -python bin/certificates.py \ - -r $HOME/sc/certification/ \ - -c input.csv -''' - -import sys -import os -import re -import csv -import tempfile -import subprocess -import unicodedata -from optparse import OptionParser -import time -from datetime import date -import cairosvg - - -DATE_FORMAT = '%B %-d, %Y' - - -def main(): - args = parse_args() - if args.csv_file: - process_csv(args) - else: - process_single(args) - - -def parse_args(): - '''Get command-line arguments.''' - - parser = OptionParser() - # -i argument retained for backward incompatibility, - # not used anymore - parser.add_option('-i', '--ink', - default='/Applications/Inkscape.app/Contents/Resources/bin/inkscape', - dest='inkscape', - help='[deprecated] Path to Inkscape') - parser.add_option('-b', '--badge', - default=None, dest='badge_type', help='Type of badge') - parser.add_option('-r', '--root', - default=os.getcwd(), dest='root_dir', help='Root directory (current by default)') - parser.add_option('-u', '--userid', - default=None, dest='user_id', help='User ID') - parser.add_option('-c', '--csv', - default=None, dest='csv_file', help='CSV file') - - args, extras = parser.parse_args() - check(args.root_dir is not None, 'Must specify root directory') - msg = 'Must specify either CSV file or both root directory and user ID' - if args.csv_file is not None: - check((args.badge_type is None) and (args.user_id is None), msg) - elif args.badge_type and args.user_id: - check(args.csv_file is None, msg) - else: - check(False, msg) - - args.params = extract_parameters(extras) - if 'date' not in args.params: - args.params['date'] = date.strftime(date.today(), DATE_FORMAT) - - return args - - -def extract_parameters(args): - '''Extract key-value pairs from command line (checking for uniqueness).''' - - result = {} - for a in args: - fields = a.split('=') - assert len(fields) == 2, 'Badly formatted key-value pair "{0}"'.format(a) - key, value = fields - assert key not in result, 'Duplicate key "{0}"'.format(key) - result[key] = value - return result - - -def process_csv(args): - '''Process a CSV file.''' - - with open(args.csv_file, 'r') as raw: - reader = csv.reader(raw) - for row in reader: - check(len(row) == 6, 'Badly-formatted row in CSV: {0}'.format(row)) - badge_type, args.params['instructor'], user_id, args.params['name'], email, args.params['date'] = row - if '-' in args.params['date']: - d = time.strptime(args.params['date'], '%Y-%m-%d') - d = date(*d[:3]) - args.params['date'] = date.strftime(d, DATE_FORMAT) - template_path = construct_template_path(args.root_dir, badge_type) - output_path = construct_output_path(args.root_dir, badge_type, user_id) - create_certificate(template_path, output_path, args.params) - -def process_single(args): - '''Process a single entry.''' - - template_path = construct_template_path(args.root_dir, args.badge_type) - output_path = construct_output_path(args.root_dir, args.badge_type, args.user_id) - create_certificate(template_path, output_path, args.params) - - -def construct_template_path(root_dir, badge_type): - '''Create path for template file.''' - - return os.path.join(root_dir, badge_type + '.svg') - - -def construct_output_path(root_dir, badge_type, user_id): - '''Create path for generated PDF certificate.''' - - badge_path = os.path.join(root_dir, badge_type) - path_exists = os.path.exists(badge_path) - - if not path_exists: - os.mkdir(badge_path) - - return os.path.join(badge_path, user_id + '.pdf') - - -def create_certificate(template_path, output_path, params): - '''Create a single certificate.''' - - with open(template_path, 'r') as reader: - template = reader.read() - check_template(template, params) - - for key, value in params.items(): - pattern = '{{' + key + '}}' - template = template.replace(pattern, value) - - tmp = tempfile.NamedTemporaryFile(suffix='.svg', delete=False) - tmp.write(bytes(template, 'utf-8')) - - cairosvg.svg2pdf(url=tmp.name, write_to=output_path, dpi=90) - - -def check_template(template, params): - '''Check that all values required by template are present.''' - - expected = re.findall(r'\{\{([^}]*)\}\}', template) - missing = set(expected) - set(params.keys()) - check(not missing, - 'Missing parameters required by template: {0}'.format(' '.join(missing))) - - -def check(condition, message): - '''Fail if condition not met.''' - - if not condition: - print(message, file=sys.stderr) - sys.exit(1) - - -if __name__ == '__main__': - main() From 893d0fc55177319fe48755aca86d957c5be2ad21 Mon Sep 17 00:00:00 2001 From: Mathew Biddle <8480023+MathewBiddle@users.noreply.github.com> Date: Fri, 5 May 2023 12:17:43 -0400 Subject: [PATCH 06/10] clarifying variable convention for svg --- certificate/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/certificate/README.md b/certificate/README.md index e09df3a..b1009b0 100644 --- a/certificate/README.md +++ b/certificate/README.md @@ -24,6 +24,16 @@ In `make_certificate.py` edit `config` for the persons name and date of the work `make_certificate.py` will pick up the template and insert the appropriate information from the `config` variable. +The variables in the svg should follow the structure of the `config` dictionary: +```python +config = { + "name": {"first_name": "Mathew", "last_name": "Biddle"}, + "date": "2023-05-19", +} +``` + +first name is accessed through `config.name.first_name`, last name through `config.name.last_name` and date is accessed through `config.date`. + ## Historical information: There are two ways to build certificates from this repo, one depends on the python package cairosvg which in turn depends on cairo development libraries being installed. To use this method, use `bin/certificates.py` to build certificates. From ce6f53ed43778f21c8ba26342bbd34d2a3c8a00c Mon Sep 17 00:00:00 2001 From: Mathew Biddle <8480023+MathewBiddle@users.noreply.github.com> Date: Fri, 5 May 2023 13:00:48 -0400 Subject: [PATCH 07/10] saving svg as pdf --- certificate/bin/make_certificate.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/certificate/bin/make_certificate.py b/certificate/bin/make_certificate.py index be6e619..0766b16 100644 --- a/certificate/bin/make_certificate.py +++ b/certificate/bin/make_certificate.py @@ -1,7 +1,14 @@ import os from jinja2 import Environment, FileSystemLoader +from svglib.svglib import svg2rlg +from reportlab.graphics import renderPDF +def svg2pdf(fname): + drawing = svg2rlg(fname) + outname = fname.replace(".svg", '.pdf') + renderPDF.drawToFile(drawing, outname) + def write_svg_cert(template, config): root = os.path.dirname(os.path.abspath(__file__)) # root = path to output directory @@ -17,6 +24,7 @@ def write_svg_cert(template, config): with open(filename, "w") as fh: fh.write(template.render(configs=config)) + svg2pdf(filename) def load_template(): root = os.path.dirname(os.path.abspath(__file__)) From 8d320f3e7e7a84cf8c75fcbde63e47dc1a38dc7e Mon Sep 17 00:00:00 2001 From: Mathew Biddle <8480023+MathewBiddle@users.noreply.github.com> Date: Fri, 5 May 2023 13:02:18 -0400 Subject: [PATCH 08/10] running black --- certificate/bin/make_certificate.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/certificate/bin/make_certificate.py b/certificate/bin/make_certificate.py index 0766b16..934497a 100644 --- a/certificate/bin/make_certificate.py +++ b/certificate/bin/make_certificate.py @@ -6,9 +6,10 @@ def svg2pdf(fname): drawing = svg2rlg(fname) - outname = fname.replace(".svg", '.pdf') + outname = fname.replace(".svg", ".pdf") renderPDF.drawToFile(drawing, outname) + def write_svg_cert(template, config): root = os.path.dirname(os.path.abspath(__file__)) # root = path to output directory @@ -26,6 +27,7 @@ def write_svg_cert(template, config): svg2pdf(filename) + def load_template(): root = os.path.dirname(os.path.abspath(__file__)) templates_dir = os.path.join(root, "templates") From 3f27fa0c1387508bbf9de61b05f99a05953ee967 Mon Sep 17 00:00:00 2001 From: "Mathew.Biddle" Date: Wed, 17 May 2023 08:53:28 -0400 Subject: [PATCH 09/10] finalizing template adding iterator for cert auto-generation --- certificate/bin/make_certificate.py | 57 ++- certificate/bin/templates/certificate.svg | 452 ++++++++++++++++++---- 2 files changed, 439 insertions(+), 70 deletions(-) diff --git a/certificate/bin/make_certificate.py b/certificate/bin/make_certificate.py index 934497a..d0b77b1 100644 --- a/certificate/bin/make_certificate.py +++ b/certificate/bin/make_certificate.py @@ -43,13 +43,60 @@ def write_templates(config): def main(config): - write_templates(config) + for person in config: + write_templates(person) if __name__ == "__main__": - config = { - "name": {"first_name": "Mathew", "last_name": "Biddle"}, - "date": "2023-05-19", - } + config = [ + { + "name": {"first_name": "Abby", "last_name": "Benson"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Matt", "last_name": "Biddle"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Julieta", "last_name": "Maldonado"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Errol", "last_name": "Ronje"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Kylie", "last_name": "Langlois"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Laura", "last_name": "Teed"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Kourtney", "last_name": "Burger"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Javier", "last_name": ""}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Fernando GarcÃa", "last_name": "González"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Marine", "last_name": "Lebrec"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Marc", "last_name": "Ghergariu"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Rodrigo J.", "last_name": "Gonçalves"}, + "date": "2023-05-19", + }, + ] main(config) diff --git a/certificate/bin/templates/certificate.svg b/certificate/bin/templates/certificate.svg index bc70472..04bbd16 100644 --- a/certificate/bin/templates/certificate.svg +++ b/certificate/bin/templates/certificate.svg @@ -1,68 +1,390 @@ - - - - - - - - - - - - - - - Certificate of Participation - - - - - - Certificate of Participati... - - - - - - - - - - - This certifies that - - {{configs.name.first_name}} {{configs.name.last_name}} - - successfully participated in the2023 Marine - Biological Data Mobilization Workshop - - - - - - This certifies that... - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Certificate of Completion + This certificate is awarded to + + {{configs.name.first_name}} + {{configs.name.last_name}} + + For successfully completing the Marine Biodiversity Data Mobilization Workshop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - Text is not SVG - cannot display - - \ No newline at end of file From d972af104d0eaab30775c964a73c703912526773 Mon Sep 17 00:00:00 2001 From: "Mathew.Biddle" Date: Wed, 17 May 2023 09:50:06 -0400 Subject: [PATCH 10/10] adding power point svg template instructions --- certificate/README.md | 54 ++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/certificate/README.md b/certificate/README.md index b1009b0..0b51414 100644 --- a/certificate/README.md +++ b/certificate/README.md @@ -1,15 +1,39 @@ # Certificates for The Carpentries -To create the certificate, run: +To create certificates, run: ```bash python make_certificate.py ``` In `make_certificate.py` edit `config` for the persons name and date of the workshop. +This will generate `.svg` and `.pdf` certificates in the `certs/` directory. File names follow the convention `firstName_lastName_date.[svg|pdf]` + + ## Create the template certificate.svg +### Using Microsoft Power Point +1. Create the certificate of interest in MS Power Point. +1. Make sure to include the jinja template variables in the location you want the content to appear. + 1. For example, the appicants first name will replace the variable `{{configs.name.first_name}}` in the svg file. +1. Save the slide as SVG. File -> Save As -> select "Scalable Vector Graphics". Choose to save only the one slide. +1. This is where is gets tricky. The SVG from Power Point has some very specific formatting for text location on the slide. For example, text will be stored as `tspan` with specific x & y starting locations on the page. Unfortunately, this doesn't ensure the content is centered on the page, especially when we have variable content through the jinja template. + ```xml + + This certificate is awarded to + + ``` + Instead, we can generalize this to a `text` element and specify center and the y location: + ```xml + + This certificate is awarded to + + ``` +1. Edit the XML in the svg file to adjust the text elements to be percentages in the x-direction. Make any other custom edits to the svg file. Note that Power Point might separate each work into it's own `tspan` element. These can be simplified into one `text` element. +1. Save the template svg as `certificate.svg` in the `templates\` directory. + +### Using diagrams.net 1. Using https://app.diagrams.net/ design the certificate. 1. Include the jinja template variables where the information should be replaced. 1. The appicants first name will replace the variable `{{configs.name.first_name}}` in the svg file. @@ -24,24 +48,18 @@ In `make_certificate.py` edit `config` for the persons name and date of the work `make_certificate.py` will pick up the template and insert the appropriate information from the `config` variable. -The variables in the svg should follow the structure of the `config` dictionary: +The variables in the svg should follow the structure of the `config` list: ```python -config = { - "name": {"first_name": "Mathew", "last_name": "Biddle"}, - "date": "2023-05-19", -} +config = [ + { + "name": {"first_name": "Mathew", "last_name": "Biddle"}, + "date": "2023-05-19", + }, + { + "name": {"first_name": "Abby", "last_name": "Benson"}, + "date": "2023-05-19", + }, +] ``` first name is accessed through `config.name.first_name`, last name through `config.name.last_name` and date is accessed through `config.date`. - -## Historical information: - -There are two ways to build certificates from this repo, one depends on the python package cairosvg which in turn depends on cairo development libraries being installed. To use this method, use `bin/certificates.py` to build certificates. - -The second, pure python method uses the python packages jinja2, jinja2-cli and svglib to build the certificates. - -To build certificates this way, you can run: -``` -jinja2 swc-attendance.svg -D name="Firstname Lastname" -D date="Nov. 6, 2017" -D instructor="Some Instructor Name" > lastname_firstname.svg -svg2pdf lastname_firstname.svg -```