Files
2025-11-15 16:15:00 +03:00

109 lines
2.7 KiB
Go

// Package jabber contains all buny jabber bot guts.
package jabber
import (
"bufio"
"buny-jabber-bot/internal/log"
"fmt"
"io"
"os"
"strings"
"github.com/jbrukh/bayesian"
)
const (
// goodDictionaryFile путь до файла с заведомо хорошими фразами.
goodDictionaryFile string = "./data/good_dictionary.txt" //nolint: unused
// badDictionaryFile путь до файла с заведемо плохими фразами.
badDictionaryFile string = "./data/bad_dictionary.txt" //nolint: unused
// dataFile путь до файла с данными тренировки фильтра.
dataFile string = "./data/data.bin" //nolint: unused
// Bad bayessian class with bad items.
Bad bayesian.Class = "Bad"
// Good bayessian class with good items.
Good bayesian.Class = "Good"
)
// Выдаёт "очки похожести" для данной фразы.
func checkPhrase(s string) error { //nolint: unused
classifier, err := bayesian.NewClassifierFromFile(dataFile)
if err != nil {
return fmt.Errorf("unable to open %s: %w", dataFile, err)
}
s = nStringLower(s)
scores, _, _ := classifier.LogScores(strings.Split(s, " "))
_, err = fmt.Printf("Score %v\n", scores[0])
return err
}
// Выучивает слова из предопределённых словарей.
func learn() error { //nolint: unused
classifier := bayesian.NewClassifier(Bad, Good)
if err := feed(classifier, goodDictionaryFile, Good); err != nil {
return err
}
if err := feed(classifier, badDictionaryFile, Bad); err != nil {
return err
}
if err := classifier.WriteToFile(dataFile); err != nil {
return fmt.Errorf("unable to save data to file %s: %w", dataFile, err)
}
return nil
}
// Дополняет заданный класс фразами из указанного файла.
func feed(c *bayesian.Classifier, filename string, bc bayesian.Class) error { //nolint:unused
fh, err := os.Open(filename)
if err != nil {
return fmt.Errorf("unable to open file %s: %w", filename, err)
}
defer func(fh *os.File) {
if err := fh.Close(); err != nil {
log.Errorf("unable to close %s cleanly: %s", filename, err)
}
}(fh)
reader := bufio.NewReader(fh)
for {
line, err := reader.ReadString('\n')
line = nStringLower(line)
if err != nil {
// Правильно обрабатываем последнюю строку и конец файла.
if err == io.EOF {
if line != "" {
stuff := strings.Split(line, " ")
c.Learn(stuff, bc)
}
break
}
return fmt.Errorf("unable to read %s: %w", filename, err)
}
if line != "" {
stuff := strings.Split(line, " ")
c.Learn(stuff, bc)
}
}
return nil
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */