Browse Source

Merge pull request #887 from wtayl0r/replace-primitives-with-iconfiguration

Replace primitive injection with IConfiguration
Vasily 6 years ago
parent
commit
13f2783a8e

+ 8 - 10
Emby.Server.Implementations/ApplicationHost.cs

@@ -104,10 +104,10 @@ using MediaBrowser.Providers.Manager;
 using MediaBrowser.Providers.Subtitles;
 using MediaBrowser.WebDashboard.Api;
 using MediaBrowser.XbmcMetadata.Providers;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.DependencyInjection;
 using ServiceStack;
-using ServiceStack.Text.Jsv;
 using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate;
 
 namespace Emby.Server.Implementations
@@ -318,6 +318,8 @@ namespace Emby.Server.Implementations
         private IMediaSourceManager MediaSourceManager { get; set; }
         private IPlaylistManager PlaylistManager { get; set; }
 
+        private readonly IConfiguration _configuration;
+
         /// <summary>
         /// Gets or sets the installation manager.
         /// </summary>
@@ -356,8 +358,10 @@ namespace Emby.Server.Implementations
             IFileSystem fileSystem,
             IEnvironmentInfo environmentInfo,
             IImageEncoder imageEncoder,
-            INetworkManager networkManager)
+            INetworkManager networkManager,
+            IConfiguration configuration)
         {
+            _configuration = configuration;
 
             // hack alert, until common can target .net core
             BaseExtensions.CryptographyProvider = CryptographyProvider;
@@ -727,11 +731,10 @@ namespace Emby.Server.Implementations
             HttpServer = new HttpListenerHost(this,
                 LoggerFactory,
                 ServerConfigurationManager,
-                "web/index.html",
+                _configuration,
                 NetworkManager,
                 JsonSerializer,
-                XmlSerializer,
-                GetParseFn);
+                XmlSerializer);
 
             HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading");
             serviceCollection.AddSingleton(HttpServer);
@@ -831,11 +834,6 @@ namespace Emby.Server.Implementations
             return null;
         }
 
-        private static Func<string, object> GetParseFn(Type propertyType)
-        {
-            return s => JsvReader.GetParseFn(propertyType)(s);
-        }
-
         public virtual string PackageRuntime => "netcore";
 
         public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths, EnvironmentInfo.EnvironmentInfo environmentInfo)

+ 12 - 0
Emby.Server.Implementations/ConfigurationOptions.cs

@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+
+namespace Emby.Server.Implementations
+{
+    public static class ConfigurationOptions
+    {
+        public static readonly Dictionary<string, string> Configuration = new Dictionary<string, string>
+        {
+            {"HttpListenerHost:DefaultRedirectPath", "web/index.html"}
+        };
+    }
+}

+ 1 - 0
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -24,6 +24,7 @@
   <ItemGroup>
     <PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
+    <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" />
     <PackageReference Include="ServiceStack.Text.Core" Version="5.4.0" />
     <PackageReference Include="sharpcompress" Version="0.22.0" />
     <PackageReference Include="SQLitePCL.pretty.netstandard" Version="1.0.0" />

+ 7 - 5
Emby.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -19,7 +19,9 @@ using MediaBrowser.Model.Events;
 using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Services;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Logging;
+using ServiceStack.Text.Jsv;
 
 namespace Emby.Server.Implementations.HttpServer
 {
@@ -53,20 +55,20 @@ namespace Emby.Server.Implementations.HttpServer
             IServerApplicationHost applicationHost,
             ILoggerFactory loggerFactory,
             IServerConfigurationManager config,
-            string defaultRedirectPath,
+            IConfiguration configuration,
             INetworkManager networkManager,
             IJsonSerializer jsonSerializer,
-            IXmlSerializer xmlSerializer,
-            Func<Type, Func<string, object>> funcParseFn)
+            IXmlSerializer xmlSerializer)
         {
             _appHost = applicationHost;
             _logger = loggerFactory.CreateLogger("HttpServer");
             _config = config;
-            DefaultRedirectPath = defaultRedirectPath;
+            DefaultRedirectPath = configuration["HttpListenerHost:DefaultRedirectPath"];
             _networkManager = networkManager;
             _jsonSerializer = jsonSerializer;
             _xmlSerializer = xmlSerializer;
-            _funcParseFn = funcParseFn;
+            
+            _funcParseFn = t => s => JsvReader.GetParseFn(t)(s);
 
             Instance = this;
             ResponseFilters = Array.Empty<Action<IRequest, IResponse, object>>();

+ 11 - 48
Emby.Server.Implementations/IO/ManagedFileSystem.cs

@@ -4,8 +4,10 @@ using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using System.Text;
+using MediaBrowser.Common.Configuration;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.System;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.IO
@@ -20,61 +22,27 @@ namespace Emby.Server.Implementations.IO
         private readonly bool _supportsAsyncFileStreams;
         private char[] _invalidFileNameChars;
         private readonly List<IShortcutHandler> _shortcutHandlers = new List<IShortcutHandler>();
-        private bool EnableSeparateFileAndDirectoryQueries;
 
-        private string _tempPath;
+        private readonly string _tempPath;
 
-        private IEnvironmentInfo _environmentInfo;
-        private bool _isEnvironmentCaseInsensitive;
-
-        private string _defaultDirectory;
+        private readonly IEnvironmentInfo _environmentInfo;
+        private readonly bool _isEnvironmentCaseInsensitive;
 
         public ManagedFileSystem(
             ILoggerFactory loggerFactory,
             IEnvironmentInfo environmentInfo,
-            string defaultDirectory,
-            string tempPath,
-            bool enableSeparateFileAndDirectoryQueries)
+            IApplicationPaths applicationPaths)
         {
             Logger = loggerFactory.CreateLogger("FileSystem");
             _supportsAsyncFileStreams = true;
-            _tempPath = tempPath;
+            _tempPath = applicationPaths.TempDirectory;
             _environmentInfo = environmentInfo;
-            _defaultDirectory = defaultDirectory;
-
-            // On Linux with mono, this needs to be true or symbolic links are ignored
-            EnableSeparateFileAndDirectoryQueries = enableSeparateFileAndDirectoryQueries;
 
             SetInvalidFileNameChars(environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows);
 
             _isEnvironmentCaseInsensitive = environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows;
         }
 
