Merge pull request 'Barcode generation feature/13-barcode_generation' (#21) from feature/13-barcode_generation into dev
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is failing
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	continuous-integration/drone/push Build is failing
				
			Reviewed-on: #21
This commit was merged in pull request #21.
	This commit is contained in:
		@@ -40,7 +40,9 @@
 | 
			
		||||
  "license": "CC-BY-NC-SA-4.0",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@odit/class-validator-jsonschema": "^2.1.1",
 | 
			
		||||
    "async-helpers": "^0.3.17",
 | 
			
		||||
    "axios": "^0.21.1",
 | 
			
		||||
    "bwip-js": "^2.0.12",
 | 
			
		||||
    "cheerio": "^1.0.0-rc.5",
 | 
			
		||||
    "class-transformer": "0.3.1",
 | 
			
		||||
    "class-validator": "^0.13.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,11 @@ import mime from "mime-types";
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import { PDFDocument } from 'pdf-lib';
 | 
			
		||||
import puppeteer from "puppeteer";
 | 
			
		||||
import { awaitAsyncHandlebarHelpers, helpers } from './asyncHelpers';
 | 
			
		||||
import { config } from './config';
 | 
			
		||||
import { Runner } from './models/Runner';
 | 
			
		||||
import { RunnerGroup } from './models/RunnerGroup';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class is responsible for all things pdf creation.
 | 
			
		||||
 * This uses the html templates from src/templates.
 | 
			
		||||
@@ -68,7 +70,6 @@ export class PdfCreator {
 | 
			
		||||
            '--use-gl=swiftshader',
 | 
			
		||||
            '--no-sandbox'
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        await i18next
 | 
			
		||||
            .use(Backend)
 | 
			
		||||
            .init({
 | 
			
		||||
@@ -78,6 +79,8 @@ export class PdfCreator {
 | 
			
		||||
                    loadPath: path.join(__dirname, '/locales/{{lng}}.json')
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        await Handlebars.registerHelper(helpers);
 | 
			
		||||
        await Handlebars.registerHelper('__',
 | 
			
		||||
            function (str) {
 | 
			
		||||
                return i18next.t(str, PdfCreator.interpolations).toString();
 | 
			
		||||
@@ -91,7 +94,7 @@ export class PdfCreator {
 | 
			
		||||
     * @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 generateSponsoringContract(runners: Runner[], locale: string = "en", codeformat: string = config.codeformat): Promise<Buffer> {
 | 
			
		||||
        if (runners.length == 1 && Object.keys(runners[0]).length == 0) {
 | 
			
		||||
            runners[0] = this.generateEmptyRunner();
 | 
			
		||||
        }
 | 
			
		||||
@@ -108,7 +111,8 @@ export class PdfCreator {
 | 
			
		||||
        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 })
 | 
			
		||||
        let result = template({ runners, codeformat });
 | 
			
		||||
        result = await awaitAsyncHandlebarHelpers(result);
 | 
			
		||||
        const pdf = await this.renderPdf(result, { format: "A5", landscape: true });
 | 
			
		||||
        return pdf
 | 
			
		||||
    }
 | 
			
		||||
@@ -122,6 +126,9 @@ export class PdfCreator {
 | 
			
		||||
        const $ = cheerio.load(html)
 | 
			
		||||
        $('img').each(async (index, element) => {
 | 
			
		||||
            let imgsrc = $(element).attr("src");
 | 
			
		||||
            if (imgsrc.startsWith("data:image")) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            const img_type = mime.lookup(imgsrc);
 | 
			
		||||
 | 
			
		||||
            if (!(img_type.includes("image"))) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								src/asyncHelpers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/asyncHelpers.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -7,7 +7,8 @@ export const config = {
 | 
			
		||||
    version: process.env.VERSION || require('../package.json').version,
 | 
			
		||||
    eventname: process.env.EVENT_NAME || "Please set the event name",
 | 
			
		||||
    currency_symbol: process.env.CURRENCY_SYMBOL || "€",
 | 
			
		||||
    sponsoring_receipt_minimum_amount: process.env.SPONSORING_RECEIPT_MINIMUM_AMOUNT || "10"
 | 
			
		||||
    sponsoring_receipt_minimum_amount: process.env.SPONSORING_RECEIPT_MINIMUM_AMOUNT || "10",
 | 
			
		||||
    codeformat: process.env.CODEFORMAT || "qrcode"
 | 
			
		||||
}
 | 
			
		||||
let errors = 0
 | 
			
		||||
if (typeof config.internal_port !== "number") {
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ export class PdfController {
 | 
			
		||||
 | 
			
		||||
    @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) {
 | 
			
		||||
    async generateContracts(@Body({ validate: true, options: { limit: "500mb" } }) runners: Runner | Runner[], @Res() res: any, @QueryParam("locale") locale: string, @QueryParam("codeformat") codeformat: string) {
 | 
			
		||||
        if (!this.initialized) {
 | 
			
		||||
            await this.pdf.init();
 | 
			
		||||
            this.initialized = true;
 | 
			
		||||
@@ -23,7 +23,7 @@ export class PdfController {
 | 
			
		||||
        if (!Array.isArray(runners)) {
 | 
			
		||||
            runners = [runners];
 | 
			
		||||
        }
 | 
			
		||||
        const contracts = await this.pdf.generateSponsoringContract(runners, locale);
 | 
			
		||||
        const contracts = await this.pdf.generateSponsoringContract(runners, locale, codeformat);
 | 
			
		||||
        res.setHeader('content-type', 'application/pdf');
 | 
			
		||||
        return contracts;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,8 @@
 | 
			
		||||
  <div class="sheet">
 | 
			
		||||
    <img id="header_img" width="100%" src="sponsoringheader.png" />
 | 
			
		||||
    <div style=" padding: 0 1rem 0 1rem;">
 | 
			
		||||
      <div class="columns">
 | 
			
		||||
        <div class="column is-10">
 | 
			
		||||
          <div class="columns" style="padding-bottom: 0;">
 | 
			
		||||
            <div class="column is-two-fifths">
 | 
			
		||||
              <p style="font-size: large; font-weight: bold;">{{__ "sponsoring_title"}}</p>
 | 
			
		||||
@@ -39,21 +41,24 @@
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <p> {{__ "sponsoring_subtitle"}} </p>
 | 
			
		||||
      <div class="columns" style="padding-top: 0;">
 | 
			
		||||
        <div class="column is-8">
 | 
			
		||||
          <div class="columns">
 | 
			
		||||
            <div class="column is-9">
 | 
			
		||||
              <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">
 | 
			
		||||
            <div class="column is-3">
 | 
			
		||||
              <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>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="column">
 | 
			
		||||
          <!-- CODE Here -->
 | 
			
		||||
          <img style="vertical-align: revert; margin-top: auto; object-fit: cover; max-height: 2cm;"
 | 
			
		||||
            src="{{--bc this.id ../codeformat}}" />
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="columns">
 | 
			
		||||
      <div class="columns" style="padding-top: 1rem;">
 | 
			
		||||
        <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>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user