diff --git a/app.go b/app.go index 8ee7bdc..944d733 100644 --- a/app.go +++ b/app.go @@ -57,15 +57,16 @@ func (a *app) makeBotService() (s *tlg.BotService) { Storage: a.storage, Version: a.version, } - handler.Init() - return &tlg.BotService{ - Bot: bot, + service := tlg.BotService{ + Bot: bot, Handler: handler, } + service.Init() + return &service } -func (a app) printVersion() { +func (a *app) printVersion() { fmt.Printf("Version: %s\nCommit: %s\nRuntime: %s %s/%s\nDate: %s\n", a.version, a.commit, @@ -75,3 +76,7 @@ func (a app) printVersion() { a.date, ) } + +func (a *app) Close() () { + a.storage.Close() +} diff --git a/show.go b/show.go index c583f0f..287b27c 100644 --- a/show.go +++ b/show.go @@ -2,19 +2,13 @@ package main import ( "fmt" - "github.com/taras-by/tbot/store" - "log" ) func show() (err error) { + a := newApp() + defer a.Close() - storage, err := store.NewStorage(Opts.StorePath) - if err != nil { - log.Fatal(err) - } - defer storage.Close() - - for _, p := range storage.FindAll() { + for _, p := range a.storage.FindAll() { fmt.Printf("Participant: %v\n", p) } diff --git a/store/storage.go b/store/storage.go index 2ace90b..09bcc46 100644 --- a/store/storage.go +++ b/store/storage.go @@ -42,7 +42,7 @@ func NewStorage(storePath string) (*Storage, error) { func (s *Storage) Close() () { _ = s.db.Close() - log.Printf("Storage closed") + log.Print("Storage closed") } func (s *Storage) Create(participant Participant) Participant { @@ -184,6 +184,11 @@ func (s *Storage) FindByChatId(chatId int64) (participants []Participant) { return participants } +func (s *Storage) CountByChatId(chatId int64) int { + participants := s.FindByChatId(chatId) + return len(participants) +} + func (s *Storage) list(bucketName string) (values [][]byte) { s.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(bucketName)) diff --git a/tbot.go b/tbot.go index 26bf0be..d867b39 100644 --- a/tbot.go +++ b/tbot.go @@ -66,7 +66,7 @@ func showCmd() command { func runCmd() command { return command{fn: func([]string) error { a := newApp() - defer a.storage.Close() + defer a.Close() s := a.makeBotService() return s.Run() }} diff --git a/telegram/handler.go b/telegram/handler.go index 025b656..d4a1f52 100644 --- a/telegram/handler.go +++ b/telegram/handler.go @@ -13,6 +13,7 @@ import ( const ( maxLengthStringArgument = 50 + maxParticipants = 100 ) type MessageHandler struct { @@ -35,24 +36,6 @@ type conversation struct { message *tgbotapi.Message } -func (h *MessageHandler) Init() { - h.routes = []route{ - {`add`, ``, h.addMe}, - {`add`, `^@(\S+)$`, h.addByLink}, - {`add`, `^\d+$`, h.addByNumber}, - {`add`, `^.+$`, h.addByName}, - {`rm`, ``, h.removeMe}, - {`rm`, `^@(\S+)$`, h.removeByLink}, - {`rm`, `^\d+$`, h.removeByNumber}, - {`rm`, `^.+$`, h.removeByName}, - {`list`, ``, h.list}, - {`ping`, ``, h.ping}, - {`reset`, ``, h.reset}, - {`start`, ``, h.help}, - {`help`, ``, h.help}, - } -} - func (h *MessageHandler) handle(message *tgbotapi.Message) { if message == nil { // ignore any non-Message Updates return @@ -128,6 +111,11 @@ func (h *MessageHandler) addMe(c conversation) { } } + if h.Storage.CountByChatId(c.chatId) >= maxParticipants { + h.sendMessageToChat(c.chatId, fmt.Sprintf("Maximum chat participants: *%v*", maxParticipants)) + return + } + participant := h.Storage.Create( store.Participant{ User: store.User{ @@ -142,8 +130,8 @@ func (h *MessageHandler) addMe(c conversation) { }, ) - h.sendMessageToChat(c.chatId, fmt.Sprintf("Added %s", store.Escape(participant.Link()))) - text := h.participantsText(c.chatId) + text := fmt.Sprintf("*Added %s*", store.Escape(participant.Link())) + "\n" + + h.participantsText(c.chatId) h.sendMessageToChat(c.chatId, text) } @@ -162,6 +150,11 @@ func (h *MessageHandler) addByLink(c conversation) { return } + if h.Storage.CountByChatId(c.chatId) >= maxParticipants { + h.sendMessageToChat(c.chatId, fmt.Sprintf("Maximum chat participants: *%v*", maxParticipants)) + return + } + participant := h.Storage.Create( store.Participant{ User: store.User{ @@ -173,13 +166,24 @@ func (h *MessageHandler) addByLink(c conversation) { }, ) - h.sendMessageToChat(c.chatId, fmt.Sprintf("Added %s", store.Escape(participant.Link()))) - text := h.participantsText(c.chatId) + text := fmt.Sprintf("*Added %s*", store.Escape(participant.Link())) + "\n" + + h.participantsText(c.chatId) h.sendMessageToChat(c.chatId, text) } func (h *MessageHandler) addByName(c conversation) { + existingParticipant, err := h.Storage.FindByName(c.args, c.chatId) + if err == nil && existingParticipant.Id() != "" { + h.sendMessageToChat(c.chatId, "User is already in the list of participants") + return + } + + if h.Storage.CountByChatId(c.chatId) >= maxParticipants { + h.sendMessageToChat(c.chatId, fmt.Sprintf("Maximum chat participants: *%v*", maxParticipants)) + return + } + participant := h.Storage.Create( store.Participant{ User: store.User{ @@ -191,8 +195,8 @@ func (h *MessageHandler) addByName(c conversation) { }, ) - h.sendMessageToChat(c.chatId, fmt.Sprintf("Added %s", store.Escape(participant.Link()))) - text := h.participantsText(c.chatId) + text := fmt.Sprintf("*Added %s*", store.Escape(participant.Link())) + "\n" + + h.participantsText(c.chatId) h.sendMessageToChat(c.chatId, text) } @@ -202,10 +206,7 @@ func (h *MessageHandler) addByNumber(c conversation) { func (h *MessageHandler) removeMe(c conversation) { - var participant store.Participant - var err error - - participant, err = h.Storage.Find(strconv.Itoa(c.message.From.ID), c.chatId) + participant, err := h.Storage.Find(strconv.Itoa(c.message.From.ID), c.chatId) if err != nil { participant, err = h.Storage.FindByLink("@"+c.message.From.UserName, c.chatId) if err != nil { @@ -215,17 +216,14 @@ func (h *MessageHandler) removeMe(c conversation) { } h.Storage.Delete(participant) - h.sendMessageToChat(c.chatId, fmt.Sprintf("Removed %s", store.Escape(participant.Link()))) - text := h.participantsText(c.chatId) + text := fmt.Sprintf("*Removed %s*", store.Escape(participant.Link())) + "\n" + + h.participantsText(c.chatId) h.sendMessageToChat(c.chatId, text) } func (h *MessageHandler) removeByNumber(c conversation) { - var participant store.Participant - var err error - numberString := string(c.checker.Find([]byte(c.args))) number, err := strconv.Atoi(numberString) if err != nil { @@ -233,53 +231,47 @@ func (h *MessageHandler) removeByNumber(c conversation) { return } - participant, err = h.Storage.FindByNumber(number, c.chatId) + participant, err := h.Storage.FindByNumber(number, c.chatId) if err != nil { h.sendMessageToChat(c.chatId, store.Escape(err.Error())) return } h.Storage.Delete(participant) - h.sendMessageToChat(c.chatId, fmt.Sprintf("Removed %s", store.Escape(participant.Link()))) - text := h.participantsText(c.chatId) + text := fmt.Sprintf("*Removed %s*", store.Escape(participant.Link())) + "\n" + + h.participantsText(c.chatId) h.sendMessageToChat(c.chatId, text) } func (h *MessageHandler) removeByLink(c conversation) { - var participant store.Participant - var err error - linkString := string(c.checker.Find([]byte(c.args))) - participant, err = h.Storage.FindByLink(linkString, c.chatId) + participant, err := h.Storage.FindByLink(linkString, c.chatId) if err != nil { h.sendMessageToChat(c.chatId, store.Escape(err.Error())) return } h.Storage.Delete(participant) - h.sendMessageToChat(c.chatId, fmt.Sprintf("Removed %s", store.Escape(participant.Link()))) - text := h.participantsText(c.chatId) + text := fmt.Sprintf("*Removed %s*", store.Escape(participant.Link())) + "\n" + + h.participantsText(c.chatId) h.sendMessageToChat(c.chatId, text) } func (h *MessageHandler) removeByName(c conversation) { - var participant store.Participant - var err error - - participant, err = h.Storage.FindByName(c.args, c.chatId) + participant, err := h.Storage.FindByName(c.args, c.chatId) if err != nil { h.sendMessageToChat(c.chatId, store.Escape(err.Error())) return } h.Storage.Delete(participant) - h.sendMessageToChat(c.chatId, fmt.Sprintf("Removed %s", store.Escape(participant.Link()))) - text := h.participantsText(c.chatId) + text := fmt.Sprintf("*Removed %s*", store.Escape(participant.Link())) + "\n" + + h.participantsText(c.chatId) h.sendMessageToChat(c.chatId, text) } @@ -323,7 +315,7 @@ func (h *MessageHandler) participantsText(chatId int64) (text string) { if len(participants) == 0 { return "No participants" } - text = "List of participants:\n" + text = "Participants:\n" for i, p := range participants { text = text + fmt.Sprintf(" *%v)* %v\n", i+1, store.Escape(p.Name())) } diff --git a/telegram/telegram.go b/telegram/telegram.go index 3d04192..8c1bf52 100644 --- a/telegram/telegram.go +++ b/telegram/telegram.go @@ -9,6 +9,25 @@ type BotService struct { Handler *MessageHandler } +func (s *BotService) Init() { + h := s.Handler + h.routes = []route{ + {`add`, ``, h.addMe}, + {`add`, `^@(\S+)$`, h.addByLink}, + {`add`, `^\d+$`, h.addByNumber}, + {`add`, `^.+$`, h.addByName}, + {`rm`, ``, h.removeMe}, + {`rm`, `^@(\S+)$`, h.removeByLink}, + {`rm`, `^\d+$`, h.removeByNumber}, + {`rm`, `^.+$`, h.removeByName}, + {`list`, ``, h.list}, + {`ping`, ``, h.ping}, + {`reset`, ``, h.reset}, + {`start`, ``, h.help}, + {`help`, ``, h.help}, + } +} + func (s *BotService) Run() error { updates, err := s.chatUpdates()