package main import ( "bytes" "encoding/json" "fmt" "io" "log" "net/http" "reflect" "strconv" ) var SimklWatchList SimklWatchListType func SimklHelper(method string, url string, body interface{}) json.RawMessage { reader, _ := json.Marshal(body) var req *http.Request client := &http.Client{} if body != nil { req, _ = http.NewRequest(method, url, bytes.NewBuffer(reader)) } else { req, _ = http.NewRequest(method, url, nil) } req.Header.Add("Content-Type", "application/json") req.Header.Add("Authorization", "Bearer "+simklJwt.AccessToken) req.Header.Add("simkl-api-key", Environment.SIMKL_CLIENT_ID) resp, err := client.Do(req) if err != nil { fmt.Println("Errored when sending request to the server") message, _ := json.Marshal(struct { Message string `json:"message"` }{ Message: "Errored when sending request to the server" + err.Error(), }) return message } defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) return respBody } func (a *App) SimklGetUserWatchlist() SimklWatchListType { method := "GET" url := "https://api.simkl.com/sync/all-items/anime/watching" respBody := SimklHelper(method, url, nil) var errCheck struct { Error string `json:"error"` Message string `json:"message"` } err := json.Unmarshal(respBody, &errCheck) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) } if errCheck.Error != "" { a.LogoutSimkl() return SimklWatchListType{} } var watchlist SimklWatchListType err = json.Unmarshal(respBody, &watchlist) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) } SimklWatchList = watchlist return watchlist } func (a *App) SimklSyncEpisodes(anime SimklAnime, progress int) SimklAnime { var episodes []Episode var url string var shows []SimklPostShow if progress >= anime.WatchedEpisodesCount { for i := 1; i <= progress; i++ { episodes = append(episodes, Episode{Number: i}) } url = "https://api.simkl.com/sync/history" } else { for i := anime.WatchedEpisodesCount; i > progress; i-- { episodes = append(episodes, Episode{Number: i}) } url = "https://api.simkl.com/sync/history/remove" } formattedShow := SimklPostShow{ Title: anime.Show.Title, Ids: Ids{ Simkl: anime.Show.Ids.Simkl, Mal: anime.Show.Ids.Mal, Anilist: anime.Show.Ids.AniList, }, Episodes: episodes, } shows = append(shows, formattedShow) simklSync := SimklSyncHistoryType{shows} respBody := SimklHelper("POST", url, simklSync) var success interface{} err := json.Unmarshal(respBody, &success) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) } for i, simklAnime := range SimklWatchList.Anime { if anime.Show.Ids.Simkl == simklAnime.Show.Ids.Simkl { SimklWatchList.Anime[i].WatchedEpisodesCount = progress } } anime.WatchedEpisodesCount = progress return anime } func (a *App) SimklSyncRating(anime SimklAnime, rating int) SimklAnime { var url string var showWithRating = ShowWithRating{ Title: anime.Show.Title, Ids: Ids{ Simkl: anime.Show.Ids.Simkl, Mal: anime.Show.Ids.Mal, Anilist: anime.Show.Ids.AniList, }, Rating: rating, } var showWithoutRating = ShowWithoutRating{ Title: anime.Show.Title, Ids: Ids{ Simkl: anime.Show.Ids.Simkl, Mal: anime.Show.Ids.Mal, Anilist: anime.Show.Ids.AniList, }, } var shows []interface{} if rating > 0 { shows = append(shows, showWithRating) url = "https://api.simkl.com/sync/ratings" } else { shows = append(shows, showWithoutRating) url = "https://api.simkl.com/sync/ratings/remove" } simklSync := struct { Shows []interface{} `json:"shows" ts_type:"shows"` }{shows} respBody := SimklHelper("POST", url, simklSync) var success interface{} err := json.Unmarshal(respBody, &success) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) } for i, simklAnime := range SimklWatchList.Anime { if anime.Show.Ids.Simkl == simklAnime.Show.Ids.Simkl { SimklWatchList.Anime[i].UserRating = rating } } anime.UserRating = rating return anime } func (a *App) SimklSyncStatus(anime SimklAnime, status string) SimklAnime { url := "https://api.simkl.com/sync/add-to-list" var show = SimklShowStatus{ Title: anime.Show.Title, Ids: Ids{ Simkl: anime.Show.Ids.Simkl, Mal: anime.Show.Ids.Mal, Anilist: anime.Show.Ids.AniList, }, To: status, } var shows []SimklShowStatus shows = append(shows, show) simklSync := struct { Shows []SimklShowStatus `json:"shows" ts_type:"shows"` }{shows} respBody := SimklHelper("POST", url, simklSync) var success interface{} err := json.Unmarshal(respBody, &success) if err != nil { log.Printf("Failed at unmarshal, %s\n", err) } for i, simklAnime := range SimklWatchList.Anime { if anime.Show.Ids.Simkl == simklAnime.Show.Ids.Simkl { SimklWatchList.Anime[i].Status = status } } anime.Status = status return anime } func (a *App) SimklSearch(aniListAnime MediaList) SimklAnime { var result SimklAnime if reflect.DeepEqual(SimklWatchList, SimklWatchListType{}) { fmt.Println("Watchlist empty. Calling...") SimklWatchList = a.SimklGetUserWatchlist() } for _, anime := range SimklWatchList.Anime { id, err := strconv.Atoi(anime.Show.Ids.AniList) if err != nil { fmt.Println("AniList ID does not exist on " + anime.Show.Title) } if id == aniListAnime.Media.ID { result = anime } } if reflect.DeepEqual(result, SimklAnime{}) { var anime SimklSearchType url := "https://api.simkl.com/search/id?anilist=" + strconv.Itoa(aniListAnime.Media.ID) respBody := SimklHelper("GET", url, nil) err := json.Unmarshal(respBody, &anime) if len(anime) == 0 { fmt.Println("reached search by mal") url = "https://api.simkl.com/search/id?mal=" + strconv.Itoa(aniListAnime.Media.IDMal) respBody = SimklHelper("GET", url, nil) fmt.Println(string(respBody)) err = json.Unmarshal(respBody, &anime) } if err != nil { log.Printf("Failed at unmarshal, %s\n", err) } if len(anime) == 0 { return result } for _, watchListAnime := range SimklWatchList.Anime { id := watchListAnime.Show.Ids.Simkl if id == anime[0].Ids.Simkl { result = watchListAnime } } if reflect.DeepEqual(result, SimklAnime{}) && len(anime) > 0 { result.Show.Title = anime[0].Title result.Show.Poster = anime[0].Poster result.Show.Ids.Simkl = anime[0].Ids.Simkl result.Show.Ids.Slug = anime[0].Ids.Slug } } return result }