Repository navigation
Expand file tree
/
Copy pathdefault_printer.js
More file actions
146 lines (124 loc) · 5.07 KB
/
Copy pathdefault_printer.js
File metadata and controls
146 lines (124 loc) · 5.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const fs = require('fs');
const app = express();
const PORT = process.env.PORT || 3000;
app.use(express.static(__dirname));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const COUNTERS_FILE = path.join(__dirname, 'data', 'counters.json');
function readCounters() {
try {
if (fs.existsSync(COUNTERS_FILE)) {
const data = fs.readFileSync(COUNTERS_FILE, 'utf8');
const parsed = JSON.parse(data);
return parsed && typeof parsed === 'object' ? parsed : {};
}
} catch (error) {
console.error('Error reading counters file:', error);
}
return {};
}
function writeCounters(counters) {
try {
fs.writeFileSync(COUNTERS_FILE, JSON.stringify(counters, null, 2), 'utf8');
} catch (error) {
console.error('Error writing counters file:', error);
}
}
const USE_REAL_PRINTER = process.env.REAL_PRINTER === '1';
let ThermalPrinter, PrinterTypes;
if (USE_REAL_PRINTER) {
try {
({ ThermalPrinter, PrinterTypes } = require("node-thermal-printer"));
} catch (e) {
console.warn('node-thermal-printer not available or failed to load; using simulation.');
ThermalPrinter = null; PrinterTypes = null;
}
} else {
console.log('REAL_PRINTER not enabled; running in simulation mode. Set REAL_PRINTER=1 to enable.');
}
// Diagnostic: log whether the printer library appears to be present
try {
console.log('Diagnostic: node-thermal-printer loaded?', !!ThermalPrinter, 'PrinterTypes?', !!PrinterTypes);
if (ThermalPrinter && PrinterTypes) {
const p = require('node-thermal-printer');
console.log('Diagnostic: node-thermal-printer exports:', Object.keys(p));
}
} catch (e) {
console.error('Diagnostic: failed to inspect node-thermal-printer:', e && e.message);
}
async function printMessageToThermalPrinter(ipAddress, message) {
if (!ThermalPrinter || !PrinterTypes) {
throw new Error('Thermal printer library not loaded');
}
const PRINTER_DEVICE = process.env.PRINTER_DEVICE;
if (!PRINTER_DEVICE) throw new Error('PRINTER_DEVICE not configured');
const printer = new ThermalPrinter({
type: PrinterTypes.EPSON,
interface: PRINTER_DEVICE,
});
try {
printer.alignLeft();
printer.setTextDoubleHeight();
printer.setTextDoubleWidth();
printer.println(message);
printer.setTextNormal();
printer.newLine();
printer.alignRight();
printer.println(`IP: ${ipAddress}`);
printer.newLine();
printer.alignCenter();
printer.println(new Date().toLocaleString());
printer.newLine();
// Partial cut: GS V 1 -> 0x1D 0x56 0x01
printer.raw(Buffer.from([0x1D, 0x56, 0x01]));
printer.raw(Buffer.from([0x1D, 0x56, 0x01]));
await printer.execute();
} catch (error) {
console.error('Print failed:', error);
throw error;
} finally {
// Some implementations expose disconnect/cut - best-effort
try { if (typeof printer.disconnect === 'function') printer.disconnect(); } catch (e) {}
}
}
app.post('/print', async (req, res) => {
const ipAddress = req.headers['x-forwarded-for'] ? req.headers['x-forwarded-for'].split(',')[0].trim() : (req.ip || 'Unknown IP');
const message = req.body.message;
if (!message || message.trim() === '') {
console.warn(`Invalid submission from ${ipAddress}: Missing message.`);
return res.status(400).send("Message is required.");
}
const safeMessage = message.substring(0, 200).replace(/</g, "<").replace(/>/g, ">");
try {
if (USE_REAL_PRINTER && typeof printMessageToThermalPrinter === 'function' && ThermalPrinter && PrinterTypes) {
try {
await printMessageToThermalPrinter(ipAddress, safeMessage);
console.log(`[Server] Message from ${ipAddress} printed to thermal printer.`);
} catch (printerError) {
console.error('Thermal printer failed, falling back to simulation:', printerError);
}
} else {
console.log(`[Server] Message from ${ipAddress} received and "printed" (simulation).`);
}
const counters = readCounters();
const current = Number(counters[ipAddress] || 0) + 1;
counters[ipAddress] = current;
writeCounters(counters);
res.status(200).json({ ok: true, ip: ipAddress, count: current });
} catch (error) {
console.error("Error during printing process:", error);
res.status(500).send("Failed to print message due to internal server error.");
}
});
app.get('/whoami', (req, res) => {
const ip = req.headers['x-forwarded-for'] ? req.headers['x-forwarded-for'].split(',')[0].trim() : (req.ip || 'Unknown');
const counters = readCounters();
const count = Number(counters[ip] || 0);
res.json({ ip, count });
});
app.listen(PORT, () => {
console.log(`✅ Server running at http://localhost:${PORT}`);
});