Skip to content

Commit fd8993f

Browse files
author
fansinatingRu
committed
initial commit
0 parents  commit fd8993f

27 files changed

+10490
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
.DS_Store
3+
node_modules
4+
scratch.js

README.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Internet Printing Protocol (IPP) for nodejs
2+
---
3+
4+
A pure Javascript implementation of the IPP/2.0 protocol that has no dependencies.
5+
6+
The IPP protocol was started in the 90's and is still being worked on today. It is a very indepth protocol that spans many
7+
RFCs- some of which are dead while others were herded into IPP/v2.x.
8+
9+
There are millions of printers that support IPP. If you have one, this module will allow you to send/recieve data to/from
10+
the printer.
11+
12+
To find out if your printer supports IPP:
13+
14+
* Google your printer's specs
15+
* Try: `telnet YOUR_PRINTER 631`. If it connects, that's a good sign.
16+
* Use the ['/examples/findPrinters.js'](https://github.com/williamkapke/ipp/tree/master/examples/findPrinters.js) script.
17+
18+
I have a pretty good starting point here. I created reference files
19+
(`attributes`, `enums`, `keywords`, `operations`, `status-codes`, `versions` and `tags`) and tried to include as many
20+
links in the comments to the ref docs as I could.
21+
22+
23+
### Install
24+
```bash
25+
$ npm install ipp
26+
```
27+
28+
29+
## Printer(url [,options])
30+
```javascript
31+
var ipp = require('ipp');
32+
var PDFDocument = require('pdfkit');
33+
34+
//make a PDF document
35+
var doc = new PDFDocument({margin:0});
36+
doc.text(".", 0, 780);
37+
38+
doc.output(function(pdf){
39+
var printer = ipp.Printer("http://NPI977E4E.local.:631/ipp/printer");
40+
var msg = {
41+
"operation-attributes-tag": {
42+
"requesting-user-name": "William",
43+
"job-name": "My Test Job",
44+
"document-format": "application/pdf"
45+
},
46+
data: pdf
47+
};
48+
printer.execute("Print-Job", msg, function(err, res){
49+
console.log(res);
50+
});
51+
});
52+
```
53+
54+
To interact with a printer, create a `Printer` object.
55+
56+
> Technically speaking: a `Printer` object does not need to be an actual printer. According to the IPP spec, it
57+
> could be any endpoint that accepts IPP messages. For example; the IPP object __could__ be persistant media- like a
58+
> CD ROM, hard drive, thumb drive, ...etc.
59+
60+
**options:**
61+
* `charset` - Specifies the value for the 'attributes-charset' attribute of requests. Defaults to `utf-8`.
62+
* `language` - Specifies the value for the 'attributes-natural-language' attribute of requests. Defaults to `en-us`.
63+
* `uri` - Specifies the value for the 'printer-uri' attribute of requests. Defaults to `ipp://+url.host+url.path`.
64+
* `version` - Specifies the value for the 'version' attribute of requests. Defaults to `2.0`.
65+
66+
67+
68+
69+
70+
### printer.execute(operation, message, callback)
71+
Executes an IPP operation on the Printer object.
72+
73+
* 'operation' - There are many operations defined by IPP. See: [/lib/enums.js](https://github.com/williamkapke/ipp/blob/master/lib/enums.js#L52).
74+
* 'message - A javascript object to be serealized into an IPP binary message.
75+
* 'callback(err, response)' - A function to callback with the Printer's response.
76+
77+
## ipp.parse(buffer)
78+
79+
Parses a binary IPP message into a javascript object tree.
80+
81+
```javascript
82+
var ipp = require('ipp');
83+
var data = new Buffer(
84+
'0200' + //version 2.0
85+
'000B' + //Get-Printer-Attributes
86+
'00000001'+ //reqid
87+
'01' + //operation-attributes-tag
88+
//blah blah the required bloat of this protocol
89+
'470012617474726962757465732d6368617273657400057574662d3848001b617474726962757465732d6e61747572616c2d6c616e67756167650002656e' +
90+
'03' //end-of-attributes-tag
91+
,'hex');
92+
93+
94+
var result = ipp.parse(data);
95+
console.log(JSON.stringify(result,null,2));
96+
// ta-da!
97+
//{
98+
// "version": "2.0",
99+
// "operation": 11,
100+
// "id": 1,
101+
// "operation-attributes-tag": {
102+
// "attributes-charset": "utf-8",
103+
// "attributes-natural-language": "en"
104+
// }
105+
//}
106+
```
107+
108+
## ipp.serialize(msg)
109+
Converts an IPP message object to IPP binary.
110+
111+
See [request](#request) for example.
112+
113+
<a id="request"></a>
114+
## ipp.request(url, data, callback)
115+
116+
Makes an IPP request to a url.
117+
118+
```javascript
119+
var ipp = require('ipp');
120+
var uri = "your_printer";
121+
var data = ipp.serialize({
122+
"operation":"Get-Printer-Attributes",
123+
"operation-attributes-tag": {
124+
"attributes-charset": "utf-8",
125+
"attributes-natural-language": "en",
126+
"printer-uri": uri
127+
}
128+
});
129+
130+
ipp.request(uri, data, function(err, res){
131+
if(err){
132+
return console.log(err);
133+
}
134+
console.log(JSON.stringify(res,null,2));
135+
})
136+
// ta-da!.. hopefully you'll see a ton of stuff from your printer
137+
```
138+
139+
## Browser Support?
140+
See [this thread](https://github.com/williamkapke/ipp/issues/3)
141+
142+
## License
143+
144+
MIT

backend/public/dorms.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
1222222
2+
333
3+
1
4+
1
5+
1

backend/server.js

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
const express = require('express');
2+
var bodyParser = require('body-parser')
3+
const fileUpload = require('express-fileupload');
4+
const cors = require('cors')
5+
const ipp = require('../ipp.js')
6+
const mime = require('mime')
7+
const libre = require('libreoffice-convert');
8+
const fs = require('fs');
9+
10+
var extension
11+
var buffer
12+
var Printer = ipp.Printer("http://192.168.66.50:631/printers/412_printer");
13+
const officeFormat = ['application/vnd.openxmlformats-officedocument.wordprocessingml.document',
14+
'application/msword',
15+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
16+
'application/vnd.ms-excel',
17+
"application/vnd.ms-powerpoint",
18+
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
19+
]
20+
const validExtensions = ['application/pdf',
21+
'image/jpeg',
22+
'image/png'].concat(officeFormat)
23+
24+
25+
const app = express();
26+
app.use(bodyParser())
27+
// middleware
28+
app.use(express.static('public')); //to access the files in public folder
29+
app.use(cors()); // it enables all cors requests
30+
// once the file is uploaded,it can be accessed from req.files.*
31+
app.use(fileUpload({
32+
// 10MB
33+
limits: {fileSize: 10 * 1024 * 1024},
34+
}));
35+
// file upload api
36+
app.post('/upload', (req, res, next) => {
37+
38+
if (!req.files) {
39+
return res.send({msg: "file is not found"})
40+
}
41+
extension = mime.getType(req.files.file.name)
42+
if (validExtensions.indexOf(extension) === -1) {
43+
return res.send({msg: "非法文件类型!"})
44+
}
45+
buffer = req.files.file.data
46+
47+
if (officeFormat.indexOf(extension) !== -1) {
48+
// extension = 'application/pdf'
49+
ConvertDocToPdfPrint()
50+
.then(modifiedData => {
51+
var msg = {
52+
"operation-attributes-tag": {
53+
"last-document": true,
54+
"job-id": req.body['job-id'],
55+
"requesting-user-name": "normal user",
56+
// this is really problematic
57+
// "document-format": "application/octet-stream"
58+
"document-format": "application/pdf",
59+
//iso_a4_210x297mm
60+
},
61+
data: modifiedData
62+
};
63+
64+
Printer.execute("Send-Document", msg, function (err, res_) {
65+
res.send(err || res_);
66+
});
67+
})
68+
.catch(err=>{res.send({msg: `${err}服务端错误`})})
69+
}else{
70+
var msg = {
71+
"operation-attributes-tag": {
72+
"last-document": true,
73+
"job-id": req.body['job-id'],
74+
"requesting-user-name": "normal user",
75+
// this is really problematic
76+
// "document-format": "application/octet-stream"
77+
"document-format": extension,
78+
//iso_a4_210x297mm
79+
},
80+
data: buffer
81+
};
82+
83+
Printer.execute("Send-Document", msg, function (err, res_) {
84+
res.send(err || res_);
85+
});
86+
}
87+
// pass all the filter,then go to print stage
88+
})
89+
90+
91+
app.post('/query', (req, res) => {
92+
Printer.execute("Get-Printer-Attributes", null, function (err, res_) {
93+
availability = res_["printer-attributes-tag"]["printer-state"] == 'idle' && res_["printer-attributes-tag"]["printer-is-accepting-jobs"]
94+
queuedJob = res_["printer-attributes-tag"]["queued-job-count"]
95+
res.send({"status": availability, "wait": queuedJob})
96+
res.send({"status": 'fuck', "wait": 'you'})
97+
});
98+
})
99+
100+
101+
app.post('/create-job', (req, res) => {
102+
console.log('fuck')
103+
var create_msg = {
104+
"operation-attributes-tag": {
105+
"requesting-user-name": "normal user"
106+
},
107+
// fix none A4 document bug
108+
"job-attributes-tag": {
109+
"copies": req.body.copies,
110+
// this is for routing and schedualing only
111+
// "job-impressions":req.body.number,
112+
// "job-media-sheets":(req.body.copies)*(req.body.number)
113+
}
114+
};
115+
fs.appendFileSync('./public/dorms.txt',req.body.dorm+'\n',function (err) {
116+
console.log(err)
117+
})
118+
try {
119+
Printer.execute("Create-Job", create_msg, function (err, res_) {
120+
// console.log(res_)
121+
if (!("job-id" in res_['job-attributes-tag'])) {
122+
return res.status(500).send({msg: "创建任务失败,请重试"})
123+
}
124+
let jobId = res_['job-attributes-tag']['job-id'];
125+
// console.log(jobId)
126+
res.send({"job-id": jobId})
127+
});
128+
} catch (e) {
129+
res.send(e)
130+
};
131+
132+
})
133+
134+
function ConvertDocToPdfPrint() {
135+
return new Promise((resolve,reject)=> {
136+
libre.convert(buffer, '.pdf', undefined, (err, done) => {
137+
return err ?
138+
reject(err) :
139+
resolve(done)
140+
});
141+
})
142+
}
143+
144+
145+
app.listen(4500, () => {
146+
console.log('server is running at port 8080');
147+
})

examples/Get-Job-Attributes.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
var ipp = require('./../ipp');
2+
var printer = ipp.Printer("http://cp02.local.:631/ipp/printer");
3+
var msg = {
4+
"operation-attributes-tag": {
5+
'job-uri': 'ipp://CP01.local/ipp/printer/0186'
6+
}
7+
};
8+
function go(){
9+
printer.execute("Get-Job-Attributes", msg, function(err, res){
10+
console.log(res);
11+
setTimeout(go, 0);
12+
});
13+
}
14+
go();

examples/Get-Jobs.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
var ipp = require('./../ipp');
2+
var printer = ipp.Printer("ipp://cp02.local.:631/ipp/printer");
3+
4+
var msg = {
5+
"operation-attributes-tag": {
6+
//use these to view completed jobs...
7+
// "limit": 10,
8+
"which-jobs": "completed",
9+
10+
"requested-attributes": [
11+
"job-id",
12+
"job-uri",
13+
"job-state",
14+
"job-state-reasons",
15+
"job-name",
16+
"job-originating-user-name",
17+
"job-media-sheets-completed"
18+
]
19+
}
20+
}
21+
22+
printer.execute("Get-Jobs", msg, function(err, res){
23+
if (err) return console.log(err);
24+
console.log(res['job-attributes-tag']);
25+
});

examples/Get-Printer-Attributes.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var ipp = require('./../ipp');
2+
var id = 0x0123;//made up reqid
3+
4+
var printer = ipp.Printer("http://cp02.local.:631/ipp/printer");
5+
printer.execute("Get-Printer-Attributes", null, function(err, res){
6+
console.log(res);
7+
});

examples/Get-Printer-Attributes2.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
/*
3+
Poll the printer for a limited set of attributes
4+
*/
5+
6+
var ipp = require('./../ipp');
7+
var id = 0x0123;//made up reqid
8+
9+
var printer = ipp.Printer("http://cp02.local.:631/ipp/printer");
10+
var msg = {
11+
"operation-attributes-tag": {
12+
"document-format": "application/pdf",
13+
"requested-attributes": [
14+
"queued-job-count",
15+
"marker-levels",
16+
"printer-state",
17+
"printer-state-reasons",
18+
"printer-up-time"
19+
]
20+
}
21+
};
22+
function printer_info(){
23+
printer.execute("Get-Printer-Attributes", msg, function(err, res){
24+
console.log(JSON.stringify(res['printer-attributes-tag'], null, 2));
25+
setTimeout(printer_info, 1);
26+
});
27+
}
28+
printer_info();

examples/Identify-Printer.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
var ipp = require('./../ipp');
2+
var id = 0x0123;//made up reqid
3+
4+
var printer = ipp.Printer("http://cp02.local.:631/ipp/printer");
5+
var msg = {
6+
"operation-attributes-tag": {
7+
"requesting-user-name": "William",
8+
"message": "These are not the droids you are looking for"
9+
}
10+
};
11+
printer.execute("Identify-Printer", msg, function(err, res){
12+
console.log(res);
13+
});

0 commit comments

Comments
 (0)