Compare commits
No commits in common. "bc2b6fadd912f275bc05be29c6fbd87367d617df" and "4585a83838b80552160c9d9e5be0af891eae39c8" have entirely different histories.
bc2b6fadd9
...
4585a83838
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,7 +4,6 @@
|
|||||||
!.vscode/tasks.json
|
!.vscode/tasks.json
|
||||||
!.vscode/launch.json
|
!.vscode/launch.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
!.vscode/i18n-ally-custom-framework.yml
|
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
# Local History for Visual Studio Code
|
||||||
|
7
.vscode/extensions.json
vendored
7
.vscode/extensions.json
vendored
@ -2,10 +2,7 @@
|
|||||||
"recommendations": [
|
"recommendations": [
|
||||||
"2gua.rainbow-brackets",
|
"2gua.rainbow-brackets",
|
||||||
"christian-kohler.npm-intellisense",
|
"christian-kohler.npm-intellisense",
|
||||||
"remimarsal.prettier-now",
|
"remimarsal.prettier-now"
|
||||||
"lokalise.i18n-ally",
|
|
||||||
],
|
],
|
||||||
"unwantedRecommendations": [
|
"unwantedRecommendations": []
|
||||||
"antfu.i18n-ally"
|
|
||||||
]
|
|
||||||
}
|
}
|
8
.vscode/i18n-ally-custom-framework.yml
vendored
8
.vscode/i18n-ally-custom-framework.yml
vendored
@ -1,8 +0,0 @@
|
|||||||
languageIds:
|
|
||||||
- javascript
|
|
||||||
- html
|
|
||||||
keyMatchReg:
|
|
||||||
- '\{\{__ "([a-zA-Z0-9_]+)"\}\}'
|
|
||||||
monopoly: false
|
|
||||||
refactorTemplates:
|
|
||||||
- '{{__ "$1"}}'
|
|
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
@ -5,6 +5,7 @@
|
|||||||
"[json]": {
|
"[json]": {
|
||||||
"editor.defaultFormatter": "vscode.json-language-features"
|
"editor.defaultFormatter": "vscode.json-language-features"
|
||||||
},
|
},
|
||||||
|
"prettier.enable": false,
|
||||||
"[typescript]": {
|
"[typescript]": {
|
||||||
"editor.defaultFormatter": "vscode.typescript-language-features",
|
"editor.defaultFormatter": "vscode.typescript-language-features",
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
@ -15,13 +16,5 @@
|
|||||||
"javascript.preferences.quoteStyle": "single",
|
"javascript.preferences.quoteStyle": "single",
|
||||||
"javascript.preferences.importModuleSpecifierEnding": "minimal",
|
"javascript.preferences.importModuleSpecifierEnding": "minimal",
|
||||||
"typescript.preferences.importModuleSpecifierEnding": "minimal",
|
"typescript.preferences.importModuleSpecifierEnding": "minimal",
|
||||||
"typescript.preferences.includePackageJsonAutoImports": "on",
|
"typescript.preferences.includePackageJsonAutoImports": "on"
|
||||||
"i18n-ally.localesPaths": "src/locales",
|
|
||||||
"i18n-ally.keystyle": "nested",
|
|
||||||
"i18n-ally.extract.keygenStrategy":"slug",
|
|
||||||
"i18n-ally.enabledFrameworks": [
|
|
||||||
"custom"
|
|
||||||
],
|
|
||||||
"i18n-ally.sourceLanguage": "en"
|
|
||||||
|
|
||||||
}
|
}
|
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
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.
|
||||||
|
|
||||||
#### 0.1.0
|
#### 0.0.2
|
||||||
|
11
README.md
11
README.md
@ -37,7 +37,7 @@ The basic generation mechanism makes the templates and routes interchangeable (i
|
|||||||
> The templates are stored in src/templates by default.
|
> The templates are stored in src/templates by default.
|
||||||
|
|
||||||
We provide a set of default templates that we use for the ["Lauf für Kaya!" charity run](https://lauf-fuer-kaya.de).
|
We provide a set of default templates that we use for the ["Lauf für Kaya!" charity run](https://lauf-fuer-kaya.de).
|
||||||
We use handlebars for templateing utilizing i18next for translation - the i18n string format in the templates is : `{{__ "string"}}`
|
We use mustache-style templating strings to fill the templates with real information (exact strings are explained below).
|
||||||
You can provide your own templates by replacing the ones we provided before compiling the project or by simply mounting your custom templates into the docker container.
|
You can provide your own templates by replacing the ones we provided before compiling the project or by simply mounting your custom templates into the docker container.
|
||||||
|
|
||||||
The server currently needs the following templates to work:
|
The server currently needs the following templates to work:
|
||||||
@ -45,10 +45,12 @@ The server currently needs the following templates to work:
|
|||||||
|
|
||||||
### Sponsoring Contracts
|
### Sponsoring Contracts
|
||||||
|
|
||||||
| Template Data | Type | Optional | Description
|
| Template String | Type | Optional | Description
|
||||||
| - | - | - | -
|
| - | - | - | -
|
||||||
| runners | array(Runner) | ❌ | The runner objects. We generate a contract for each runner on a new DIN-A5 page.
|
| runner_firstname | string | ❌ | The runner's first name
|
||||||
|
| runner_middlename | string | ✅ | The runner's middle name
|
||||||
|
| runner_lastname | string | ❌ | The runner's last name
|
||||||
|
| runner_id | int | ❌ | The runner's id
|
||||||
|
|
||||||
## Recommended Editor
|
## Recommended Editor
|
||||||
|
|
||||||
@ -57,7 +59,6 @@ The server currently needs the following templates to work:
|
|||||||
### Recommended Extensions
|
### Recommended Extensions
|
||||||
|
|
||||||
* will be automatically recommended via ./vscode/extensions.json
|
* will be automatically recommended via ./vscode/extensions.json
|
||||||
* we also provide a config for i18n-ally in the .vscode folder
|
|
||||||
|
|
||||||
## Staging
|
## Staging
|
||||||
### Branches & Tags
|
### Branches & Tags
|
||||||
|
401
licenses.md
401
licenses.md
@ -27,61 +27,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
# axios
|
|
||||||
**Author**: Matt Zabriskie
|
|
||||||
**Repo**: [object Object]
|
|
||||||
**License**: MIT
|
|
||||||
**Description**: Promise based HTTP client for the browser and node.js
|
|
||||||
## License Text
|
|
||||||
Copyright (c) 2014-present Matt Zabriskie
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
# cheerio
|
|
||||||
**Author**: Matt Mueller <mattmuelle@gmail.com> (mat.io)
|
|
||||||
**Repo**: [object Object]
|
|
||||||
**License**: MIT
|
|
||||||
**Description**: Tiny, fast, and elegant implementation of core jQuery designed specifically for the server
|
|
||||||
## License Text
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2016 Matt Mueller
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
# class-transformer
|
# class-transformer
|
||||||
**Author**: [object Object]
|
**Author**: [object Object]
|
||||||
**Repo**: [object Object]
|
**Repo**: [object Object]
|
||||||
@ -240,13 +185,15 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
# handlebars
|
# html-pdf
|
||||||
**Author**: Yehuda Katz
|
**Author**: Marc Bachmann
|
||||||
**Repo**: [object Object]
|
**Repo**: [object Object]
|
||||||
**License**: MIT
|
**License**: MIT
|
||||||
**Description**: Handlebars provides the power necessary to let you build semantic templates effectively with no frustration
|
**Description**: HTML to PDF converter that uses phantomjs
|
||||||
## License Text
|
## License Text
|
||||||
Copyright (C) 2011-2019 by Yehuda Katz
|
The MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016 Contributors https://github.com/marcbachmann/node-html-pdf/graphs/contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -267,313 +214,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
# i18next
|
|
||||||
**Author**: Jan Mühlemann <jan.muehlemann@gmail.com> (https://github.com/jamuhl)
|
|
||||||
**Repo**: [object Object]
|
|
||||||
**License**: MIT
|
|
||||||
**Description**: i18next internationalization framework
|
|
||||||
## License Text
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2017 i18next
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
# i18next-fs-backend
|
|
||||||
**Author**: undefined
|
|
||||||
**Repo**: [object Object]
|
|
||||||
**License**: undefined
|
|
||||||
**Description**: i18next-fs-backend is a backend layer for i18next using in Node.js and for Deno to load translations from the filesystem.
|
|
||||||
## License Text
|
|
||||||
|
|
||||||
|
|
||||||
# mime-types
|
|
||||||
**Author**: undefined
|
|
||||||
**Repo**: jshttp/mime-types
|
|
||||||
**License**: MIT
|
|
||||||
**Description**: The ultimate javascript content-type utility.
|
|
||||||
## License Text
|
|
||||||
(The MIT License)
|
|
||||||
|
|
||||||
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
|
|
||||||
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.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.
|
|
||||||
|
|
||||||
|
|
||||||
# pdf-lib
|
|
||||||
**Author**: Andrew Dillon <andrew.dillon.j@gmail.com>
|
|
||||||
**Repo**: git+https://github.com/Hopding/pdf-lib.git
|
|
||||||
**License**: MIT
|
|
||||||
**Description**: Create and modify PDF files with JavaScript
|
|
||||||
## License Text
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2019 Andrew Dillon
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
# puppeteer
|
|
||||||
**Author**: The Chromium Authors
|
|
||||||
**Repo**: github:puppeteer/puppeteer
|
|
||||||
**License**: Apache-2.0
|
|
||||||
**Description**: A high-level API to control headless Chrome over the DevTools Protocol
|
|
||||||
## License Text
|
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
https://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright 2017 Google Inc.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
|
|
||||||
# reflect-metadata
|
# reflect-metadata
|
||||||
**Author**: [object Object]
|
**Author**: [object Object]
|
||||||
**Repo**: [object Object]
|
**Repo**: [object Object]
|
||||||
@ -758,35 +398,6 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
SOFTWARE
|
SOFTWARE
|
||||||
|
|
||||||
|
|
||||||
# @types/puppeteer
|
|
||||||
**Author**: undefined
|
|
||||||
**Repo**: [object Object]
|
|
||||||
**License**: MIT
|
|
||||||
**Description**: TypeScript definitions for puppeteer
|
|
||||||
## License Text
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) Microsoft Corporation.
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
# nodemon
|
# nodemon
|
||||||
**Author**: [object Object]
|
**Author**: [object Object]
|
||||||
**Repo**: [object Object]
|
**Repo**: [object Object]
|
||||||
|
15
package.json
15
package.json
@ -1,14 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@odit/lfk-document-server",
|
"name": "@odit/lfk-document-server",
|
||||||
"version": "0.1.0",
|
"version": "0.0.2",
|
||||||
"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",
|
"build": "rimraf ./dist && tsc",
|
||||||
"licenses:export": "license-exporter --markdown",
|
"licenses:export": "license-exporter --markdown",
|
||||||
"release": "release-it --only-version",
|
"release": "release-it --only-version"
|
||||||
"translations:sort": "node sort_translations.js"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -40,20 +39,13 @@
|
|||||||
"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",
|
||||||
"axios": "^0.21.1",
|
|
||||||
"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.0",
|
"consola": "^2.15.0",
|
||||||
"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.6",
|
"html-pdf": "^2.2.0",
|
||||||
"i18next": "^19.8.7",
|
|
||||||
"i18next-fs-backend": "^1.0.8",
|
|
||||||
"mime-types": "^2.1.28",
|
|
||||||
"pdf-lib": "^1.16.0",
|
|
||||||
"puppeteer": "^7.0.1",
|
|
||||||
"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"
|
||||||
@ -62,7 +54,6 @@
|
|||||||
"@odit/license-exporter": "^0.0.9",
|
"@odit/license-exporter": "^0.0.9",
|
||||||
"@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",
|
|
||||||
"nodemon": "^2.0.7",
|
"nodemon": "^2.0.7",
|
||||||
"release-it": "^14.2.2",
|
"release-it": "^14.2.2",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
const fs = require('fs');
|
|
||||||
// get all language files
|
|
||||||
const files = fs.readdirSync('./src/locales/');
|
|
||||||
files.forEach((f) => {
|
|
||||||
// read file as object
|
|
||||||
const unordered = JSON.parse(fs.readFileSync(`src/locales/${f}`));
|
|
||||||
// order object by keys alpabetically A-Z
|
|
||||||
const ordered = Object.keys(unordered).sort().reduce((obj, key) => {
|
|
||||||
obj[key] = unordered[key];
|
|
||||||
return obj;
|
|
||||||
}, {});
|
|
||||||
// format output as json for commit diff compatibility
|
|
||||||
const out = JSON.stringify(ordered, 0, 4);
|
|
||||||
// write output file
|
|
||||||
fs.writeFileSync(`src/locales/${f}`, out);
|
|
||||||
});
|
|
@ -1,197 +1,56 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import cheerio from "cheerio";
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import Handlebars from 'handlebars';
|
import pdf_converter from "html-pdf";
|
||||||
import i18next from "i18next";
|
|
||||||
import Backend from 'i18next-fs-backend';
|
|
||||||
import mime from "mime-types";
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { PDFDocument } from 'pdf-lib';
|
import { Stream } from 'stream';
|
||||||
import puppeteer from "puppeteer";
|
|
||||||
import { Runner } from './models/Runner';
|
|
||||||
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 static interpolations = { eventname: "Lauf für Kaya! 2021", sponsoring_receipt_minimum_amount: '10', currency_symbol: "€" }
|
|
||||||
|
|
||||||
/**
|
//TODO: Accept the runner class
|
||||||
* Main constructor.
|
public async generateSponsoringContract(): Promise<Pdf> {
|
||||||
* Initializes i18n(ext), Handlebars and puppeteer.
|
let template = fs.readFileSync(`${this.templateDir}/sponsoring_contract.html`, 'utf8');
|
||||||
*/
|
template = template.replace("{{Runner Name}}", "lelele");
|
||||||
constructor() {
|
return new Pdf(await pdf_converter.create(template, { format: "A5", orientation: "landscape" }));
|
||||||
this.init();
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a wrapper for the pdf objects created by html-pdf.
|
||||||
|
* It offers typed conversion to Buffer and Stream.
|
||||||
|
*/
|
||||||
|
export class Pdf {
|
||||||
|
content: any;
|
||||||
|
|
||||||
|
constructor(pdf: any) {
|
||||||
|
this.content = pdf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main constructor.
|
* Promise wrapper function that resolves the toBuffer promise for pdf generation.
|
||||||
* Initializes i18n(ext), Handlebars and puppeteer.
|
|
||||||
*/
|
*/
|
||||||
public async init() {
|
public async toBuffer(): Promise<Buffer> {
|
||||||
const minimal_args = [
|
let promise = await new Promise<Buffer>((resolve, reject) => {
|
||||||
'--autoplay-policy=user-gesture-required',
|
this.content.toBuffer(function (err, buffer: Buffer) {
|
||||||
'--disable-background-networking',
|
resolve(buffer);
|
||||||
'--disable-background-timer-throttling',
|
|
||||||
'--disable-backgrounding-occluded-windows',
|
|
||||||
'--disable-breakpad',
|
|
||||||
'--disable-client-side-phishing-detection',
|
|
||||||
'--disable-component-update',
|
|
||||||
'--disable-default-apps',
|
|
||||||
'--disable-dev-shm-usage',
|
|
||||||
'--disable-domain-reliability',
|
|
||||||
'--disable-extensions',
|
|
||||||
'--disable-features=AudioServiceOutOfProcess',
|
|
||||||
'--disable-hang-monitor',
|
|
||||||
'--disable-ipc-flooding-protection',
|
|
||||||
'--disable-notifications',
|
|
||||||
'--disable-offer-store-unmasked-wallet-cards',
|
|
||||||
'--disable-popup-blocking',
|
|
||||||
'--disable-print-preview',
|
|
||||||
'--disable-prompt-on-repost',
|
|
||||||
'--disable-renderer-backgrounding',
|
|
||||||
'--disable-speech-api',
|
|
||||||
'--disable-sync',
|
|
||||||
'--hide-scrollbars',
|
|
||||||
'--ignore-gpu-blacklist',
|
|
||||||
'--metrics-recording-only',
|
|
||||||
'--mute-audio',
|
|
||||||
'--no-default-browser-check',
|
|
||||||
'--no-first-run',
|
|
||||||
'--no-pings',
|
|
||||||
'--no-zygote',
|
|
||||||
'--password-store=basic',
|
|
||||||
'--use-gl=swiftshader'
|
|
||||||
];
|
|
||||||
|
|
||||||
await i18next
|
|
||||||
.use(Backend)
|
|
||||||
.init({
|
|
||||||
fallbackLng: 'en',
|
|
||||||
lng: 'en',
|
|
||||||
backend: {
|
|
||||||
loadPath: path.join(__dirname, '/locales/{{lng}}.json')
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
await Handlebars.registerHelper('__',
|
});
|
||||||
function (str) {
|
return await promise;
|
||||||
return i18next.t(str, PdfCreator.interpolations).toString();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.browser = await puppeteer.launch({ headless: true, args: minimal_args });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate sponsoring contract pdfs.
|
* Promise wrapper function that resolves the toStream promise for pdf generation.
|
||||||
* @param runner The runner you want to generate the contracts for.
|
|
||||||
* @param locale The locale used for the contracts (default:en)
|
|
||||||
*/
|
*/
|
||||||
public async generateSponsoringContract(runners: Runner[], locale: string = "en"): Promise<Buffer> {
|
public async toStream(): Promise<Stream> {
|
||||||
if (runners.length == 1 && Object.keys(runners[0]).length == 0) {
|
let promise = await new Promise<Stream>((resolve, reject) => {
|
||||||
runners[0] = this.generateEmptyRunner();
|
this.content.toStream(function (err, stream: Stream) {
|
||||||
}
|
resolve(stream);
|
||||||
if (runners.length > 50) {
|
|
||||||
let pdf_promises = new Array<Promise<Buffer>>();
|
|
||||||
let i, j;
|
|
||||||
for (i = 0, j = runners.length; i < j; i += 50) {
|
|
||||||
let chunk = runners.slice(i, i + 50);
|
|
||||||
pdf_promises.push(this.generateSponsoringContract(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}/sponsoring_contract.html`, 'utf8');
|
|
||||||
const template = Handlebars.compile(template_source);
|
|
||||||
const result = template({ runners })
|
|
||||||
const pdf = await this.renderPdf(result, { format: "A5", landscape: true });
|
|
||||||
return pdf
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts all images in html to base64.
|
|
||||||
* Works with image files in the template directory or images from urls.
|
|
||||||
* @param html The html string whoms images shall get replaced.
|
|
||||||
*/
|
|
||||||
public async imgToBase64(html): Promise<string> {
|
|
||||||
const $ = cheerio.load(html)
|
|
||||||
$('img').each(async (index, element) => {
|
|
||||||
let imgsrc = $(element).attr("src");
|
|
||||||
const img_type = mime.lookup(imgsrc);
|
|
||||||
|
|
||||||
if (!(img_type.includes("image"))) {
|
|
||||||
throw new Error("File is not image mime type");
|
|
||||||
}
|
|
||||||
|
|
||||||
let image;
|
|
||||||
if (imgsrc.startsWith("http")) {
|
|
||||||
image = (await axios.get(imgsrc)).data;
|
|
||||||
image = Buffer.from(image).toString('base64');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (imgsrc.startsWith("./")) {
|
|
||||||
imgsrc = imgsrc.replace("./", "");
|
|
||||||
}
|
|
||||||
image = fs.readFileSync(`${this.templateDir}/${imgsrc}`, { encoding: "base64" });
|
|
||||||
}
|
|
||||||
|
|
||||||
image = `data:${img_type};base64,${image}`
|
|
||||||
$(element).attr("src", image)
|
|
||||||
})
|
|
||||||
|
|
||||||
return $.html();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method manages the creation of pdfs via puppeteer.
|
|
||||||
* @param html The HTML that should get rendered.
|
|
||||||
* @param options Puppeteer PDF option (eg: {format: "A4"})
|
|
||||||
*/
|
|
||||||
public async renderPdf(html: string, options): Promise<any> {
|
|
||||||
html = await this.imgToBase64(html);
|
|
||||||
let page = await this.browser.newPage();
|
|
||||||
await page.setContent(html);
|
|
||||||
const pdf = await page.pdf(options);
|
|
||||||
await page.close();
|
|
||||||
return pdf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merges multiple pdfs into one.
|
|
||||||
* @param pdfs The pdfs you want to merge as an buffer array.
|
|
||||||
* @returns The merged pdf as a buffer.
|
|
||||||
*/
|
|
||||||
private async mergePdfs(pdfs: Buffer[]): Promise<Buffer> {
|
|
||||||
const mergedPdf = await PDFDocument.create();
|
|
||||||
|
|
||||||
for (const pdfBuffer of pdfs) {
|
|
||||||
const pdf = await PDFDocument.load(pdfBuffer);
|
|
||||||
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
|
|
||||||
copiedPages.forEach((page) => {
|
|
||||||
mergedPdf.addPage(page);
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
return await promise;
|
||||||
return <Buffer>(await mergedPdf.save());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a new dummy runner with halfspaces for all strings.
|
|
||||||
* Can be used to generate empty sponsoring contracts.
|
|
||||||
* @returns A new runner object that apears to be empty.
|
|
||||||
*/
|
|
||||||
private generateEmptyRunner(): Runner {
|
|
||||||
let group = new RunnerGroup();
|
|
||||||
group.id = 0;
|
|
||||||
group.name = " ";
|
|
||||||
let runner = new Runner();
|
|
||||||
runner.id = 0;
|
|
||||||
runner.firstname = " ";
|
|
||||||
runner.lastname = " ";
|
|
||||||
runner.group = group;
|
|
||||||
return runner;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,30 +1,20 @@
|
|||||||
import { Body, JsonController, Post, QueryParam, Res } from 'routing-controllers';
|
import { ContentType, Controller, Get } from 'routing-controllers';
|
||||||
import { OpenAPI } from 'routing-controllers-openapi';
|
import { OpenAPI } from 'routing-controllers-openapi';
|
||||||
import { Runner } from '../models/Runner';
|
|
||||||
import { PdfCreator } from '../PdfCreator';
|
import { PdfCreator } from '../PdfCreator';
|
||||||
|
|
||||||
/**
|
@Controller()
|
||||||
* The pdf controller handels all endpoints concerning pdf generation.
|
|
||||||
* It therefore is the hearth of the document-generation server's endpoints.
|
|
||||||
* All endpoints have to accept a locale query-param to support i18n.
|
|
||||||
*/
|
|
||||||
@JsonController()
|
|
||||||
export class PdfController {
|
export class PdfController {
|
||||||
private pdf: PdfCreator = new PdfCreator();
|
private pdf: PdfCreator;
|
||||||
private initialized: boolean = false;
|
constructor() {
|
||||||
|
this.pdf = new PdfCreator();
|
||||||
@Post('/contracts')
|
|
||||||
@OpenAPI({ description: "Generate Sponsoring contract pdfs from runner objects.<br>You can choose your prefered locale by passing the 'locale' query-param.<br> If you provide more than 100 runenrs this could take a moment or two (we tested up to 1000 runners in about 70sec so far)." })
|
|
||||||
async generateContracts(@Body({ validate: true, options: { limit: "500mb" } }) runners: Runner | Runner[], @Res() res: any, @QueryParam("locale") locale: string) {
|
|
||||||
if (!this.initialized) {
|
|
||||||
await this.pdf.init();
|
|
||||||
this.initialized = true;
|
|
||||||
}
|
|
||||||
if (!Array.isArray(runners)) {
|
|
||||||
runners = [runners];
|
|
||||||
}
|
|
||||||
const contracts = await this.pdf.generateSponsoringContract(runners, locale);
|
|
||||||
res.setHeader('content-type', 'application/pdf');
|
|
||||||
return contracts;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Get('/contracts')
|
||||||
|
@ContentType("application/pdf")
|
||||||
|
@OpenAPI({ description: "Generate Sponsoring contract pdfs from runner objects." })
|
||||||
|
async generateContracts() {
|
||||||
|
//TODO: Accept the real classes
|
||||||
|
const contracts = await this.pdf.generateSponsoringContract();
|
||||||
|
return await contracts.toBuffer();
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,6 @@ import { Get, JsonController } from 'routing-controllers';
|
|||||||
import { OpenAPI } from 'routing-controllers-openapi';
|
import { OpenAPI } from 'routing-controllers-openapi';
|
||||||
import { config } from '../config';
|
import { config } from '../config';
|
||||||
|
|
||||||
/**
|
|
||||||
* The statuscontroller provides simple endpoints concerning basic information about the server.
|
|
||||||
*/
|
|
||||||
@JsonController()
|
@JsonController()
|
||||||
export class StatusController {
|
export class StatusController {
|
||||||
@Get('/version')
|
@Get('/version')
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"address": "Adresse",
|
|
||||||
"city": "Stadt",
|
|
||||||
"date": "Datum",
|
|
||||||
"firstname": "Vorname",
|
|
||||||
"group": "Team/Klasse",
|
|
||||||
"house_number": "Hausnummer",
|
|
||||||
"id": "ID",
|
|
||||||
"lastname": "Nachname",
|
|
||||||
"location": "Ort",
|
|
||||||
"please_use_blockletters": "Bitte in DRUCKBUCHSTABEN schreiben",
|
|
||||||
"postalcode": "Postleitzahl",
|
|
||||||
"signature": "Unterschrift",
|
|
||||||
"sponsor": "Sponsor",
|
|
||||||
"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_subtitle": "Ich/Wir sind bereit anlässlich des {{eventname}}",
|
|
||||||
"sponsoring_title": "Sponsoringerklärung",
|
|
||||||
"street": "Straße"
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"address": "Address",
|
|
||||||
"city": "City",
|
|
||||||
"date": "date",
|
|
||||||
"firstname": "First name",
|
|
||||||
"group": "Team/class",
|
|
||||||
"house_number": "House number",
|
|
||||||
"lastname": "Last name",
|
|
||||||
"location": "Location",
|
|
||||||
"please_use_blockletters": "Please write in BLOCK LETTERS.",
|
|
||||||
"postalcode": "Postal code",
|
|
||||||
"signature": "Signature",
|
|
||||||
"sponsor": "sponsor",
|
|
||||||
"sponsoring_address_condition": "You have to provide an address if you want a donation receipt - Donation receipts can't be issued for total donation amounts under {{sponsoring_receipt_minimum_amount}}{{currency_symbol}}",
|
|
||||||
"sponsoring_amount_per_distance": "with the amount of _____{{currency_symbol}} per kilometer run.",
|
|
||||||
"sponsoring_subtitle": "On the ocation of the {{eventname}} I/We want to support",
|
|
||||||
"sponsoring_title": "Sponsoring contract",
|
|
||||||
"street": "Street"
|
|
||||||
}
|
|
@ -1,18 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
IsInt,
|
IsInt,
|
||||||
|
|
||||||
IsNotEmpty,
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
IsObject,
|
IsObject,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
IsOptional,
|
|
||||||
|
|
||||||
IsPositive,
|
|
||||||
|
|
||||||
IsString
|
IsString
|
||||||
} from "class-validator";
|
} from "class-validator";
|
||||||
import { RunnerGroup } from './RunnerGroup';
|
import { RunnerGroup } from './RunnerGroup';
|
||||||
@ -25,28 +13,24 @@ export class Runner {
|
|||||||
* The runner's id.
|
* The runner's id.
|
||||||
*/
|
*/
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@IsPositive()
|
|
||||||
id: number;
|
id: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The runner's first name.
|
* The runner's first name.
|
||||||
*/
|
*/
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
|
||||||
firstname: string;
|
firstname: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The runner's middle name.
|
* The runner's middle name.
|
||||||
*/
|
*/
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
|
||||||
middlename?: string;
|
middlename?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The runner's last name.
|
* The runner's last name.
|
||||||
*/
|
*/
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
|
||||||
lastname: string;
|
lastname: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { IsInt, IsNotEmpty, IsObject, IsOptional, IsPositive, IsString } from "class-validator";
|
import { IsInt, IsNotEmpty, IsObject, IsOptional, IsString } from "class-validator";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the runner group class - a simplified version of the backend's ResponseRunnerTeam/-Organization
|
* Defines the runner group class - a simplified version of the backend's ResponseRunnerTeam/-Organization
|
||||||
*/
|
*/
|
||||||
export class RunnerGroup {
|
export abstract class RunnerGroup {
|
||||||
/**
|
/**
|
||||||
* The group's id.
|
* The group's id.
|
||||||
*/
|
*/
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@IsPositive()
|
@IsNotEmpty()
|
||||||
id: number;
|
id: number;;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The group's name.
|
* The group's name.
|
||||||
@ -24,5 +24,13 @@ export class RunnerGroup {
|
|||||||
*/
|
*/
|
||||||
@IsObject()
|
@IsObject()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
parentGroup?: RunnerGroup;
|
parentGroup?: RunnerGroup
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the groups full name in the format: org.name/team.name (or just org).
|
||||||
|
*/
|
||||||
|
public get fullName(): string {
|
||||||
|
if (!this.parentGroup) { return this.name; }
|
||||||
|
return `${this.name}/${this.parentGroup.fullName}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,115 +1,45 @@
|
|||||||
<html>
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf8">
|
||||||
|
<title>Sponsoring contract</title>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: 'Sackers Gothic Std';
|
||||||
|
font-weight: 500;
|
||||||
|
background: rgb(241,241,241);
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
<head>
|
.page {
|
||||||
<meta charset="utf8">
|
position: relative;
|
||||||
<title>Sponsoring contract</title>
|
height: 148mm;
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
|
width: 210mm;
|
||||||
<style>
|
display: block;
|
||||||
.sheet {
|
background: white;
|
||||||
margin: 0;
|
page-break-after: auto;
|
||||||
overflow: hidden;
|
margin: 50px;
|
||||||
position: relative;
|
overflow: hidden;
|
||||||
box-sizing: border-box;
|
}
|
||||||
page-break-after: always;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.A5.landscape .sheet {
|
@media print {
|
||||||
width: 210mm;
|
body {
|
||||||
height: 147mm
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.column {
|
.page {
|
||||||
margin-bottom: -20;
|
margin: 0;
|
||||||
}
|
height: 100%;
|
||||||
</style>
|
width: 100%;
|
||||||
</head>
|
}
|
||||||
|
}
|
||||||
<body class="A5 landscape">
|
</style>
|
||||||
{{#each runners}}
|
</head>
|
||||||
<div class="sheet">
|
<body>
|
||||||
<img id="header_img" width="100%" src="sponsoringheader.png" />
|
<div class="page">
|
||||||
<div style=" padding: 0 1rem 0 1rem;">
|
<p style="font-size: 100vw;">{{Runner Name}}</p>
|
||||||
<div class="columns" style="padding-bottom: 0;">
|
|
||||||
<div class="column is-two-fifths">
|
|
||||||
<p style="font-size: large; font-weight: bold;">{{__ "sponsoring_title"}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<p style="font-size: x-small; vertical-align: revert; margin-top: auto;">{{__ "please_use_blockletters"}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p> {{__ "sponsoring_subtitle"}} </p>
|
|
||||||
<div class="columns" style="padding-top: 0;">
|
|
||||||
<div class="column is-8">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;">{{this.firstname}}
|
|
||||||
{{this.middlename}}</span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "firstname"}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="column is-2">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;">{{this.id}}</span>
|
|
||||||
<p style="font-size: x-small; display: block;">ID</p>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<!-- CODE Here -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-6">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;">{{this.lastname}}</span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "lastname"}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="column is-6">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;">{{this.group.name}}</span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "group"}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p>{{__ "sponsoring_amount_per_distance"}}</p>
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-6">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;"> </span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "lastname"}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="column is-6">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;"> </span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "firstname"}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p style="font-size: medium;">{{__ "address"}} ({{__ "sponsor"}})</p>
|
|
||||||
<p style="font-size: x-small;">({{__ "sponsoring_address_condition"}})</p>
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-8">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;"> </span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "street"}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="column is-4">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;"> </span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "house_number"}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-4">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;"> </span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "postalcode"}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="column is-8">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;"> </span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "city"}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-7">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;"> </span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "location"}}, {{__ "date"}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="column is-5">
|
|
||||||
<span style="border-bottom: 1px solid; width: 100%; display: block;"> </span>
|
|
||||||
<p style="font-size: x-small; display: block;">{{__ "signature"}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</body>
|
||||||
{{/each}}
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
Binary file not shown.
Before Width: | Height: | Size: 225 KiB |
Loading…
x
Reference in New Issue
Block a user