using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; using System.Linq; using MediaBrowser.Model.Serialization; using System.Threading.Tasks; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Providers; namespace MediaBrowser.Controller.Playlists { public class Playlist : Folder, IHasShares { public string OwnerUserId { get; set; } public List Shares { get; set; } public Playlist() { Shares = new List(); } [IgnoreDataMember] protected override bool FilterLinkedChildrenPerUser { get { return true; } } [IgnoreDataMember] public override bool SupportsPlayedStatus { get { return string.Equals(MediaType, "Video", StringComparison.OrdinalIgnoreCase); } } [IgnoreDataMember] public override bool AlwaysScanInternalMetadataPath { get { return true; } } [IgnoreDataMember] public override bool SupportsCumulativeRunTimeTicks { get { return true; } } public override double? GetDefaultPrimaryImageAspectRatio() { return 1; } public override bool IsAuthorizedToDelete(User user) { return true; } public override bool IsSaveLocalMetadataEnabled() { return true; } protected override IEnumerable LoadChildren() { // Save a trip to the database return new List(); } public override IEnumerable GetChildren(User user, bool includeLinkedChildren) { return GetPlayableItems(user, new DtoOptions(true)).Result; } protected override IEnumerable GetNonCachedChildren(IDirectoryService directoryService) { return new List(); } public override IEnumerable GetRecursiveChildren(User user, InternalItemsQuery query) { var items = GetPlayableItems(user, query.DtoOptions).Result; if (query != null) { items = items.Where(i => UserViewBuilder.FilterItem(i, query)); } return items; } public IEnumerable> GetManageableItems() { return GetLinkedChildrenInfos(); } private Task> GetPlayableItems(User user, DtoOptions options) { return GetPlaylistItems(MediaType, base.GetChildren(user, true), user, options); } public static async Task> GetPlaylistItems(string playlistMediaType, IEnumerable inputItems, User user, DtoOptions options) { if (user != null) { inputItems = inputItems.Where(i => i.IsVisible(user)); } var list = new List(); foreach (var item in inputItems) { var playlistItems = await GetPlaylistItems(item, user, playlistMediaType, options).ConfigureAwait(false); list.AddRange(playlistItems); } return list; } private static async Task> GetPlaylistItems(BaseItem item, User user, string mediaType, DtoOptions options) { var musicGenre = item as MusicGenre; if (musicGenre != null) { return LibraryManager.GetItemList(new InternalItemsQuery(user) { Recursive = true, IncludeItemTypes = new[] { typeof(Audio).Name }, GenreIds = new[] { musicGenre.Id.ToString("N") }, SortBy = new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder = SortOrder.Ascending, DtoOptions = options }); } var musicArtist = item as MusicArtist; if (musicArtist != null) { return LibraryManager.GetItemList(new InternalItemsQuery(user) { Recursive = true, IncludeItemTypes = new[] { typeof(Audio).Name }, ArtistIds = new[] { musicArtist.Id.ToString("N") }, SortBy = new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder = SortOrder.Ascending, DtoOptions = options }); } var folder = item as Folder; if (folder != null) { var query = new InternalItemsQuery(user) { Recursive = true, IsFolder = false, SortBy = new[] { ItemSortBy.SortName }, MediaTypes = new[] { mediaType }, EnableTotalRecordCount = false, DtoOptions = options }; var itemsResult = await folder.GetItems(query).ConfigureAwait(false); var items = itemsResult.Items; return items; } return new[] { item }; } [IgnoreDataMember] public override bool IsPreSorted { get { return true; } } public string PlaylistMediaType { get; set; } [IgnoreDataMember] public override string MediaType { get { return PlaylistMediaType; } } public void SetMediaType(string value) { PlaylistMediaType = value; } public override bool IsVisible(User user) { var userId = user.Id.ToString("N"); return Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)) || string.Equals(OwnerUserId, userId, StringComparison.OrdinalIgnoreCase); } public override bool IsVisibleStandalone(User user) { return IsVisible(user); } } }