forked from racingmars/virtual1403
-
Notifications
You must be signed in to change notification settings - Fork 0
/
online.go
123 lines (106 loc) · 3.27 KB
/
online.go
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
package main
// Copyright 2021 Matthew R. Wilson <mwilson@mattwilson.org>
//
// This file is part of virtual1403
// <https://github.com/racingmars/virtual1403>.
//
// virtual1403 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// virtual1403 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with virtual1403. If not, see <https://www.gnu.org/licenses/>.
import (
"bufio"
"bytes"
"io"
"log"
"net/http"
"github.com/klauspost/compress/zstd"
"github.com/racingmars/virtual1403/scanner"
)
type onlineOutputHandler struct {
buf bytes.Buffer
enc *zstd.Encoder
w *bufio.Writer
api string
key string
profile string
inputName string
}
func newOnlineOutputHandler(api, key, profile,
inputName string) scanner.PrinterHandler {
o := &onlineOutputHandler{
api: api,
key: key,
profile: profile,
inputName: inputName,
}
o.enc, _ = zstd.NewWriter(&o.buf)
o.w = bufio.NewWriter(o.enc)
if o.profile == "" {
o.profile = "default"
}
return o
}
func (o *onlineOutputHandler) AddLine(line string, linefeed bool) {
command := "L:"
if !linefeed {
command = "O:"
}
o.w.WriteString(command + line + "\n")
}
func (o *onlineOutputHandler) PageBreak() {
o.w.WriteString("P:\n")
}
func (o *onlineOutputHandler) EndOfJob(jobinfo string) {
o.w.WriteString("J:" + jobinfo + "\n")
// No matter what happens, we always want to reset our state to a fresh
// new job.
defer func() {
// We could use Buffer.Reset(), but if this was a particularly large
// job, there's no reason for us to hold on to that much allocated
// memory indefinitely. All things considered, this is a low-volume
// application to paying for the allocation of a new buffer slice
// isn't going to have a noticable performance penalty.
o.buf = bytes.Buffer{}
o.enc, _ = zstd.NewWriter(&o.buf)
o.w = bufio.NewWriter(o.enc)
}()
o.w.Flush()
o.enc.Close()
// We now have a complete zstd-compressed job stream in o.buf.
req, err := http.NewRequest(http.MethodPost,
o.api+"?profile="+o.profile, &o.buf)
if err != nil {
log.Printf("ERROR: [%s] unable to create HTTP request: %v",
o.inputName, err)
return
}
req.Header.Set("Content-Encoding", "zstd")
req.Header.Set("Content-Type", "text/x-print-job")
req.Header.Set("Authorization", "Bearer "+o.key)
log.Printf("INFO: [%s] Sending print job to online print API...",
o.inputName)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Printf("ERROR: [%s] unable to execute HTTP request: %v",
o.inputName, err)
return
}
defer resp.Body.Close()
defer io.ReadAll(resp.Body) // ensure keep-alive client reuse when able
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
log.Printf("INFO: [%s] Print API response status: %s", o.inputName,
resp.Status)
} else {
log.Printf("ERROR: [%s] Print API response status: %s", o.inputName,
resp.Status)
}
}