Compare commits
No commits in common. "v0.6.0" and "v0.5.1" have entirely different histories.
89
.drone.yml
89
.drone.yml
@ -33,23 +33,53 @@ steps:
|
|||||||
- git clone $DRONE_REMOTE_URL .
|
- git clone $DRONE_REMOTE_URL .
|
||||||
- git checkout dev
|
- git checkout dev
|
||||||
- name: build dev
|
- name: build dev
|
||||||
depends_on: ["clone"]
|
image: plugins/docker
|
||||||
image: registry.odit.services/library/drone-kaniko
|
depends_on: [clone]
|
||||||
settings:
|
settings:
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
password:
|
password:
|
||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
build_args:
|
repo: registry.odit.services/lfk/document-server
|
||||||
- NPM_REGISTRY_DOMAIN:
|
|
||||||
from_secret: npmjs_domain
|
|
||||||
- NPM_REGISTRY_TOKEN:
|
|
||||||
from_secret: npmjs_token
|
|
||||||
repo: lfk/document-server
|
|
||||||
tags:
|
tags:
|
||||||
- dev
|
- dev
|
||||||
cache: true
|
|
||||||
registry: registry.odit.services
|
registry: registry.odit.services
|
||||||
|
mtu: 1000
|
||||||
|
- name: run changelog export
|
||||||
|
depends_on: ["clone"]
|
||||||
|
image: node:latest
|
||||||
|
commands:
|
||||||
|
- npx auto-changelog --commit-limit false -p -u --hide-credit
|
||||||
|
- name: push new changelog to repo
|
||||||
|
depends_on: ["run changelog export"]
|
||||||
|
image: appleboy/drone-git-push
|
||||||
|
settings:
|
||||||
|
branch: dev
|
||||||
|
commit: true
|
||||||
|
commit_message: 🧾New changelog file version [CI SKIP] [skip ci]
|
||||||
|
author_email: bot@odit.services
|
||||||
|
remote: git@git.odit.services:lfk/document-server.git
|
||||||
|
ssh_key:
|
||||||
|
from_secret: git_ssh
|
||||||
|
- name: run full license export
|
||||||
|
depends_on: ["clone"]
|
||||||
|
image: node:14.15.1-alpine3.12
|
||||||
|
commands:
|
||||||
|
- yarn
|
||||||
|
- yarn licenses:export
|
||||||
|
- name: push new licenses file to repo
|
||||||
|
depends_on: ["run full license export"]
|
||||||
|
image: appleboy/drone-git-push
|
||||||
|
settings:
|
||||||
|
branch: dev
|
||||||
|
commit: true
|
||||||
|
commit_message: 📖New license file version [CI SKIP] [skip ci]
|
||||||
|
author_email: bot@odit.services
|
||||||
|
remote: git@git.odit.services:lfk/document-server.git
|
||||||
|
skip_verify: true
|
||||||
|
ssh_key:
|
||||||
|
from_secret: git_ssh
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
- dev
|
- dev
|
||||||
@ -69,24 +99,30 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- git clone $DRONE_REMOTE_URL .
|
- git clone $DRONE_REMOTE_URL .
|
||||||
- git checkout dev
|
- git checkout dev
|
||||||
- name: build dev
|
- git merge main
|
||||||
|
- git checkout main
|
||||||
|
- name: build latest
|
||||||
depends_on: ["clone"]
|
depends_on: ["clone"]
|
||||||
image: registry.odit.services/library/drone-kaniko
|
image: plugins/docker
|
||||||
settings:
|
settings:
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
password:
|
password:
|
||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
build_args:
|
repo: registry.odit.services/lfk/document-server
|
||||||
- NPM_REGISTRY_DOMAIN:
|
|
||||||
from_secret: npmjs_domain
|
|
||||||
- NPM_REGISTRY_TOKEN:
|
|
||||||
from_secret: npmjs_token
|
|
||||||
repo: lfk/document-server
|
|
||||||
tags:
|
tags:
|
||||||
- latest
|
- latest
|
||||||
cache: true
|
|
||||||
registry: registry.odit.services
|
registry: registry.odit.services
|
||||||
|
mtu: 1000
|
||||||
|
- name: push merge to repo
|
||||||
|
depends_on: ["clone"]
|
||||||
|
image: appleboy/drone-git-push
|
||||||
|
settings:
|
||||||
|
branch: dev
|
||||||
|
commit: false
|
||||||
|
remote: git@git.odit.services:lfk/document-server.git
|
||||||
|
ssh_key:
|
||||||
|
from_secret: git_ssh
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
@ -101,23 +137,18 @@ name: build:tags
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: build $DRONE_TAG
|
- name: build $DRONE_TAG
|
||||||
depends_on: ["clone"]
|
image: plugins/docker
|
||||||
image: registry.odit.services/library/drone-kaniko
|
depends_on: [clone]
|
||||||
settings:
|
settings:
|
||||||
username:
|
username:
|
||||||
from_secret: docker_username
|
from_secret: docker_username
|
||||||
password:
|
password:
|
||||||
from_secret: docker_password
|
from_secret: docker_password
|
||||||
build_args:
|
repo: registry.odit.services/lfk/document-server
|
||||||
- NPM_REGISTRY_DOMAIN:
|
|
||||||
from_secret: npmjs_domain
|
|
||||||
- NPM_REGISTRY_TOKEN:
|
|
||||||
from_secret: npmjs_token
|
|
||||||
repo: lfk/document-server
|
|
||||||
tags:
|
tags:
|
||||||
- "${DRONE_TAG}"
|
- '${DRONE_TAG}'
|
||||||
cache: true
|
|
||||||
registry: registry.odit.services
|
registry: registry.odit.services
|
||||||
|
mtu: 1000
|
||||||
trigger:
|
trigger:
|
||||||
event:
|
event:
|
||||||
- tag
|
- tag
|
40
CHANGELOG.md
40
CHANGELOG.md
@ -2,47 +2,8 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||||
|
|
||||||
#### [v0.6.0](https://git.odit.services/lfk/document-server/compare/v0.5.1...v0.6.0)
|
|
||||||
|
|
||||||
- Merge branch 'bugfix/44-runner-certificates-result-in-a-status-500' into dev [`#44`](https://git.odit.services/lfk/document-server/issues/44)
|
|
||||||
- Lockfile [`b47b2f8`](https://git.odit.services/lfk/document-server/commit/b47b2f804f5419bff6f0cddbc1dbc12d29afd935)
|
|
||||||
- Fixed Locale comma format [`2a33226`](https://git.odit.services/lfk/document-server/commit/2a3322612d473bd9002cf8d6f9807f9dc7d687da)
|
|
||||||
- Added autochangelog [`d064b51`](https://git.odit.services/lfk/document-server/commit/d064b51e1b3e00d9c49b1e983bd75def6d8512be)
|
|
||||||
- Moved drone to kaniko [`744f567`](https://git.odit.services/lfk/document-server/commit/744f567b7cc7fcbe916143bb98f1dd784fe794da)
|
|
||||||
- Updated translation due to customer request [`517e8a0`](https://git.odit.services/lfk/document-server/commit/517e8a081970b9ce4f6f225a7f9b5b54cca1258e)
|
|
||||||
- Bumped docker images [`05e0c63`](https://git.odit.services/lfk/document-server/commit/05e0c639319a2a635bbcf0f5f6bd08d6a46dce74)
|
|
||||||
- wrap distanceDonations.reduce in array length check [`bac004d`](https://git.odit.services/lfk/document-server/commit/bac004d74eb954d1753d4efcdb927822b89fa757)
|
|
||||||
- Nerf [`7dbce9e`](https://git.odit.services/lfk/document-server/commit/7dbce9e87046567de1ea46deaea427a5353057b3)
|
|
||||||
- Version pin [`6add09c`](https://git.odit.services/lfk/document-server/commit/6add09c7df6872b6922f6624ee89b4a04ad6fc0a)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`300b8fd`](https://git.odit.services/lfk/document-server/commit/300b8fd01a0b601935c3658b195759dd19041c5f)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`ff0421d`](https://git.odit.services/lfk/document-server/commit/ff0421da2f16a8f79f9987dabea7bdcb4ef88c05)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`fcbcec8`](https://git.odit.services/lfk/document-server/commit/fcbcec85c531d774be1337f179dae2aa1d5f3839)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`b78534e`](https://git.odit.services/lfk/document-server/commit/b78534e1b0165522ff0ee1dfd110d8ba78f183d8)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`5e92b9a`](https://git.odit.services/lfk/document-server/commit/5e92b9a48fcbb8ab6a179c53f180a7a6bd743ae7)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`dca2829`](https://git.odit.services/lfk/document-server/commit/dca2829323f3a19247455df99498633605d09603)
|
|
||||||
- Fixed decimal separator in docker [`c9cb03e`](https://git.odit.services/lfk/document-server/commit/c9cb03ea95acccd6cdc8b86c747c787938840d07)
|
|
||||||
- Fix for runner donation array [`72303b1`](https://git.odit.services/lfk/document-server/commit/72303b11052276ad15373887f9e04183841f56f4)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`573b921`](https://git.odit.services/lfk/document-server/commit/573b9211972a55df0a38742cb6eb789d6fd3717b)
|
|
||||||
- Added image [`5f4fc74`](https://git.odit.services/lfk/document-server/commit/5f4fc74cd9ff6764d209d49822020cda70b3514e)
|
|
||||||
- 🚀Bumped version to v0.6.0 [`72ed249`](https://git.odit.services/lfk/document-server/commit/72ed2495f6feb90643d3c9d7fa943a2703533331)
|
|
||||||
- Changed default kilometer formatting to min 2 decimals, max 3 [`3af4b52`](https://git.odit.services/lfk/document-server/commit/3af4b521d302e3aab558d20f1fccca57ea61fff3)
|
|
||||||
- Merge pull request 'Fixed decimal separator' (#47) from dev into main [`57a84c2`](https://git.odit.services/lfk/document-server/commit/57a84c256a978f583508bdf772499466a73b4a22)
|
|
||||||
- 🚀Bumped version to v0.5.4 [`4b5a862`](https://git.odit.services/lfk/document-server/commit/4b5a86282d0618a0c5b00fc796efe77db2103356)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`c7f5754`](https://git.odit.services/lfk/document-server/commit/c7f57548f316e1bb6635bd56bd269d80ac1e220f)
|
|
||||||
- Merge pull request 'Hotfixes' (#46) from dev into main [`8d00307`](https://git.odit.services/lfk/document-server/commit/8d003071704b5a6d7b0d70aff2f9cb05c3660b78)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`f846572`](https://git.odit.services/lfk/document-server/commit/f8465721cddfb55d51eb30d29d74ef63d825b5ac)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`451b7fb`](https://git.odit.services/lfk/document-server/commit/451b7fbe0543991e8a203e38daa350a954ae0e11)
|
|
||||||
- 🚀Bumped version to v0.5.3 [`01e1323`](https://git.odit.services/lfk/document-server/commit/01e1323555fe67f6f0ce3c18163e475035bd1cdd)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`4b4d66a`](https://git.odit.services/lfk/document-server/commit/4b4d66ae784150f7e1cc491a3fc5d84c93273aee)
|
|
||||||
- Merge pull request 'v0.5.2: hotfix TypeError in Runner Certificate generation' (#45) from dev into main [`c935950`](https://git.odit.services/lfk/document-server/commit/c935950eb052bce71185fc74c750ec77f081e7df)
|
|
||||||
- 🚀Bumped version to v0.5.2 [`274c13e`](https://git.odit.services/lfk/document-server/commit/274c13e358f16207fe8bb5cdc1b9ede0582ecb46)
|
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`b7b7f6a`](https://git.odit.services/lfk/document-server/commit/b7b7f6a0ae304d24f90a3de3931f53cf08770060)
|
|
||||||
|
|
||||||
#### [v0.5.1](https://git.odit.services/lfk/document-server/compare/v0.5.0...v0.5.1)
|
#### [v0.5.1](https://git.odit.services/lfk/document-server/compare/v0.5.0...v0.5.1)
|
||||||
|
|
||||||
> 22 April 2021
|
|
||||||
|
|
||||||
- Merge pull request 'Release 0.5.1' (#43) from dev into main [`11efdeb`](https://git.odit.services/lfk/document-server/commit/11efdebacf076ecfe0e10cdcda37ac07464901ce)
|
|
||||||
- Quick callstack fix🛠 [`76418f6`](https://git.odit.services/lfk/document-server/commit/76418f65e1e111e83838f0d42c541ae6a8063a09)
|
- Quick callstack fix🛠 [`76418f6`](https://git.odit.services/lfk/document-server/commit/76418f65e1e111e83838f0d42c541ae6a8063a09)
|
||||||
- Fixed barcode generation for runenrcard pdfs🐞 [`f78037c`](https://git.odit.services/lfk/document-server/commit/f78037c0f15162d5b98986edf20d263961f43e69)
|
- Fixed barcode generation for runenrcard pdfs🐞 [`f78037c`](https://git.odit.services/lfk/document-server/commit/f78037c0f15162d5b98986edf20d263961f43e69)
|
||||||
- Updated docker-compose example🐳 [`a4c8dad`](https://git.odit.services/lfk/document-server/commit/a4c8dade23e448d4d4caefe304a6cd9195c873a4)
|
- Updated docker-compose example🐳 [`a4c8dad`](https://git.odit.services/lfk/document-server/commit/a4c8dade23e448d4d4caefe304a6cd9195c873a4)
|
||||||
@ -51,7 +12,6 @@ All notable changes to this project will be documented in this file. Dates are d
|
|||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`2ee4c06`](https://git.odit.services/lfk/document-server/commit/2ee4c060557a44db1974a015412288f7942ebe72)
|
- 🧾New changelog file version [CI SKIP] [skip ci] [`2ee4c06`](https://git.odit.services/lfk/document-server/commit/2ee4c060557a44db1974a015412288f7942ebe72)
|
||||||
- more typo fixes [`981bae4`](https://git.odit.services/lfk/document-server/commit/981bae4786a2fa12a1355122e8c5a1e95e29cf32)
|
- more typo fixes [`981bae4`](https://git.odit.services/lfk/document-server/commit/981bae4786a2fa12a1355122e8c5a1e95e29cf32)
|
||||||
- You can now configure the card's code format distinct from the others [`ac9be79`](https://git.odit.services/lfk/document-server/commit/ac9be793bd598771174f5313ef8288240306ba5c)
|
- You can now configure the card's code format distinct from the others [`ac9be79`](https://git.odit.services/lfk/document-server/commit/ac9be793bd598771174f5313ef8288240306ba5c)
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`0f2d6f5`](https://git.odit.services/lfk/document-server/commit/0f2d6f58d6a8a8888263778cf1a14c73b28e774e)
|
|
||||||
- 🚀Bumped version to v0.5.1 [`22fb3ed`](https://git.odit.services/lfk/document-server/commit/22fb3edd7836ba4ca35e6b208ab6f6620da60f4a)
|
- 🚀Bumped version to v0.5.1 [`22fb3ed`](https://git.odit.services/lfk/document-server/commit/22fb3edd7836ba4ca35e6b208ab6f6620da60f4a)
|
||||||
- Emoji+Chinese fixes🌍 [`b6fc069`](https://git.odit.services/lfk/document-server/commit/b6fc069042dc9c5d7ec97f2660568e8e105780b9)
|
- Emoji+Chinese fixes🌍 [`b6fc069`](https://git.odit.services/lfk/document-server/commit/b6fc069042dc9c5d7ec97f2660568e8e105780b9)
|
||||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`cc4a2b4`](https://git.odit.services/lfk/document-server/commit/cc4a2b4ab4c2cb9976797f93e8348607fb88ea7d)
|
- 🧾New changelog file version [CI SKIP] [skip ci] [`cc4a2b4`](https://git.odit.services/lfk/document-server/commit/cc4a2b4ab4c2cb9976797f93e8348607fb88ea7d)
|
||||||
|
26
Dockerfile
26
Dockerfile
@ -1,5 +1,5 @@
|
|||||||
# Typescript Build
|
# Typescript Build
|
||||||
FROM registry.odit.services/hub/library/node:19.0.1-alpine3.16
|
FROM registry.odit.services/hub/library/node:14.15.1-alpine3.12
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package.json ./
|
COPY package.json ./
|
||||||
RUN npm i -g pnpm
|
RUN npm i -g pnpm
|
||||||
@ -8,20 +8,20 @@ COPY tsconfig.json ./
|
|||||||
COPY src ./src
|
COPY src ./src
|
||||||
RUN pnpm run build
|
RUN pnpm run build
|
||||||
# final image
|
# final image
|
||||||
FROM registry.odit.services/hub/library/alpine:3.16
|
FROM registry.odit.services/hub/library/alpine:3.13.1
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
chromium \
|
chromium \
|
||||||
nss \
|
nss \
|
||||||
freetype \
|
freetype \
|
||||||
freetype-dev \
|
freetype-dev \
|
||||||
harfbuzz \
|
harfbuzz \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
ttf-freefont \
|
ttf-freefont \
|
||||||
nodejs \
|
nodejs \
|
||||||
yarn \
|
yarn \
|
||||||
font-noto-emoji \
|
font-noto-emoji \
|
||||||
&& apk add wqy-zenhei --update-cache --repository https://nl.alpinelinux.org/alpine/edge/testing
|
&& apk add wqy-zenhei --update-cache --repository https://nl.alpinelinux.org/alpine/edge/testing
|
||||||
|
|
||||||
# Tell Puppeteer to skip installing Chrome. We'll be using the installed package.
|
# Tell Puppeteer to skip installing Chrome. We'll be using the installed package.
|
||||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
|
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
version: "3"
|
version: "3"
|
||||||
services:
|
services:
|
||||||
document_server:
|
document_server:
|
||||||
# image: registry.odit.services/lfk/beamershow:0.1.3
|
|
||||||
build: .
|
build: .
|
||||||
ports:
|
ports:
|
||||||
- 4010:4010
|
- 4010:4010
|
||||||
@ -16,4 +15,4 @@ services:
|
|||||||
DISCLAIMER_TEXT: "Hier könnte ihre Werbung stehen"
|
DISCLAIMER_TEXT: "Hier könnte ihre Werbung stehen"
|
||||||
CODEFORMAT: "code39"
|
CODEFORMAT: "code39"
|
||||||
CODEFORMAT_CARDS: "ean13"
|
CODEFORMAT_CARDS: "ean13"
|
||||||
CARD_SUBTITLE: "Hier könnte mehr Werbung stehen"
|
CARD_SUBTITLE: "Hier könnte mehr Werbung stehen"
|
29
licenses.md
29
licenses.md
@ -848,35 +848,6 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
SOFTWARE
|
SOFTWARE
|
||||||
|
|
||||||
|
|
||||||
# auto-changelog
|
|
||||||
**Author**: Pete Cook <pete@cookpete.com> (https://github.com/cookpete)
|
|
||||||
**Repo**: https://github.com/CookPete/auto-changelog
|
|
||||||
**License**: MIT
|
|
||||||
**Description**: Command line tool for generating a changelog from git tags and commit history
|
|
||||||
## License Text
|
|
||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2017 Pete Cook https://cookpete.com
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
|
|
||||||
# cp-cli
|
# cp-cli
|
||||||
**Author**: ?
|
**Author**: ?
|
||||||
**Repo**: https://github.com/screendriver/cp-cli
|
**Repo**: https://github.com/screendriver/cp-cli
|
||||||
|
187
package.json
187
package.json
@ -1,97 +1,90 @@
|
|||||||
{
|
{
|
||||||
"name": "@odit/lfk-document-server",
|
"name": "@odit/lfk-document-server",
|
||||||
"version": "0.6.0",
|
"version": "0.5.1",
|
||||||
"description": "The document generation server for the LfK! runner system. This generates certificates, sponsoring aggreements and more",
|
"description": "The document generation server for the LfK! runner system. This generates certificates, sponsoring aggreements and more",
|
||||||
"main": "src/app.ts",
|
"main": "src/app.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nodemon src/app.ts",
|
"dev": "nodemon src/app.ts",
|
||||||
"build": "rimraf ./dist && tsc && cp-cli ./src/templates ./dist/templates && cp-cli ./src/locales ./dist/locales",
|
"build": "rimraf ./dist && tsc && cp-cli ./src/templates ./dist/templates && cp-cli ./src/locales ./dist/locales",
|
||||||
"licenses:export": "license-exporter --markdown",
|
"licenses:export": "license-exporter --markdown",
|
||||||
"changelog:export": "auto-changelog --commit-limit false -p -u --hide-credit",
|
"release": "release-it --only-version",
|
||||||
"release": "release-it --only-version",
|
"translations:sort": "node sort_translations.js"
|
||||||
"translations:sort": "node sort_translations.js"
|
},
|
||||||
},
|
"repository": {
|
||||||
"repository": {
|
"type": "git",
|
||||||
"type": "git",
|
"url": "git@git.odit.services:lfk/document-server.git"
|
||||||
"url": "git@git.odit.services:lfk/document-server.git"
|
},
|
||||||
},
|
"keywords": [
|
||||||
"keywords": [
|
"odit",
|
||||||
"odit",
|
"lfk",
|
||||||
"lfk",
|
"pdf",
|
||||||
"pdf",
|
"generate"
|
||||||
"generate"
|
],
|
||||||
],
|
"author": {
|
||||||
"author": {
|
"name": "ODIT.Services",
|
||||||
"name": "ODIT.Services",
|
"email": "info@odit.services",
|
||||||
"email": "info@odit.services",
|
"url": "https://odit.services"
|
||||||
"url": "https://odit.services"
|
},
|
||||||
},
|
"contributors": [
|
||||||
"contributors": [
|
{
|
||||||
{
|
"name": "Philipp Dormann",
|
||||||
"name": "Philipp Dormann",
|
"email": "philipp@philippdormann.de",
|
||||||
"email": "philipp@philippdormann.de",
|
"url": "https://philippdormann.de"
|
||||||
"url": "https://philippdormann.de"
|
},
|
||||||
},
|
{
|
||||||
{
|
"name": "Nicolai Ort",
|
||||||
"name": "Nicolai Ort",
|
"email": "info@nicolai-ort.com",
|
||||||
"email": "info@nicolai-ort.com",
|
"url": "https://nicolai-ort.com"
|
||||||
"url": "https://nicolai-ort.com"
|
}
|
||||||
}
|
],
|
||||||
],
|
"license": "CC-BY-NC-SA-4.0",
|
||||||
"license": "CC-BY-NC-SA-4.0",
|
"dependencies": {
|
||||||
"dependencies": {
|
"@odit/class-validator-jsonschema": "2.1.1",
|
||||||
"@odit/class-validator-jsonschema": "2.1.1",
|
"async-helpers": "0.3.17",
|
||||||
"async-helpers": "0.3.17",
|
"axios": "0.21.1",
|
||||||
"axios": "0.21.1",
|
"bwip-js": "2.1.1",
|
||||||
"bwip-js": "2.1.1",
|
"cheerio": "1.0.0-rc.5",
|
||||||
"cheerio": "1.0.0-rc.5",
|
"class-transformer": "0.3.1",
|
||||||
"class-transformer": "0.3.1",
|
"class-validator": "0.13.1",
|
||||||
"class-validator": "0.13.1",
|
"consola": "2.15.3",
|
||||||
"consola": "2.15.3",
|
"cors": "2.8.5",
|
||||||
"cors": "2.8.5",
|
"dotenv": "8.2.0",
|
||||||
"dotenv": "8.2.0",
|
"express": "4.17.1",
|
||||||
"express": "4.17.1",
|
"handlebars": "4.7.7",
|
||||||
"handlebars": "4.7.7",
|
"i18next": "20.1.0",
|
||||||
"i18next": "20.1.0",
|
"i18next-fs-backend": "1.1.1",
|
||||||
"i18next-fs-backend": "1.1.1",
|
"mime-types": "2.1.30",
|
||||||
"mime-types": "2.1.30",
|
"pdf-lib": "1.16.0",
|
||||||
"pdf-lib": "1.16.0",
|
"puppeteer": "8.0.0",
|
||||||
"puppeteer": "8.0.0",
|
"reflect-metadata": "0.1.13",
|
||||||
"reflect-metadata": "0.1.13",
|
"routing-controllers": "0.9.0-alpha.6",
|
||||||
"routing-controllers": "0.9.0-alpha.6",
|
"routing-controllers-openapi": "2.2.0"
|
||||||
"routing-controllers-openapi": "2.2.0"
|
},
|
||||||
},
|
"devDependencies": {
|
||||||
"devDependencies": {
|
"@odit/license-exporter": "0.0.11",
|
||||||
"@odit/license-exporter": "0.0.11",
|
"@types/express": "4.17.11",
|
||||||
"@types/express": "4.17.11",
|
"@types/node": "14.14.22",
|
||||||
"@types/node": "14.14.22",
|
"@types/puppeteer": "5.4.3",
|
||||||
"@types/puppeteer": "5.4.3",
|
"cp-cli": "2.0.0",
|
||||||
"auto-changelog": "^2.4.0",
|
"faker": "5.3.1",
|
||||||
"cp-cli": "2.0.0",
|
"nodemon": "2.0.7",
|
||||||
"faker": "5.3.1",
|
"release-it": "^14.2.2",
|
||||||
"nodemon": "2.0.7",
|
"rimraf": "3.0.2",
|
||||||
"release-it": "14.2.2",
|
"start-server-and-test": "1.12.0",
|
||||||
"rimraf": "3.0.2",
|
"ts-node": "9.1.1",
|
||||||
"start-server-and-test": "1.12.0",
|
"typescript": "4.1.3"
|
||||||
"ts-node": "9.1.1",
|
},
|
||||||
"typescript": "4.1.3"
|
"release-it": {
|
||||||
},
|
"git": {
|
||||||
"release-it": {
|
"commit": true,
|
||||||
"git": {
|
"requireCleanWorkingDir": false,
|
||||||
"commit": true,
|
"commitMessage": "🚀Bumped version to v${version}",
|
||||||
"requireCleanWorkingDir": false,
|
"requireBranch": "dev",
|
||||||
"commitMessage": "🚀Bumped version to v${version}",
|
"push": false,
|
||||||
"requireBranch": "dev",
|
"tag": false
|
||||||
"push": true,
|
},
|
||||||
"tag": true,
|
"npm": {
|
||||||
"tagName": "v${version}",
|
"publish": false
|
||||||
"tagAnnotation": "v${version}"
|
}
|
||||||
},
|
}
|
||||||
"npm": {
|
}
|
||||||
"publish": false
|
|
||||||
},
|
|
||||||
"hooks": {
|
|
||||||
"after:bump": "npm run changelog:export && npm run licenses:export && git add CHANGELOG.md && git add licenses.md"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
4730
pnpm-lock.yaml
generated
4730
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,308 +1,308 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import cheerio from "cheerio";
|
import cheerio from "cheerio";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import Handlebars from 'handlebars';
|
import Handlebars from 'handlebars';
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import Backend from 'i18next-fs-backend';
|
import Backend from 'i18next-fs-backend';
|
||||||
import mime from "mime-types";
|
import mime from "mime-types";
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { PDFDocument } from 'pdf-lib';
|
import { PDFDocument } from 'pdf-lib';
|
||||||
import puppeteer from "puppeteer";
|
import puppeteer from "puppeteer";
|
||||||
import { awaitAsyncHandlebarHelpers, helpers } from './asyncHelpers';
|
import { awaitAsyncHandlebarHelpers, helpers } from './asyncHelpers';
|
||||||
import { config } from './config';
|
import { config } from './config';
|
||||||
import { CertificateRunner } from './models/CertificateRunner';
|
import { CertificateRunner } from './models/CertificateRunner';
|
||||||
import { Runner } from './models/Runner';
|
import { Runner } from './models/Runner';
|
||||||
import { RunnerCard } from './models/RunnerCard';
|
import { RunnerCard } from './models/RunnerCard';
|
||||||
import { RunnerGroup } from './models/RunnerGroup';
|
import { RunnerGroup } from './models/RunnerGroup';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is responsible for all things pdf creation.
|
* This class is responsible for all things pdf creation.
|
||||||
* This uses the html templates from src/templates.
|
* This uses the html templates from src/templates.
|
||||||
*/
|
*/
|
||||||
export class PdfCreator {
|
export class PdfCreator {
|
||||||
private templateDir = path.join(__dirname, '/templates');
|
private templateDir = path.join(__dirname, '/templates');
|
||||||
private browser;
|
private browser;
|
||||||
private static interpolations = { eventname: config.eventname, sponsoring_receipt_minimum_amount: config.sponsoring_receipt_minimum_amount, currency_symbol: config.currency_symbol }
|
private static interpolations = { eventname: config.eventname, sponsoring_receipt_minimum_amount: config.sponsoring_receipt_minimum_amount, currency_symbol: config.currency_symbol }
|
||||||
private static contractsPerRunner = config.contracts_per_runner;
|
private static contractsPerRunner = config.contracts_per_runner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main constructor.
|
* Main constructor.
|
||||||
* Initializes i18n(ext), Handlebars and puppeteer.
|
* Initializes i18n(ext), Handlebars and puppeteer.
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main constructor.
|
* Main constructor.
|
||||||
* Initializes i18n(ext), Handlebars and puppeteer.
|
* Initializes i18n(ext), Handlebars and puppeteer.
|
||||||
*/
|
*/
|
||||||
public async init() {
|
public async init() {
|
||||||
const minimal_args = [
|
const minimal_args = [
|
||||||
'--autoplay-policy=user-gesture-required',
|
'--autoplay-policy=user-gesture-required',
|
||||||
'--disable-background-networking',
|
'--disable-background-networking',
|
||||||
'--disable-background-timer-throttling',
|
'--disable-background-timer-throttling',
|
||||||
'--disable-backgrounding-occluded-windows',
|
'--disable-backgrounding-occluded-windows',
|
||||||
'--disable-breakpad',
|
'--disable-breakpad',
|
||||||
'--disable-client-side-phishing-detection',
|
'--disable-client-side-phishing-detection',
|
||||||
'--disable-component-update',
|
'--disable-component-update',
|
||||||
'--disable-default-apps',
|
'--disable-default-apps',
|
||||||
'--disable-dev-shm-usage',
|
'--disable-dev-shm-usage',
|
||||||
'--disable-domain-reliability',
|
'--disable-domain-reliability',
|
||||||
'--disable-extensions',
|
'--disable-extensions',
|
||||||
'--disable-features=AudioServiceOutOfProcess',
|
'--disable-features=AudioServiceOutOfProcess',
|
||||||
'--disable-hang-monitor',
|
'--disable-hang-monitor',
|
||||||
'--disable-ipc-flooding-protection',
|
'--disable-ipc-flooding-protection',
|
||||||
'--disable-notifications',
|
'--disable-notifications',
|
||||||
'--disable-offer-store-unmasked-wallet-cards',
|
'--disable-offer-store-unmasked-wallet-cards',
|
||||||
'--disable-popup-blocking',
|
'--disable-popup-blocking',
|
||||||
'--disable-print-preview',
|
'--disable-print-preview',
|
||||||
'--disable-prompt-on-repost',
|
'--disable-prompt-on-repost',
|
||||||
'--disable-renderer-backgrounding',
|
'--disable-renderer-backgrounding',
|
||||||
'--disable-speech-api',
|
'--disable-speech-api',
|
||||||
'--disable-sync',
|
'--disable-sync',
|
||||||
'--hide-scrollbars',
|
'--hide-scrollbars',
|
||||||
'--ignore-gpu-blacklist',
|
'--ignore-gpu-blacklist',
|
||||||
'--metrics-recording-only',
|
'--metrics-recording-only',
|
||||||
'--mute-audio',
|
'--mute-audio',
|
||||||
'--no-default-browser-check',
|
'--no-default-browser-check',
|
||||||
'--no-first-run',
|
'--no-first-run',
|
||||||
'--no-pings',
|
'--no-pings',
|
||||||
'--no-zygote',
|
'--no-zygote',
|
||||||
'--password-store=basic',
|
'--password-store=basic',
|
||||||
'--use-gl=swiftshader',
|
'--use-gl=swiftshader',
|
||||||
'--no-sandbox'
|
'--no-sandbox'
|
||||||
];
|
];
|
||||||
await i18next
|
await i18next
|
||||||
.use(Backend)
|
.use(Backend)
|
||||||
.init({
|
.init({
|
||||||
fallbackLng: 'en',
|
fallbackLng: 'en',
|
||||||
lng: 'en',
|
lng: 'en',
|
||||||
backend: {
|
backend: {
|
||||||
loadPath: path.join(__dirname, '/locales/{{lng}}.json')
|
loadPath: path.join(__dirname, '/locales/{{lng}}.json')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await Handlebars.registerHelper(helpers);
|
await Handlebars.registerHelper(helpers);
|
||||||
await Handlebars.registerHelper('__',
|
await Handlebars.registerHelper('__',
|
||||||
function (str) {
|
function (str) {
|
||||||
return i18next.t(str, PdfCreator.interpolations).toString();
|
return i18next.t(str, PdfCreator.interpolations).toString();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await Handlebars.registerHelper('--sponsor',
|
await Handlebars.registerHelper('--sponsor',
|
||||||
function (str) {
|
function (str) {
|
||||||
const index = (parseInt(str) % config.sponor_logos.length);
|
const index = (parseInt(str) % config.sponor_logos.length);
|
||||||
if (isNaN(index)) {
|
if (isNaN(index)) {
|
||||||
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg=="
|
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg=="
|
||||||
}
|
}
|
||||||
return config.sponor_logos[index];
|
return config.sponor_logos[index];
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await Handlebars.registerHelper('--format_kilometers',
|
await Handlebars.registerHelper('--format_kilometers',
|
||||||
function (str) {
|
function (str) {
|
||||||
let meters = parseInt(str);
|
let meters = parseInt(str);
|
||||||
return ((meters / 1000).toLocaleString("en-EN", { minimumFractionDigits: 2, maximumFractionDigits: 3 }).replace(".", ","));
|
return ((meters / 1000).toFixed(3).toString())
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await Handlebars.registerHelper('--format_currency',
|
await Handlebars.registerHelper('--format_currency',
|
||||||
function (str) {
|
function (str) {
|
||||||
let meters = parseInt(str);
|
let meters = parseInt(str);
|
||||||
return ((meters / 100).toLocaleString("en-EN", { minimumFractionDigits: 2, maximumFractionDigits: 2 }).replace(".", ","));
|
return ((meters / 100).toFixed(2).toString())
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.browser = await puppeteer.launch({ headless: true, args: minimal_args });
|
this.browser = await puppeteer.launch({ headless: true, args: minimal_args });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate sponsoring contract pdfs.
|
* Generate sponsoring contract pdfs.
|
||||||
* @param runner The runner you want to generate the contracts for.
|
* @param runner The runner you want to generate the contracts for.
|
||||||
* @param locale The locale used for the contracts (default:en)
|
* @param locale The locale used for the contracts (default:en)
|
||||||
*/
|
*/
|
||||||
public async generateSponsoringContract(runners: Runner[], locale: string = "en", codeformat: string = config.codeformat): Promise<Buffer> {
|
public async generateSponsoringContract(runners: Runner[], locale: string = "en", codeformat: string = config.codeformat): Promise<Buffer> {
|
||||||
if (runners.length == 1 && Object.keys(runners[0]).length == 0) {
|
if (runners.length == 1 && Object.keys(runners[0]).length == 0) {
|
||||||
runners[0] = this.generateEmptyRunner();
|
runners[0] = this.generateEmptyRunner();
|
||||||
}
|
}
|
||||||
if (runners.length > 50) {
|
if (runners.length > 50) {
|
||||||
let pdf_promises = new Array<Promise<Buffer>>();
|
let pdf_promises = new Array<Promise<Buffer>>();
|
||||||
let i, j;
|
let i, j;
|
||||||
for (i = 0, j = runners.length; i < j; i += 50) {
|
for (i = 0, j = runners.length; i < j; i += 50) {
|
||||||
let chunk = runners.slice(i, i + 50);
|
let chunk = runners.slice(i, i + 50);
|
||||||
pdf_promises.push(this.generateSponsoringContract(chunk, locale));
|
pdf_promises.push(this.generateSponsoringContract(chunk, locale));
|
||||||
}
|
}
|
||||||
const pdfs = await Promise.all(pdf_promises);
|
const pdfs = await Promise.all(pdf_promises);
|
||||||
return await this.mergePdfs(pdfs);
|
return await this.mergePdfs(pdfs);
|
||||||
}
|
}
|
||||||
for (var i = 1; i < PdfCreator.contractsPerRunner; i++) {
|
for (var i = 1; i < PdfCreator.contractsPerRunner; i++) {
|
||||||
runners = runners.reduce(function (res, current, index, array) {
|
runners = runners.reduce(function (res, current, index, array) {
|
||||||
return res.concat([current, current]);
|
return res.concat([current, current]);
|
||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
await i18next.changeLanguage(locale);
|
await i18next.changeLanguage(locale);
|
||||||
const template_source = fs.readFileSync(`${this.templateDir}/sponsoring_contract.html`, 'utf8');
|
const template_source = fs.readFileSync(`${this.templateDir}/sponsoring_contract.html`, 'utf8');
|
||||||
const template = Handlebars.compile(template_source);
|
const template = Handlebars.compile(template_source);
|
||||||
let result = template({ runners, codeformat, disclaimer: config.disclaimer_text });
|
let result = template({ runners, codeformat, disclaimer: config.disclaimer_text });
|
||||||
result = await awaitAsyncHandlebarHelpers(result);
|
result = await awaitAsyncHandlebarHelpers(result);
|
||||||
const pdf = await this.renderPdf(result, { format: "A5", landscape: true });
|
const pdf = await this.renderPdf(result, { format: "A5", landscape: true });
|
||||||
return pdf
|
return pdf
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate runner card pdfs.
|
* Generate runner card pdfs.
|
||||||
* @param cards The runner cars you want to generate the cards for.
|
* @param cards The runner cars you want to generate the cards for.
|
||||||
* @param locale The locale used for the cards (default:en)
|
* @param locale The locale used for the cards (default:en)
|
||||||
*/
|
*/
|
||||||
public async generateRunnerCards(cards: RunnerCard[], locale: string = "en", codeformat: string = config.codeformat_cards): Promise<Buffer> {
|
public async generateRunnerCards(cards: RunnerCard[], locale: string = "en", codeformat: string = config.codeformat_cards): Promise<Buffer> {
|
||||||
if (cards.length > 10) {
|
if (cards.length > 10) {
|
||||||
let pdf_promises = new Array<Promise<Buffer>>();
|
let pdf_promises = new Array<Promise<Buffer>>();
|
||||||
let i, j;
|
let i, j;
|
||||||
for (i = 0, j = cards.length; i < j; i += 10) {
|
for (i = 0, j = cards.length; i < j; i += 10) {
|
||||||
let chunk = cards.slice(i, i + 10);
|
let chunk = cards.slice(i, i + 10);
|
||||||
pdf_promises.push(this.generateRunnerCards(chunk, locale, codeformat));
|
pdf_promises.push(this.generateRunnerCards(chunk, locale, codeformat));
|
||||||
}
|
}
|
||||||
const pdfs = await Promise.all(pdf_promises);
|
const pdfs = await Promise.all(pdf_promises);
|
||||||
return await this.mergePdfs(pdfs);
|
return await this.mergePdfs(pdfs);
|
||||||
}
|
}
|
||||||
const cards_swapped = this.swapArrayPairs(cards);
|
const cards_swapped = this.swapArrayPairs(cards);
|
||||||
await i18next.changeLanguage(locale);
|
await i18next.changeLanguage(locale);
|
||||||
const template_source = fs.readFileSync(`${this.templateDir}/runner_card.html`, 'utf8');
|
const template_source = fs.readFileSync(`${this.templateDir}/runner_card.html`, 'utf8');
|
||||||
const template = Handlebars.compile(template_source);
|
const template = Handlebars.compile(template_source);
|
||||||
let result = template({ cards, cards_swapped, eventname: config.eventname, codeformat: codeformat, card_subtitle: config.card_subtitle })
|
let result = template({ cards, cards_swapped, eventname: config.eventname, codeformat: codeformat, card_subtitle: config.card_subtitle })
|
||||||
result = await awaitAsyncHandlebarHelpers(result);
|
result = await awaitAsyncHandlebarHelpers(result);
|
||||||
const pdf = await this.renderPdf(result, { format: "A4", landscape: false });
|
const pdf = await this.renderPdf(result, { format: "A4", landscape: false });
|
||||||
return pdf
|
return pdf
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate sponsoring contract pdfs.
|
* Generate sponsoring contract pdfs.
|
||||||
* @param runner The runner you want to generate the contracts for.
|
* @param runner The runner you want to generate the contracts for.
|
||||||
* @param locale The locale used for the contracts (default:en)
|
* @param locale The locale used for the contracts (default:en)
|
||||||
*/
|
*/
|
||||||
public async generateRunnerCertficates(runners: CertificateRunner[], locale: string = "en"): Promise<Buffer> {
|
public async generateRunnerCertficates(runners: CertificateRunner[], locale: string = "en"): Promise<Buffer> {
|
||||||
if (runners.length > 50) {
|
if (runners.length > 50) {
|
||||||
let pdf_promises = new Array<Buffer>();
|
let pdf_promises = new Array<Buffer>();
|
||||||
let i, j;
|
let i, j;
|
||||||
for (i = 0, j = runners.length; i < j; i += 50) {
|
for (i = 0, j = runners.length; i < j; i += 50) {
|
||||||
let chunk = runners.slice(i, i + 50);
|
let chunk = runners.slice(i, i + 50);
|
||||||
pdf_promises.push(await this.generateRunnerCertficates(chunk, locale));
|
pdf_promises.push(await this.generateRunnerCertficates(chunk, locale));
|
||||||
}
|
}
|
||||||
return await this.mergePdfs(pdf_promises);
|
return await this.mergePdfs(pdf_promises);
|
||||||
}
|
}
|
||||||
await i18next.changeLanguage(locale);
|
await i18next.changeLanguage(locale);
|
||||||
const template_source = fs.readFileSync(`${this.templateDir}/runner_certificate.html`, 'utf8');
|
const template_source = fs.readFileSync(`${this.templateDir}/runner_certificate.html`, 'utf8');
|
||||||
const template = Handlebars.compile(template_source);
|
const template = Handlebars.compile(template_source);
|
||||||
let result = template({ runners, eventname: config.eventname, currency_symbol: config.currency_symbol, donations_footer_text: config.donations_footer_text });
|
let result = template({ runners, eventname: config.eventname, currency_symbol: config.currency_symbol, donations_footer_text: config.donations_footer_text });
|
||||||
result = await awaitAsyncHandlebarHelpers(result);
|
result = await awaitAsyncHandlebarHelpers(result);
|
||||||
const pdf = await this.renderPdf(result, { format: "A4", landscape: false, printBackground: true });
|
const pdf = await this.renderPdf(result, { format: "A4", landscape: false, printBackground: true });
|
||||||
return pdf;
|
return pdf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts all images in html to base64.
|
* Converts all images in html to base64.
|
||||||
* Works with image files in the template directory or images from urls.
|
* Works with image files in the template directory or images from urls.
|
||||||
* @param html The html string whoms images shall get replaced.
|
* @param html The html string whoms images shall get replaced.
|
||||||
*/
|
*/
|
||||||
public async imgToBase64(html): Promise<string> {
|
public async imgToBase64(html): Promise<string> {
|
||||||
const $ = cheerio.load(html)
|
const $ = cheerio.load(html)
|
||||||
|
|
||||||
$('img').each(async (index, element) => {
|
$('img').each(async (index, element) => {
|
||||||
let imgsrc = $(element).attr("src");
|
let imgsrc = $(element).attr("src");
|
||||||
if (imgsrc.startsWith("data:image")) {
|
if (imgsrc.startsWith("data:image")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const img_type = mime.lookup(imgsrc);
|
const img_type = mime.lookup(imgsrc);
|
||||||
|
|
||||||
if (!(img_type.includes("image"))) {
|
if (!(img_type.includes("image"))) {
|
||||||
throw new Error("File is not image mime type");
|
throw new Error("File is not image mime type");
|
||||||
}
|
}
|
||||||
|
|
||||||
let image;
|
let image;
|
||||||
if (imgsrc.startsWith("http")) {
|
if (imgsrc.startsWith("http")) {
|
||||||
image = (await axios.get(imgsrc)).data;
|
image = (await axios.get(imgsrc)).data;
|
||||||
image = Buffer.from(image).toString('base64');
|
image = Buffer.from(image).toString('base64');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (imgsrc.startsWith("./")) {
|
if (imgsrc.startsWith("./")) {
|
||||||
imgsrc = imgsrc.replace("./", "");
|
imgsrc = imgsrc.replace("./", "");
|
||||||
}
|
}
|
||||||
image = fs.readFileSync(`${this.templateDir}/${imgsrc}`, { encoding: "base64" });
|
image = fs.readFileSync(`${this.templateDir}/${imgsrc}`, { encoding: "base64" });
|
||||||
}
|
}
|
||||||
|
|
||||||
image = `data:${img_type};base64,${image}`
|
image = `data:${img_type};base64,${image}`
|
||||||
$(element).attr("src", image)
|
$(element).attr("src", image)
|
||||||
});
|
});
|
||||||
|
|
||||||
return $.html();
|
return $.html();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method manages the creation of pdfs via puppeteer.
|
* This method manages the creation of pdfs via puppeteer.
|
||||||
* @param html The HTML that should get rendered.
|
* @param html The HTML that should get rendered.
|
||||||
* @param options Puppeteer PDF option (eg: {format: "A4"})
|
* @param options Puppeteer PDF option (eg: {format: "A4"})
|
||||||
*/
|
*/
|
||||||
public async renderPdf(html: string, options): Promise<any> {
|
public async renderPdf(html: string, options): Promise<any> {
|
||||||
html = await this.imgToBase64(html);
|
html = await this.imgToBase64(html);
|
||||||
let page = await this.browser.newPage();
|
let page = await this.browser.newPage();
|
||||||
await page.setContent(html);
|
await page.setContent(html);
|
||||||
const pdf = await page.pdf(options);
|
const pdf = await page.pdf(options);
|
||||||
await page.close();
|
await page.close();
|
||||||
return pdf;
|
return pdf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges multiple pdfs into one.
|
* Merges multiple pdfs into one.
|
||||||
* @param pdfs The pdfs you want to merge as an buffer array.
|
* @param pdfs The pdfs you want to merge as an buffer array.
|
||||||
* @returns The merged pdf as a buffer.
|
* @returns The merged pdf as a buffer.
|
||||||
*/
|
*/
|
||||||
private async mergePdfs(pdfs: Buffer[]): Promise<Buffer> {
|
private async mergePdfs(pdfs: Buffer[]): Promise<Buffer> {
|
||||||
const mergedPdf = await PDFDocument.create();
|
const mergedPdf = await PDFDocument.create();
|
||||||
|
|
||||||
for (const pdfBuffer of pdfs) {
|
for (const pdfBuffer of pdfs) {
|
||||||
const pdf = await PDFDocument.load(pdfBuffer);
|
const pdf = await PDFDocument.load(pdfBuffer);
|
||||||
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
|
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
|
||||||
copiedPages.forEach((page) => {
|
copiedPages.forEach((page) => {
|
||||||
mergedPdf.addPage(page);
|
mergedPdf.addPage(page);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Buffer>(await mergedPdf.save());
|
return <Buffer>(await mergedPdf.save());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a new dummy runner with halfspaces for all strings.
|
* Generates a new dummy runner with halfspaces for all strings.
|
||||||
* Can be used to generate empty sponsoring contracts.
|
* Can be used to generate empty sponsoring contracts.
|
||||||
* @returns A new runner object that apears to be empty.
|
* @returns A new runner object that apears to be empty.
|
||||||
*/
|
*/
|
||||||
private generateEmptyRunner(): Runner {
|
private generateEmptyRunner(): Runner {
|
||||||
let group = new RunnerGroup();
|
let group = new RunnerGroup();
|
||||||
group.id = 0;
|
group.id = 0;
|
||||||
group.name = " ";
|
group.name = " ";
|
||||||
let runner = new Runner();
|
let runner = new Runner();
|
||||||
runner.id = 0;
|
runner.id = 0;
|
||||||
runner.firstname = " ";
|
runner.firstname = " ";
|
||||||
runner.lastname = " ";
|
runner.lastname = " ";
|
||||||
runner.group = group;
|
runner.group = group;
|
||||||
return runner;
|
return runner;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Swaps pairs (0/1, 2/3, ...) of elements in an array recursively.
|
* 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
|
* 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.
|
* 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.
|
* @param array The array which's pairs shall get switched.
|
||||||
* @returns Array with swapped pairs,
|
* @returns Array with swapped pairs,
|
||||||
*/
|
*/
|
||||||
private swapArrayPairs(array): Array<any> {
|
private swapArrayPairs(array): Array<any> {
|
||||||
if (array.length == 1) {
|
if (array.length == 1) {
|
||||||
return [null, array[0]];
|
return [null, array[0]];
|
||||||
}
|
}
|
||||||
if (array.length == 0) {
|
if (array.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rest = this.swapArrayPairs(array.slice(2))
|
const rest = this.swapArrayPairs(array.slice(2))
|
||||||
if (!rest) {
|
if (!rest) {
|
||||||
return [array[1], array[0]]
|
return [array[1], array[0]]
|
||||||
}
|
}
|
||||||
return [array[1], array[0]].concat(rest);
|
return [array[1], array[0]].concat(rest);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -97,21 +97,12 @@ export class PdfController {
|
|||||||
else {
|
else {
|
||||||
runner.group.fullName = `${runner.group.parentGroup.name}/${runner.group.name}`;
|
runner.group.fullName = `${runner.group.parentGroup.name}/${runner.group.name}`;
|
||||||
}
|
}
|
||||||
runner.donationPerDistanceTotal = 0;
|
runner.donationPerDistanceTotal = runner.distanceDonations.reduce(function (sum, current) {
|
||||||
if (!Array.isArray(runner.distanceDonations)){
|
return sum + current.amountPerDistance;
|
||||||
runner.distanceDonations = [].concat(runner.distanceDonations)
|
}, 0);
|
||||||
}
|
runner.donationTotal = runner.distanceDonations.reduce(function (sum, current) {
|
||||||
if (runner.distanceDonations.length > 0) {
|
return sum + current.amount;
|
||||||
runner.donationPerDistanceTotal += runner.distanceDonations.reduce(function (sum, current) {
|
}, 0);
|
||||||
return sum + current.amountPerDistance;
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
runner.donationTotal = 0;
|
|
||||||
if (runner.distanceDonations.length > 0) {
|
|
||||||
runner.donationTotal += runner.distanceDonations.reduce(function (sum, current) {
|
|
||||||
return sum + current.amount;
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
response.push(runner)
|
response.push(runner)
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
{
|
{
|
||||||
"address": "Adresse",
|
"address": "Adresse",
|
||||||
"betrag-km": "Betrag/ km",
|
"betrag-km": "Betrag/ km",
|
||||||
"city": "Stadt",
|
"city": "Stadt",
|
||||||
"date": "Datum",
|
"date": "Datum",
|
||||||
"firstname": "Vorname",
|
"firstname": "Vorname",
|
||||||
"fuer-den-guten-zweck-zurueckgelegt": "für den guten Zweck zurückgelegt.",
|
"fuer-den-guten-zweck-zurueckgelegt": "für den guten Zweck zurückgelegt",
|
||||||
"gesamt": "Gesamt",
|
"gesamt": "Gesamt",
|
||||||
"gesamtbetrag": "Gesamtbetrag",
|
"gesamtbetrag": "Gesamtbetrag",
|
||||||
"group": "Team/ Klasse",
|
"group": "Team/ Klasse",
|
||||||
"hat-beim-eventname": "hat beim {{eventname}}",
|
"hat-beim-eventname": "Hat beim {{eventname}}",
|
||||||
"house_number": "Hausnummer",
|
"house_number": "Hausnummer",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
"lastname": "Nachname",
|
"lastname": "Nachname",
|
||||||
"location": "Ort",
|
"location": "Ort",
|
||||||
"mit_unterstuetzung_von": "Mit Unterstützung von:",
|
"mit_unterstuetzung_von": "Mit Unterstützung von:",
|
||||||
"please_use_blockletters": "Bitte in DRUCKBUCHSTABEN schreiben",
|
"please_use_blockletters": "Bitte in DRUCKBUCHSTABEN schreiben",
|
||||||
"postalcode": "Postleitzahl",
|
"postalcode": "Postleitzahl",
|
||||||
"signature": "Unterschrift",
|
"signature": "Unterschrift",
|
||||||
"sponsor": "Sponsor",
|
"sponsor": "Sponsor",
|
||||||
"sponsor-in": "Sponsor:in",
|
"sponsor-in": "Sponsor:in",
|
||||||
"sponsoring_address_condition": "Muss ausgefüllt werden, wenn Sie eine Spendenquittung benötigen - Spendenquittungen können erst ab einem Gesamtbetrag von {{sponsoring_receipt_minimum_amount}}{{currency_symbol}} ausgestellt werden",
|
"sponsoring_address_condition": "Muss ausgefüllt werden, wenn Sie eine Spendenquittung benötigen - Spendenquittungen können erst ab einem Gesamtbetrag von {{sponsoring_receipt_minimum_amount}}{{currency_symbol}} ausgestellt werden",
|
||||||
"sponsoring_amount_per_distance": "mit einem Betrag von _____{{currency_symbol}} pro gelaufenem Kilometer zu unterstützen.",
|
"sponsoring_amount_per_distance": "mit einem Betrag von _____{{currency_symbol}} pro gelaufenem Kilometer zu unterstützen.",
|
||||||
"sponsoring_subtitle": "Ich bin/ Wir sind bereit anlässlich des {{eventname}}",
|
"sponsoring_subtitle": "Ich bin/ Wir sind bereit anlässlich des {{eventname}}",
|
||||||
"sponsoring_title": "Sponsoringerklärung",
|
"sponsoring_title": "Sponsoringerklärung",
|
||||||
"sponsorings": "Sponsorings",
|
"sponsorings": "Sponsorings",
|
||||||
"street": "Straße",
|
"street": "Straße",
|
||||||
"urkunde": "Urkunde"
|
"urkunde": "Urkunde"
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user