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

196 lines
5.7 KiB
Go

package query
import (
"fmt"
"log/slog"
"strconv"
"strings"
"sync"
"time"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/maximotejeda/us_dop_bot/internal/application/domain"
"github.com/maximotejeda/us_dop_bot/internal/application/helpers"
"github.com/maximotejeda/us_dop_bot/internal/ports"
)
var chatPool *sync.Pool
type Query struct {
bot *tgbotapi.BotAPI
update *tgbotapi.Update
msg *tgbotapi.MessageConfig
log *slog.Logger
dolar ports.DolarService
user ports.UserService
}
// NewQuery
// Factory for query handlers
func NewQuery(bot *tgbotapi.BotAPI, update *tgbotapi.Update, dolar ports.DolarService, user ports.UserService) *Query {
if chatPool == nil {
chatPool = &sync.Pool{
New: func() any { return &Query{} },
}
for i := 0; i < 20; i++ {
chatPool.Put(chatPool.New())
}
}
log := slog.Default()
log = log.With("function", "query", "chat", update.CallbackQuery.From.ID, "userid", update.CallbackQuery.From.ID, "username", update.CallbackQuery.From.UserName)
query := chatPool.Get().(*Query)
query.update = update
query.bot = bot
query.log = log
query.dolar = dolar
query.user = user
return query
}
// Empty
// Returns pointer to pool
func (q *Query) Empty() {
q.update = nil
q.msg = nil
q.log = nil
chatPool.Put(q)
}
// Send
// Process Query message
func (q *Query) Send() {
defer q.Empty()
q.bot.Send(q.msg)
// Delete previous message
del := tgbotapi.NewDeleteMessage(q.update.CallbackQuery.From.ID, q.update.CallbackQuery.Message.MessageID)
q.bot.Send(del)
}
// Handler
// Manage query message
func (q *Query) Handler() {
msg := tgbotapi.NewMessage(q.update.CallbackQuery.Message.Chat.ID, "")
q.msg = &msg
tUser := q.update.CallbackQuery.From
data := q.update.CallbackQuery.Data
dataList := strings.Split(data, "&")
dataMap := map[string]string{}
for _, val := range dataList {
subData := strings.Split(val, "=")
dataMap[subData[0]] = subData[1]
}
switch {
case dataMap["subs"] != "":
_, err := q.dolar.Subscribe(q.update.CallbackQuery.From.ID, dataMap["name"])
if err != nil {
q.log.Error("subs-query", "error", err.Error(), "user", q.update.CallbackQuery.From)
}
case dataMap["unsubs"] != "":
_, err := q.dolar.Unsubscribe(q.update.CallbackQuery.From.ID, dataMap["name"])
if err != nil {
q.log.Error("subs-query", "error", err.Error(), "user", q.update.CallbackQuery.From)
}
case dataMap["reset"] != "":
subscriptions, _ := q.dolar.GetSubscribedInsts(q.update.CallbackQuery.From.ID)
if len(subscriptions) > 0 {
for _, inst := range subscriptions {
q.dolar.Unsubscribe(q.update.CallbackQuery.From.ID, inst)
q.log.Info("unsubscribing", "institution", inst)
}
}
case dataMap["consultar"] != "":
name := "&name=" + dataMap["name"]
queryMap := map[string]string{
"Actual": "query=true&time=0&unit=now" + name,
//"30 Minutos": "query=true&time=30&unit=minute" + name,
"1 Hora": "query=true&time=1&unit=hour" + name,
"6 Horas": "query=true&time=6&unit=hour" + name,
"12 Horas": "query=true&time=12&unit=hour" + name,
"1 Dia": "query=true&time=24&unit=hour" + name,
"1 Semana": "query=true&time=168&unit=hour" + name,
"2 Semanas": "query=true&time=336&unit=hour" + name,
"1 Mes": "query=true&time=672&unit=hour" + name,
}
keyboard := helpers.CreateKeyboard(queryMap)
msg = tgbotapi.MessageConfig{}
msg.ChatID = tUser.ID
msg.ReplyMarkup = keyboard
msg.Text = fmt.Sprintf("Intervalos de tiempo disponibles para consulta en %s el cambio del dolar desde hace:", dataMap["name"])
case dataMap["query"] != "":
var timeUnit time.Duration
timeAmntSTR := dataMap["time"]
timeUnitSTR := dataMap["unit"]
name := dataMap["name"]
timeAmnt, err := strconv.Atoi(timeAmntSTR)
switch name {
case "apap":
name = "asociacion popular de ahorros y prestamos"
case "acap":
name = "asociacion cibao de ahorros y prestamos"
case "anap":
name = "asociacion la nacional de ahorros y prestamos"
case "aperap":
name = "asociacion peravia de ahorros y prestamos"
}
if err != nil {
q.log.Error("[query-query] converting amount of time to int", "error", err)
q.Send()
return
}
switch timeUnitSTR {
case "hour":
timeUnit = time.Hour * time.Duration(timeAmnt)
instList, err := q.dolar.GetSince(name, int64(timeUnit.Minutes()))
//q.log.Info("hour provided", "hour", timeUnit, "int hours", int64(timeUnit.Minutes()))
if err != nil {
q.log.Error("[GETLIST] querying the inst database hours", "error", err)
return
}
queryMap := map[string]string{"clear": "cancel=true"}
keyboard := helpers.CreateKeyboard(queryMap)
msg = tgbotapi.MessageConfig{}
msg.ChatID = tUser.ID
msg.ReplyMarkup = keyboard
msg.Text = instMessage(instList)
case "now":
instRes, err := q.dolar.GetLatest(name)
if err != nil {
q.log.Error("queriing the inst database now", "error", err)
return
}
queryMap := map[string]string{"clear": "cancel=true"}
keyboard := helpers.CreateKeyboard(queryMap)
msg = tgbotapi.MessageConfig{}
msg.ChatID = tUser.ID
msg.ReplyMarkup = keyboard
msg.Text = fmt.Sprintf("%s\nCompra: %.2f\nVenta: %.2f", instRes.Institution.Name, instRes.Compra, instRes.Venta)
}
}
q.Send()
}
func instMessage(insts []*domain.History) string {
if len(insts) <= 0 {
return "Sin cambios registrados en este intervalo\nPrueba a ampliar el rango del tiempo deseado."
}
name := insts[0].Institution.Name
resultText := fmt.Sprintf("%s\n\n", name)
for _, i := range insts {
date := time.Unix(i.Parsed, 0)
loc, _ := time.LoadLocation("America/Santo_Domingo")
resultText = resultText + fmt.Sprintf(" %s\n Compra: %.2f Venta: %.2f\n", date.In(loc).Format(time.DateTime), i.Compra, i.Venta)
}
return resultText
}