maximo tejeda ceb402a65d
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
INITIAL COMMIT
2024-07-21 11:40:07 -04:00

193 lines
4.6 KiB
Go

package chat
import (
"bytes"
"context"
"fmt"
"regexp"
"strconv"
"strings"
"sync"
"unicode"
tgb "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"golang.org/x/text/runes"
"golang.org/x/text/transform"
"golang.org/x/text/unicode/norm"
)
var ChatPool *sync.Pool
type ChatObj struct {
update *tgb.Update
bot *tgb.BotAPI
}
func NewChatObj(bot *tgb.BotAPI, updt *tgb.Update) (chat *ChatObj) {
if ChatPool == nil {
ChatPool = &sync.Pool{
New: func() any { return &ChatObj{} },
}
for i := 0; i < 20; i++ {
ChatPool.Put(ChatPool.New())
}
} else {
fmt.Println("alredy populated")
}
chat = ChatPool.Get().(*ChatObj)
chat.update = updt
chat.bot = bot
return chat
}
func EmptyChat(chat *ChatObj) {
chat.update = nil
ChatPool.Put(chat)
}
func HandleChat(bot *tgb.BotAPI, updt *tgb.Update) {
chat := NewChatObj(bot, updt)
defer EmptyChat(chat)
text := NormalizeText(updt.Message.Text)
textList := strings.Split(text, " ")
msg := tgb.NewMessage(updt.Message.Chat.ID, "")
if len(textList) >= 1 && MessageChecker(text) == "digit" {
// in case of message match a cedula
ced, err := info.NewCedula(text)
if err != nil {
msg.Text = "cedula no reconocida " + err.Error()
} else {
msg, photoMsg := ProcessByCedula(*ced)
msg.ChatID = updt.Message.Chat.ID
if photoMsg != nil {
photoMsg.ChatID = updt.Message.Chat.ID
bot.Send(photoMsg)
}
bot.Send(msg)
return
}
} else if len(textList) >= 2 && MessageChecker(text) == "word" {
msg := ProcessByName(textList)
msg.ChatID = updt.Message.Chat.ID
bot.Send(msg)
}
msg.ReplyToMessageID = updt.Message.MessageID
bot.Send(msg)
}
// ProcessByCedula
//
// When a text arrives the chat if it match a cedula try to query db
func ProcessByCedula(dbS *db.DB, ced info.Cedula) (message *tgb.MessageConfig, fotoMsg *tgb.PhotoConfig) {
msg := tgb.NewMessage(0, "")
message = &msg
ctx := context.Background()
info, err := info.GetByCedula(ctx, dbS, ced)
if err != nil {
msg.Text = "error buscando cedula " + err.Error()
}
if info != nil {
msg.Text = fmt.Sprintf(`
Nombres: %s
Apellidos: %s %s
Cedula: %s
Direccion: %s
Telefono: %s
`,
strings.ToLower(info.Nombres), strings.ToLower(info.Apellido1), strings.ToLower(info.Apellido2),
info.MunCed+info.SeqCed+info.VerCed, RemoveSpaces(info.Direccion), info.Telefono)
}
foto, err := fotos.GetImageByCedulas(ctx, dbS, ced)
if err != nil {
fmt.Println("Photo not found", err.Error())
return
}
if foto != nil {
rq := tgb.FileReader{Name: fmt.Sprintf("%s-%s-%s", ced.MunCed, ced.SeqCed, ced.VerCed), Reader: bytes.NewReader(foto)}
fotost := tgb.NewPhoto(msg.ChatID, rq)
fotoMsg = &fotost
}
return
}
func ProcessByName(dbS *db.DB, nameList []string) (message *tgb.MessageConfig) {
ctx := context.Background()
var err error
page := 0
// look for if the last part of the list is a number
lastItem := nameList[len(nameList)-1]
if MessageChecker(lastItem) == "digit" && !strings.HasPrefix(lastItem, "0") {
pageInt, err := strconv.Atoi(lastItem)
if err != nil {
fmt.Println(err)
}
nameList = nameList[:len(nameList)-1]
if pageInt < 20 {
page = pageInt
}
}
rows := &info.MultipleResults{}
message = &tgb.MessageConfig{}
text := strings.Join(nameList, " ")
rows, err = info.GetByFTS(ctx, dbS, text, uint(page))
if err != nil {
message.Text = "no hubo resultados para la busqueda"
return
}
textToSend := fmt.Sprintf(`
Busqueda:
Texto: %s
Pagina: %d
resultados desde: %d A %d
De un total de: %d
`,
text,
(rows.Page),
(rows.Page*10)-9, (rows.Page)*10,
rows.Total)
for _, v := range rows.Data {
textToSend = textToSend + fmt.Sprintf("\n %s %s %s \n %s-%s-%s\n", strings.ToLower(v.Nombres), strings.ToLower(v.Apellido1), strings.ToLower(v.Apellido2), v.MunCed, v.SeqCed, v.VerCed)
}
message.Text = textToSend
return
}
func MessageChecker(text string) string {
// Check is text start with number
checkSpace := regexp.MustCompile(`^[\s]+.*`)
checkNumber := regexp.MustCompile(`^[\d]+.*`)
checkWord := regexp.MustCompile(`^[a-zA-Z% ]+.*`)
if checkNumber.MatchString(text) {
return "digit"
} else if checkWord.MatchString(text) {
return "word"
} else if checkSpace.MatchString(text) {
t := strings.TrimSpace(text)
return MessageChecker(t)
}
return ""
}
// NormalizeText
// remove foreign accent
func NormalizeText(text string) string {
t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
result, _, _ := transform.String(t, text)
return result
}
func RemoveSpaces(text string) (res string) {
re := regexp.MustCompile(`[\s]+`)
res = re.ReplaceAllString(text, " ")
return
}