mirror of
https://github.com/glenndehaan/unifi-voucher-site.git
synced 2026-04-05 00:44:18 -04:00
Migrated README.md images to .docs folder. Moved print logic to own module. Implemented ESC/POS printer support. Added logo_grayscale_dark.png. Replaced PDF logo. Implemented size.js util for dynamic PDF page length. Updated README.md. Updated auth output log with type. Updated print output log with printer ip
This commit is contained in:
236
modules/print.js
Normal file
236
modules/print.js
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* Import base packages
|
||||
*/
|
||||
const PDFDocument = require('pdfkit');
|
||||
const ThermalPrinter = require('node-thermal-printer').printer;
|
||||
const PrinterTypes = require('node-thermal-printer').types;
|
||||
|
||||
/**
|
||||
* Import own modules
|
||||
*/
|
||||
const log = require('./log');
|
||||
const config = require('./config');
|
||||
const time = require('../utils/time');
|
||||
const bytes = require('../utils/bytes');
|
||||
const size = require('../utils/size');
|
||||
|
||||
/**
|
||||
* Define global variables
|
||||
*/
|
||||
const printerIp = config('printer_ip') || process.env.PRINTER_IP || '192.168.1.1';
|
||||
|
||||
/**
|
||||
* Exports the printer module
|
||||
*/
|
||||
module.exports = {
|
||||
/**
|
||||
* Generates a voucher as a PDF
|
||||
*
|
||||
* @param voucher
|
||||
* @return {Promise<unknown>}
|
||||
*/
|
||||
pdf: (voucher) => {
|
||||
return new Promise((resolve) => {
|
||||
const doc = new PDFDocument({
|
||||
bufferPages: true,
|
||||
size: [226.77165354330398, size(voucher)],
|
||||
margins : {
|
||||
top: 20,
|
||||
bottom: 20,
|
||||
left: 20,
|
||||
right: 20
|
||||
}
|
||||
});
|
||||
|
||||
const buffers = [];
|
||||
doc.on('data', buffers.push.bind(buffers));
|
||||
doc.on('end', () => {
|
||||
log.info('[Printer] PDF generation completed!');
|
||||
resolve(buffers);
|
||||
});
|
||||
|
||||
doc.image('public/images/logo_grayscale_dark.png', 75, 15, {fit: [75, 75], align: 'center', valign: 'center'});
|
||||
|
||||
doc.moveDown(6);
|
||||
|
||||
doc.font('Helvetica-Bold')
|
||||
.fontSize(20)
|
||||
.text(`WiFi Voucher Code`, {
|
||||
align: 'center'
|
||||
});
|
||||
doc.font('Helvetica-Bold')
|
||||
.fontSize(15)
|
||||
.text(`${voucher.code.slice(0, 5)}-${voucher.code.slice(5)}`, {
|
||||
align: 'center'
|
||||
});
|
||||
|
||||
doc.moveDown(2);
|
||||
|
||||
doc.font('Helvetica-Bold')
|
||||
.fontSize(12)
|
||||
.text(`Voucher Details`);
|
||||
|
||||
doc.font('Helvetica-Bold')
|
||||
.fontSize(10)
|
||||
.text(`--------------------------------------------------------`);
|
||||
|
||||
doc.font('Helvetica-Bold')
|
||||
.fontSize(10)
|
||||
.text(`Type: `, {
|
||||
continued: true
|
||||
});
|
||||
doc.font('Helvetica')
|
||||
.fontSize(10)
|
||||
.text(voucher.quota === 0 ? 'Multi-use' : 'Single-use');
|
||||
|
||||
doc.font('Helvetica-Bold')
|
||||
.fontSize(10)
|
||||
.text(`Duration: `, {
|
||||
continued: true
|
||||
});
|
||||
doc.font('Helvetica')
|
||||
.fontSize(10)
|
||||
.text(time(voucher.duration));
|
||||
|
||||
if(voucher.qos_usage_quota) {
|
||||
doc.font('Helvetica-Bold')
|
||||
.fontSize(10)
|
||||
.text(`Data Limit: `, {
|
||||
continued: true
|
||||
});
|
||||
doc.font('Helvetica')
|
||||
.fontSize(10)
|
||||
.text(`${bytes(voucher.qos_usage_quota, 2)}`);
|
||||
}
|
||||
|
||||
if(voucher.qos_rate_max_down) {
|
||||
doc.font('Helvetica-Bold')
|
||||
.fontSize(10)
|
||||
.text(`Download Limit: `, {
|
||||
continued: true
|
||||
});
|
||||
doc.font('Helvetica')
|
||||
.fontSize(10)
|
||||
.text(`${bytes(voucher.qos_rate_max_down, 1, true)}`);
|
||||
}
|
||||
|
||||
if(voucher.qos_rate_max_up) {
|
||||
doc.font('Helvetica-Bold')
|
||||
.fontSize(10)
|
||||
.text(`Upload Limit: `, {
|
||||
continued: true
|
||||
});
|
||||
doc.font('Helvetica')
|
||||
.fontSize(10)
|
||||
.text(`${bytes(voucher.qos_rate_max_up, 1, true)}`);
|
||||
}
|
||||
|
||||
doc.end();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends a print job to an ESC/POS compatible network printer
|
||||
*
|
||||
* @param voucher
|
||||
* @return {Promise<unknown>}
|
||||
*/
|
||||
escpos: (voucher) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const printer = new ThermalPrinter({
|
||||
type: PrinterTypes.EPSON,
|
||||
interface: `tcp://${printerIp}`
|
||||
});
|
||||
|
||||
const status = await printer.isPrinterConnected();
|
||||
|
||||
if(!status) {
|
||||
reject('Unable to connect to printer!');
|
||||
return;
|
||||
}
|
||||
|
||||
printer.setTypeFontB();
|
||||
printer.alignCenter();
|
||||
printer.newLine();
|
||||
await printer.printImage(`${process.cwd()}/public/images/logo_grayscale_dark.png`);
|
||||
printer.newLine();
|
||||
|
||||
printer.alignCenter();
|
||||
printer.newLine();
|
||||
printer.setTextSize(2, 2);
|
||||
printer.println('WiFi Voucher Code');
|
||||
printer.setTextSize(1, 1);
|
||||
printer.println(`${voucher.code.slice(0, 5)}-${voucher.code.slice(5)}`);
|
||||
printer.setTextNormal();
|
||||
|
||||
printer.newLine();
|
||||
printer.newLine();
|
||||
printer.newLine();
|
||||
printer.newLine();
|
||||
printer.newLine();
|
||||
|
||||
printer.alignLeft();
|
||||
printer.setTypeFontB();
|
||||
printer.setTextSize(1, 1);
|
||||
printer.println('Voucher Details');
|
||||
printer.setTextNormal();
|
||||
printer.drawLine();
|
||||
|
||||
printer.setTextDoubleHeight();
|
||||
printer.invert(true);
|
||||
printer.print('Type:');
|
||||
printer.invert(false);
|
||||
printer.print(voucher.quota === 0 ? ' Multi-use' : ' Single-use');
|
||||
printer.newLine();
|
||||
|
||||
printer.setTextDoubleHeight();
|
||||
printer.invert(true);
|
||||
printer.print('Duration:');
|
||||
printer.invert(false);
|
||||
printer.print(` ${time(voucher.duration)}`);
|
||||
printer.newLine();
|
||||
|
||||
if(voucher.qos_usage_quota) {
|
||||
printer.setTextDoubleHeight();
|
||||
printer.invert(true);
|
||||
printer.print('Data Limit:');
|
||||
printer.invert(false);
|
||||
printer.print(` ${bytes(voucher.qos_usage_quota, 2)}`);
|
||||
printer.newLine();
|
||||
}
|
||||
|
||||
if(voucher.qos_rate_max_down) {
|
||||
printer.setTextDoubleHeight();
|
||||
printer.invert(true);
|
||||
printer.print('Download Limit:');
|
||||
printer.invert(false);
|
||||
printer.print(` ${bytes(voucher.qos_rate_max_down, 1, true)}`);
|
||||
printer.newLine();
|
||||
}
|
||||
|
||||
if(voucher.qos_rate_max_up) {
|
||||
printer.setTextDoubleHeight();
|
||||
printer.invert(true);
|
||||
printer.print('Upload Limit:');
|
||||
printer.invert(false);
|
||||
printer.print(` ${bytes(voucher.qos_rate_max_up, 1, true)}`);
|
||||
printer.newLine();
|
||||
}
|
||||
|
||||
printer.newLine();
|
||||
printer.newLine();
|
||||
printer.newLine();
|
||||
printer.newLine();
|
||||
printer.cut();
|
||||
printer.beep(2, 2);
|
||||
|
||||
try {
|
||||
await printer.execute();
|
||||
log.info('[Printer] Data send to printer!');
|
||||
resolve(true);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user