Implement caching previously queried (by chatter) city in weather module

This commit is contained in:
eleksir
2025-02-09 14:27:01 +03:00
parent a9e0095dc9
commit 07430d87ed
3 changed files with 59 additions and 4 deletions

View File

@@ -12,6 +12,7 @@ import (
"aleesa-webapp-go/internal/prazdnikisegodnyaru" "aleesa-webapp-go/internal/prazdnikisegodnyaru"
"aleesa-webapp-go/internal/randomfox" "aleesa-webapp-go/internal/randomfox"
"aleesa-webapp-go/internal/thecatapi" "aleesa-webapp-go/internal/thecatapi"
"aleesa-webapp-go/internal/types"
"aleesa-webapp-go/internal/xkcdru" "aleesa-webapp-go/internal/xkcdru"
"context" "context"
"encoding/json" "encoding/json"
@@ -28,7 +29,7 @@ func MsgParser(cfg *config.MyConfig, ctx context.Context, msg string) {
var ( var (
sendTo string sendTo string
answer string answer string
j RMsg j types.RMsg
err error err error
) )
@@ -411,6 +412,21 @@ func MsgParser(cfg *config.MyConfig, ctx context.Context, msg string) {
j.Message = answer j.Message = answer
} }
case cmd == "w" || cmd == "п" || cmd == "погода" || cmd == "weather" || cmd == "погодка" || cmd == "погадка":
// TODO: научиться различать 5-дневные и моментальные прогнозы. Пока умеем только моментальные.
city := openweathermap.QueryOwmUserCache(cfg, j.Chatid, j.Userid)
if city == "" {
j.Message = fmt.Sprint("Не припоминаю, какой город вас интересовал в прошлый раз.")
} else {
if answer, err := openweathermap.OwmClient(cfg, city, 0); err != nil {
log.Errorf("Unable to handle city %s in openweartermap api: %s", city, err)
j.Message = fmt.Sprintf("Я не знаю, какая погода в %s", city)
} else {
j.Message = answer
}
}
case regexpWeather.MatchString(cmd): case regexpWeather.MatchString(cmd):
re := regexp.MustCompile("[[:space:]]+") re := regexp.MustCompile("[[:space:]]+")
cmdStr := re.Split(cmd, 2)[0] cmdStr := re.Split(cmd, 2)[0]
@@ -432,6 +448,16 @@ func MsgParser(cfg *config.MyConfig, ctx context.Context, msg string) {
} }
} }
if err = openweathermap.UpdateOwmUserCache(cfg, j.Chatid, j.Userid, city); err != nil {
log.Errorf(
"Unable to save value to cache, for chatid %s, userid %s and city %s: %s",
j.Chatid,
j.Userid,
city,
err,
)
}
default: default:
log.Errorf("Unknown command %s, unable to handle, skipping", j.Message) log.Errorf("Unknown command %s, unable to handle, skipping", j.Message)
@@ -444,7 +470,7 @@ func MsgParser(cfg *config.MyConfig, ctx context.Context, msg string) {
} }
// Настало время формировать json и засылать его в дальше // Настало время формировать json и засылать его в дальше
var message SMsg var message types.SMsg
message.From = j.From message.From = j.From
message.Userid = j.Userid message.Userid = j.Userid
message.Chatid = j.Chatid message.Chatid = j.Chatid
@@ -477,7 +503,7 @@ func MsgParser(cfg *config.MyConfig, ctx context.Context, msg string) {
} }
// ValidateRmsg валидирует входящее сообщение. // ValidateRmsg валидирует входящее сообщение.
func ValidateRmsg(cfg *config.MyConfig, j RMsg, msg string) (RMsg, error) { func ValidateRmsg(cfg *config.MyConfig, j types.RMsg, msg string) (types.RMsg, error) {
if exist := j.From; exist == "" { if exist := j.From; exist == "" {
emsg := fmt.Errorf("incorrect msg from redis, no from field: %s", msg) emsg := fmt.Errorf("incorrect msg from redis, no from field: %s", msg)

View File

@@ -3,6 +3,7 @@ package openweathermap
import ( import (
"aleesa-webapp-go/internal/config" "aleesa-webapp-go/internal/config"
"aleesa-webapp-go/internal/pcachedb" "aleesa-webapp-go/internal/pcachedb"
"crypto/sha256"
"fmt" "fmt"
"net/http" "net/http"
"strconv" "strconv"
@@ -357,4 +358,32 @@ func QueryOwmCache(cfg *config.MyConfig, item OwmItem) (string, error) {
return answer, err return answer, err
} }
// Записывает в кэш, кто каким городом интересовался в последний раз, когда спрашивал о погоде.
// STUB
func UpdateOwmUserCache(cfg *config.MyConfig, chatid string, entry string, value string) error {
var err error
// Chatid как есть лучше на диск не пробовать класть, мало ли что туда юзер впишет. Возьмём от него sha256.
data := []byte(chatid)
hash := fmt.Sprintf("%x", sha256.Sum256(data))
if err = pcachedb.SaveKeyWithValue(cfg, hash, entry, value); err != nil {
return fmt.Errorf("OWM-Cache: unable to save timestamp to cache: %w", err)
}
return err
}
// Возвращает из кэша город, которым интересовался пользователь из даденного чятика.
func QueryOwmUserCache(cfg *config.MyConfig, chatid string, entry string) string {
// Chatid как есть лучше на диск не пробовать класть, мало ли что туда юзер впишет. Возьмём от него sha256.
var (
data = []byte(chatid)
hash = fmt.Sprintf("%x", sha256.Sum256(data))
value = pcachedb.GetValue(cfg, hash, entry)
)
return value
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */ /* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

View File

@@ -1,4 +1,4 @@
package lib package types
// RMsg структурка, описывающая входящее сообщение из pubsub-канала redis-ки. // RMsg структурка, описывающая входящее сообщение из pubsub-канала redis-ки.
type RMsg struct { type RMsg struct {