diff --git a/envvars.go b/envvars.go index f22512d..16185a2 100644 --- a/envvars.go +++ b/envvars.go @@ -16,10 +16,11 @@ var ( ThreadCount = envvars.Int("THREADS", runtime.NumCPU()) DeleteLowPriorityFiles = envvars.Bool("DELETE_LOW_PRIORITY_FILES", false) - TelegramBotToken = envvars.String("TELEGRAM_API_TOKEN", "") - TelegramChatID = envvars.Int64("TELEGRAM_CHAT_ID", 0) - TelegramOrganizeMessagePatternStr = logic.EscSeqReplacer.Replace(envvars.String("TELEGRAM_ORGANIZE_MESSAGE_PATTERN", `Download finished\n\n{{.Title.UserPreferred}} episode {{.Episode}}`)) - TelegramOrganizeMessagePattern = template.Must(template.New("TELEGRAM_ORGANIZE_MESSAGE_PATTERN").Parse(TelegramOrganizeMessagePatternStr)) + TelegramBotToken = envvars.String("TELEGRAM_API_TOKEN", "") + TelegramChatID = envvars.Int64("TELEGRAM_CHAT_ID", 0) + 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) Uid = envvars.Object("UID", 1000, func(s string) (int, error) { if uid, err := strconv.Atoi(s); err == nil { diff --git a/go.mod b/go.mod index 6d8b179..3cd2444 100644 --- a/go.mod +++ b/go.mod @@ -4,20 +4,20 @@ go 1.19 require ( git.milar.in/milarin/adverr v1.1.0 - git.milar.in/milarin/channel v0.0.14 + git.milar.in/milarin/anilist v1.5.1 + git.milar.in/milarin/channel v0.0.16 git.milar.in/milarin/envvars/v2 v2.0.0 git.milar.in/milarin/gmath v0.0.3 - git.milar.in/nyaanime/logic v0.0.0-20230116090010-d266f73152af - git.milar.in/nyaanime/model v0.0.0-20230115221845-51c282652aef - git.milar.in/nyaanime/parsers v0.0.0-20230116085940-13e09638e07d + git.milar.in/milarin/slices v0.0.6 + git.milar.in/nyaanime/logic v0.0.0-20230118092507-da15313c21f8 + git.milar.in/nyaanime/model v0.0.0-20230117081612-d3fc649dad67 + git.milar.in/nyaanime/parsers v0.0.0-20230117113144-375fc1faab9f github.com/fatih/color v1.13.0 github.com/fsnotify/fsnotify v1.6.0 github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible ) require ( - git.milar.in/milarin/anilist v1.5.1 // indirect - git.milar.in/milarin/slices v0.0.6 // indirect git.milar.in/milarin/tprint v0.0.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect diff --git a/go.sum b/go.sum index 6503d73..7fa5ff9 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ git.milar.in/milarin/adverr v1.1.0 h1:jD9WnOvs40lfMhvqQ7cllOaRJNBMWr1f07/s9jAadp git.milar.in/milarin/adverr v1.1.0/go.mod h1:joU9sBb7ySyNv4SpTXB0Z4o1mjXsArBw4N27wjgzj9E= git.milar.in/milarin/anilist v1.5.1 h1:gW08WaAvXxC5/+P1QCjyfa5YtaiY9XvF5x/8G4orT6I= git.milar.in/milarin/anilist v1.5.1/go.mod h1:8PTHXFMA45JpfRFIpcdrKwDHue8fbT/wwV1BuHFn6c0= -git.milar.in/milarin/channel v0.0.14 h1:1jBaKNNOK/mmMMgC7yVW1Cgnbb7q9aKBXZ5WnWptDek= -git.milar.in/milarin/channel v0.0.14/go.mod h1:We83LTI8S7u7II3pD+A2ChCDWJfCkcBUCUqii9HjTtM= +git.milar.in/milarin/channel v0.0.16 h1:gyxwUFdw2pJUusdNhgnuTb2Tmb5MQAbTYcyxa3wp494= +git.milar.in/milarin/channel v0.0.16/go.mod h1:We83LTI8S7u7II3pD+A2ChCDWJfCkcBUCUqii9HjTtM= git.milar.in/milarin/envvars/v2 v2.0.0 h1:DWRQCWaHqzDD8NGpSgv5tYLuF9A/dVFPAtTvz3oiIqE= git.milar.in/milarin/envvars/v2 v2.0.0/go.mod h1:HkdEi+gG2lJSmVq547bTlQV4qQ0hO333bE8IrE0B9yY= git.milar.in/milarin/gmath v0.0.3 h1:ii6rKNItS55O/wtIFhD1cTN2BMwDZjTBmiOocKURvxM= @@ -12,18 +12,14 @@ git.milar.in/milarin/slices v0.0.6 h1:AQoSarZ58WHYol9c6woWJSe8wFpPC2RC4cvIlZpfg9 git.milar.in/milarin/slices v0.0.6/go.mod h1:NOr53AOeur/qscu/FBj3lsFR262PNYBccLYSTCAXRk4= git.milar.in/milarin/tprint v0.0.7 h1:dvm4l4BhXOie4vtnRMZii0WTLTz2wju8wyUPB/lNeVo= git.milar.in/milarin/tprint v0.0.7/go.mod h1:UwW/B+0cTCbN5hi0bQBE9rIRgLkq+x4V751rrS2KVoI= -git.milar.in/nyaanime/logic v0.0.0-20230115195351-8ed3e407ee72 h1:/kSY7P/NNaUmkxCJMKmB5YbhIA9owX9pErPxREuBAog= -git.milar.in/nyaanime/logic v0.0.0-20230115195351-8ed3e407ee72/go.mod h1:cLuIBDTtpXdzprOIsz73r6ZCE5s0k+o6HA7fH9OuW/M= -git.milar.in/nyaanime/logic v0.0.0-20230116090010-d266f73152af h1:x+1rL6HXWM9LL3ttLwCxp2/uXw7kWy0FI7VVaIpVaZ4= -git.milar.in/nyaanime/logic v0.0.0-20230116090010-d266f73152af/go.mod h1:cLuIBDTtpXdzprOIsz73r6ZCE5s0k+o6HA7fH9OuW/M= -git.milar.in/nyaanime/model v0.0.0-20230115221845-51c282652aef h1:Bp1cMHgGnz5SAVWSL1hk1w7F75LGAkfwHqoTZnNQNbY= -git.milar.in/nyaanime/model v0.0.0-20230115221845-51c282652aef/go.mod h1:kPWLDvFrhc1Uf77gxsBOxNeJ5JTVF2HhVs1IdVcw0tg= -git.milar.in/nyaanime/parsers v0.0.0-20230115231942-89b759a7829f h1:xJiFxbLRKyb+43Yfv3UaZO1GiRGAsakebz6mHKUaRdI= -git.milar.in/nyaanime/parsers v0.0.0-20230115231942-89b759a7829f/go.mod h1:fqiJqSWxh1YVJkKhvQql/21HmQzv4elhC3SpH/2TybI= -git.milar.in/nyaanime/parsers v0.0.0-20230115232356-54a23b868d71 h1:BwWlk7UuQ/Ii97/XUVijujH4nkYJwZ0dHpghQ04hQeo= -git.milar.in/nyaanime/parsers v0.0.0-20230115232356-54a23b868d71/go.mod h1:fqiJqSWxh1YVJkKhvQql/21HmQzv4elhC3SpH/2TybI= -git.milar.in/nyaanime/parsers v0.0.0-20230116085940-13e09638e07d h1:aKLQh9zAbVudH1Fjbew06R0opqMdq4tIhnCRYpoQ4Xs= -git.milar.in/nyaanime/parsers v0.0.0-20230116085940-13e09638e07d/go.mod h1:fqiJqSWxh1YVJkKhvQql/21HmQzv4elhC3SpH/2TybI= +git.milar.in/nyaanime/logic v0.0.0-20230118092325-6abd63d6e075 h1:MXkLDMSSoCEKUNUMBDn8sn5cZQ53IyGIwiKhS4EVxXc= +git.milar.in/nyaanime/logic v0.0.0-20230118092325-6abd63d6e075/go.mod h1:cLuIBDTtpXdzprOIsz73r6ZCE5s0k+o6HA7fH9OuW/M= +git.milar.in/nyaanime/logic v0.0.0-20230118092507-da15313c21f8 h1:guRZ/0cJq1s7I0OMhrcAbB5YqC0nzkQAipGyqY6vHkQ= +git.milar.in/nyaanime/logic v0.0.0-20230118092507-da15313c21f8/go.mod h1:cLuIBDTtpXdzprOIsz73r6ZCE5s0k+o6HA7fH9OuW/M= +git.milar.in/nyaanime/model v0.0.0-20230117081612-d3fc649dad67 h1:p69LqaWzN/2zsgw45tR1XbFxyayu9ffVlikiKE2ibRw= +git.milar.in/nyaanime/model v0.0.0-20230117081612-d3fc649dad67/go.mod h1:kPWLDvFrhc1Uf77gxsBOxNeJ5JTVF2HhVs1IdVcw0tg= +git.milar.in/nyaanime/parsers v0.0.0-20230117113144-375fc1faab9f h1:6DFFgqeBeU+qi24PLOwc5trPIPKief/YmGlQfyXrpAQ= +git.milar.in/nyaanime/parsers v0.0.0-20230117113144-375fc1faab9f/go.mod h1:fqiJqSWxh1YVJkKhvQql/21HmQzv4elhC3SpH/2TybI= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= diff --git a/send_condition.go b/send_condition.go new file mode 100644 index 0000000..2ebda66 --- /dev/null +++ b/send_condition.go @@ -0,0 +1,45 @@ +package main + +import ( + "errors" + "strings" + + "git.milar.in/milarin/anilist" + "git.milar.in/nyaanime/model" +) + +type SendCondition string + +var AllSendConditions = []SendCondition{SendConditionOnList, SendConditionAlways, SendConditionPlanned, SendConditionNotWatched} + +const ( + SendConditionOnList = "ON_LIST" + SendConditionAlways = "ALWAYS" + SendConditionPlanned = "PLANNED" + SendConditionNotWatched = "NOT_WATCHED" +) + +func SendConditionFromString(str string) (SendCondition, error) { + str = strings.ToLower(str) + for _, condition := range AllSendConditions { + if str == strings.ToLower(string(condition)) { + return condition, nil + } + } + return SendCondition(""), errors.New("invalid message send condition") +} + +func (c SendCondition) ShouldSend(animeEp model.AnimeEpisode, listEntry *anilist.MediaList) bool { + switch c { + case SendConditionOnList: + return listEntry != nil + case SendConditionPlanned: + return listEntry != nil && listEntry.Status == anilist.MediaListStatusPlanning + case SendConditionNotWatched: + return listEntry != nil && listEntry.Progress < animeEp.Episode + case SendConditionAlways: + return true + default: + panic("invalid telegram message send condition") + } +} diff --git a/telegram.go b/telegram.go index 23a9f79..e41a69b 100644 --- a/telegram.go +++ b/telegram.go @@ -1,10 +1,16 @@ package main import ( + "context" + "fmt" "strings" "text/template" "git.milar.in/milarin/adverr" + "git.milar.in/milarin/anilist" + "git.milar.in/milarin/channel" + "git.milar.in/milarin/slices" + "git.milar.in/nyaanime/logic" "git.milar.in/nyaanime/model" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" ) @@ -35,9 +41,71 @@ func SendTelegramMessage(text string) { } func SendTelegramAnimeEpMessage(messagePattern *template.Template, 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") + b := new(strings.Builder) - if err := messagePattern.Execute(b, animeEp); err != nil { + if err := messagePattern.Execute(b, []model.AnimeEpisode{animeEp}); err != nil { adverr.Println(adverr.Wrap("could not send telegram message", err)) } + SendTelegramMessage(b.String()) } + +func CheckSendConditions(animeEp model.AnimeEpisode) (bool, error) { + listEntry, err := GetListEntry(animeEp.Anime) + if err != nil { + 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 +} + +func GetListEntry(anime *anilist.Media) (*anilist.MediaList, error) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + listEntries, err := logic.GetCurrentlyWatchingAnimesContext(ctx, logic.AllMediaListStatuses...) + if err != nil { + return nil, err + } + + filteredListEntries := channel.Filter(listEntries, func(a *anilist.MediaList) bool { return a.MediaID == anime.ID }) + listEntry := channel.FindFirstAndCancelFlush(filteredListEntries, cancel) // TODO flush working properly? + + if listEntry == nil { + return nil, nil + } + + return *listEntry, nil +}