diff --git a/integrations/jikan/episodes.go b/integrations/jikan/episodes.go index 2565ea7..884639d 100644 --- a/integrations/jikan/episodes.go +++ b/integrations/jikan/episodes.go @@ -19,6 +19,19 @@ func (c *Client) GetEpisodes(ctx context.Context, animeID int, page int) (Episod return result, err } +func (c *Client) GetVideoEpisodes(ctx context.Context, animeID int, page int) (EpisodesResponse, error) { + if page < 1 { + page = 1 + } + + cacheKey := fmt.Sprintf("anime:%d:videos:episodes:%d", animeID, page) + var result EpisodesResponse + reqURL := fmt.Sprintf("%s/anime/%d/videos/episodes?page=%d", c.baseURL, animeID, page) + + err := c.getWithCache(ctx, cacheKey, 12*time.Hour, reqURL, &result) + return result, err +} + func (c *Client) GetEpisode(ctx context.Context, animeID int, episode int) (EpisodeResponse, error) { cacheKey := fmt.Sprintf("anime:%d:episode:%d", animeID, episode) var result EpisodeResponse diff --git a/integrations/jikan/search.go b/integrations/jikan/search.go index 679d34b..435cbe6 100644 --- a/integrations/jikan/search.go +++ b/integrations/jikan/search.go @@ -10,8 +10,53 @@ func (c *Client) Search(ctx context.Context, query string, page int) (SearchResu return c.search(ctx, query, page, 0) } -func (c *Client) SearchWithLimit(ctx context.Context, query string, page int, limit int) (SearchResult, error) { - return c.search(ctx, query, page, limit) +func (c *Client) SearchAdvanced(ctx context.Context, query, animeType, status, orderBy, sort string, page, limit int) (SearchResult, error) { + if page < 1 { + page = 1 + } + if limit < 0 { + limit = 0 + } + + cacheKey := fmt.Sprintf("search:%s:%s:%s:%s:%s:%d:%d", query, animeType, status, orderBy, sort, page, limit) + + var result SearchResponse + reqURL := fmt.Sprintf("%s/anime?page=%d", c.baseURL, page) + if query != "" { + reqURL += "&q=" + url.QueryEscape(query) + } + if animeType != "" { + reqURL += "&type=" + url.QueryEscape(animeType) + } + if status != "" { + reqURL += "&status=" + url.QueryEscape(status) + } + if orderBy != "" { + reqURL += "&order_by=" + url.QueryEscape(orderBy) + } + if sort != "" { + reqURL += "&sort=" + url.QueryEscape(sort) + } + if limit > 0 { + reqURL += fmt.Sprintf("&limit=%d", limit) + } + + if err := c.getWithCache(ctx, cacheKey, shortCacheTTL, reqURL, &result); err != nil { + if IsRetryableError(err) { + if fallbackErr := c.fetchWithRetry(ctx, reqURL, &result); fallbackErr == nil { + return SearchResult{ + Animes: result.Data, + HasNextPage: result.Pagination.HasNextPage, + }, nil + } + } + return SearchResult{}, err + } + + return SearchResult{ + Animes: result.Data, + HasNextPage: result.Pagination.HasNextPage, + }, nil } func (c *Client) search(ctx context.Context, query string, page int, limit int) (SearchResult, error) { diff --git a/integrations/jikan/types.go b/integrations/jikan/types.go index 77324a4..bebd857 100644 --- a/integrations/jikan/types.go +++ b/integrations/jikan/types.go @@ -52,6 +52,7 @@ type Anime struct { Status string `json:"status"` Airing bool `json:"airing"` Episodes int `json:"episodes"` + Score float64 `json:"score"` Season string `json:"season"` Year int `json:"year"` Type string `json:"type"` @@ -157,10 +158,16 @@ type TopAnimeResponse struct { } type Episode struct { - MalID int `json:"mal_id"` - Title string `json:"title"` - Filler bool `json:"filler"` - Recap bool `json:"recap"` + MalID int `json:"mal_id"` + Title string `json:"title"` + Episode string `json:"episode"` + Filler bool `json:"filler"` + Recap bool `json:"recap"` + Images *struct { + Jpg struct { + ImageURL string `json:"image_url"` + } `json:"jpg"` + } `json:"images,omitempty"` } type EpisodesResponse struct {