From 5c2b8ff9b7a6c239424f54f3a818b1916253955d Mon Sep 17 00:00:00 2001 From: Dmitry Ilvokhin Date: Sat, 8 Mar 2025 22:26:47 +0000 Subject: Manage options with CLI flags --- flatbot.go | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 15 deletions(-) (limited to 'flatbot.go') diff --git a/flatbot.go b/flatbot.go index ef10854..0a0e751 100644 --- a/flatbot.go +++ b/flatbot.go @@ -1,46 +1,119 @@ package main import ( + "flag" "fmt" "io" "log" "net/http" "os" + "time" ) +var ( + apiToken = flag.String("api-token", + os.Getenv("FLATBOT_TELEGRAM_BOT_API_TOKEN"), + "Telegram Bot API token") + chatID = flag.String("chat-id", + os.Getenv("FLATBOT_TELEGRAM_CHAT_ID"), + "Telegram chat id where to send notification messages") + state = flag.String("state", "/tmp/flatbot-sent.json", + "Filename to save and load already sent flats") + interval = flag.Duration("frequency", 5*time.Minute, + "Frequency interval to fetch new data") + once = flag.Bool("once", false, "Run fetch and message loop only once") + dryRun = flag.Bool("dry-run", false, + "Run entire flow, but print new flats to stdout instead of "+ + "sending them to Telegram") +) + +func usage() { + fmt.Fprintf(os.Stderr, + "usage: flatbot [-api-token token] [-chat-id id] "+ + "[-state file] [-interval duration] [-once] [-send] "+ + "URL...\n") + flag.PrintDefaults() + os.Exit(2) +} + func main() { - url := "http://localhost:8000/2025-02-19-isle-of-dogs.html" - body, err := fetch(url) + flag.Usage = usage + flag.Parse() + if !*dryRun { + if len(*apiToken) == 0 { + fmt.Fprintf(os.Stderr, + "Going to send messages to Telegram, "+ + "but no API token was provided\n") + os.Exit(1) + } + if len(*chatID) == 0 { + fmt.Fprintf(os.Stderr, + "Going to send messages to Telegram, "+ + "but no chat id was provided\n") + os.Exit(1) + } + } + if flag.NArg() == 0 { + usage() + os.Exit(1) + } + + for { + err := loopOnce() + if err != nil { + log.Fatal(err) + } + if *once { + break + } + log.Printf("Going to sleep for %v", *interval) + time.Sleep(*interval) + } +} + +func loopOnce() error { + sent, err := readSent(*state) if err != nil { - log.Fatal(err) + return err } - fetched, err := parse(body) + for _, url := range flag.Args() { + sent, err = doOneURL(url, sent) + if err != nil { + log.Print(err) + continue + } + } + // TODO: trim sent file here? + return writeSent(sent, *state) +} + +func doOneURL(url string, sent []flat) ([]flat, error) { + body, err := fetch(url) if err != nil { - log.Fatal(err) + return sent, err } - sent, err := readSent("sent/sent.json") + fetched, err := parse(body) if err != nil { - log.Fatal(err) + return sent, err } newFlats := removeAlreadySent(fetched, sent) m := messenger{ - Token: os.Getenv("FLATBOT_TELEGRAM_BOT_API_TOKEN"), - ChatID: os.Getenv("FLATBOT_TELEGRAM_CHANNEL_ID"), + Token: *apiToken, + ChatID: *chatID, } for _, f := range newFlats { - if false { + if !*dryRun { err = m.Send(f) if err != nil { - // TODO: what to do with it? log.Print(err) + continue } } + log.Printf("Should have been sent to chat: %v, %v", + f.Price, f.URL()) sent = append(sent, f) } - // Remove flats from sent that are no longer in the search response to - // prevent indefinite grow of sent file. - sent = removeDelisted(sent, fetched) - writeSent(sent, "/tmp/sent.json") + return sent, nil } func fetch(url string) ([]byte, error) { -- cgit v1.2.3-70-g09d2