This commit is contained in:
truewhile
2026-09-02 19:00:01 +08:00
parent e079a3cbb2
commit a02583ee7d
7 changed files with 199 additions and 15 deletions
+16 -5
View File
@@ -301,11 +301,22 @@ func (r *EmbyRemoteService) MapRemoteItemToMedia(ctx context.Context, mount *mod
media.SeasonNum = 0
media.EpisodeNum = 0
}
if mount != nil && strings.TrimSpace(mount.RemoteViewID) != "" {
libID := EncodeEmbyRemoteID(mount.ID, mount.RemoteViewID)
media.DisplayLibraryID = libID
media.LibraryID = libID
}
if mount != nil && strings.TrimSpace(mount.RemoteViewID) != "" {
libID := EncodeEmbyRemoteID(mount.ID, mount.RemoteViewID)
media.DisplayLibraryID = libID
media.LibraryID = libID
libName := strings.TrimSpace(mount.Name)
if libName == "" {
libName = strings.TrimSpace(mount.RemoteViewName)
}
if libName == "" && acct != nil {
libName = acct.Name
} else if acct != nil && acct.Name != "" && !strings.Contains(libName, acct.Name) {
libName = acct.Name + " · " + libName
}
media.LibraryName = libName
media.DisplayLibraryName = libName
}
return media
}
+26
View File
@@ -120,6 +120,11 @@ func GroupMediaVersions(items []model.Media) []MediaItem {
}
func mediaVersionGroupKey(m model.Media) string {
// 远程 Emby 挂载条目保持独立,不与其它远程条目或本地条目折叠合并。
if IsEmbyRemoteID(m.ID) {
return fmt.Sprintf("embyremote:%s", m.ID)
}
if m.SeasonNum > 0 || m.EpisodeNum > 0 {
switch {
case m.TMDbID > 0:
@@ -146,14 +151,32 @@ func mediaVersionGroupKey(m model.Media) string {
fmt.Sprintf("%d:%d", m.SeasonNum, m.EpisodeNum),
}, "|")
}
libKey := strings.ToLower(strings.TrimSpace(m.LibraryID))
if libKey == "" {
libKey = strings.ToLower(strings.TrimSpace(m.DisplayLibraryID))
}
switch {
case m.TMDbID > 0:
if libKey != "" {
return fmt.Sprintf("movie:%s:tmdb:%d", libKey, m.TMDbID)
}
return fmt.Sprintf("tmdb:%d", m.TMDbID)
case m.BangumiID > 0:
if libKey != "" {
return fmt.Sprintf("movie:%s:bangumi:%d", libKey, m.BangumiID)
}
return fmt.Sprintf("bangumi:%d", m.BangumiID)
case strings.TrimSpace(m.DoubanID) != "":
if libKey != "" {
return fmt.Sprintf("movie:%s:douban:%s", libKey, strings.ToLower(strings.TrimSpace(m.DoubanID)))
}
return "douban:" + strings.ToLower(strings.TrimSpace(m.DoubanID))
case strings.TrimSpace(m.TheTVDBID) != "":
if libKey != "" {
return fmt.Sprintf("movie:%s:thetvdb:%s", libKey, strings.ToLower(strings.TrimSpace(m.TheTVDBID)))
}
return "thetvdb:" + strings.ToLower(strings.TrimSpace(m.TheTVDBID))
}
title := firstNonEmpty(m.OriginalName, m.Title)
@@ -173,6 +196,9 @@ func mediaVersionGroupKey(m model.Media) string {
if year <= 0 {
_, year = CleanQuery(m.Path)
}
if libKey != "" {
return fmt.Sprintf("movie:%s:%s:%d", libKey, title, year)
}
return fmt.Sprintf("movie:%s:%d", title, year)
}
+46
View File
@@ -218,3 +218,49 @@ func TestSearchMediaVisiblePageGroupedPaginatesAfterVersionGrouping(t *testing.T
t.Fatalf("primary version = %q, want %q", page[0].Media.Path, rows[0].Path)
}
}
func TestGroupMediaVersionsDoesNotMergeDifferentRemoteSeries(t *testing.T) {
// 模拟来自两个不同挂载库(如 00 新番连载 与 2018 动漫)的同名剧集《碧蓝之海》
season1 := model.Media{
Base: model.Base{ID: EncodeEmbyRemoteID("mount-1", "156019")},
LibraryID: EncodeEmbyRemoteID("mount-1", "view-1"),
Title: "碧蓝之海",
Year: 2018,
LibraryName: "2018 动漫",
}
season2 := model.Media{
Base: model.Base{ID: EncodeEmbyRemoteID("mount-2", "156030")},
LibraryID: EncodeEmbyRemoteID("mount-2", "view-2"),
Title: "碧蓝之海",
Year: 2024,
LibraryName: "00 新番连载",
}
grouped := groupMediaVersions([]model.Media{season1, season2})
if len(grouped) != 2 {
t.Fatalf("expected 2 separate groups for different remote series/libraries, got %d: %#v", len(grouped), grouped)
}
if grouped[0].Title != "碧蓝之海" || grouped[1].Title != "碧蓝之海" {
t.Fatalf("expected both titles to be '碧蓝之海'")
}
}
func TestGroupMediaVersionsDoesNotMergeAcrossDifferentLibrariesForMovies(t *testing.T) {
movieLib1 := model.Media{
Base: model.Base{ID: "m-1"},
LibraryID: "lib-1",
Title: "碧蓝之海",
Year: 2018,
}
movieLib2 := model.Media{
Base: model.Base{ID: "m-2"},
LibraryID: "lib-2",
Title: "碧蓝之海",
Year: 2018,
}
grouped := groupMediaVersions([]model.Media{movieLib1, movieLib2})
if len(grouped) != 2 {
t.Fatalf("expected 2 separate groups for movies in different libraries, got %d", len(grouped))
}
}