package main import ( "encoding/json" "fmt" "strconv" "strings" "time" "github.com/gookit/color" "github.com/xujiajun/nutsdb" ) func Arbeiten() { for range time.Tick(time.Hour) { 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 for _, a := range appoints { if a.Time.Before(time.Now()) { // 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++ } } } 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 } // 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) } 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) } 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) } } } } 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 = GetUserData(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 _, bytes, err := GetSeasonDataAll() if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } else { err = seasoncache.Set(seasonApiJikan, bytes) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } } // next season data nextSeason := GetNextSeasonString() _, bytes, err = GetNextSeasonDataAll(nextSeason) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } else { err = seasoncache.Set(nextSeason, bytes) 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 season first _, err = SearchSeason(a.Anime) if err == nil { continue } err = refreshAnime(a.Anime) if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) continue } count++ } } charts, err := BuildMovieCharts() if err != nil { color.Errorln(err.Error()) logOut.WriteError(err) } else { for _, c := range charts { // search season first _, err = SearchSeason(c.Data.Anime) if err == nil { continue } err = refreshAnime(c.Data.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 } animeCache.Set(key, data) return nil }