Merge pull request #11220 from Shadowghost/add-playlist-acl-api

Add playlist ACL endpoints
This commit is contained in:
Joshua M. Boniface
2024-04-10 12:52:01 -04:00
committed by GitHub
18 changed files with 663 additions and 146 deletions

View File

@@ -833,7 +833,7 @@ namespace MediaBrowser.Controller.Entities
return CanDelete() && IsAuthorizedToDelete(user, allCollectionFolders);
}
public bool CanDelete(User user)
public virtual bool CanDelete(User user)
{
var allCollectionFolders = LibraryManager.GetUserRootFolder().Children.OfType<Folder>().ToList();

View File

@@ -4,12 +4,35 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Playlists;
namespace MediaBrowser.Controller.Playlists
{
public interface IPlaylistManager
{
/// <summary>
/// Gets the playlist.
/// </summary>
/// <param name="playlistId">The playlist identifier.</param>
/// <param name="userId">The user identifier.</param>
/// <returns>Playlist.</returns>
Playlist GetPlaylistForUser(Guid playlistId, Guid userId);
/// <summary>
/// Creates the playlist.
/// </summary>
/// <param name="request">The <see cref="PlaylistCreationRequest"/>.</param>
/// <returns>The created playlist.</returns>
Task<PlaylistCreationResult> CreatePlaylist(PlaylistCreationRequest request);
/// <summary>
/// Updates a playlist.
/// </summary>
/// <param name="request">The <see cref="PlaylistUpdateRequest"/>.</param>
/// <returns>Task.</returns>
Task UpdatePlaylist(PlaylistUpdateRequest request);
/// <summary>
/// Gets the playlists.
/// </summary>
@@ -18,11 +41,20 @@ namespace MediaBrowser.Controller.Playlists
IEnumerable<Playlist> GetPlaylists(Guid userId);
/// <summary>
/// Creates the playlist.
/// Adds a share to the playlist.
/// </summary>
/// <param name="options">The options.</param>
/// <returns>Task&lt;Playlist&gt;.</returns>
Task<PlaylistCreationResult> CreatePlaylist(PlaylistCreationRequest options);
/// <param name="request">The <see cref="PlaylistUserUpdateRequest"/>.</param>
/// <returns>Task.</returns>
Task AddUserToShares(PlaylistUserUpdateRequest request);
/// <summary>
/// Removes a share from the playlist.
/// </summary>
/// <param name="playlistId">The playlist identifier.</param>
/// <param name="userId">The user identifier.</param>
/// <param name="share">The share.</param>
/// <returns>Task.</returns>
Task RemoveUserFromShares(Guid playlistId, Guid userId, PlaylistUserPermissions share);
/// <summary>
/// Adds to playlist.
@@ -31,7 +63,7 @@ namespace MediaBrowser.Controller.Playlists
/// <param name="itemIds">The item ids.</param>
/// <param name="userId">The user identifier.</param>
/// <returns>Task.</returns>
Task AddToPlaylistAsync(Guid playlistId, IReadOnlyCollection<Guid> itemIds, Guid userId);
Task AddItemToPlaylistAsync(Guid playlistId, IReadOnlyCollection<Guid> itemIds, Guid userId);
/// <summary>
/// Removes from playlist.
@@ -39,7 +71,7 @@ namespace MediaBrowser.Controller.Playlists
/// <param name="playlistId">The playlist identifier.</param>
/// <param name="entryIds">The entry ids.</param>
/// <returns>Task.</returns>
Task RemoveFromPlaylistAsync(string playlistId, IEnumerable<string> entryIds);
Task RemoveItemFromPlaylistAsync(string playlistId, IEnumerable<string> entryIds);
/// <summary>
/// Gets the playlists folder.

View File

@@ -16,24 +16,23 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
namespace MediaBrowser.Controller.Playlists
{
public class Playlist : Folder, IHasShares
{
public static readonly IReadOnlyList<string> SupportedExtensions = new[]
{
public static readonly IReadOnlyList<string> SupportedExtensions =
[
".m3u",
".m3u8",
".pls",
".wpl",
".zpl"
};
];
public Playlist()
{
Shares = Array.Empty<Share>();
Shares = [];
OpenAccess = false;
}
@@ -41,7 +40,7 @@ namespace MediaBrowser.Controller.Playlists
public bool OpenAccess { get; set; }
public Share[] Shares { get; set; }
public IReadOnlyList<PlaylistUserPermissions> Shares { get; set; }
[JsonIgnore]
public bool IsFile => IsPlaylistFile(Path);
@@ -130,7 +129,7 @@ namespace MediaBrowser.Controller.Playlists
protected override List<BaseItem> LoadChildren()
{
// Save a trip to the database
return new List<BaseItem>();
return [];
}
protected override Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
@@ -145,7 +144,7 @@ namespace MediaBrowser.Controller.Playlists
protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
{
return new List<BaseItem>();
return [];
}
public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
@@ -167,7 +166,7 @@ namespace MediaBrowser.Controller.Playlists
return base.GetChildren(user, true, query);
}
public static List<BaseItem> GetPlaylistItems(MediaType playlistMediaType, IEnumerable<BaseItem> inputItems, User user, DtoOptions options)
public static IReadOnlyList<BaseItem> GetPlaylistItems(MediaType playlistMediaType, IEnumerable<BaseItem> inputItems, User user, DtoOptions options)
{
if (user is not null)
{
@@ -192,9 +191,9 @@ namespace MediaBrowser.Controller.Playlists
return LibraryManager.GetItemList(new InternalItemsQuery(user)
{
Recursive = true,
IncludeItemTypes = new[] { BaseItemKind.Audio },
GenreIds = new[] { musicGenre.Id },
OrderBy = new[] { (ItemSortBy.AlbumArtist, SortOrder.Ascending), (ItemSortBy.Album, SortOrder.Ascending), (ItemSortBy.SortName, SortOrder.Ascending) },
IncludeItemTypes = [BaseItemKind.Audio],
GenreIds = [musicGenre.Id],
OrderBy = [(ItemSortBy.AlbumArtist, SortOrder.Ascending), (ItemSortBy.Album, SortOrder.Ascending), (ItemSortBy.SortName, SortOrder.Ascending)],
DtoOptions = options
});
}
@@ -204,9 +203,9 @@ namespace MediaBrowser.Controller.Playlists
return LibraryManager.GetItemList(new InternalItemsQuery(user)
{
Recursive = true,
IncludeItemTypes = new[] { BaseItemKind.Audio },
ArtistIds = new[] { musicArtist.Id },
OrderBy = new[] { (ItemSortBy.AlbumArtist, SortOrder.Ascending), (ItemSortBy.Album, SortOrder.Ascending), (ItemSortBy.SortName, SortOrder.Ascending) },
IncludeItemTypes = [BaseItemKind.Audio],
ArtistIds = [musicArtist.Id],
OrderBy = [(ItemSortBy.AlbumArtist, SortOrder.Ascending), (ItemSortBy.Album, SortOrder.Ascending), (ItemSortBy.SortName, SortOrder.Ascending)],
DtoOptions = options
});
}
@@ -217,8 +216,8 @@ namespace MediaBrowser.Controller.Playlists
{
Recursive = true,
IsFolder = false,
OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
MediaTypes = new[] { mediaType },
OrderBy = [(ItemSortBy.SortName, SortOrder.Ascending)],
MediaTypes = [mediaType],
EnableTotalRecordCount = false,
DtoOptions = options
};
@@ -226,7 +225,7 @@ namespace MediaBrowser.Controller.Playlists
return folder.GetItemList(query);
}
return new[] { item };
return [item];
}
public override bool IsVisible(User user)
@@ -248,12 +247,17 @@ namespace MediaBrowser.Controller.Playlists
}
var shares = Shares;
if (shares.Length == 0)
if (shares.Count == 0)
{
return false;
}
return shares.Any(share => Guid.TryParse(share.UserId, out var id) && id.Equals(userId));
return shares.Any(s => s.UserId.Equals(userId));
}
public override bool CanDelete(User user)
{
return user.HasPermission(PermissionKind.IsAdministrator) || user.Id.Equals(OwnerUserId);
}
public override bool IsVisibleStandalone(User user)