mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-03 19:17:24 -05:00 
			
		
		
		
	Merge pull request #6649 from barronpm/implementations-warn2
This commit is contained in:
		
						commit
						a1246ba3a0
					
				@ -10,8 +10,8 @@ using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Jellyfin.Data.Entities;
 | 
			
		||||
using Jellyfin.Data.Enums;
 | 
			
		||||
using MediaBrowser.Common.Extensions;
 | 
			
		||||
using Jellyfin.Extensions.Json;
 | 
			
		||||
using MediaBrowser.Common.Extensions;
 | 
			
		||||
using MediaBrowser.Common.Progress;
 | 
			
		||||
using MediaBrowser.Controller.Channels;
 | 
			
		||||
using MediaBrowser.Controller.Configuration;
 | 
			
		||||
 | 
			
		||||
@ -15,9 +15,18 @@ namespace Emby.Server.Implementations.Devices
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IApplicationPaths _appPaths;
 | 
			
		||||
        private readonly ILogger<DeviceId> _logger;
 | 
			
		||||
 | 
			
		||||
        private readonly object _syncLock = new object();
 | 
			
		||||
 | 
			
		||||
        private string _id;
 | 
			
		||||
 | 
			
		||||
        public DeviceId(IApplicationPaths appPaths, ILoggerFactory loggerFactory)
 | 
			
		||||
        {
 | 
			
		||||
            _appPaths = appPaths;
 | 
			
		||||
            _logger = loggerFactory.CreateLogger<DeviceId>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Value => _id ?? (_id = GetDeviceId());
 | 
			
		||||
 | 
			
		||||
        private string CachePath => Path.Combine(_appPaths.DataPath, "device.txt");
 | 
			
		||||
 | 
			
		||||
        private string GetCachedId()
 | 
			
		||||
@ -86,15 +95,5 @@ namespace Emby.Server.Implementations.Devices
 | 
			
		||||
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string _id;
 | 
			
		||||
 | 
			
		||||
        public DeviceId(IApplicationPaths appPaths, ILoggerFactory loggerFactory)
 | 
			
		||||
        {
 | 
			
		||||
            _appPaths = appPaths;
 | 
			
		||||
            _logger = loggerFactory.CreateLogger<DeviceId>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Value => _id ?? (_id = GetDeviceId());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -436,7 +436,7 @@ namespace Emby.Server.Implementations.EntryPoints
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Translates the physical item to user library.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T"></typeparam>
 | 
			
		||||
        /// <typeparam name="T">The type of item.</typeparam>
 | 
			
		||||
        /// <param name="item">The item.</param>
 | 
			
		||||
        /// <param name="user">The user.</param>
 | 
			
		||||
        /// <param name="includeIfNotFound">if set to <c>true</c> [include if not found].</param>
 | 
			
		||||
 | 
			
		||||
@ -96,7 +96,7 @@ namespace Emby.Server.Implementations.HttpServer
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sends a message asynchronously.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T"></typeparam>
 | 
			
		||||
        /// <typeparam name="T">The type of the message.</typeparam>
 | 
			
		||||
        /// <param name="message">The message.</param>
 | 
			
		||||
        /// <param name="cancellationToken">The cancellation token.</param>
 | 
			
		||||
        /// <returns>Task.</returns>
 | 
			
		||||
@ -150,8 +150,8 @@ namespace Emby.Server.Implementations.HttpServer
 | 
			
		||||
                {
 | 
			
		||||
                    await ProcessInternal(pipe.Reader).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            } while (
 | 
			
		||||
                (_socket.State == WebSocketState.Open || _socket.State == WebSocketState.Connecting)
 | 
			
		||||
            }
 | 
			
		||||
            while ((_socket.State == WebSocketState.Open || _socket.State == WebSocketState.Connecting)
 | 
			
		||||
                && receiveresult.MessageType != WebSocketMessageType.Close);
 | 
			
		||||
 | 
			
		||||
            Closed?.Invoke(this, EventArgs.Empty);
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,25 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
 | 
			
		||||
        private bool _disposed = false;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="LibraryMonitor" /> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="logger">The logger.</param>
 | 
			
		||||
        /// <param name="libraryManager">The library manager.</param>
 | 
			
		||||
        /// <param name="configurationManager">The configuration manager.</param>
 | 
			
		||||
        /// <param name="fileSystem">The filesystem.</param>
 | 
			
		||||
        public LibraryMonitor(
 | 
			
		||||
            ILogger<LibraryMonitor> logger,
 | 
			
		||||
            ILibraryManager libraryManager,
 | 
			
		||||
            IServerConfigurationManager configurationManager,
 | 
			
		||||
            IFileSystem fileSystem)
 | 
			
		||||
        {
 | 
			
		||||
            _libraryManager = libraryManager;
 | 
			
		||||
            _logger = logger;
 | 
			
		||||
            _configurationManager = configurationManager;
 | 
			
		||||
            _fileSystem = fileSystem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Add the path to our temporary ignore list.  Use when writing to a path within our listening scope.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -95,21 +114,6 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="LibraryMonitor" /> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public LibraryMonitor(
 | 
			
		||||
            ILogger<LibraryMonitor> logger,
 | 
			
		||||
            ILibraryManager libraryManager,
 | 
			
		||||
            IServerConfigurationManager configurationManager,
 | 
			
		||||
            IFileSystem fileSystem)
 | 
			
		||||
        {
 | 
			
		||||
            _libraryManager = libraryManager;
 | 
			
		||||
            _logger = logger;
 | 
			
		||||
            _configurationManager = configurationManager;
 | 
			
		||||
            _fileSystem = fileSystem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool IsLibraryMonitorEnabled(BaseItem item)
 | 
			
		||||
        {
 | 
			
		||||
            if (item is BasePluginFolder)
 | 
			
		||||
@ -199,7 +203,7 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
        /// <param name="lst">The LST.</param>
 | 
			
		||||
        /// <param name="path">The path.</param>
 | 
			
		||||
        /// <returns><c>true</c> if [contains parent folder] [the specified LST]; otherwise, <c>false</c>.</returns>
 | 
			
		||||
        /// <exception cref="ArgumentNullException">path</exception>
 | 
			
		||||
        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <c>null</c>.</exception>
 | 
			
		||||
        private static bool ContainsParentFolder(IEnumerable<string> lst, string path)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(path))
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ManagedFileSystem : IFileSystem
 | 
			
		||||
    {
 | 
			
		||||
        protected ILogger<ManagedFileSystem> Logger;
 | 
			
		||||
        private readonly ILogger<ManagedFileSystem> _logger;
 | 
			
		||||
 | 
			
		||||
        private readonly List<IShortcutHandler> _shortcutHandlers = new List<IShortcutHandler>();
 | 
			
		||||
        private readonly string _tempPath;
 | 
			
		||||
@ -27,7 +27,7 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
            ILogger<ManagedFileSystem> logger,
 | 
			
		||||
            IApplicationPaths applicationPaths)
 | 
			
		||||
        {
 | 
			
		||||
            Logger = logger;
 | 
			
		||||
            _logger = logger;
 | 
			
		||||
            _tempPath = applicationPaths.TempDirectory;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="filename">The filename.</param>
 | 
			
		||||
        /// <returns><c>true</c> if the specified filename is shortcut; otherwise, <c>false</c>.</returns>
 | 
			
		||||
        /// <exception cref="ArgumentNullException">filename</exception>
 | 
			
		||||
        /// <exception cref="ArgumentNullException"><paramref name="filename"/> is <c>null</c>.</exception>
 | 
			
		||||
        public virtual bool IsShortcut(string filename)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(filename))
 | 
			
		||||
@ -58,7 +58,7 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="filename">The filename.</param>
 | 
			
		||||
        /// <returns>System.String.</returns>
 | 
			
		||||
        /// <exception cref="ArgumentNullException">filename</exception>
 | 
			
		||||
        /// <exception cref="ArgumentNullException"><paramref name="filename"/> is <c>null</c>.</exception>
 | 
			
		||||
        public virtual string? ResolveShortcut(string filename)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(filename))
 | 
			
		||||
@ -233,9 +233,9 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
                result.IsDirectory = info is DirectoryInfo || (info.Attributes & FileAttributes.Directory) == FileAttributes.Directory;
 | 
			
		||||
 | 
			
		||||
                // if (!result.IsDirectory)
 | 
			
		||||
                //{
 | 
			
		||||
                // {
 | 
			
		||||
                //    result.IsHidden = (info.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden;
 | 
			
		||||
                //}
 | 
			
		||||
                // }
 | 
			
		||||
 | 
			
		||||
                if (info is FileInfo fileInfo)
 | 
			
		||||
                {
 | 
			
		||||
@ -254,7 +254,7 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
                        catch (FileNotFoundException ex)
 | 
			
		||||
                        {
 | 
			
		||||
                            // Dangling symlinks cannot be detected before opening the file unfortunately...
 | 
			
		||||
                            Logger.LogError(ex, "Reading the file size of the symlink at {Path} failed. Marking the file as not existing.", fileInfo.FullName);
 | 
			
		||||
                            _logger.LogError(ex, "Reading the file size of the symlink at {Path} failed. Marking the file as not existing.", fileInfo.FullName);
 | 
			
		||||
                            result.Exists = false;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@ -343,7 +343,7 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.LogError(ex, "Error determining CreationTimeUtc for {FullName}", info.FullName);
 | 
			
		||||
                _logger.LogError(ex, "Error determining CreationTimeUtc for {FullName}", info.FullName);
 | 
			
		||||
                return DateTime.MinValue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@ -382,7 +382,7 @@ namespace Emby.Server.Implementations.IO
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.LogError(ex, "Error determining LastAccessTimeUtc for {FullName}", info.FullName);
 | 
			
		||||
                _logger.LogError(ex, "Error determining LastAccessTimeUtc for {FullName}", info.FullName);
 | 
			
		||||
                return DateTime.MinValue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -647,7 +647,7 @@ namespace Emby.Server.Implementations.Library
 | 
			
		||||
        /// Determines whether a path should be ignored based on its contents - called after the contents have been read.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="args">The args.</param>
 | 
			
		||||
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
 | 
			
		||||
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
 | 
			
		||||
        private static bool ShouldResolvePathContents(ItemResolveArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            // Ignore any folders containing a file called .ignore
 | 
			
		||||
@ -1266,7 +1266,7 @@ namespace Emby.Server.Implementations.Library
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="id">The id.</param>
 | 
			
		||||
        /// <returns>BaseItem.</returns>
 | 
			
		||||
        /// <exception cref="ArgumentNullException">id</exception>
 | 
			
		||||
        /// <exception cref="ArgumentNullException"><paramref name="id"/> is <c>null</c>.</exception>
 | 
			
		||||
        public BaseItem GetItemById(Guid id)
 | 
			
		||||
        {
 | 
			
		||||
            if (id == Guid.Empty)
 | 
			
		||||
 | 
			
		||||
@ -13,9 +13,9 @@ using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Jellyfin.Data.Entities;
 | 
			
		||||
using Jellyfin.Data.Enums;
 | 
			
		||||
using Jellyfin.Extensions.Json;
 | 
			
		||||
using MediaBrowser.Common.Configuration;
 | 
			
		||||
using MediaBrowser.Common.Extensions;
 | 
			
		||||
using Jellyfin.Extensions.Json;
 | 
			
		||||
using MediaBrowser.Controller.Entities;
 | 
			
		||||
using MediaBrowser.Controller.Library;
 | 
			
		||||
using MediaBrowser.Controller.MediaEncoding;
 | 
			
		||||
 | 
			
		||||
@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.Library
 | 
			
		||||
        /// <param name="path">The original path.</param>
 | 
			
		||||
        /// <param name="subPath">The original sub path.</param>
 | 
			
		||||
        /// <param name="newSubPath">The new sub path.</param>
 | 
			
		||||
        /// <param name="newPath">The result of the sub path replacement</param>
 | 
			
		||||
        /// <param name="newPath">The result of the sub path replacement.</param>
 | 
			
		||||
        /// <returns>The path after replacing the sub path.</returns>
 | 
			
		||||
        /// <exception cref="ArgumentNullException"><paramref name="path" />, <paramref name="newSubPath" /> or <paramref name="newSubPath" /> is empty.</exception>
 | 
			
		||||
        public static bool TryReplaceSubPath(
 | 
			
		||||
 | 
			
		||||
@ -82,6 +82,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Determine if the supplied file data points to a music album.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="path">The path to check.</param>
 | 
			
		||||
        /// <param name="directoryService">The directory service.</param>
 | 
			
		||||
        /// <returns><c>true</c> if the provided path points to a music album, <c>false</c> otherwise.</returns>
 | 
			
		||||
        public bool IsMusicAlbum(string path, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            return ContainsMusic(directoryService.GetFileSystemEntries(path), true, directoryService, _logger, _fileSystem, _libraryManager);
 | 
			
		||||
 | 
			
		||||
@ -275,6 +275,10 @@ namespace Emby.Server.Implementations.Library.Resolvers
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Determines whether [is DVD directory] [the specified directory name].
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="fullPath">The full path of the directory.</param>
 | 
			
		||||
        /// <param name="directoryName">The name of the directory.</param>
 | 
			
		||||
        /// <param name="directoryService">The directory service.</param>
 | 
			
		||||
        /// <returns><c>true</c> if the provided directory is a DVD directory, <c>false</c> otherwise.</returns>
 | 
			
		||||
        protected bool IsDvdDirectory(string fullPath, string directoryName, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            if (!string.Equals(directoryName, "video_ts", StringComparison.OrdinalIgnoreCase))
 | 
			
		||||
 | 
			
		||||
@ -49,13 +49,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books
 | 
			
		||||
        {
 | 
			
		||||
            var bookFiles = args.FileSystemChildren.Where(f =>
 | 
			
		||||
            {
 | 
			
		||||
                var fileExtension = Path.GetExtension(f.FullName) ??
 | 
			
		||||
                                    string.Empty;
 | 
			
		||||
                var fileExtension = Path.GetExtension(f.FullName)
 | 
			
		||||
                    ?? string.Empty;
 | 
			
		||||
 | 
			
		||||
                return _validExtensions.Contains(
 | 
			
		||||
                    fileExtension,
 | 
			
		||||
                                                StringComparer
 | 
			
		||||
                                                    .OrdinalIgnoreCase);
 | 
			
		||||
                    StringComparer.OrdinalIgnoreCase);
 | 
			
		||||
            }).ToList();
 | 
			
		||||
 | 
			
		||||
            // Don't return a Book if there is more (or less) than one document in the directory
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class MovieResolver : BaseVideoResolver<Video>, IMultiItemResolver
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IImageProcessor _imageProcessor;
 | 
			
		||||
 | 
			
		||||
        private string[] _validCollectionTypes = new[]
 | 
			
		||||
        {
 | 
			
		||||
                CollectionType.Movies,
 | 
			
		||||
@ -33,8 +35,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
 | 
			
		||||
                CollectionType.Photos
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private readonly IImageProcessor _imageProcessor;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="MovieResolver"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
 | 
			
		||||
@ -67,7 +67,6 @@ namespace Emby.Server.Implementations.Library.Resolvers
 | 
			
		||||
            return args.FileSystemChildren
 | 
			
		||||
                .Where(i =>
 | 
			
		||||
                {
 | 
			
		||||
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        return !i.IsDirectory &&
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ namespace Emby.Server.Implementations.Library
 | 
			
		||||
        /// <param name="query">The query.</param>
 | 
			
		||||
        /// <param name="user">The user.</param>
 | 
			
		||||
        /// <returns>IEnumerable{SearchHintResult}.</returns>
 | 
			
		||||
        /// <exception cref="ArgumentNullException">searchTerm</exception>
 | 
			
		||||
        /// <exception cref="ArgumentException"><c>query.SearchTerm</c> is <c>null</c> or empty.</exception>
 | 
			
		||||
        private List<SearchHintInfo> GetSearchHints(SearchQuery query, User user)
 | 
			
		||||
        {
 | 
			
		||||
            var searchTerm = query.SearchTerm;
 | 
			
		||||
 | 
			
		||||
@ -25,8 +25,6 @@ namespace Emby.Server.Implementations.Library
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class UserDataManager : IUserDataManager
 | 
			
		||||
    {
 | 
			
		||||
        public event EventHandler<UserDataSaveEventArgs> UserDataSaved;
 | 
			
		||||
 | 
			
		||||
        private readonly ConcurrentDictionary<string, UserItemData> _userData =
 | 
			
		||||
            new ConcurrentDictionary<string, UserItemData>(StringComparer.OrdinalIgnoreCase);
 | 
			
		||||
 | 
			
		||||
@ -44,6 +42,8 @@ namespace Emby.Server.Implementations.Library
 | 
			
		||||
            _repository = repository;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public event EventHandler<UserDataSaveEventArgs> UserDataSaved;
 | 
			
		||||
 | 
			
		||||
        public void SaveUserData(Guid userId, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            var user = _userManager.GetUserById(userId);
 | 
			
		||||
@ -90,10 +90,9 @@ namespace Emby.Server.Implementations.Library
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Save the provided user data for the given user.  Batch operation. Does not fire any events or update the cache.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="userId"></param>
 | 
			
		||||
        /// <param name="userData"></param>
 | 
			
		||||
        /// <param name="cancellationToken"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        /// <param name="userId">The user id.</param>
 | 
			
		||||
        /// <param name="userData">The user item data.</param>
 | 
			
		||||
        /// <param name="cancellationToken">The cancellation token.</param>
 | 
			
		||||
        public void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            var user = _userManager.GetUserById(userId);
 | 
			
		||||
@ -104,8 +103,8 @@ namespace Emby.Server.Implementations.Library
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Retrieve all user data for the given user.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="userId"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        /// <param name="userId">The user id.</param>
 | 
			
		||||
        /// <returns>A <see cref="List{UserItemData}"/> containing all of the user's item data.</returns>
 | 
			
		||||
        public List<UserItemData> GetAllUserData(Guid userId)
 | 
			
		||||
        {
 | 
			
		||||
            var user = _userManager.GetUserById(userId);
 | 
			
		||||
 | 
			
		||||
@ -341,14 +341,16 @@ namespace Emby.Server.Implementations.Library
 | 
			
		||||
                mediaTypes = mediaTypes.Distinct().ToList();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var excludeItemTypes = includeItemTypes.Length == 0 && mediaTypes.Count == 0 ? new[]
 | 
			
		||||
            {
 | 
			
		||||
                nameof(Person),
 | 
			
		||||
                nameof(Studio),
 | 
			
		||||
                nameof(Year),
 | 
			
		||||
                nameof(MusicGenre),
 | 
			
		||||
                nameof(Genre)
 | 
			
		||||
            } : Array.Empty<string>();
 | 
			
		||||
            var excludeItemTypes = includeItemTypes.Length == 0 && mediaTypes.Count == 0
 | 
			
		||||
                ? new[]
 | 
			
		||||
                {
 | 
			
		||||
                    nameof(Person),
 | 
			
		||||
                    nameof(Studio),
 | 
			
		||||
                    nameof(Year),
 | 
			
		||||
                    nameof(MusicGenre),
 | 
			
		||||
                    nameof(Genre)
 | 
			
		||||
                }
 | 
			
		||||
                : Array.Empty<string>();
 | 
			
		||||
 | 
			
		||||
            var query = new InternalItemsQuery(user)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
@ -95,10 +95,13 @@ namespace Emby.Server.Implementations.Library.Validators
 | 
			
		||||
 | 
			
		||||
                _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name, item.GetType().Name);
 | 
			
		||||
 | 
			
		||||
                _libraryManager.DeleteItem(item, new DeleteOptions
 | 
			
		||||
                {
 | 
			
		||||
                    DeleteFileLocation = false
 | 
			
		||||
                }, false);
 | 
			
		||||
                _libraryManager.DeleteItem(
 | 
			
		||||
                    item,
 | 
			
		||||
                    new DeleteOptions
 | 
			
		||||
                    {
 | 
			
		||||
                        DeleteFileLocation = false
 | 
			
		||||
                    },
 | 
			
		||||
                    false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            progress.Report(100);
 | 
			
		||||
 | 
			
		||||
@ -205,9 +205,9 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
			
		||||
            // var audioChannels = 2;
 | 
			
		||||
            // var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
 | 
			
		||||
            // if (audioStream != null)
 | 
			
		||||
            //{
 | 
			
		||||
            // {
 | 
			
		||||
            //    audioChannels = audioStream.Channels ?? audioChannels;
 | 
			
		||||
            //}
 | 
			
		||||
            // }
 | 
			
		||||
            // return "-codec:a:0 aac -strict experimental -ab 320000";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,13 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Records the specified media source.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="directStreamProvider">The direct stream provider, or <c>null</c>.</param>
 | 
			
		||||
        /// <param name="mediaSource">The media source.</param>
 | 
			
		||||
        /// <param name="targetFile">The target file.</param>
 | 
			
		||||
        /// <param name="duration">The duration to record.</param>
 | 
			
		||||
        /// <param name="onStarted">An action to perform when recording starts.</param>
 | 
			
		||||
        /// <param name="cancellationToken">The cancellation token.</param>
 | 
			
		||||
        /// <returns>A <see cref="Task"/> that represents the recording operation.</returns>
 | 
			
		||||
        Task Record(IDirectStreamProvider? directStreamProvider, MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken);
 | 
			
		||||
 | 
			
		||||
        string GetOutputPath(MediaSourceInfo mediaSource, string targetFile);
 | 
			
		||||
 | 
			
		||||
@ -16,11 +16,7 @@ namespace Emby.Server.Implementations.Net
 | 
			
		||||
 | 
			
		||||
    public sealed class UdpSocket : ISocket, IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private Socket _socket;
 | 
			
		||||
        private readonly int _localPort;
 | 
			
		||||
        private bool _disposed = false;
 | 
			
		||||
 | 
			
		||||
        public Socket Socket => _socket;
 | 
			
		||||
 | 
			
		||||
        private readonly SocketAsyncEventArgs _receiveSocketAsyncEventArgs = new SocketAsyncEventArgs()
 | 
			
		||||
        {
 | 
			
		||||
@ -32,6 +28,8 @@ namespace Emby.Server.Implementations.Net
 | 
			
		||||
            SocketFlags = SocketFlags.None
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private Socket _socket;
 | 
			
		||||
        private bool _disposed = false;
 | 
			
		||||
        private TaskCompletionSource<SocketReceiveResult> _currentReceiveTaskCompletionSource;
 | 
			
		||||
        private TaskCompletionSource<int> _currentSendTaskCompletionSource;
 | 
			
		||||
 | 
			
		||||
@ -64,6 +62,8 @@ namespace Emby.Server.Implementations.Net
 | 
			
		||||
            InitReceiveSocketAsyncEventArgs();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Socket Socket => _socket;
 | 
			
		||||
 | 
			
		||||
        public IPAddress LocalIPAddress { get; }
 | 
			
		||||
 | 
			
		||||
        private void InitReceiveSocketAsyncEventArgs()
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,11 @@ namespace Emby.Server.Implementations
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="ServerApplicationPaths" /> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="programDataPath">The path for Jellyfin's data.</param>
 | 
			
		||||
        /// <param name="logDirectoryPath">The path for Jellyfin's logging directory.</param>
 | 
			
		||||
        /// <param name="configurationDirectoryPath">The path for Jellyfin's configuration directory.</param>
 | 
			
		||||
        /// <param name="cacheDirectoryPath">The path for Jellyfin's cache directory.</param>
 | 
			
		||||
        /// <param name="webDirectoryPath">The path for Jellyfin's web UI.</param>
 | 
			
		||||
        public ServerApplicationPaths(
 | 
			
		||||
            string programDataPath,
 | 
			
		||||
            string logDirectoryPath,
 | 
			
		||||
 | 
			
		||||
@ -741,6 +741,8 @@ namespace Emby.Server.Implementations.Session
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Used to report playback progress for an item.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="info">The playback progress info.</param>
 | 
			
		||||
        /// <param name="isAutomated">Whether this is an automated update.</param>
 | 
			
		||||
        /// <returns>Task.</returns>
 | 
			
		||||
        public async Task OnPlaybackProgress(PlaybackProgressInfo info, bool isAutomated)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
{
 | 
			
		||||
    public class AiredEpisodeOrderComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.AiredEpisodeOrder;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -155,11 +161,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return comparisonResult;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.AiredEpisodeOrder;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class AlbumArtistComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.AlbumArtist;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -34,11 +40,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return audio?.AlbumArtists.FirstOrDefault();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.AlbumArtist;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class AlbumComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.Album;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -33,11 +39,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return audio == null ? string.Empty : audio.Album;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.Album;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class CriticRatingComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.CriticRating;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -24,11 +30,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
        {
 | 
			
		||||
            return x?.CriticRating ?? 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.CriticRating;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class DateCreatedComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.DateCreated;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -30,11 +36,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return DateTime.Compare(x.DateCreated, y.DateCreated);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.DateCreated;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
        /// <value>The user data repository.</value>
 | 
			
		||||
        public IUserDataManager UserDataRepository { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.DatePlayed;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -59,11 +65,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return DateTime.MinValue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.DatePlayed;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class NameComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.Name;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -30,11 +36,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return string.Compare(x.Name, y.Name, StringComparison.CurrentCultureIgnoreCase);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.Name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -19,6 +19,24 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
        /// <value>The user.</value>
 | 
			
		||||
        public User User { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.PlayCount;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the user data repository.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The user data repository.</value>
 | 
			
		||||
        public IUserDataManager UserDataRepository { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the user manager.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The user manager.</value>
 | 
			
		||||
        public IUserManager UserManager { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -41,23 +59,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return userdata == null ? 0 : userdata.PlayCount;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.PlayCount;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the user data repository.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The user data repository.</value>
 | 
			
		||||
        public IUserDataManager UserDataRepository { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the user manager.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The user manager.</value>
 | 
			
		||||
        public IUserManager UserManager { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class PremiereDateComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.PremiereDate;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -52,11 +58,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return DateTime.MinValue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.PremiereDate;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ProductionYearComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.ProductionYear;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -44,11 +50,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.ProductionYear;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class RandomComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.Random;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -20,11 +26,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
        {
 | 
			
		||||
            return Guid.NewGuid().CompareTo(Guid.NewGuid());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.Random;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class RuntimeComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.Runtime;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -32,11 +38,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return (x.RunTimeTicks ?? 0).CompareTo(y.RunTimeTicks ?? 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.Runtime;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class SortNameComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.SortName;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -32,11 +38,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return string.Compare(x.SortName, y.SortName, StringComparison.CurrentCultureIgnoreCase);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.SortName;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,12 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
{
 | 
			
		||||
    public class StudioComparer : IBaseItemComparer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.Studio;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Compares the specified x.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -33,11 +39,5 @@ namespace Emby.Server.Implementations.Sorting
 | 
			
		||||
 | 
			
		||||
            return AlphanumericComparator.CompareValues(x.Studios.FirstOrDefault(), y.Studios.FirstOrDefault());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The name.</value>
 | 
			
		||||
        public string Name => ItemSortBy.Studio;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -29,10 +29,10 @@ namespace Emby.Server.Implementations.Udp
 | 
			
		||||
        private readonly IServerApplicationHost _appHost;
 | 
			
		||||
        private readonly IConfiguration _config;
 | 
			
		||||
 | 
			
		||||
        private Socket _udpSocket;
 | 
			
		||||
        private IPEndPoint _endpoint;
 | 
			
		||||
        private readonly byte[] _receiveBuffer = new byte[8192];
 | 
			
		||||
 | 
			
		||||
        private Socket _udpSocket;
 | 
			
		||||
        private IPEndPoint _endpoint;
 | 
			
		||||
        private bool _disposed = false;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
 | 
			
		||||
@ -10,8 +10,8 @@ using System.Text.Json;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Jellyfin.Data.Events;
 | 
			
		||||
using MediaBrowser.Common.Configuration;
 | 
			
		||||
using Jellyfin.Extensions.Json;
 | 
			
		||||
using MediaBrowser.Common.Configuration;
 | 
			
		||||
using MediaBrowser.Common.Net;
 | 
			
		||||
using MediaBrowser.Common.Plugins;
 | 
			
		||||
using MediaBrowser.Common.Updates;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user