From 654f34083831b81b8f18fe729fa501d6fa667c72 Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Mon, 27 Nov 2023 19:37:59 +0100 Subject: [PATCH] Use callback as interface in `model` module --- bot/bot.go | 17 +++++++++- json/actions.json | 4 ++- bot/callbacks.go => model/callback.go | 47 ++++++++++++++++++++++----- model/model.go | 2 ++ model/timetables.go | 2 +- model/timetables_test.go | 46 ++++++++++++++------------ 6 files changed, 87 insertions(+), 31 deletions(-) rename bot/callbacks.go => model/callback.go (57%) diff --git a/bot/bot.go b/bot/bot.go index 0c3e7de..35fabc6 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -44,7 +44,7 @@ func run(bot *tgbotapi.BotAPI) { callback_text := update.CallbackQuery.Data if strings.HasPrefix(callback_text, "lectures_") { - lecturesCallback(bot, &update, callback_text) + handleCallback(bot, &update, "lezioni", callback_text) } continue @@ -268,6 +268,21 @@ func handleAction(bot *tgbotapi.BotAPI, update *tgbotapi.Update, commandName str return false } +// Handle a callback searching a the good action +func handleCallback(bot *tgbotapi.BotAPI, update *tgbotapi.Update, commandName string, callback_text string) bool { + idx := slices.IndexFunc(model.Actions, func(action model.Action) bool { + return action.Name == commandName + }) + + if idx != -1 { + model.Actions[idx].Data.HandleBotCallback(bot, update, callback_text) + + return true + } + + return false +} + func filterMessage(bot *tgbotapi.BotAPI, message *tgbotapi.Message) bool { if message.Dice != nil { // msg := tgbotapi.NewMessage(message.Chat.ID, "Found a dice") diff --git a/json/actions.json b/json/actions.json index 268d0c7..7e5a1c8 100644 --- a/json/actions.json +++ b/json/actions.json @@ -94,7 +94,9 @@ "lezioni": { "type": "buttonsLecture", "data": { - "description": "Orari lezioni" + "description": "Orari lezioni", + "title": " Lezioni di %s di (%d\u00b0 anno) di giorno %s", + "fallbackText": "Non ci sono lezioni in questo giorno. SMETTILA DI PRESSARMI ao" } }, "materiali": { diff --git a/bot/callbacks.go b/model/callback.go similarity index 57% rename from bot/callbacks.go rename to model/callback.go index 5ea0666..ceeabaf 100644 --- a/bot/callbacks.go +++ b/model/callback.go @@ -1,4 +1,4 @@ -package bot +package model import ( "fmt" @@ -11,15 +11,34 @@ import ( tgbotapi "github.com/musianisamuele/telegram-bot-api" "github.com/csunibo/informabot/commands" - "github.com/csunibo/informabot/model" ) +func (_ MessageData) HandleBotCallback(_bot *tgbotapi.BotAPI, _udpate *tgbotapi.Update, _callback_text string) { + log.Printf("`HandleBotCallback` not defined for `MessageData`") +} + +func (_ HelpData) HandleBotCallback(_bot *tgbotapi.BotAPI, _udpate *tgbotapi.Update, _callback_text string) { + log.Printf("`HandleBotCallback` not defined for `HelpData`") +} + +func (_ IssueData) HandleBotCallback(_bot *tgbotapi.BotAPI, _udpate *tgbotapi.Update, _callback_text string) { + log.Printf("`HandleBotCallback` not defined for `IssueData`") +} + +func (_ LookingForData) HandleBotCallback(_bot *tgbotapi.BotAPI, _udpate *tgbotapi.Update, _callback_text string) { + log.Printf("`HandleBotCallback` not defined for `LookingForData`") +} + +func (_ NotLookingForData) HandleBotCallback(_bot *tgbotapi.BotAPI, _udpate *tgbotapi.Update, _callback_text string) { + log.Printf("`HandleBotCallback` not defined for `NotLookingForData`") +} + // Handle the callback for the lectures command (`/lezioni`) // Parse the `callback_text` to check which operation it must to do: // - If the string ends with "_today" or "_tomorrow" it returns the timetable // - If the string just contains a "_y_" it asks for today or tomorrow // - Otherwise prints the course year of what timetable the user wants to see -func lecturesCallback(bot *tgbotapi.BotAPI, update *tgbotapi.Update, callback_text string) { +func (data Lectures) HandleBotCallback(bot *tgbotapi.BotAPI, update *tgbotapi.Update, callback_text string) { var chatId = int64(update.CallbackQuery.Message.Chat.ID) var messageId = update.CallbackQuery.Message.MessageID @@ -52,16 +71,16 @@ func lecturesCallback(bot *tgbotapi.BotAPI, update *tgbotapi.Update, callback_te timetableKey := callback_text[len("lectures_"):strings.Index(callback_text, "_y_")] - timetable := model.Timetables[timetableKey] + timetable := Timetables[timetableKey] response, err := commands.GetTimeTable(timetable.Type, timetable.Name, timetable.Curriculum, year, timeForLectures) if err != nil { log.Printf("Error [GetTimeTable]: %s\n", err) } if response == "" { - response = timetable.FallbackText + response = data.FallbackText } else { - response = fmt.Sprintf(timetable.Title, timetable.Course, year, timeForLectures.Format("2006-01-02")) + "\n\n" + response + response = fmt.Sprintf(data.Title, timetable.Course, year, timeForLectures.Format("2006-01-02")) + "\n\n" + response } editConfig := tgbotapi.NewEditMessageText(chatId, messageId, response) @@ -72,7 +91,7 @@ func lecturesCallback(bot *tgbotapi.BotAPI, update *tgbotapi.Update, callback_te log.Printf("Error [bot.Send() for the NewEditMessageText]: %s\n", err) } } else if strings.Contains(callback_text, "_y_") { - rows := model.ChooseTimetableDay(callback_text) + rows := ChooseTimetableDay(callback_text) keyboard := tgbotapi.NewInlineKeyboardMarkup(rows...) editConfig := tgbotapi.NewEditMessageReplyMarkup(chatId, messageId, keyboard) _, err := bot.Send(editConfig) @@ -81,7 +100,7 @@ func lecturesCallback(bot *tgbotapi.BotAPI, update *tgbotapi.Update, callback_te } } else { timetableName := strings.TrimPrefix(callback_text, "lectures_") - rows := model.GetLectureYears(callback_text, model.Timetables[timetableName].Course) + rows := GetLectureYears(callback_text, Timetables[timetableName].Course) keyboard := tgbotapi.NewInlineKeyboardMarkup(rows...) editConfig := tgbotapi.NewEditMessageReplyMarkup(chatId, messageId, keyboard) _, err := bot.Send(editConfig) @@ -90,3 +109,15 @@ func lecturesCallback(bot *tgbotapi.BotAPI, update *tgbotapi.Update, callback_te } } } + +func (_ ListData) HandleBotCallback(_bot *tgbotapi.BotAPI, _udpate *tgbotapi.Update, _callback_text string) { + log.Printf("`HandleBotCallback` not defined for `ListData`") +} + +func (_ LuckData) HandleBotCallback(_bot *tgbotapi.BotAPI, _udpate *tgbotapi.Update, _callback_text string) { + log.Printf("`HandleBotCallback` not defined for `LuckData`") +} + +func (_ InvalidData) HandleBotCallback(_bot *tgbotapi.BotAPI, _udpate *tgbotapi.Update, _callback_text string) { + log.Printf("`HandleBotCallback` not defined for `InvalidData`") +} diff --git a/model/model.go b/model/model.go index e1c49f2..4e98815 100644 --- a/model/model.go +++ b/model/model.go @@ -9,6 +9,7 @@ import ( type DataInterface interface { HandleBotCommand(bot *tgbotapi.BotAPI, message *tgbotapi.Message) CommandResponse + HandleBotCallback(bot *tgbotapi.BotAPI, update *tgbotapi.Update, callback_text string) GetDescription() string } @@ -153,6 +154,7 @@ type NotLookingForData struct { type Lectures struct { Description string `json:"description"` + Title string `json:"title"` FallbackText string `json:"fallbackText"` } diff --git a/model/timetables.go b/model/timetables.go index 4138e97..ed980b5 100644 --- a/model/timetables.go +++ b/model/timetables.go @@ -55,7 +55,7 @@ func GetLectureYears(callback_text string, course string) InlineKeyboardRows { i := 1 for i <= yearsNro { - buttonText := fmt.Sprintf("%s: %d^ anno", course, i) + buttonText := fmt.Sprintf("%s: %d\u00b0 anno", course, i) buttonCallback := fmt.Sprintf("%s_y_%d", callback_text, i) row := tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData(buttonText, buttonCallback)) rows[i-1] = row diff --git a/model/timetables_test.go b/model/timetables_test.go index 36553d5..d1e10c0 100644 --- a/model/timetables_test.go +++ b/model/timetables_test.go @@ -9,12 +9,16 @@ import ( ) func TestGetTimetableCoursesRows(t *testing.T) { - var timetables = map[string]Timetable{ + timetables := make([]map[string]Timetable, 2) + + timetables[0] = map[string]Timetable{ "l_informatica": { Course: "Informatica", Type: "laurea", Name: "informatica", }, + } + timetables[1] = map[string]Timetable{ "lm_informatica_software_techniques": { Course: "Informatica Magistrale - Tecniche del software", Type: "magistrale", @@ -22,34 +26,36 @@ func TestGetTimetableCoursesRows(t *testing.T) { Curriculum: "A58-000", }, } + wants := make([]InlineKeyboardRows, 2) + wants[0] = InlineKeyboardRows{tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica", "lectures_l_informatica"))} + wants[1] = InlineKeyboardRows{tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica Magistrale - Tecniche del software", "lectures_lm_informatica_software_techniques"))} type args struct { - data map[string]Timetable + data []map[string]Timetable } tests := []struct { name string args args - want InlineKeyboardRows + want []InlineKeyboardRows }{ { name: "All the timetables from the map", args: args{data: timetables}, - want: InlineKeyboardRows{ - tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica", "lectures_l_informatica")), - tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica Magistrale - Tecniche del software", "lectures_lm_informatica_software_techniques")), - }, + want: wants, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - var got InlineKeyboardRows = GetTimetableCoursesRows(&tt.args.data) - if len(got) != len(tt.want) { - t.Errorf("GetTimetableCoursesRows() = %v, want %v", got, tt.want) - } else { - for i, v := range got { - for j, w := range v { - if w.Text != tt.want[i][j].Text || *w.CallbackData != *tt.want[i][j].CallbackData { - t.Errorf("GetTimetableCoursesRows() = %v, want %v", w, tt.want[i][j]) + for idx, timetable := range tt.args.data { + var got InlineKeyboardRows = GetTimetableCoursesRows(&timetable) + if len(got) != len(tt.want[idx]) { + t.Errorf("GetTimetableCoursesRows() = %v, want %v", got, tt.want) + } else { + for i, v := range got { + for j, w := range v { + if w.Text != tt.want[idx][i][j].Text || *w.CallbackData != *tt.want[idx][i][j].CallbackData { + t.Errorf("GetTimetableCoursesRows() = %v, want %v", w, tt.want[idx][i][j]) + } } } } @@ -118,17 +124,17 @@ func TestGetLectureYears(t *testing.T) { name: "Get rows for bachelor's degree", args: args{data: [2]string{"lectures_l_informatica", "Informatica"}}, want: InlineKeyboardRows{ - tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica: 1^ anno", "lectures_l_informatica_y_1")), - tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica: 2^ anno", "lectures_l_informatica_y_2")), - tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica: 3^ anno", "lectures_l_informatica_y_3")), + tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica: 1\u00b0 anno", "lectures_l_informatica_y_1")), + tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica: 2\u00b0 anno", "lectures_l_informatica_y_2")), + tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica: 3\u00b0 anno", "lectures_l_informatica_y_3")), }, }, { name: "Get rows for master's degree", args: args{data: [2]string{"lectures_lm_informatica_software_techniques", "Informatica Magistrale"}}, want: InlineKeyboardRows{ - tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica Magistrale: 1^ anno", "lectures_lm_informatica_software_techniques_y_1")), - tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica Magistrale: 2^ anno", "lectures_lm_informatica_software_techniques_y_2")), + tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica Magistrale: 1\u00b0 anno", "lectures_lm_informatica_software_techniques_y_1")), + tgbotapi.NewInlineKeyboardRow(tgbotapi.NewInlineKeyboardButtonData("Informatica Magistrale: 2\u00b0 anno", "lectures_lm_informatica_software_techniques_y_2")), }, }, }