diff options
Diffstat (limited to 'MediaBrowser.Controller/Entities/BaseItem.cs')
| -rw-r--r-- | MediaBrowser.Controller/Entities/BaseItem.cs | 171 |
1 files changed, 111 insertions, 60 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 7ed8fa767..bf87c0336 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -7,6 +7,8 @@ using System.Text; using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; +using Jellyfin.Data.Entities; +using Jellyfin.Data.Enums; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; @@ -24,18 +26,17 @@ using MediaBrowser.Model.Library; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Providers; -using MediaBrowser.Model.Users; using Microsoft.Extensions.Logging; namespace MediaBrowser.Controller.Entities { /// <summary> - /// Class BaseItem + /// Class BaseItem. /// </summary> public abstract class BaseItem : IHasProviderIds, IHasLookupInfo<ItemLookupInfo>, IEquatable<BaseItem> { /// <summary> - /// The supported image extensions + /// The supported image extensions. /// </summary> public static readonly string[] SupportedImageExtensions = new[] { ".png", ".jpg", ".jpeg", ".tbn", ".gif" }; @@ -63,7 +64,7 @@ namespace MediaBrowser.Controller.Entities Genres = Array.Empty<string>(); Studios = Array.Empty<string>(); ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); - LockedFields = Array.Empty<MetadataFields>(); + LockedFields = Array.Empty<MetadataField>(); ImageInfos = Array.Empty<ItemImageInfo>(); ProductionLocations = Array.Empty<string>(); RemoteTrailers = Array.Empty<MediaUrl>(); @@ -74,7 +75,7 @@ namespace MediaBrowser.Controller.Entities public static char SlugChar = '-'; /// <summary> - /// The trailer folder name + /// The trailer folder name. /// </summary> public const string TrailerFolderName = "trailers"; public const string ThemeSongsFolderName = "theme-music"; @@ -107,6 +108,7 @@ namespace MediaBrowser.Controller.Entities public string PreferredMetadataLanguage { get; set; } public long? Size { get; set; } + public string Container { get; set; } [JsonIgnore] @@ -242,7 +244,7 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Returns the folder containing the item. - /// If the item is a folder, it returns the folder itself + /// If the item is a folder, it returns the folder itself. /// </summary> [JsonIgnore] public virtual string ContainingFolderPath @@ -266,7 +268,7 @@ namespace MediaBrowser.Controller.Entities public string ServiceName { get; set; } /// <summary> - /// If this content came from an external service, the id of the content on that service + /// If this content came from an external service, the id of the content on that service. /// </summary> [JsonIgnore] public string ExternalId { get; set; } @@ -299,7 +301,7 @@ namespace MediaBrowser.Controller.Entities { get { - //if (IsOffline) + // if (IsOffline) //{ // return LocationType.Offline; //} @@ -410,7 +412,7 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// This is just a helper for convenience + /// This is just a helper for convenience. /// </summary> /// <value>The primary image path.</value> [JsonIgnore] @@ -447,6 +449,7 @@ namespace MediaBrowser.Controller.Entities // hack alert return true; } + if (SourceType == SourceType.Channel) { // hack alert @@ -481,12 +484,12 @@ namespace MediaBrowser.Controller.Entities public virtual bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders) { - if (user.Policy.EnableContentDeletion) + if (user.HasPermission(PermissionKind.EnableContentDeletion)) { return true; } - var allowed = user.Policy.EnableContentDeletionFromFolders; + var allowed = user.GetPreference(PreferenceKind.EnableContentDeletionFromFolders); if (SourceType == SourceType.Channel) { @@ -527,7 +530,7 @@ namespace MediaBrowser.Controller.Entities public virtual bool IsAuthorizedToDownload(User user) { - return user.Policy.EnableContentDownloading; + return user.HasPermission(PermissionKind.EnableContentDownloading); } public bool CanDownload(User user) @@ -555,17 +558,28 @@ namespace MediaBrowser.Controller.Entities public DateTime DateLastRefreshed { get; set; } /// <summary> - /// The logger + /// The logger. /// </summary> - public static ILogger Logger { get; set; } + public static ILoggerFactory LoggerFactory { get; set; } + + public static ILogger<BaseItem> Logger { get; set; } + public static ILibraryManager LibraryManager { get; set; } + public static IServerConfigurationManager ConfigurationManager { get; set; } + public static IProviderManager ProviderManager { get; set; } + public static ILocalizationManager LocalizationManager { get; set; } + public static IItemRepository ItemRepository { get; set; } + public static IFileSystem FileSystem { get; set; } + public static IUserDataManager UserDataManager { get; set; } + public static IChannelManager ChannelManager { get; set; } + public static IMediaSourceManager MediaSourceManager { get; set; } /// <summary> @@ -585,7 +599,7 @@ namespace MediaBrowser.Controller.Entities /// </summary> /// <value>The locked fields.</value> [JsonIgnore] - public MetadataFields[] LockedFields { get; set; } + public MetadataField[] LockedFields { get; set; } /// <summary> /// Gets the type of the media. @@ -642,8 +656,10 @@ namespace MediaBrowser.Controller.Entities _sortName = CreateSortName(); } } + return _sortName; } + set => _sortName = value; } @@ -674,7 +690,10 @@ namespace MediaBrowser.Controller.Entities /// <returns>System.String.</returns> protected virtual string CreateSortName() { - if (Name == null) return null; //some items may not have name filled in properly + if (Name == null) + { + return null; // some items may not have name filled in properly + } if (!EnableAlphaNumericSorting) { @@ -734,7 +753,7 @@ namespace MediaBrowser.Controller.Entities builder.Append(chunkBuilder); } - //logger.LogDebug("ModifySortChunks Start: {0} End: {1}", name, builder.ToString()); + // logger.LogDebug("ModifySortChunks Start: {0} End: {1}", name, builder.ToString()); return builder.ToString().RemoveDiacritics(); } @@ -765,7 +784,6 @@ namespace MediaBrowser.Controller.Entities get => GetParent() as Folder; set { - } } @@ -798,7 +816,7 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// Finds a parent of a given type + /// Finds a parent of a given type. /// </summary> /// <typeparam name="T"></typeparam> /// <returns>``0.</returns> @@ -813,6 +831,7 @@ namespace MediaBrowser.Controller.Entities return item; } } + return null; } @@ -836,6 +855,7 @@ namespace MediaBrowser.Controller.Entities { return null; } + return LibraryManager.GetItemById(id); } } @@ -1004,12 +1024,12 @@ namespace MediaBrowser.Controller.Entities /// <returns>PlayAccess.</returns> public PlayAccess GetPlayAccess(User user) { - if (!user.Policy.EnableMediaPlayback) + if (!user.HasPermission(PermissionKind.EnableMediaPlayback)) { return PlayAccess.None; } - //if (!user.IsParentalScheduleAllowed()) + // if (!user.IsParentalScheduleAllowed()) //{ // return PlayAccess.None; //} @@ -1062,7 +1082,6 @@ namespace MediaBrowser.Controller.Entities } return 1; - }).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0) .ThenByDescending(i => { @@ -1213,11 +1232,11 @@ namespace MediaBrowser.Controller.Entities { if (video.IsoType.HasValue) { - if (video.IsoType.Value == Model.Entities.IsoType.BluRay) + if (video.IsoType.Value == IsoType.BluRay) { terms.Add("Bluray"); } - else if (video.IsoType.Value == Model.Entities.IsoType.Dvd) + else if (video.IsoType.Value == IsoType.Dvd) { terms.Add("DVD"); } @@ -1245,8 +1264,7 @@ namespace MediaBrowser.Controller.Entities // Support plex/xbmc convention files.AddRange(fileSystemChildren - .Where(i => !i.IsDirectory && string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase)) - ); + .Where(i => !i.IsDirectory && string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase))); return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions()) .OfType<Audio.Audio>() @@ -1345,20 +1363,18 @@ namespace MediaBrowser.Controller.Entities protected virtual void TriggerOnRefreshStart() { - } protected virtual void TriggerOnRefreshComplete() { - } /// <summary> - /// Overrides the base implementation to refresh metadata for local trailers + /// Overrides the base implementation to refresh metadata for local trailers. /// </summary> /// <param name="options">The options.</param> /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>true if a provider reports we changed</returns> + /// <returns>true if a provider reports we changed.</returns> public async Task<ItemUpdateType> RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken) { TriggerOnRefreshStart(); @@ -1374,6 +1390,7 @@ namespace MediaBrowser.Controller.Entities new List<FileSystemMetadata>(); var ownedItemsChanged = await RefreshedOwnedItems(options, files, cancellationToken).ConfigureAwait(false); + LibraryManager.UpdateImages(this); // ensure all image properties in DB are fresh if (ownedItemsChanged) { @@ -1755,7 +1772,7 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// Determines if a given user has access to this item + /// Determines if a given user has access to this item. /// </summary> /// <param name="user">The user.</param> /// <returns><c>true</c> if [is parental allowed] [the specified user]; otherwise, <c>false</c>.</returns> @@ -1772,7 +1789,7 @@ namespace MediaBrowser.Controller.Entities return false; } - var maxAllowedRating = user.Policy.MaxParentalRating; + var maxAllowedRating = user.MaxParentalAgeRating; if (maxAllowedRating == null) { @@ -1788,7 +1805,7 @@ namespace MediaBrowser.Controller.Entities if (string.IsNullOrEmpty(rating)) { - return !GetBlockUnratedValue(user.Policy); + return !GetBlockUnratedValue(user); } var value = LocalizationManager.GetRatingLevel(rating); @@ -1796,7 +1813,7 @@ namespace MediaBrowser.Controller.Entities // Could not determine the integer value if (!value.HasValue) { - var isAllowed = !GetBlockUnratedValue(user.Policy); + var isAllowed = !GetBlockUnratedValue(user); if (!isAllowed) { @@ -1858,8 +1875,7 @@ namespace MediaBrowser.Controller.Entities private bool IsVisibleViaTags(User user) { - var policy = user.Policy; - if (policy.BlockedTags.Any(i => Tags.Contains(i, StringComparer.OrdinalIgnoreCase))) + if (user.GetPreference(PreferenceKind.BlockedTags).Any(i => Tags.Contains(i, StringComparer.OrdinalIgnoreCase))) { return false; } @@ -1885,22 +1901,18 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Gets the block unrated value. /// </summary> - /// <param name="config">The configuration.</param> + /// <param name="user">The configuration.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> - protected virtual bool GetBlockUnratedValue(UserPolicy config) + protected virtual bool GetBlockUnratedValue(User user) { // Don't block plain folders that are unrated. Let the media underneath get blocked // Special folders like series and albums will override this method. - if (IsFolder) - { - return false; - } - if (this is IItemByName) + if (IsFolder || this is IItemByName) { return false; } - return config.BlockUnratedItems.Contains(GetBlockUnratedType()); + return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(GetBlockUnratedType().ToString()); } /// <summary> @@ -2066,7 +2078,7 @@ namespace MediaBrowser.Controller.Entities public virtual bool EnableRememberingTrackSelections => true; /// <summary> - /// Adds a studio to the item + /// Adds a studio to the item. /// </summary> /// <param name="name">The name.</param> /// <exception cref="ArgumentNullException"></exception> @@ -2102,7 +2114,7 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// Adds a genre to the item + /// Adds a genre to the item. /// </summary> /// <param name="name">The name.</param> /// <exception cref="ArgumentNullException"></exception> @@ -2130,7 +2142,8 @@ namespace MediaBrowser.Controller.Entities /// <param name="resetPosition">if set to <c>true</c> [reset position].</param> /// <returns>Task.</returns> /// <exception cref="ArgumentNullException"></exception> - public virtual void MarkPlayed(User user, + public virtual void MarkPlayed( + User user, DateTime? datePlayed, bool resetPosition) { @@ -2176,7 +2189,7 @@ namespace MediaBrowser.Controller.Entities var data = UserDataManager.GetUserData(user, this); - //I think it is okay to do this here. + // I think it is okay to do this here. // if this is only called when a user is manually forcing something to un-played // then it probably is what we want to do... data.PlayCount = 0; @@ -2196,7 +2209,7 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// Gets an image + /// Gets an image. /// </summary> /// <param name="type">The type.</param> /// <param name="imageIndex">Index of the image.</param> @@ -2222,6 +2235,7 @@ namespace MediaBrowser.Controller.Entities existingImage.DateModified = image.DateModified; existingImage.Width = image.Width; existingImage.Height = image.Height; + existingImage.BlurHash = image.BlurHash; } else { @@ -2373,6 +2387,46 @@ namespace MediaBrowser.Controller.Entities .ElementAtOrDefault(imageIndex); } + /// <summary> + /// Computes image index for given image or raises if no matching image found. + /// </summary> + /// <param name="image">Image to compute index for.</param> + /// <exception cref="ArgumentException">Image index cannot be computed as no matching image found. + /// </exception> + /// <returns>Image index.</returns> + public int GetImageIndex(ItemImageInfo image) + { + if (image == null) + { + throw new ArgumentNullException(nameof(image)); + } + + if (image.Type == ImageType.Chapter) + { + var chapters = ItemRepository.GetChapters(this); + for (var i = 0; i < chapters.Count; i++) + { + if (chapters[i].ImagePath == image.Path) + { + return i; + } + } + + throw new ArgumentException("No chapter index found for image path", image.Path); + } + + var images = GetImages(image.Type).ToArray(); + for (var i = 0; i < images.Length; i++) + { + if (images[i].Path == image.Path) + { + return i; + } + } + + throw new ArgumentException("No image index found for image path", image.Path); + } + public IEnumerable<ItemImageInfo> GetImages(ImageType imageType) { if (imageType == ImageType.Chapter) @@ -2471,7 +2525,7 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// Gets the file system path to delete when the item is to be deleted + /// Gets the file system path to delete when the item is to be deleted. /// </summary> /// <returns></returns> public virtual IEnumerable<FileSystemMetadata> GetDeletePaths() @@ -2720,8 +2774,8 @@ namespace MediaBrowser.Controller.Entities newOptions.ForceSave = true; } - //var parentId = Id; - //if (!video.IsOwnedItem || video.ParentId != parentId) + // var parentId = Id; + // if (!video.IsOwnedItem || video.ParentId != parentId) //{ // video.IsOwnedItem = true; // video.ParentId = parentId; @@ -2763,14 +2817,7 @@ namespace MediaBrowser.Controller.Entities return this; } - foreach (var parent in GetParents()) - { - if (parent.IsTopParent) - { - return parent; - } - } - return null; + return GetParents().FirstOrDefault(parent => parent.IsTopParent); } [JsonIgnore] @@ -2904,9 +2951,13 @@ namespace MediaBrowser.Controller.Entities public IEnumerable<BaseItem> GetTrailers() { if (this is IHasTrailers) + { return ((IHasTrailers)this).LocalTrailerIds.Select(LibraryManager.GetItemById).Where(i => i != null).OrderBy(i => i.SortName); + } else + { return Array.Empty<BaseItem>(); + } } public virtual bool IsHD => Height >= 720; |
