diff --git a/cmd/valera/main.go b/cmd/valera/main.go index 38af6e7..f51c4de 100644 --- a/cmd/valera/main.go +++ b/cmd/valera/main.go @@ -14,12 +14,13 @@ import ( "valera/internal/states/ping_bot_state" "valera/internal/states/start_bot_state" "valera/internal/states/stat_bot_state" + "valera/internal/states/weight_bot_state" tgbot "github.com/go-telegram-bot-api/telegram-bot-api" ) const ( - version = "v1.7.3" + version = "v1.8.0" ) func main() { @@ -52,6 +53,7 @@ func main() { ping_bot_state.NewPingBotState(bot, dataBase), pause_bot_state.NewPauseBotState(bot, dataBase), eat_bot_state.NewEatBotState(bot, dataBase), + weight_bot_state.NewWeightBotState(bot, dataBase), } go func() { diff --git a/internal/config/config.go b/internal/config/config.go index 7b96739..8042779 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -17,6 +17,7 @@ type MongoConfig struct { ChatsCollectionName string WorkoutsCollectionName string CaloriesCollectionName string + WeightCollectionName string } type TgConfig struct { @@ -50,6 +51,7 @@ func NewAppConfig() *AppConfig { ChatsCollectionName: "chats", WorkoutsCollectionName: "workouts", CaloriesCollectionName: "calories", + WeightCollectionName: "weights", }, TgConfig: &TgConfig{ Token: token, diff --git a/internal/db/chat.go b/internal/db/chat.go index 775ae58..e583736 100644 --- a/internal/db/chat.go +++ b/internal/db/chat.go @@ -1,10 +1,11 @@ package db const ( - UserStateNone = UserState("") - UserStateGo = UserState("Go") - UserStateEat = UserState("Eat") - UserStatePause = UserState("Pause") + UserStateNone = UserState("") + UserStateGo = UserState("Go") + UserStateEat = UserState("Eat") + UserStatePause = UserState("Pause") + UserStateWeight = UserState("Weight") ) type UserState string diff --git a/internal/db/db.go b/internal/db/db.go index 0e85558..377bd21 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -16,6 +16,7 @@ type DB struct { chatsColection *mongo.Collection workoutsColection *mongo.Collection caloriesColection *mongo.Collection + weightColection *mongo.Collection } func NewDB( @@ -35,6 +36,7 @@ func NewDB( chatsColection: client.Database(cfg.MongoConfig.DBName).Collection(cfg.MongoConfig.ChatsCollectionName), workoutsColection: client.Database(cfg.MongoConfig.DBName).Collection(cfg.MongoConfig.WorkoutsCollectionName), caloriesColection: client.Database(cfg.MongoConfig.DBName).Collection(cfg.MongoConfig.CaloriesCollectionName), + weightColection: client.Database(cfg.MongoConfig.DBName).Collection(cfg.MongoConfig.WeightCollectionName), }, nil } @@ -82,9 +84,6 @@ func (db *DB) AddWorkout(chatID int64, workout *Workout) error { func (db *DB) AddCalories(chatID int64, calories *Calories) error { ctx := context.Background() - if calories.Count <= 0 { - return nil - } if err := db.AddChat(chatID); err != nil { return err } @@ -97,6 +96,24 @@ func (db *DB) AddCalories(chatID int64, calories *Calories) error { return err } +func (db *DB) AddWeight(chatID int64, weight *Weight) error { + ctx := context.Background() + + if weight.Weight <= 0 { + return nil + } + if err := db.AddChat(chatID); err != nil { + return err + } + weight.ChatID = chatID + + _, err := db.weightColection.InsertOne( + ctx, + weight, + ) + return err +} + func (db *DB) GetChatInfo(chatID int64, username string) (*ChatInfo, error) { ctx := context.Background() @@ -135,14 +152,14 @@ func (db *DB) SetPause(chatID int64, duration time.Duration) error { return err } -func (db *DB) GetStatAfter(chatID int64, t time.Time) (map[string]int, error) { +func (db *DB) GetStatAfter(chatID int64, t time.Time) (map[string]float64, error) { ctx := context.Background() if err := db.AddChat(chatID); err != nil { return nil, err } - res := map[string]int{} + res := map[string]float64{} cursor, err := db.workoutsColection.Find( ctx, @@ -159,7 +176,7 @@ func (db *DB) GetStatAfter(chatID int64, t time.Time) (map[string]int, error) { if err := cursor.Decode(&result); err != nil { log.Fatal(err) } - res[result.Name] += result.Count + res[result.Name] += float64(result.Count) } if err := cursor.Err(); err != nil { log.Fatal(err) @@ -180,12 +197,33 @@ func (db *DB) GetStatAfter(chatID int64, t time.Time) (map[string]int, error) { if err := caloriesCursor.Decode(&result); err != nil { log.Fatal(err) } - res["Калории"] += result.Count + res["Калории"] += float64(result.Count) } if err := caloriesCursor.Err(); err != nil { log.Fatal(err) } + weightCursor, err := db.weightColection.Find( + ctx, + bson.M{ + "chat_id": chatID, + "created_at": bson.M{"$gt": t}, + }, + ) + if err != nil { + return nil, err + } + for weightCursor.Next(context.Background()) { + var result Weight + if err := weightCursor.Decode(&result); err != nil { + log.Fatal(err) + } + res["Вес кг"] = result.Weight + } + if err := weightCursor.Err(); err != nil { + log.Fatal(err) + } + return res, err } diff --git a/internal/db/weight.go b/internal/db/weight.go new file mode 100644 index 0000000..a92052f --- /dev/null +++ b/internal/db/weight.go @@ -0,0 +1,22 @@ +package db + +import "time" + +type Weight struct { + ChatID int64 `bson:"chat_id"` + Weight float64 `bson:"weight"` + CreatedAt time.Time `bson:"created_at"` + Username string `bson:"username"` +} + +func NewWeight( + weight float64, + username string, +) *Weight { + loc, _ := time.LoadLocation("Asia/Novosibirsk") + return &Weight{ + Weight: weight, + Username: username, + CreatedAt: time.Now().In(loc), + } +} diff --git a/internal/states/eat_bot_state/eat_bot_state.go b/internal/states/eat_bot_state/eat_bot_state.go index 63e7d60..994f739 100644 --- a/internal/states/eat_bot_state/eat_bot_state.go +++ b/internal/states/eat_bot_state/eat_bot_state.go @@ -38,10 +38,6 @@ func (s *eatBotState) Do(text string, chatInfo *db.ChatInfo) error { log.Println(err) return nil } - if count <= 0 { - _, _ = s.bot.Send(tgbot.NewMessage(chatInfo.ChatID, "Все фигня, давай по новой")) - return nil - } _, _ = s.bot.Send(tgbot.NewMessage(chatInfo.ChatID, fmt.Sprintf("Калории, фу, %d, записал.", count))) return s.dataBase.SetStatusToChat(chatInfo.ChatID, db.UserStateNone) } diff --git a/internal/states/go_bot_state/go_bot_state.go b/internal/states/go_bot_state/go_bot_state.go index f0dbf6c..f54b03c 100644 --- a/internal/states/go_bot_state/go_bot_state.go +++ b/internal/states/go_bot_state/go_bot_state.go @@ -77,10 +77,11 @@ func (s *goBotState) Do(text string, chatInfo *db.ChatInfo) error { return nil } - if slices.Contains(names, text) { - s.sendGoToChat(chatInfo.ChatID) + if !slices.Contains(names, text) { + return nil } - + + s.sendGoToChat(chatInfo.ChatID) return nil } diff --git a/internal/states/stat_bot_state/stat_bot_state.go b/internal/states/stat_bot_state/stat_bot_state.go index 89f99b5..b073082 100644 --- a/internal/states/stat_bot_state/stat_bot_state.go +++ b/internal/states/stat_bot_state/stat_bot_state.go @@ -84,7 +84,7 @@ func (s *statBotState) sendStatToChatAfter(chatID int64, prefix string, t time.T return err } for k, v := range stat { - msgText += fmt.Sprintf("- %s: %d\n", k, v) + msgText += fmt.Sprintf("- %s: %v\n", k, v) } _, _ = s.bot.Send(tgbot.NewMessage(chatID, msgText)) return nil diff --git a/internal/states/weight_bot_state/weight_bot_state.go b/internal/states/weight_bot_state/weight_bot_state.go new file mode 100644 index 0000000..bc2c630 --- /dev/null +++ b/internal/states/weight_bot_state/weight_bot_state.go @@ -0,0 +1,89 @@ +package weight_bot_state + +import ( + "fmt" + "log" + "net/http" + "strconv" + "strings" + "valera/internal/db" + "valera/internal/states" + + tgbot "github.com/go-telegram-bot-api/telegram-bot-api" + "golang.org/x/exp/slices" +) + +var names = []string{ + "/weight", +} + +type weightBotState struct { + bot *tgbot.BotAPI + dataBase *db.DB +} + +func NewWeightBotState(bot *tgbot.BotAPI, dataBase *db.DB) states.BotState { + return &weightBotState{ + bot: bot, + dataBase: dataBase, + } +} + +func (s *weightBotState) Do(text string, chatInfo *db.ChatInfo) error { + if chatInfo.Status == string(db.UserStateWeight) { + weight, err := getWeight(text) + if err != nil { + log.Println(err) + return nil + } + if weight <= 0 { + _, _ = s.bot.Send(tgbot.NewMessage(chatInfo.ChatID, "Все фигня, давай по новой")) + return nil + } + if err := s.dataBase.AddWeight(chatInfo.ChatID, db.NewWeight(weight, chatInfo.Username)); err != nil { + log.Println(err) + return nil + } + _, _ = s.bot.Send(tgbot.NewMessage(chatInfo.ChatID, fmt.Sprintf("%vкг, записал.", weight))) + return s.dataBase.SetStatusToChat(chatInfo.ChatID, db.UserStateNone) + } + + if !slices.Contains(names, text) { + return nil + } + + s.sendWeightToChat(chatInfo.ChatID) + return nil +} + +func (s *weightBotState) GetHandler() (string, func(http.ResponseWriter, *http.Request)) { + return names[0], func(w http.ResponseWriter, r *http.Request) { + chats, err := s.dataBase.GetAllChats() + if err != nil { + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusInternalServerError) + _, _ = fmt.Fprintf(w, `{"result":"error"}`) + return + } + for _, chatID := range chats { + s.sendWeightToChat(chatID) + } + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = fmt.Fprintf(w, `{"result":"ok"}`) + } +} + +func (s *weightBotState) sendWeightToChat(chatID int64) { + msg := tgbot.NewMessage(chatID, "Давай взвешивайся, отпишись сколько кг ты весишь") + if _, err := s.bot.Send(msg); err == nil { + if err := s.dataBase.SetStatusToChat(chatID, db.UserStateWeight); err != nil { + log.Println(err) + } + } +} + +func getWeight(text string) (float64, error) { + number := strings.ReplaceAll(text, ",", ".") + return strconv.ParseFloat(number, 64) +}