diff options
Diffstat (limited to 'Emby.Server.Implementations/Playlists/PlaylistManager.cs')
| -rw-r--r-- | Emby.Server.Implementations/Playlists/PlaylistManager.cs | 212 |
1 files changed, 141 insertions, 71 deletions
diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs index aea8d6532..47ff22c0b 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -59,68 +59,74 @@ namespace Emby.Server.Implementations.Playlists _appConfig = appConfig; } + public Playlist GetPlaylistForUser(Guid playlistId, Guid userId) + { + return GetPlaylists(userId).Where(p => p.Id.Equals(playlistId)).FirstOrDefault(); + } + public IEnumerable<Playlist> GetPlaylists(Guid userId) { var user = _userManager.GetUserById(userId); - - return GetPlaylistsFolder(userId).GetChildren(user, true).OfType<Playlist>(); + return _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = [BaseItemKind.Playlist], + Recursive = true, + DtoOptions = new DtoOptions(false) + }) + .Cast<Playlist>() + .Where(p => p.IsVisible(user)); } - public async Task<PlaylistCreationResult> CreatePlaylist(PlaylistCreationRequest options) + public async Task<PlaylistCreationResult> CreatePlaylist(PlaylistCreationRequest request) { - var name = options.Name; + var name = request.Name; var folderName = _fileSystem.GetValidFilename(name); - var parentFolder = GetPlaylistsFolder(options.UserId); + var parentFolder = GetPlaylistsFolder(request.UserId); if (parentFolder is null) { throw new ArgumentException(nameof(parentFolder)); } - if (options.MediaType is null || options.MediaType == MediaType.Unknown) + if (request.MediaType is null || request.MediaType == MediaType.Unknown) { - foreach (var itemId in options.ItemIdList) + foreach (var itemId in request.ItemIdList) { - var item = _libraryManager.GetItemById(itemId); - if (item is null) - { - throw new ArgumentException("No item exists with the supplied Id"); - } - + var item = _libraryManager.GetItemById(itemId) ?? throw new ArgumentException("No item exists with the supplied Id"); if (item.MediaType != MediaType.Unknown) { - options.MediaType = item.MediaType; + request.MediaType = item.MediaType; } else if (item is MusicArtist || item is MusicAlbum || item is MusicGenre) { - options.MediaType = MediaType.Audio; + request.MediaType = MediaType.Audio; } else if (item is Genre) { - options.MediaType = MediaType.Video; + request.MediaType = MediaType.Video; } else { if (item is Folder folder) { - options.MediaType = folder.GetRecursiveChildren(i => !i.IsFolder && i.SupportsAddingToPlaylist) + request.MediaType = folder.GetRecursiveChildren(i => !i.IsFolder && i.SupportsAddingToPlaylist) .Select(i => i.MediaType) .FirstOrDefault(i => i != MediaType.Unknown); } } - if (options.MediaType is not null && options.MediaType != MediaType.Unknown) + if (request.MediaType is not null && request.MediaType != MediaType.Unknown) { break; } } } - if (options.MediaType is null || options.MediaType == MediaType.Unknown) + if (request.MediaType is null || request.MediaType == MediaType.Unknown) { - options.MediaType = MediaType.Audio; + request.MediaType = MediaType.Audio; } - var user = _userManager.GetUserById(options.UserId); + var user = _userManager.GetUserById(request.UserId); var path = Path.Combine(parentFolder.Path, folderName); path = GetTargetPath(path); @@ -133,19 +139,20 @@ namespace Emby.Server.Implementations.Playlists { Name = name, Path = path, - OwnerUserId = options.UserId, - Shares = options.Shares ?? Array.Empty<Share>() + OwnerUserId = request.UserId, + Shares = request.Users ?? [], + OpenAccess = request.Public ?? false }; - playlist.SetMediaType(options.MediaType); + playlist.SetMediaType(request.MediaType); parentFolder.AddChild(playlist); await playlist.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { ForceSave = true }, CancellationToken.None) .ConfigureAwait(false); - if (options.ItemIdList.Count > 0) + if (request.ItemIdList.Count > 0) { - await AddToPlaylistInternal(playlist.Id, options.ItemIdList, user, new DtoOptions(false) + await AddToPlaylistInternal(playlist.Id, request.ItemIdList, user, new DtoOptions(false) { EnableImages = true }).ConfigureAwait(false); @@ -160,7 +167,19 @@ namespace Emby.Server.Implementations.Playlists } } - private string GetTargetPath(string path) + private List<Playlist> GetUserPlaylists(Guid userId) + { + var user = _userManager.GetUserById(userId); + var playlistsFolder = GetPlaylistsFolder(userId); + if (playlistsFolder is null) + { + return []; + } + + return playlistsFolder.GetChildren(user, true).OfType<Playlist>().ToList(); + } + + private static string GetTargetPath(string path) { while (Directory.Exists(path)) { @@ -170,14 +189,14 @@ namespace Emby.Server.Implementations.Playlists return path; } - private List<BaseItem> GetPlaylistItems(IEnumerable<Guid> itemIds, MediaType playlistMediaType, User user, DtoOptions options) + private IReadOnlyList<BaseItem> GetPlaylistItems(IEnumerable<Guid> itemIds, User user, DtoOptions options) { - var items = itemIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i is not null); + var items = itemIds.Select(_libraryManager.GetItemById).Where(i => i is not null); - return Playlist.GetPlaylistItems(playlistMediaType, items, user, options); + return Playlist.GetPlaylistItems(items, user, options); } - public Task AddToPlaylistAsync(Guid playlistId, IReadOnlyCollection<Guid> itemIds, Guid userId) + public Task AddItemToPlaylistAsync(Guid playlistId, IReadOnlyCollection<Guid> itemIds, Guid userId) { var user = userId.IsEmpty() ? null : _userManager.GetUserById(userId); @@ -194,7 +213,7 @@ namespace Emby.Server.Implementations.Playlists ?? throw new ArgumentException("No Playlist exists with Id " + playlistId); // Retrieve all the items to be added to the playlist - var newItems = GetPlaylistItems(newItemIds, playlist.MediaType, user, options) + var newItems = GetPlaylistItems(newItemIds, user, options) .Where(i => i.SupportsAddingToPlaylist); // Filter out duplicate items, if necessary @@ -224,20 +243,10 @@ namespace Emby.Server.Implementations.Playlists return; } - // Create a new array with the updated playlist items - var newLinkedChildren = new LinkedChild[playlist.LinkedChildren.Length + childrenToAdd.Count]; - playlist.LinkedChildren.CopyTo(newLinkedChildren, 0); - childrenToAdd.CopyTo(newLinkedChildren, playlist.LinkedChildren.Length); - // Update the playlist in the repository - playlist.LinkedChildren = newLinkedChildren; - await playlist.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); + playlist.LinkedChildren = [.. playlist.LinkedChildren, .. childrenToAdd]; - // Update the playlist on disk - if (playlist.IsFile) - { - SavePlaylistFile(playlist); - } + await UpdatePlaylistInternal(playlist).ConfigureAwait(false); // Refresh playlist metadata _providerManager.QueueRefresh( @@ -249,7 +258,7 @@ namespace Emby.Server.Implementations.Playlists RefreshPriority.High); } - public async Task RemoveFromPlaylistAsync(string playlistId, IEnumerable<string> entryIds) + public async Task RemoveItemFromPlaylistAsync(string playlistId, IEnumerable<string> entryIds) { if (_libraryManager.GetItemById(playlistId) is not Playlist playlist) { @@ -266,12 +275,7 @@ namespace Emby.Server.Implementations.Playlists .Select(i => i.Item1) .ToArray(); - await playlist.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); - - if (playlist.IsFile) - { - SavePlaylistFile(playlist); - } + await UpdatePlaylistInternal(playlist).ConfigureAwait(false); _providerManager.QueueRefresh( playlist.Id, @@ -313,14 +317,9 @@ namespace Emby.Server.Implementations.Playlists newList.Insert(newIndex, item); } - playlist.LinkedChildren = newList.ToArray(); + playlist.LinkedChildren = [.. newList]; - await playlist.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); - - if (playlist.IsFile) - { - SavePlaylistFile(playlist); - } + await UpdatePlaylistInternal(playlist).ConfigureAwait(false); } /// <inheritdoc /> @@ -430,8 +429,11 @@ namespace Emby.Server.Implementations.Playlists } else if (extension.Equals(".m3u8", StringComparison.OrdinalIgnoreCase)) { - var playlist = new M3uPlaylist(); - playlist.IsExtended = true; + var playlist = new M3uPlaylist + { + IsExtended = true + }; + foreach (var child in item.GetLinkedChildren()) { var entry = new M3uPlaylistEntry() @@ -481,7 +483,7 @@ namespace Emby.Server.Implementations.Playlists } } - private string NormalizeItemPath(string playlistPath, string itemPath) + private static string NormalizeItemPath(string playlistPath, string itemPath) { return MakeRelativePath(Path.GetDirectoryName(playlistPath), itemPath); } @@ -516,11 +518,13 @@ namespace Emby.Server.Implementations.Playlists return relativePath; } + /// <inheritdoc /> public Folder GetPlaylistsFolder() { return GetPlaylistsFolder(Guid.Empty); } + /// <inheritdoc /> public Folder GetPlaylistsFolder(Guid userId) { const string TypeName = "PlaylistsFolder"; @@ -532,21 +536,16 @@ namespace Emby.Server.Implementations.Playlists /// <inheritdoc /> public async Task RemovePlaylistsAsync(Guid userId) { - var playlists = GetPlaylists(userId); + var playlists = GetUserPlaylists(userId); foreach (var playlist in playlists) { // Update owner if shared - var rankedShares = playlist.Shares.OrderByDescending(x => x.CanEdit).ToArray(); - if (rankedShares.Length > 0 && Guid.TryParse(rankedShares[0].UserId, out var guid)) + var rankedShares = playlist.Shares.OrderByDescending(x => x.CanEdit).ToList(); + if (rankedShares.Count > 0) { - playlist.OwnerUserId = guid; + playlist.OwnerUserId = rankedShares[0].UserId; playlist.Shares = rankedShares.Skip(1).ToArray(); - await playlist.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); - - if (playlist.IsFile) - { - SavePlaylistFile(playlist); - } + await UpdatePlaylistInternal(playlist).ConfigureAwait(false); } else if (!playlist.OpenAccess) { @@ -563,5 +562,76 @@ namespace Emby.Server.Implementations.Playlists } } } + + public async Task UpdatePlaylist(PlaylistUpdateRequest request) + { + var playlist = GetPlaylistForUser(request.Id, request.UserId); + + if (request.Ids is not null) + { + playlist.LinkedChildren = []; + await UpdatePlaylistInternal(playlist).ConfigureAwait(false); + + var user = _userManager.GetUserById(request.UserId); + await AddToPlaylistInternal(request.Id, request.Ids, user, new DtoOptions(false) + { + EnableImages = true + }).ConfigureAwait(false); + + playlist = GetPlaylistForUser(request.Id, request.UserId); + } + + if (request.Name is not null) + { + playlist.Name = request.Name; + } + + if (request.Users is not null) + { + playlist.Shares = request.Users; + } + + if (request.Public is not null) + { + playlist.OpenAccess = request.Public.Value; + } + + await UpdatePlaylistInternal(playlist).ConfigureAwait(false); + } + + public async Task AddUserToShares(PlaylistUserUpdateRequest request) + { + var userId = request.UserId; + var playlist = GetPlaylistForUser(request.Id, userId); + var shares = playlist.Shares.ToList(); + var existingUserShare = shares.FirstOrDefault(s => s.UserId.Equals(userId)); + if (existingUserShare is not null) + { + shares.Remove(existingUserShare); + } + + shares.Add(new PlaylistUserPermissions(userId, request.CanEdit ?? false)); + playlist.Shares = shares; + await UpdatePlaylistInternal(playlist).ConfigureAwait(false); + } + + public async Task RemoveUserFromShares(Guid playlistId, Guid userId, PlaylistUserPermissions share) + { + var playlist = GetPlaylistForUser(playlistId, userId); + var shares = playlist.Shares.ToList(); + shares.Remove(share); + playlist.Shares = shares; + await UpdatePlaylistInternal(playlist).ConfigureAwait(false); + } + + private async Task UpdatePlaylistInternal(Playlist playlist) + { + await playlist.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); + + if (playlist.IsFile) + { + SavePlaylistFile(playlist); + } + } } } |