-        public virtual string DefaultDirectory
-        {
-            get
-            {
-                var value = _defaultDirectory;
-
-                if (!string.IsNullOrEmpty(value))
-                {
-                    try
-                    {
-                        if (Directory.Exists(value))
-                        {
-                            return value;
-                        }
-                    }
-                    catch
-                    {
-
-                    }
-                }
-
-                return null;
-            }
-        }
-
         public virtual void AddShortcutHandler(IShortcutHandler handler)
         {
             _shortcutHandlers.Add(handler);
@@ -718,7 +686,7 @@ namespace Emby.Server.Implementations.IO
             SetAttributes(path, false, false);
             File.Delete(path);
         }
-        
+
         public virtual List<FileSystemMetadata> GetDrives()
         {
             // Only include drives in the ready state or this method could end up being very slow, waiting for drives to timeout
@@ -777,20 +745,15 @@ namespace Emby.Server.Implementations.IO
             var directoryInfo = new DirectoryInfo(path);
             var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
 
-            if (EnableSeparateFileAndDirectoryQueries)
-            {
-                return ToMetadata(directoryInfo.EnumerateDirectories("*", searchOption))
-                                .Concat(ToMetadata(directoryInfo.EnumerateFiles("*", searchOption)));
-            }
-
-            return ToMetadata(directoryInfo.EnumerateFileSystemInfos("*", searchOption));
+            return ToMetadata(directoryInfo.EnumerateDirectories("*", searchOption))
+                .Concat(ToMetadata(directoryInfo.EnumerateFiles("*", searchOption)));
         }
 
         private IEnumerable<FileSystemMetadata> ToMetadata(IEnumerable<FileSystemInfo> infos)
         {
             return infos.Select(GetFileSystemMetadata);
         }
-        
+
         public virtual IEnumerable<string> GetDirectoryPaths(string path, bool recursive = false)
         {
             var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;

+ 19 - 2
Jellyfin.Server/CoreAppHost.cs

@@ -5,14 +5,31 @@ using Emby.Server.Implementations.HttpServer;
 using Jellyfin.Server.SocketSharp;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.System;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Logging;
 
 namespace Jellyfin.Server
 {
     public class CoreAppHost : ApplicationHost
     {
-        public CoreAppHost(ServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory, StartupOptions options, IFileSystem fileSystem, IEnvironmentInfo environmentInfo, MediaBrowser.Controller.Drawing.IImageEncoder imageEncoder, MediaBrowser.Common.Net.INetworkManager networkManager)
-            : base(applicationPaths, loggerFactory, options, fileSystem, environmentInfo, imageEncoder, networkManager)
+        public CoreAppHost(
+            ServerApplicationPaths applicationPaths,
+            ILoggerFactory loggerFactory,
+            StartupOptions options,
+            IFileSystem fileSystem,
+            IEnvironmentInfo environmentInfo,
+            MediaBrowser.Controller.Drawing.IImageEncoder imageEncoder,
+            MediaBrowser.Common.Net.INetworkManager networkManager,
+            IConfiguration configuration)
+            : base(
+                applicationPaths,
+                loggerFactory,
+                options,
+                fileSystem,
+                environmentInfo,
+                imageEncoder,
+                networkManager,
+                configuration)
         {
         }
 

+ 30 - 20
Jellyfin.Server/Program.cs

@@ -35,6 +35,7 @@ namespace Jellyfin.Server
         private static readonly ILoggerFactory _loggerFactory = new SerilogLoggerFactory();
         private static ILogger _logger;
         private static bool _restartOnShutdown;
+        private static IConfiguration appConfig;
 
         public static async Task Main(string[] args)
         {
@@ -78,7 +79,11 @@ namespace Jellyfin.Server
 
             // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager
             Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath);
-            await CreateLogger(appPaths).ConfigureAwait(false);
+
+            appConfig = await CreateConfiguration(appPaths).ConfigureAwait(false);
+
+            CreateLogger(appConfig, appPaths);
+
             _logger = _loggerFactory.CreateLogger("Main");
 
             AppDomain.CurrentDomain.UnhandledException += (sender, e)
@@ -121,7 +126,7 @@ namespace Jellyfin.Server
             // Allow all https requests
             ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; } );
 
-            var fileSystem = new ManagedFileSystem(_loggerFactory, environmentInfo, null, appPaths.TempDirectory, true);
+            var fileSystem = new ManagedFileSystem(_loggerFactory, environmentInfo, appPaths);
 
             using (var appHost = new CoreAppHost(
                 appPaths,
@@ -130,7 +135,8 @@ namespace Jellyfin.Server
                 fileSystem,
                 environmentInfo,
                 new NullImageEncoder(),
-                new NetworkManager(_loggerFactory, environmentInfo)))
+                new NetworkManager(_loggerFactory, environmentInfo),
+                appConfig))
             {
                 await appHost.Init(new ServiceCollection()).ConfigureAwait(false);
 
@@ -309,29 +315,33 @@ namespace Jellyfin.Server
             return new ServerApplicationPaths(dataDir, logDir, configDir, cacheDir);
         }
 
