Files
mal/internal/jikan/recommendations.go

91 lines
2.0 KiB
Go

package jikan
import (
"context"
"fmt"
"time"
)
type RecommendationEntry struct {
Entry struct {
MalID int `json:"mal_id"`
URL string `json:"url"`
Images struct {
Webp struct {
LargeImageURL string `json:"large_image_url"`
} `json:"webp"`
} `json:"images"`
Title string `json:"title"`
} `json:"entry"`
Votes int `json:"votes"`
}
type RecommendationsResponse struct {
Data []RecommendationEntry `json:"data"`
}
func (c *Client) GetRecommendations(ctx context.Context, animeID int, limit int) ([]Anime, error) {
cacheKey := fmt.Sprintf("recs:%d", animeID)
var cached []Anime
if c.getCache(ctx, cacheKey, &cached) {
if limit > 0 && len(cached) > limit {
return cached[:limit], nil
}
return cached, nil
}
var result RecommendationsResponse
reqURL := fmt.Sprintf("%s/anime/%d/recommendations", c.baseURL, animeID)
if err := c.fetchWithRetry(ctx, reqURL, &result); err != nil {
var stale []Anime
if c.getStaleCache(ctx, cacheKey, &stale) {
if limit > 0 && len(stale) > limit {
return stale[:limit], nil
}
return stale, nil
}
return nil, err
}
max := len(result.Data)
if limit > 0 && max > limit {
max = limit
}
animes := make([]Anime, 0, max)
for i := 0; i < max; i++ {
rec := result.Data[i]
var fullAnime Anime
animeCacheKey := fmt.Sprintf("anime:%d", rec.Entry.MalID)
if c.getCache(ctx, animeCacheKey, &fullAnime) {
animes = append(animes, fullAnime)
} else {
anime := Anime{
MalID: rec.Entry.MalID,
Title: rec.Entry.Title,
Images: struct {
Jpg struct {
LargeImageURL string `json:"large_image_url"`
} `json:"jpg"`
Webp struct {
LargeImageURL string `json:"large_image_url"`
} `json:"webp"`
}{
Webp: struct {
LargeImageURL string `json:"large_image_url"`
}{
LargeImageURL: rec.Entry.Images.Webp.LargeImageURL,
},
},
}
animes = append(animes, anime)
}
}
c.setCache(ctx, cacheKey, animes, time.Hour*24)
return animes, nil
}