diff options
| author | Shadowghost <Ghost_of_Stone@web.de> | 2026-05-04 21:26:26 +0200 |
|---|---|---|
| committer | Shadowghost <Ghost_of_Stone@web.de> | 2026-05-04 21:26:26 +0200 |
| commit | 57c0fcd674c659c658369f0aebfd5d9d6787a9d4 (patch) | |
| tree | 7aff23d6f54e913a6a34cb5a2568a07298582444 /Emby.Server.Implementations/Library/Validators | |
| parent | 68ab58589444091925c15ad20d36f935b7bc2e21 (diff) | |
| parent | ec04313317bed62728b059108cd232e9744f6354 (diff) | |
Merge remote-tracking branch 'upstream/master' into epg-fixes
Diffstat (limited to 'Emby.Server.Implementations/Library/Validators')
6 files changed, 96 insertions, 40 deletions
diff --git a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs index ef20ae9bca..fa7112eb90 100644 --- a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs @@ -55,25 +55,35 @@ public class ArtistsValidator IncludeItemTypes = [BaseItemKind.MusicArtist] }).ToHashSet(); + var existingArtists = _libraryManager.GetArtists(names); + var numComplete = 0; var count = names.Count; + var refreshed = 0; foreach (var name in names) { try { - var item = _libraryManager.GetArtist(name); + MusicArtist? item = null; + if (existingArtists.TryGetValue(name, out var artists) && artists.Length > 0) + { + item = artists.OrderBy(i => i.IsAccessedByName ? 1 : 0).First(); + } + + // Fall back to GetArtist if not found (creates new item if needed) + item ??= _libraryManager.GetArtist(name); var isNew = !existingArtistIds.Contains(item.Id); var neverRefreshed = item.DateLastRefreshed == default; if (isNew || neverRefreshed) { await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); + refreshed++; } } catch (OperationCanceledException) { - // Don't clutter the log throw; } catch (Exception ex) @@ -89,31 +99,24 @@ public class ArtistsValidator progress.Report(percent); } + _logger.LogInformation("Refreshed metadata for {RefreshedCount} new artists out of {TotalCount} total", refreshed, count); + var deadEntities = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = [BaseItemKind.MusicArtist], IsDeadArtist = true, IsLocked = false - }).Cast<MusicArtist>().ToList(); + }).Cast<MusicArtist>() + .Where(item => item.IsAccessedByName) + .ToList(); foreach (var item in deadEntities) { - if (!item.IsAccessedByName) - { - continue; - } - _logger.LogInformation("Deleting dead {ItemType} {ItemId} {ItemName}", item.GetType().Name, item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name); - - _libraryManager.DeleteItem( - item, - new DeleteOptions - { - DeleteFileLocation = false - }, - false); } + _libraryManager.DeleteItemsUnsafeFast(deadEntities, deleteSourceFiles: true); + progress.Report(100); } } diff --git a/Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs b/Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs index e62c638ed6..e3ef75b9ee 100644 --- a/Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs +++ b/Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs @@ -74,7 +74,7 @@ public class CollectionPostScanTask : ILibraryPostScanTask foreach (var m in movies) { - if (m is Movie movie && !string.IsNullOrEmpty(movie.CollectionName)) + if (m is Movie movie && !string.IsNullOrEmpty(movie.CollectionName) && !movie.PrimaryVersionId.HasValue) { if (collectionNameMoviesMap.TryGetValue(movie.CollectionName, out var movieList)) { diff --git a/Emby.Server.Implementations/Library/Validators/GenresValidator.cs b/Emby.Server.Implementations/Library/Validators/GenresValidator.cs index fbfc9f7d54..fc5a2fa0c5 100644 --- a/Emby.Server.Implementations/Library/Validators/GenresValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/GenresValidator.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Jellyfin.Data.Enums; @@ -48,17 +49,40 @@ public class GenresValidator public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { var names = _itemRepo.GetGenreNames(); + var existingGenreIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.Genre] + }).ToHashSet(); + + var existingGenres = _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.Genre] + }).Cast<Genre>() + .GroupBy(g => g.Name, StringComparer.OrdinalIgnoreCase) + .ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase); var numComplete = 0; var count = names.Count; + var refreshed = 0; foreach (var name in names) { try { - var item = _libraryManager.GetGenre(name); + Genre? item = null; + if (existingGenres.TryGetValue(name, out var existingGenre)) + { + item = existingGenre; + } + + // Fall back to GetGenre if not found (creates new item if needed) + item ??= _libraryManager.GetGenre(name); - await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); + if (!existingGenreIds.Contains(item.Id)) + { + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); + refreshed++; + } } catch (OperationCanceledException) { @@ -78,6 +102,8 @@ public class GenresValidator progress.Report(percent); } + _logger.LogInformation("Refreshed metadata for {RefreshedCount} new genres out of {TotalCount} total", refreshed, count); + var deadEntities = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = [BaseItemKind.Genre, BaseItemKind.MusicGenre], @@ -88,16 +114,10 @@ public class GenresValidator foreach (var item in deadEntities) { _logger.LogInformation("Deleting dead {ItemType} {ItemId} {ItemName}", item.GetType().Name, item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name); - - _libraryManager.DeleteItem( - item, - new DeleteOptions - { - DeleteFileLocation = false - }, - false); } + _libraryManager.DeleteItemsUnsafeFast(deadEntities, deleteSourceFiles: true); + progress.Report(100); } } diff --git a/Emby.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/Emby.Server.Implementations/Library/Validators/MusicGenresValidator.cs index 6203bce2bc..4365707529 100644 --- a/Emby.Server.Implementations/Library/Validators/MusicGenresValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/MusicGenresValidator.cs @@ -1,6 +1,9 @@ using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; +using Jellyfin.Data.Enums; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using Microsoft.Extensions.Logging; @@ -45,17 +48,25 @@ public class MusicGenresValidator public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { var names = _itemRepo.GetMusicGenreNames(); + var existingMusicGenreIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.MusicGenre] + }).ToHashSet(); var numComplete = 0; var count = names.Count; + var refreshed = 0; foreach (var name in names) { try { var item = _libraryManager.GetMusicGenre(name); - - await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); + if (!existingMusicGenreIds.Contains(item.Id)) + { + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); + refreshed++; + } } catch (OperationCanceledException) { @@ -75,6 +86,8 @@ public class MusicGenresValidator progress.Report(percent); } + _logger.LogInformation("Refreshed metadata for {RefreshedCount} new music genres out of {TotalCount} total", refreshed, count); + progress.Report(100); } } diff --git a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs index f9a6f0d19e..dacef102dd 100644 --- a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -109,7 +109,7 @@ public class PeopleValidator var i = 0; foreach (var item in deadEntities.Chunk(500)) { - _libraryManager.DeleteItemsUnsafeFast(item); + _libraryManager.DeleteItemsUnsafeFast(item, true); subProgress.Report(100f / deadEntities.Count * (i++ * 100)); } diff --git a/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs b/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs index 5b87e4d9d0..88f86ae6ca 100644 --- a/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Jellyfin.Data.Enums; @@ -49,17 +50,40 @@ public class StudiosValidator public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { var names = _itemRepo.GetStudioNames(); + var existingStudioIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.Studio] + }).ToHashSet(); + + var existingStudios = _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.Studio] + }).Cast<Studio>() + .GroupBy(s => s.Name, StringComparer.OrdinalIgnoreCase) + .ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase); var numComplete = 0; var count = names.Count; + var refreshed = 0; foreach (var name in names) { try { - var item = _libraryManager.GetStudio(name); + Studio? item = null; + if (existingStudios.TryGetValue(name, out var existingStudio)) + { + item = existingStudio; + } + + // Fall back to GetStudio if not found (creates new item if needed) + item ??= _libraryManager.GetStudio(name); - await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); + if (!existingStudioIds.Contains(item.Id)) + { + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); + refreshed++; + } } catch (OperationCanceledException) { @@ -79,6 +103,8 @@ public class StudiosValidator progress.Report(percent); } + _logger.LogInformation("Refreshed metadata for {RefreshedCount} new studios out of {TotalCount} total", refreshed, count); + var deadEntities = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = [BaseItemKind.Studio], @@ -89,16 +115,10 @@ public class StudiosValidator foreach (var item in deadEntities) { _logger.LogInformation("Deleting dead {ItemType} {ItemId} {ItemName}", item.GetType().Name, item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name); - - _libraryManager.DeleteItem( - item, - new DeleteOptions - { - DeleteFileLocation = false - }, - false); } + _libraryManager.DeleteItemsUnsafeFast(deadEntities, deleteSourceFiles: true); + progress.Report(100); } } |