-        private static async Task CreateLogger(IApplicationPaths appPaths)
+        private static async Task<IConfiguration> CreateConfiguration(IApplicationPaths appPaths)
         {
-            try
-            {
-                string configPath = Path.Combine(appPaths.ConfigurationDirectoryPath, "logging.json");
+            string configPath = Path.Combine(appPaths.ConfigurationDirectoryPath, "logging.json");
 
-                if (!File.Exists(configPath))
+            if (!File.Exists(configPath))
+            {
+                // For some reason the csproj name is used instead of the assembly name
+                using (Stream rscstr = typeof(Program).Assembly
+                    .GetManifestResourceStream("Jellyfin.Server.Resources.Configuration.logging.json"))
+                using (Stream fstr = File.Open(configPath, FileMode.CreateNew))
                 {
-                    // For some reason the csproj name is used instead of the assembly name
-                    using (Stream rscstr = typeof(Program).Assembly
-                        .GetManifestResourceStream("Jellyfin.Server.Resources.Configuration.logging.json"))
-                    using (Stream fstr = File.Open(configPath, FileMode.CreateNew))
-                    {
-                        await rscstr.CopyToAsync(fstr).ConfigureAwait(false);
-                    }
+                    await rscstr.CopyToAsync(fstr).ConfigureAwait(false);
                 }
+            }
 
-                var configuration = new ConfigurationBuilder()
-                    .SetBasePath(appPaths.ConfigurationDirectoryPath)
-                    .AddJsonFile("logging.json")
-                    .AddEnvironmentVariables("JELLYFIN_")
-                    .Build();
+            return new ConfigurationBuilder()
+                .SetBasePath(appPaths.ConfigurationDirectoryPath)
+                .AddJsonFile("logging.json")
+                .AddEnvironmentVariables("JELLYFIN_")
+                .AddInMemoryCollection(ConfigurationOptions.Configuration)
+                .Build();
+        }
 
+        private static void CreateLogger(IConfiguration configuration, IApplicationPaths appPaths)
+        {
+            try
+            {
                 // Serilog.Log is used by SerilogLoggerFactory when no logger is specified
                 Serilog.Log.Logger = new LoggerConfiguration()
                     .ReadFrom.Configuration(configuration)

+ 2 - 8
MediaBrowser.Api/EnvironmentService.cs

@@ -173,14 +173,8 @@ namespace MediaBrowser.Api
             _fileSystem.DeleteFile(file);
         }
 
-        public object Get(GetDefaultDirectoryBrowser request)
-        {
-            var result = new DefaultDirectoryBrowserInfo();
-
-            result.Path = _fileSystem.DefaultDirectory;
-
-            return ToOptimizedResult(result);
-        }
+        public object Get(GetDefaultDirectoryBrowser request) =>
+            ToOptimizedResult(new DefaultDirectoryBrowserInfo {Path = null});
 
         /// <summary>
         /// Gets the specified request.

+ 0 - 2
MediaBrowser.Model/IO/IFileSystem.cs

@@ -113,8 +113,6 @@ namespace MediaBrowser.Model.IO
         Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share,
             FileOpenOptions fileOpenOptions);
 
-        string DefaultDirectory { get; }
-
         /// <summary>
         /// Swaps the files.
         /// </summary>