Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
digibib
kohaprinter
Commits
a648bca2
Commit
a648bca2
authored
Feb 06, 2018
by
Benjamin Rokseth
Browse files
Initial commit
parents
Changes
5
Hide whitespace changes
Inline
Side-by-side
.gitignore
0 → 100644
View file @
a648bca2
kohaprinter
kohaprinter_mapping.json
README.md
0 → 100644
View file @
a648bca2
Kohaprinter
==
A Cups Backend and printer delegator for use in Koha Intra and other services attached.
Purpose is to generate a simple connection between browser and thermal printers connected
in local network, so that you can print any HTML slip or label to a printer in the network.
Requirements
==
To build backend: golang
*
wkhtmltopdf (webkit html to pdf renderer) for rastering html
must be placed in /usr/bin on the cups server
https://github.com/wkhtmltopdf/wkhtmltopdf/releases
*
compiled backend (kohaprinter) must be placed in /usr/lib/cups/backend/ on the cups server
*
a json mapping file (see example) must be placed in same directory as backend and named kohaprinter_mapping.json
*
Cups is strict on permissions, so make sure backend is owned by root and chmod 0755
*
also beware that backend is run by user
`lp`
so main log turns up in /tmp/kohaprinter.log and
spool logs and output in /var/spool/cups/
Setup and Testing
==
## 1. In Cups, a Raw Print Queue must be set up to point to backend.
Make sure the Device URI corresponds with the backend, (kohaprinter), as this is picked up automagically by Cups
e.g.
```
lpadmin -p KohaKvittPrinter -v kohaprinter:/kvitt -m raw -E
```
This means any job sent to this Queue on this Cups server will be passed along to the
`kohaprinter`
backend
with the kohaprinter:/kvitt Device URI. Likewise a
`kohaprinter:/label`
queue could be made to handle label printing.
If the Cups server was running on host, say,
`cupsserver`
, the queue would now be accessible as normal by Cups, e.g.
```
ipps://cupsserver/printers/KohaKvittPrinter
```
## 2. The Client Printer must be mapped to correct network printer
On cups server: (See the example mapping file for examples)
/usr/lib/cups/backend/kohaprinter_mapping.json:
```
{
"cupsclient": {
"name": "a koha staff client",
"kvittering": "lab-kvitt-10"
}
}
```
## 3. The Client Must be configured with a Raw printer
Setup a Raw Printer to the Queue created in #1
Eg. in linux:
```
lpadmin -p IppKohaKvitt -v ipps://cupsserver/printers/KohaKvittPrinter8 -m raw -E
```
Now you should be able to print any html to the receipt printer. Eg. in linux:
```
lp -d IppKohaKvitt -o document-format=text/html test.html
```
Behind the scenes
==
What happens is that :
*
html document is sent raw to the Remote Print Queue KohaKvittPrinter
*
it is delegated to the kohaprinter backend which :
*
fetches originating IP and DeviceURI from request
*
rasters the html document to PDF with Webkit
*
forwards generated PDF to Print Queue of Thermal Printer found in json mapping
kohaprinter.go
0 → 100644
View file @
a648bca2
package
main
import
(
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
wkhtml
"github.com/SebastiaanKlippert/go-wkhtmltopdf"
)
type
Printer
struct
{
Name
,
Kvittering
,
Etikett
string
}
var
(
Log
*
log
.
Logger
)
/*
* Prerequisites:
* wkhtmltopdf binary MUST be downloaded to /usr/bin
* this file needs to be chown root and chmod 755 executable in /usr/lib/cups/backend/
* job needs job-originating-host-name
* kohaprint.json mapping must exist beside this file
*/
func
main
()
{
lfile
,
err
:=
os
.
Create
(
"/tmp/kohaprint.log"
)
if
err
!=
nil
{
fail
(
err
)
}
Log
=
log
.
New
(
lfile
,
""
,
log
.
LstdFlags
|
log
.
Lshortfile
)
var
mapping
map
[
string
]
Printer
cfgFile
,
err
:=
os
.
Open
(
"/usr/lib/cups/backend/kohaprinter_mapping.json"
)
defer
cfgFile
.
Close
()
if
err
!=
nil
{
fail
(
err
)
}
dec
:=
json
.
NewDecoder
(
cfgFile
)
dec
.
Decode
(
&
mapping
)
Log
.
Printf
(
"[INFO ] MAPPING: %v"
,
mapping
)
// No args? Return status line as cups expects this to discover backend
if
len
(
os
.
Args
)
==
1
{
fmt
.
Println
(
"network kohaprint
\"
Unknown
\"
\"
Print any job to queue specified in device-URI
\"
"
)
os
.
Exit
(
0
)
}
else
if
len
(
os
.
Args
)
<
6
{
fmt
.
Println
(
"Usage: kohaprint job-id user title copies options [file]"
)
os
.
Exit
(
0
)
}
opts
:=
os
.
Args
[
5
]
Log
.
Printf
(
"[INFO ] OPTS: %s"
,
opts
)
h
:=
getOriginHostName
(
opts
)
if
h
==
""
{
fail
(
errors
.
New
(
"Missing params: job-originating-host-name"
))
}
if
_
,
ok
:=
mapping
[
h
];
!
ok
{
fail
(
errors
.
New
(
"Originating Host IP missing from mapping file"
))
}
pdfg
,
err
:=
wkhtml
.
NewPDFGenerator
()
if
err
!=
nil
{
fail
(
err
)
}
// Read job data from stdin
data
,
err
:=
ioutil
.
ReadAll
(
os
.
Stdin
)
if
err
!=
nil
{
fail
(
err
)
}
Log
.
Printf
(
"[INFO ] DATA: %s"
,
data
)
pdfg
.
AddPage
(
wkhtml
.
NewPageReader
(
strings
.
NewReader
(
string
(
data
))))
err
=
pdfg
.
Create
()
if
err
!=
nil
{
fail
(
err
)
}
tmpf
,
err
:=
ioutil
.
TempFile
(
""
,
"kohaprintpdf"
)
if
err
!=
nil
{
fail
(
err
)
}
defer
os
.
Remove
(
tmpf
.
Name
())
if
_
,
err
:=
tmpf
.
Write
(
pdfg
.
Bytes
());
err
!=
nil
{
fail
(
err
)
}
if
err
:=
tmpf
.
Close
();
err
!=
nil
{
fail
(
err
)
}
args
:=
[]
string
{
"-d"
,
mapping
[
h
]
.
Kvittering
,
tmpf
.
Name
()}
Log
.
Printf
(
"[INFO ] ARGS: %s
\n
"
,
args
)
out
,
err
:=
exec
.
Command
(
"lp"
,
args
...
)
.
Output
()
if
err
!=
nil
{
Log
.
Printf
(
"[INFO ] CMD OUTPUT: %s
\n
"
,
out
)
fail
(
err
)
}
os
.
Exit
(
0
)
}
func
getOriginHostName
(
opts
string
)
string
{
arr
:=
strings
.
Split
(
opts
,
" "
)
for
_
,
a
:=
range
arr
{
p
:=
strings
.
Split
(
a
,
"="
)
if
p
[
0
]
==
"job-originating-host-name"
{
return
p
[
1
]
}
}
return
""
}
func
fail
(
err
error
)
{
Log
.
Printf
(
"[ERROR] %s"
,
err
.
Error
())
os
.
Exit
(
1
)
}
kohaprinter_mapping_example.json
0 → 100644
View file @
a648bca2
{
"10.172.2.10"
:
{
"name"
:
"a test client"
,
"kvittering"
:
"printer-thermal-in-cups"
},
"10.172.2.11"
:
{
"name"
:
"another client"
,
"kvittering"
:
"another-thermal-printer-in-cups"
,
"etikett"
:
"label-printer-in-cups"
}
}
\ No newline at end of file
test.html
0 → 100644
View file @
a648bca2
<!DOCTYPE html>
<html><body><h1>
It actually works!
</h1>
<p>
Give me a
<strong>
Bloody Beer!
</strong></p>
<pre>
/######\
/##########\
/ \###/ \
/ \#/ \
/\| |/\
| | \ ==\ /== / | |
\| \
<
|
>
\ /
<
|
>
/ |/ /|
\__ | - \ - | /#|
\#\ | | | /###|
\##\ | \| | /#####|
\###\ | _______ | /######|
\####\ | / \/ \/ \|/#######|
|######\| |#########|
|########\______/##########|
|#########\ /##########/
|##########\ |#########/\
/###########\/########/###\
/################\######/########\
/##################\###/###########\
/###################\#/##############\
/####################/#################\
/###################/####################\
</pre>
</body></html>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment