From dde02770509d6bee1e18d041eb6a1dc471dc8111 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Mon, 2 Mar 2020 21:12:35 +0100 Subject: [PATCH] Check for duplicates when adding items to a playlist --- .../Playlists/PlaylistManager.cs | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs index b26f4026c5..edba30eb39 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -189,41 +189,45 @@ namespace Emby.Server.Implementations.Playlists private void AddToPlaylistInternal(string playlistId, IEnumerable itemIds, User user, DtoOptions options) { - var playlist = _libraryManager.GetItemById(playlistId) as Playlist; - - if (playlist == null) - { - throw new ArgumentException("No Playlist exists with the supplied Id"); - } - - var list = new List(); + // Retrieve the existing playlist + var playlist = _libraryManager.GetItemById(playlistId) as Playlist + ?? throw new ArgumentException("No Playlist exists with Id " + playlistId); + // Retrieve all the items to be added to the playlist var items = GetPlaylistItems(itemIds, playlist.MediaType, user, options) .Where(i => i.SupportsAddingToPlaylist) .ToList(); - foreach (var item in items) + // Remove duplicates from the new items to be added + var existingIds = playlist.LinkedChildren.Select(c => c.ItemId).ToHashSet(); + var uniqueItems = items + .Where(i => !existingIds.Contains(i.Id)) + .GroupBy(i => i.Id) + .Select(group => group.First()) + .ToList(); + + // Log duplicates that have been ignored, if any + if (uniqueItems.Count != items.Count) { - list.Add(LinkedChild.Create(item)); + var numDuplicates = items.Count - uniqueItems.Count; + _logger.LogWarning("Ignored adding {DuplicateCount} duplicate items to playlist {PlaylistName}.", numDuplicates, playlist.Name); } - var newList = playlist.LinkedChildren.ToList(); - newList.AddRange(list); - playlist.LinkedChildren = newList.ToArray(); - + // Update the playlist in the repository + var linkedItems = uniqueItems.Select(i => LinkedChild.Create(i)); + playlist.LinkedChildren = playlist.LinkedChildren.Concat(linkedItems).ToArray(); playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None); + // Update the playlist on disk if (playlist.IsFile) { SavePlaylistFile(playlist); } + // Refresh playlist metadata _providerManager.QueueRefresh( playlist.Id, - new MetadataRefreshOptions(new DirectoryService(_fileSystem)) - { - ForceSave = true - }, + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { ForceSave = true }, RefreshPriority.High); }