package main import ( "encoding/json" "fmt" "strconv" "strings" "time" "github.com/gookit/color" "github.com/xujiajun/nutsdb" ) func Arbeiten() { for range time.Tick(10 * time.Minute) { Arbeit() } } func Arbeit() { // check appointments appoints, err := ReadAppointments() if err != nil { if !strings.Contains(err.Error(), "not found") && err != nutsdb.ErrBucketEmpty { color.Errorln(err.Error()) logOut.WriteError(err) } } else { cleared := 0 lastAnnounce.Lock() defer lastAnnounce.Unlock() newCheckDate := time.Now() for _, a := range appoints { if a.Time.Add(22 * time.Hour).Before(newCheckDate) { // appointment expired keyBytes := Int64AndDateToBytes(a.Anime, a.Time) err = DbDelete(bucketAppoint, string(keyBytes)) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } else { cleared++ } } else { if lastAnnounce.stamp.Add(time.Hour).Before(a.Time) && newCheckDate.Add(time.Hour).After(a.Time) { // This has not happened and is happening soon go AnnounceBomb(a.Anime, a.Time.Unix(), time.Until(a.Time.Add(-25*time.Minute))) } } } lastAnnounce.stamp = newCheckDate if cleared > 0 { color.Infof("Cleared %d expired appointments\n", cleared) logOut.WriteLine(fmt.Sprintf("♻️ Cleared %d expired appointments", cleared)) } } // refresh animelist of users animesUsers, err := ReadAnimeUsers() if err != nil { if err != nutsdb.ErrBucketEmpty { color.Errorln(err.Error()) logOut.WriteError(err) } return } // ACTUALLY STUPID ENOUGH TO FIX A LOT OF PROBLEMS animeListCache.Reset() color.Infoln("Animelisten abfragen...") //logOut.WriteLine("📜 Animelisten abfragen...") count := 0 // iterate anime for _, a := range animesUsers { // iterate users for _, u := range a.Users { newProgress, updated, score, listState, err := FetchProgress(a.Anime, u.Username) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) continue } // check if user set anime as completed if listState == malApiStatusC { color.Infof("%s finished %d scored %d\n", u.Username, a.Anime, score) logOut.WriteLine(fmt.Sprintf("📝 %s finished %d scored %d !", u.Username, a.Anime, score)) // delete user from anime _, err = DeleteUserFromAnime(u.Username, u.MalID, a.Anime) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } count++ continue } // check if user set anime as dropped if listState == malApiStatusD { color.Infof("%s dropped %d\n", u.Username, a.Anime) logOut.WriteLine(fmt.Sprintf("📝 %s dropped %d !", u.Username, a.Anime)) // delete user from anime _, err = DeleteUserFromAnime(u.Username, u.MalID, a.Anime) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } count++ continue } if newProgress == u.Progress { continue } color.Infof("%s progress von %d: %d -> %d\n", u.Username, a.Anime, u.Progress, newProgress) logOut.WriteLine(fmt.Sprintf("📝 %s progress von %d: %d -> %d", u.Username, a.Anime, u.Progress, newProgress)) // update db err = UpdateUserAnimeProgress(a.Anime, u.MalID, newProgress, updated) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } count++ } } if count > 0 { color.Infof("%d Sachen aktualisiert\n", count) logOut.WriteLine(fmt.Sprintf("📜 %d Sachen aktualisiert", count)) } } func BissleArbeiten() { for range time.Tick(4 * time.Hour) { BissleArbeit() } } func BissleArbeit() { // refresh user cache count := 0 regUsers, err := ReadRegisteredUsers() if err != nil { // check if no users registered if err != nutsdb.ErrBucketEmpty { color.Errorln(err.Error()) logOut.WriteError(err) } } else { for _, u := range regUsers { err = refreshUser(u.Username) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) continue } count++ } } color.Infof("%d User aktualisiert\n", count) logOut.WriteLine(fmt.Sprintf("🔃 %d User aktualisiert", count)) } func LangeArbeiten() { for range time.Tick(6 * time.Hour) { LangeArbeit() } } func LangeArbeit() { // season data err := refreshSeason(GetCurrentSeasonString()) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } // next season data err = refreshSeason(GetNextSeasonString()) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } // next next season data err = refreshSeason(GetNextNextSeasonString()) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } // last season data err = refreshSeason(GetLastSeasonString()) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } // refresh anime cache with watched count := 0 animesUsers, err := ReadAnimeUsers() if err != nil { if err != nutsdb.ErrBucketEmpty { color.Errorln(err.Error()) logOut.WriteError(err) } } else { for _, a := range animesUsers { // search seasons first _, err = SearchSeasons(a.Anime) if err == nil { continue } err = refreshAnime(a.Anime) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) continue } count++ } } color.Infof("%d Anime aktualisiert\n", count) logOut.WriteLine(fmt.Sprintf("🔃 %d Anime aktualisiert", count)) } func SehrLangeArbeiten() { for range time.Tick(time.Hour * 24) { err := DbClean() if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } } } func refreshAnime(animeId int64) error { key := strconv.FormatInt(animeId, 10) dataMal, err := GetDataMal(animeApiMal + key + "?fields=id,title,main_picture,alternative_titles,start_date,end_date,synopsis,mean,rank,popularity,num_list_users,num_scoring_users,nsfw,media_type,status,genres,my_list_status,num_episodes,start_season,broadcast,source,average_episode_duration,rating,studios") if err != nil { return err } var animeMal AnimeDetailMal err = json.Unmarshal(dataMal, &animeMal) if err != nil { return err } // convert to anime anime := MalConvert(&animeMal) data, err := json.Marshal(&anime) if err != nil { return err } return animeCache.Set(key, data) } func refreshSeason(season string) error { _, bytes, err := GetSeasonDataAll(season) if err != nil { return err } return seasoncache.Set(season, bytes) } func refreshUser(username string) error { _, data, err := GetUserData(username) if err != nil { return err } return userCache.Set(username, data) }