Skip to content
This repository has been archived by the owner on May 16, 2023. It is now read-only.

Generate QR Code with Poster as PDF #5

Merged
merged 5 commits into from
Apr 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ $ cwa-event-qr-code terminal \
--type 1 \
--default-check-in-length-in-minutes 30

# Create poster
$ cwa-event-qr-code poster \
--description hello-world \
--address hello \
--type 1 \
--default-check-in-length-in-minutes 30 \
--filepath hello-world.pdf

# Alternatively, you can skip the global installation by using npx
$ npx cwa-event-qr-code --help
```
Expand Down
5 changes: 5 additions & 0 deletions THIRD-PARTY-NOTICES
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ corona-warn-app.opensource@sap.com

Components:
-----------
Component: pdf-lib
Licensor: Andrew Dillon and other contributors
Website: https://github.com/Hopding/pdf-lib
License: MIT License

Component: protobufjs
Licensor: Google Inc. and other contributors
Website: https://github.com/protobufjs/protobuf.js
Expand Down
Binary file added assets/.DS_Store
Binary file not shown.
Binary file added assets/pt-poster-1.0.0.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions bin/cli
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ const yargs = require('yargs')

yargs
.command(require('./../lib/yargs/commands/file')())
.command(require('./../lib/yargs/commands/poster')())
.command(require('./../lib/yargs/commands/terminal')())
.argv
56 changes: 56 additions & 0 deletions lib/generate-poster.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict'

const fs = require('fs')
const path = require('path')
const {
PDFDocument,
rgb,
StandardFonts
} = require('pdf-lib')
const { promisify } = require('util')

const readFile = promisify(fs.readFile)

module.exports = async ({ qrCode, locationData }) => {
const templateFilepath = path.resolve(__dirname, '../assets/pt-poster-1.0.0.pdf')
const template = await readFile(templateFilepath)

const pdfDoc = await PDFDocument.load(template)

const pngImage = await pdfDoc.embedPng(qrCode)
const pngDims = pngImage.scaleToFit(400, 400)
const page = pdfDoc.getPage(0)
page.drawImage(pngImage, {
x: page.getWidth() / 2 - pngDims.width / 2,
y: page.getHeight() / 2 - pngDims.height + 340,
width: pngDims.width,
height: pngDims.height
})

const fontSize = 10
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
const maxTextWidth = 420
const truncateText = text => {
while (helveticaFont.widthOfTextAtSize(text, fontSize) > maxTextWidth) {
text = text.substr(0, text.length - 1)
}
return text
}

page.drawText(truncateText(locationData.description), {
x: 80,
y: 325,
size: fontSize,
font: helveticaFont,
color: rgb(0, 0, 0)
})
page.drawText(truncateText(locationData.address), {
x: 80,
y: 310,
size: fontSize,
font: helveticaFont,
color: rgb(0, 0, 0)
})

return pdfDoc.save()
}
16 changes: 15 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
'use strict'

const fs = require('fs')
const QRCode = require('qrcode')
const { promisify } = require('util')

const generateQRCodePayload = require('./generate-qr-code-payload')
const generateQRCodeUrl = require('./generate-qr-code-url')
const generatePoster = require('./generate-poster')

const qrCodeToFile = promisify(QRCode.toFile)
const qrCodeToBuffer = promisify(QRCode.toBuffer)
const qrCodeToString = promisify(QRCode.toString)
const writeFile = promisify(fs.writeFile)

const createEventQRCode = ({ locationData, vendorData }) => {
const toQRCodePayloadBuffer = () => generateQRCodePayload({ locationData, vendorData })
Expand All @@ -20,6 +24,10 @@ const createEventQRCode = ({ locationData, vendorData }) => {
const url = await toURL()
return qrCodeToFile(filepath, url, options)
}
const toBuffer = async (options) => {
const url = await toURL()
return qrCodeToBuffer(url, options)
}
const toPNG = async (filepath, options) => {
options.type = 'png'
return toFile(filepath, options)
Expand All @@ -32,14 +40,20 @@ const createEventQRCode = ({ locationData, vendorData }) => {
const url = await toURL()
return qrCodeToString(url, { type: 'terminal' })
}
const toPoster = async (filepath) => {
const qrCode = await toBuffer({ width: 1000, type: 'png' })
const pdf = await generatePoster({ qrCode, locationData })
await writeFile(filepath, pdf)
}

return {
toQRCodePayloadBuffer,
toURL,
toFile,
toPNG,
toSVG,
toString
toString,
toPoster
}
}

Expand Down
32 changes: 32 additions & 0 deletions lib/yargs/commands/poster.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict'

const path = require('path')
const { createEventQRCode } = require('../../index')
const {
addOptionsForLocationData,
addOptionsForVendorData,
getLocationDataFromArgv,
getVendorDataFromArgv
} = require('../yargs-util')

module.exports = () => {
return {
command: ['poster'],
desc: 'create poster with QR code',
builder: yargs => {
addOptionsForLocationData(yargs)
addOptionsForVendorData(yargs)
yargs.option('filepath')
},
handler: async argv => {
const locationData = getLocationDataFromArgv(argv)
const vendorData = getVendorDataFromArgv(argv)
const eventQRCode = createEventQRCode({ locationData, vendorData })

const filepath = path.resolve(process.cwd(), argv.filepath)
await eventQRCode.toPoster(filepath)

console.log(`Created ${filepath}`)
}
}
}
74 changes: 70 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"homepage": "https://github.com/corona-warn-app/cwa-event-qr-code#readme",
"dependencies": {
"pdf-lib": "1.16.0",
"protobufjs": "6.10.2",
"qrcode": "1.4.4",
"yargs": "16.2.0"
Expand Down