williamkapke / ipp Goto Github PK
View Code? Open in Web Editor NEWInternet Printing Protocol (IPP) for nodejs
Internet Printing Protocol (IPP) for nodejs
I can get it to "Print-Job" but when I try to print using a URI I get the error "Print-URI not supported". Any Ideas?
var printer = ipp.Printer("http://10.0.1.156:631/printers/Kyocera_FS-9530DN");
var msg = {
"operation-attributes-tag": {
"requesting-user-name": "William",
"job-name": "My Test Job",
"document-format": "application/pdf",
"document-uri": "http://10.0.1.156:5000/#/extension/reports/DfUny9LY4tUwxYMZ"
}
};
printer.execute("Print-URI", msg, function(err, d){
if(err){
return res.send(err);
}
return res.send(d);
});
returns
{
"version": "2.0",
"statusCode": "server-error-operation-not-supported",
"id": 33660406,
"operation-attributes-tag": {
"attributes-charset": "utf-8",
"attributes-natural-language": "en-us",
"status-message": "Print-URI not supported."
}
}
We have two HP PageWide Pro printers, 477w and 452dw models.
I am successful at printing jobs, the problem I found is that from the internal web page of the printers we cannot set the Job Names. They appear as follows:
You can see how the IPP jobs are indicated with User "Guest" and Job Name "Print".
Here is a snippet of the code I put together using this package:
const printer = ipp.Printer(`http://${hostname}:631/ipp/printer`);
let inputFile = 'whatever.pdf'; // passed in argv, omitted here
[...]
fs.readFile(inputFile, (readErr, pdfData) => {
if (readErr) {
throw readErr;
}
const payload = {
'operation-attributes-tag': {
'requesting-user-name': 'Bumblebee',
'job-name': path.basename(inputFile),
'document-format': 'application/pdf',
},
data: pdfData,
};
const runPrint = () => {
printer.execute('Print-Job', payload, (executeErr, res) => {
if (executeErr) {
const fileName = path.basename(inputFile);
slack.sendNotification({
channel: '#prepress',
text: `Printing the file *${fileName}* has failed. @here`,
link_names: true,
})
.then(() => {
throw executeErr;
});
}
if (res.statusCode === 'server-error-busy') {
setTimeout(runPrint, 1000);
}
});
};
runPrint();
});
Do you have any experience in successfully working with HP printers? I tried googling but I could find their IPP internals spec, maybe the use some custom fields for attributes?
Hey guys,
i'm trying to print a document on the second paper tray.
My printer supports following media sources:
'media-source-supported': [ 'tray-1', 'tray-2', 'tray-3', 'tray-1-man' ],
I'm using the code from your printPDF.js sample:
var file = { "operation-attributes-tag": { "requesting-user-name": "User", "job-name": "Print Job", "document-format": "application/pdf" }, "job-attributes-tag": { "media-col": { "media-source": "tray-2" } }, data: data };
But my printer always shows the error message you need to add paper to the first tray.
Do you have any ideas?
Hi guys.
I'm trying to send the following message:
var msg = {
'operation-attributes-tag': {
'requesting-user-name': 'leandro',
'job-name': 'j1234',
'document-format': 'application/pdf'
},
'job-attributes-tag': {
'media-col': {
'media-source': 'tray-2',
'media-size': {
'x-dimension': 14800,
'y-dimension': 21000
}
},
'orientation-requested': 'landscape'
},
data: data
};
And I'm facing a "TypeError: Cannot read property 'x-dimension' of undefined" (at .\node_modules\ipp\lib\serializer.js:204:27). But as per what I looked up (https://github.com/williamkapke/ipp/blob/master/lib/attributes.js#L471), there is this property "x-dimension" and "y-dimension" into "media-size", which is a property of "media-col".
Just for a test, I moved "media-size" to the same level as "media-col" and then I got "Unknown attribute: media-size" as expected.
Can't figure it out.
I'm trying to print from a specific tray but I'm unable to set the "media-source" attribute.
var printer = ipp.Printer(uri);
var msg = {
"operation-attributes-tag": {
"attributes-charset": "utf-8",
"attributes-natural-language": "en",
"printer-uri": uri,
"document-format": "application/pdf"
},
"job-attributes-tag": {
"media-source": "tray-2",
"copies": "2"
},
data: Buffer.concat(buffers)
}
printer.execute("Print-Job", msg, function(err, res){
console.log(JSON.stringify(res,null,2));
})
returns
U:\pdfparser\node_modules\ipp\lib\serializer.js:64
if(!groupName) throw "Unknown attribute: " + name;
^
Unknown attribute: media-source
The printer seems to have "media-source" as an attribute.
"media-source-supported": [ "auto", "tray-1", "tray-2", "tray-3", "tray-4", "tray-5" ],
Hi,
I am using 'Get-Printer-Attributes' operation to query printer's state -
var msg = {
"operation-attributes-tag": {
"requested-attributes": [
"printer-state",
"printer-state-message",
"printer-state-reasons"
]
}
};
var printer = ipp.Printer("printer-uri");
printer.execute("Get-Printer-Attributes", msg, function(err, res){
console.log(res);
});
However even if I switch off the printer, it still responds back with state as Idle. When I try to send prints it accepts and then state becomes 'processing' with additional printer-message as 'printer is not responding'. After a while, print job goes to canceled state and printer state is back to idle. Printer is still switched off.
Could you please help in identifying the exact state of printer, is there anyway i can get the actual state of the printer (Switched Off etc).
Thanks!
I use nodemon in the debug mode during the development time and attach a debugger only when I really intended to dig into something.
Today when I worked with a new printer I encountered a problem that my application hangs. After a quick investigation I found that the problem is in this line:
Line 132 in 8ce50cc
Since I run my code in the debug mode, execution pauses on this line, but I have no debugger attached, so I'm not notified about the pause and has no way to do something with it.
There is one more line that can cause the same problem:
Line 197 in 8ce50cc
@williamkapke do you think it's OK to remove the statement? If so, I'll create a PR.
Hello, my printer doesn't show the content, show all the request, are there any configuration in this case
Try run the following code,
var ipp = require('ipp');
var uri = "http://192.168.0.123:631/lp1";
var data = ipp.serialize({
"operation":"Get-Printer-Attributes",
"operation-attributes-tag": {
"attributes-charset": "utf-8",
"attributes-natural-language": "en",
"printer-uri": uri
}
});
ipp.request(uri, data, function(err, res){
if(err){
return console.log(err);
}
console.log(JSON.stringify(res,null,2));
})
Got the following error,
{
"version": "1.0",
"statusCode": "server-error-version-not-supported",
"id": 0,
"operation-attributes-tag": {
"attributes-charset": "utf-8",
"attributes-natural-language": "en-us"
}
}
Please help.
Thanks a lot.
Hey guys,
I am trying to save print jobs to a custom location, but I cannot figure out where to modify the code to do so.
Would be nice if you could point me to the right direction.
I'm trying to print double sided using this code:
let msg = {
"operation-attributes-tag": {
"requesting-user-name": req.body.name + " via printerService",
"job-name": req.body.file,
// "document-format": "application/pdf" <- this doesn't work, but below does.
"document-format": "application/octet-stream",
},
"job-attributes-tag": {
"copies": "1",
"sides": "two-sided-long-edge"
},
data: data,
version: "1.1"
};
printer.execute("Print-Job", msg, (err, res) => {
console.log(err);
console.log(res);
});
However, when I run it I get the following error:
The spec is not clear on how to handle tag 16. Please open a github issue to help find a solution!
The spec is not clear on how to handle tag 16. Please open a github issue to help find a solution!
null
{ version: '1.1',
statusCode: 'successful-ok-ignored-or-substituted-attributes',
id: 42831385,
'operation-attributes-tag':
{ 'attributes-charset': 'utf-8',
'attributes-natural-language': 'en' },
'unsupported-attributes-tag': { copies: undefined, sides: undefined },
'job-attributes-tag':
{ 'job-uri': 'ipp://MY-PRINTER:631/ipp/job-79',
'job-id': 79,
'job-state': 'processing',
'job-state-reasons': 'job-printing',
'job-state-message': 'Printing...',
'number-of-intervening-jobs': 0 } }
Do you know what's causing the problem?
Thanks.
Nathan
I'm having trouble switching the orientation from portrait to landscape.
var printer = ipp.Printer(Config.get("printer.url"), Config.get('printer.options'));
var msg = {
"operation-attributes-tag": {
"requesting-user-name": "Ryan",
"document-format": "application/pdf",
},
"job-attributes-tag": {
"orientation-requested": "landscape"
},
data: Buffer.from(table, 'utf8')
};
printer.execute("Print-Job", msg, function (err, res) {
if (err) { console.log(err); }
console.log(res);
});
I am super new to this so any help would be appreciated. Thanks in advance!
Running from node js printing is done as expected.
When run from nw.js with angular (same code) does not print.
Just happened across this. Does it (or is it expected to) work inside a browser environment?
Hello,
I am trying to print images of different sizes (A4, A3 and A2) to plotter HP Designjet T520 using cups server and ipp library. There is a requirement to always print long side of the image first.
Can anyone please help with attribute which can be used to specify the same ?
I came across 'media-source-feed-direction' attribute but looks like it is not yet supported in this library.
Also 'finishing-col' seems to have impact on the prints.
It would be helpful if any attribute could be used with current version of library to print long side/short side first.
Regards,
Sonia
Hi there, I love the library and have implemented it in a little server side job which handles printing for a client.
I wanted to list the available printers to the client, which means (in my case) issuing a CUPS-Get-Printers to my server.
I've managed to make it work by doing this:
var ipp = require('ipp');
ipp.enums["operations-supported"]['CUPS-Get-Default'] = 0x4001;
ipp.enums["operations-supported"]['CUPS-Get-Printers'] = 0x4002;
and
printerList: function(uri, conn, packet)
{
var msg = {
"operation": 'CUPS-Get-Printers',
"operation-attributes-tag": {
"attributes-charset": "utf-8",
"attributes-natural-language": "en",
"printer-uri": uri
}
}
ipp.request(uri, ipp.serialize(msg), function(err, res){
var response = { 'function':'printerlist', 'module':'cups', 'result':res };
if( err )
response['error'] = err;
conn.transmit(response);
});
}
Would it be worth adding CUPS extensions to the enums.js, or is there a reason for omitting vendor extensions? Is there a "better" way to shoehorn such extensions into working with the library?
Cheers!
How i can send a jpeg/png to printer?
Hi,
I'm owning a TL-WPS510U Printserver. The Specification says, it's supporting TCP/IP, IPX/SPX, NetBEUI, AppleTalk, LPR/LPD, IPP
But I can't access it using ipp.js
đ˘
First I did try to access it using telnet
, that worked:
sunbox:~ sunbox$ telnet 192.168.1.245 631
Trying 192.168.1.245...
Connected to 192.168.1.245.
Escape character is '^]'.
Trying to access http://192.168.1.245:631/lp1
using a Browser shows this:
Than I wrote a small script:
var ipp = require('ipp');
var printer = ipp.Printer('http://192.168.1.245:631/lp1');
var msg = {
"operation-attributes-tag": {
"requesting-user-name": 'sunbox',
"job-name": 'My Test Job',
"document-format": 'text/plain'
},
data: new Buffer('Hello World!', 'utf-8')
};
printer.execute('Print-Job', msg, function (err, res) {
console.log(res);
});
which returned with the message:
sunbox:~ sunbox$ node test.js
{ version: '1.0',
statusCode: 'server-error-version-not-supported',
id: 0,
'operation-attributes-tag':
{ 'attributes-charset': 'utf-8',
'attributes-natural-language': 'en-us' } }
I changed the URI trying to get it work to these values:
var printer = ipp.Printer('http://192.168.1.245:631/lp1');
var printer = ipp.Printer('http://192.168.1.245/lp1');
var printer = ipp.Printer('ipp://192.168.1.245:631/lp1');
var printer = ipp.Printer('ipp://192.168.1.245/lp1');
which failed with the the same message. đ
Trying these:
var printer = ipp.Printer('lpd://192.168.1.245:631/lp1');
var printer = ipp.Printer('lpr://192.168.1.245:631/lp1');
failed with:
sunbox:~ sunbox$ node test.js
http.js:1840
throw new Error('Protocol:' + options.protocol + ' not supported.');
So now I'm clueless. đ How can I get ipp.js
to talk to my TL-WPS510U printserver â
var printer = ipp.Printer("http://192.168.0.123:631/lp1", {version:"1.0"});
var msg = {
"operation-attributes-tag": {
"requesting-user-name": "William",
"job-name": "My Test Job",
"document-format": "text/plain"
},
data: new Buffer("ä¸ćĺ
厚 will be garbled", "utf-8")
};
printer.execute("Print-Job", msg, function(err, res){
console.log(err);
console.log(res);
});
If data like above contains Chinese characters, the printed result will be garbled.
Please Help.
As a workaround I make changes proposed in #37 and also convert attributes.js to JSON obvious way.
Maybe some build step can be added here to also generate attributes so the package will be more compatible. I think there is no sense to refactor current attributes.js to remove those incompatible arguments.callee.name
....
Does ipp support finding the current default printer of the machine? I tried using the findPrinters example, but the printer that prints out isn't my default. I have several printers connected to my machine, and I'm able to print to my default from ipp, but it doesn't show up with the mdns example.
I got this message while requesting printer attributes from a TOSHIBA e-STUDIO 525P.
I hope it helps:
The spec is not clear on how to handle tag 18. Please open a github issue to help find a solution!
{ version: '2.0',
statusCode: 'successful-ok',
id: 5819511,
'operation-attributes-tag':
{ 'attributes-charset': 'utf-8',
'attributes-natural-language': 'en-us' },
'printer-attributes-tag':
{ 'compression-supported': [ 'none', 'gzip' ],
'charset-configured': 'utf-8',
'charset-supported': [ 'utf-8', 'us-ascii' ],
'natural-language-configured': 'en-us',
'generated-natural-language-supported': 'en-us',
'color-supported': false,
'copies-default': 1,
'copies-supported': [ 1, 999 ],
'document-format-default': 'application/octet-stream',
'document-format-supported':
[ 'application/octet-stream',
'application/pdf',
'image/jpeg',
'application/postscript',
'application/vnd.hp-PCL',
'text/plain' ],
'document-format-preferred': 'application/pdf',
'finishings-default': 'none',
'finishings-supported': 'none',
'ipp-versions-supported': [ '1.0', '1.1', '2.0' ],
'job-creation-attributes-supported':
[ 'copies',
'finishings',
'ipp-attribute-fidelity',
'job-description',
'job-id',
'job-impressions',
'job-impressions-completed',
'job-k-octets-processed',
'job-media-sheets',
'job-media-sheets-completed',
'job-name',
'job-originating-user-name',
'job-printer-up-time',
'job-printer-uri',
'job-sheets',
'job-state',
'job-state-reasons',
'job-template',
'job-uri',
'job-uuid',
'media',
'media-bottom-margin',
'media-col',
'media-left-margin',
'media-right-margin',
'media-source',
'media-top-margin',
'media-type',
'multiple-document-handling',
'number-up',
'orientation-requested',
'output-bin',
'output-mode',
'page-ranges',
'print-color-mode',
'print-quality',
'printer-resolution',
'sides',
'time-at-completed',
'time-at-creation',
'time-at-processing' ],
'job-media-sheets-supported': [ 1, 2147483647 ],
'job-sheets-default': 'none',
'job-sheets-supported': [ 'none', 'standard' ],
'job-impressions-supported': [ 1, 2147483647 ],
'jpeg-k-octets-supported': [ 0, 131072 ],
'jpeg-x-dimension-supported': [ 1, 32768 ],
'jpeg-y-dimension-supported': [ 1, 32768 ],
'landscape-orientation-requested-preferred': 4,
'marker-colors': '#000000',
'marker-low-levels': 10,
'marker-levels': 28,
'marker-high-levels': 100,
'marker-names': 'Black',
'marker-types': 'tonerCartridge',
'media-supported':
[ 'na_letter_8.5x11in',
'na_legal_8.5x14in',
'jis_b5_182x257mm',
'iso_a4_210x297mm',
'na_executive_7.25x10.5in',
'iso_a5_148x210mm',
'om_universal_216x356mm',
'na_foolscap_8.5x13in',
'na_invoice_5.5x8.5in',
'iso_a6_105x148mm',
'na_foolscap_8.5x13.4in',
'na_monarch_3.875x7.5in',
'na_number-9_3.875x8.875in',
'na_number-10_4.125x9.5in',
'iso_dl_110x220mm',
'iso_c5_162x229mm',
'iso_b5_176x250mm',
'custom_min_98.42x148mm',
'custom_max_216x356mm' ],
'media-ready': [ 'iso_a4_210x297mm', 'iso_a5_148x210mm', 'iso_a4_210x297mm' ],
'media-default': 'iso_a4_210x297mm',
'media-top-margin-default': 423,
'media-bottom-margin-default': 423,
'media-left-margin-default': 423,
'media-right-margin-default': 423,
'media-top-margin-supported': 423,
'media-bottom-margin-supported': 423,
'media-left-margin-supported': 423,
'media-right-margin-supported': 423,
'media-col-supported':
[ 'media-size',
'media-top-margin',
'media-bottom-margin',
'media-left-margin',
'media-right-margin',
'media-source',
'media-type' ],
'media-col-default':
{ 'media-size': [Object],
'media-top-margin': 423,
'media-bottom-margin': 423,
'media-left-margin': 423,
'media-right-margin': 423,
'media-source': 'tray-2',
'media-type': 'stationery' },
'media-col-ready': [ [Object], [Object], [Object] ],
'media-source-default': 'tray-2',
'media-size-supported':
[ [Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object] ],
'media-source-supported': [ 'auto', 'alternate', 'tray-1', 'tray-2', 'envelope', 'manual' ],
'media-type-default': 'stationery',
'media-type-supported':
[ 'stationery',
'cardstock',
'transparency',
'custom-media-type-recycled',
'labels',
'custom-media-type-vinyllabel',
'custom-media-type-bond',
'envelope',
'custom-media-type-roughenv',
'stationery-letterhead',
'stationery-preprinted',
'custom-media-type-coloredpaper',
'stationery-lightweight',
'stationery-heavyweight',
'custom-media-type-rough',
'custom-media-type-customtype1',
'custom-media-type-customtype2',
'custom-media-type-customtype3',
'custom-media-type-customtype4',
'custom-media-type-customtype5',
'custom-media-type-customtype6' ],
'multiple-document-handling-default': 'separate-documents-collated-copies',
'multiple-document-handling-supported':
[ 'separate-documents-uncollated-copies',
'separate-documents-collated-copies' ],
'multiple-document-jobs-supported': false,
'multiple-operation-time-out': 120,
'number-up-default': 1,
'number-up-supported': [ 1, 2, 3, 4, 6, 9, 12, 16 ],
'orientation-requested-default': 'portrait',
'orientation-requested-supported': [ 'portrait', 'landscape' ],
'output-bin-default': 'face-down',
'output-bin-supported': 'face-down',
'output-mode-default': 'monochrome',
'print-color-mode-default': 'monochrome',
'output-mode-supported': [ 'auto', 'monochrome' ],
'print-color-mode-supported': [ 'auto', 'monochrome' ],
'operations-supported':
[ 'Print-Job',
'Print-URI',
'Validate-Job',
'Create-Job',
'Send-Document',
'Cancel-Job',
'Get-Job-Attributes',
'Get-Jobs',
'Get-Printer-Attributes',
'Pause-Printer',
'Resume-Printer',
'Purge-Jobs' ],
'pdf-k-octets-supported': [ 0, 85000 ],
'page-ranges-supported': true,
'pdl-override-supported': 'attempted',
'pdf-versions-supported': 'iso-32000-1_2008',
'printer-name': 'TOSHIBA e-STUDIO525P',
'printer-make-and-model': 'TOSHIBA e-STUDIO525P',
'pages-per-minute': 55,
'printer-device-id': 'MANUFACTURER:TOSHIBA;COMMAND SET:PCL 6 Emulation, PostScript Level 3 Emulation, PDF, NPAP, PJL;MODEL:TOSHIBA e-STUDIO525P;CLS:PRINTER;DES:TOSHIBA e-STUDIO525P;CID:TOSHIBAMonoA;COMMENT:ECP1.0, LV_043D, LP_0229, LF_0084;',
'printer-dns-sd-name': 'TOSHIBA e-STUDIO525P',
'printer-geo-location': undefined,
'printer-icons':
[ 'http://192.168.1.88:80/cgi-bin/dynamic/printer/images/printer.48x48.png',
'http://192.168.1.88:80/cgi-bin/dynamic/printer/images/printer.128x128.png',
'http://192.168.1.88:80/cgi-bin/dynamic/printer/images/printer.512x512.png' ],
'printer-is-accepting-jobs': true,
'printer-info': 'Monochrome - Up to 55 Pages/Minute',
'printer-location': '',
'printer-more-info': 'http://192.168.1.88/',
'printer-state': 'idle',
'printer-state-reasons': 'none',
'printer-up-time': 2079253,
'printer-supplies-info-uri': 'http://192.168.1.88:80/',
'printer-supply-info-uri': 'http://192.168.1.88:80/',
'printer-uri-supported':
[ 'ipp://192.168.1.88:631/ipp/print',
'ipps://192.168.1.88:443/ipp/print' ],
'printer-uuid': 'urn:uuid:e25dbead-c0c2-43b4-83f5-13ec1b194a31',
'print-quality-default': 'normal',
'print-quality-supported': 'normal',
'printer-resolution-default': [ 600, 600, 'dpi' ],
'printer-resolution-supported': [ [Object], [Object], [Object] ],
'reference-uri-schemes-supported': [ 'http', 'https', 'ftp' ],
'queued-job-count': 0,
'sides-default': 'one-sided',
'sides-supported': [ 'one-sided', 'two-sided-long-edge', 'two-sided-short-edge' ],
'uri-security-supported': [ 'none', 'tls' ],
'uri-authentication-supported': [ 'none', 'none' ] } }
It would be handy if printer.execute offered a way to set request headers to accommodate authentication or other endpoint specific requirements.
When I try to serialize a dateTime type, ipptool doesn't like the format that's being sent out. My repro is here: https://github.com/fantapop/dateTime-bug-repro
Note: I'm pointing to my fork of ipp in package.json which contains a couple other dateTime bug fixes.
I think I see what's going on but not sure how you want to fix it. The code is currently encoding the sign of timezone as an Unsigned 8 bit Int. I was comparing this implementation as a reference and noticed its explicitly writing that character to the buffer as a string. https://github.com/watson/ipp-encoder/blob/master/index.js#L342
If I add something like this to the serializer:
function writeStr(str, enc){
var length = Buffer.byteLength(str);
checkBufferSize(length);
buf.write(str, position, length, enc || "utf8");
position+=length;
}
and use it to write the sign of the timezone, it works correctly. I can submit this in another pull request if you think it looks reasonable. I was unsure because there is an existing write
function which is additionally writing the length into the output which is not what is required for this case.
I hope it helps improve this amazing lib. Cheers!
This is linked to the other issues of not being able to select the tray.
var msg = { "job-attributes-tag": { "media-col": { "media-source": "tray-2" } }}
Serializes to:
'02'+ //job attributes tag
'34'+ //begin collection
'0009'+ //length
'6d656469612d636f6c'+ //media-col
'0000'+ //value length
'4a'+ //collection entry
'0000'+ //name length
'000c'+ //value length
'6d656469612d736f75726365'+ // media-source
'4a'+ // collection entry
'0000'+ //name length
'0006'+ //value length
'747261792d32'+ //tray-2
'37'+ //end of collection
'00000000'+ //name length and value length
'03'
According to the spec
The first value after the 'begCollection' value has
the attribute syntax, 'memberAttrName' (0x4A), and its value holds
the name of the first member attribute (e.g., "aaa"). The second
value holds the first member's attribute value, which can be of
any attribute syntax, except 'memberAttrName' or 'endCollection'.
The issue is that the "0x4a" tag is being applied to the second entry in the collection, but it should only be applied to the parent name. The correct message is below.
'02'+ //job attributes tag
'34'+ //begin collection
'0009'+ //length
'6d656469612d636f6c'+ //media-col
'0000'+ //value length
'4a'+ //collection entry
'0000'+ //name length
'000c'+ //value length
'6d656469612d736f75726365'+ // media-source
'44'+ // keyword tag
'0000'+ //name length
'0006'+ //value length
'747261792d32'+ //tray-2
'37'+ //end of collection
'00000000'+ //name length and value length
'03'
Please let me know if you need any additional information.
lib/operations.js was removed since it had duplicate information from lib/enums.js.
The readme should point to:
https://github.com/williamwicks/ipp/blob/master/lib/enums.js#L52
On my local terminal are workings, but when i try to do in heroku this fail.
New topic for this (started here: #3 (comment)).
Thanks for the answer @williamkapke. I started to write an interface depending on your module with two main objects Printer
and Job
.
You can get the code on http://github.com/alepee/node-ipp-interface. Project name suggestions are welcome.
We could help each other on this. I ran into the RFC, but as you surely already know it, it's not always crystal clear đ
I currently implemented most common operations (more to come):
Printer
|- constructor // get printer attributes and store your `Printer` object into `this._api`
|- createJob // return a Job object
|- getJobs // return res['job-attributes-tag']
|- pause
|- resume
Job
|- constructor // create a job and get its id, uri and state
|- send // add a new document to it
|- process // send signal to start printing it
|- hold
|- release
|- restart
|- cancel
|- refresh // get latest state of it
I think this is a good starting point, but I now deal with notifications/subscriptions and it's not really clear to me. The goal is to be able to dispatch an event on Job
object when it changes it state.
Any idea?
Hey you guys! :)
I see a lot of printers saying media-*-margin-supported = 423. I myself have one here as follow:
"media-col-default": {
"media-size": {
"x-dimension": 21000,
"y-dimension": 29700
},
"media-top-margin": 423,
"media-bottom-margin": 423,
"media-left-margin": 423,
"media-right-margin": 423,
"media-source": "auto",
"media-type": "stationery",
"duplex-supported": 0
},
"media-left-margin-supported": 423,
"media-right-margin-supported": 423,
"media-top-margin-supported": 423,
"media-bottom-margin-supported": 423,
But I have seen some throughout the Internet with different values as an array like:
'media-right-margin-supported': [428, 423, 421, 445, 406, 432, 433, 419].
OK. My question is: Does that mean the given printer supports only the specified list of values?
I wondering this because I'm trying to print a PDF with zero margin but the printer is applying 423 no matter what:
var msg = {
'operation-attributes-tag': {
'requesting-user-name': 'codezone',
'job-name': 'test',
'document-format': 'application/pdf'
},
'job-attributes-tag': {
'media-col': {
'media-source': 'tray-1',
'media-type': 'stationery',
'media-size': {
'x-dimension': 14800,
'y-dimension': 21000
},
'media-top-margin': 0,
'media-bottom-margin': 0,
'media-left-margin': 0,
'media-right-margin': 0
},
'margins-pre-applied': true,
'orientation-requested': 'portrait'
},
data: data
};
I appreciate any help.
Thanks!
Hi.
Thanks for creating this great library.
Would it be possible to provide some sample content one would receive after a "Get-Printer-Attributes" request? Perhaps an addition to the readme?
Hey,
my printer doesn't seem to support PDF. đ
My print-server's printer information tells me, it's supported printing languages are BJL, BJRaster3 and BSCCe (Canon iP5000).
Is there any chance to print on it using ipp.js
& the Bubble Jet Language (superset of the IBM ProPrinter) â
I tried this example in my electron project, but printer prints file name not content of file.
I use electron 1.4.0, node 6.7.0, ubuntu.
Any suggestions?
Thanks for this module. It seems to be exactly what I'm looking for but try as I might my stubborn Brother QL-570 refuses to emit a single label. I have tried, I really have. So far I have tried:
orientation-requested
attributemedia
attribute set to the appropriate value obtained from a Get-Printer-Attributes
callNothing's worked so far. Here's my code:
var ipp = require('ipp');
var PDFDocument = require('pdfkit');
var bufs = [];
var doc = new PDFDocument({
size: [175.691, 283.436], // 100 x 62 mm in 'PDF points'
margin:0,
layout: 'landscape'
});
doc.text("Hello world", 0, 0);
doc.on('data', function(chunk) { bufs.push(chunk); });
doc.on('end', function() {
var pdf = Buffer.concat(bufs);
var printer = ipp.Printer("ipp://localhost/printers/Brother_QL_570");
var msg = {
"operation-attributes-tag": {
"requesting-user-name": "Andrew",
"job-name": "Test",
"document-format": "application/pdf"
},
"job-attributes-tag":{
"copies": 1,
"sides": "one-sided",
"media": "om_62mm_61.98x99.99mm",
"orientation-requested": "landscape"
},
"data": pdf
};
printer.execute("Print-Job", msg, function(err, res){
console.log(res);
});
});
doc.end();
I get a success response, but when I run a Get-Job-Attributes
on it, the output includes:
'job-state': 'processing',
'job-state-reasons': 'job-printing',
'job-media-sheets-completed': 32767,
'job-k-octets': 1,
'job-hold-until': 'no-hold',
'job-sheets': [ 'none', 'none' ],
'job-printer-state-message': 'Sending data to printer.',
'job-printer-state-reasons': 'com.brother-paper-size-error'
My use case is printing name badges for a tech meetup - I'd like them to be printed automatically when people are checked in using Eventbrite. I have the whole system working except this bit. I'm sur eyou have better things to do but if you have any advice I'd really appreciate it.
Somehow I used tabs when I created these files and it's really annoying haha. Sorry everyone.
I'd prefer to just use https://www.npmjs.com/package/standard
PR that converts everything would be AMAZING!
Re-open issue #12
This line https://github.com/williamkapke/ipp/blob/master/lib/parser.js#L131
Was:
case tags.novalue:
Should be:
case tags["no-value"]:
See output from: lpstat implemented in JavaScript
I think my printer wants the y-dimension [ 1270, 100000 ].
But I can't set an array as x-/y-dimension, it will be converted to integer 0.
You can find the complete output for get-Attributes below.
I can send the print-job the printer returns "successful-ok" but the job stays with processing & reason job-incoming
Maybe I make something else wrong.
It's a Brother QL-720NW thermal printer with a 62mm roll as medium.
My Print attributes are:
"finishings": "trim-after-pages",
"media": "roll_max_62x1000mm",
"media-col": {
"media-type": "roll",
"media-size": {
"x-dimension": 6200,
"y-dimension": 10000
},
"media-bottom-margin": 303,
"media-left-margin": 154,
"media-right-margin": 154,
"media-top-margin": 303
}
}
Any tips?
{
"version": "2.0",
"statusCode": "successful-ok",
"id": 91460598,
"operation-attributes-tag": {
"attributes-charset": "utf-8",
"attributes-natural-language": "en-us"
},
"printer-attributes-tag": {
"copies-default": 1,
"finishings-default": "trim-after-pages",
"media-default": "om_brother-label-29x90mm_29x90mm",
"media-col-default": {
"media-type": "labels",
"media-size": {
"x-dimension": 2900,
"y-dimension": 9000
},
"media-bottom-margin": 303,
"media-left-margin": 154,
"media-right-margin": 154,
"media-top-margin": 303,
"media-source": "main",
"media-source-properties": {
"media-source-feed-direction": "short-edge-first",
"media-source-feed-orientation": 3
}
},
"orientation-requested-default": "portrait",
"output-bin-default": "face-down",
"output-mode-default": "monochrome",
"print-quality-default": "normal",
"printer-resolution-default": [
300,
300,
"dpi"
],
"sides-default": "one-sided",
"print-color-mode-default": "auto",
"print-content-optimize-default": "auto",
"copies-supported": [
1,
1
],
"finishings-supported": [
"none",
"trim",
"trim-after-pages",
"trim-after-job"
],
"media-supported": [
"om_brother-label-29x90mm_29x90mm",
"om_brother-label-38x90mm_38x90mm",
"om_brother-label-29x62mm_29x62mm",
"om_brother-label-62x100mm_62x100mm",
"om_brother-label-17x54mm_17x54mm",
"om_brother-label-17x87mm_17x87mm",
"om_brother-label-58x58mm_58x58mm",
"om_brother-label-29x42mm_29x42mm",
"om_brother-label-29x52mm_29x52mm",
"om_brother-label-23x23mm_23x23mm",
"om_brother-label-39x48mm_39x48mm",
"om_brother-label-12x12mm_12x12mm",
"om_brother-label-24x24mm_24x24mm",
"om_brother-label-33x48mm_32.9x47.62mm",
"om_brother-label-60x86mm_60x86mm",
"roll_min_12x12.7mm",
"roll_max_62x1000mm",
"custom_min_12x12.7mm",
"custom_max_62x1000mm"
],
"media-col-supported": [
"media-type",
"media-size",
"media-top-margin",
"media-left-margin",
"media-right-margin",
"media-bottom-margin",
"media-source"
],
"orientation-requested-supported": "portrait",
"output-bin-supported": "face-down",
"output-mode-supported": [
"monochrome",
"auto",
"auto-monochrome"
],
"print-quality-supported": [
"normal",
"high"
],
"printer-resolution-supported": [
300,
300,
"dpi"
],
"sides-supported": "one-sided",
"print-color-mode-supported": [
"monochrome",
"auto",
"auto-monochrome"
],
"print-content-optimize-supported": "auto",
"generated-natural-language-supported": "en",
"printer-uri-supported": "ipp://192.168.2.25/ipp/print",
"uri-security-supported": "none",
"uri-authentication-supported": "none",
"printer-name": "en\u001eBRN008077585105",
"printer-location": "en\u001e",
"printer-info": "en\u001eBrother QL-720NW",
"printer-make-and-model": "en\u001eBrother QL-720NW",
"printer-state": "idle",
"printer-state-reasons": "none",
"ipp-versions-supported": [
"1.0",
"1.1",
"2.0"
],
"operations-supported": [
"Print-Job",
"Validate-Job",
"Create-Job",
"Send-Document",
"Cancel-Job",
"Get-Job-Attributes",
"Get-Jobs",
"Get-Printer-Attributes"
],
"multiple-document-jobs-supported": false,
"multiple-operation-time-out": 150,
"natural-language-configured": "en",
"charset-configured": "utf-8",
"charset-supported": "utf-8",
"document-format-supported": [
"application/octet-stream",
"image/urf"
],
"document-format-default": "application/octet-stream",
"printer-is-accepting-jobs": true,
"queued-job-count": 0,
"pdl-override-supported": "attempted",
"printer-up-time": 14434,
"compression-supported": "none",
"color-supported": false,
"job-creation-attributes-supported": [
"copies",
"finishings",
"ipp-attribute-fidelity",
"job-name",
"media",
"media-col",
"orientation-requested",
"output-bin",
"output-mode",
"print-quality",
"printer-resolution",
"requesting-user-name",
"sides",
"print-color-mode"
],
"landscape-orientation-requested-preferred": 4,
"marker-colors": "en\u001e#000000",
"marker-high-levels": 100,
"marker-levels": 100,
"marker-low-levels": 10,
"marker-names": "en\u001eThermal",
"marker-types": "unknown",
"media-bottom-margin-supported": [
303,
154,
288,
202,
262,
303
],
"media-left-margin-supported": [
154,
303,
288,
202,
154,
202
],
"media-right-margin-supported": [
154,
303,
288,
202,
154,
202
],
"media-source-supported": "main",
"media-top-margin-supported": [
303,
154,
288,
202,
262,
303
],
"media-type-supported": [
"labels",
"roll"
],
"media-size-supported": [
{
"x-dimension": 2900,
"y-dimension": 9000
},
{
"x-dimension": 3800,
"y-dimension": 9000
},
{
"x-dimension": 2900,
"y-dimension": 6200
},
{
"x-dimension": 6200,
"y-dimension": 10000
},
{
"x-dimension": 1700,
"y-dimension": 5400
},
{
"x-dimension": 1700,
"y-dimension": 8700
},
{
"x-dimension": 5800,
"y-dimension": 5800
},
{
"x-dimension": 2900,
"y-dimension": 4200
},
{
"x-dimension": 2900,
"y-dimension": 5200
},
{
"x-dimension": 2300,
"y-dimension": 2300
},
{
"x-dimension": 3900,
"y-dimension": 4800
},
{
"x-dimension": 1200,
"y-dimension": 1200
},
{
"x-dimension": 2400,
"y-dimension": 2400
},
{
"x-dimension": 3290,
"y-dimension": 4762
},
{
"x-dimension": 6000,
"y-dimension": 8600
},
{
"x-dimension": [
1200,
6200
],
"y-dimension": [
1270,
100000
]
},
{
"x-dimension": [
1200,
6200
],
"y-dimension": [
1270,
100000
]
},
{
"x-dimension": [
1200,
6200
],
"y-dimension": [
1270,
100000
]
}
],
"pages-per-minute": 93,
"pdf-versions-supported": "none",
"printer-device-id": "en\u001eMFG:Brother;CMD:PJL;MDL:QL-720NW;CLS:PRINTER;URF:V1.3,W8,CP1,IS1,MT1-8-11,OB10,PQ4-5,RS300,FN3-11-60-63;",
"printer-icons": [
"http://192.168.2.25/ipp/printer-icons-128.png",
"http://192.168.2.25/ipp/printer-icons-512.png"
],
"printer-more-info": "http://192.168.2.25/bio/brairprint.html",
"printer-uuid": "urn:uuid:e3248000-80ce-11db-8000-008077585105",
"urf-supported": [
"V1.3",
"W8",
"CP1",
"IS1",
"MT1-8-11",
"OB10",
"PQ4-5",
"RS300",
"FN3-11-60-63"
],
"job-impressions-supported": [
1,
99
],
"printer-dns-sd-name": "en\u001eBrother QL-720NW",
"printer-supply-info-uri": "http://192.168.2.25/general/status.html",
"media-ready": "roll_current_62x0mm",
"media-col-ready": {
"media-type": "roll",
"media-size": {
"x-dimension": 6200,
"y-dimension": [
1270,
100000
]
},
"media-bottom-margin": 303,
"media-left-margin": 154,
"media-right-margin": 154,
"media-top-margin": 303,
"media-source": "main",
"media-source-properties": {
"media-source-feed-direction": "short-edge-first",
"media-source-feed-orientation": 3
}
},
"printer-kind": [
"label",
"roll"
],
"ipp-features-supported": "airprint-1.3"
}
}
This succeeds:
var ipp = require('ipp')
var printer = ipp.Printer('http://192.168.1.123:631/ipp/printer')
var msg = {
"operation-attributes-tag": {
"requested-attributes": [
"queued-job-count",
"marker-levels",
"printer-state",
"printer-state-reasons",
"printer-up-time"
]
}
}
printer.execute("Get-Printer-Attributes", msg, console.log)
Output:
null { version: '2.0',
statusCode: 'successful-ok',
id: 99864674,
'operation-attributes-tag':
{ 'attributes-charset': 'utf-8',
'attributes-natural-language': 'nl' },
'printer-attributes-tag':
{ 'queued-job-count': 0,
'marker-levels': [ 100, 100, 99, 89 ],
'printer-state': 'idle',
'printer-state-reasons': 'none',
'printer-up-time': 1365091 } }
But when I add marker-names
the decoding fails:
var ipp = require('ipp')
var printer = ipp.Printer('http://192.168.1.123:631/ipp/printer')
var msg = {
"operation-attributes-tag": {
"requested-attributes": [
"queued-job-count",
"marker-names", // <-- this one
"marker-levels",
"printer-state",
"printer-state-reasons",
"printer-up-time"
]
}
}
printer.execute("Get-Printer-Attributes", msg, console.log)
Output:
null { version: '2.0',
statusCode: 'successful-ok',
id: 94819212,
'operation-attributes-tag':
{ 'attributes-charset': 'utf-8',
'attributes-natural-language': 'nl' },
'printer-attributes-tag':
{ 'queued-job-count': 0,
'marker-names': '\u0000\u0002en\u0000\u0015Magenta Ink Cartridge\u001e\u0000\u0000\u0018\u0000\u0002en\u0000\u0012Cyan Ink Cartridge6\u0000\u0000\u0000\u001a\u0000\u0002en\u0000\u0014Yellow Ink Cartridge6\u0000\u0000\u0000\u0019\u0000\u0002en\u0000\u0013Black Ink Cartridge!\u0000\rmarker-levels\u0000\u0004\u0000\u0000\u0000d!\u0000\u0000\u0000\u0004\u0000\u0000\u0000d!\u0000\u0000\u0000\u0004\u0000\u0000\u0000c!\u0000\u0000\u0000\u0004\u0000\u0000\u0000Y#\u0000\rprinter-state\u0000\u0004\u0000\u0000\u0000\u0003D\u0000\u0015printer-state-reasons\u0000\u0004none!\u0000\u000fprinter-up-time\u0000\u0004\u0000\u0014�M\u0003' } }
Hi,
Many of the printers that I am trying to connect to do not have support for the document-format "application/pdf". However, they all list the following document-formats as supported: "application/vnd.hp-PCL" and "application/octet-stream".
How I can print a PDF using IPP when the printer does not support application/pdf?
I have already tried switching the document-format to one of the supported options, but it does not print the expected output. Instead it prints some gibberish, and what looks like styling code.
var ipp = require('ipp');
var PDFDocument = require('pdfkit');
//make a PDF document
var buffers = [];
var doc = new PDFDocument();
doc.fontSize(14);
doc.text("THIS IS A TEST PRINT JOB", 10, 10);
doc.on('data', buffers.push.bind(buffers));
doc.on('end', function() {
var printer = ipp.Printer("http://myprinter/ipp");
var msg = {
"version": 1.1,
"operation-attributes-tag": {
"requesting-user-name": "testuser",
"job-name": "Test7",
// "document-format": "application/octet-stream"
"document-format": "application/vnd.hp-PCL"
},
data: new Buffer(Buffer.concat(buffers))
};
printer.execute("Print-Job", msg, function(err, res) {
console.log('Err: ' + JSON.stringify(err));
console.log('Res: ' + JSON.stringify(res));
});
});
doc.end();
Thanks
Hi, how do I pass username/password for Authentication? I tried http://username:[email protected]/ipp but it rejected with invalid login. Not sure if there is another way. Thank you.
I'm working with a printer with multiple media trays and so I'd like to select one according to the paper size. Is it possible?
Thanks!
-- pretty good lib btw ;)
found this while trying get my printer attributes printer.execute("Get-Printer-Attributes", null, function(err, res) { console.log(res); })
name: 'IppResponseError',
statusCode: 403,
message: 'Received unexpected response status 403 from the printer',
stack:
'Error\n at new IppResponseError (/Users/baojia/Desktop/ćĺ°/ipp-master/lib/request.js:72:17)\n at ClientRequest. (/Users/baojia/Desktop/ćĺ°/ipp-master/lib/request.js:40:8)\n at Object.onceWrapper (events.js:273:13)\n at ClientRequest.emit (events.js:182:13)\n at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:546:21)\n at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)\n at Socket.socketOnData (_http_client.js:432:20)\n at Socket.emit (events.js:182:13)\n at addChunk (_stream_readable.js:283:12)\n at readableAddChunk (_stream_readable.js:264:11)' }
I keep getting this when requiring mdns:
Unexpected result while probing for avahi: [TypeError: argument 3 must be an integer (interfaceIndex)]
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointer.de/avahi-compat?s=libdns_sd&e=node
I don't know what is wrong tbh!
Hi guys, I'm working with a Lexmark MS911de printer, which provides me these media-supported and media-size-supported options below.
Problem is, I have to print to a 320x600mm, which is not listed below. It is what we call in Brazil "Super A3" and it is very common in visual merchandising at supermarkets and the likes.
I can print a 320x600mm PDF to this printer from Adobe Reader or Google Chrome with no problem using the installed printer driver (as for troubleshooting purpose). But I cannot thru ipp lib. It prints out a "The spec is not clear on how to handle tag 16: media-size=undefined." message, finishes the request with status code "successful-ok-ignored-or-substituted-attributes", and prints and error message to the actual paper.
The request is like:
{
"operation-attributes-tag": {
"requesting-user-name": "john",
"job-name": "sa3h.pdf",
"document-format": "application/pdf"
},
"job-attributes-tag": {
"media-col": {
"media-source": "manual",
"media-size": {
"x-dimension": "60000",
"y-dimension": "32000"
}
},
"orientation-requested": "landscape"
},
"data": "..."
}
And the response is what follows:
{
"version": "2.0",
"statusCode": "successful-ok-ignored-or-substituted-attributes",
"id": 41886823,
"operation-attributes-tag": {
"attributes-charset": "utf-8",
"attributes-natural-language": "en-us"
},
"unsupported-attributes-tag": {},
"job-attributes-tag": {
"job-uri": "ipp://10.124.59.191:631/print/job97",
"job-id": 97,
"job-state": "pending",
"job-state-reasons": "none",
"job-state-message": "none"
}
}
Any idea on how I can manage to print this 320x600mm PDF thru ipp lib?
Many many thanks, guys.
"media-supported": [
"na_letter_8.5x11in",
"jis_b4_257x364mm",
"jis_b5_182x257mm",
"na_monarch_3.875x7.5in",
"na_number-9_3.875x8.875in",
"na_number-10_4.125x9.5in",
"na_arch-b_12x18in",
"na_ledger_11x17in",
"iso_a3_297x420mm",
"iso_a4_210x297mm",
"iso_a5_148x210mm",
"na_foolscap_8.5x13in",
"na_invoice_5.5x8.5in",
"na_oficio_8.5x13.4in",
"iso_a6_105x148mm",
"om_universal_320x432mm",
"iso_sra3_320x450mm",
"na_legal_8.5x14in",
"iso_b5_176x250mm",
"iso_c5_162x229mm",
"iso_dl_110x220mm",
"na_executive_7.25x10.5in",
"custom_min_76.2x123.86mm",
"custom_max_215.9x1320.8mm"
],
"media-size-supported": [
{
"x-dimension": 21590,
"y-dimension": 27940
},
{
"x-dimension": 25700,
"y-dimension": 36400
},
{
"x-dimension": 18200,
"y-dimension": 25700
},
{
"x-dimension": 9842,
"y-dimension": 19050
},
{
"x-dimension": 9842,
"y-dimension": 22542
},
{
"x-dimension": 10477,
"y-dimension": 24130
},
{
"x-dimension": 30480,
"y-dimension": 45720
},
{
"x-dimension": 27940,
"y-dimension": 43180
},
{
"x-dimension": 29700,
"y-dimension": 42000
},
{
"x-dimension": 21000,
"y-dimension": 29700
},
{
"x-dimension": 14800,
"y-dimension": 21000
},
{
"x-dimension": 21590,
"y-dimension": 33020
},
{
"x-dimension": 13970,
"y-dimension": 21590
},
{
"x-dimension": 21590,
"y-dimension": 34036
},
{
"x-dimension": 10500,
"y-dimension": 14800
},
{
"x-dimension": 32000,
"y-dimension": 43200
},
{
"x-dimension": 32000,
"y-dimension": 45000
},
{
"x-dimension": 21590,
"y-dimension": 35560
},
{
"x-dimension": 17600,
"y-dimension": 25000
},
{
"x-dimension": 16200,
"y-dimension": 22900
},
{
"x-dimension": 11000,
"y-dimension": 22000
},
{
"x-dimension": 18415,
"y-dimension": 26670
},
{
"x-dimension": [
7620,
21590
],
"y-dimension": [
12386,
132080
]
}
],
can i use uri = "socket://192.168.0.250" ??
i use linux and i use CUPS print test page is ok
but i want use your ipp it don't work
how can i do ???
my printer is use raw (PD3160 or TM88)
Hey,
I just came here 'cause I was looking for a solution to print from a web application directly to a (network) printer and it seems that IPP is the way to go. Unfortunately I'm not using Node.js as a backend and therefore I wonder if it's possible to use your library in the frontend as well? Would it be possible to pack it so that it could be installed through Bower or something like that?
Am I right that "the only thing you have to do" is to get a build tool like Grunt
or something to pull in all files from the lib
folder and compile it to one ipp.js
file? If so, how would I set up Grunt
to do this properly and build a file which I can use in the frontend as well?
Would be cool if you could give me some advice here as I'm really stuck at the moment :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
đ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. đđđ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google â¤ď¸ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.