refactor: remove unreachable jikan client functions
This commit is contained in:
@@ -51,16 +51,6 @@ func (e *APIError) Error() string {
|
|||||||
return fmt.Sprintf("jikan api returned status %d", e.StatusCode)
|
return fmt.Sprintf("jikan api returned status %d", e.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsNotFoundError returns true if the error is an APIError with 404 status.
|
|
||||||
func IsNotFoundError(err error) bool {
|
|
||||||
var apiErr *APIError
|
|
||||||
if errors.As(err, &apiErr) {
|
|
||||||
return apiErr.StatusCode == http.StatusNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRetryableError returns true if the error should trigger a retry.
|
// IsRetryableError returns true if the error should trigger a retry.
|
||||||
func IsRetryableError(err error) bool {
|
func IsRetryableError(err error) bool {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -69,15 +69,3 @@ func (c *Client) GetAllEpisodes(ctx context.Context, animeID int) ([]Episode, er
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEpisodesRange fetches episodes from startPage to endPage sequentially.
|
|
||||||
func (c *Client) GetEpisodesRange(ctx context.Context, animeID int, startPage, endPage int) ([]Episode, error) {
|
|
||||||
var all []Episode
|
|
||||||
for page := startPage; page <= endPage; page++ {
|
|
||||||
resp, err := c.GetEpisodes(ctx, animeID, page)
|
|
||||||
if err != nil {
|
|
||||||
return all, err
|
|
||||||
}
|
|
||||||
all = append(all, resp.Data...)
|
|
||||||
}
|
|
||||||
return all, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Search performs a basic anime search by query string.
|
|
||||||
func (c *Client) Search(ctx context.Context, query string, page int) (SearchResult, error) {
|
|
||||||
return c.search(ctx, query, page, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SearchAdvanced performs a filtered anime search with type, status, ordering, and genre filters.
|
// SearchAdvanced performs a filtered anime search with type, status, ordering, and genre filters.
|
||||||
func (c *Client) SearchAdvanced(ctx context.Context, query, animeType, status, orderBy, sort string, genres []int, sfw bool, page, limit int) (SearchResult, error) {
|
func (c *Client) SearchAdvanced(ctx context.Context, query, animeType, status, orderBy, sort string, genres []int, sfw bool, page, limit int) (SearchResult, error) {
|
||||||
if page < 1 {
|
if page < 1 {
|
||||||
@@ -78,52 +73,6 @@ func (c *Client) SearchAdvanced(ctx context.Context, query, animeType, status, o
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) search(ctx context.Context, query string, page int, limit int) (SearchResult, error) {
|
|
||||||
if query == "" {
|
|
||||||
return SearchResult{}, nil
|
|
||||||
}
|
|
||||||
if page < 1 {
|
|
||||||
page = 1
|
|
||||||
}
|
|
||||||
if limit < 0 {
|
|
||||||
limit = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
cacheKey := fmt.Sprintf("search:%s:%d:%d", query, page, limit)
|
|
||||||
|
|
||||||
var result SearchResponse
|
|
||||||
reqURL := fmt.Sprintf("%s/anime?q=%s&page=%d", c.baseURL, url.QueryEscape(query), page)
|
|
||||||
if limit > 0 {
|
|
||||||
reqURL = fmt.Sprintf("%s&limit=%d", reqURL, limit)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.getWithCache(ctx, cacheKey, shortCacheTTL, reqURL, &result); err != nil {
|
|
||||||
if limit > 0 && IsRetryableError(err) {
|
|
||||||
fallbackURL := fmt.Sprintf("%s/anime?q=%s&page=%d", c.baseURL, url.QueryEscape(query), page)
|
|
||||||
if fallbackErr := c.fetchWithRetry(ctx, fallbackURL, &result); fallbackErr == nil {
|
|
||||||
res := SearchResult{
|
|
||||||
Animes: result.Data,
|
|
||||||
HasNextPage: result.Pagination.HasNextPage,
|
|
||||||
}
|
|
||||||
c.setCache(ctx, cacheKey, res, shortCacheTTL)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var stale SearchResult
|
|
||||||
if c.getStaleCache(ctx, cacheKey, &stale) {
|
|
||||||
return stale, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return SearchResult{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return SearchResult{
|
|
||||||
Animes: result.Data,
|
|
||||||
HasNextPage: result.Pagination.HasNextPage,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTopAnime returns the top-rated anime list for a given page.
|
// GetTopAnime returns the top-rated anime list for a given page.
|
||||||
func (c *Client) GetTopAnime(ctx context.Context, page int) (TopAnimeResult, error) {
|
func (c *Client) GetTopAnime(ctx context.Context, page int) (TopAnimeResult, error) {
|
||||||
if page < 1 {
|
if page < 1 {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package jikan
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ScheduleResult struct {
|
type ScheduleResult struct {
|
||||||
@@ -11,40 +10,6 @@ type ScheduleResult struct {
|
|||||||
HasNextPage bool // whether more pages available
|
HasNextPage bool // whether more pages available
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSchedule returns anime airing on a specific day of the week.
|
|
||||||
func (c *Client) GetSchedule(ctx context.Context, day string) (ScheduleResult, error) {
|
|
||||||
day = strings.ToLower(day)
|
|
||||||
cacheKey := fmt.Sprintf("schedule_%s", day)
|
|
||||||
|
|
||||||
var result TopAnimeResponse
|
|
||||||
reqURL := fmt.Sprintf("%s/schedules?filter=%s&sfw=true", c.baseURL, day)
|
|
||||||
|
|
||||||
err := c.getWithCache(ctx, cacheKey, shortCacheTTL, reqURL, &result)
|
|
||||||
if err != nil {
|
|
||||||
return ScheduleResult{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ScheduleResult{
|
|
||||||
Animes: result.Data,
|
|
||||||
HasNextPage: result.Pagination.HasNextPage,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFullSchedule returns anime airing schedule for all seven days.
|
|
||||||
func (c *Client) GetFullSchedule(ctx context.Context) (map[string][]Anime, error) {
|
|
||||||
days := []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}
|
|
||||||
schedule := make(map[string][]Anime)
|
|
||||||
|
|
||||||
for _, day := range days {
|
|
||||||
res, err := c.GetSchedule(ctx, day)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to fetch %s schedule: %w", day, err)
|
|
||||||
}
|
|
||||||
schedule[day] = res.Animes
|
|
||||||
}
|
|
||||||
|
|
||||||
return schedule, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSeasonsNow returns currently airing anime for the current season.
|
// GetSeasonsNow returns currently airing anime for the current season.
|
||||||
func (c *Client) GetSeasonsNow(ctx context.Context, page int) (TopAnimeResult, error) {
|
func (c *Client) GetSeasonsNow(ctx context.Context, page int) (TopAnimeResult, error) {
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package jikan
|
package jikan
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProducerResponse struct {
|
type ProducerResponse struct {
|
||||||
@@ -28,61 +26,3 @@ type ProducerResponse struct {
|
|||||||
} `json:"data"`
|
} `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAnimeByProducer returns anime list for a producer/studio, includes producer name.
|
|
||||||
func (c *Client) GetAnimeByProducer(ctx context.Context, producerID int, page int) (StudioAnimeResult, error) {
|
|
||||||
if page < 1 {
|
|
||||||
page = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
cacheKey := fmt.Sprintf("producer:%d:%d", producerID, page)
|
|
||||||
|
|
||||||
var cached StudioAnimeResult
|
|
||||||
if c.getCache(ctx, cacheKey, &cached) {
|
|
||||||
return cached, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var stale StudioAnimeResult
|
|
||||||
hasStale := c.getStaleCache(ctx, cacheKey, &stale)
|
|
||||||
|
|
||||||
var result SearchResponse
|
|
||||||
reqURL := fmt.Sprintf("%s/anime?producers=%d&page=%d", c.baseURL, producerID, page)
|
|
||||||
|
|
||||||
if err := c.fetchWithRetry(ctx, reqURL, &result); err != nil {
|
|
||||||
if hasStale {
|
|
||||||
return stale, nil
|
|
||||||
}
|
|
||||||
return StudioAnimeResult{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
producerName := ""
|
|
||||||
var producerRes ProducerResponse
|
|
||||||
producerURL := fmt.Sprintf("%s/producers/%d", c.baseURL, producerID)
|
|
||||||
if err := c.fetchWithRetry(ctx, producerURL, &producerRes); err == nil {
|
|
||||||
for _, title := range producerRes.Data.Titles {
|
|
||||||
if title.Type == "Default" {
|
|
||||||
producerName = title.Title
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res := StudioAnimeResult{
|
|
||||||
Animes: result.Data,
|
|
||||||
HasNextPage: result.Pagination.HasNextPage,
|
|
||||||
StudioName: producerName,
|
|
||||||
}
|
|
||||||
|
|
||||||
c.setCache(ctx, cacheKey, res, shortCacheTTL)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetProducerByID returns full producer/studio details.
|
|
||||||
func (c *Client) GetProducerByID(ctx context.Context, producerID int) (ProducerResponse, error) {
|
|
||||||
cacheKey := fmt.Sprintf("producer:info:%d", producerID)
|
|
||||||
|
|
||||||
var result ProducerResponse
|
|
||||||
reqURL := fmt.Sprintf("%s/producers/%d/full", c.baseURL, producerID)
|
|
||||||
|
|
||||||
err := c.getWithCache(ctx, cacheKey, shortCacheTTL, reqURL, &result)
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user