-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
executable file
·124 lines (109 loc) · 2.84 KB
/
main.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
124
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"os/exec"
)
var addr string
var device string
var port int
func init() {
const (
defaultAddr = ""
defaultPort = 8080
addrUsage = "address for webserver to listen on"
portUsage = "port for webserver to listen on"
defaultDevice = ""
deviceUsage = "device used for scanning"
)
flag.StringVar(&addr, "address", defaultAddr, addrUsage)
flag.StringVar(&addr, "a", defaultAddr, addrUsage+" (shorthand)")
flag.IntVar(&port, "port", defaultPort, portUsage)
flag.IntVar(&port, "p", defaultPort, portUsage+" (shorthand)")
flag.StringVar(&device, "device", defaultDevice, deviceUsage)
flag.StringVar(&device, "d", defaultDevice, deviceUsage+" (shorthand)")
}
func main() {
// Parse command line flags and validate them.
flag.Parse()
if device == "" {
log.Fatalln("You must specify a device to scan from.")
}
log.Printf("Starting webserver on %s:%d...", addr, port)
http.HandleFunc("/scan", handleScan)
log.Fatalln(http.ListenAndServe(fmt.Sprintf("%s:%d", addr, port), nil))
}
func handleScan(w http.ResponseWriter, r *http.Request) {
// We don't allow any requests except POST to this endpoint.
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
// Parse form grabs the form values from the request.
err := r.ParseForm()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Println(err)
return
}
// Scan defaults
format := "png"
mode := "gray"
resolution := "300"
// Set scan parameters from POST data.
if reqFormat := r.PostForm.Get("format"); reqFormat != "" {
format = reqFormat
}
if reqMode := r.PostForm.Get("mode"); reqMode != "" {
mode = reqMode
}
if reqResolution := r.PostForm.Get("resolution"); reqResolution != "" {
resolution = reqResolution
}
// Create command.
cmd := exec.Command(
"scanimage",
fmt.Sprintf("--device-name=%s", device),
fmt.Sprintf("--format=%s", format),
fmt.Sprintf("--mode=%s", mode),
fmt.Sprintf("--resolution=%s", resolution),
)
// Set command's stdout and stderr.
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
w.WriteHeader(http.StatusGatewayTimeout)
log.Printf("Err: %s | %s", err, stderr.String())
if err.Error() == "exit status 7" {
w.Write([]byte("Document feeder out of documents"))
}
return
}
// Read bytes from stdout and send response.
reader := bytes.NewReader(stdout.Bytes())
data, err := ioutil.ReadAll(reader)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Println(err)
return
}
response := struct {
Data []byte
}{
Data: data,
}
responseJSON, err := json.Marshal(&response)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Println(err)
return
}
w.Write(responseJSON)
}