forked from lug/matterbridge
		
	
		
			
				
	
	
		
			156 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package qrcodeTerminal
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 
 | |
| 	"github.com/skip2/go-qrcode"
 | |
| 	"github.com/mattn/go-colorable"
 | |
| 	"image/png"
 | |
| 	nbytes "bytes"
 | |
| )
 | |
| 
 | |
| type consoleColor string
 | |
| type consoleColors struct {
 | |
| 	NormalBlack   consoleColor
 | |
| 	NormalRed     consoleColor
 | |
| 	NormalGreen   consoleColor
 | |
| 	NormalYellow  consoleColor
 | |
| 	NormalBlue    consoleColor
 | |
| 	NormalMagenta consoleColor
 | |
| 	NormalCyan    consoleColor
 | |
| 	NormalWhite   consoleColor
 | |
| 	BrightBlack   consoleColor
 | |
| 	BrightRed     consoleColor
 | |
| 	BrightGreen   consoleColor
 | |
| 	BrightYellow  consoleColor
 | |
| 	BrightBlue    consoleColor
 | |
| 	BrightMagenta consoleColor
 | |
| 	BrightCyan    consoleColor
 | |
| 	BrightWhite   consoleColor
 | |
| }
 | |
| type qrcodeRecoveryLevel qrcode.RecoveryLevel
 | |
| type qrcodeRecoveryLevels struct {
 | |
| 	Low     qrcodeRecoveryLevel
 | |
| 	Medium  qrcodeRecoveryLevel
 | |
| 	High    qrcodeRecoveryLevel
 | |
| 	Highest qrcodeRecoveryLevel
 | |
| }
 | |
| 
 | |
| var (
 | |
| 	ConsoleColors consoleColors = consoleColors{
 | |
| 		NormalBlack:   "\033[38;5;0m  \033[0m",
 | |
| 		NormalRed:     "\033[38;5;1m  \033[0m",
 | |
| 		NormalGreen:   "\033[38;5;2m  \033[0m",
 | |
| 		NormalYellow:  "\033[38;5;3m  \033[0m",
 | |
| 		NormalBlue:    "\033[38;5;4m  \033[0m",
 | |
| 		NormalMagenta: "\033[38;5;5m  \033[0m",
 | |
| 		NormalCyan:    "\033[38;5;6m  \033[0m",
 | |
| 		NormalWhite:   "\033[38;5;7m  \033[0m",
 | |
| 		BrightBlack:   "\033[48;5;0m  \033[0m",
 | |
| 		BrightRed:     "\033[48;5;1m  \033[0m",
 | |
| 		BrightGreen:   "\033[48;5;2m  \033[0m",
 | |
| 		BrightYellow:  "\033[48;5;3m  \033[0m",
 | |
| 		BrightBlue:    "\033[48;5;4m  \033[0m",
 | |
| 		BrightMagenta: "\033[48;5;5m  \033[0m",
 | |
| 		BrightCyan:    "\033[48;5;6m  \033[0m",
 | |
| 		BrightWhite:   "\033[48;5;7m  \033[0m"}
 | |
| 	QRCodeRecoveryLevels = qrcodeRecoveryLevels{
 | |
| 		Low:     qrcodeRecoveryLevel(qrcode.Low),
 | |
| 		Medium:  qrcodeRecoveryLevel(qrcode.Medium),
 | |
| 		High:    qrcodeRecoveryLevel(qrcode.High),
 | |
| 		Highest: qrcodeRecoveryLevel(qrcode.Highest)}
 | |
| )
 | |
| 
 | |
| type QRCodeString string
 | |
| 
 | |
| func (v *QRCodeString) Print() {
 | |
| 	fmt.Fprint(outer, *v)
 | |
| }
 | |
| 
 | |
| type qrcodeTerminal struct {
 | |
| 	front consoleColor
 | |
| 	back  consoleColor
 | |
| 	level qrcodeRecoveryLevel
 | |
| }
 | |
| 
 | |
| func (v *qrcodeTerminal) Get(content interface{}) (result *QRCodeString) {
 | |
| 	var qr *qrcode.QRCode
 | |
| 	var err error
 | |
| 	if t, ok := content.(string); ok {
 | |
| 		qr, err = qrcode.New(t, qrcode.RecoveryLevel(v.level))
 | |
| 	} else if t, ok := content.([]byte); ok {
 | |
| 		qr, err = qrcode.New(string(t), qrcode.RecoveryLevel(v.level))
 | |
| 	}
 | |
| 	if qr != nil && err == nil {
 | |
| 		data := qr.Bitmap()
 | |
| 		result = v.getQRCodeString(data)
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (v *qrcodeTerminal) Get2(bytes []byte) (result *QRCodeString) {
 | |
| 	data, err := parseQR(bytes)
 | |
| 	if err == nil {
 | |
| 		result = v.getQRCodeString(data)
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func New2(front, back consoleColor, level qrcodeRecoveryLevel) *qrcodeTerminal {
 | |
| 	obj := qrcodeTerminal{front: front, back: back, level: level}
 | |
| 	return &obj
 | |
| }
 | |
| 
 | |
| func New() *qrcodeTerminal {
 | |
| 	front, back, level := ConsoleColors.BrightBlack, ConsoleColors.BrightWhite, QRCodeRecoveryLevels.Medium
 | |
| 	return New2(front, back, level)
 | |
| }
 | |
| 
 | |
| func (v *qrcodeTerminal) getQRCodeString(data [][]bool) (result *QRCodeString) {
 | |
| 	str := ""
 | |
| 	for ir, row := range data {
 | |
| 		lr := len(row)
 | |
| 		if ir == 0 || ir == 1 || ir == 2 ||
 | |
| 			ir == lr-1 || ir == lr-2 || ir == lr-3 {
 | |
| 			continue
 | |
| 		}
 | |
| 		for ic, col := range row {
 | |
| 			lc := len(data)
 | |
| 			if ic == 0 || ic == 1 || ic == 2 ||
 | |
| 				ic == lc-1 || ic == lc-2 || ic == lc-3 {
 | |
| 				continue
 | |
| 			}
 | |
| 			if col {
 | |
| 				str += fmt.Sprint(v.front)
 | |
| 			} else {
 | |
| 				str += fmt.Sprint(v.back)
 | |
| 			}
 | |
| 		}
 | |
| 		str += fmt.Sprintln()
 | |
| 	}
 | |
| 	obj := QRCodeString(str)
 | |
| 	result = &obj
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func parseQR(bytes []byte) (data [][]bool, err error) {
 | |
| 	r := nbytes.NewReader(bytes)
 | |
| 	img, err := png.Decode(r)
 | |
| 	if err == nil {
 | |
| 		rect := img.Bounds()
 | |
| 		mx, my := rect.Max.X, rect.Max.Y
 | |
| 		data = make([][]bool, mx)
 | |
| 		for x := 0; x < mx; x++ {
 | |
| 			data[x] = make([]bool, my)
 | |
| 			for y := 0; y < my; y++ {
 | |
| 				c := img.At(x, y)
 | |
| 				r, _, _, _ := c.RGBA()
 | |
| 				data[x][y] = r == 0
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| var outer = colorable.NewColorableStdout()
 | 
