Первая версия (CLI-only) #1

Merged
weirdcat merged 26 commits from develop into main 2025-11-27 13:09:27 +03:00
5 changed files with 83 additions and 1 deletions
Showing only changes of commit 4876ba5954 - Show all commits

View File

@@ -24,6 +24,7 @@ import (
"git.weirdcat.su/weirdcat/auto-attendance/internal/linkvalidator"
"git.weirdcat.su/weirdcat/auto-attendance/internal/logger"
"git.weirdcat.su/weirdcat/auto-attendance/internal/screencapturer"
"git.weirdcat.su/weirdcat/auto-attendance/internal/vision"
"go.uber.org/fx"
)
@@ -34,6 +35,7 @@ func main() {
logger.NewLogger,
linkvalidator.NewLinkValidator,
screencapturer.NewWholeScreenCapturer,
vision.NewVision,
),
fx.Invoke(func(log *logger.Logger, capturer screencapturer.ScreenCapturer) {
log.Debug("starting application...")

View File

@@ -12,6 +12,7 @@ require (
github.com/jezek/xgb v1.1.1 // indirect
github.com/kbinani/screenshot v0.0.0-20250624051815-089614a94018 // indirect
github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect
github.com/makiuchi-d/gozxing v0.1.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
@@ -24,6 +25,8 @@ require (
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.26.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
gocv.io/x/gocv v0.42.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.28.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
)

View File

@@ -12,6 +12,8 @@ github.com/kbinani/screenshot v0.0.0-20250624051815-089614a94018 h1:NQYgMY188uWr
github.com/kbinani/screenshot v0.0.0-20250624051815-089614a94018/go.mod h1:Pmpz2BLf55auQZ67u3rvyI2vAQvNetkK/4zYUmpauZQ=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
github.com/makiuchi-d/gozxing v0.1.1 h1:xxqijhoedi+/lZlhINteGbywIrewVdVv2wl9r5O9S1I=
github.com/makiuchi-d/gozxing v0.1.1/go.mod h1:eRIHbOjX7QWxLIDJoQuMLhuXg9LAuw6znsUtRkNw9DU=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
@@ -38,9 +40,13 @@ go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
gocv.io/x/gocv v0.42.0 h1:AAsrFJH2aIsQHukkCovWqj0MCGZleQpVyf5gNVRXjQI=
gocv.io/x/gocv v0.42.0/go.mod h1:zYdWMj29WAEznM3Y8NsU3A0TRq/wR/cy75jeUypThqU=
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -18,3 +18,71 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package vision
import (
"errors"
"git.weirdcat.su/weirdcat/auto-attendance/internal/logger"
"github.com/makiuchi-d/gozxing"
"github.com/makiuchi-d/gozxing/qrcode"
"gocv.io/x/gocv"
)
type Vision interface {
AnalyzeImage(filePath string) (data VisionData, err error)
}
type visionImpl struct {
log *logger.Logger
}
var (
ErrImageEmpty = errors.New("Image from file was empty")
)
// AnalyzeImage implements Vision.
func (v *visionImpl) AnalyzeImage(filePath string) (data VisionData, err error) {
v.log.Debug("analyzing image for qr codes", "filePath", filePath)
img := gocv.IMRead(filePath, gocv.IMReadColor)
if img.Empty() {
v.log.Error("could not read image file", "filePath", filePath)
return VisionData{}, ErrImageEmpty
}
defer img.Close()
// Convert to grayscale for QR code detection
gray := gocv.NewMat()
defer gray.Close()
gocv.CvtColor(img, &gray, gocv.ColorBGRToGray)
// Convert gocv.Mat to image.Image for gozxing
imgGray, err := gray.ToImage()
if err != nil {
v.log.Error("failed to convert image", "error", err)
return VisionData{}, err
}
// Create a binary bitmap from the image
bmp, err := gozxing.NewBinaryBitmapFromImage(imgGray)
if err != nil {
v.log.Error("failed to create binary bitmap", "error", err)
return VisionData{}, err
}
reader := qrcode.NewQRCodeReader()
result, err := reader.Decode(bmp, nil)
if err != nil {
v.log.Debug("no qr code found in image", "filePath", filePath, "error", err)
return VisionData{}, nil
}
v.log.Info("QR code decoded successfully", "content", result.GetText())
data = VisionData{result.GetText()}
return data, nil
}
func NewVision(log *logger.Logger) Vision {
return &visionImpl{log: log}
}

View File

@@ -0,0 +1,3 @@
package vision
type VisionData []string