refactor: domain anime type
This commit is contained in:
@@ -22,6 +22,14 @@ type AnimeHandler struct {
|
|||||||
watchlistSvc domain.WatchlistService
|
watchlistSvc domain.WatchlistService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wrapAnimes(in []jikan.Anime) []domain.Anime {
|
||||||
|
out := make([]domain.Anime, 0, len(in))
|
||||||
|
for _, a := range in {
|
||||||
|
out = append(out, domain.Anime{Anime: a})
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
func NewAnimeHandler(svc domain.AnimeService, watchlistSvc domain.WatchlistService) *AnimeHandler {
|
func NewAnimeHandler(svc domain.AnimeService, watchlistSvc domain.WatchlistService) *AnimeHandler {
|
||||||
return &AnimeHandler{
|
return &AnimeHandler{
|
||||||
svc: svc,
|
svc: svc,
|
||||||
@@ -405,7 +413,8 @@ func (h *AnimeHandler) HandleBrowse(c *gin.Context) {
|
|||||||
if u, ok := user.(*domain.User); ok {
|
if u, ok := user.(*domain.User); ok {
|
||||||
userID = u.ID
|
userID = u.ID
|
||||||
}
|
}
|
||||||
watchlistMap := h.watchlistMapForAnimes(c.Request.Context(), userID, res.Animes)
|
animes := wrapAnimes(res.Animes)
|
||||||
|
watchlistMap := h.watchlistMapForAnimes(c.Request.Context(), userID, animes)
|
||||||
|
|
||||||
studioName := ""
|
studioName := ""
|
||||||
if studioID > 0 {
|
if studioID > 0 {
|
||||||
@@ -417,10 +426,10 @@ func (h *AnimeHandler) HandleBrowse(c *gin.Context) {
|
|||||||
|
|
||||||
if c.GetHeader("HX-Request") == "true" && page > 1 {
|
if c.GetHeader("HX-Request") == "true" && page > 1 {
|
||||||
c.HTML(http.StatusOK, "browse.gohtml", gin.H{
|
c.HTML(http.StatusOK, "browse.gohtml", gin.H{
|
||||||
"_fragment": "anime_card_scroll",
|
"_fragment": "anime_card_scroll",
|
||||||
"Animes": res.Animes,
|
"Animes": animes,
|
||||||
"NextPage": page + 1,
|
"NextPage": page + 1,
|
||||||
"HasNextPage": res.HasNextPage,
|
"HasNextPage": res.HasNextPage,
|
||||||
"Query": q,
|
"Query": q,
|
||||||
"Type": animeType,
|
"Type": animeType,
|
||||||
"Status": status,
|
"Status": status,
|
||||||
@@ -450,9 +459,9 @@ func (h *AnimeHandler) HandleBrowse(c *gin.Context) {
|
|||||||
"Studio": studioID,
|
"Studio": studioID,
|
||||||
"StudioName": studioName,
|
"StudioName": studioName,
|
||||||
"SFW": sfw,
|
"SFW": sfw,
|
||||||
"GenresList": genresList,
|
"GenresList": genresList,
|
||||||
"Animes": res.Animes,
|
"Animes": animes,
|
||||||
"HasNextPage": res.HasNextPage,
|
"HasNextPage": res.HasNextPage,
|
||||||
"NextPage": page + 1,
|
"NextPage": page + 1,
|
||||||
"User": user,
|
"User": user,
|
||||||
"WatchlistMap": watchlistMap,
|
"WatchlistMap": watchlistMap,
|
||||||
@@ -472,8 +481,8 @@ func (h *AnimeHandler) HandleBrowse(c *gin.Context) {
|
|||||||
"StudioName": studioName,
|
"StudioName": studioName,
|
||||||
"SFW": sfw,
|
"SFW": sfw,
|
||||||
"GenresList": genresList,
|
"GenresList": genresList,
|
||||||
"Animes": res.Animes,
|
"Animes": animes,
|
||||||
"HasNextPage": res.HasNextPage,
|
"HasNextPage": res.HasNextPage,
|
||||||
"NextPage": page + 1,
|
"NextPage": page + 1,
|
||||||
"User": user,
|
"User": user,
|
||||||
"WatchlistMap": watchlistMap,
|
"WatchlistMap": watchlistMap,
|
||||||
@@ -634,7 +643,8 @@ func (h *AnimeHandler) HandleQuickSearch(c *gin.Context) {
|
|||||||
if u, ok := user.(*domain.User); ok {
|
if u, ok := user.(*domain.User); ok {
|
||||||
userID = u.ID
|
userID = u.ID
|
||||||
}
|
}
|
||||||
watchlistMap := h.watchlistMapForAnimes(c.Request.Context(), userID, res.Animes)
|
animes := wrapAnimes(res.Animes)
|
||||||
|
watchlistMap := h.watchlistMapForAnimes(c.Request.Context(), userID, animes)
|
||||||
|
|
||||||
type quickSearchResult struct {
|
type quickSearchResult struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
@@ -645,8 +655,8 @@ func (h *AnimeHandler) HandleQuickSearch(c *gin.Context) {
|
|||||||
InWatchlist bool `json:"in_watchlist"`
|
InWatchlist bool `json:"in_watchlist"`
|
||||||
}
|
}
|
||||||
|
|
||||||
output := make([]quickSearchResult, len(res.Animes))
|
output := make([]quickSearchResult, len(animes))
|
||||||
for i, anime := range res.Animes {
|
for i, anime := range animes {
|
||||||
output[i] = quickSearchResult{
|
output[i] = quickSearchResult{
|
||||||
ID: anime.MalID,
|
ID: anime.MalID,
|
||||||
Title: anime.DisplayTitle(),
|
Title: anime.DisplayTitle(),
|
||||||
@@ -736,8 +746,9 @@ func (h *AnimeHandler) commandPaletteAnimeResults(c *gin.Context, query string)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
items := make([]commandPaletteItem, 0, len(res.Animes))
|
animes := wrapAnimes(res.Animes)
|
||||||
for _, anime := range res.Animes {
|
items := make([]commandPaletteItem, 0, len(animes))
|
||||||
|
for _, anime := range animes {
|
||||||
items = append(items, commandPaletteItem{
|
items = append(items, commandPaletteItem{
|
||||||
ID: fmt.Sprintf("anime:%d", anime.MalID),
|
ID: fmt.Sprintf("anime:%d", anime.MalID),
|
||||||
Type: "anime",
|
Type: "anime",
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ type animeService struct {
|
|||||||
repo domain.AnimeRepository
|
repo domain.AnimeRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wrapAnimes(in []jikan.Anime) []domain.Anime {
|
||||||
|
out := make([]domain.Anime, 0, len(in))
|
||||||
|
for _, a := range in {
|
||||||
|
out = append(out, domain.Anime{Anime: a})
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
func NewAnimeService(jikan *jikan.Client, repo domain.AnimeRepository) domain.AnimeService {
|
func NewAnimeService(jikan *jikan.Client, repo domain.AnimeRepository) domain.AnimeService {
|
||||||
return &animeService{jikan: jikan, repo: repo}
|
return &animeService{jikan: jikan, repo: repo}
|
||||||
}
|
}
|
||||||
@@ -56,7 +64,7 @@ func (s *animeService) GetCatalogSection(ctx context.Context, userID string, sec
|
|||||||
return domain.CatalogSectionData{}, err
|
return domain.CatalogSectionData{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
animes := res.Animes
|
animes := wrapAnimes(res.Animes)
|
||||||
if len(animes) > 6 {
|
if len(animes) > 6 {
|
||||||
animes = animes[:6]
|
animes = animes[:6]
|
||||||
}
|
}
|
||||||
@@ -89,7 +97,7 @@ func (s *animeService) GetDiscoverSection(ctx context.Context, userID string, se
|
|||||||
return domain.DiscoverSectionData{}, err
|
return domain.DiscoverSectionData{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
animes := res.Animes
|
animes := wrapAnimes(res.Animes)
|
||||||
if len(animes) > 8 {
|
if len(animes) > 8 {
|
||||||
animes = animes[:8]
|
animes = animes[:8]
|
||||||
}
|
}
|
||||||
@@ -197,7 +205,7 @@ func (s *animeService) GetDiscoverForYou(ctx context.Context, userID string) (do
|
|||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
animes = append(animes, anime)
|
animes = append(animes, domain.Anime{Anime: anime})
|
||||||
}
|
}
|
||||||
|
|
||||||
return domain.DiscoverSectionData{Animes: animes}, nil
|
return domain.DiscoverSectionData{Animes: animes}, nil
|
||||||
@@ -247,7 +255,7 @@ func (s *animeService) GetAiringSchedule(ctx context.Context, userID string) ([]
|
|||||||
return fetchErr
|
return fetchErr
|
||||||
}
|
}
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
animes = append(animes, anime)
|
animes = append(animes, domain.Anime{Anime: anime})
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@@ -271,7 +279,11 @@ func (s *animeService) GetAiringSchedule(ctx context.Context, userID string) ([]
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *animeService) GetAnimeByID(ctx context.Context, id int) (domain.Anime, error) {
|
func (s *animeService) GetAnimeByID(ctx context.Context, id int) (domain.Anime, error) {
|
||||||
return s.jikan.GetAnimeByID(ctx, id)
|
anime, err := s.jikan.GetAnimeByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return domain.Anime{}, err
|
||||||
|
}
|
||||||
|
return domain.Anime{Anime: anime}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *animeService) SearchAdvanced(ctx context.Context, q, animeType, status, orderBy, sort string, genres []int, studioID int, sfw bool, page, limit int) (jikan.SearchResult, error) {
|
func (s *animeService) SearchAdvanced(ctx context.Context, q, animeType, status, orderBy, sort string, genres []int, studioID int, sfw bool, page, limit int) (jikan.SearchResult, error) {
|
||||||
@@ -341,7 +353,7 @@ func (s *animeService) GetRandomAnime(ctx context.Context) (domain.Anime, error)
|
|||||||
|
|
||||||
anime, err := s.jikan.GetRandomAnime(randomCtx)
|
anime, err := s.jikan.GetRandomAnime(randomCtx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return anime, nil
|
return domain.Anime{Anime: anime}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fallback := range []func(context.Context, int) (jikan.TopAnimeResult, error){
|
for _, fallback := range []func(context.Context, int) (jikan.TopAnimeResult, error){
|
||||||
@@ -350,12 +362,12 @@ func (s *animeService) GetRandomAnime(ctx context.Context) (domain.Anime, error)
|
|||||||
s.jikan.GetSeasonsUpcoming,
|
s.jikan.GetSeasonsUpcoming,
|
||||||
} {
|
} {
|
||||||
res, fallbackErr := fallback(ctx, 1)
|
res, fallbackErr := fallback(ctx, 1)
|
||||||
if fallbackErr != nil || len(res.Animes) == 0 {
|
if fallbackErr != nil || len(res.Animes) == 0 {
|
||||||
continue
|
continue
|
||||||
|
}
|
||||||
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
return domain.Anime{Anime: res.Animes[r.Intn(len(res.Animes))]}, nil
|
||||||
}
|
}
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
||||||
return res.Animes[r.Intn(len(res.Animes))], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return domain.Anime{}, err
|
return domain.Anime{}, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import (
|
|||||||
"mal/internal/db"
|
"mal/internal/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Anime = jikan.Anime
|
type Anime struct {
|
||||||
|
jikan.Anime
|
||||||
|
}
|
||||||
type TopAnimeResult = jikan.TopAnimeResult
|
type TopAnimeResult = jikan.TopAnimeResult
|
||||||
type Genre = jikan.Genre
|
type Genre = jikan.Genre
|
||||||
type Character = jikan.CharacterEntry
|
type Character = jikan.CharacterEntry
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ func (s *EpisodeService) RefreshTrackedDue(ctx context.Context, limit int) error
|
|||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, err := s.refresh(ctx, anime); err != nil {
|
if _, err := s.refresh(ctx, domain.Anime{Anime: anime}); err != nil {
|
||||||
observability.Warn(
|
observability.Warn(
|
||||||
"episodes_refresh_failed",
|
"episodes_refresh_failed",
|
||||||
"episodes",
|
"episodes",
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func TestMergeEpisodesUsesUnionAndSynthesizesProviderOnlyEntries(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNextBroadcastAfterUsesJikanTimezone(t *testing.T) {
|
func TestNextBroadcastAfterUsesJikanTimezone(t *testing.T) {
|
||||||
anime := domain.Anime{MalID: 1}
|
anime := domain.Anime{Anime: jikan.Anime{MalID: 1}}
|
||||||
anime.Broadcast.Day = "Saturdays"
|
anime.Broadcast.Day = "Saturdays"
|
||||||
anime.Broadcast.Time = "23:00"
|
anime.Broadcast.Time = "23:00"
|
||||||
anime.Broadcast.Timezone = "Asia/Tokyo"
|
anime.Broadcast.Timezone = "Asia/Tokyo"
|
||||||
@@ -44,7 +44,7 @@ func TestNextBroadcastAfterUsesJikanTimezone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNextRetryTimeWithinAndAfterRetryWindow(t *testing.T) {
|
func TestNextRetryTimeWithinAndAfterRetryWindow(t *testing.T) {
|
||||||
anime := domain.Anime{MalID: 1}
|
anime := domain.Anime{Anime: jikan.Anime{MalID: 1}}
|
||||||
anime.Broadcast.Day = "Saturdays"
|
anime.Broadcast.Day = "Saturdays"
|
||||||
anime.Broadcast.Time = "12:00"
|
anime.Broadcast.Time = "12:00"
|
||||||
anime.Broadcast.Timezone = "UTC"
|
anime.Broadcast.Timezone = "UTC"
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ func (s *playbackService) BuildWatchData(ctx context.Context, animeID int, title
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canonicalEpisodes, err := s.episodes.GetCanonicalEpisodes(ctx, anime, false)
|
canonicalEpisodes, err := s.episodes.GetCanonicalEpisodes(ctx, domain.Anime{Anime: anime}, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.WatchPageData{}, fmt.Errorf("failed to fetch episodes: %w", err)
|
return domain.WatchPageData{}, fmt.Errorf("failed to fetch episodes: %w", err)
|
||||||
}
|
}
|
||||||
@@ -289,12 +289,12 @@ func (s *playbackService) BuildWatchData(ctx context.Context, animeID int, title
|
|||||||
Segments: segments,
|
Segments: segments,
|
||||||
}
|
}
|
||||||
|
|
||||||
return domain.WatchPageData{
|
return domain.WatchPageData{
|
||||||
WatchData: watchData,
|
WatchData: watchData,
|
||||||
Anime: anime,
|
Anime: domain.Anime{Anime: anime},
|
||||||
Episodes: canonicalEpisodes.Episodes,
|
Episodes: canonicalEpisodes.Episodes,
|
||||||
CurrentEpID: episode,
|
CurrentEpID: episode,
|
||||||
WatchlistStatus: watchlistStatus,
|
WatchlistStatus: watchlistStatus,
|
||||||
WatchlistIDs: watchlistIDs,
|
WatchlistIDs: watchlistIDs,
|
||||||
Seasons: seasons,
|
Seasons: seasons,
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
Reference in New Issue
Block a user