forked from google/cloud-print-connector
/
privet.go
130 lines (103 loc) · 2.93 KB
/
privet.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
125
126
127
128
129
130
/*
Copyright 2015 Google Inc. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file or at
https://developers.google.com/open-source/licenses/bsd
*/
package privet
import (
"fmt"
"sync"
"github.com/google/cups-connector/lib"
)
// Privet managers local discovery and printing.
type Privet struct {
xsrf xsrfSecret
apis map[string]*privetAPI
apisMutex sync.RWMutex // Protects apis
zc *zeroconf
jobs chan<- *lib.Job
jc jobCache
gcpBaseURL string
getProximityToken func(string, string) ([]byte, int, error)
}
// NewPrivet constructs a new Privet object.
//
// getProximityToken should be GoogleCloudPrint.ProximityToken()
func NewPrivet(jobs chan<- *lib.Job, gcpBaseURL string, getProximityToken func(string, string) ([]byte, int, error)) (*Privet, error) {
zc, err := newZeroconf()
if err != nil {
return nil, err
}
p := Privet{
xsrf: newXSRFSecret(),
apis: make(map[string]*privetAPI),
zc: zc,
jobs: jobs,
jc: *newJobCache(),
gcpBaseURL: gcpBaseURL,
getProximityToken: getProximityToken,
}
return &p, nil
}
// AddPrinter makes a printer available locally.
func (p *Privet) AddPrinter(printer lib.Printer, getPrinter func(string) (lib.Printer, bool)) error {
online := false
if printer.GCPID != "" {
online = true
}
api, err := newPrivetAPI(printer.GCPID, printer.Name, p.gcpBaseURL, p.xsrf, online, &p.jc, p.jobs, getPrinter, p.getProximityToken)
if err != nil {
return err
}
var localDefaultDisplayName = printer.DefaultDisplayName
if online {
localDefaultDisplayName = fmt.Sprintf("%s (local)", localDefaultDisplayName)
}
err = p.zc.addPrinter(printer.Name, api.port(), localDefaultDisplayName, p.gcpBaseURL, printer.GCPID, online)
if err != nil {
api.quit()
return err
}
p.apisMutex.Lock()
defer p.apisMutex.Unlock()
p.apis[printer.Name] = api
return nil
}
// UpdatePrinter updates a printer's TXT mDNS record.
func (p *Privet) UpdatePrinter(diff *lib.PrinterDiff) error {
online := false
if diff.Printer.GCPID != "" {
online = true
}
var localDefaultDisplayName = diff.Printer.DefaultDisplayName
if online {
localDefaultDisplayName = fmt.Sprintf("%s (local)", localDefaultDisplayName)
}
return p.zc.updatePrinterTXT(diff.Printer.GCPID, localDefaultDisplayName, p.gcpBaseURL, diff.Printer.GCPID, online)
}
// DeletePrinter removes a printer from Privet.
func (p *Privet) DeletePrinter(cupsPrinterName string) error {
p.apisMutex.Lock()
defer p.apisMutex.Unlock()
err := p.zc.removePrinter(cupsPrinterName)
if api, ok := p.apis[cupsPrinterName]; ok {
api.quit()
delete(p.apis, cupsPrinterName)
}
return err
}
func (p *Privet) Quit() {
p.apisMutex.Lock()
defer p.apisMutex.Unlock()
p.zc.quit()
for cupsPrinterName, api := range p.apis {
api.quit()
delete(p.apis, cupsPrinterName)
}
}
func (p *Privet) Size() int {
p.apisMutex.RLock()
defer p.apisMutex.RUnlock()
return len(p.apis)
}