diff --git a/command_handler.go b/command_handler.go new file mode 100644 index 0000000..2330320 --- /dev/null +++ b/command_handler.go @@ -0,0 +1,54 @@ +package main + +import ( + "html/template" + "log" + "sync" + + "git.sr.ht/~michalr/go-satel" + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" +) + +func handleStatusCommand(dataStore *DataStore, msg tgbotapi.MessageConfig, bot *tgbotapi.BotAPI, tpl *template.Template, + s SatelNameGetter, logger *log.Logger) { + data := dataStore.GetGenericMessageOfAllowedPartitions(satel.ArmedPartition) + msg.Text = data.Format(tpl, s, logger) + + if _, err := bot.Send(msg); err != nil { + log.Panic(err) + } +} + +func HandleIncomingCommands(dataStore *DataStore, tgChan tgbotapi.UpdatesChannel, bot *tgbotapi.BotAPI, wg *sync.WaitGroup, + tpl *template.Template, s SatelNameGetter, quitChan <-chan interface{}, logger *log.Logger) { + wg.Add(1) + defer wg.Done() + + for { + select { + case update, ok := <-tgChan: + if ok == false { // quit when tgChan closes + return + } + + if update.Message == nil { // ignore any non-Message updates + continue + } + + if !update.Message.IsCommand() { // ignore any non-command Messages + continue + } + + msg := tgbotapi.NewMessage(update.Message.Chat.ID, "") + msg.ReplyToMessageID = update.Message.MessageID + switch update.Message.Command() { + case "status": + handleStatusCommand(dataStore, msg, bot, tpl, s, logger) + default: + logger.Print("Received an unknown command: ", update.Message.Command()) + } + case <-quitChan: + return + } + } +} diff --git a/command_handler_test.go b/command_handler_test.go new file mode 100644 index 0000000..3310d52 --- /dev/null +++ b/command_handler_test.go @@ -0,0 +1,12 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCommandHandler_Status(t *testing.T) { + a := assert.New(t) + a.True(true) +} diff --git a/data_store.go b/data_store.go index bf73071..3adea44 100644 --- a/data_store.go +++ b/data_store.go @@ -37,6 +37,7 @@ type DataStore struct { mtx sync.Mutex logger *log.Logger persistenceFilePath string + allowedPartitions []int lastSeen map[EventKey]EventValue } @@ -99,7 +100,7 @@ func (self *DataStore) saveSystemState() { } } -func MakeDataStore(logger *log.Logger, persistenceFilePath string) DataStore { +func MakeDataStore(logger *log.Logger, persistenceFilePath string, allowedPartitions []int) DataStore { return DataStore{ logger: logger, persistenceFilePath: persistenceFilePath, @@ -118,6 +119,44 @@ func (self *DataStore) GetSystemState() map[EventKey]EventValue { return copiedMap } +func (self *DataStore) isMessageAllowed(key EventKey, allowedType satel.ChangeType) bool { + if key.ChangeType != allowedType { + return false + } + if len(self.allowedPartitions) == 0 { + // all partitions are allowed + return true + } + for _, allowedIndex := range self.allowedPartitions { + if key.Index == allowedIndex { + return true + } + } + return false +} + +func (self *DataStore) GetGenericMessageOfAllowedPartitions(allowedType satel.ChangeType) GenericMessage { + self.mtx.Lock() + defer self.mtx.Unlock() + + messages := make([]satel.BasicEventElement, 0) + + for key, value := range self.lastSeen { + if self.isMessageAllowed(key, allowedType) { + messages = append(messages, satel.BasicEventElement{ + Type: key.ChangeType, + Index: key.Index, + Value: value.Value, + }) + } + } + + return GenericMessage{ + ChatIds: EmptyChatId{}, + Messages: messages, + } +} + func (self *DataStore) SetSystemState(key EventKey, value EventValue) { self.mtx.Lock() self.lastSeen[key] = value diff --git a/filters_test.go b/filters_test.go index 370f144..e826812 100644 --- a/filters_test.go +++ b/filters_test.go @@ -130,7 +130,7 @@ func TestSatelLastSeenFiltering(t *testing.T) { receivedEvents := make([]satel.Event, 0) wg := sync.WaitGroup{} fakeLog := log.New(io.Discard, "", log.Ltime) - ds := MakeDataStore(fakeLog, tempFileName) + ds := MakeDataStore(fakeLog, tempFileName, []int{}) go func() { wg.Add(1) @@ -166,7 +166,7 @@ func TestSatelLastSeenFilteringWithPersistence(t *testing.T) { receivedEvents := make([]satel.Event, 0) wg := sync.WaitGroup{} fakeLog := log.New(io.Discard, "", log.Ltime) - ds := MakeDataStore(fakeLog, tempFileName) + ds := MakeDataStore(fakeLog, tempFileName, []int{}) go func() { wg.Add(1) @@ -193,7 +193,7 @@ func TestSatelLastSeenFilteringWithPersistence(t *testing.T) { testEvents = make(chan satel.Event) receivedEvents = make([]satel.Event, 0) - ds = MakeDataStore(fakeLog, tempFileName) + ds = MakeDataStore(fakeLog, tempFileName, []int{}) go func() { wg.Add(1) for e := range FilterByLastSeen(testEvents, &wg, &ds, fakeLog) { diff --git a/main.go b/main.go index f0da7a7..9214eeb 100644 --- a/main.go +++ b/main.go @@ -148,7 +148,7 @@ func main() { tpl := template.Must(template.New("TelegramMessage").Parse(TelegramMessageTemplate)) - dataStore := MakeDataStore(log.New(os.Stderr, "DataStore", log.Lmicroseconds), getPersistenceFilePath()) + dataStore := MakeDataStore(log.New(os.Stderr, "DataStore", log.Lmicroseconds), getPersistenceFilePath(), allowedIndexes) Consume( SendToTg(Throttle(NotifyViaHTTP(tgEvents, &wg, log.New(os.Stderr, "HTTPNotify", log.Lmicroseconds)), diff --git a/sender_worker.go b/sender_worker.go index c898e95..7cb16ef 100644 --- a/sender_worker.go +++ b/sender_worker.go @@ -30,10 +30,16 @@ type TgChatId struct { tgChatId int64 } +type EmptyChatId struct{} + func (self TgChatId) GetTgIds() *[]int64 { return &[]int64{self.tgChatId} } +func (self EmptyChatId) GetTgIds() *[]int64 { + return nil +} + func Consume(events <-chan GenericMessage) { go func() { for range events {