From 460964a4e1276c556c8e26c10f3f0c4143746efe Mon Sep 17 00:00:00 2001 From: mput Date: Wed, 3 Jul 2024 01:28:23 +0100 Subject: [PATCH] basic reports suport --- app/bot/bot.go | 74 ++++++++++++++++++++++++++++++++--- app/teledger/teledger.go | 30 +++++++++++--- app/teledger/teledger_test.go | 2 +- 3 files changed, 95 insertions(+), 11 deletions(-) diff --git a/app/bot/bot.go b/app/bot/bot.go index e8e59f5..002ba10 100644 --- a/app/bot/bot.go +++ b/app/bot/bot.go @@ -52,6 +52,11 @@ func NewBot(opts *Opts) (*Bot, error) { ldgr := ledger.NewLedger(rs, llmGenerator) tel := teledger.NewTeledger(ldgr) + err = tel.Init() + if err != nil { + return nil, fmt.Errorf("unable to init teledger: %v", err) + } + return &Bot{ opts: opts, teledger: tel, @@ -62,8 +67,9 @@ func NewBot(opts *Opts) (*Bot, error) { func (bot *Bot) Start() error { defaultCommands := []gotgbot.BotCommand{ - {Command: "balance", Description: "Show balance"}, - {Command: "version", Description: "Show version"}, + {Command: "reports", Description: "Show available reports"}, + // {Command: "balance", Description: "Show balance"}, + // {Command: "version", Description: "Show version"}, } smcRes, err := bot.bot.SetMyCommands(defaultCommands, nil) if err != nil { @@ -83,12 +89,18 @@ func (bot *Bot) Start() error { updater := ext.NewUpdater(dispatcher, nil) - dispatcher.AddHandler(handlers.NewCommand("start", wrapUserResponse(start, "start"))) - dispatcher.AddHandler(handlers.NewCommand("version", wrapUserResponse(bot.vesrion, "version"))) + + dispatcher.AddHandler(handlers.NewCommand("/", wrapUserResponse(bot.comment, "comment"))) - dispatcher.AddHandler(handlers.NewCommand("balance", wrapUserResponse(bot.bal, "balance"))) dispatcher.AddHandler(handlers.NewMessage(nil, wrapUserResponse(bot.proposeTransaction, "propose-transaction"))) + dispatcher.AddHandler(handlers.NewCommand("reports", wrapUserResponse(bot.showAvailableReports, "reports"))) + dispatcher.AddHandler(handlers.NewCallback(isReportCallback, wrapUserResponse(bot.showReport, "show-report"))) + + + dispatcher.AddHandler(handlers.NewCommand("start", wrapUserResponse(start, "start"))) + dispatcher.AddHandler(handlers.NewCommand("v", wrapUserResponse(bot.vesrion, "version"))) + dispatcher.AddHandler(handlers.NewCommand("b", wrapUserResponse(bot.bal, "balance"))) // Start receiving updates. @@ -198,3 +210,55 @@ func (bot *Bot) proposeTransaction(ctx *ext.Context) (string, *gotgbot.SendMessa return transaction, &gotgbot.SendMessageOpts{ParseMode: "MarkdownV2"}, nil } + + +func (bot *Bot) showAvailableReports(ctx *ext.Context) (string, *gotgbot.SendMessageOpts, error) { + reports := bot.teledger.Ledger.Config.Reports + + inlineKeyboard := [][]gotgbot.InlineKeyboardButton{} + + for _, report := range reports { + inlineKeyboard = append(inlineKeyboard, []gotgbot.InlineKeyboardButton{ + { + Text: report.Title, + CallbackData: fmt.Sprintf("report:%s", report.Title), + }, + }) + } + + opts := &gotgbot.SendMessageOpts{ + ParseMode: "MarkdownV2", + ReplyMarkup: gotgbot.InlineKeyboardMarkup{ + InlineKeyboard: inlineKeyboard, + }, + + } + + return "Available reports:", opts, nil +} + +func isReportCallback(cq *gotgbot.CallbackQuery) bool { + return true +} + +func (bot *Bot) showReport(ctx *ext.Context) (string, *gotgbot.SendMessageOpts, error) { + cq := ctx.CallbackQuery + _, err := bot.bot.AnswerCallbackQuery(cq.Id, &gotgbot.AnswerCallbackQueryOpts{ + Text: "✔️", + }) + + if err != nil { + slog.Error("unable to answer callback query", "error", err) + } + + + reportTitle := strings.TrimPrefix(cq.Data, "report:") + report, err := bot.teledger.Report(reportTitle) + + if err != nil { + return fmt.Sprintf("Error: %v", err), nil, nil + } + + + return fmt.Sprintf("```\n%s\n```", report), &gotgbot.SendMessageOpts{ParseMode: "MarkdownV2"}, nil +} diff --git a/app/teledger/teledger.go b/app/teledger/teledger.go index 7ce8a94..ef43eb8 100644 --- a/app/teledger/teledger.go +++ b/app/teledger/teledger.go @@ -10,13 +10,13 @@ import ( // Teledger is the service that handles all the // operations related to the Ledger files type Teledger struct { - ledger *ledger.Ledger + Ledger *ledger.Ledger } func NewTeledger(ldgr *ledger.Ledger) *Teledger { return &Teledger{ - ledger: ldgr, + Ledger: ldgr, } } @@ -41,7 +41,7 @@ func (tel *Teledger) AddComment(comment string) (string, error) { now.Format("2006-01-02"), ) - res, err := tel.ledger.AddComment(commitLine) + res, err := tel.Ledger.AddComment(commitLine) if err != nil { return "", err } @@ -49,7 +49,27 @@ func (tel *Teledger) AddComment(comment string) (string, error) { } func (tel *Teledger) Balance() (string, error) { - return tel.ledger.Execute("bal") + return tel.Ledger.Execute("bal") +} + +func (tel *Teledger) Report(reportTitle string) (string, error) { + var reportArgs []string + for _, report := range tel.Ledger.Config.Reports { + if report.Title == reportTitle { + reportArgs = report.Command + break + } + } + if len(reportArgs) == 0 { + return "", fmt.Errorf("Report not found") + } + return tel.Ledger.Execute(reportArgs...) +} + + +func (tel *Teledger) Init() error { + _, err := tel.Ledger.Execute("bal") + return err } @@ -63,7 +83,7 @@ func inBacktick(s string) string { // Store the transaction in a state, so the user can confirm // or reject it. func (tel *Teledger) ProposeTransaction(desc string) (string, error) { - wasGenerated, tr, err := tel.ledger.AddOrProposeTransaction(desc, 2) + wasGenerated, tr, err := tel.Ledger.AddOrProposeTransaction(desc, 2) if wasGenerated { if err == nil { return inBacktick(tr.Format(false)), nil diff --git a/app/teledger/teledger_test.go b/app/teledger/teledger_test.go index 34bf7c3..00524f7 100644 --- a/app/teledger/teledger_test.go +++ b/app/teledger/teledger_test.go @@ -26,7 +26,7 @@ func TestTeledger_AddComment(t *testing.T) { l := ledger.NewLedger(r, nil) tldgr := &Teledger{ - ledger: l, + Ledger: l, } _, err := tldgr.AddComment("This is a comment\n multiline")