mirror of
https://github.com/h44z/wg-portal.git
synced 2025-04-19 08:55:12 +00:00
fix qr-code generation for large configurations (#374)
This commit is contained in:
parent
40b4538e78
commit
66ccdc29e9
1
go.mod
1
go.mod
@ -21,6 +21,7 @@ require (
|
|||||||
github.com/vishvananda/netlink v1.3.0
|
github.com/vishvananda/netlink v1.3.0
|
||||||
github.com/xhit/go-simple-mail/v2 v2.16.0
|
github.com/xhit/go-simple-mail/v2 v2.16.0
|
||||||
github.com/yeqown/go-qrcode/v2 v2.2.5
|
github.com/yeqown/go-qrcode/v2 v2.2.5
|
||||||
|
github.com/yeqown/go-qrcode/writer/compressed v1.0.1
|
||||||
golang.org/x/crypto v0.34.0
|
golang.org/x/crypto v0.34.0
|
||||||
golang.org/x/oauth2 v0.26.0
|
golang.org/x/oauth2 v0.26.0
|
||||||
golang.org/x/sys v0.30.0
|
golang.org/x/sys v0.30.0
|
||||||
|
2
go.sum
2
go.sum
@ -284,6 +284,8 @@ github.com/xhit/go-simple-mail/v2 v2.16.0 h1:ouGy/Ww4kuaqu2E2UrDw7SvLaziWTB60ICL
|
|||||||
github.com/xhit/go-simple-mail/v2 v2.16.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98=
|
github.com/xhit/go-simple-mail/v2 v2.16.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98=
|
||||||
github.com/yeqown/go-qrcode/v2 v2.2.5 h1:HCOe2bSjkhZyYoyyNaXNzh4DJZll6inVJQQw+8228Zk=
|
github.com/yeqown/go-qrcode/v2 v2.2.5 h1:HCOe2bSjkhZyYoyyNaXNzh4DJZll6inVJQQw+8228Zk=
|
||||||
github.com/yeqown/go-qrcode/v2 v2.2.5/go.mod h1:uHpt9CM0V1HeXLz+Wg5MN50/sI/fQhfkZlOM+cOTHxw=
|
github.com/yeqown/go-qrcode/v2 v2.2.5/go.mod h1:uHpt9CM0V1HeXLz+Wg5MN50/sI/fQhfkZlOM+cOTHxw=
|
||||||
|
github.com/yeqown/go-qrcode/writer/compressed v1.0.1 h1:0el6zOppx3oPiYWMUJWRYGvxWYh8MDmUU0j3rSWGWlI=
|
||||||
|
github.com/yeqown/go-qrcode/writer/compressed v1.0.1/go.mod h1:BJScsGUIKM+eg0CCLCcVaDTaclDM1IEXtq2r8qQnDKk=
|
||||||
github.com/yeqown/reedsolomon v1.0.0 h1:x1h/Ej/uJnNu8jaX7GLHBWmZKCAWjEJTetkqaabr4B0=
|
github.com/yeqown/reedsolomon v1.0.0 h1:x1h/Ej/uJnNu8jaX7GLHBWmZKCAWjEJTetkqaabr4B0=
|
||||||
github.com/yeqown/reedsolomon v1.0.0/go.mod h1:P76zpcn2TCuL0ul1Fso373qHRc69LKwAw/Iy6g1WiiM=
|
github.com/yeqown/reedsolomon v1.0.0/go.mod h1:P76zpcn2TCuL0ul1Fso373qHRc69LKwAw/Iy6g1WiiM=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
evbus "github.com/vardius/message-bus"
|
evbus "github.com/vardius/message-bus"
|
||||||
"github.com/yeqown/go-qrcode/v2"
|
"github.com/yeqown/go-qrcode/v2"
|
||||||
|
"github.com/yeqown/go-qrcode/writer/compressed"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
@ -27,7 +28,13 @@ type Manager struct {
|
|||||||
wg WireguardDatabaseRepo
|
wg WireguardDatabaseRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfigFileManager(cfg *config.Config, bus evbus.MessageBus, users UserDatabaseRepo, wg WireguardDatabaseRepo, fsRepo FileSystemRepo) (*Manager, error) {
|
func NewConfigFileManager(
|
||||||
|
cfg *config.Config,
|
||||||
|
bus evbus.MessageBus,
|
||||||
|
users UserDatabaseRepo,
|
||||||
|
wg WireguardDatabaseRepo,
|
||||||
|
fsRepo FileSystemRepo,
|
||||||
|
) (*Manager, error) {
|
||||||
tplHandler, err := newTemplateHandler()
|
tplHandler, err := newTemplateHandler()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to initialize template handler: %w", err)
|
return nil, fmt.Errorf("failed to initialize template handler: %w", err)
|
||||||
@ -156,18 +163,19 @@ func (m Manager) GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifi
|
|||||||
return nil, fmt.Errorf("failed to read peer config for %s: %w", id, err)
|
return nil, fmt.Errorf("failed to read peer config for %s: %w", id, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
code, err := qrcode.New(sb.String())
|
code, err := qrcode.NewWith(sb.String(),
|
||||||
|
qrcode.WithErrorCorrectionLevel(qrcode.ErrorCorrectionLow), qrcode.WithEncodingMode(qrcode.EncModeByte))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to initializeqr code for %s: %w", id, err)
|
return nil, fmt.Errorf("failed to initialize qr code for %s: %w", id, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
wr := nopCloser{Writer: buf}
|
wr := nopCloser{Writer: buf}
|
||||||
option := Option{
|
option := compressed.Option{
|
||||||
Padding: 8, // padding pixels around the qr code.
|
Padding: 8, // padding pixels around the qr code.
|
||||||
BlockSize: 4, // block pixels which represents a bit data.
|
BlockSize: 4, // block pixels which represents a bit data.
|
||||||
}
|
}
|
||||||
qrWriter := NewCompressedWriter(wr, &option)
|
qrWriter := compressed.NewWithWriter(wr, &option)
|
||||||
err = code.Save(qrWriter)
|
err = code.Save(qrWriter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to write code for %s: %w", id, err)
|
return nil, fmt.Errorf("failed to write code for %s: %w", id, err)
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
package configfile
|
|
||||||
|
|
||||||
// waiting for https://github.com/yeqown/go-qrcode/pull/85 to get merged
|
|
||||||
// meanwhile we use our own writer implementation
|
|
||||||
|
|
||||||
import (
|
|
||||||
"image"
|
|
||||||
"image/color"
|
|
||||||
"image/png"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/yeqown/go-qrcode/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Option struct {
|
|
||||||
Padding int
|
|
||||||
BlockSize int
|
|
||||||
}
|
|
||||||
|
|
||||||
// compressedWriter implements issue#69, generating compressed images
|
|
||||||
// in some special situations, such as, network transferring.
|
|
||||||
// https://github.com/yeqown/go-qrcode/issues/69
|
|
||||||
type compressedWriter struct {
|
|
||||||
fd io.WriteCloser
|
|
||||||
|
|
||||||
option *Option
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
backgroundColor = color.Gray{Y: 0xff}
|
|
||||||
foregroundColor = color.Gray{Y: 0x00}
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewCompressedWriter(writer io.WriteCloser, opt *Option) qrcode.Writer {
|
|
||||||
return compressedWriter{fd: writer, option: opt}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w compressedWriter) Write(mat qrcode.Matrix) error {
|
|
||||||
padding := w.option.Padding
|
|
||||||
blockWidth := w.option.BlockSize
|
|
||||||
width := mat.Width()*blockWidth + 2*padding
|
|
||||||
height := width
|
|
||||||
|
|
||||||
img := image.NewPaletted(
|
|
||||||
image.Rect(0, 0, width, height),
|
|
||||||
color.Palette([]color.Color{backgroundColor, foregroundColor}),
|
|
||||||
)
|
|
||||||
bgColor := uint8(img.Palette.Index(backgroundColor))
|
|
||||||
fgColor := uint8(img.Palette.Index(foregroundColor))
|
|
||||||
|
|
||||||
rectangle := func(x1, y1 int, x2, y2 int, img *image.Paletted, color uint8) {
|
|
||||||
for x := x1; x < x2; x++ {
|
|
||||||
for y := y1; y < y2; y++ {
|
|
||||||
pos := img.PixOffset(x, y)
|
|
||||||
img.Pix[pos] = color
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// background
|
|
||||||
rectangle(0, 0, width, height, img, bgColor)
|
|
||||||
|
|
||||||
mat.Iterate(qrcode.IterDirection_COLUMN, func(x int, y int, v qrcode.QRValue) {
|
|
||||||
sx := x*blockWidth + padding
|
|
||||||
sy := y*blockWidth + padding
|
|
||||||
es := (x+1)*blockWidth + padding
|
|
||||||
ey := (y+1)*blockWidth + padding
|
|
||||||
|
|
||||||
if v.IsSet() {
|
|
||||||
rectangle(sx, sy, es, ey, img, fgColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
//switch v.IsSet() {
|
|
||||||
//case false:
|
|
||||||
// gray = backgroundColor
|
|
||||||
//default:
|
|
||||||
// gray = foregroundColor
|
|
||||||
//}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
encoder := png.Encoder{CompressionLevel: png.BestCompression}
|
|
||||||
return encoder.Encode(w.fd, img)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w compressedWriter) Close() error {
|
|
||||||
return w.fd.Close()
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user