using MediaBrowser.Common.Progress; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.Movies { /// /// Class BoxSet /// public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasPreferredMetadataLanguage, IHasDisplayOrder, IHasLookupInfo, IMetadataContainer, IHasShares { public List Shares { get; set; } public BoxSet() { RemoteTrailers = new List(); LocalTrailerIds = new List(); RemoteTrailerIds = new List(); DisplayOrder = ItemSortBy.PremiereDate; Keywords = new List(); Shares = new List(); } protected override bool FilterLinkedChildrenPerUser { get { return true; } } public List LocalTrailerIds { get; set; } public List RemoteTrailerIds { get; set; } /// /// Gets or sets the remote trailers. /// /// The remote trailers. public List RemoteTrailers { get; set; } /// /// Gets or sets the tags. /// /// The tags. public List Keywords { get; set; } public string PreferredMetadataLanguage { get; set; } /// /// Gets or sets the preferred metadata country code. /// /// The preferred metadata country code. public string PreferredMetadataCountryCode { get; set; } /// /// Gets or sets the display order. /// /// The display order. public string DisplayOrder { get; set; } protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Movie); } [IgnoreDataMember] public override bool IsPreSorted { get { return true; } } /// /// Gets the trailer ids. /// /// List<Guid>. public List GetTrailerIds() { var list = LocalTrailerIds.ToList(); list.AddRange(RemoteTrailerIds); return list; } /// /// Updates the official rating based on content and returns true or false indicating if it changed. /// /// public bool UpdateRatingToContent() { var currentOfficialRating = OfficialRating; // Gather all possible ratings var ratings = RecursiveChildren .Concat(GetLinkedChildren()) .Where(i => i is Movie || i is Series) .Select(i => i.OfficialRating) .Where(i => !string.IsNullOrEmpty(i)) .Distinct(StringComparer.OrdinalIgnoreCase) .Select(i => new Tuple(i, LocalizationManager.GetRatingLevel(i))) .OrderBy(i => i.Item2 ?? 1000) .Select(i => i.Item1); OfficialRating = ratings.FirstOrDefault() ?? currentOfficialRating; return !string.Equals(currentOfficialRating ?? string.Empty, OfficialRating ?? string.Empty, StringComparison.OrdinalIgnoreCase); } public override IEnumerable GetChildren(User user, bool includeLinkedChildren) { var children = base.GetChildren(user, includeLinkedChildren); if (string.Equals(DisplayOrder, ItemSortBy.SortName, StringComparison.OrdinalIgnoreCase)) { // Sort by name return LibraryManager.Sort(children, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending); } if (string.Equals(DisplayOrder, ItemSortBy.PremiereDate, StringComparison.OrdinalIgnoreCase)) { // Sort by release date return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending); } // Default sorting return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending); } public BoxSetInfo GetLookupInfo() { return GetItemLookupInfo(); } public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress progress, CancellationToken cancellationToken) { // Refresh bottom up, children first, then the boxset // By then hopefully the movies within will have Tmdb collection values var items = RecursiveChildren.ToList(); var totalItems = items.Count; var percentages = new Dictionary(totalItems); // Refresh songs foreach (var item in items) { cancellationToken.ThrowIfCancellationRequested(); var innerProgress = new ActionableProgress(); // Avoid implicitly captured closure var currentChild = item; innerProgress.RegisterAction(p => { lock (percentages) { percentages[currentChild.Id] = p / 100; var percent = percentages.Values.Sum(); percent /= totalItems; percent *= 100; progress.Report(percent); } }); // Avoid implicitly captured closure await RefreshItem(item, refreshOptions, innerProgress, cancellationToken).ConfigureAwait(false); } // Refresh current item await RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); progress.Report(100); } private async Task RefreshItem(BaseItem item, MetadataRefreshOptions refreshOptions, IProgress progress, CancellationToken cancellationToken) { await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); progress.Report(100); } public override bool IsVisible(User user) { if (base.IsVisible(user)) { var userId = user.Id.ToString("N"); // Need to check Count > 0 for boxsets created prior to the introduction of Shares if (Shares.Count > 0 && !Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase))) { //return false; } return true; } return false; } } }