mirror of https://github.com/h44z/wg-portal.git
				
				
				
			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/xhit/go-simple-mail/v2 v2.16.0 | ||||
| 	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/oauth2 v0.26.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/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/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/go.mod h1:P76zpcn2TCuL0ul1Fso373qHRc69LKwAw/Iy6g1WiiM= | ||||
| github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ import ( | |||
| 	"github.com/sirupsen/logrus" | ||||
| 	evbus "github.com/vardius/message-bus" | ||||
| 	"github.com/yeqown/go-qrcode/v2" | ||||
| 	"github.com/yeqown/go-qrcode/writer/compressed" | ||||
| ) | ||||
| 
 | ||||
| type Manager struct { | ||||
|  | @ -27,7 +28,13 @@ type Manager struct { | |||
| 	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() | ||||
| 	if err != nil { | ||||
| 		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) | ||||
| 	} | ||||
| 
 | ||||
| 	code, err := qrcode.New(sb.String()) | ||||
| 	code, err := qrcode.NewWith(sb.String(), | ||||
| 		qrcode.WithErrorCorrectionLevel(qrcode.ErrorCorrectionLow), qrcode.WithEncodingMode(qrcode.EncModeByte)) | ||||
| 	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) | ||||
| 	wr := nopCloser{Writer: buf} | ||||
| 	option := Option{ | ||||
| 	option := compressed.Option{ | ||||
| 		Padding:   8, // padding pixels around the qr code.
 | ||||
| 		BlockSize: 4, // block pixels which represents a bit data.
 | ||||
| 	} | ||||
| 	qrWriter := NewCompressedWriter(wr, &option) | ||||
| 	qrWriter := compressed.NewWithWriter(wr, &option) | ||||
| 	err = code.Save(qrWriter) | ||||
| 	if err != nil { | ||||
| 		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…
	
		Reference in New Issue