From a71040ba1b0f5f8ff78683971338704d9a9ff254 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sat, 9 Feb 2019 21:28:36 +0100 Subject: Chnage to own NuGet package --- Emby.Server.Implementations/Emby.Server.Implementations.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index af01001a5..8356a9501 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -25,8 +25,7 @@ - - + -- cgit v1.2.3 From 74d2698c5fd7f70b2409afc5be0e9825c5edeeda Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Sat, 9 Feb 2019 18:37:35 -0500 Subject: Fix poor handling of cache directories --- .../AppBase/BaseConfigurationManager.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs index 460809e93..cf07cb1ec 100644 --- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs +++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs @@ -171,16 +171,29 @@ namespace Emby.Server.Implementations.AppBase private void UpdateCachePath() { string cachePath; - + // If the configuration file has no entry (i.e. not set in UI) if (string.IsNullOrWhiteSpace(CommonConfiguration.CachePath)) { - cachePath = null; + // If the current live configuration has no entry (i.e. not set on CLI/envvars, during startup) + if (string.IsNullOrWhiteSpace(((BaseApplicationPaths)CommonApplicationPaths).CachePath)) + { + // Set cachePath to a default value under ProgramDataPath + cachePath = (((BaseApplicationPaths)CommonApplicationPaths).ProgramDataPath + "/cache"); + } + else + { + // Set cachePath to the existing live value; will require restart if UI value is removed (but not replaced) + // TODO: Figure out how to re-grab this from the CLI/envvars while running + cachePath = ((BaseApplicationPaths)CommonApplicationPaths).CachePath; + } } else { - cachePath = Path.Combine(CommonConfiguration.CachePath, "cache"); + // Set cachePath to the new UI-set value + cachePath = CommonConfiguration.CachePath; } + Logger.LogInformation("Setting cache path to " + cachePath); ((BaseApplicationPaths)CommonApplicationPaths).CachePath = cachePath; } -- cgit v1.2.3 From 382b8bb509bbce34354a5d667c755b91d52c4fa4 Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Sat, 9 Feb 2019 19:14:34 -0500 Subject: Use Path.Combine --- Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs index cf07cb1ec..5feac1adf 100644 --- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs +++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs @@ -178,7 +178,7 @@ namespace Emby.Server.Implementations.AppBase if (string.IsNullOrWhiteSpace(((BaseApplicationPaths)CommonApplicationPaths).CachePath)) { // Set cachePath to a default value under ProgramDataPath - cachePath = (((BaseApplicationPaths)CommonApplicationPaths).ProgramDataPath + "/cache"); + cachePath = Path.Combine(((BaseApplicationPaths)CommonApplicationPaths).ProgramDataPath, "cache"); } else { -- cgit v1.2.3 From 86089ec03a4af121281154a6159cc70787571dbe Mon Sep 17 00:00:00 2001 From: Felix Ruhnow Date: Sun, 10 Feb 2019 22:23:47 +0100 Subject: Adding support for "tvg-chno"-Tag in M3U Channel Lists --- Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 9a01c42d3..e10c44501 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -204,6 +204,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts } } + if (!IsValidChannelNumber(numberString)) + { + if (attributes.TryGetValue("tvg-chno", out string value)) + { + numberString = value; + } + } + if (!string.IsNullOrWhiteSpace(numberString)) { numberString = numberString.Trim(); -- cgit v1.2.3 From edf5ee0cc43beaff4437ace4ae6b0202e414ec03 Mon Sep 17 00:00:00 2001 From: Felix Ruhnow Date: Mon, 11 Feb 2019 10:11:07 +0100 Subject: combining some of the if's and adressing #820 --- .../LiveTv/TunerHosts/M3uParser.cs | 78 ++++++++++------------ 1 file changed, 37 insertions(+), 41 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index e10c44501..d2a835b85 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -157,72 +157,68 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts var nameInExtInf = nameParts.Length > 1 ? nameParts.Last().Trim() : null; string numberString = null; + string attributeValue; + double doubleValue; - // Check for channel number with the format from SatIp - // #EXTINF:0,84. VOX Schweiz - // #EXTINF:0,84.0 - VOX Schweiz - if (!string.IsNullOrWhiteSpace(nameInExtInf)) + if (attributes.TryGetValue("tvg-chno", out attributeValue)) { - var numberIndex = nameInExtInf.IndexOf(' '); - if (numberIndex > 0) + if (double.TryParse(attributeValue, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleValue)) { - var numberPart = nameInExtInf.Substring(0, numberIndex).Trim(new[] { ' ', '.' }); - - if (double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out var number)) - { - numberString = numberPart; - } + numberString = attributeValue; } } - if (!string.IsNullOrWhiteSpace(numberString)) - { - numberString = numberString.Trim(); - } - if (!IsValidChannelNumber(numberString)) { - if (attributes.TryGetValue("tvg-id", out string value)) + if (attributes.TryGetValue("tvg-id", out attributeValue)) { - if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var doubleValue)) + if (double.TryParse(attributeValue, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleValue)) { - numberString = value; + numberString = attributeValue; + } + else if (attributes.TryGetValue("channel-id", out attributeValue)) + { + if (double.TryParse(attributeValue, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleValue)) + { + numberString = attributeValue; + } } } - } - if (!string.IsNullOrWhiteSpace(numberString)) - { - numberString = numberString.Trim(); - } - - if (!IsValidChannelNumber(numberString)) - { - if (attributes.TryGetValue("channel-id", out string value)) + if (String.IsNullOrWhiteSpace(numberString)) { - numberString = value; + // Using this as a fallback now as this leads to Problems with channels like "5 USA" + // where 5 isnt ment to be the channel number + // Check for channel number with the format from SatIp + // #EXTINF:0,84. VOX Schweiz + // #EXTINF:0,84.0 - VOX Schweiz + if (!string.IsNullOrWhiteSpace(nameInExtInf)) + { + var numberIndex = nameInExtInf.IndexOf(' '); + if (numberIndex > 0) + { + var numberPart = nameInExtInf.Substring(0, numberIndex).Trim(new[] { ' ', '.' }); + + if (double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out var number)) + { + numberString = numberPart; + } + } + } } + } if (!IsValidChannelNumber(numberString)) { - if (attributes.TryGetValue("tvg-chno", out string value)) - { - numberString = value; - } + numberString = null; } if (!string.IsNullOrWhiteSpace(numberString)) { numberString = numberString.Trim(); } - - if (!IsValidChannelNumber(numberString)) - { - numberString = null; - } - - if (string.IsNullOrWhiteSpace(numberString)) + else { if (string.IsNullOrWhiteSpace(mediaUrl)) { -- cgit v1.2.3 From 81a8ebde22e92c9d8f4292bfb18c9134f43bd956 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sun, 3 Feb 2019 17:09:12 +0100 Subject: Move to Microsoft.Extensions.DependencyInjection This PR replaces SimpleInjector with Microsoft.Extensions.DependencyInjection. --- Emby.Dlna/DlnaManager.cs | 4 +- Emby.Dlna/MediaReceiverRegistrar/ControlHandler.cs | 3 +- Emby.Server.Implementations/ApplicationHost.cs | 498 ++++++--------------- .../Emby.Server.Implementations.csproj | 3 +- Jellyfin.Server/Program.cs | 3 +- MediaBrowser.Common/IApplicationHost.cs | 16 +- MediaBrowser.Common/MediaBrowser.Common.csproj | 4 + MediaBrowser.Model/System/PublicSystemInfo.cs | 6 +- MediaBrowser.Model/System/SystemInfo.cs | 3 +- 9 files changed, 151 insertions(+), 389 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index c507b14e9..f53d27451 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -38,7 +38,9 @@ namespace Emby.Dlna IFileSystem fileSystem, IApplicationPaths appPaths, ILoggerFactory loggerFactory, - IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IAssemblyInfo assemblyInfo) + IJsonSerializer jsonSerializer, + IServerApplicationHost appHost, + IAssemblyInfo assemblyInfo) { _xmlSerializer = xmlSerializer; _fileSystem = fileSystem; diff --git a/Emby.Dlna/MediaReceiverRegistrar/ControlHandler.cs b/Emby.Dlna/MediaReceiverRegistrar/ControlHandler.cs index 6257892b1..ae8175f4a 100644 --- a/Emby.Dlna/MediaReceiverRegistrar/ControlHandler.cs +++ b/Emby.Dlna/MediaReceiverRegistrar/ControlHandler.cs @@ -36,7 +36,8 @@ namespace Emby.Dlna.MediaReceiverRegistrar }; } - public ControlHandler(IServerConfigurationManager config, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory) : base(config, logger, xmlReaderSettingsFactory) + public ControlHandler(IServerConfigurationManager config, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory) + : base(config, logger, xmlReaderSettingsFactory) { } } diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index bb475eb2c..b9d38504c 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -105,6 +105,7 @@ using MediaBrowser.Providers.Subtitles; using MediaBrowser.WebDashboard.Api; using MediaBrowser.XbmcMetadata.Providers; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; using ServiceStack; using ServiceStack.Text.Jsv; using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate; @@ -202,7 +203,7 @@ namespace Emby.Server.Implementations /// Gets all concrete types. /// /// All concrete types. - public Tuple[] AllConcreteTypes { get; protected set; } + public Type[] AllConcreteTypes { get; protected set; } /// /// The disposable parts @@ -219,8 +220,6 @@ namespace Emby.Server.Implementations protected IEnvironmentInfo EnvironmentInfo { get; set; } - private IBlurayExaminer BlurayExaminer { get; set; } - public PackageVersionClass SystemUpdateLevel { get @@ -232,12 +231,7 @@ namespace Emby.Server.Implementations } } - public virtual string OperatingSystemDisplayName => EnvironmentInfo.OperatingSystemName; - - /// - /// The container - /// - protected readonly SimpleInjector.Container Container = new SimpleInjector.Container(); + protected IServiceProvider _serviceProvider; /// /// Gets the server configuration manager. @@ -453,138 +447,58 @@ namespace Emby.Server.Implementations /// The name. public string Name => ApplicationProductName; - private static Tuple GetAssembly(Type type) - { - var assembly = type.GetTypeInfo().Assembly; - - return new Tuple(assembly, null); - } - - public virtual IStreamHelper CreateStreamHelper() - { - return new StreamHelper(); - } - /// - /// Creates an instance of type and resolves all constructor dependancies + /// Creates an instance of type and resolves all constructor dependencies /// /// The type. /// System.Object. public object CreateInstance(Type type) - { - return Container.GetInstance(type); - } + => ActivatorUtilities.CreateInstance(_serviceProvider, type); + + /// + /// Creates an instance of type and resolves all constructor dependencies + /// + /// The type. + /// System.Object. + public T CreateInstance() + => ActivatorUtilities.CreateInstance(_serviceProvider); /// /// Creates the instance safe. /// /// The type information. /// System.Object. - protected object CreateInstanceSafe(Tuple typeInfo) + protected object CreateInstanceSafe(Type type) { - var type = typeInfo.Item1; - try { - return Container.GetInstance(type); + return ActivatorUtilities.CreateInstance(_serviceProvider, type); } catch (Exception ex) { - Logger.LogError(ex, "Error creating {type}", type.FullName); + Logger.LogError(ex, "Error creating {Type}", type); // Don't blow up in release mode return null; } } - /// - /// Registers the specified obj. - /// - /// - /// The obj. - /// if set to true [manage lifetime]. - protected void RegisterSingleInstance(T obj, bool manageLifetime = true) - where T : class - { - Container.RegisterInstance(obj); - - if (manageLifetime) - { - var disposable = obj as IDisposable; - - if (disposable != null) - { - DisposableParts.Add(disposable); - } - } - } - - /// - /// Registers the single instance. - /// - /// - /// The func. - protected void RegisterSingleInstance(Func func) - where T : class - { - Container.RegisterSingleton(func); - } - - /// - /// Resolves this instance. - /// - /// - /// ``0. - public T Resolve() - { - return (T)Container.GetRegistration(typeof(T), true).GetInstance(); - } - /// /// Resolves this instance. /// /// /// ``0. - public T TryResolve() - { - var result = Container.GetRegistration(typeof(T), false); - - if (result == null) - { - return default(T); - } - return (T)result.GetInstance(); - } - - /// - /// Loads the assembly. - /// - /// The file. - /// Assembly. - protected Tuple LoadAssembly(string file) - { - try - { - var assembly = Assembly.Load(File.ReadAllBytes(file)); - - return new Tuple(assembly, file); - } - catch (Exception ex) - { - Logger.LogError(ex, "Error loading assembly {File}", file); - return null; - } - } + public T Resolve() => _serviceProvider.GetService(); /// /// Gets the export types. /// /// /// IEnumerable{Type}. - public IEnumerable> GetExportTypes() + public IEnumerable GetExportTypes() { var currentType = typeof(T); - return AllConcreteTypes.Where(i => currentType.IsAssignableFrom(i.Item1)); + return AllConcreteTypes.Where(i => currentType.IsAssignableFrom(i)); } /// @@ -596,7 +510,7 @@ namespace Emby.Server.Implementations public IEnumerable GetExports(bool manageLifetime = true) { var parts = GetExportTypes() - .Select(CreateInstanceSafe) + .Select(x => CreateInstanceSafe(x)) .Where(i => i != null) .Cast(); @@ -611,20 +525,16 @@ namespace Emby.Server.Implementations return parts; } - public List> GetExportsWithInfo(bool manageLifetime = true) + public List<(T, string)> GetExportsWithInfo(bool manageLifetime = true) { var parts = GetExportTypes() .Select(i => { var obj = CreateInstanceSafe(i); - if (obj == null) - { - return null; - } - return new Tuple((T)obj, i.Item2); + return ((T)obj, i.Assembly.Location); }) - .Where(i => i != null) + .Where(i => i.Item1 != null) .ToList(); if (manageLifetime) @@ -691,7 +601,7 @@ namespace Emby.Server.Implementations } } - public async Task Init() + public async Task Init(IServiceCollection serviceCollection) { HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber; HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber; @@ -721,7 +631,7 @@ namespace Emby.Server.Implementations SetHttpLimit(); - await RegisterResources(); + await RegisterResources(serviceCollection); FindParts(); } @@ -736,104 +646,104 @@ namespace Emby.Server.Implementations /// /// Registers resources that classes will depend on /// - protected async Task RegisterResources() + protected async Task RegisterResources(IServiceCollection serviceCollection) { - RegisterSingleInstance(ConfigurationManager); - RegisterSingleInstance(this); + serviceCollection.AddSingleton(ConfigurationManager); + serviceCollection.AddSingleton(this); - RegisterSingleInstance(ApplicationPaths); + serviceCollection.AddSingleton(ApplicationPaths); - RegisterSingleInstance(JsonSerializer); - RegisterSingleInstance(LoggerFactory, false); - RegisterSingleInstance(Logger); + serviceCollection.AddSingleton(JsonSerializer); - RegisterSingleInstance(EnvironmentInfo); + serviceCollection.AddSingleton(LoggerFactory); + serviceCollection.AddLogging(); + serviceCollection.AddSingleton(Logger); - RegisterSingleInstance(FileSystemManager); + serviceCollection.AddSingleton(EnvironmentInfo); + + serviceCollection.AddSingleton(FileSystemManager); HttpClient = CreateHttpClient(); - RegisterSingleInstance(HttpClient); + serviceCollection.AddSingleton(HttpClient); - RegisterSingleInstance(NetworkManager); + serviceCollection.AddSingleton(NetworkManager); IsoManager = new IsoManager(); - RegisterSingleInstance(IsoManager); + serviceCollection.AddSingleton(IsoManager); TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LoggerFactory, FileSystemManager); - RegisterSingleInstance(TaskManager); + serviceCollection.AddSingleton(TaskManager); - RegisterSingleInstance(XmlSerializer); + serviceCollection.AddSingleton(XmlSerializer); ProcessFactory = new ProcessFactory(); - RegisterSingleInstance(ProcessFactory); + serviceCollection.AddSingleton(ProcessFactory); - var streamHelper = CreateStreamHelper(); - ApplicationHost.StreamHelper = streamHelper; - RegisterSingleInstance(streamHelper); + ApplicationHost.StreamHelper = new StreamHelper(); + serviceCollection.AddSingleton(StreamHelper); - RegisterSingleInstance(CryptographyProvider); + serviceCollection.AddSingleton(CryptographyProvider); SocketFactory = new SocketFactory(); - RegisterSingleInstance(SocketFactory); + serviceCollection.AddSingleton(SocketFactory); InstallationManager = new InstallationManager(LoggerFactory, this, ApplicationPaths, HttpClient, JsonSerializer, ServerConfigurationManager, FileSystemManager, CryptographyProvider, PackageRuntime); - RegisterSingleInstance(InstallationManager); + serviceCollection.AddSingleton(InstallationManager); ZipClient = new ZipClient(FileSystemManager); - RegisterSingleInstance(ZipClient); + serviceCollection.AddSingleton(ZipClient); HttpResultFactory = new HttpResultFactory(LoggerFactory, FileSystemManager, JsonSerializer, CreateBrotliCompressor()); - RegisterSingleInstance(HttpResultFactory); + serviceCollection.AddSingleton(HttpResultFactory); - RegisterSingleInstance(this); - RegisterSingleInstance(ApplicationPaths); + serviceCollection.AddSingleton(this); + serviceCollection.AddSingleton(ApplicationPaths); - RegisterSingleInstance(ServerConfigurationManager); + serviceCollection.AddSingleton(ServerConfigurationManager); - IAssemblyInfo assemblyInfo = new AssemblyInfo(); - RegisterSingleInstance(assemblyInfo); + var assemblyInfo = new AssemblyInfo(); + serviceCollection.AddSingleton(assemblyInfo); LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer, LoggerFactory); await LocalizationManager.LoadAll(); - RegisterSingleInstance(LocalizationManager); + serviceCollection.AddSingleton(LocalizationManager); - BlurayExaminer = new BdInfoExaminer(FileSystemManager); - RegisterSingleInstance(BlurayExaminer); + serviceCollection.AddSingleton(new BdInfoExaminer(FileSystemManager)); - RegisterSingleInstance(new XmlReaderSettingsFactory()); + serviceCollection.AddSingleton(new XmlReaderSettingsFactory()); UserDataManager = new UserDataManager(LoggerFactory, ServerConfigurationManager, () => UserManager); - RegisterSingleInstance(UserDataManager); + serviceCollection.AddSingleton(UserDataManager); UserRepository = GetUserRepository(); // This is only needed for disposal purposes. If removing this, make sure to have the manager handle disposing it - RegisterSingleInstance(UserRepository); + serviceCollection.AddSingleton(UserRepository); var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LoggerFactory, JsonSerializer, ApplicationPaths, FileSystemManager); DisplayPreferencesRepository = displayPreferencesRepo; - RegisterSingleInstance(DisplayPreferencesRepository); + serviceCollection.AddSingleton(DisplayPreferencesRepository); ItemRepository = new SqliteItemRepository(ServerConfigurationManager, this, JsonSerializer, LoggerFactory, assemblyInfo); - RegisterSingleInstance(ItemRepository); + serviceCollection.AddSingleton(ItemRepository); AuthenticationRepository = GetAuthenticationRepository(); - RegisterSingleInstance(AuthenticationRepository); + serviceCollection.AddSingleton(AuthenticationRepository); UserManager = new UserManager(LoggerFactory, ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, this, JsonSerializer, FileSystemManager, CryptographyProvider); - RegisterSingleInstance(UserManager); + serviceCollection.AddSingleton(UserManager); LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager); - RegisterSingleInstance(LibraryManager); + serviceCollection.AddSingleton(LibraryManager); // TODO wtaylor: investigate use of second music manager var musicManager = new MusicManager(LibraryManager); - RegisterSingleInstance(new MusicManager(LibraryManager)); + serviceCollection.AddSingleton(new MusicManager(LibraryManager)); LibraryMonitor = new LibraryMonitor(LoggerFactory, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, EnvironmentInfo); - RegisterSingleInstance(LibraryMonitor); + serviceCollection.AddSingleton(LibraryMonitor); - RegisterSingleInstance(() => new SearchEngine(LoggerFactory, LibraryManager, UserManager)); + serviceCollection.AddSingleton(new SearchEngine(LoggerFactory, LibraryManager, UserManager)); CertificateInfo = GetCertificateInfo(true); Certificate = GetCertificate(CertificateInfo); @@ -848,81 +758,80 @@ namespace Emby.Server.Implementations GetParseFn); HttpServer.GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading"); - RegisterSingleInstance(HttpServer); + serviceCollection.AddSingleton(HttpServer); ImageProcessor = GetImageProcessor(); - RegisterSingleInstance(ImageProcessor); + serviceCollection.AddSingleton(ImageProcessor); TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager); - RegisterSingleInstance(TVSeriesManager); + serviceCollection.AddSingleton(TVSeriesManager); var encryptionManager = new EncryptionManager(); - RegisterSingleInstance(encryptionManager); + serviceCollection.AddSingleton(encryptionManager); DeviceManager = new DeviceManager(AuthenticationRepository, JsonSerializer, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager, LoggerFactory, NetworkManager); - RegisterSingleInstance(DeviceManager); + serviceCollection.AddSingleton(DeviceManager); MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory, JsonSerializer, FileSystemManager, UserDataManager, () => MediaEncoder); - RegisterSingleInstance(MediaSourceManager); + serviceCollection.AddSingleton(MediaSourceManager); SubtitleManager = new SubtitleManager(LoggerFactory, FileSystemManager, LibraryMonitor, MediaSourceManager, LocalizationManager); - RegisterSingleInstance(SubtitleManager); + serviceCollection.AddSingleton(SubtitleManager); ProviderManager = new ProviderManager(HttpClient, SubtitleManager, ServerConfigurationManager, LibraryMonitor, LoggerFactory, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer); - RegisterSingleInstance(ProviderManager); + serviceCollection.AddSingleton(ProviderManager); DtoService = new DtoService(LoggerFactory, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, this, () => DeviceManager, () => MediaSourceManager, () => LiveTvManager); - RegisterSingleInstance(DtoService); + serviceCollection.AddSingleton(DtoService); ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LoggerFactory, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient, ProviderManager); - RegisterSingleInstance(ChannelManager); + serviceCollection.AddSingleton(ChannelManager); SessionManager = new SessionManager(UserDataManager, LoggerFactory, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager); - RegisterSingleInstance(SessionManager); + serviceCollection.AddSingleton(SessionManager); - var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LoggerFactory, JsonSerializer, this, assemblyInfo); - RegisterSingleInstance(dlnaManager); + serviceCollection.AddSingleton(new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LoggerFactory, JsonSerializer, this, assemblyInfo)); CollectionManager = new CollectionManager(LibraryManager, ApplicationPaths, LocalizationManager, FileSystemManager, LibraryMonitor, LoggerFactory, ProviderManager); - RegisterSingleInstance(CollectionManager); + serviceCollection.AddSingleton(CollectionManager); PlaylistManager = new PlaylistManager(LibraryManager, FileSystemManager, LibraryMonitor, LoggerFactory, UserManager, ProviderManager); - RegisterSingleInstance(PlaylistManager); + serviceCollection.AddSingleton(PlaylistManager); LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, LoggerFactory, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, FileSystemManager, () => ChannelManager); - RegisterSingleInstance(LiveTvManager); + serviceCollection.AddSingleton(LiveTvManager); UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager); - RegisterSingleInstance(UserViewManager); + serviceCollection.AddSingleton(UserViewManager); NotificationManager = new NotificationManager(LoggerFactory, UserManager, ServerConfigurationManager); - RegisterSingleInstance(NotificationManager); + serviceCollection.AddSingleton(NotificationManager); - RegisterSingleInstance(new DeviceDiscovery(LoggerFactory, ServerConfigurationManager, SocketFactory)); + serviceCollection.AddSingleton(new DeviceDiscovery(LoggerFactory, ServerConfigurationManager, SocketFactory)); ChapterManager = new ChapterManager(LibraryManager, LoggerFactory, ServerConfigurationManager, ItemRepository); - RegisterSingleInstance(ChapterManager); + serviceCollection.AddSingleton(ChapterManager); - RegisterMediaEncoder(assemblyInfo); + RegisterMediaEncoder(serviceCollection); EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager); - RegisterSingleInstance(EncodingManager); + serviceCollection.AddSingleton(EncodingManager); var activityLogRepo = GetActivityLogRepository(); - RegisterSingleInstance(activityLogRepo); - RegisterSingleInstance(new ActivityManager(LoggerFactory, activityLogRepo, UserManager)); + serviceCollection.AddSingleton(activityLogRepo); + serviceCollection.AddSingleton(new ActivityManager(LoggerFactory, activityLogRepo, UserManager)); var authContext = new AuthorizationContext(AuthenticationRepository, UserManager); - RegisterSingleInstance(authContext); - RegisterSingleInstance(new SessionContext(UserManager, authContext, SessionManager)); + serviceCollection.AddSingleton(authContext); + serviceCollection.AddSingleton(new SessionContext(UserManager, authContext, SessionManager)); AuthService = new AuthService(UserManager, authContext, ServerConfigurationManager, SessionManager, NetworkManager); - RegisterSingleInstance(AuthService); + serviceCollection.AddSingleton(AuthService); SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(LibraryManager, LoggerFactory, ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, ProcessFactory); - RegisterSingleInstance(SubtitleEncoder); + serviceCollection.AddSingleton(SubtitleEncoder); - RegisterSingleInstance(CreateResourceFileManager()); + serviceCollection.AddSingleton(CreateResourceFileManager()); displayPreferencesRepo.Initialize(); @@ -935,6 +844,8 @@ namespace Emby.Server.Implementations ((UserDataManager)UserDataManager).Repository = userDataRepo; ItemRepository.Initialize(userDataRepo, UserManager); ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; + + _serviceProvider = serviceCollection.BuildServiceProvider(); } protected virtual IBrotliCompressor CreateBrotliCompressor() @@ -1066,7 +977,7 @@ namespace Emby.Server.Implementations /// Registers the media encoder. /// /// Task. - private void RegisterMediaEncoder(IAssemblyInfo assemblyInfo) + private void RegisterMediaEncoder(IServiceCollection serviceCollection) { string encoderPath = null; string probePath = null; @@ -1098,7 +1009,7 @@ namespace Emby.Server.Implementations 5000); MediaEncoder = mediaEncoder; - RegisterSingleInstance(MediaEncoder); + serviceCollection.AddSingleton(MediaEncoder); } /// @@ -1208,7 +1119,7 @@ namespace Emby.Server.Implementations IsoManager.AddParts(GetExports()); } - private IPlugin LoadPlugin(Tuple info) + private IPlugin LoadPlugin((IPlugin, string) info) { var plugin = info.Item1; var assemblyFilePath = info.Item2; @@ -1264,78 +1175,15 @@ namespace Emby.Server.Implementations { Logger.LogInformation("Loading assemblies"); - var assemblyInfos = GetComposablePartAssemblies(); - - foreach (var assemblyInfo in assemblyInfos) - { - var assembly = assemblyInfo.Item1; - var path = assemblyInfo.Item2; - - if (path == null) - { - Logger.LogInformation("Loading {assemblyName}", assembly.FullName); - } - else + AllConcreteTypes = GetComposablePartAssemblies() + .SelectMany(x => x.ExportedTypes) + .Where(type => { - Logger.LogInformation("Loading {assemblyName} from {path}", assembly.FullName, path); - } - } - - AllConcreteTypes = assemblyInfos - .SelectMany(GetTypes) - .Where(info => - { - var t = info.Item1; - return t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType; + return type.IsClass && !type.IsAbstract && !type.IsInterface && !type.IsGenericType; }) .ToArray(); } - /// - /// Gets a list of types within an assembly - /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference - /// - protected List> GetTypes(Tuple assemblyInfo) - { - if (assemblyInfo == null) - { - return new List>(); - } - - var assembly = assemblyInfo.Item1; - - try - { - // This null checking really shouldn't be needed but adding it due to some - // unhandled exceptions in mono 5.0 that are a little hard to hunt down - var types = assembly.GetTypes() ?? new Type[] { }; - return types.Where(t => t != null).Select(i => new Tuple(i, assemblyInfo.Item2)).ToList(); - } - catch (ReflectionTypeLoadException ex) - { - if (ex.LoaderExceptions != null) - { - foreach (var loaderException in ex.LoaderExceptions) - { - if (loaderException != null) - { - Logger.LogError("LoaderException: " + loaderException.Message); - } - } - } - - // If it fails we can still get a list of the Types it was able to resolve - var types = ex.Types ?? new Type[] { }; - return types.Where(t => t != null).Select(i => new Tuple(i, assemblyInfo.Item2)).ToList(); - } - catch (Exception ex) - { - Logger.LogError(ex, "Error loading types from assembly"); - - return new List>(); - } - } - private CertificateInfo CertificateInfo { get; set; } protected X509Certificate Certificate { get; private set; } @@ -1546,150 +1394,66 @@ namespace Emby.Server.Implementations /// Gets the composable part assemblies. /// /// IEnumerable{Assembly}. - protected List> GetComposablePartAssemblies() + protected IEnumerable GetComposablePartAssemblies() { - var list = GetPluginAssemblies(ApplicationPaths.PluginsPath); + if (Directory.Exists(ApplicationPaths.PluginsPath)) + { + foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly)) + { + Logger.LogInformation("Loading assembly {Path}", file); + yield return Assembly.LoadFile(file); + } + } // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that // This will prevent the .dll file from getting locked, and allow us to replace it when needed // Include composable parts in the Api assembly - list.Add(GetAssembly(typeof(ApiEntryPoint))); + yield return typeof(ApiEntryPoint).Assembly; // Include composable parts in the Dashboard assembly - list.Add(GetAssembly(typeof(DashboardService))); + yield return typeof(DashboardService).Assembly; // Include composable parts in the Model assembly - list.Add(GetAssembly(typeof(SystemInfo))); + yield return typeof(SystemInfo).Assembly; // Include composable parts in the Common assembly - list.Add(GetAssembly(typeof(IApplicationHost))); + yield return typeof(IApplicationHost).Assembly; // Include composable parts in the Controller assembly - list.Add(GetAssembly(typeof(IServerApplicationHost))); + yield return typeof(IServerApplicationHost).Assembly; // Include composable parts in the Providers assembly - list.Add(GetAssembly(typeof(ProviderUtils))); + yield return typeof(ProviderUtils).Assembly; // Include composable parts in the Photos assembly - list.Add(GetAssembly(typeof(PhotoProvider))); + yield return typeof(PhotoProvider).Assembly; // Emby.Server implementations - list.Add(GetAssembly(typeof(InstallationManager))); + yield return typeof(InstallationManager).Assembly; // MediaEncoding - list.Add(GetAssembly(typeof(MediaBrowser.MediaEncoding.Encoder.MediaEncoder))); + yield return typeof(MediaBrowser.MediaEncoding.Encoder.MediaEncoder).Assembly; // Dlna - list.Add(GetAssembly(typeof(DlnaEntryPoint))); + yield return typeof(DlnaEntryPoint).Assembly; // Local metadata - list.Add(GetAssembly(typeof(BoxSetXmlSaver))); + yield return typeof(BoxSetXmlSaver).Assembly; // Notifications - list.Add(GetAssembly(typeof(NotificationManager))); + yield return typeof(NotificationManager).Assembly; // Xbmc - list.Add(GetAssembly(typeof(ArtistNfoProvider))); + yield return typeof(ArtistNfoProvider).Assembly; - list.AddRange(GetAssembliesWithPartsInternal().Select(i => new Tuple(i, null))); - - return list.ToList(); - } - - protected abstract IEnumerable GetAssembliesWithPartsInternal(); - - private List> GetPluginAssemblies(string path) - { - try - { - return FilterAssembliesToLoad(Directory.EnumerateFiles(path, "*.dll", SearchOption.TopDirectoryOnly)) - .Select(LoadAssembly) - .Where(a => a != null) - .ToList(); - } - catch (DirectoryNotFoundException) + foreach (var i in GetAssembliesWithPartsInternal()) { - return new List>(); + yield return i; } } - private IEnumerable FilterAssembliesToLoad(IEnumerable paths) - { - - var exclude = new[] - { - "mbplus.dll", - "mbintros.dll", - "embytv.dll", - "Messenger.dll", - "Messages.dll", - "MediaBrowser.Plugins.TvMazeProvider.dll", - "MBBookshelf.dll", - "MediaBrowser.Channels.Adult.YouJizz.dll", - "MediaBrowser.Channels.Vine-co.dll", - "MediaBrowser.Plugins.Vimeo.dll", - "MediaBrowser.Channels.Vevo.dll", - "MediaBrowser.Plugins.Twitch.dll", - "MediaBrowser.Channels.SvtPlay.dll", - "MediaBrowser.Plugins.SoundCloud.dll", - "MediaBrowser.Plugins.SnesBox.dll", - "MediaBrowser.Plugins.RottenTomatoes.dll", - "MediaBrowser.Plugins.Revision3.dll", - "MediaBrowser.Plugins.NesBox.dll", - "MBChapters.dll", - "MediaBrowser.Channels.LeagueOfLegends.dll", - "MediaBrowser.Plugins.ADEProvider.dll", - "MediaBrowser.Channels.BallStreams.dll", - "MediaBrowser.Channels.Adult.Beeg.dll", - "ChannelDownloader.dll", - "Hamstercat.Emby.EmbyBands.dll", - "EmbyTV.dll", - "MediaBrowser.Channels.HitboxTV.dll", - "MediaBrowser.Channels.HockeyStreams.dll", - "MediaBrowser.Plugins.ITV.dll", - "MediaBrowser.Plugins.Lastfm.dll", - "ServerRestart.dll", - "MediaBrowser.Plugins.NotifyMyAndroidNotifications.dll", - "MetadataViewer.dll" - }; - - var minRequiredVersions = new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "moviethemesongs.dll", new Version(1, 6) }, - { "themesongs.dll", new Version(1, 2) } - }; - - return paths.Where(path => - { - var filename = Path.GetFileName(path); - if (exclude.Contains(filename ?? string.Empty, StringComparer.OrdinalIgnoreCase)) - { - return false; - } - - if (minRequiredVersions.TryGetValue(filename, out Version minRequiredVersion)) - { - try - { - var version = Version.Parse(FileVersionInfo.GetVersionInfo(path).FileVersion); - - if (version < minRequiredVersion) - { - Logger.LogInformation("Not loading {filename} {version} because the minimum supported version is {minRequiredVersion}. Please update to the newer version", filename, version, minRequiredVersion); - return false; - } - } - catch (Exception ex) - { - Logger.LogError(ex, "Error getting version number from {path}", path); - - return false; - } - } - return true; - }); - } + protected abstract IEnumerable GetAssembliesWithPartsInternal(); /// /// Gets the system status. @@ -1718,7 +1482,7 @@ namespace Emby.Server.Implementations SupportsHttps = SupportsHttps, HttpsPortNumber = HttpsPort, OperatingSystem = EnvironmentInfo.OperatingSystem.ToString(), - OperatingSystemDisplayName = OperatingSystemDisplayName, + OperatingSystemDisplayName = EnvironmentInfo.OperatingSystemName, CanSelfRestart = CanSelfRestart, CanSelfUpdate = CanSelfUpdate, CanLaunchWebBrowser = CanLaunchWebBrowser, @@ -1788,7 +1552,7 @@ namespace Emby.Server.Implementations public async Task GetWanApiUrl(CancellationToken cancellationToken) { - var url = "http://ipv4.icanhazip.com"; + const string url = "http://ipv4.icanhazip.com"; try { using (var response = await HttpClient.Get(new HttpRequestOptions diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 8356a9501..6bf776f53 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -22,9 +22,10 @@ + + - diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 7826fde35..2e6226b22 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -21,6 +21,7 @@ using MediaBrowser.Controller.Drawing; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.IO; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Serilog; using Serilog.AspNetCore; @@ -114,7 +115,7 @@ namespace Jellyfin.Server new NullImageEncoder(), new NetworkManager(_loggerFactory, environmentInfo))) { - await appHost.Init(); + await appHost.Init(new ServiceCollection()); appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager); diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs index 59e3c1767..6891152ee 100644 --- a/MediaBrowser.Common/IApplicationHost.cs +++ b/MediaBrowser.Common/IApplicationHost.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using MediaBrowser.Common.Plugins; using MediaBrowser.Model.Events; using MediaBrowser.Model.Updates; +using Microsoft.Extensions.DependencyInjection; namespace MediaBrowser.Common { @@ -13,12 +14,6 @@ namespace MediaBrowser.Common /// public interface IApplicationHost { - /// - /// Gets the display name of the operating system. - /// - /// The display name of the operating system. - string OperatingSystemDisplayName { get; } - /// /// Gets the name. /// @@ -104,13 +99,6 @@ namespace MediaBrowser.Common /// ``0. T Resolve(); - /// - /// Resolves this instance. - /// - /// - /// ``0. - T TryResolve(); - /// /// Shuts down. /// @@ -131,7 +119,7 @@ namespace MediaBrowser.Common /// /// Inits this instance. /// - Task Init(); + Task Init(IServiceCollection serviceCollection); /// /// Creates the instance. diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 2220d4661..715f4fccd 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -11,6 +11,10 @@ + + + + diff --git a/MediaBrowser.Model/System/PublicSystemInfo.cs b/MediaBrowser.Model/System/PublicSystemInfo.cs index accdc9e60..d97eda352 100644 --- a/MediaBrowser.Model/System/PublicSystemInfo.cs +++ b/MediaBrowser.Model/System/PublicSystemInfo.cs @@ -24,12 +24,12 @@ namespace MediaBrowser.Model.System /// Gets or sets the server version. /// /// The version. - public string Version { get; set; } + public string Version { get; set; } /// - /// Gets or sets the operating sytem. + /// Gets or sets the operating system. /// - /// The operating sytem. + /// The operating system. public string OperatingSystem { get; set; } /// diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index 26f735330..d9ed68b27 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -1,3 +1,4 @@ +using System; using System.Runtime.InteropServices; using MediaBrowser.Model.Updates; @@ -136,7 +137,7 @@ namespace MediaBrowser.Model.System /// public SystemInfo() { - CompletedInstallations = new InstallationInfo[] { }; + CompletedInstallations = Array.Empty(); } } } -- cgit v1.2.3 From 9af28607c990f5ddcd738c72d7183b9a57ba47c2 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 6 Feb 2019 14:04:32 +0100 Subject: Simplify plugin loading --- Emby.Server.Implementations/ApplicationHost.cs | 45 ++++++-------------------- Jellyfin.Server/CoreAppHost.cs | 4 ++- 2 files changed, 13 insertions(+), 36 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index b9d38504c..5dcf42aae 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -303,7 +303,6 @@ namespace Emby.Server.Implementations /// The user data repository. private IUserDataManager UserDataManager { get; set; } private IUserRepository UserRepository { get; set; } - internal IDisplayPreferencesRepository DisplayPreferencesRepository { get; set; } internal SqliteItemRepository ItemRepository { get; set; } private INotificationManager NotificationManager { get; set; } @@ -472,6 +471,7 @@ namespace Emby.Server.Implementations { try { + Logger.LogWarning("Creating instance of {Type}", type); return ActivatorUtilities.CreateInstance(_serviceProvider, type); } catch (Exception ex) @@ -525,29 +525,6 @@ namespace Emby.Server.Implementations return parts; } - public List<(T, string)> GetExportsWithInfo(bool manageLifetime = true) - { - var parts = GetExportTypes() - .Select(i => - { - var obj = CreateInstanceSafe(i); - - return ((T)obj, i.Assembly.Location); - }) - .Where(i => i.Item1 != null) - .ToList(); - - if (manageLifetime) - { - lock (DisposableParts) - { - DisposableParts.AddRange(parts.Select(i => i.Item1).OfType()); - } - } - - return parts; - } - /// /// Runs the startup tasks. /// @@ -721,8 +698,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(UserRepository); var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LoggerFactory, JsonSerializer, ApplicationPaths, FileSystemManager); - DisplayPreferencesRepository = displayPreferencesRepo; - serviceCollection.AddSingleton(DisplayPreferencesRepository); + serviceCollection.AddSingleton(displayPreferencesRepo); ItemRepository = new SqliteItemRepository(ServerConfigurationManager, this, JsonSerializer, LoggerFactory, assemblyInfo); serviceCollection.AddSingleton(ItemRepository); @@ -1085,7 +1061,10 @@ namespace Emby.Server.Implementations } ConfigurationManager.AddParts(GetExports()); - Plugins = GetExportsWithInfo().Select(LoadPlugin).Where(i => i != null).ToArray(); + Plugins = GetExports() + .Select(LoadPlugin) + .Where(i => i != null) + .ToArray(); HttpServer.Init(GetExports(false), GetExports()); @@ -1119,19 +1098,15 @@ namespace Emby.Server.Implementations IsoManager.AddParts(GetExports()); } - private IPlugin LoadPlugin((IPlugin, string) info) + private IPlugin LoadPlugin(IPlugin plugin) { - var plugin = info.Item1; - var assemblyFilePath = info.Item2; - try { - var assemblyPlugin = plugin as IPluginAssembly; - - if (assemblyPlugin != null) + if (plugin is IPluginAssembly assemblyPlugin) { var assembly = plugin.GetType().Assembly; var assemblyName = assembly.GetName(); + var assemblyFilePath = assembly.Location; var dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(assemblyFilePath)); @@ -1401,7 +1376,7 @@ namespace Emby.Server.Implementations foreach (var file in Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly)) { Logger.LogInformation("Loading assembly {Path}", file); - yield return Assembly.LoadFile(file); + yield return Assembly.LoadFrom(file); } } diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index 315e34a04..a486c2a47 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -21,7 +21,9 @@ namespace Jellyfin.Server protected override void RestartInternal() => Program.Restart(); protected override IEnumerable GetAssembliesWithPartsInternal() - => new[] { typeof(CoreAppHost).Assembly }; + { + yield return typeof(CoreAppHost).Assembly; + } protected override void ShutdownInternal() => Program.Shutdown(); -- cgit v1.2.3 From d409623086e210d9256ce0863f6fb8dad57e69ef Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 6 Feb 2019 17:41:38 +0100 Subject: Don't create multiple instances of the same type --- Emby.Server.Implementations/ApplicationHost.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 5dcf42aae..41ac4fcff 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -512,7 +512,8 @@ namespace Emby.Server.Implementations var parts = GetExportTypes() .Select(x => CreateInstanceSafe(x)) .Where(i => i != null) - .Cast(); + .Cast() + .ToList(); // Convert to list so this isn't executed for each iteration if (manageLifetime) { -- cgit v1.2.3 From c74028d08d4fcbd2a921423f5b2b6dea7012a11e Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Tue, 12 Feb 2019 20:50:47 +0100 Subject: Address comments --- Emby.Server.Implementations/ApplicationHost.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 41ac4fcff..784486d52 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -477,7 +477,6 @@ namespace Emby.Server.Implementations catch (Exception ex) { Logger.LogError(ex, "Error creating {Type}", type); - // Don't blow up in release mode return null; } } @@ -767,7 +766,8 @@ namespace Emby.Server.Implementations SessionManager = new SessionManager(UserDataManager, LoggerFactory, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager); serviceCollection.AddSingleton(SessionManager); - serviceCollection.AddSingleton(new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LoggerFactory, JsonSerializer, this, assemblyInfo)); + serviceCollection.AddSingleton( + new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LoggerFactory, JsonSerializer, this, assemblyInfo)); CollectionManager = new CollectionManager(LibraryManager, ApplicationPaths, LocalizationManager, FileSystemManager, LibraryMonitor, LoggerFactory, ProviderManager); serviceCollection.AddSingleton(CollectionManager); @@ -784,7 +784,8 @@ namespace Emby.Server.Implementations NotificationManager = new NotificationManager(LoggerFactory, UserManager, ServerConfigurationManager); serviceCollection.AddSingleton(NotificationManager); - serviceCollection.AddSingleton(new DeviceDiscovery(LoggerFactory, ServerConfigurationManager, SocketFactory)); + serviceCollection.AddSingleton( + new DeviceDiscovery(LoggerFactory, ServerConfigurationManager, SocketFactory)); ChapterManager = new ChapterManager(LibraryManager, LoggerFactory, ServerConfigurationManager, ItemRepository); serviceCollection.AddSingleton(ChapterManager); @@ -1381,9 +1382,6 @@ namespace Emby.Server.Implementations } } - // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that - // This will prevent the .dll file from getting locked, and allow us to replace it when needed - // Include composable parts in the Api assembly yield return typeof(ApiEntryPoint).Assembly; -- cgit v1.2.3 From a2dd2ddd55adc001bf3752dce6d4a95616e5dc4b Mon Sep 17 00:00:00 2001 From: ploughpuff <33969763+ploughpuff@users.noreply.github.com> Date: Wed, 13 Feb 2019 15:35:14 +0000 Subject: Rewrite rules for determining app paths and use XDG_CONFIG_HOME for configDir (#781) Re-write rules for determining dataDir, configDir and logDir. Generally, arguments from command line take precedence, then JELLYFIN env vars, before using XDG names. Co-Authored-By: ploughpuff <33969763+ploughpuff@users.noreply.github.com> --- .../AppBase/BaseApplicationPaths.cs | 103 +++---------- .../ServerApplicationPaths.cs | 15 +- Jellyfin.Server/Program.cs | 168 +++++++++++++-------- 3 files changed, 132 insertions(+), 154 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs index 701c04f9e..f26cc4f62 100644 --- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs +++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs @@ -1,3 +1,4 @@ +using System; using System.IO; using MediaBrowser.Common.Configuration; @@ -14,50 +15,44 @@ namespace Emby.Server.Implementations.AppBase /// protected BaseApplicationPaths( string programDataPath, - string appFolderPath, - string logDirectoryPath = null, - string configurationDirectoryPath = null, - string cacheDirectoryPath = null) + string logDirectoryPath, + string configurationDirectoryPath, + string cacheDirectoryPath) { ProgramDataPath = programDataPath; - ProgramSystemPath = appFolderPath; LogDirectoryPath = logDirectoryPath; ConfigurationDirectoryPath = configurationDirectoryPath; CachePath = cacheDirectoryPath; + + DataPath = Path.Combine(ProgramDataPath, "data"); } + /// + /// Gets the path to the program data folder + /// + /// The program data path. public string ProgramDataPath { get; private set; } /// /// Gets the path to the system folder /// - public string ProgramSystemPath { get; private set; } + public string ProgramSystemPath { get; } = AppContext.BaseDirectory; - /// - /// The _data directory - /// - private string _dataDirectory; /// /// Gets the folder path to the data directory /// /// The data directory. + private string _dataPath; public string DataPath { - get - { - if (_dataDirectory == null) - { - _dataDirectory = Path.Combine(ProgramDataPath, "data"); - - Directory.CreateDirectory(_dataDirectory); - } - - return _dataDirectory; - } + get => _dataPath; + private set => _dataPath = Directory.CreateDirectory(value).FullName; } - private const string _virtualDataPath = "%AppDataPath%"; - public string VirtualDataPath => _virtualDataPath; + /// + /// Gets the magic strings used for virtual path manipulation. + /// + public string VirtualDataPath { get; } = "%AppDataPath%"; /// /// Gets the image cache path. @@ -83,55 +78,17 @@ namespace Emby.Server.Implementations.AppBase /// The plugin configurations path. public string TempUpdatePath => Path.Combine(ProgramDataPath, "updates"); - /// - /// The _log directory - /// - private string _logDirectoryPath; - /// /// Gets the path to the log directory /// /// The log directory path. - public string LogDirectoryPath - { - get - { - if (string.IsNullOrEmpty(_logDirectoryPath)) - { - _logDirectoryPath = Path.Combine(ProgramDataPath, "logs"); - - Directory.CreateDirectory(_logDirectoryPath); - } - - return _logDirectoryPath; - } - set => _logDirectoryPath = value; - } - - /// - /// The _config directory - /// - private string _configurationDirectoryPath; + public string LogDirectoryPath { get; private set; } /// /// Gets the path to the application configuration root directory /// /// The configuration directory path. - public string ConfigurationDirectoryPath - { - get - { - if (string.IsNullOrEmpty(_configurationDirectoryPath)) - { - _configurationDirectoryPath = Path.Combine(ProgramDataPath, "config"); - - Directory.CreateDirectory(_configurationDirectoryPath); - } - - return _configurationDirectoryPath; - } - set => _configurationDirectoryPath = value; - } + public string ConfigurationDirectoryPath { get; private set; } /// /// Gets the path to the system configuration file @@ -139,29 +96,11 @@ namespace Emby.Server.Implementations.AppBase /// The system configuration file path. public string SystemConfigurationFilePath => Path.Combine(ConfigurationDirectoryPath, "system.xml"); - /// - /// The _cache directory - /// - private string _cachePath; /// /// Gets the folder path to the cache directory /// /// The cache directory. - public string CachePath - { - get - { - if (string.IsNullOrEmpty(_cachePath)) - { - _cachePath = Path.Combine(ProgramDataPath, "cache"); - - Directory.CreateDirectory(_cachePath); - } - - return _cachePath; - } - set => _cachePath = value; - } + public string CachePath { get; set; } /// /// Gets the folder path to the temp directory within the cache folder diff --git a/Emby.Server.Implementations/ServerApplicationPaths.cs b/Emby.Server.Implementations/ServerApplicationPaths.cs index 36975df50..05f6469ec 100644 --- a/Emby.Server.Implementations/ServerApplicationPaths.cs +++ b/Emby.Server.Implementations/ServerApplicationPaths.cs @@ -15,21 +15,17 @@ namespace Emby.Server.Implementations /// public ServerApplicationPaths( string programDataPath, - string appFolderPath, - string applicationResourcesPath, - string logDirectoryPath = null, - string configurationDirectoryPath = null, - string cacheDirectoryPath = null) + string logDirectoryPath, + string configurationDirectoryPath, + string cacheDirectoryPath) : base(programDataPath, - appFolderPath, logDirectoryPath, configurationDirectoryPath, cacheDirectoryPath) { - ApplicationResourcesPath = applicationResourcesPath; } - public string ApplicationResourcesPath { get; private set; } + public string ApplicationResourcesPath { get; } = AppContext.BaseDirectory; /// /// Gets the path to the base root media directory @@ -148,7 +144,6 @@ namespace Emby.Server.Implementations set => _internalMetadataPath = value; } - private const string _virtualInternalMetadataPath = "%MetadataPath%"; - public string VirtualInternalMetadataPath => _virtualInternalMetadataPath; + public string VirtualInternalMetadataPath { get; } = "%MetadataPath%"; } } diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 7826fde35..6d372c36f 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -139,112 +139,156 @@ namespace Jellyfin.Server } } + /// + /// 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% + /// for everything else the XDG approach is followed: + /// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html + /// + /// + /// ServerApplicationPaths private static ServerApplicationPaths CreateApplicationPaths(StartupOptions options) { - string programDataPath = Environment.GetEnvironmentVariable("JELLYFIN_DATA_PATH"); - if (string.IsNullOrEmpty(programDataPath)) + // dataDir + // IF --datadir + // ELSE IF $JELLYFIN_DATA_PATH + // ELSE IF windows, use <%APPDATA%>/jellyfin + // ELSE IF $XDG_DATA_HOME then use $XDG_DATA_HOME/jellyfin + // ELSE use $HOME/.local/share/jellyfin + var dataDir = options.DataDir; + + if (string.IsNullOrEmpty(dataDir)) { - if (options.DataDir != null) - { - programDataPath = options.DataDir; - } - else + dataDir = Environment.GetEnvironmentVariable("JELLYFIN_DATA_PATH"); + + if (string.IsNullOrEmpty(dataDir)) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - programDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + dataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); } else { // $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored. - programDataPath = Environment.GetEnvironmentVariable("XDG_DATA_HOME"); - // If $XDG_DATA_HOME is either not set or empty, $HOME/.local/share should be used. - if (string.IsNullOrEmpty(programDataPath)) + dataDir = Environment.GetEnvironmentVariable("XDG_DATA_HOME"); + + // If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used. + if (string.IsNullOrEmpty(dataDir)) { - programDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share"); + dataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share"); } } - programDataPath = Path.Combine(programDataPath, "jellyfin"); + dataDir = Path.Combine(dataDir, "jellyfin"); } } - if (string.IsNullOrEmpty(programDataPath)) - { - Console.WriteLine("Cannot continue without path to program data folder (try -programdata)"); - Environment.Exit(1); - } - else - { - Directory.CreateDirectory(programDataPath); - } + // configDir + // IF --configdir + // ELSE IF $JELLYFIN_CONFIG_DIR + // ELSE IF --datadir, use /config (assume portable run) + // ELSE IF /config exists, use that + // ELSE IF windows, use /config + // ELSE IF $XDG_CONFIG_HOME use $XDG_CONFIG_HOME/jellyfin + // ELSE $HOME/.config/jellyfin + var configDir = options.ConfigDir; - string configDir = Environment.GetEnvironmentVariable("JELLYFIN_CONFIG_DIR"); if (string.IsNullOrEmpty(configDir)) { - if (options.ConfigDir != null) - { - configDir = options.ConfigDir; - } - else + configDir = Environment.GetEnvironmentVariable("JELLYFIN_CONFIG_DIR"); + + if (string.IsNullOrEmpty(configDir)) { - // Let BaseApplicationPaths set up the default value - configDir = null; + if (options.DataDir != null || Directory.Exists(Path.Combine(dataDir, "config")) || RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Hang config folder off already set dataDir + configDir = Path.Combine(dataDir, "config"); + } + else + { + // $XDG_CONFIG_HOME defines the base directory relative to which user specific configuration files should be stored. + configDir = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME"); + + // If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME /.config should be used. + if (string.IsNullOrEmpty(configDir)) + { + configDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".config"); + } + + configDir = Path.Combine(configDir, "jellyfin"); + } } } - if (configDir != null) - { - Directory.CreateDirectory(configDir); - } + // cacheDir + // IF --cachedir + // ELSE IF $JELLYFIN_CACHE_DIR + // ELSE IF windows, use /cache + // ELSE IF XDG_CACHE_HOME, use $XDG_CACHE_HOME/jellyfin + // ELSE HOME/.cache/jellyfin + var cacheDir = options.CacheDir; - string cacheDir = Environment.GetEnvironmentVariable("JELLYFIN_CACHE_DIR"); if (string.IsNullOrEmpty(cacheDir)) { - if (options.CacheDir != null) - { - cacheDir = options.CacheDir; - } - else if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + cacheDir = Environment.GetEnvironmentVariable("JELLYFIN_CACHE_DIR"); + + if (string.IsNullOrEmpty(cacheDir)) { - // $XDG_CACHE_HOME defines the base directory relative to which user specific non-essential data files should be stored. - cacheDir = Environment.GetEnvironmentVariable("XDG_CACHE_HOME"); - // If $XDG_CACHE_HOME is either not set or empty, $HOME/.cache should be used. - if (string.IsNullOrEmpty(cacheDir)) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Hang cache folder off already set dataDir + cacheDir = Path.Combine(dataDir, "cache"); + } + else { - cacheDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".cache"); + // $XDG_CACHE_HOME defines the base directory relative to which user specific non-essential data files should be stored. + cacheDir = Environment.GetEnvironmentVariable("XDG_CACHE_HOME"); + + // If $XDG_CACHE_HOME is either not set or empty, a default equal to $HOME/.cache should be used. + if (string.IsNullOrEmpty(cacheDir)) + { + cacheDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".cache"); + } + + cacheDir = Path.Combine(cacheDir, "jellyfin"); } - cacheDir = Path.Combine(cacheDir, "jellyfin"); } } - if (cacheDir != null) - { - Directory.CreateDirectory(cacheDir); - } + // logDir + // IF --logdir + // ELSE IF $JELLYFIN_LOG_DIR + // ELSE IF --datadir, use /log (assume portable run) + // ELSE /log + var logDir = options.LogDir; - string logDir = Environment.GetEnvironmentVariable("JELLYFIN_LOG_DIR"); if (string.IsNullOrEmpty(logDir)) { - if (options.LogDir != null) - { - logDir = options.LogDir; - } - else + logDir = Environment.GetEnvironmentVariable("JELLYFIN_LOG_DIR"); + + if (string.IsNullOrEmpty(logDir)) { - // Let BaseApplicationPaths set up the default value - logDir = null; + // Hang log folder off already set dataDir + logDir = Path.Combine(dataDir, "log"); } } - if (logDir != null) + // Ensure the main folders exist before we continue + try { + Directory.CreateDirectory(dataDir); Directory.CreateDirectory(logDir); + Directory.CreateDirectory(configDir); + Directory.CreateDirectory(cacheDir); + } + catch (IOException ex) + { + Console.Error.WriteLine("Error whilst attempting to create folder"); + Console.Error.WriteLine(ex.ToString()); + Environment.Exit(1); } - string appPath = AppContext.BaseDirectory; - - return new ServerApplicationPaths(programDataPath, appPath, appPath, logDir, configDir, cacheDir); + return new ServerApplicationPaths(dataDir, logDir, configDir, cacheDir); } private static async Task CreateLogger(IApplicationPaths appPaths) -- cgit v1.2.3 From 21f0a7e020dab7b667559b8adc51a35147941d41 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Fri, 15 Feb 2019 23:05:14 +0100 Subject: Make all class implementing dynamically loaded interfaces public --- Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs | 2 +- Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs | 2 +- Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs | 2 +- Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs | 2 +- Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs | 2 +- Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs | 2 +- MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs | 2 +- MediaBrowser.Api/System/ActivityLogWebSocketListener.cs | 2 +- MediaBrowser.LocalMetadata/Providers/PlaylistXmlProvider.cs | 2 +- MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs | 2 +- MediaBrowser.Providers/Movies/MovieDbImageProvider.cs | 2 +- MediaBrowser.Providers/Music/MusicVideoMetadataService.cs | 2 +- MediaBrowser.Providers/Photos/PhotoAlbumMetadataService.cs | 2 +- MediaBrowser.Providers/Photos/PhotoMetadataService.cs | 2 +- MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs | 2 +- MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs | 2 +- MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs | 2 +- MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs b/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs index 844f77a1a..303a8ac7b 100644 --- a/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs +++ b/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs @@ -10,7 +10,7 @@ using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Channels { - class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask + public class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask { private readonly IChannelManager _channelManager; private readonly IUserManager _userManager; diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index 774ed09da..a5badacee 100644 --- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -14,7 +14,7 @@ using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.EntryPoints { - class UserDataChangeNotifier : IServerEntryPoint + public class UserDataChangeNotifier : IServerEntryPoint { private readonly ISessionManager _sessionManager; private readonly ILogger _logger; diff --git a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs index fa8c89e88..7e4b38b4c 100644 --- a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs @@ -9,7 +9,7 @@ using MediaBrowser.Model.IO; namespace Emby.Server.Implementations.Library.Resolvers { - class SpecialFolderResolver : FolderResolver + public class SpecialFolderResolver : FolderResolver { private readonly IFileSystem _fileSystem; private readonly IServerApplicationPaths _appPaths; diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs index 81fdb96d2..2f07ff15a 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs @@ -21,7 +21,7 @@ namespace Emby.Server.Implementations.ScheduledTasks /// /// Class ChapterImagesTask /// - class ChapterImagesTask : IScheduledTask + public class ChapterImagesTask : IScheduledTask { /// /// The _logger diff --git a/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs b/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs index 271188314..16507466f 100644 --- a/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs +++ b/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs @@ -6,7 +6,7 @@ using MediaBrowser.Model.Querying; namespace Emby.Server.Implementations.Sorting { - class AiredEpisodeOrderComparer : IBaseItemComparer + public class AiredEpisodeOrderComparer : IBaseItemComparer { /// /// Compares the specified x. diff --git a/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs b/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs index 942e84704..46e0dd918 100644 --- a/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs +++ b/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs @@ -5,7 +5,7 @@ using MediaBrowser.Model.Querying; namespace Emby.Server.Implementations.Sorting { - class SeriesSortNameComparer : IBaseItemComparer + public class SeriesSortNameComparer : IBaseItemComparer { /// /// Compares the specified x. diff --git a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs index 387ccad25..beb2fb11d 100644 --- a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs +++ b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Api.Session /// /// Class SessionInfoWebSocketListener /// - class SessionInfoWebSocketListener : BasePeriodicWebSocketListener, WebSocketListenerState> + public class SessionInfoWebSocketListener : BasePeriodicWebSocketListener, WebSocketListenerState> { /// /// Gets the name. diff --git a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs index 0df46c399..43f3c5a22 100644 --- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs +++ b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Api.System /// /// Class SessionInfoWebSocketListener /// - class ActivityLogWebSocketListener : BasePeriodicWebSocketListener, WebSocketListenerState> + public class ActivityLogWebSocketListener : BasePeriodicWebSocketListener, WebSocketListenerState> { /// /// Gets the name. diff --git a/MediaBrowser.LocalMetadata/Providers/PlaylistXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/PlaylistXmlProvider.cs index 4180a4f15..442a18cb9 100644 --- a/MediaBrowser.LocalMetadata/Providers/PlaylistXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/PlaylistXmlProvider.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.LocalMetadata.Providers { - class PlaylistXmlProvider : BaseXmlProvider + public class PlaylistXmlProvider : BaseXmlProvider { private readonly ILogger _logger; private readonly IProviderManager _providerManager; diff --git a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs index c6c1a2a94..4d12b2f4a 100644 --- a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs +++ b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs @@ -14,7 +14,7 @@ using MediaBrowser.Providers.Movies; namespace MediaBrowser.Providers.BoxSets { - class MovieDbBoxSetImageProvider : IRemoteImageProvider, IHasOrder + public class MovieDbBoxSetImageProvider : IRemoteImageProvider, IHasOrder { private readonly IHttpClient _httpClient; diff --git a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs index b9c5d7ce5..20b53d58a 100644 --- a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs @@ -16,7 +16,7 @@ using MediaBrowser.Model.Serialization; namespace MediaBrowser.Providers.Movies { - class MovieDbImageProvider : IRemoteImageProvider, IHasOrder + public class MovieDbImageProvider : IRemoteImageProvider, IHasOrder { private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; diff --git a/MediaBrowser.Providers/Music/MusicVideoMetadataService.cs b/MediaBrowser.Providers/Music/MusicVideoMetadataService.cs index 8b01ff342..93412306f 100644 --- a/MediaBrowser.Providers/Music/MusicVideoMetadataService.cs +++ b/MediaBrowser.Providers/Music/MusicVideoMetadataService.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Music { - class MusicVideoMetadataService : MetadataService + public class MusicVideoMetadataService : MetadataService { protected override void MergeData(MetadataResult source, MetadataResult target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings) { diff --git a/MediaBrowser.Providers/Photos/PhotoAlbumMetadataService.cs b/MediaBrowser.Providers/Photos/PhotoAlbumMetadataService.cs index fd969c7c2..993581cca 100644 --- a/MediaBrowser.Providers/Photos/PhotoAlbumMetadataService.cs +++ b/MediaBrowser.Providers/Photos/PhotoAlbumMetadataService.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Photos { - class PhotoAlbumMetadataService : MetadataService + public class PhotoAlbumMetadataService : MetadataService { protected override void MergeData(MetadataResult source, MetadataResult target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings) { diff --git a/MediaBrowser.Providers/Photos/PhotoMetadataService.cs b/MediaBrowser.Providers/Photos/PhotoMetadataService.cs index a430e1041..b739c5765 100644 --- a/MediaBrowser.Providers/Photos/PhotoMetadataService.cs +++ b/MediaBrowser.Providers/Photos/PhotoMetadataService.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Photos { - class PhotoMetadataService : MetadataService + public class PhotoMetadataService : MetadataService { protected override void MergeData(MetadataResult source, MetadataResult target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings) { diff --git a/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs b/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs index b28d2a548..30ce5c64c 100644 --- a/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs +++ b/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs @@ -11,7 +11,7 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Playlists { - class PlaylistMetadataService : MetadataService + public class PlaylistMetadataService : MetadataService { protected override IList GetChildrenForMetadataUpdates(Playlist item) { diff --git a/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs index d0749405b..dee3030af 100644 --- a/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs @@ -16,7 +16,7 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.TV.Omdb { - class OmdbEpisodeProvider : + public class OmdbEpisodeProvider : IRemoteMetadataProvider, IHasOrder { diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs index 44590515e..3d7745085 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs @@ -20,7 +20,7 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.TV.TheMovieDb { - class MovieDbEpisodeProvider : + public class MovieDbEpisodeProvider : MovieDbProviderBase, IRemoteMetadataProvider, IHasOrder diff --git a/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs index 21ee8f92f..a3e48d30d 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs @@ -13,7 +13,7 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.XbmcMetadata.Parsers { - class MovieNfoParser : BaseNfoParser