mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-20 17:14:42 +01:00
Merge remote-tracking branch 'upstream/master' into api-upload-subtitle
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Authentication
|
||||
@@ -7,12 +9,14 @@ namespace MediaBrowser.Controller.Authentication
|
||||
public interface IAuthenticationProvider
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
bool IsEnabled { get; }
|
||||
|
||||
Task<ProviderAuthenticationResult> Authenticate(string username, string password);
|
||||
|
||||
bool HasPassword(User user);
|
||||
|
||||
Task ChangePassword(User user, string newPassword);
|
||||
void ChangeEasyPassword(User user, string newPassword, string newPasswordHash);
|
||||
string GetEasyPasswordHash(User user);
|
||||
}
|
||||
|
||||
public interface IRequiresResolvedUser
|
||||
@@ -28,6 +32,7 @@ namespace MediaBrowser.Controller.Authentication
|
||||
public class ProviderAuthenticationResult
|
||||
{
|
||||
public string Username { get; set; }
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Authentication
|
||||
@@ -8,14 +10,18 @@ namespace MediaBrowser.Controller.Authentication
|
||||
public interface IPasswordResetProvider
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
bool IsEnabled { get; }
|
||||
|
||||
Task<ForgotPasswordResult> StartForgotPasswordProcess(User user, bool isInNetwork);
|
||||
|
||||
Task<PinRedeemResult> RedeemPasswordResetPin(string pin);
|
||||
}
|
||||
|
||||
public class PasswordPinCreationResult
|
||||
{
|
||||
public string PinFile { get; set; }
|
||||
|
||||
public DateTime ExpirationDate { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Common.Progress;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
@@ -13,16 +17,18 @@ namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public override bool IsVisible(User user)
|
||||
{
|
||||
if (user.Policy.BlockedChannels != null)
|
||||
if (user.GetPreference(PreferenceKind.BlockedChannels) != null)
|
||||
{
|
||||
if (user.Policy.BlockedChannels.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase))
|
||||
if (user.GetPreference(PreferenceKind.BlockedChannels).Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase))
|
||||
if (!user.HasPermission(PermissionKind.EnableAllChannels)
|
||||
&& !user.GetPreference(PreferenceKind.EnabledChannels)
|
||||
.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
@@ -24,7 +26,9 @@ namespace MediaBrowser.Controller.Channels
|
||||
public string Overview { get; set; }
|
||||
|
||||
public List<string> Genres { get; set; }
|
||||
|
||||
public List<string> Studios { get; set; }
|
||||
|
||||
public List<string> Tags { get; set; }
|
||||
|
||||
public List<PersonInfo> People { get; set; }
|
||||
@@ -34,26 +38,33 @@ namespace MediaBrowser.Controller.Channels
|
||||
public long? RunTimeTicks { get; set; }
|
||||
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
public string OriginalTitle { get; set; }
|
||||
|
||||
public ChannelMediaType MediaType { get; set; }
|
||||
|
||||
public ChannelFolderType FolderType { get; set; }
|
||||
|
||||
public ChannelMediaContentType ContentType { get; set; }
|
||||
|
||||
public ExtraType ExtraType { get; set; }
|
||||
|
||||
public List<TrailerType> TrailerTypes { get; set; }
|
||||
|
||||
public Dictionary<string, string> ProviderIds { get; set; }
|
||||
|
||||
public DateTime? PremiereDate { get; set; }
|
||||
|
||||
public int? ProductionYear { get; set; }
|
||||
|
||||
public DateTime? DateCreated { get; set; }
|
||||
|
||||
public DateTime? StartDate { get; set; }
|
||||
|
||||
public DateTime? EndDate { get; set; }
|
||||
|
||||
public int? IndexNumber { get; set; }
|
||||
|
||||
public int? ParentIndexNumber { get; set; }
|
||||
|
||||
public List<MediaSourceInfo> MediaSources { get; set; }
|
||||
@@ -63,7 +74,9 @@ namespace MediaBrowser.Controller.Channels
|
||||
public List<string> Artists { get; set; }
|
||||
|
||||
public List<string> AlbumArtists { get; set; }
|
||||
|
||||
public bool IsLiveStream { get; set; }
|
||||
|
||||
public string Etag { get; set; }
|
||||
|
||||
public ChannelItemInfo()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public enum ChannelItemType
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public enum ChannelParentalRating
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class ChannelSearchInfo
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
@@ -31,6 +33,7 @@ namespace MediaBrowser.Controller.Channels
|
||||
ChannelFeatures[] GetAllChannelFeatures();
|
||||
|
||||
bool EnableMediaSourceDisplay(BaseItem item);
|
||||
|
||||
bool CanDelete(BaseItem item);
|
||||
|
||||
Task DeleteItem(BaseItem item);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public interface IHasCacheKey
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -30,17 +32,16 @@ namespace MediaBrowser.Controller.Channels
|
||||
public interface ISupportsDelete
|
||||
{
|
||||
bool CanDelete(BaseItem item);
|
||||
|
||||
Task DeleteItem(string id, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
public interface IDisableMediaSourceDisplay
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public interface ISupportsMediaProbe
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public interface IHasFolderAttributes
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Channels;
|
||||
|
||||
@@ -5,6 +7,14 @@ namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class InternalChannelFeatures
|
||||
{
|
||||
public InternalChannelFeatures()
|
||||
{
|
||||
MediaTypes = new List<ChannelMediaType>();
|
||||
ContentTypes = new List<ChannelMediaContentType>();
|
||||
|
||||
DefaultSortFields = new List<ChannelItemSortField>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the media types.
|
||||
/// </summary>
|
||||
@@ -18,7 +28,7 @@ namespace MediaBrowser.Controller.Channels
|
||||
public List<ChannelMediaContentType> ContentTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the maximum number of records the channel allows retrieving at a time
|
||||
/// Represents the maximum number of records the channel allows retrieving at a time.
|
||||
/// </summary>
|
||||
public int? MaxPageSize { get; set; }
|
||||
|
||||
@@ -48,13 +58,5 @@ namespace MediaBrowser.Controller.Channels
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports downloading]; otherwise, <c>false</c>.</value>
|
||||
public bool SupportsContentDownloading { get; set; }
|
||||
|
||||
public InternalChannelFeatures()
|
||||
{
|
||||
MediaTypes = new List<ChannelMediaType>();
|
||||
ContentTypes = new List<ChannelMediaContentType>();
|
||||
|
||||
DefaultSortFields = new List<ChannelItemSortField>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using MediaBrowser.Model.Channels;
|
||||
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class InternalChannelItemQuery
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Entities;
|
||||
@@ -6,6 +8,13 @@ namespace MediaBrowser.Controller.Collections
|
||||
{
|
||||
public class CollectionCreationOptions : IHasProviderIds
|
||||
{
|
||||
public CollectionCreationOptions()
|
||||
{
|
||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
ItemIdList = Array.Empty<string>();
|
||||
UserIds = Array.Empty<Guid>();
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public Guid? ParentId { get; set; }
|
||||
@@ -15,13 +24,7 @@ namespace MediaBrowser.Controller.Collections
|
||||
public Dictionary<string, string> ProviderIds { get; set; }
|
||||
|
||||
public string[] ItemIdList { get; set; }
|
||||
public Guid[] UserIds { get; set; }
|
||||
|
||||
public CollectionCreationOptions()
|
||||
{
|
||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
ItemIdList = Array.Empty<string>();
|
||||
UserIds = Array.Empty<Guid>();
|
||||
}
|
||||
public Guid[] UserIds { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
|
||||
@@ -26,24 +30,23 @@ namespace MediaBrowser.Controller.Collections
|
||||
/// Creates the collection.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
BoxSet CreateCollection(CollectionCreationOptions options);
|
||||
Task<BoxSet> CreateCollectionAsync(CollectionCreationOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Adds to collection.
|
||||
/// </summary>
|
||||
/// <param name="collectionId">The collection identifier.</param>
|
||||
/// <param name="itemIds">The item ids.</param>
|
||||
void AddToCollection(Guid collectionId, IEnumerable<string> itemIds);
|
||||
/// <returns><see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task AddToCollectionAsync(Guid collectionId, IEnumerable<Guid> itemIds);
|
||||
|
||||
/// <summary>
|
||||
/// Removes from collection.
|
||||
/// </summary>
|
||||
/// <param name="collectionId">The collection identifier.</param>
|
||||
/// <param name="itemIds">The item ids.</param>
|
||||
void RemoveFromCollection(Guid collectionId, IEnumerable<string> itemIds);
|
||||
|
||||
void AddToCollection(Guid collectionId, IEnumerable<Guid> itemIds);
|
||||
void RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds);
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task RemoveFromCollectionAsync(Guid collectionId, IEnumerable<Guid> itemIds);
|
||||
|
||||
/// <summary>
|
||||
/// Collapses the items within box sets.
|
||||
|
||||
@@ -4,7 +4,7 @@ using MediaBrowser.Model.Configuration;
|
||||
namespace MediaBrowser.Controller.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IServerConfigurationManager
|
||||
/// Interface IServerConfigurationManager.
|
||||
/// </summary>
|
||||
public interface IServerConfigurationManager : IConfigurationManager
|
||||
{
|
||||
@@ -19,7 +19,5 @@ namespace MediaBrowser.Controller.Configuration
|
||||
/// </summary>
|
||||
/// <value>The configuration.</value>
|
||||
ServerConfiguration Configuration { get; }
|
||||
|
||||
bool SetOptimalValues();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using MediaBrowser.Model.Devices;
|
||||
|
||||
namespace MediaBrowser.Controller.Devices
|
||||
{
|
||||
public class CameraImageUploadInfo
|
||||
{
|
||||
public LocalFileInfo FileInfo { get; set; }
|
||||
public DeviceInfo Device { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Events;
|
||||
using MediaBrowser.Model.Devices;
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Session;
|
||||
|
||||
@@ -11,10 +11,7 @@ namespace MediaBrowser.Controller.Devices
|
||||
{
|
||||
public interface IDeviceManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when [camera image uploaded].
|
||||
/// </summary>
|
||||
event EventHandler<GenericEventArgs<CameraImageUploadInfo>> CameraImageUploaded;
|
||||
event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Saves the capabilities.
|
||||
@@ -45,29 +42,13 @@ namespace MediaBrowser.Controller.Devices
|
||||
/// <returns>IEnumerable<DeviceInfo>.</returns>
|
||||
QueryResult<DeviceInfo> GetDevices(DeviceQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the upload history.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device identifier.</param>
|
||||
/// <returns>ContentUploadHistory.</returns>
|
||||
ContentUploadHistory GetCameraUploadHistory(string deviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Accepts the upload.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device identifier.</param>
|
||||
/// <param name="stream">The stream.</param>
|
||||
/// <param name="file">The file.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task AcceptCameraUpload(string deviceId, Stream stream, LocalFileInfo file);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this instance [can access device] the specified user identifier.
|
||||
/// </summary>
|
||||
bool CanAccessDevice(User user, string deviceId);
|
||||
|
||||
void UpdateDeviceOptions(string deviceId, DeviceOptions options);
|
||||
|
||||
DeviceOptions GetDeviceOptions(string deviceId);
|
||||
event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
@@ -43,6 +45,15 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// <returns>The image dimensions.</returns>
|
||||
ImageDimensions GetImageSize(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the blurhash of an image.
|
||||
/// </summary>
|
||||
/// <param name="xComp">Amount of X components of DCT to take.</param>
|
||||
/// <param name="yComp">Amount of Y components of DCT to take.</param>
|
||||
/// <param name="path">The filepath of the image.</param>
|
||||
/// <returns>The blurhash.</returns>
|
||||
string GetImageBlurHash(int xComp, int yComp, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Encode an image.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Entities;
|
||||
@@ -9,7 +12,7 @@ using MediaBrowser.Model.Entities;
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IImageProcessor
|
||||
/// Interface IImageProcessor.
|
||||
/// </summary>
|
||||
public interface IImageProcessor
|
||||
{
|
||||
@@ -29,7 +32,7 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// Gets the dimensions of the image.
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the image file.</param>
|
||||
/// <returns>ImageDimensions</returns>
|
||||
/// <returns>ImageDimensions.</returns>
|
||||
ImageDimensions GetImageDimensions(string path);
|
||||
|
||||
/// <summary>
|
||||
@@ -37,9 +40,16 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// </summary>
|
||||
/// <param name="item">The base item.</param>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <returns>ImageDimensions</returns>
|
||||
/// <returns>ImageDimensions.</returns>
|
||||
ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the blurhash of the image.
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the image file.</param>
|
||||
/// <returns>BlurHash.</returns>
|
||||
string GetImageBlurHash(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image cache tag.
|
||||
/// </summary>
|
||||
@@ -47,8 +57,11 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// <param name="image">The image.</param>
|
||||
/// <returns>Guid.</returns>
|
||||
string GetImageCacheTag(BaseItem item, ItemImageInfo image);
|
||||
|
||||
string GetImageCacheTag(BaseItem item, ChapterInfo info);
|
||||
|
||||
string GetImageCacheTag(User user);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the image.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
{
|
||||
public class ImageCollageOptions
|
||||
@@ -7,16 +9,19 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// </summary>
|
||||
/// <value>The input paths.</value>
|
||||
public string[] InputPaths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the output path.
|
||||
/// </summary>
|
||||
/// <value>The output path.</value>
|
||||
public string OutputPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width.
|
||||
/// </summary>
|
||||
/// <value>The width.</value>
|
||||
public int Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
@@ -16,6 +18,7 @@ namespace MediaBrowser.Controller.Drawing
|
||||
|
||||
return newSize;
|
||||
}
|
||||
|
||||
return GetSizeEstimate(options);
|
||||
}
|
||||
|
||||
@@ -57,6 +60,7 @@ namespace MediaBrowser.Controller.Drawing
|
||||
case ImageType.BoxRear:
|
||||
case ImageType.Disc:
|
||||
case ImageType.Menu:
|
||||
case ImageType.Profile:
|
||||
return 1;
|
||||
case ImageType.Logo:
|
||||
return 2.58;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -15,6 +17,7 @@ namespace MediaBrowser.Controller.Drawing
|
||||
}
|
||||
|
||||
public Guid ItemId { get; set; }
|
||||
|
||||
public BaseItem Item { get; set; }
|
||||
|
||||
public ItemImageInfo Image { get; set; }
|
||||
@@ -38,12 +41,15 @@ namespace MediaBrowser.Controller.Drawing
|
||||
public bool AddPlayedIndicator { get; set; }
|
||||
|
||||
public int? UnplayedCount { get; set; }
|
||||
|
||||
public int? Blur { get; set; }
|
||||
|
||||
public double PercentPlayed { get; set; }
|
||||
|
||||
public string BackgroundColor { get; set; }
|
||||
|
||||
public string ForegroundLayer { get; set; }
|
||||
|
||||
public bool RequiresAutoOrientation { get; set; }
|
||||
|
||||
private bool HasDefaultOptions(string originalImagePath)
|
||||
@@ -73,14 +79,17 @@ namespace MediaBrowser.Controller.Drawing
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Height.HasValue && !sizeValue.Height.Equals(Height.Value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MaxWidth.HasValue && sizeValue.Width > MaxWidth.Value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MaxHeight.HasValue && sizeValue.Height > MaxHeight.Value)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
@@ -11,6 +13,7 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// </summary>
|
||||
/// <value>The stream.</value>
|
||||
public Stream Stream { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the format.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Entities;
|
||||
@@ -14,11 +16,17 @@ namespace MediaBrowser.Controller.Dto
|
||||
};
|
||||
|
||||
public ItemFields[] Fields { get; set; }
|
||||
|
||||
public ImageType[] ImageTypes { get; set; }
|
||||
|
||||
public int ImageTypeLimit { get; set; }
|
||||
|
||||
public bool EnableImages { get; set; }
|
||||
|
||||
public bool AddProgramRecordingInfo { get; set; }
|
||||
|
||||
public bool EnableUserData { get; set; }
|
||||
|
||||
public bool AddCurrentProgram { get; set; }
|
||||
|
||||
public DtoOptions()
|
||||
|
||||
@@ -1,29 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Controller.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IDtoService
|
||||
/// Interface IDtoService.
|
||||
/// </summary>
|
||||
public interface IDtoService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the dto id.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetDtoId(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the primary image aspect ratio.
|
||||
/// </summary>
|
||||
/// <param name="dto">The dto.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
void AttachPrimaryImageAspectRatio(IItemDto dto, BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the primary image aspect ratio.
|
||||
/// </summary>
|
||||
@@ -31,15 +17,6 @@ namespace MediaBrowser.Controller.Dto
|
||||
/// <returns>System.Nullable<System.Double>.</returns>
|
||||
double? GetPrimaryImageAspectRatio(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base item dto.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="fields">The fields.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="owner">The owner.</param>
|
||||
BaseItemDto GetBaseItemDto(BaseItem item, ItemFields[] fields, User user = null, BaseItem owner = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base item dto.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@@ -35,7 +37,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
public override bool SupportsPlayedStatus => false;
|
||||
|
||||
/// <summary>
|
||||
/// The _virtual children
|
||||
/// The _virtual children.
|
||||
/// </summary>
|
||||
private readonly ConcurrentBag<BaseItem> _virtualChildren = new ConcurrentBag<BaseItem>();
|
||||
|
||||
@@ -57,6 +59,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
private Guid[] _childrenIds = null;
|
||||
private readonly object _childIdsLock = new object();
|
||||
|
||||
protected override List<BaseItem> LoadChildren()
|
||||
{
|
||||
lock (_childIdsLock)
|
||||
@@ -195,6 +198,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Audio
|
||||
/// Class Audio.
|
||||
/// </summary>
|
||||
public class Audio : BaseItem,
|
||||
IHasAlbumArtist,
|
||||
@@ -93,6 +95,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
songKey = ParentIndexNumber.Value.ToString("0000") + "-" + songKey;
|
||||
}
|
||||
|
||||
songKey += Name;
|
||||
|
||||
if (!string.IsNullOrEmpty(Album))
|
||||
@@ -117,6 +120,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
return UnratedItem.Music;
|
||||
}
|
||||
|
||||
return base.GetBlockUnratedType();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
public interface IHasMusicGenres
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
using MetadataProvider = MediaBrowser.Model.Entities.MetadataProvider;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Class MusicAlbum
|
||||
/// Class MusicAlbum.
|
||||
/// </summary>
|
||||
public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>, IMetadataContainer
|
||||
{
|
||||
@@ -55,6 +58,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
return LibraryManager.GetArtist(name, options);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -97,14 +101,14 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
list.Insert(0, albumArtist + "-" + Name);
|
||||
}
|
||||
|
||||
var id = this.GetProviderId(MetadataProviders.MusicBrainzAlbum);
|
||||
var id = this.GetProviderId(MetadataProvider.MusicBrainzAlbum);
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
list.Insert(0, "MusicAlbum-Musicbrainz-" + id);
|
||||
}
|
||||
|
||||
id = this.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
|
||||
id = this.GetProviderId(MetadataProvider.MusicBrainzReleaseGroup);
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
@@ -114,9 +118,9 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
protected override bool GetBlockUnratedValue(User user)
|
||||
{
|
||||
return config.BlockUnratedItems.Contains(UnratedItem.Music);
|
||||
return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Music.ToString());
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MetadataProvider = MediaBrowser.Model.Entities.MetadataProvider;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Class MusicArtist
|
||||
/// Class MusicArtist.
|
||||
/// </summary>
|
||||
public class MusicArtist : Folder, IItemByName, IHasMusicGenres, IHasDualAccess, IHasLookupInfo<ArtistInfo>
|
||||
{
|
||||
@@ -76,11 +79,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
|
||||
public override int GetChildCount(User user)
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return base.GetChildCount(user);
|
||||
return IsAccessedByName ? 0 : base.GetChildCount(user);
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
@@ -114,7 +113,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
|
||||
/// <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>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
@@ -128,7 +127,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
private static List<string> GetUserDataKeys(MusicArtist item)
|
||||
{
|
||||
var list = new List<string>();
|
||||
var id = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
|
||||
var id = item.GetProviderId(MetadataProvider.MusicBrainzArtist);
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
@@ -138,13 +137,15 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
list.Add("Artist-" + (item.Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return "Artist-" + (Name ?? string.Empty).RemoveDiacritics();
|
||||
}
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
|
||||
protected override bool GetBlockUnratedValue(User user)
|
||||
{
|
||||
return config.BlockUnratedItems.Contains(UnratedItem.Music);
|
||||
return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Music.ToString());
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
@@ -203,7 +204,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made.
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh(bool replaceAllMetdata)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
@@ -7,7 +9,7 @@ using Microsoft.Extensions.Logging;
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Class MusicGenre
|
||||
/// Class MusicGenre.
|
||||
/// </summary>
|
||||
public class MusicGenre : BaseItem, IItemByName
|
||||
{
|
||||
@@ -18,6 +20,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
@@ -34,7 +37,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
|
||||
/// <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>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
@@ -94,11 +97,12 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
Logger.LogDebug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made.
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh(bool replaceAllMetdata)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
@@ -15,8 +17,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
[JsonIgnore]
|
||||
public string SeriesPresentationUniqueKey { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string SeriesName { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid SeriesId { get; set; }
|
||||
|
||||
@@ -24,10 +28,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return SeriesName;
|
||||
}
|
||||
|
||||
public string FindSeriesName()
|
||||
{
|
||||
return SeriesName;
|
||||
}
|
||||
|
||||
public string FindSeriesPresentationUniqueKey()
|
||||
{
|
||||
return SeriesPresentationUniqueKey;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -7,6 +9,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 +28,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" };
|
||||
@@ -57,13 +60,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
protected BaseItem()
|
||||
{
|
||||
ThemeSongIds = Array.Empty<Guid>();
|
||||
ThemeVideoIds = Array.Empty<Guid>();
|
||||
Tags = Array.Empty<string>();
|
||||
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";
|
||||
@@ -97,16 +98,57 @@ namespace MediaBrowser.Controller.Entities
|
||||
};
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid[] ThemeSongIds { get; set; }
|
||||
public Guid[] ThemeSongIds
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_themeSongIds == null)
|
||||
{
|
||||
_themeSongIds = GetExtras()
|
||||
.Where(extra => extra.ExtraType == Model.Entities.ExtraType.ThemeSong)
|
||||
.Select(song => song.Id)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return _themeSongIds;
|
||||
}
|
||||
|
||||
private set
|
||||
{
|
||||
_themeSongIds = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid[] ThemeVideoIds { get; set; }
|
||||
public Guid[] ThemeVideoIds
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_themeVideoIds == null)
|
||||
{
|
||||
_themeVideoIds = GetExtras()
|
||||
.Where(extra => extra.ExtraType == Model.Entities.ExtraType.ThemeVideo)
|
||||
.Select(song => song.Id)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return _themeVideoIds;
|
||||
}
|
||||
|
||||
private set
|
||||
{
|
||||
_themeVideoIds = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public string PreferredMetadataCountryCode { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string PreferredMetadataLanguage { get; set; }
|
||||
|
||||
public long? Size { get; set; }
|
||||
|
||||
public string Container { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
@@ -242,7 +284,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 +308,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 +341,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
get
|
||||
{
|
||||
//if (IsOffline)
|
||||
// if (IsOffline)
|
||||
//{
|
||||
// return LocationType.Offline;
|
||||
//}
|
||||
@@ -410,7 +452,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 +489,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
// hack alert
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SourceType == SourceType.Channel)
|
||||
{
|
||||
// hack alert
|
||||
@@ -481,12 +524,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 +570,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 +598,26 @@ namespace MediaBrowser.Controller.Entities
|
||||
public DateTime DateLastRefreshed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The logger
|
||||
/// The logger.
|
||||
/// </summary>
|
||||
public static ILogger Logger { 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 +637,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.
|
||||
@@ -601,7 +653,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
if (!IsFileProtocol)
|
||||
{
|
||||
return new string[] { };
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
return new[] { Path };
|
||||
@@ -621,6 +673,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
private string _sortName;
|
||||
private Guid[] _themeSongIds;
|
||||
private Guid[] _themeVideoIds;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the sort.
|
||||
/// </summary>
|
||||
@@ -642,8 +697,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
_sortName = CreateSortName();
|
||||
}
|
||||
}
|
||||
|
||||
return _sortName;
|
||||
}
|
||||
|
||||
set => _sortName = value;
|
||||
}
|
||||
|
||||
@@ -661,11 +718,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
return System.IO.Path.Combine(basePath, "channels", ChannelId.ToString("N", CultureInfo.InvariantCulture), Id.ToString("N", CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
var idString = Id.ToString("N", CultureInfo.InvariantCulture);
|
||||
ReadOnlySpan<char> idString = Id.ToString("N", CultureInfo.InvariantCulture);
|
||||
|
||||
basePath = System.IO.Path.Combine(basePath, "library");
|
||||
|
||||
return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString);
|
||||
return System.IO.Path.Join(basePath, idString.Slice(0, 2), idString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -674,7 +731,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)
|
||||
{
|
||||
@@ -685,26 +745,27 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
foreach (var removeChar in ConfigurationManager.Configuration.SortRemoveCharacters)
|
||||
{
|
||||
sortable = sortable.Replace(removeChar, string.Empty);
|
||||
sortable = sortable.Replace(removeChar, string.Empty, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
foreach (var replaceChar in ConfigurationManager.Configuration.SortReplaceCharacters)
|
||||
{
|
||||
sortable = sortable.Replace(replaceChar, " ");
|
||||
sortable = sortable.Replace(replaceChar, " ", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
foreach (var search in ConfigurationManager.Configuration.SortRemoveWords)
|
||||
{
|
||||
// Remove from beginning if a space follows
|
||||
if (sortable.StartsWith(search + " "))
|
||||
if (sortable.StartsWith(search + " ", StringComparison.Ordinal))
|
||||
{
|
||||
sortable = sortable.Remove(0, search.Length + 1);
|
||||
}
|
||||
|
||||
// Remove from middle if surrounded by spaces
|
||||
sortable = sortable.Replace(" " + search + " ", " ");
|
||||
sortable = sortable.Replace(" " + search + " ", " ", StringComparison.Ordinal);
|
||||
|
||||
// Remove from end if followed by a space
|
||||
if (sortable.EndsWith(" " + search))
|
||||
if (sortable.EndsWith(" " + search, StringComparison.Ordinal))
|
||||
{
|
||||
sortable = sortable.Remove(sortable.Length - (search.Length + 1));
|
||||
}
|
||||
@@ -734,7 +795,8 @@ 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 +827,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
get => GetParent() as Folder;
|
||||
set
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -798,7 +859,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 +874,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -836,6 +898,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return LibraryManager.GetItemById(id);
|
||||
}
|
||||
}
|
||||
@@ -1004,12 +1067,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 +1125,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0)
|
||||
.ThenByDescending(i =>
|
||||
{
|
||||
@@ -1213,11 +1275,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 +1307,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 +1406,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 +1433,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
new List<FileSystemMetadata>();
|
||||
|
||||
var ownedItemsChanged = await RefreshedOwnedItems(options, files, cancellationToken).ConfigureAwait(false);
|
||||
await LibraryManager.UpdateImagesAsync(this).ConfigureAwait(false); // ensure all image properties in DB are fresh
|
||||
|
||||
if (ownedItemsChanged)
|
||||
{
|
||||
@@ -1563,7 +1623,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
item.ThemeVideoIds = newThemeVideoIds;
|
||||
// They are expected to be sorted by SortName
|
||||
item.ThemeVideoIds = newThemeVideos.OrderBy(i => i.SortName).Select(i => i.Id).ToArray();
|
||||
|
||||
return themeVideosChanged;
|
||||
}
|
||||
@@ -1600,7 +1661,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
item.ThemeSongIds = newThemeSongIds;
|
||||
// They are expected to be sorted by SortName
|
||||
item.ThemeSongIds = newThemeSongs.OrderBy(i => i.SortName).Select(i => i.Id).ToArray();
|
||||
|
||||
return themeSongsChanged;
|
||||
}
|
||||
@@ -1755,7 +1817,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 +1834,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
var maxAllowedRating = user.Policy.MaxParentalRating;
|
||||
var maxAllowedRating = user.MaxParentalAgeRating;
|
||||
|
||||
if (maxAllowedRating == null)
|
||||
{
|
||||
@@ -1788,7 +1850,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
if (string.IsNullOrEmpty(rating))
|
||||
{
|
||||
return !GetBlockUnratedValue(user.Policy);
|
||||
return !GetBlockUnratedValue(user);
|
||||
}
|
||||
|
||||
var value = LocalizationManager.GetRatingLevel(rating);
|
||||
@@ -1796,7 +1858,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 +1920,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 +1946,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 +2123,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 +2159,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 +2187,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 +2234,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 +2254,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 +2280,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
existingImage.DateModified = image.DateModified;
|
||||
existingImage.Width = image.Width;
|
||||
existingImage.Height = image.Height;
|
||||
existingImage.BlurHash = image.BlurHash;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2265,7 +2324,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="index">The index.</param>
|
||||
public void DeleteImage(ImageType type, int index)
|
||||
public async Task DeleteImageAsync(ImageType type, int index)
|
||||
{
|
||||
var info = GetImageInfo(type, index);
|
||||
|
||||
@@ -2283,7 +2342,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
FileSystem.DeleteFile(info.Path);
|
||||
}
|
||||
|
||||
UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
|
||||
await UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public void RemoveImage(ItemImageInfo image)
|
||||
@@ -2296,10 +2355,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
ImageInfos = ImageInfos.Except(deletedImages).ToArray();
|
||||
}
|
||||
|
||||
public virtual void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
|
||||
{
|
||||
LibraryManager.UpdateItem(this, GetParent(), updateReason, cancellationToken);
|
||||
}
|
||||
public virtual Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
|
||||
=> LibraryManager.UpdateItemAsync(this, GetParent(), updateReason, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Validates that images within the item are still on the filesystem.
|
||||
@@ -2373,6 +2430,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 +2568,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()
|
||||
@@ -2504,7 +2601,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return type == ImageType.Backdrop || type == ImageType.Screenshot || type == ImageType.Chapter;
|
||||
}
|
||||
|
||||
public void SwapImages(ImageType type, int index1, int index2)
|
||||
public Task SwapImagesAsync(ImageType type, int index1, int index2)
|
||||
{
|
||||
if (!AllowsMultipleImages(type))
|
||||
{
|
||||
@@ -2517,13 +2614,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
if (info1 == null || info2 == null)
|
||||
{
|
||||
// Nothing to do
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (!info1.IsLocalFile || !info2.IsLocalFile)
|
||||
{
|
||||
// TODO: Not supported yet
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
var path1 = info1.Path;
|
||||
@@ -2540,7 +2637,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
info2.Width = 0;
|
||||
info2.Height = 0;
|
||||
|
||||
UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
|
||||
return UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None);
|
||||
}
|
||||
|
||||
public virtual bool IsPlayed(User user)
|
||||
@@ -2579,6 +2676,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return new T
|
||||
{
|
||||
Path = Path,
|
||||
MetadataCountryCode = GetPreferredMetadataCountryCode(),
|
||||
MetadataLanguage = GetPreferredMetadataLanguage(),
|
||||
Name = GetNameForMetadataLookup(),
|
||||
@@ -2720,8 +2818,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 +2861,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]
|
||||
@@ -2862,12 +2953,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public IEnumerable<BaseItem> GetThemeSongs()
|
||||
{
|
||||
return ThemeVideoIds.Select(LibraryManager.GetItemById).Where(i => i.ExtraType.Equals(Model.Entities.ExtraType.ThemeSong)).OrderBy(i => i.SortName);
|
||||
return ThemeSongIds.Select(LibraryManager.GetItemById);
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetThemeVideos()
|
||||
{
|
||||
return ThemeVideoIds.Select(LibraryManager.GetItemById).Where(i => i.ExtraType.Equals(Model.Entities.ExtraType.ThemeVideo)).OrderBy(i => i.SortName);
|
||||
return ThemeVideoIds.Select(LibraryManager.GetItemById);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2904,9 +2995,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;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
@@ -26,13 +28,5 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
//public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
//{
|
||||
// double value = 16;
|
||||
// value /= 9;
|
||||
|
||||
// return value;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
@@ -11,6 +13,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
[JsonIgnore]
|
||||
public override string MediaType => Model.Entities.MediaType.Book;
|
||||
|
||||
public override bool SupportsPlayedStatus => true;
|
||||
|
||||
public override bool SupportsPositionTicksResume => true;
|
||||
|
||||
[JsonIgnore]
|
||||
public string SeriesPresentationUniqueKey { get; set; }
|
||||
|
||||
@@ -20,6 +26,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
[JsonIgnore]
|
||||
public Guid SeriesId { get; set; }
|
||||
|
||||
public Book()
|
||||
{
|
||||
this.RunTimeTicks = TimeSpan.TicksPerSecond;
|
||||
}
|
||||
|
||||
public string FindSeriesSortName()
|
||||
{
|
||||
return SeriesName;
|
||||
@@ -40,11 +51,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
return SeriesId;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanDownload()
|
||||
{
|
||||
return IsFileProtocol;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Book;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -18,12 +20,14 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Specialized Folder class that points to a subset of the physical folders in the system.
|
||||
/// It is created from the user-specific folders within the system root
|
||||
/// It is created from the user-specific folders within the system root.
|
||||
/// </summary>
|
||||
public class CollectionFolder : Folder, ICollectionFolder
|
||||
{
|
||||
public static IXmlSerializer XmlSerializer { get; set; }
|
||||
|
||||
public static IJsonSerializer JsonSerializer { get; set; }
|
||||
|
||||
public static IServerApplicationHost ApplicationHost { get; set; }
|
||||
|
||||
public CollectionFolder()
|
||||
@@ -140,7 +144,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow different display preferences for each collection folder
|
||||
/// Allow different display preferences for each collection folder.
|
||||
/// </summary>
|
||||
/// <value>The display prefs id.</value>
|
||||
[JsonIgnore]
|
||||
@@ -155,6 +159,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
public string[] PhysicalLocationsList { get; set; }
|
||||
|
||||
public Guid[] PhysicalFolderIds { get; set; }
|
||||
|
||||
protected override FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService)
|
||||
@@ -222,7 +227,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return null;
|
||||
}
|
||||
|
||||
return (totalProgresses / foldersWithProgress);
|
||||
return totalProgresses / foldersWithProgress;
|
||||
}
|
||||
|
||||
protected override bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren)
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public static class DayOfWeekHelper
|
||||
{
|
||||
public static List<DayOfWeek> GetDaysOfWeek(DynamicDayOfWeek day)
|
||||
{
|
||||
return GetDaysOfWeek(new List<DynamicDayOfWeek> { day });
|
||||
}
|
||||
|
||||
public static List<DayOfWeek> GetDaysOfWeek(List<DynamicDayOfWeek> days)
|
||||
{
|
||||
var list = new List<DayOfWeek>();
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Sunday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekend) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Sunday);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Saturday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekend) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Saturday);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Monday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekday) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Monday);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Tuesday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekday) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Tuesday
|
||||
);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Wednesday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekday) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Wednesday);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Thursday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekday) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Thursday);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Friday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekday) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Friday);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using MediaBrowser.Model.Entities;
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Extensions
|
||||
/// Class Extensions.
|
||||
/// </summary>
|
||||
public static class Extensions
|
||||
{
|
||||
|
||||
@@ -8,6 +8,8 @@ using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Common.Progress;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Collections;
|
||||
@@ -15,18 +17,21 @@ using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||
using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
|
||||
using Season = MediaBrowser.Controller.Entities.TV.Season;
|
||||
using Series = MediaBrowser.Controller.Entities.TV.Series;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Folder
|
||||
/// Class Folder.
|
||||
/// </summary>
|
||||
public class Folder : BaseItem
|
||||
{
|
||||
@@ -121,10 +126,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this is UserView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -151,6 +158,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
item.DateCreated = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
if (item.DateModified == DateTime.MinValue)
|
||||
{
|
||||
item.DateModified = DateTime.UtcNow;
|
||||
@@ -167,7 +175,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
public virtual IEnumerable<BaseItem> Children => LoadChildren();
|
||||
|
||||
/// <summary>
|
||||
/// thread-safe access to all recursive children of this folder - without regard to user
|
||||
/// thread-safe access to all recursive children of this folder - without regard to user.
|
||||
/// </summary>
|
||||
/// <value>The recursive children.</value>
|
||||
[JsonIgnore]
|
||||
@@ -177,19 +185,22 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
if (this is ICollectionFolder && !(this is BasePluginFolder))
|
||||
{
|
||||
if (user.Policy.BlockedMediaFolders != null)
|
||||
var blockedMediaFolders = user.GetPreference(PreferenceKind.BlockedMediaFolders);
|
||||
if (blockedMediaFolders.Length > 0)
|
||||
{
|
||||
if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase) ||
|
||||
if (blockedMediaFolders.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase) ||
|
||||
|
||||
// Backwards compatibility
|
||||
user.Policy.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase))
|
||||
blockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase))
|
||||
if (!user.HasPermission(PermissionKind.EnableAllFolders)
|
||||
&& !user.GetPreference(PreferenceKind.EnabledFolders)
|
||||
.Contains(Id.ToString("N", CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -205,8 +216,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
protected virtual List<BaseItem> LoadChildren()
|
||||
{
|
||||
//logger.LogDebug("Loading children from {0} {1} {2}", GetType().Name, Id, Path);
|
||||
//just load our children from the repo - the library will be validated and maintained in other processes
|
||||
// logger.LogDebug("Loading children from {0} {1} {2}", GetType().Name, Id, Path);
|
||||
// just load our children from the repo - the library will be validated and maintained in other processes
|
||||
return GetCachedChildren();
|
||||
}
|
||||
|
||||
@@ -221,7 +232,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the children of the folder still exist
|
||||
/// Validates that the children of the folder still exist.
|
||||
/// </summary>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
@@ -339,7 +350,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
if (currentChild.UpdateFromResolvedItem(child) > ItemUpdateType.None)
|
||||
{
|
||||
currentChild.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken);
|
||||
await currentChild.UpdateToRepositoryAsync(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// metadata is up-to-date; make sure DB has correct images dimensions and hash
|
||||
await LibraryManager.UpdateImagesAsync(currentChild).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -464,7 +480,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
innerProgress.RegisterAction(p =>
|
||||
{
|
||||
double innerPercent = currentInnerPercent;
|
||||
innerPercent += p / (count);
|
||||
innerPercent += p / count;
|
||||
progress.Report(innerPercent);
|
||||
});
|
||||
|
||||
@@ -487,8 +503,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
if (series != null)
|
||||
{
|
||||
await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
|
||||
await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -540,7 +556,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
innerProgress.RegisterAction(p =>
|
||||
{
|
||||
double innerPercent = currentInnerPercent;
|
||||
innerPercent += p / (count);
|
||||
innerPercent += p / count;
|
||||
progress.Report(innerPercent);
|
||||
});
|
||||
|
||||
@@ -558,7 +574,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the children of this folder from the actual file system
|
||||
/// Get the children of this folder from the actual file system.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
protected virtual IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
||||
@@ -570,7 +586,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get our children from the repo - stubbed for now
|
||||
/// Get our children from the repo - stubbed for now.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
protected List<BaseItem> GetCachedChildren()
|
||||
@@ -602,7 +618,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
EnableImages = false
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return result.TotalRecordCount;
|
||||
@@ -877,7 +892,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
try
|
||||
{
|
||||
query.Parent = this;
|
||||
query.ChannelIds = new Guid[] { ChannelId };
|
||||
query.ChannelIds = new[] { ChannelId };
|
||||
|
||||
// Don't blow up here because it could cause parent screens with other content to fail
|
||||
return ChannelManager.GetChannelItemsInternal(query, new SimpleProgress<double>(), CancellationToken.None).Result;
|
||||
@@ -928,6 +943,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
items = items.Where(i => string.Compare(query.NameStartsWithOrGreater, i.SortName, StringComparison.CurrentCultureIgnoreCase) < 1);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(query.NameStartsWith))
|
||||
{
|
||||
items = items.Where(i => i.SortName.StartsWith(query.NameStartsWith, StringComparison.OrdinalIgnoreCase));
|
||||
@@ -947,11 +963,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
return UserViewBuilder.SortAndPage(items, null, query, LibraryManager, enableSorting);
|
||||
}
|
||||
|
||||
private static IEnumerable<BaseItem> CollapseBoxSetItemsIfNeeded(IEnumerable<BaseItem> items,
|
||||
private static IEnumerable<BaseItem> CollapseBoxSetItemsIfNeeded(
|
||||
IEnumerable<BaseItem> items,
|
||||
InternalItemsQuery query,
|
||||
BaseItem queryParent,
|
||||
User user,
|
||||
IServerConfigurationManager configurationManager, ICollectionManager collectionManager)
|
||||
IServerConfigurationManager configurationManager,
|
||||
ICollectionManager collectionManager)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
@@ -976,18 +994,22 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (queryParent is Series)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (queryParent is Season)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (queryParent is MusicAlbum)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (queryParent is MusicArtist)
|
||||
{
|
||||
return false;
|
||||
@@ -1017,22 +1039,27 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.IsFavoriteOrLiked.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.IsLiked.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.IsPlayed.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.IsResumable.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.IsFolder.HasValue)
|
||||
{
|
||||
return false;
|
||||
@@ -1208,7 +1235,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
//the true root should return our users root folder children
|
||||
// the true root should return our users root folder children
|
||||
if (IsPhysicalRoot)
|
||||
{
|
||||
return LibraryManager.GetUserRootFolder().GetChildren(user, includeLinkedChildren);
|
||||
@@ -1273,7 +1300,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets allowed recursive children of an item
|
||||
/// Gets allowed recursive children of an item.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param>
|
||||
@@ -1378,6 +1405,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
list.Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -1400,6 +1428,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1577,7 +1606,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
EnableTotalRecordCount = false
|
||||
};
|
||||
|
||||
if (!user.Configuration.DisplayMissingEpisodes)
|
||||
if (!user.DisplayMissingEpisodes)
|
||||
{
|
||||
query.IsVirtualItem = false;
|
||||
}
|
||||
@@ -1614,7 +1643,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
Recursive = true,
|
||||
IsFolder = false,
|
||||
EnableTotalRecordCount = false
|
||||
|
||||
});
|
||||
|
||||
// Sweep through recursively and update status
|
||||
@@ -1632,7 +1660,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
IsFolder = false,
|
||||
IsVirtualItem = false,
|
||||
EnableTotalRecordCount = false
|
||||
|
||||
});
|
||||
|
||||
return itemsResult
|
||||
@@ -1654,22 +1681,27 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this is UserView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this is UserRootFolder)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this is Channel)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SourceType != SourceType.Library)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var iItemByName = this as IItemByName;
|
||||
if (iItemByName != null)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
@@ -8,7 +10,7 @@ using Microsoft.Extensions.Logging;
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Genre
|
||||
/// Class Genre.
|
||||
/// </summary>
|
||||
public class Genre : BaseItem, IItemByName
|
||||
{
|
||||
@@ -19,6 +21,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
@@ -31,7 +34,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>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
@@ -92,11 +95,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
Logger.LogDebug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made.
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh(bool replaceAllMetdata)
|
||||
{
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// This is just a marker interface to denote top level folders
|
||||
/// This is just a marker interface to denote top level folders.
|
||||
/// </summary>
|
||||
public interface ICollectionFolder : IHasCollectionType
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IHasAspectRatio
|
||||
/// Interface IHasAspectRatio.
|
||||
/// </summary>
|
||||
public interface IHasAspectRatio
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IHasDisplayOrder
|
||||
/// Interface IHasDisplayOrder.
|
||||
/// </summary>
|
||||
public interface IHasDisplayOrder
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Dto;
|
||||
@@ -7,13 +9,19 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasMediaSources
|
||||
{
|
||||
Guid Id { get; set; }
|
||||
|
||||
long? RunTimeTicks { get; set; }
|
||||
|
||||
string Path { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media sources.
|
||||
/// </summary>
|
||||
List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
|
||||
|
||||
List<MediaStream> GetMediaStreams();
|
||||
Guid Id { get; set; }
|
||||
long? RunTimeTicks { get; set; }
|
||||
string Path { get; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
@@ -5,13 +7,21 @@ namespace MediaBrowser.Controller.Entities
|
||||
public interface IHasProgramAttributes
|
||||
{
|
||||
bool IsMovie { get; set; }
|
||||
|
||||
bool IsSports { get; }
|
||||
|
||||
bool IsNews { get; }
|
||||
|
||||
bool IsKids { get; }
|
||||
|
||||
bool IsRepeat { get; set; }
|
||||
|
||||
bool IsSeries { get; set; }
|
||||
|
||||
ProgramAudio? Audio { get; set; }
|
||||
|
||||
string EpisodeTitle { get; set; }
|
||||
|
||||
string ServiceName { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IHasScreenshots
|
||||
/// Interface IHasScreenshots.
|
||||
/// </summary>
|
||||
public interface IHasScreenshots
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
@@ -9,11 +11,17 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
/// <value>The name of the series.</value>
|
||||
string SeriesName { get; set; }
|
||||
string FindSeriesName();
|
||||
string FindSeriesSortName();
|
||||
|
||||
Guid SeriesId { get; set; }
|
||||
Guid FindSeriesId();
|
||||
|
||||
string SeriesPresentationUniqueKey { get; set; }
|
||||
|
||||
string FindSeriesName();
|
||||
|
||||
string FindSeriesSortName();
|
||||
|
||||
Guid FindSeriesId();
|
||||
|
||||
string FindSeriesPresentationUniqueKey();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
@@ -8,6 +11,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// Gets or sets the special feature ids.
|
||||
/// </summary>
|
||||
/// <value>The special feature ids.</value>
|
||||
Guid[] SpecialFeatureIds { get; set; }
|
||||
IReadOnlyList<Guid> SpecialFeatureIds { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface ISupportsPlaceHolders
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
@@ -20,100 +23,167 @@ namespace MediaBrowser.Controller.Entities
|
||||
public BaseItem SimilarTo { get; set; }
|
||||
|
||||
public bool? IsFolder { get; set; }
|
||||
|
||||
public bool? IsFavorite { get; set; }
|
||||
|
||||
public bool? IsFavoriteOrLiked { get; set; }
|
||||
|
||||
public bool? IsLiked { get; set; }
|
||||
|
||||
public bool? IsPlayed { get; set; }
|
||||
|
||||
public bool? IsResumable { get; set; }
|
||||
|
||||
public bool? IncludeItemsByName { get; set; }
|
||||
|
||||
public string[] MediaTypes { get; set; }
|
||||
|
||||
public string[] IncludeItemTypes { get; set; }
|
||||
|
||||
public string[] ExcludeItemTypes { get; set; }
|
||||
|
||||
public string[] ExcludeTags { get; set; }
|
||||
|
||||
public string[] ExcludeInheritedTags { get; set; }
|
||||
|
||||
public string[] Genres { get; set; }
|
||||
|
||||
public bool? IsSpecialSeason { get; set; }
|
||||
|
||||
public bool? IsMissing { get; set; }
|
||||
|
||||
public bool? IsUnaired { get; set; }
|
||||
|
||||
public bool? CollapseBoxSetItems { get; set; }
|
||||
|
||||
public string NameStartsWithOrGreater { get; set; }
|
||||
|
||||
public string NameStartsWith { get; set; }
|
||||
|
||||
public string NameLessThan { get; set; }
|
||||
|
||||
public string NameContains { get; set; }
|
||||
|
||||
public string MinSortName { get; set; }
|
||||
|
||||
public string PresentationUniqueKey { get; set; }
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Person { get; set; }
|
||||
|
||||
public Guid[] PersonIds { get; set; }
|
||||
|
||||
public Guid[] ItemIds { get; set; }
|
||||
|
||||
public Guid[] ExcludeItemIds { get; set; }
|
||||
|
||||
public string AdjacentTo { get; set; }
|
||||
|
||||
public string[] PersonTypes { get; set; }
|
||||
|
||||
public bool? Is3D { get; set; }
|
||||
|
||||
public bool? IsHD { get; set; }
|
||||
|
||||
public bool? IsLocked { get; set; }
|
||||
|
||||
public bool? IsPlaceHolder { get; set; }
|
||||
|
||||
public bool? HasImdbId { get; set; }
|
||||
|
||||
public bool? HasOverview { get; set; }
|
||||
|
||||
public bool? HasTmdbId { get; set; }
|
||||
|
||||
public bool? HasOfficialRating { get; set; }
|
||||
|
||||
public bool? HasTvdbId { get; set; }
|
||||
|
||||
public bool? HasThemeSong { get; set; }
|
||||
|
||||
public bool? HasThemeVideo { get; set; }
|
||||
|
||||
public bool? HasSubtitles { get; set; }
|
||||
|
||||
public bool? HasSpecialFeature { get; set; }
|
||||
|
||||
public bool? HasTrailer { get; set; }
|
||||
|
||||
public bool? HasParentalRating { get; set; }
|
||||
|
||||
public Guid[] StudioIds { get; set; }
|
||||
|
||||
public Guid[] GenreIds { get; set; }
|
||||
|
||||
public ImageType[] ImageTypes { get; set; }
|
||||
|
||||
public VideoType[] VideoTypes { get; set; }
|
||||
|
||||
public UnratedItem[] BlockUnratedItems { get; set; }
|
||||
|
||||
public int[] Years { get; set; }
|
||||
|
||||
public string[] Tags { get; set; }
|
||||
|
||||
public string[] OfficialRatings { get; set; }
|
||||
|
||||
public DateTime? MinPremiereDate { get; set; }
|
||||
|
||||
public DateTime? MaxPremiereDate { get; set; }
|
||||
|
||||
public DateTime? MinStartDate { get; set; }
|
||||
|
||||
public DateTime? MaxStartDate { get; set; }
|
||||
|
||||
public DateTime? MinEndDate { get; set; }
|
||||
|
||||
public DateTime? MaxEndDate { get; set; }
|
||||
|
||||
public bool? IsAiring { get; set; }
|
||||
|
||||
public bool? IsMovie { get; set; }
|
||||
|
||||
public bool? IsSports { get; set; }
|
||||
|
||||
public bool? IsKids { get; set; }
|
||||
|
||||
public bool? IsNews { get; set; }
|
||||
|
||||
public bool? IsSeries { get; set; }
|
||||
|
||||
public int? MinIndexNumber { get; set; }
|
||||
|
||||
public int? AiredDuringSeason { get; set; }
|
||||
|
||||
public double? MinCriticRating { get; set; }
|
||||
|
||||
public double? MinCommunityRating { get; set; }
|
||||
|
||||
public Guid[] ChannelIds { get; set; }
|
||||
|
||||
public int? ParentIndexNumber { get; set; }
|
||||
|
||||
public int? ParentIndexNumberNotEquals { get; set; }
|
||||
|
||||
public int? IndexNumber { get; set; }
|
||||
|
||||
public int? MinParentalRating { get; set; }
|
||||
|
||||
public int? MaxParentalRating { get; set; }
|
||||
|
||||
public bool? HasDeadParentId { get; set; }
|
||||
|
||||
public bool? IsVirtualItem { get; set; }
|
||||
|
||||
public Guid ParentId { get; set; }
|
||||
|
||||
public string ParentType { get; set; }
|
||||
|
||||
public Guid[] AncestorIds { get; set; }
|
||||
|
||||
public Guid[] TopParentIds { get; set; }
|
||||
|
||||
public BaseItem Parent
|
||||
@@ -134,41 +204,65 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
public string[] PresetViews { get; set; }
|
||||
|
||||
public TrailerType[] TrailerTypes { get; set; }
|
||||
|
||||
public SourceType[] SourceTypes { get; set; }
|
||||
|
||||
public SeriesStatus[] SeriesStatuses { get; set; }
|
||||
|
||||
public string ExternalSeriesId { get; set; }
|
||||
|
||||
public string ExternalId { get; set; }
|
||||
|
||||
public Guid[] AlbumIds { get; set; }
|
||||
|
||||
public Guid[] ArtistIds { get; set; }
|
||||
|
||||
public Guid[] ExcludeArtistIds { get; set; }
|
||||
|
||||
public string AncestorWithPresentationUniqueKey { get; set; }
|
||||
|
||||
public string SeriesPresentationUniqueKey { get; set; }
|
||||
|
||||
public bool GroupByPresentationUniqueKey { get; set; }
|
||||
|
||||
public bool GroupBySeriesPresentationUniqueKey { get; set; }
|
||||
|
||||
public bool EnableTotalRecordCount { get; set; }
|
||||
|
||||
public bool ForceDirect { get; set; }
|
||||
|
||||
public Dictionary<string, string> ExcludeProviderIds { get; set; }
|
||||
|
||||
public bool EnableGroupByMetadataKey { get; set; }
|
||||
|
||||
public bool? HasChapterImages { get; set; }
|
||||
|
||||
public IReadOnlyList<(string, SortOrder)> OrderBy { get; set; }
|
||||
|
||||
public DateTime? MinDateCreated { get; set; }
|
||||
|
||||
public DateTime? MinDateLastSaved { get; set; }
|
||||
|
||||
public DateTime? MinDateLastSavedForUser { get; set; }
|
||||
|
||||
public DtoOptions DtoOptions { get; set; }
|
||||
|
||||
public int MinSimilarityScore { get; set; }
|
||||
|
||||
public string HasNoAudioTrackWithLanguage { get; set; }
|
||||
|
||||
public string HasNoInternalSubtitleTrackWithLanguage { get; set; }
|
||||
|
||||
public string HasNoExternalSubtitleTrackWithLanguage { get; set; }
|
||||
|
||||
public string HasNoSubtitleTrackWithLanguage { get; set; }
|
||||
|
||||
public bool? IsDeadArtist { get; set; }
|
||||
|
||||
public bool? IsDeadStudio { get; set; }
|
||||
|
||||
public bool? IsDeadPerson { get; set; }
|
||||
|
||||
public InternalItemsQuery()
|
||||
@@ -223,32 +317,45 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
if (user != null)
|
||||
{
|
||||
var policy = user.Policy;
|
||||
MaxParentalRating = policy.MaxParentalRating;
|
||||
MaxParentalRating = user.MaxParentalAgeRating;
|
||||
|
||||
if (policy.MaxParentalRating.HasValue)
|
||||
if (MaxParentalRating.HasValue)
|
||||
{
|
||||
BlockUnratedItems = policy.BlockUnratedItems.Where(i => i != UnratedItem.Other).ToArray();
|
||||
BlockUnratedItems = user.GetPreference(PreferenceKind.BlockUnratedItems)
|
||||
.Where(i => i != UnratedItem.Other.ToString())
|
||||
.Select(e => Enum.Parse<UnratedItem>(e, true)).ToArray();
|
||||
}
|
||||
|
||||
ExcludeInheritedTags = policy.BlockedTags;
|
||||
ExcludeInheritedTags = user.GetPreference(PreferenceKind.BlockedTags);
|
||||
|
||||
User = user;
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, string> HasAnyProviderId { get; set; }
|
||||
|
||||
public Guid[] AlbumArtistIds { get; set; }
|
||||
|
||||
public Guid[] BoxSetLibraryFolders { get; set; }
|
||||
|
||||
public Guid[] ContributingArtistIds { get; set; }
|
||||
|
||||
public bool? HasAired { get; set; }
|
||||
|
||||
public bool? HasOwnerId { get; set; }
|
||||
|
||||
public bool? Is4K { get; set; }
|
||||
|
||||
public int? MaxHeight { get; set; }
|
||||
|
||||
public int? MaxWidth { get; set; }
|
||||
|
||||
public int? MinHeight { get; set; }
|
||||
|
||||
public int? MinWidth { get; set; }
|
||||
|
||||
public string SearchTerm { get; set; }
|
||||
|
||||
public string SeriesTimerId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using MediaBrowser.Model.Entities;
|
||||
@@ -28,6 +30,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public int Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the blurhash.
|
||||
/// </summary>
|
||||
/// <value>The blurhash.</value>
|
||||
public string BlurHash { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool IsLocalFile => Path == null || !Path.StartsWith("http", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -9,14 +11,16 @@ namespace MediaBrowser.Controller.Entities
|
||||
public class LinkedChild
|
||||
{
|
||||
public string Path { get; set; }
|
||||
|
||||
public LinkedChildType Type { get; set; }
|
||||
|
||||
public string LibraryItemId { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a cache
|
||||
/// Serves as a cache.
|
||||
/// </summary>
|
||||
public Guid? ItemId { get; set; }
|
||||
|
||||
@@ -63,6 +67,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return _fileSystem.AreEqual(x.Path, y.Path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Movies
|
||||
{
|
||||
/// <summary>
|
||||
/// Class BoxSet
|
||||
/// Class BoxSet.
|
||||
/// </summary>
|
||||
public class BoxSet : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<BoxSetInfo>
|
||||
{
|
||||
@@ -45,9 +47,9 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
/// <value>The display order.</value>
|
||||
public string DisplayOrder { get; set; }
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
protected override bool GetBlockUnratedValue(User user)
|
||||
{
|
||||
return config.BlockUnratedItems.Contains(UnratedItem.Movie);
|
||||
return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Movie.ToString());
|
||||
}
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
@@ -198,7 +200,7 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
|
||||
public Guid[] GetLibraryFolderIds()
|
||||
{
|
||||
var expandedFolders = new List<Guid>() { };
|
||||
var expandedFolders = new List<Guid>();
|
||||
|
||||
return FlattenItems(this, expandedFolders)
|
||||
.SelectMany(i => LibraryManager.GetCollectionFolders(i))
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Providers;
|
||||
@@ -13,12 +16,10 @@ using MediaBrowser.Model.Providers;
|
||||
namespace MediaBrowser.Controller.Entities.Movies
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Movie
|
||||
/// Class Movie.
|
||||
/// </summary>
|
||||
public class Movie : Video, IHasSpecialFeatures, IHasTrailers, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping
|
||||
{
|
||||
public Guid[] SpecialFeatureIds { get; set; }
|
||||
|
||||
public Movie()
|
||||
{
|
||||
SpecialFeatureIds = Array.Empty<Guid>();
|
||||
@@ -27,6 +28,9 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
RemoteTrailerIds = Array.Empty<Guid>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<Guid> SpecialFeatureIds { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<Guid> LocalTrailerIds { get; set; }
|
||||
|
||||
@@ -46,6 +50,9 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
set => TmdbCollectionName = value;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool StopRefreshIfLocalMetadataFound => false;
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
// hack for tv plugins
|
||||
@@ -105,6 +112,7 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
return itemsChanged;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Movie;
|
||||
@@ -133,6 +141,7 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
return info;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool BeforeMetadataRefresh(bool replaceAllMetdata)
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh(replaceAllMetdata);
|
||||
@@ -169,24 +178,22 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override List<ExternalUrl> GetRelatedUrls()
|
||||
{
|
||||
var list = base.GetRelatedUrls();
|
||||
|
||||
var imdbId = this.GetProviderId(MetadataProviders.Imdb);
|
||||
var imdbId = this.GetProviderId(MetadataProvider.Imdb);
|
||||
if (!string.IsNullOrEmpty(imdbId))
|
||||
{
|
||||
list.Add(new ExternalUrl
|
||||
{
|
||||
Name = "Trakt",
|
||||
Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
|
||||
Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/movies/{0}", imdbId)
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool StopRefreshIfLocalMetadataFound => false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -113,6 +115,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
@@ -19,6 +21,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
@@ -46,7 +49,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>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
@@ -114,11 +117,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
Logger.LogDebug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made.
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh(bool replaceAllMetdata)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
|
||||
@@ -29,6 +31,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return photoAlbum;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -68,17 +71,27 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
public string CameraMake { get; set; }
|
||||
|
||||
public string CameraModel { get; set; }
|
||||
|
||||
public string Software { get; set; }
|
||||
|
||||
public double? ExposureTime { get; set; }
|
||||
|
||||
public double? FocalLength { get; set; }
|
||||
|
||||
public ImageOrientation? Orientation { get; set; }
|
||||
|
||||
public double? Aperture { get; set; }
|
||||
|
||||
public double? ShutterSpeed { get; set; }
|
||||
|
||||
public double? Latitude { get; set; }
|
||||
|
||||
public double? Longitude { get; set; }
|
||||
|
||||
public double? Altitude { get; set; }
|
||||
|
||||
public int? IsoSpeedRating { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasShares
|
||||
@@ -8,6 +10,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
public class Share
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
|
||||
public bool CanEdit { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public enum SourceType
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
@@ -7,7 +9,7 @@ using Microsoft.Extensions.Logging;
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Studio
|
||||
/// Class Studio.
|
||||
/// </summary>
|
||||
public class Studio : BaseItem, IItemByName
|
||||
{
|
||||
@@ -18,6 +20,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
@@ -25,7 +28,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>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
@@ -93,11 +96,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
Logger.LogDebug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made.
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh(bool replaceAllMetdata)
|
||||
{
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -12,7 +14,7 @@ using Microsoft.Extensions.Logging;
|
||||
namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Episode
|
||||
/// Class Episode.
|
||||
/// </summary>
|
||||
public class Episode : Video, IHasTrailers, IHasLookupInfo<EpisodeInfo>, IHasSeries
|
||||
{
|
||||
@@ -34,7 +36,9 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
/// </summary>
|
||||
/// <value>The aired season.</value>
|
||||
public int? AirsBeforeSeasonNumber { get; set; }
|
||||
|
||||
public int? AirsAfterSeasonNumber { get; set; }
|
||||
|
||||
public int? AirsBeforeEpisodeNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -94,6 +98,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
take--;
|
||||
}
|
||||
|
||||
list.InsertRange(0, seriesUserDataKeys.Take(take).Select(i => i + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000")));
|
||||
}
|
||||
|
||||
@@ -101,7 +106,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This Episode's Series Instance
|
||||
/// This Episode's Series Instance.
|
||||
/// </summary>
|
||||
/// <value>The series.</value>
|
||||
[JsonIgnore]
|
||||
@@ -114,6 +119,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
seriesId = FindSeriesId();
|
||||
}
|
||||
|
||||
return !seriesId.Equals(Guid.Empty) ? (LibraryManager.GetItemById(seriesId) as Series) : null;
|
||||
}
|
||||
}
|
||||
@@ -128,6 +134,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
seasonId = FindSeasonId();
|
||||
}
|
||||
|
||||
return !seasonId.Equals(Guid.Empty) ? (LibraryManager.GetItemById(seasonId) as Season) : null;
|
||||
}
|
||||
}
|
||||
@@ -160,6 +167,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
return "Season " + ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
return "Season Unknown";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Season
|
||||
/// Class Season.
|
||||
/// </summary>
|
||||
public class Season : Folder, IHasSeries, IHasLookupInfo<SeasonInfo>
|
||||
{
|
||||
@@ -68,7 +70,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This Episode's Series Instance
|
||||
/// This Episode's Series Instance.
|
||||
/// </summary>
|
||||
/// <value>The series.</value>
|
||||
[JsonIgnore]
|
||||
@@ -81,6 +83,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
seriesId = FindSeriesId();
|
||||
}
|
||||
|
||||
return seriesId == Guid.Empty ? null : (LibraryManager.GetItemById(seriesId) as Series);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +171,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
return GetEpisodes(user, new DtoOptions(true));
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
protected override bool GetBlockUnratedValue(User user)
|
||||
{
|
||||
// Don't block. Let either the entire series rating or episode rating determine it
|
||||
return false;
|
||||
@@ -203,7 +206,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
public Guid FindSeriesId()
|
||||
{
|
||||
var series = FindParent<Series>();
|
||||
return series == null ? Guid.Empty : series.Id;
|
||||
return series?.Id ?? Guid.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -225,7 +228,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
public override bool BeforeMetadataRefresh(bool replaceAllMetdata)
|
||||
@@ -234,7 +237,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
|
||||
if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path))
|
||||
{
|
||||
IndexNumber = IndexNumber ?? LibraryManager.GetSeasonNumberFromPath(Path);
|
||||
IndexNumber ??= LibraryManager.GetSeasonNumberFromPath(Path);
|
||||
|
||||
// If a change was made record it
|
||||
if (IndexNumber.HasValue)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -5,18 +7,19 @@ using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Users;
|
||||
using MetadataProvider = MediaBrowser.Model.Entities.MetadataProvider;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Series
|
||||
/// Class Series.
|
||||
/// </summary>
|
||||
public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IMetadataContainer
|
||||
{
|
||||
@@ -29,6 +32,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
}
|
||||
|
||||
public DayOfWeek[] AirDays { get; set; }
|
||||
|
||||
public string AirTime { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
@@ -53,7 +57,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
public IReadOnlyList<Guid> RemoteTrailerIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// airdate, dvd or absolute
|
||||
/// airdate, dvd or absolute.
|
||||
/// </summary>
|
||||
public string DisplayOrder { get; set; }
|
||||
|
||||
@@ -119,7 +123,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
AncestorWithPresentationUniqueKey = null,
|
||||
SeriesPresentationUniqueKey = seriesKey,
|
||||
IncludeItemTypes = new[] { typeof(Season).Name },
|
||||
IncludeItemTypes = new[] { nameof(Season) },
|
||||
IsVirtualItem = false,
|
||||
Limit = 0,
|
||||
DtoOptions = new DtoOptions(false)
|
||||
@@ -149,6 +153,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
query.IncludeItemTypes = new[] { typeof(Episode).Name };
|
||||
}
|
||||
|
||||
query.IsVirtualItem = false;
|
||||
query.Limit = 0;
|
||||
var totalRecordCount = LibraryManager.GetCount(query);
|
||||
@@ -164,13 +169,13 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
var key = this.GetProviderId(MetadataProviders.Imdb);
|
||||
var key = this.GetProviderId(MetadataProvider.Imdb);
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
}
|
||||
|
||||
key = this.GetProviderId(MetadataProviders.Tvdb);
|
||||
key = this.GetProviderId(MetadataProvider.Tvdb);
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
@@ -205,14 +210,9 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
query.IncludeItemTypes = new[] { typeof(Season).Name };
|
||||
query.OrderBy = new[] { ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray();
|
||||
|
||||
if (user != null)
|
||||
if (user != null && !user.DisplayMissingEpisodes)
|
||||
{
|
||||
var config = user.Configuration;
|
||||
|
||||
if (!config.DisplayMissingEpisodes)
|
||||
{
|
||||
query.IsMissing = false;
|
||||
}
|
||||
query.IsMissing = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,8 +257,8 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
OrderBy = new[] { ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
|
||||
DtoOptions = options
|
||||
};
|
||||
var config = user.Configuration;
|
||||
if (!config.DisplayMissingEpisodes)
|
||||
|
||||
if (!user.DisplayMissingEpisodes)
|
||||
{
|
||||
query.IsMissing = false;
|
||||
}
|
||||
@@ -311,7 +311,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
// Refresh episodes and other children
|
||||
foreach (var item in items)
|
||||
{
|
||||
if ((item is Season))
|
||||
if (item is Season)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -370,8 +370,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
};
|
||||
if (user != null)
|
||||
{
|
||||
var config = user.Configuration;
|
||||
if (!config.DisplayMissingEpisodes)
|
||||
if (!user.DisplayMissingEpisodes)
|
||||
{
|
||||
query.IsMissing = false;
|
||||
}
|
||||
@@ -452,9 +451,9 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
}
|
||||
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
protected override bool GetBlockUnratedValue(User user)
|
||||
{
|
||||
return config.BlockUnratedItems.Contains(UnratedItem.Series);
|
||||
return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Series.ToString());
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
@@ -493,13 +492,13 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
var list = base.GetRelatedUrls();
|
||||
|
||||
var imdbId = this.GetProviderId(MetadataProviders.Imdb);
|
||||
var imdbId = this.GetProviderId(MetadataProvider.Imdb);
|
||||
if (!string.IsNullOrEmpty(imdbId))
|
||||
{
|
||||
list.Add(new ExternalUrl
|
||||
{
|
||||
Name = "Trakt",
|
||||
Url = string.Format("https://trakt.tv/shows/{0}", imdbId)
|
||||
Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/shows/{0}", imdbId)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Trailer
|
||||
/// Class Trailer.
|
||||
/// </summary>
|
||||
public class Trailer : Video, IHasLookupInfo<TrailerInfo>
|
||||
{
|
||||
@@ -80,13 +83,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
var list = base.GetRelatedUrls();
|
||||
|
||||
var imdbId = this.GetProviderId(MetadataProviders.Imdb);
|
||||
var imdbId = this.GetProviderId(MetadataProvider.Imdb);
|
||||
if (!string.IsNullOrEmpty(imdbId))
|
||||
{
|
||||
list.Add(new ExternalUrl
|
||||
{
|
||||
Name = "Trakt",
|
||||
Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
|
||||
Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/movies/{0}", imdbId)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class User
|
||||
/// </summary>
|
||||
public class User : BaseItem
|
||||
{
|
||||
public static IUserManager UserManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
/// <value>The password.</value>
|
||||
public string Password { get; set; }
|
||||
public string EasyPassword { get; set; }
|
||||
|
||||
// Strictly to remove JsonIgnore
|
||||
public override ItemImageInfo[] ImageInfos
|
||||
{
|
||||
get => base.ImageInfos;
|
||||
set => base.ImageInfos = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path.
|
||||
/// </summary>
|
||||
/// <value>The path.</value>
|
||||
[JsonIgnore]
|
||||
public override string Path
|
||||
{
|
||||
get => ConfigurationDirectoryPath;
|
||||
set => base.Path = value;
|
||||
}
|
||||
|
||||
private string _name;
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public override string Name
|
||||
{
|
||||
get => _name;
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
|
||||
// lazy load this again
|
||||
SortName = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
public override string ContainingFolderPath => Path;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the root folder.
|
||||
/// </summary>
|
||||
/// <value>The root folder.</value>
|
||||
[JsonIgnore]
|
||||
public Folder RootFolder => LibraryManager.GetUserRootFolder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the last login date.
|
||||
/// </summary>
|
||||
/// <value>The last login date.</value>
|
||||
public DateTime? LastLoginDate { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the last activity date.
|
||||
/// </summary>
|
||||
/// <value>The last activity date.</value>
|
||||
public DateTime? LastActivityDate { get; set; }
|
||||
|
||||
private volatile UserConfiguration _config;
|
||||
private readonly object _configSyncLock = new object();
|
||||
[JsonIgnore]
|
||||
public UserConfiguration Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_config == null)
|
||||
{
|
||||
lock (_configSyncLock)
|
||||
{
|
||||
if (_config == null)
|
||||
{
|
||||
_config = UserManager.GetUserConfiguration(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _config;
|
||||
}
|
||||
set => _config = value;
|
||||
}
|
||||
|
||||
private volatile UserPolicy _policy;
|
||||
private readonly object _policySyncLock = new object();
|
||||
[JsonIgnore]
|
||||
public UserPolicy Policy
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_policy == null)
|
||||
{
|
||||
lock (_policySyncLock)
|
||||
{
|
||||
if (_policy == null)
|
||||
{
|
||||
_policy = UserManager.GetUserPolicy(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _policy;
|
||||
}
|
||||
set => _policy = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renames the user.
|
||||
/// </summary>
|
||||
/// <param name="newName">The new name.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public Task Rename(string newName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(newName))
|
||||
{
|
||||
throw new ArgumentException("Username can't be empty", nameof(newName));
|
||||
}
|
||||
|
||||
Name = newName;
|
||||
|
||||
return RefreshMetadata(
|
||||
new MetadataRefreshOptions(new DirectoryService(FileSystem))
|
||||
{
|
||||
ReplaceAllMetadata = true,
|
||||
ImageRefreshMode = MetadataRefreshMode.FullRefresh,
|
||||
MetadataRefreshMode = MetadataRefreshMode.FullRefresh,
|
||||
ForceSave = true
|
||||
|
||||
},
|
||||
CancellationToken.None);
|
||||
}
|
||||
|
||||
public override void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
|
||||
{
|
||||
UserManager.UpdateUser(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the user's configuration directory
|
||||
/// </summary>
|
||||
/// <value>The configuration directory path.</value>
|
||||
[JsonIgnore]
|
||||
public string ConfigurationDirectoryPath => GetConfigurationDirectoryPath(Name);
|
||||
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the configuration directory path.
|
||||
/// </summary>
|
||||
/// <param name="username">The username.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private string GetConfigurationDirectoryPath(string username)
|
||||
{
|
||||
var parentPath = ConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath;
|
||||
|
||||
// TODO: Remove idPath and just use usernamePath for future releases
|
||||
var usernamePath = System.IO.Path.Combine(parentPath, username);
|
||||
var idPath = System.IO.Path.Combine(parentPath, Id.ToString("N", CultureInfo.InvariantCulture));
|
||||
if (!Directory.Exists(usernamePath) && Directory.Exists(idPath))
|
||||
{
|
||||
Directory.Move(idPath, usernamePath);
|
||||
}
|
||||
|
||||
return usernamePath;
|
||||
}
|
||||
|
||||
public bool IsParentalScheduleAllowed()
|
||||
{
|
||||
return IsParentalScheduleAllowed(DateTime.UtcNow);
|
||||
}
|
||||
|
||||
public bool IsParentalScheduleAllowed(DateTime date)
|
||||
{
|
||||
var schedules = Policy.AccessSchedules;
|
||||
|
||||
if (schedules.Length == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (var i in schedules)
|
||||
{
|
||||
if (IsParentalScheduleAllowed(i, date))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date)
|
||||
{
|
||||
if (date.Kind != DateTimeKind.Utc)
|
||||
{
|
||||
throw new ArgumentException("Utc date expected");
|
||||
}
|
||||
|
||||
var localTime = date.ToLocalTime();
|
||||
|
||||
return DayOfWeekHelper.GetDaysOfWeek(schedule.DayOfWeek).Contains(localTime.DayOfWeek) &&
|
||||
IsWithinTime(schedule, localTime);
|
||||
}
|
||||
|
||||
private bool IsWithinTime(AccessSchedule schedule, DateTime localTime)
|
||||
{
|
||||
var hour = localTime.TimeOfDay.TotalHours;
|
||||
|
||||
return hour >= schedule.StartHour && hour <= schedule.EndHour;
|
||||
}
|
||||
|
||||
public bool IsFolderGrouped(Guid id)
|
||||
{
|
||||
foreach (var i in Configuration.GroupedFolders)
|
||||
{
|
||||
if (new Guid(i) == id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override bool SupportsPeople => false;
|
||||
|
||||
public long InternalId { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class UserItemData
|
||||
/// Class UserItemData.
|
||||
/// </summary>
|
||||
public class UserItemData
|
||||
{
|
||||
@@ -21,11 +23,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The _rating
|
||||
/// The _rating.
|
||||
/// </summary>
|
||||
private double? _rating;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the users 0-10 rating
|
||||
/// Gets or sets the users 0-10 rating.
|
||||
/// </summary>
|
||||
/// <value>The rating.</value>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Rating;A 0 to 10 rating is required for UserItemData.</exception>
|
||||
@@ -75,11 +78,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
|
||||
public bool Played { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the index of the audio stream.
|
||||
/// </summary>
|
||||
/// <value>The index of the audio stream.</value>
|
||||
public int? AudioStreamIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the index of the subtitle stream.
|
||||
/// </summary>
|
||||
@@ -105,6 +110,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value.HasValue)
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Library;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Controller.TV;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
@@ -110,7 +113,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
private static string[] UserSpecificViewTypes = new string[]
|
||||
{
|
||||
MediaBrowser.Model.Entities.CollectionType.Playlists
|
||||
Model.Entities.CollectionType.Playlists
|
||||
};
|
||||
|
||||
public static bool IsUserSpecific(Folder folder)
|
||||
@@ -139,8 +142,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
private static string[] ViewTypesEligibleForGrouping = new string[]
|
||||
{
|
||||
MediaBrowser.Model.Entities.CollectionType.Movies,
|
||||
MediaBrowser.Model.Entities.CollectionType.TvShows,
|
||||
Model.Entities.CollectionType.Movies,
|
||||
Model.Entities.CollectionType.TvShows,
|
||||
string.Empty
|
||||
};
|
||||
|
||||
@@ -151,12 +154,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
private static string[] OriginalFolderViewTypes = new string[]
|
||||
{
|
||||
MediaBrowser.Model.Entities.CollectionType.Books,
|
||||
MediaBrowser.Model.Entities.CollectionType.MusicVideos,
|
||||
MediaBrowser.Model.Entities.CollectionType.HomeVideos,
|
||||
MediaBrowser.Model.Entities.CollectionType.Photos,
|
||||
MediaBrowser.Model.Entities.CollectionType.Music,
|
||||
MediaBrowser.Model.Entities.CollectionType.BoxSets
|
||||
Model.Entities.CollectionType.Books,
|
||||
Model.Entities.CollectionType.MusicVideos,
|
||||
Model.Entities.CollectionType.HomeVideos,
|
||||
Model.Entities.CollectionType.Photos,
|
||||
Model.Entities.CollectionType.Music,
|
||||
Model.Entities.CollectionType.BoxSets
|
||||
};
|
||||
|
||||
public static bool EnableOriginalFolder(string viewType)
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.TV;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||
using MetadataProvider = MediaBrowser.Model.Entities.MetadataProvider;
|
||||
using Movie = MediaBrowser.Controller.Entities.Movies.Movie;
|
||||
using Season = MediaBrowser.Controller.Entities.TV.Season;
|
||||
using Series = MediaBrowser.Controller.Entities.TV.Series;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
@@ -17,7 +25,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
private readonly IUserViewManager _userViewManager;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILogger<BaseItem> _logger;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly ITVSeriesManager _tvSeriesManager;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
@@ -25,7 +33,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
public UserViewBuilder(
|
||||
IUserViewManager userViewManager,
|
||||
ILibraryManager libraryManager,
|
||||
ILogger logger,
|
||||
ILogger<BaseItem> logger,
|
||||
IUserDataManager userDataManager,
|
||||
ITVSeriesManager tvSeriesManager,
|
||||
IServerConfigurationManager config)
|
||||
@@ -42,7 +50,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
var user = query.User;
|
||||
|
||||
//if (query.IncludeItemTypes != null &&
|
||||
// if (query.IncludeItemTypes != null &&
|
||||
// query.IncludeItemTypes.Length == 1 &&
|
||||
// string.Equals(query.IncludeItemTypes[0], "Playlist", StringComparison.OrdinalIgnoreCase))
|
||||
//{
|
||||
@@ -140,14 +148,15 @@ namespace MediaBrowser.Controller.Entities
|
||||
return parent.QueryRecursive(query);
|
||||
}
|
||||
|
||||
var list = new List<BaseItem>();
|
||||
|
||||
list.Add(GetUserView(SpecialFolder.MovieResume, "HeaderContinueWatching", "0", parent));
|
||||
list.Add(GetUserView(SpecialFolder.MovieLatest, "Latest", "1", parent));
|
||||
list.Add(GetUserView(SpecialFolder.MovieMovies, "Movies", "2", parent));
|
||||
list.Add(GetUserView(SpecialFolder.MovieCollections, "Collections", "3", parent));
|
||||
list.Add(GetUserView(SpecialFolder.MovieFavorites, "Favorites", "4", parent));
|
||||
list.Add(GetUserView(SpecialFolder.MovieGenres, "Genres", "5", parent));
|
||||
var list = new List<BaseItem>
|
||||
{
|
||||
GetUserView(SpecialFolder.MovieResume, "HeaderContinueWatching", "0", parent),
|
||||
GetUserView(SpecialFolder.MovieLatest, "Latest", "1", parent),
|
||||
GetUserView(SpecialFolder.MovieMovies, "Movies", "2", parent),
|
||||
GetUserView(SpecialFolder.MovieCollections, "Collections", "3", parent),
|
||||
GetUserView(SpecialFolder.MovieFavorites, "Favorites", "4", parent),
|
||||
GetUserView(SpecialFolder.MovieGenres, "Genres", "5", parent)
|
||||
};
|
||||
|
||||
return GetResult(list, parent, query);
|
||||
}
|
||||
@@ -264,7 +273,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
_logger.LogError(ex, "Error getting genre");
|
||||
return null;
|
||||
}
|
||||
|
||||
})
|
||||
.Where(i => i != null)
|
||||
.Select(i => GetUserViewWithName(i.Name, SpecialFolder.MovieGenre, i.SortName, parent));
|
||||
@@ -293,21 +301,27 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
if (query.IncludeItemTypes.Length == 0)
|
||||
{
|
||||
query.IncludeItemTypes = new[] { typeof(Series).Name, typeof(Season).Name, typeof(Episode).Name };
|
||||
query.IncludeItemTypes = new[]
|
||||
{
|
||||
nameof(Series),
|
||||
nameof(Season),
|
||||
nameof(Episode)
|
||||
};
|
||||
}
|
||||
|
||||
return parent.QueryRecursive(query);
|
||||
}
|
||||
|
||||
var list = new List<BaseItem>();
|
||||
|
||||
list.Add(GetUserView(SpecialFolder.TvResume, "HeaderContinueWatching", "0", parent));
|
||||
list.Add(GetUserView(SpecialFolder.TvNextUp, "HeaderNextUp", "1", parent));
|
||||
list.Add(GetUserView(SpecialFolder.TvLatest, "Latest", "2", parent));
|
||||
list.Add(GetUserView(SpecialFolder.TvShowSeries, "Shows", "3", parent));
|
||||
list.Add(GetUserView(SpecialFolder.TvFavoriteSeries, "HeaderFavoriteShows", "4", parent));
|
||||
list.Add(GetUserView(SpecialFolder.TvFavoriteEpisodes, "HeaderFavoriteEpisodes", "5", parent));
|
||||
list.Add(GetUserView(SpecialFolder.TvGenres, "Genres", "6", parent));
|
||||
var list = new List<BaseItem>
|
||||
{
|
||||
GetUserView(SpecialFolder.TvResume, "HeaderContinueWatching", "0", parent),
|
||||
GetUserView(SpecialFolder.TvNextUp, "HeaderNextUp", "1", parent),
|
||||
GetUserView(SpecialFolder.TvLatest, "Latest", "2", parent),
|
||||
GetUserView(SpecialFolder.TvShowSeries, "Shows", "3", parent),
|
||||
GetUserView(SpecialFolder.TvFavoriteSeries, "HeaderFavoriteShows", "4", parent),
|
||||
GetUserView(SpecialFolder.TvFavoriteEpisodes, "HeaderFavoriteEpisodes", "5", parent),
|
||||
GetUserView(SpecialFolder.TvGenres, "Genres", "6", parent)
|
||||
};
|
||||
|
||||
return GetResult(list, parent, query);
|
||||
}
|
||||
@@ -335,7 +349,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
Limit = query.Limit,
|
||||
StartIndex = query.StartIndex,
|
||||
UserId = query.User.Id
|
||||
|
||||
}, parentFolders, query.DtoOptions);
|
||||
|
||||
return result;
|
||||
@@ -372,7 +385,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
IncludeItemTypes = new[] { typeof(Series).Name },
|
||||
Recursive = true,
|
||||
EnableTotalRecordCount = false
|
||||
|
||||
}).Items
|
||||
.SelectMany(i => i.Genres)
|
||||
.DistinctNames()
|
||||
@@ -387,7 +399,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
_logger.LogError(ex, "Error getting genre");
|
||||
return null;
|
||||
}
|
||||
|
||||
})
|
||||
.Where(i => i != null)
|
||||
.Select(i => GetUserViewWithName(i.Name, SpecialFolder.TvGenre, i.SortName, parent));
|
||||
@@ -412,12 +423,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return new QueryResult<BaseItem>
|
||||
{
|
||||
Items = result.Items, //TODO Fix The co-variant conversion between T[] and BaseItem[], this can generate runtime issues if T is not BaseItem.
|
||||
Items = result.Items, // TODO Fix The co-variant conversion between T[] and BaseItem[], this can generate runtime issues if T is not BaseItem.
|
||||
TotalRecordCount = result.TotalRecordCount
|
||||
};
|
||||
}
|
||||
|
||||
private QueryResult<BaseItem> GetResult<T>(IEnumerable<T> items,
|
||||
private QueryResult<BaseItem> GetResult<T>(
|
||||
IEnumerable<T> items,
|
||||
BaseItem queryParent,
|
||||
InternalItemsQuery query)
|
||||
where T : BaseItem
|
||||
@@ -611,7 +623,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
var filterValue = query.HasImdbId.Value;
|
||||
|
||||
var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Imdb));
|
||||
var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProvider.Imdb));
|
||||
|
||||
if (hasValue != filterValue)
|
||||
{
|
||||
@@ -623,7 +635,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
var filterValue = query.HasTmdbId.Value;
|
||||
|
||||
var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tmdb));
|
||||
var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProvider.Tmdb));
|
||||
|
||||
if (hasValue != filterValue)
|
||||
{
|
||||
@@ -635,7 +647,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
var filterValue = query.HasTvdbId.Value;
|
||||
|
||||
var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tvdb));
|
||||
var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProvider.Tvdb));
|
||||
|
||||
if (hasValue != filterValue)
|
||||
{
|
||||
@@ -661,9 +673,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
var isPlaceHolder = false;
|
||||
|
||||
var hasPlaceHolder = item as ISupportsPlaceHolders;
|
||||
|
||||
if (hasPlaceHolder != null)
|
||||
if (item is ISupportsPlaceHolders hasPlaceHolder)
|
||||
{
|
||||
isPlaceHolder = hasPlaceHolder.IsPlaceHolder;
|
||||
}
|
||||
@@ -678,13 +688,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
var filterValue = query.HasSpecialFeature.Value;
|
||||
|
||||
var movie = item as IHasSpecialFeatures;
|
||||
|
||||
if (movie != null)
|
||||
if (item is IHasSpecialFeatures movie)
|
||||
{
|
||||
var ok = filterValue
|
||||
? movie.SpecialFeatureIds.Length > 0
|
||||
: movie.SpecialFeatureIds.Length == 0;
|
||||
? movie.SpecialFeatureIds.Count > 0
|
||||
: movie.SpecialFeatureIds.Count == 0;
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
@@ -951,6 +959,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
.OfType<Folder>()
|
||||
.Where(UserView.IsEligibleForGrouping);
|
||||
}
|
||||
|
||||
return _libraryManager.GetUserRootFolder()
|
||||
.GetChildren(user, true)
|
||||
.OfType<Folder>()
|
||||
@@ -969,6 +978,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
return GetMediaFolders(user)
|
||||
.Where(i =>
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -17,7 +19,7 @@ using MediaBrowser.Model.MediaInfo;
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Video
|
||||
/// Class Video.
|
||||
/// </summary>
|
||||
public class Video : BaseItem,
|
||||
IHasAspectRatio,
|
||||
@@ -28,7 +30,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
public string PrimaryVersionId { get; set; }
|
||||
|
||||
public string[] AdditionalParts { get; set; }
|
||||
|
||||
public string[] LocalAlternateVersions { get; set; }
|
||||
|
||||
public LinkedChild[] LinkedAlternateVersions { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
@@ -52,15 +56,18 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extraType.Value == Model.Entities.ExtraType.ThemeVideo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extraType.Value == Model.Entities.ExtraType.Trailer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -196,6 +203,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return video.MediaSourceCount;
|
||||
}
|
||||
}
|
||||
|
||||
return LinkedAlternateVersions.Length + LocalAlternateVersions.Length + 1;
|
||||
}
|
||||
}
|
||||
@@ -272,13 +280,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
if (ExtraType.HasValue)
|
||||
{
|
||||
var key = this.GetProviderId(MetadataProviders.Tmdb);
|
||||
var key = this.GetProviderId(MetadataProvider.Tmdb);
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
list.Insert(0, GetUserDataKey(key));
|
||||
}
|
||||
|
||||
key = this.GetProviderId(MetadataProviders.Imdb);
|
||||
key = this.GetProviderId(MetadataProvider.Imdb);
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
list.Insert(0, GetUserDataKey(key));
|
||||
@@ -286,13 +294,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
var key = this.GetProviderId(MetadataProviders.Imdb);
|
||||
var key = this.GetProviderId(MetadataProvider.Imdb);
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
}
|
||||
|
||||
key = this.GetProviderId(MetadataProviders.Tmdb);
|
||||
key = this.GetProviderId(MetadataProvider.Tmdb);
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
@@ -390,11 +398,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
AdditionalParts = newVideo.AdditionalParts;
|
||||
updateType |= ItemUpdateType.MetadataImport;
|
||||
}
|
||||
|
||||
if (!LocalAlternateVersions.SequenceEqual(newVideo.LocalAlternateVersions, StringComparer.Ordinal))
|
||||
{
|
||||
LocalAlternateVersions = newVideo.LocalAlternateVersions;
|
||||
updateType |= ItemUpdateType.MetadataImport;
|
||||
}
|
||||
|
||||
if (VideoType != newVideo.VideoType)
|
||||
{
|
||||
VideoType = newVideo.VideoType;
|
||||
@@ -416,6 +426,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
.Select(i => i.FullName)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (videoType == VideoType.BluRay)
|
||||
{
|
||||
return FileSystem.GetFiles(rootPath, new[] { ".m2ts" }, false, true)
|
||||
@@ -425,6 +436,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
.Select(i => i.FullName)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
@@ -485,9 +497,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
|
||||
/// <inheritdoc />
|
||||
public override async Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
|
||||
{
|
||||
base.UpdateToRepository(updateReason, cancellationToken);
|
||||
await base.UpdateToRepositoryAsync(updateReason, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var localAlternates = GetLocalAlternateVersionIds()
|
||||
.Select(i => LibraryManager.GetItemById(i))
|
||||
@@ -504,7 +517,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
item.Genres = Genres;
|
||||
item.ProviderIds = ProviderIds;
|
||||
|
||||
item.UpdateToRepository(ItemUpdateType.MetadataDownload, cancellationToken);
|
||||
await item.UpdateToRepositoryAsync(ItemUpdateType.MetadataDownload, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,7 +548,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
ItemId = Id,
|
||||
Index = DefaultVideoStreamIndex.Value
|
||||
|
||||
}).FirstOrDefault();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -7,7 +9,7 @@ using Microsoft.Extensions.Logging;
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Year
|
||||
/// Class Year.
|
||||
/// </summary>
|
||||
public class Year : BaseItem, IItemByName
|
||||
{
|
||||
@@ -21,7 +23,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>
|
||||
/// <value>The containing folder path.</value>
|
||||
[JsonIgnore]
|
||||
@@ -103,11 +105,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
Logger.LogDebug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made.
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh(bool replaceAllMetdata)
|
||||
{
|
||||
|
||||
20
MediaBrowser.Controller/Events/IEventConsumer.cs
Normal file
20
MediaBrowser.Controller/Events/IEventConsumer.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface representing a type that consumes events of type <c>T</c>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of events this consumes.</typeparam>
|
||||
public interface IEventConsumer<in T>
|
||||
where T : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// A method that is called when an event of type <c>T</c> is fired.
|
||||
/// </summary>
|
||||
/// <param name="eventArgs">The event.</param>
|
||||
/// <returns>A task representing the consumption of the event.</returns>
|
||||
Task OnEvent(T eventArgs);
|
||||
}
|
||||
}
|
||||
28
MediaBrowser.Controller/Events/IEventManager.cs
Normal file
28
MediaBrowser.Controller/Events/IEventManager.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface that handles eventing.
|
||||
/// </summary>
|
||||
public interface IEventManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Publishes an event.
|
||||
/// </summary>
|
||||
/// <param name="eventArgs">the event arguments.</param>
|
||||
/// <typeparam name="T">The type of event.</typeparam>
|
||||
void Publish<T>(T eventArgs)
|
||||
where T : EventArgs;
|
||||
|
||||
/// <summary>
|
||||
/// Publishes an event asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="eventArgs">The event arguments.</param>
|
||||
/// <typeparam name="T">The type of event.</typeparam>
|
||||
/// <returns>A task representing the publishing of the event.</returns>
|
||||
Task PublishAsync<T>(T eventArgs)
|
||||
where T : EventArgs;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Jellyfin.Data.Events;
|
||||
using MediaBrowser.Controller.Session;
|
||||
|
||||
namespace MediaBrowser.Controller.Events.Session
|
||||
{
|
||||
/// <summary>
|
||||
/// An event that fires when a session is ended.
|
||||
/// </summary>
|
||||
public class SessionEndedEventArgs : GenericEventArgs<SessionInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SessionEndedEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arg">The session info.</param>
|
||||
public SessionEndedEventArgs(SessionInfo arg) : base(arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Jellyfin.Data.Events;
|
||||
using MediaBrowser.Controller.Session;
|
||||
|
||||
namespace MediaBrowser.Controller.Events.Session
|
||||
{
|
||||
/// <summary>
|
||||
/// An event that fires when a session is started.
|
||||
/// </summary>
|
||||
public class SessionStartedEventArgs : GenericEventArgs<SessionInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SessionStartedEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arg">The session info.</param>
|
||||
public SessionStartedEventArgs(SessionInfo arg) : base(arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Jellyfin.Data.Events;
|
||||
using MediaBrowser.Model.Updates;
|
||||
|
||||
namespace MediaBrowser.Controller.Events.Updates
|
||||
{
|
||||
/// <summary>
|
||||
/// An event that occurs when a plugin installation is cancelled.
|
||||
/// </summary>
|
||||
public class PluginInstallationCancelledEventArgs : GenericEventArgs<InstallationInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PluginInstallationCancelledEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arg">The installation info.</param>
|
||||
public PluginInstallationCancelledEventArgs(InstallationInfo arg) : base(arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Jellyfin.Data.Events;
|
||||
using MediaBrowser.Model.Updates;
|
||||
|
||||
namespace MediaBrowser.Controller.Events.Updates
|
||||
{
|
||||
/// <summary>
|
||||
/// An event that occurs when a plugin is installed.
|
||||
/// </summary>
|
||||
public class PluginInstalledEventArgs : GenericEventArgs<InstallationInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PluginInstalledEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arg">The installation info.</param>
|
||||
public PluginInstalledEventArgs(InstallationInfo arg) : base(arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Jellyfin.Data.Events;
|
||||
using MediaBrowser.Model.Updates;
|
||||
|
||||
namespace MediaBrowser.Controller.Events.Updates
|
||||
{
|
||||
/// <summary>
|
||||
/// An event that occurs when a plugin is installing.
|
||||
/// </summary>
|
||||
public class PluginInstallingEventArgs : GenericEventArgs<InstallationInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PluginInstallingEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arg">The installation info.</param>
|
||||
public PluginInstallingEventArgs(InstallationInfo arg) : base(arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Jellyfin.Data.Events;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
|
||||
namespace MediaBrowser.Controller.Events.Updates
|
||||
{
|
||||
/// <summary>
|
||||
/// An event that occurs when a plugin is uninstalled.
|
||||
/// </summary>
|
||||
public class PluginUninstalledEventArgs : GenericEventArgs<IPlugin>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PluginUninstalledEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arg">The plugin.</param>
|
||||
public PluginUninstalledEventArgs(IPlugin arg) : base(arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Jellyfin.Data.Events;
|
||||
using MediaBrowser.Model.Updates;
|
||||
|
||||
namespace MediaBrowser.Controller.Events.Updates
|
||||
{
|
||||
/// <summary>
|
||||
/// An event that occurs when a plugin is updated.
|
||||
/// </summary>
|
||||
public class PluginUpdatedEventArgs : GenericEventArgs<InstallationInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PluginUpdatedEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arg">The installation info.</param>
|
||||
public PluginUpdatedEventArgs(InstallationInfo arg) : base(arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,12 @@ namespace MediaBrowser.Controller.Extensions
|
||||
/// </summary>
|
||||
public static class ConfigurationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// The key for a setting that specifies the default redirect path
|
||||
/// to use for requests where the URL base prefix is invalid or missing..
|
||||
/// </summary>
|
||||
public const string DefaultRedirectKey = "DefaultRedirectPath";
|
||||
|
||||
/// <summary>
|
||||
/// The key for a setting that indicates whether the application should host web client content.
|
||||
/// </summary>
|
||||
@@ -23,11 +29,26 @@ namespace MediaBrowser.Controller.Extensions
|
||||
/// </summary>
|
||||
public const string FfmpegAnalyzeDurationKey = "FFmpeg:analyzeduration";
|
||||
|
||||
/// <summary>
|
||||
/// The key for the FFmpeg path option.
|
||||
/// </summary>
|
||||
public const string FfmpegPathKey = "ffmpeg";
|
||||
|
||||
/// <summary>
|
||||
/// The key for a setting that indicates whether playlists should allow duplicate entries.
|
||||
/// </summary>
|
||||
public const string PlaylistsAllowDuplicatesKey = "playlists:allowDuplicates";
|
||||
|
||||
/// <summary>
|
||||
/// The key for a setting that indicates whether kestrel should bind to a unix socket.
|
||||
/// </summary>
|
||||
public const string BindToUnixSocketKey = "kestrel:socket";
|
||||
|
||||
/// <summary>
|
||||
/// The key for the unix socket path.
|
||||
/// </summary>
|
||||
public const string UnixSocketPathKey = "kestrel:socketPath";
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the application should host static web content from the <see cref="IConfiguration"/>.
|
||||
/// </summary>
|
||||
@@ -60,5 +81,21 @@ namespace MediaBrowser.Controller.Extensions
|
||||
/// <returns>True if playlists should allow duplicates, otherwise false.</returns>
|
||||
public static bool DoPlaylistsAllowDuplicates(this IConfiguration configuration)
|
||||
=> configuration.GetValue<bool>(PlaylistsAllowDuplicatesKey);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether kestrel should bind to a unix socket from the <see cref="IConfiguration" />.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to read the setting from.</param>
|
||||
/// <returns><c>true</c> if kestrel should bind to a unix socket, otherwise <c>false</c>.</returns>
|
||||
public static bool UseUnixSocket(this IConfiguration configuration)
|
||||
=> configuration.GetValue<bool>(BindToUnixSocketKey);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path for the unix socket from the <see cref="IConfiguration" />.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to read the setting from.</param>
|
||||
/// <returns>The unix socket path.</returns>
|
||||
public static string GetUnixSocketPath(this IConfiguration configuration)
|
||||
=> configuration[UnixSocketPathKey];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -7,7 +9,7 @@ using System.Text.RegularExpressions;
|
||||
namespace MediaBrowser.Controller.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Class BaseExtensions
|
||||
/// Class BaseExtensions.
|
||||
/// </summary>
|
||||
public static class StringExtensions
|
||||
{
|
||||
|
||||
42
MediaBrowser.Controller/IDisplayPreferencesManager.cs
Normal file
42
MediaBrowser.Controller/IDisplayPreferencesManager.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Data.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages the storage and retrieval of display preferences.
|
||||
/// </summary>
|
||||
public interface IDisplayPreferencesManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the display preferences for the user and client.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user's id.</param>
|
||||
/// <param name="client">The client string.</param>
|
||||
/// <returns>The associated display preferences.</returns>
|
||||
DisplayPreferences GetDisplayPreferences(Guid userId, string client);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default item display preferences for the user and client.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="itemId">The item id.</param>
|
||||
/// <param name="client">The client string.</param>
|
||||
/// <returns>The item display preferences.</returns>
|
||||
ItemDisplayPreferences GetItemDisplayPreferences(Guid userId, Guid itemId, string client);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all of the item display preferences for the user and client.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="client">The client string.</param>
|
||||
/// <returns>A list of item display preferences.</returns>
|
||||
IList<ItemDisplayPreferences> ListItemDisplayPreferences(Guid userId, string client);
|
||||
|
||||
/// <summary>
|
||||
/// Saves changes made to the database.
|
||||
/// </summary>
|
||||
void SaveChanges();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user