Files
MeBox/internal/service/bangumi_calendar.go
T
2026-06-27 10:42:39 +08:00

78 lines
2.0 KiB
Go

// Package service — Bangumi discovery calendar.
package service
import (
"context"
"strconv"
"strings"
)
// Calendar returns Bangumi's public on-air anime calendar as a recommendation
// rail. It needs no token, but NewBangumiProvider still attaches one when set.
func (b *BangumiProvider) Calendar(ctx context.Context) ([]ExternalMediaResult, error) {
type subject struct {
ID int `json:"id"`
Name string `json:"name"`
NameCN string `json:"name_cn"`
Summary string `json:"summary"`
AirDate string `json:"air_date"`
Images struct {
Large string `json:"large"`
Common string `json:"common"`
} `json:"images"`
Rating struct {
Score float32 `json:"score"`
} `json:"rating"`
}
type day struct {
Items []subject `json:"items"`
}
var days []day
if err := b.getJSON(ctx, b.base+"/calendar", &days); err != nil {
return nil, err
}
out := make([]ExternalMediaResult, 0, 24)
seen := map[int]struct{}{}
for _, day := range days {
for _, item := range day.Items {
if _, ok := seen[item.ID]; ok {
continue
}
seen[item.ID] = struct{}{}
title := strings.TrimSpace(item.NameCN)
if title == "" {
title = strings.TrimSpace(item.Name)
}
if title == "" {
continue
}
poster := item.Images.Large
if poster == "" {
poster = item.Images.Common
}
poster = normalizeBangumiImageURL(poster)
year := 0
if len(item.AirDate) >= 4 {
year, _ = strconv.Atoi(item.AirDate[:4])
}
out = append(out, ExternalMediaResult{
Source: "bangumi",
MediaType: "anime",
Title: title,
OriginalName: item.Name,
Overview: item.Summary,
PosterURL: poster,
Year: year,
Rating: item.Rating.Score,
BangumiID: item.ID,
SubscribeKeyword: buildSubscribeKeyword(title, year),
SubscribeAliases: buildSubscribeAliases(title, item.Name, year),
})
if len(out) >= 24 {
return out, nil
}
}
}
return out, nil
}