Skip to content

Instantly share code, notes, and snippets.

@vodolaz095
Last active August 30, 2023 20:47
Show Gist options
  • Star 28 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save vodolaz095/5325917 to your computer and use it in GitHub Desktop.
Save vodolaz095/5325917 to your computer and use it in GitHub Desktop.
Print for NodeJS using CUPS backend
var ipp = require('ipp'); //get it from there - https://npmjs.org/package/ipp - $npm install ipp
var request = require('request'); //get it from there - https://npmjs.org/package/request - $npm install request
var fs = require('fs');
function getPrinterUrls(callback) {
var CUPSurl = 'http://localhost:631/printers';//todo - change of you have CUPS running on other host
request(CUPSurl, function (error, response, body) {
if (!error && response.statusCode == 200) {
var printersMatches = body.match(/<TR><TD><A HREF="\/printers\/([a-zA-Z0-9-^"]+)">/gm);//i know, this is terrible, sorry(
var printersUrls = [];
var i;
if (printersMatches) {
for (i = 0; i < printersMatches.length; i++) {
var a = (/"\/printers\/([a-zA-Z0-9-^"]+)"/).exec(printersMatches[i]);
if (a) {
printersUrls.push(CUPSurl + '/' + a[1]);
}
}
}
}
callback(error, printersUrls);
});
};
function doPrintOnSelectedPrinter(printer, bufferToBePrinted, callback) {
printer.execute("Get-Printer-Attributes", null, function(err, printerStatus){
if(printerStatus['printer-attributes-tag']['printer-state']=='idle'){
//printer ready to work
//*/
printer.execute("Print-Job",
{
"operation-attributes-tag":{
"requesting-user-name":"nap",
"job-name":"testing"
},
"job-attributes-tag":{},
data:bufferToBePrinted
},
function (err, res) {
if (res.statusCode == 'successful-ok') {
var jobUri = res['job-attributes-tag']['job-uri'];
var tries = 0;
var t = setInterval(function () {
printer.execute("Get-Job-Attributes",
{"operation-attributes-tag":{'job-uri':jobUri}},
function (err2, job) {
// console.log(job);
if (err2) throw err2;
tries++;
if (job && job["job-attributes-tag"]["job-state"] == 'completed') {
clearInterval(t);
// console.log('Testins if job is ready. Try N '+tries);
callback(null, job);//job is succesefully printed!
}
if (tries > 50) {//todo - change it to what you need!
clearInterval(t);
printer.execute("Cancel-Job", {
"operation-attributes-tag":{
//"job-uri":jobUri, //uncomment this
//*/
"printer-uri":printer.uri, //or uncomment this two lines - one of variants should work!!!
"job-id":job["job-attributes-tag"]["job-id"]
//*/
}
}, function (err, res) {
if (err) throw err;
console.log('Job with id '+job["job-attributes-tag"]["job-id"]+'is being canceled');
});
callback(new Error('Job is canceled - too many tries and job is not printed!'), null);
}
});
}, 2000);
} else {
callback(new Error('Error sending job to printer!'), null);
}
});
//*/
} else {
callback(new Error('Printer '+printerStatus['printer-attributes-tag']['printer-name']+' is not ready!'),null);
}
});
}
function doPrintOnAllPrinters(data, callback) {
var b = new Buffer(data, 'binary');
getPrinterUrls(function (err, printers) {
if (err) throw err;
if (printers) {
for (var i = 0; i < printers.length; i++) {
var printer = ipp.Printer(printers[i]);
doPrintOnSelectedPrinter(printer, b, callback);
}
} else {
throw new Error('Unable to find printer. Do you have printer installed and accessible via CUPS?');
}
});
}
/*
Example of usage
*/
fs.readFile('package.json', function (err, data) {
doPrintOnAllPrinters(data, function (err, job) {
if (err) {
console.error('Error printing');
console.error(err);
} else {
console.log('Printed. Job parameters are: ');
console.log(job);
}
}
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment