From 929ac81515b3b426ff06f1d6d913bab930421a92 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Mon, 8 Feb 2021 09:51:52 +0100 Subject: [PATCH 01/15] Added cards api endpoint ref #14 --- src/controllers/PdfController.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/controllers/PdfController.ts b/src/controllers/PdfController.ts index affc7a4..49bb1a0 100644 --- a/src/controllers/PdfController.ts +++ b/src/controllers/PdfController.ts @@ -1,6 +1,7 @@ import { Body, JsonController, Post, QueryParam, Res } from 'routing-controllers'; import { OpenAPI } from 'routing-controllers-openapi'; import { Runner } from '../models/Runner'; +import { RunnerCard } from '../models/RunnerCard'; import { PdfCreator } from '../PdfCreator'; /** @@ -27,4 +28,19 @@ export class PdfController { res.setHeader('content-type', 'application/pdf'); return contracts; } + + @Post('/cards') + @OpenAPI({ description: "Generate runner card pdfs from runner card objects.
You can choose your prefered locale by passing the 'locale' query-param." }) + async generateCards(@Body({ validate: true, options: { limit: "500mb" } }) cards: RunnerCard | RunnerCard[], @Res() res: any, @QueryParam("locale") locale: string) { + if (!this.initialized) { + await this.pdf.init(); + this.initialized = true; + } + if (!Array.isArray(cards)) { + cards = [cards]; + } + const contracts = await this.pdf.generateRunnerCards(cards, locale); + res.setHeader('content-type', 'application/pdf'); + return contracts; + } } From 8fc6c7176ee92f813db1e1d4b3e5ef1b2f4e1aef Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Mon, 8 Feb 2021 09:55:29 +0100 Subject: [PATCH 02/15] Added basic card generation function ref #14 --- src/PdfCreator.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index df60730..bc03f2d 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -9,6 +9,7 @@ import path from 'path'; import { PDFDocument } from 'pdf-lib'; import puppeteer from "puppeteer"; import { Runner } from './models/Runner'; +import { RunnerCard } from './models/RunnerCard'; import { RunnerGroup } from './models/RunnerGroup'; /** * This class is responsible for all things pdf creation. @@ -112,6 +113,30 @@ export class PdfCreator { return pdf } + /** + * Generate runner card pdfs. + * @param cards The runner cars you want to generate the cards for. + * @param locale The locale used for the cards (default:en) + */ + public async generateRunnerCards(cards: RunnerCard[], locale: string = "en"): Promise { + if (cards.length > 10) { + let pdf_promises = new Array>(); + let i, j; + for (i = 0, j = cards.length; i < j; i += 10) { + let chunk = cards.slice(i, i + 10); + pdf_promises.push(this.generateRunnerCards(chunk, locale)); + } + const pdfs = await Promise.all(pdf_promises); + return await this.mergePdfs(pdfs); + } + await i18next.changeLanguage(locale); + const template_source = fs.readFileSync(`${this.templateDir}/runner_card.html`, 'utf8'); + const template = Handlebars.compile(template_source); + const result = template({ cards }) + const pdf = await this.renderPdf(result, { format: "A4", landscape: false }); + return pdf + } + /** * Converts all images in html to base64. * Works with image files in the template directory or images from urls. From d3a213ce3326aeb96d924e16a31fc87bf82eb5b3 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Mon, 8 Feb 2021 10:07:58 +0100 Subject: [PATCH 03/15] Added basic logic to generate two-sided runnercards ref #14 --- src/templates/runner_card.html | 44 ++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/templates/runner_card.html diff --git a/src/templates/runner_card.html b/src/templates/runner_card.html new file mode 100644 index 0000000..fdf0dc9 --- /dev/null +++ b/src/templates/runner_card.html @@ -0,0 +1,44 @@ + + + + + Sponsoring contract + + + + + +
+
+ {{#each cards}} +
+

Front: {{this.code}}

+
+ {{/each}} +
+
+
+
+ {{#each cards}} +
+

Back: {{this.code}}

+
+ {{/each}} +
+
+ + + \ No newline at end of file From b92a6f7b2b98fb0074d5a563d9918295e9ec0274 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Mon, 8 Feb 2021 10:14:27 +0100 Subject: [PATCH 04/15] Added sizing for the real cards ref #14 --- src/templates/runner_card.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/templates/runner_card.html b/src/templates/runner_card.html index fdf0dc9..5f00ad6 100644 --- a/src/templates/runner_card.html +++ b/src/templates/runner_card.html @@ -11,12 +11,18 @@ position: relative; box-sizing: border-box; page-break-after: always; + padding: 1.2cm 2cm 1.2cm 2cm } body.A4 .sheet { width: 210mm; height: 296mm } + + .runnercard { + border: 1px solid; + height: 5.5cm; + } @@ -24,7 +30,7 @@
{{#each cards}} -
+

Front: {{this.code}}

{{/each}} @@ -33,7 +39,7 @@
{{#each cards}} -
+

Back: {{this.code}}

{{/each}} From 016f746c7cec29ab391b3918c7589dea0cff9890 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Mon, 8 Feb 2021 15:53:44 +0100 Subject: [PATCH 05/15] Styled front ref #14 --- src/PdfCreator.ts | 2 +- src/templates/runner_card.html | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index bc03f2d..64286ad 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -132,7 +132,7 @@ export class PdfCreator { await i18next.changeLanguage(locale); const template_source = fs.readFileSync(`${this.templateDir}/runner_card.html`, 'utf8'); const template = Handlebars.compile(template_source); - const result = template({ cards }) + const result = template({ cards, eventname: "LfK! 2069" }) const pdf = await this.renderPdf(result, { format: "A4", landscape: false }); return pdf } diff --git a/src/templates/runner_card.html b/src/templates/runner_card.html index 5f00ad6..c1b0ef5 100644 --- a/src/templates/runner_card.html +++ b/src/templates/runner_card.html @@ -22,6 +22,7 @@ .runnercard { border: 1px solid; height: 5.5cm; + overflow: hidden; } @@ -31,7 +32,21 @@
{{#each cards}}
-

Front: {{this.code}}

+

{{../eventname}}

+

lauf-fuer-kaya.de - am 01.01.2021

+

Mit unterstützung von:

+
+
+ + +
+
+ + +
+
+

{{this.runner.lastname}}, {{this.runner.firstname}} {{this.runner.middlename}}

+

{{this.runner.group.name}}

{{/each}}
From 68f46a45b5a51c8a8edafca852cb274af388fa76 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Mon, 8 Feb 2021 15:57:09 +0100 Subject: [PATCH 06/15] Added **very** basic backside ref #14 --- src/templates/runner_card.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/templates/runner_card.html b/src/templates/runner_card.html index c1b0ef5..2a85229 100644 --- a/src/templates/runner_card.html +++ b/src/templates/runner_card.html @@ -55,7 +55,10 @@
{{#each cards}}
-

Back: {{this.code}}

+ + + +
{{/each}}
From 7f58dd694b53152069c2095b2e18dd3a46cd04dd Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Mon, 8 Feb 2021 16:14:10 +0100 Subject: [PATCH 07/15] Fixed double-sided printing ref #14 --- src/PdfCreator.ts | 21 ++++++++++++++++++++- src/templates/runner_card.html | 7 +++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index 64286ad..707e003 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -129,10 +129,11 @@ export class PdfCreator { const pdfs = await Promise.all(pdf_promises); return await this.mergePdfs(pdfs); } + const cards_swapped = this.swapArrayPairs(cards); await i18next.changeLanguage(locale); const template_source = fs.readFileSync(`${this.templateDir}/runner_card.html`, 'utf8'); const template = Handlebars.compile(template_source); - const result = template({ cards, eventname: "LfK! 2069" }) + const result = template({ cards, cards_swapped, eventname: "LfK! 2069" }) const pdf = await this.renderPdf(result, { format: "A4", landscape: false }); return pdf } @@ -220,4 +221,22 @@ export class PdfCreator { runner.group = group; return runner; } + + /** + * Swaps pairs (0/1, 2/3, ...) of elements in an array recursively. + * If the last element has no partner it inserts an empty element at the end and swaps the two + * This is needed to generate pdfs with front- and backside that get printet on one paper. + * @param array The array which's pairs shall get switched. + * @returns Array with swapped pairs, + */ + private swapArrayPairs(array): Array { + if (array.length == 1) { + return [null, array[0]]; + } + if (array.length == 0) { + return null; + } + + return [array[1], array[0]].concat(this.swapArrayPairs(array.slice(2))); + } } \ No newline at end of file diff --git a/src/templates/runner_card.html b/src/templates/runner_card.html index 2a85229..987194e 100644 --- a/src/templates/runner_card.html +++ b/src/templates/runner_card.html @@ -46,19 +46,18 @@

{{this.runner.lastname}}, {{this.runner.firstname}} {{this.runner.middlename}}

-

{{this.runner.group.name}}

+

{{this.runner.group.name}} {{this.id}}

{{/each}}
- {{#each cards}} + {{#each cards_swapped}}
+

{{this.id}}

- -
{{/each}}
From 5c075bce8b94ff4482448c3cd56bdc28cbe0a7d9 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 9 Feb 2021 19:15:08 +0100 Subject: [PATCH 08/15] Added barcode generatin ref #19 --- src/PdfCreator.ts | 5 +++-- src/asyncHelpers.ts | 3 ++- src/templates/runner_card.html | 13 +++++++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index 025e7f8..ce3d430 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -123,7 +123,7 @@ export class PdfCreator { * @param cards The runner cars you want to generate the cards for. * @param locale The locale used for the cards (default:en) */ - public async generateRunnerCards(cards: RunnerCard[], locale: string = "en"): Promise { + public async generateRunnerCards(cards: RunnerCard[], locale: string = "en", codeformat: string = config.codeformat): Promise { if (cards.length > 10) { let pdf_promises = new Array>(); let i, j; @@ -138,7 +138,8 @@ export class PdfCreator { await i18next.changeLanguage(locale); const template_source = fs.readFileSync(`${this.templateDir}/runner_card.html`, 'utf8'); const template = Handlebars.compile(template_source); - const result = template({ cards, cards_swapped, eventname: "LfK! 2069" }) + let result = template({ cards, cards_swapped, eventname: "LfK! 2069", codeformat: "qrcode" }) + result = await awaitAsyncHandlebarHelpers(result); const pdf = await this.renderPdf(result, { format: "A4", landscape: false }); return pdf } diff --git a/src/asyncHelpers.ts b/src/asyncHelpers.ts index 881bbe6..53a9f16 100644 --- a/src/asyncHelpers.ts +++ b/src/asyncHelpers.ts @@ -3,6 +3,7 @@ import bwipjs from "bwip-js"; export const asyncHelpers = new AsyncHelpers(); async function generateBarcode(str, options, emtpy, cb) { + if (str == null) { cb(null, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg=="); return; } let res = await generateBase64Barcode(options.toString(), str.toString()); cb(null, res); } @@ -18,7 +19,7 @@ export async function generateBase64Barcode(type: string, content: string): Prom height: 10, width: 10, includetext: true, - textxalign: 'center', + textxalign: 'center' } if (type != "qrcode") { delete options.width; diff --git a/src/templates/runner_card.html b/src/templates/runner_card.html index 987194e..09f6eb8 100644 --- a/src/templates/runner_card.html +++ b/src/templates/runner_card.html @@ -38,15 +38,17 @@
- +
- +

{{this.runner.lastname}}, {{this.runner.firstname}} {{this.runner.middlename}}

-

{{this.runner.group.name}} {{this.id}}

+

{{this.runner.group.name}}

{{/each}}
@@ -55,9 +57,12 @@
{{#each cards_swapped}}
-

{{this.id}}

+ +
{{/each}}
From 68572b194eb740238be8101efed6fdb2a207f65b Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 9 Feb 2021 19:37:32 +0100 Subject: [PATCH 09/15] Added card generation speed tests (part 1) ref #14 --- src/tests/speedtest.ts | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/tests/speedtest.ts b/src/tests/speedtest.ts index c016204..aefb2a1 100644 --- a/src/tests/speedtest.ts +++ b/src/tests/speedtest.ts @@ -1,6 +1,7 @@ import axios from "axios" import faker from "faker" import { Runner } from '../models/Runner' +import { RunnerCard } from '../models/RunnerCard' import { RunnerGroup } from '../models/RunnerGroup' const baseurl = "http://localhost:4010" @@ -33,11 +34,45 @@ function generateRunners(amount: number): Runner[] { return runners; } +function generateCards(amount: number): RunnerCard[] { + let cards: RunnerCard[] = new Array(); + let card = new RunnerCard(); + for (let runner of generateRunners(amount)) { + card.id = runner.id; + card.code = idToEan13(card.id); + card.runner = runner; + cards.push(card); + } + return cards; +} + +function idToEan13(id): string { + const multiply = [1, 3]; + id = id.toString(); + + if (id.length > 12) { + throw new Error("id too long"); + } + while (id.length < 12) { id = '0' + id; } + + let total = 0; + this.id.split('').forEach((letter, index) => { + total += parseInt(letter, 10) * multiply[index % 2]; + }); + const checkSum = (Math.ceil(total / 10) * 10) - total; + return this.id + checkSum.toString(); +} + async function postContracts(runners: Runner[]): Promise { const res = await axios.post(`${baseurl}/contracts`, runners); return new Measurement("contract", runners.length, parseInt(res.headers['request-duration'])) } +async function postCards(cards: RunnerCard[]): Promise { + const res = await axios.post(`${baseurl}/cards`, cards); + return new Measurement("card", cards.length, parseInt(res.headers['request-duration'])) +} + async function testContracts(sizes): Promise { let measurements = new Array(); console.log("#### Testing contracts ####"); @@ -50,14 +85,28 @@ async function testContracts(sizes): Promise { return measurements; } +async function testCards(sizes): Promise { + let measurements = new Array(); + console.log("#### Testing Cards ####"); + + for (let size of sizes) { + const m = await postCards(generateCards(size)); + console.log(m.toString()); + measurements.push(m); + } + return measurements; +} + async function main() { const sizes = [0, 1, 10, 50, 100, 200, 500, 1000] console.log("########### Speedtest ###########"); console.log(`Document server version (according to the api): ${(await axios.get("http://localhost:4010/version")).data.version}`); console.log("####### Running tests #######"); const contractResults = await testContracts(sizes); + const cardResults = await testCards(sizes); console.log("####### Results #######"); console.table(contractResults); + console.table(cardResults); } main(); From d38923c4ad3a2cf8872e236dd42f078e2a0e1045 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 9 Feb 2021 19:40:02 +0100 Subject: [PATCH 10/15] Added card generation speed tests (part 2) ref #14 --- src/tests/speedtest.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/speedtest.ts b/src/tests/speedtest.ts index aefb2a1..0ed4372 100644 --- a/src/tests/speedtest.ts +++ b/src/tests/speedtest.ts @@ -56,11 +56,11 @@ function idToEan13(id): string { while (id.length < 12) { id = '0' + id; } let total = 0; - this.id.split('').forEach((letter, index) => { + id.split('').forEach((letter, index) => { total += parseInt(letter, 10) * multiply[index % 2]; }); const checkSum = (Math.ceil(total / 10) * 10) - total; - return this.id + checkSum.toString(); + return id + checkSum.toString(); } async function postContracts(runners: Runner[]): Promise { From 9697d53a1527854536f8ddf5426f7ca902772f51 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Fri, 12 Feb 2021 17:06:20 +0100 Subject: [PATCH 11/15] Fixed bug in array swapping function ref #14 --- src/PdfCreator.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index ce3d430..3b21eab 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -246,6 +246,10 @@ export class PdfCreator { return null; } - return [array[1], array[0]].concat(this.swapArrayPairs(array.slice(2))); + const rest = this.swapArrayPairs(array.slice(2)) + if (!rest) { + return [array[1], array[0]] + } + return [array[1], array[0]].concat(rest); } } \ No newline at end of file From 68a1b8f3e0515e56c7c6069f7f3ef8db24c92674 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Fri, 12 Feb 2021 17:19:57 +0100 Subject: [PATCH 12/15] Implmented sponsoring image selection from array ref #14 --- src/PdfCreator.ts | 12 ++++++++++++ src/templates/runner_card.html | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index 3b21eab..83b5b5f 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -14,6 +14,8 @@ import { Runner } from './models/Runner'; import { RunnerCard } from './models/RunnerCard'; import { RunnerGroup } from './models/RunnerGroup'; +const sponsors: string[] = ["https://odit.services/assets/img/profile-pic-no_bg.hash.0c81702a.png", "./sponsoringheader.png"] + /** * This class is responsible for all things pdf creation. * This uses the html templates from src/templates. @@ -87,6 +89,15 @@ export class PdfCreator { return i18next.t(str, PdfCreator.interpolations).toString(); } ); + await Handlebars.registerHelper('--sponsor', + function (str) { + const index = (parseInt(str) % sponsors.length); + if (isNaN(index)) { + return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==" + } + return sponsors[index]; + } + ); this.browser = await puppeteer.launch({ headless: true, args: minimal_args }); } @@ -140,6 +151,7 @@ export class PdfCreator { const template = Handlebars.compile(template_source); let result = template({ cards, cards_swapped, eventname: "LfK! 2069", codeformat: "qrcode" }) result = await awaitAsyncHandlebarHelpers(result); + fs.writeFileSync("lelelelele.tmp", result); const pdf = await this.renderPdf(result, { format: "A4", landscape: false }); return pdf } diff --git a/src/templates/runner_card.html b/src/templates/runner_card.html index 09f6eb8..69066c8 100644 --- a/src/templates/runner_card.html +++ b/src/templates/runner_card.html @@ -39,7 +39,7 @@
+ src="{{--sponsor this.id}}" />
@@ -59,7 +59,7 @@
+ src="{{--sponsor this.id}}" /> From 08e858726c1462b599ba9cb3f7fb057f35178b83 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Fri, 12 Feb 2021 17:45:52 +0100 Subject: [PATCH 13/15] Fixed runnercard backside padding ref #14 --- src/templates/runner_card.html | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/templates/runner_card.html b/src/templates/runner_card.html index 69066c8..c85218e 100644 --- a/src/templates/runner_card.html +++ b/src/templates/runner_card.html @@ -56,13 +56,12 @@
{{#each cards_swapped}} -
+
- - - +
+ +
+
{{/each}}
From 29376a7782ce39f04f856ec78775e65aa11f0ed7 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Fri, 12 Feb 2021 17:55:37 +0100 Subject: [PATCH 14/15] Now loading sponsor logos from env ref #14 --- src/PdfCreator.ts | 6 ++---- src/config.ts | 12 +++++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index 83b5b5f..b48889e 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -14,8 +14,6 @@ import { Runner } from './models/Runner'; import { RunnerCard } from './models/RunnerCard'; import { RunnerGroup } from './models/RunnerGroup'; -const sponsors: string[] = ["https://odit.services/assets/img/profile-pic-no_bg.hash.0c81702a.png", "./sponsoringheader.png"] - /** * This class is responsible for all things pdf creation. * This uses the html templates from src/templates. @@ -91,11 +89,11 @@ export class PdfCreator { ); await Handlebars.registerHelper('--sponsor', function (str) { - const index = (parseInt(str) % sponsors.length); + const index = (parseInt(str) % config.sponor_logos.length); if (isNaN(index)) { return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==" } - return sponsors[index]; + return config.sponor_logos[index]; } ); this.browser = await puppeteer.launch({ headless: true, args: minimal_args }); diff --git a/src/config.ts b/src/config.ts index 8422d8d..6815cc2 100644 --- a/src/config.ts +++ b/src/config.ts @@ -8,7 +8,8 @@ export const config = { eventname: process.env.EVENT_NAME || "Please set the event name", currency_symbol: process.env.CURRENCY_SYMBOL || "€", sponsoring_receipt_minimum_amount: process.env.SPONSORING_RECEIPT_MINIMUM_AMOUNT || "10", - codeformat: process.env.CODEFORMAT || "qrcode" + codeformat: process.env.CODEFORMAT || "qrcode", + sponor_logos: getSponsorLogos() } let errors = 0 if (typeof config.internal_port !== "number") { @@ -17,4 +18,13 @@ if (typeof config.internal_port !== "number") { if (typeof config.development !== "boolean") { errors++ } +function getSponsorLogos(): string[] { + try { + const logos = JSON.parse(process.env.SPONOR_LOGOS); + if (!Array.isArray(logos)) { throw new Error("Not an array.") } + return logos; + } catch (error) { + return ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg=="]; + } +} export let e = errors \ No newline at end of file From cf0f5839ee1e1b87f7b5bd5a299a35574fd1bb3c Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Fri, 12 Feb 2021 17:55:48 +0100 Subject: [PATCH 15/15] Added new env vars to readme ref #14 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 91dea08..7e77e25 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ The basic generation mechanism makes the templates and routes interchangeable (i | EVENT_NAME | String | "Please set the event name" | The event's name - used to generate pdf text. | CURRENCY_SYMBOL | String | "€" | The your currency's symbol - used to generate pdf text. | SPONSORING_RECEIPT_MINIMUM_AMOUNT | String | "10" | The mimimum total donation amount a sponsor has to donate to be able to receive a donation receipt - used to generate pdf text. +| SPONOR_LOGOS | Array | Empty png | The sponsor images you want to loop through. You can provide them via http url, local file or base64-encoded image. ## Templates > The document server uses html templates to generate various pdf documents.