diff --git a/envvars.go b/envvars.go index 16185a2..dece52c 100644 --- a/envvars.go +++ b/envvars.go @@ -21,6 +21,7 @@ var ( TelegramOrganizeMessagePatternStr = logic.EscSeqReplacer.Replace(envvars.String("TELEGRAM_ORGANIZE_MESSAGE_PATTERN", `Download finished{{range .}}\n{{.Anime.Title.UserPreferred}} episode {{.Episode}}{{end}}`)) TelegramOrganizeMessagePattern = template.Must(template.New("TELEGRAM_ORGANIZE_MESSAGE_PATTERN").Parse(TelegramOrganizeMessagePatternStr)) TelegramOrganizeMessageSendCondition = envvars.ObjectSlice("TELEGRAM_ORGANIZE_MESSAGE_SEND_CONDITION", ",", []SendCondition{SendConditionAlways}, SendConditionFromString) + TelegramOrganizeMessageSendInterval = envvars.Duration("TELEGRAM_ORGANIZE_MESSAGE_SEND_INTERVAL", 0) Uid = envvars.Object("UID", 1000, func(s string) (int, error) { if uid, err := strconv.Atoi(s); err == nil { diff --git a/handle_file.go b/handle_file.go index b7424e0..b144dfe 100644 --- a/handle_file.go +++ b/handle_file.go @@ -86,7 +86,7 @@ func HandleParsedFile(w io.Writer, parsedFile *model.ParsedFile) { } func OrganizeAnimeEpisode(w io.Writer, parsedFile *model.ParsedFile) error { - SendTelegramAnimeEpMessage(TelegramOrganizeMessagePattern, parsedFile.AnimeEpisode()) + PrepareTelegramAnimeEpMessage(parsedFile.AnimeEpisode()) start := time.Now() diff --git a/main.go b/main.go index f6bf768..49ee773 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,9 @@ package main import ( + "os" "os/exec" + "time" "git.milar.in/milarin/channel" "git.milar.in/nyaanime/logic" @@ -25,6 +27,17 @@ func main() { panic(err) // TODO error handling } + //anime := adverr.Must(logic.SearchAnimeByTitle("トモちゃんは女の子!")) + //animeEp1 := model.AnimeEpisode{Anime: anime, Episode: 2} + //animeEp2 := model.AnimeEpisode{Anime: anime, Episode: 3} + //animeEp3 := model.AnimeEpisode{Anime: anime, Episode: 4} + //PrepareTelegramAnimeEpMessage(animeEp1) + //PrepareTelegramAnimeEpMessage(animeEp2) + //PrepareTelegramAnimeEpMessage(animeEp3) + + time.Sleep(time.Minute) + os.Exit(0) + logic.PrintPriorityTables() fileChan, err := WatchDirectory(fsnotify.Create, DownloadPath) diff --git a/telegram.go b/telegram.go index e41a69b..9640f51 100644 --- a/telegram.go +++ b/telegram.go @@ -2,9 +2,8 @@ package main import ( "context" - "fmt" "strings" - "text/template" + "time" "git.milar.in/milarin/adverr" "git.milar.in/milarin/anilist" @@ -16,6 +15,7 @@ import ( ) var TelegramBot *tgbotapi.BotAPI +var AnimeEpisodeMessageChannel = make(chan model.AnimeEpisode, 1000) func InitTelegramBot() error { if TelegramBotToken != "" && TelegramChatID != 0 { @@ -25,9 +25,44 @@ func InitTelegramBot() error { } TelegramBot = bot } + go SendMessagePeriodically() return nil } +func SendMessagePeriodically() { + var messagesPerInterval <-chan []model.AnimeEpisode + + if TelegramOrganizeMessageSendInterval > 0 { + lastCycle := time.Now().Truncate(TelegramOrganizeMessageSendInterval) + nextCycle := lastCycle.Add(TelegramOrganizeMessageSendInterval) + time.Sleep(time.Until(nextCycle)) + sendAllQueuedAnimeEpisodes() + + grouperFunc := func(current []model.AnimeEpisode, value model.AnimeEpisode) []model.AnimeEpisode { + return append(current, value) + } + messagesPerInterval = channel.GroupByTime(AnimeEpisodeMessageChannel, TelegramOrganizeMessageSendInterval, grouperFunc) + } else { + mapperFunc := func(value model.AnimeEpisode) []model.AnimeEpisode { + return []model.AnimeEpisode{value} + } + messagesPerInterval = channel.MapSuccessive(AnimeEpisodeMessageChannel, mapperFunc) + } + + for animeEpisodes := range messagesPerInterval { + sendTelegramAnimeEpMessage(animeEpisodes) + } +} + +func sendAllQueuedAnimeEpisodes() { + queuedEpisodeAmount := len(AnimeEpisodeMessageChannel) + animeEpisodes := make([]model.AnimeEpisode, 0, queuedEpisodeAmount) + for i := 0; i < queuedEpisodeAmount; i++ { + animeEpisodes = append(animeEpisodes, <-AnimeEpisodeMessageChannel) + } + sendTelegramAnimeEpMessage(animeEpisodes) +} + func SendTelegramMessage(text string) { if TelegramBot == nil { return @@ -40,23 +75,26 @@ func SendTelegramMessage(text string) { } } -func SendTelegramAnimeEpMessage(messagePattern *template.Template, animeEp model.AnimeEpisode) { +func PrepareTelegramAnimeEpMessage(animeEp model.AnimeEpisode) { shouldSendMessage, err := CheckSendConditions(animeEp) if err != nil { adverr.Println(adverr.Wrap("could not check telegram message send conditions", err)) } - fmt.Println("shouldSendMessage:", shouldSendMessage) - if !shouldSendMessage { - fmt.Println("do not send message") return } - fmt.Println("send message") + AnimeEpisodeMessageChannel <- animeEp +} + +func sendTelegramAnimeEpMessage(animeEpisodes []model.AnimeEpisode) { + if len(animeEpisodes) == 0 { + return + } b := new(strings.Builder) - if err := messagePattern.Execute(b, []model.AnimeEpisode{animeEp}); err != nil { + if err := TelegramOrganizeMessagePattern.Execute(b, animeEpisodes); err != nil { adverr.Println(adverr.Wrap("could not send telegram message", err)) } @@ -69,25 +107,18 @@ func CheckSendConditions(animeEp model.AnimeEpisode) (bool, error) { return false, err } - fmt.Println("listEntry:", listEntry) - for _, sendCondition := range AllSendConditions { // check if user configured current sendCondition if !slices.Contains(TelegramOrganizeMessageSendCondition, sendCondition) { - fmt.Println("condition not configured", sendCondition) continue } // check if current sendCondition applies for given anime episode if sendCondition.ShouldSend(animeEp, listEntry) { - fmt.Println("condition applies", sendCondition) return true, nil } - - fmt.Println("condition does not apply", sendCondition) } - fmt.Println("no condition applies") return false, nil }