From 0df899943f45db9d95b7d7ba07f593dffe98e597 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Fri, 27 Jan 2023 18:24:53 -0500 Subject: [PATCH 1/6] Move LogEnvironmentInfo to StartupHelpers --- .../ApplicationHost.cs | 36 ----------------- Jellyfin.Server/Helpers/StartupHelpers.cs | 40 +++++++++++++++++++ Jellyfin.Server/Program.cs | 2 +- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 560ba7d10d..4ed055cdf4 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -11,7 +11,6 @@ using System.IO; using System.Linq; using System.Net; using System.Reflection; -using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -115,11 +114,6 @@ namespace Emby.Server.Implementations /// public abstract class ApplicationHost : IServerApplicationHost, IAsyncDisposable, IDisposable { - /// - /// The environment variable prefixes to log at server startup. - /// - private static readonly string[] _relevantEnvVarPrefixes = { "JELLYFIN_", "DOTNET_", "ASPNETCORE_" }; - /// /// The disposable parts. /// @@ -670,36 +664,6 @@ namespace Emby.Server.Implementations FindParts(); } - public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths) - { - // Distinct these to prevent users from reporting problems that aren't actually problems - var commandLineArgs = Environment - .GetCommandLineArgs() - .Distinct(); - - // Get all relevant environment variables - var allEnvVars = Environment.GetEnvironmentVariables(); - var relevantEnvVars = new Dictionary(); - foreach (var key in allEnvVars.Keys) - { - if (_relevantEnvVarPrefixes.Any(prefix => key.ToString().StartsWith(prefix, StringComparison.OrdinalIgnoreCase))) - { - relevantEnvVars.Add(key, allEnvVars[key]); - } - } - - logger.LogInformation("Environment Variables: {EnvVars}", relevantEnvVars); - logger.LogInformation("Arguments: {Args}", commandLineArgs); - logger.LogInformation("Operating system: {OS}", RuntimeInformation.OSDescription); - logger.LogInformation("Architecture: {Architecture}", RuntimeInformation.OSArchitecture); - logger.LogInformation("64-Bit Process: {Is64Bit}", Environment.Is64BitProcess); - logger.LogInformation("User Interactive: {IsUserInteractive}", Environment.UserInteractive); - logger.LogInformation("Processor count: {ProcessorCount}", Environment.ProcessorCount); - logger.LogInformation("Program data path: {ProgramDataPath}", appPaths.ProgramDataPath); - logger.LogInformation("Web resources path: {WebPath}", appPaths.WebPath); - logger.LogInformation("Application directory: {ApplicationPath}", appPaths.ProgramSystemPath); - } - private X509Certificate2 GetCertificate(string path, string password) { if (string.IsNullOrWhiteSpace(path)) diff --git a/Jellyfin.Server/Helpers/StartupHelpers.cs b/Jellyfin.Server/Helpers/StartupHelpers.cs index f1bb9b2831..9a1299fe20 100644 --- a/Jellyfin.Server/Helpers/StartupHelpers.cs +++ b/Jellyfin.Server/Helpers/StartupHelpers.cs @@ -1,7 +1,10 @@ using System; +using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Net; +using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Threading.Tasks; @@ -22,6 +25,43 @@ namespace Jellyfin.Server.Helpers; /// public static class StartupHelpers { + private static readonly string[] _relevantEnvVarPrefixes = { "JELLYFIN_", "DOTNET_", "ASPNETCORE_" }; + + /// + /// Logs relevant environment variables and information about the host. + /// + /// The logger to use. + /// The application paths to use. + public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths) + { + // Distinct these to prevent users from reporting problems that aren't actually problems + var commandLineArgs = Environment + .GetCommandLineArgs() + .Distinct(); + + // Get all relevant environment variables + var allEnvVars = Environment.GetEnvironmentVariables(); + var relevantEnvVars = new Dictionary(); + foreach (var key in allEnvVars.Keys) + { + if (_relevantEnvVarPrefixes.Any(prefix => key.ToString()!.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))) + { + relevantEnvVars.Add(key, allEnvVars[key]!); + } + } + + logger.LogInformation("Environment Variables: {EnvVars}", relevantEnvVars); + logger.LogInformation("Arguments: {Args}", commandLineArgs); + logger.LogInformation("Operating system: {OS}", RuntimeInformation.OSDescription); + logger.LogInformation("Architecture: {Architecture}", RuntimeInformation.OSArchitecture); + logger.LogInformation("64-Bit Process: {Is64Bit}", Environment.Is64BitProcess); + logger.LogInformation("User Interactive: {IsUserInteractive}", Environment.UserInteractive); + logger.LogInformation("Processor count: {ProcessorCount}", Environment.ProcessorCount); + logger.LogInformation("Program data path: {ProgramDataPath}", appPaths.ProgramDataPath); + logger.LogInformation("Web resources path: {WebPath}", appPaths.WebPath); + logger.LogInformation("Application directory: {ApplicationPath}", appPaths.ProgramSystemPath); + } + /// /// Create the data, config and log paths from the variety of inputs(command line args, /// environment variables) or decide on what default to use. For Windows it's %AppPath% diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 25fe30a392..6e8b17a737 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -148,7 +148,7 @@ namespace Jellyfin.Server "Jellyfin version: {Version}", Assembly.GetEntryAssembly()!.GetName().Version!.ToString(3)); - ApplicationHost.LogEnvironmentInfo(_logger, appPaths); + StartupHelpers.LogEnvironmentInfo(_logger, appPaths); // If hosting the web client, validate the client content path if (startupConfig.HostWebClient()) From 990bd7d1eef46dba1e22a83d6144b769680e042c Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Fri, 27 Jan 2023 18:29:35 -0500 Subject: [PATCH 2/6] Initialize device id in constructor --- Emby.Server.Implementations/ApplicationHost.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 4ed055cdf4..c9720de1a5 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -118,6 +118,7 @@ namespace Emby.Server.Implementations /// The disposable parts. /// private readonly ConcurrentDictionary _disposableParts = new(); + private readonly DeviceId _deviceId; private readonly IFileSystem _fileSystemManager; private readonly IConfiguration _startupConfig; @@ -135,8 +136,6 @@ namespace Emby.Server.Implementations /// All concrete types. private Type[] _allConcreteTypes; - private DeviceId _deviceId; - private bool _disposed = false; /// @@ -160,6 +159,7 @@ namespace Emby.Server.Implementations Logger = LoggerFactory.CreateLogger(); _fileSystemManager.AddShortcutHandler(new MbLinkShortcutHandler(_fileSystemManager)); + _deviceId = new DeviceId(ApplicationPaths, LoggerFactory); ApplicationVersion = typeof(ApplicationHost).Assembly.GetName().Version; ApplicationVersionString = ApplicationVersion.ToString(3); @@ -280,15 +280,7 @@ namespace Emby.Server.Implementations /// The application name. public string ApplicationProductName { get; } = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).ProductName; - public string SystemId - { - get - { - _deviceId ??= new DeviceId(ApplicationPaths, LoggerFactory); - - return _deviceId.Value; - } - } + public string SystemId => _deviceId.Value; /// public string Name => ApplicationProductName; From 8898012121e99e23c0507e396d6a9330fb80831d Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Fri, 27 Jan 2023 18:33:32 -0500 Subject: [PATCH 3/6] Convert CanLaunchWebBrowser to expression body --- .../ApplicationHost.cs | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index c9720de1a5..2e7386bf32 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -187,23 +187,9 @@ namespace Emby.Server.Implementations public bool CoreStartupHasCompleted { get; private set; } - public virtual bool CanLaunchWebBrowser - { - get - { - if (!Environment.UserInteractive) - { - return false; - } - - if (_startupOptions.IsService) - { - return false; - } - - return OperatingSystem.IsWindows() || OperatingSystem.IsMacOS(); - } - } + public virtual bool CanLaunchWebBrowser => Environment.UserInteractive + && !_startupOptions.IsService + && (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS()); /// /// Gets the singleton instance. From 4f81f4daaa77ac58381a95f1fd32fecd4e0a7d2b Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Fri, 27 Jan 2023 18:41:10 -0500 Subject: [PATCH 4/6] Use depencency injection for ISubtitleProvider --- Emby.Server.Implementations/ApplicationHost.cs | 2 -- .../Subtitles/ISubtitleManager.cs | 6 ------ .../Subtitles/SubtitleManager.cs | 16 ++++++---------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 2e7386bf32..be4845c29a 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -728,8 +728,6 @@ namespace Emby.Server.Implementations Resolve().AddParts(GetExports(), GetExports(), GetExports()); - Resolve().AddParts(GetExports()); - Resolve().AddParts(GetExports()); Resolve().AddParts(GetExports()); diff --git a/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs b/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs index 52aa44024d..841b320376 100644 --- a/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs +++ b/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs @@ -19,12 +19,6 @@ namespace MediaBrowser.Controller.Subtitles /// event EventHandler SubtitleDownloadFailure; - /// - /// Adds the parts. - /// - /// The subtitle providers. - void AddParts(IEnumerable subtitleProviders); - /// /// Searches the subtitles. /// diff --git a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs index b1a26cfba3..12570f0a7e 100644 --- a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs +++ b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs @@ -35,33 +35,29 @@ namespace MediaBrowser.Providers.Subtitles private readonly IMediaSourceManager _mediaSourceManager; private readonly ILocalizationManager _localization; - private ISubtitleProvider[] _subtitleProviders; + private readonly ISubtitleProvider[] _subtitleProviders; public SubtitleManager( ILogger logger, IFileSystem fileSystem, ILibraryMonitor monitor, IMediaSourceManager mediaSourceManager, - ILocalizationManager localizationManager) + ILocalizationManager localizationManager, + IEnumerable subtitleProviders) { _logger = logger; _fileSystem = fileSystem; _monitor = monitor; _mediaSourceManager = mediaSourceManager; _localization = localizationManager; - } - - /// - public event EventHandler SubtitleDownloadFailure; - - /// - public void AddParts(IEnumerable subtitleProviders) - { _subtitleProviders = subtitleProviders .OrderBy(i => i is IHasOrder hasOrder ? hasOrder.Order : 0) .ToArray(); } + /// + public event EventHandler SubtitleDownloadFailure; + /// public async Task SearchSubtitles(SubtitleSearchRequest request, CancellationToken cancellationToken) { From f7ec85d7a0d30619721d13064437993d2f3a86d4 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Fri, 27 Jan 2023 18:46:54 -0500 Subject: [PATCH 5/6] Use dependency injection for IChannel --- Emby.Server.Implementations/ApplicationHost.cs | 2 -- .../Channels/ChannelManager.cs | 17 +++++++---------- .../Channels/IChannelManager.cs | 6 ------ 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index be4845c29a..3527e40480 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -728,8 +728,6 @@ namespace Emby.Server.Implementations Resolve().AddParts(GetExports(), GetExports(), GetExports()); - Resolve().AddParts(GetExports()); - Resolve().AddParts(GetExports()); Resolve().AddParts(GetExports(), GetExports()); diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 85ccbc0284..84ba194648 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -66,6 +66,7 @@ namespace Emby.Server.Implementations.Channels /// The user data manager. /// The provider manager. /// The memory cache. + /// The channels. public ChannelManager( IUserManager userManager, IDtoService dtoService, @@ -75,7 +76,8 @@ namespace Emby.Server.Implementations.Channels IFileSystem fileSystem, IUserDataManager userDataManager, IProviderManager providerManager, - IMemoryCache memoryCache) + IMemoryCache memoryCache, + IEnumerable channels) { _userManager = userManager; _dtoService = dtoService; @@ -86,18 +88,13 @@ namespace Emby.Server.Implementations.Channels _userDataManager = userDataManager; _providerManager = providerManager; _memoryCache = memoryCache; - } - - internal IChannel[] Channels { get; private set; } - - private static TimeSpan CacheLength => TimeSpan.FromHours(3); - - /// - public void AddParts(IEnumerable channels) - { Channels = channels.ToArray(); } + internal IChannel[] Channels { get; } + + private static TimeSpan CacheLength => TimeSpan.FromHours(3); + /// public bool EnableMediaSourceDisplay(BaseItem item) { diff --git a/MediaBrowser.Controller/Channels/IChannelManager.cs b/MediaBrowser.Controller/Channels/IChannelManager.cs index 49be897ef3..e392a3493e 100644 --- a/MediaBrowser.Controller/Channels/IChannelManager.cs +++ b/MediaBrowser.Controller/Channels/IChannelManager.cs @@ -15,12 +15,6 @@ namespace MediaBrowser.Controller.Channels { public interface IChannelManager { - /// - /// Adds the parts. - /// - /// The channels. - void AddParts(IEnumerable channels); - /// /// Gets the channel features. /// From 0bbeead6c7d68bdb09b8b3d0367e9f186042167d Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Fri, 27 Jan 2023 20:32:15 -0500 Subject: [PATCH 6/6] Don't store media encoder as field --- Emby.Server.Implementations/ApplicationHost.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 3527e40480..0b2dd00b96 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -127,7 +127,6 @@ namespace Emby.Server.Implementations private readonly IPluginManager _pluginManager; private List _creatingInstances; - private IMediaEncoder _mediaEncoder; private ISessionManager _sessionManager; /// @@ -419,7 +418,7 @@ namespace Emby.Server.Implementations ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated; ConfigurationManager.NamedConfigurationUpdated += OnConfigurationUpdated; - _mediaEncoder.SetFFmpegPath(); + Resolve().SetFFmpegPath(); Logger.LogInformation("ServerId: {ServerId}", SystemId); @@ -631,7 +630,6 @@ namespace Emby.Server.Implementations var localizationManager = (LocalizationManager)Resolve(); await localizationManager.LoadAll().ConfigureAwait(false); - _mediaEncoder = Resolve(); _sessionManager = Resolve(); SetStaticProperties();