diff --git a/.gitignore b/.gitignore index 37345c3..72aa169 100644 --- a/.gitignore +++ b/.gitignore @@ -136,4 +136,5 @@ build /docs lib /oss-attribution -*.tmp \ No newline at end of file +*.tmp +*.pdf \ No newline at end of file diff --git a/package.json b/package.json index f2e080c..eb1477f 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "cors": "^2.8.5", "dotenv": "^8.2.0", "express": "^4.17.1", + "html-pdf": "^2.2.0", "reflect-metadata": "^0.1.13", "routing-controllers": "^0.9.0-alpha.6", "routing-controllers-openapi": "^2.2.0" @@ -72,4 +73,4 @@ "publish": false } } -} \ No newline at end of file +} diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts new file mode 100644 index 0000000..2345c8c --- /dev/null +++ b/src/PdfCreator.ts @@ -0,0 +1,56 @@ +import fs from "fs"; +import pdf_converter from "html-pdf"; +import path from 'path'; +import { Stream } from 'stream'; + +/** + * This class is responsible for all things pdf creation. + * This uses the html templates from src/templates. + */ +export class PdfCreator { + private templateDir = path.join(__dirname, '/templates'); + + //TODO: Accept the runner class + public async generateSponsoringContract(): Promise { + let template = fs.readFileSync(`${this.templateDir}/sponsoring_contract.html`, 'utf8'); + template = template.replace("{{Runner Name}}", "lelele"); + return new Pdf(await pdf_converter.create(template, { format: "A5", orientation: "landscape" })); + } + +} + +/** + * 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; + } + + /** + * Promise wrapper function that resolves the toBuffer promise for pdf generation. + */ + public async toBuffer(): Promise { + let promise = await new Promise((resolve, reject) => { + this.content.toBuffer(function (err, buffer: Buffer) { + resolve(buffer); + }); + }); + return await promise; + } + + /** + * Promise wrapper function that resolves the toStream promise for pdf generation. + */ + public async toStream(): Promise { + let promise = await new Promise((resolve, reject) => { + this.content.toStream(function (err, stream: Stream) { + resolve(stream); + }); + }); + return await promise; + } +} \ No newline at end of file diff --git a/src/controllers/PdfController.ts b/src/controllers/PdfController.ts new file mode 100644 index 0000000..0ec9581 --- /dev/null +++ b/src/controllers/PdfController.ts @@ -0,0 +1,20 @@ +import { ContentType, Controller, Get } from 'routing-controllers'; +import { OpenAPI } from 'routing-controllers-openapi'; +import { PdfCreator } from '../PdfCreator'; + +@Controller() +export class PdfController { + private pdf: PdfCreator; + constructor() { + this.pdf = new PdfCreator(); + } + + @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(); + } +} \ No newline at end of file diff --git a/src/templates/.gitkeep b/src/templates/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/templates/sponsoring_contract.html b/src/templates/sponsoring_contract.html new file mode 100644 index 0000000..1597b2c --- /dev/null +++ b/src/templates/sponsoring_contract.html @@ -0,0 +1,45 @@ + + + + Sponsoring contract + + + +
+

{{Runner Name}}

+
+ + \ No newline at end of file