From dd3d4c1aece5a7a9142b9dd523fb71647598cb13 Mon Sep 17 00:00:00 2001 From: ShukeBta <272197458+ShukeBta@users.noreply.github.com> Date: Wed, 24 Jun 2026 21:30:44 +0800 Subject: [PATCH] fix: load real discover posters --- internal/service/bangumi.go | 27 ++++++++++++++++++++-- internal/service/bangumi_image_test.go | 18 +++++++++++++++ internal/service/discover.go | 1 + internal/service/discover_artwork.go | 28 +++++++++++++++++------ internal/service/discover_artwork_test.go | 22 ++++++++++++++++++ web/src/pages/DiscoverContentRow.tsx | 3 ++- web/src/pages/discoverPageModel.ts | 2 +- 7 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 internal/service/bangumi_image_test.go diff --git a/internal/service/bangumi.go b/internal/service/bangumi.go index 1aaa392..b0e2895 100644 --- a/internal/service/bangumi.go +++ b/internal/service/bangumi.go @@ -96,7 +96,7 @@ func (b *BangumiProvider) Search(ctx context.Context, query string) (*Match, err BangumiID: r.ID, Title: title, Overview: r.Summary, - PosterURL: r.Images.Large, + PosterURL: normalizeBangumiImageURL(r.Images.Large), Rating: r.Rating.Score, } if len(r.Air) >= 4 { @@ -141,7 +141,7 @@ func (b *BangumiProvider) GetSubject(ctx context.Context, bangumiID int) (*Match Title: title, OriginalName: r.Name, Overview: r.Summary, - PosterURL: firstText(r.Images.Large, r.Images.Common), + PosterURL: normalizeBangumiImageURL(firstText(r.Images.Large, r.Images.Common)), Rating: r.Rating.Score, } if len(r.Air) >= 4 { @@ -192,3 +192,26 @@ func (b *BangumiProvider) getJSON(ctx context.Context, u string, out any) error } return json.NewDecoder(resp.Body).Decode(out) } + +func normalizeBangumiImageURL(raw string) string { + raw = strings.TrimSpace(raw) + if raw == "" { + return "" + } + if strings.HasPrefix(raw, "//") { + raw = "https:" + raw + } + u, err := url.Parse(raw) + if err != nil || u.Host == "" { + return raw + } + host := strings.ToLower(u.Host) + if host != "lain.bgm.tv" && host != "bgm.tv" && !strings.HasSuffix(host, ".bgm.tv") { + return raw + } + u.Scheme = "https" + if strings.HasPrefix(u.Path, "/pic/cover/") { + u.Path = "/r/400" + u.Path + } + return u.String() +} diff --git a/internal/service/bangumi_image_test.go b/internal/service/bangumi_image_test.go new file mode 100644 index 0000000..b5bcb33 --- /dev/null +++ b/internal/service/bangumi_image_test.go @@ -0,0 +1,18 @@ +package service + +import "testing" + +func TestNormalizeBangumiImageURLUsesHTTPSResizedCover(t *testing.T) { + got := normalizeBangumiImageURL("http://lain.bgm.tv/pic/cover/l/27/ff/377130_wDU1x.jpg") + want := "https://lain.bgm.tv/r/400/pic/cover/l/27/ff/377130_wDU1x.jpg" + if got != want { + t.Fatalf("url = %q, want %q", got, want) + } +} + +func TestNormalizeBangumiImageURLLeavesExternalHostsAlone(t *testing.T) { + raw := "https://image.tmdb.org/t/p/w500/poster.jpg" + if got := normalizeBangumiImageURL(raw); got != raw { + t.Fatalf("url = %q, want %q", got, raw) + } +} diff --git a/internal/service/discover.go b/internal/service/discover.go index 0e52f20..cb5638c 100644 --- a/internal/service/discover.go +++ b/internal/service/discover.go @@ -312,6 +312,7 @@ func (b *BangumiProvider) Calendar(ctx context.Context) ([]ExternalMediaResult, if poster == "" { poster = item.Images.Common } + poster = normalizeBangumiImageURL(poster) year := 0 if len(item.AirDate) >= 4 { year, _ = strconv.Atoi(item.AirDate[:4]) diff --git a/internal/service/discover_artwork.go b/internal/service/discover_artwork.go index 5af80b6..a5c8218 100644 --- a/internal/service/discover_artwork.go +++ b/internal/service/discover_artwork.go @@ -10,9 +10,9 @@ import ( ) const ( - discoverArtworkPrefetchLimit = 48 - discoverArtworkPrefetchConcurrency = 4 - discoverArtworkPrefetchTimeout = 45 * time.Second + discoverArtworkPrefetchLimit = 384 + discoverArtworkPrefetchConcurrency = 8 + discoverArtworkPrefetchTimeout = 90 * time.Second ) func (d *DiscoverService) SetImageProxy(images *ImageProxy) *DiscoverService { @@ -23,19 +23,33 @@ func (d *DiscoverService) SetImageProxy(images *ImageProxy) *DiscoverService { } func (d *DiscoverService) WarmMatchArtwork(items []Match) int { + return d.warmArtworkURLs(matchArtworkURLs(items)) +} + +func matchArtworkURLs(items []Match) []string { urls := make([]string, 0, len(items)*2) for _, item := range items { - urls = append(urls, item.PosterURL, item.BackdropURL) + urls = append(urls, item.PosterURL) } - return d.warmArtworkURLs(urls) + for _, item := range items { + urls = append(urls, item.BackdropURL) + } + return urls } func (d *DiscoverService) WarmExternalArtwork(items []ExternalMediaResult) int { + return d.warmArtworkURLs(externalArtworkURLs(items)) +} + +func externalArtworkURLs(items []ExternalMediaResult) []string { urls := make([]string, 0, len(items)*2) for _, item := range items { - urls = append(urls, item.PosterURL, item.BackdropURL) + urls = append(urls, item.PosterURL) } - return d.warmArtworkURLs(urls) + for _, item := range items { + urls = append(urls, item.BackdropURL) + } + return urls } func (d *DiscoverService) warmArtworkURLs(urls []string) int { diff --git a/internal/service/discover_artwork_test.go b/internal/service/discover_artwork_test.go index fb28f09..06e069d 100644 --- a/internal/service/discover_artwork_test.go +++ b/internal/service/discover_artwork_test.go @@ -32,6 +32,28 @@ func TestUniqueDiscoverArtworkURLsFiltersDuplicatesAndLimits(t *testing.T) { } } +func TestDiscoverArtworkURLsPrioritizePosters(t *testing.T) { + items := []ExternalMediaResult{ + {PosterURL: "https://img.example/a-poster.jpg", BackdropURL: "https://img.example/a-backdrop.jpg"}, + {PosterURL: "https://img.example/b-poster.jpg", BackdropURL: "https://img.example/b-backdrop.jpg"}, + } + urls := externalArtworkURLs(items) + want := []string{ + "https://img.example/a-poster.jpg", + "https://img.example/b-poster.jpg", + "https://img.example/a-backdrop.jpg", + "https://img.example/b-backdrop.jpg", + } + if len(urls) != len(want) { + t.Fatalf("len = %d, want %d: %v", len(urls), len(want), urls) + } + for i := range want { + if urls[i] != want[i] { + t.Fatalf("url[%d] = %q, want %q", i, urls[i], want[i]) + } + } +} + func TestDiscoverWarmExternalArtworkPrefetchesAndCaches(t *testing.T) { proxy := NewImageProxy(&config.Config{Cache: config.CacheConfig{CacheDir: filepath.Join(t.TempDir(), "cache")}}, zap.NewNop()) var calls int32 diff --git a/web/src/pages/DiscoverContentRow.tsx b/web/src/pages/DiscoverContentRow.tsx index 28dd22b..85579b1 100644 --- a/web/src/pages/DiscoverContentRow.tsx +++ b/web/src/pages/DiscoverContentRow.tsx @@ -128,7 +128,8 @@ function DiscoverCard({ {item.title} { diff --git a/web/src/pages/discoverPageModel.ts b/web/src/pages/discoverPageModel.ts index 679dbbb..fd2636f 100644 --- a/web/src/pages/discoverPageModel.ts +++ b/web/src/pages/discoverPageModel.ts @@ -10,7 +10,7 @@ export const defaultSections = [ ] export const discoverStorageKey = 'mediastation.discover.sections' -const discoverStorageVersion = 2 +const discoverStorageVersion = 3 const legacyDefaultAdditions = ['tmdb_latest_movie', 'tmdb_latest_tv'] export const defaultSectionDefs: DiscoverSection[] = [