From 7986465cf785ca385fd1765326887e550bced033 Mon Sep 17 00:00:00 2001 From: Greenback Date: Sun, 6 Dec 2020 23:48:54 +0000 Subject: Initial upload --- Emby.Server.Implementations/Plugins/Active.png | Bin 0 -> 1422 bytes .../Plugins/Malfunction.png | Bin 0 -> 2091 bytes .../Plugins/NotSupported.png | Bin 0 -> 2046 bytes .../Plugins/PluginManager.cs | 674 +++++++++++++++++++++ .../Plugins/PluginManifest.cs | 60 -- .../Plugins/RestartRequired.png | Bin 0 -> 1996 bytes Emby.Server.Implementations/Plugins/Superceded.png | Bin 0 -> 2136 bytes Emby.Server.Implementations/Plugins/blank.png | Bin 0 -> 120 bytes Emby.Server.Implementations/Plugins/disabled.png | Bin 0 -> 1790 bytes 9 files changed, 674 insertions(+), 60 deletions(-) create mode 100644 Emby.Server.Implementations/Plugins/Active.png create mode 100644 Emby.Server.Implementations/Plugins/Malfunction.png create mode 100644 Emby.Server.Implementations/Plugins/NotSupported.png create mode 100644 Emby.Server.Implementations/Plugins/PluginManager.cs delete mode 100644 Emby.Server.Implementations/Plugins/PluginManifest.cs create mode 100644 Emby.Server.Implementations/Plugins/RestartRequired.png create mode 100644 Emby.Server.Implementations/Plugins/Superceded.png create mode 100644 Emby.Server.Implementations/Plugins/blank.png create mode 100644 Emby.Server.Implementations/Plugins/disabled.png (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/Active.png b/Emby.Server.Implementations/Plugins/Active.png new file mode 100644 index 000000000..3722ee520 Binary files /dev/null and b/Emby.Server.Implementations/Plugins/Active.png differ diff --git a/Emby.Server.Implementations/Plugins/Malfunction.png b/Emby.Server.Implementations/Plugins/Malfunction.png new file mode 100644 index 000000000..d4726150e Binary files /dev/null and b/Emby.Server.Implementations/Plugins/Malfunction.png differ diff --git a/Emby.Server.Implementations/Plugins/NotSupported.png b/Emby.Server.Implementations/Plugins/NotSupported.png new file mode 100644 index 000000000..a13c1f7c1 Binary files /dev/null and b/Emby.Server.Implementations/Plugins/NotSupported.png differ diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs new file mode 100644 index 000000000..8596dfcf8 --- /dev/null +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -0,0 +1,674 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.Json; +using MediaBrowser.Common; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Json; +using MediaBrowser.Common.Plugins; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Plugins; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace Emby.Server.Implementations +{ + /// + /// Defines the . + /// + public class PluginManager : IPluginManager + { + private const int OffsetFromTopRightCorner = 38; + + private readonly string _pluginsPath; + private readonly Version _appVersion; + private readonly JsonSerializerOptions _jsonOptions; + private readonly ILogger _logger; + private readonly IApplicationHost _appHost; + private readonly string _imagesPath; + private readonly ServerConfiguration _config; + private readonly IList _plugins; + private readonly Version _nextVersion; + private readonly Version _minimumVersion; + + /// + /// Initializes a new instance of the class. + /// + /// The . + /// The . + /// The . + /// The plugin path. + /// The image cache path. + /// The application version. + public PluginManager( + ILoggerFactory loggerfactory, + IApplicationHost appHost, + ServerConfiguration config, + string pluginsPath, + string imagesPath, + Version appVersion) + { + _logger = loggerfactory.CreateLogger(); + _pluginsPath = pluginsPath; + _appVersion = appVersion ?? throw new ArgumentNullException(nameof(appVersion)); + _jsonOptions = JsonDefaults.GetOptions(); + _jsonOptions.PropertyNameCaseInsensitive = true; + _jsonOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + _config = config; + _appHost = appHost; + _imagesPath = imagesPath; + _nextVersion = new Version(_appVersion.Major, _appVersion.Minor + 2, _appVersion.Build, _appVersion.Revision); + _minimumVersion = new Version(0, 0, 0, 1); + _plugins = Directory.Exists(_pluginsPath) ? DiscoverPlugins().ToList() : new List(); + } + + /// + /// Gets the Plugins. + /// + public IList Plugins => _plugins; + + /// + /// Returns all the assemblies. + /// + /// An IEnumerable{Assembly}. + public IEnumerable LoadAssemblies() + { + foreach (var plugin in _plugins) + { + foreach (var file in plugin.DllFiles) + { + try + { + plugin.Assembly = Assembly.LoadFrom(file); + } + catch (FileLoadException ex) + { + _logger.LogError(ex, "Failed to load assembly {Path}. Disabling plugin.", file); + ChangePluginState(plugin, PluginStatus.Malfunction); + continue; + } + + _logger.LogInformation("Loaded assembly {Assembly} from {Path}", plugin.Assembly.FullName, file); + yield return plugin.Assembly; + } + } + } + + /// + /// Creates all the plugin instances. + /// + public void CreatePlugins() + { + var createdPlugins = _appHost.GetExports(CreatePluginInstance) + .Where(i => i != null) + .ToArray(); + } + + /// + /// Registers the plugin's services with the DI. + /// Note: DI is not yet instantiated yet. + /// + /// A instance. + public void RegisterServices(IServiceCollection serviceCollection) + { + foreach (var pluginServiceRegistrator in _appHost.GetExportTypes()) + { + var plugin = GetPluginByType(pluginServiceRegistrator.Assembly.GetType()); + if (plugin == null) + { + throw new NullReferenceException(); + } + + CheckIfStillSuperceded(plugin); + if (!plugin.IsEnabledAndSupported) + { + continue; + } + + try + { + var instance = (IPluginServiceRegistrator?)Activator.CreateInstance(pluginServiceRegistrator); + instance?.RegisterServices(serviceCollection); + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception ex) +#pragma warning restore CA1031 // Do not catch general exception types + { + _logger.LogError(ex, "Error registering plugin services from {Assembly}.", pluginServiceRegistrator.Assembly.FullName); + if (ChangePluginState(plugin, PluginStatus.Malfunction)) + { + _logger.LogInformation("Disabling plugin {Path}", plugin.Path); + } + } + } + } + + /// + /// Imports a plugin manifest from . + /// + /// Folder of the plugin. + public void ImportPluginFrom(string folder) + { + if (string.IsNullOrEmpty(folder)) + { + throw new ArgumentNullException(nameof(folder)); + } + + // Load the plugin. + var plugin = LoadManifest(folder); + // Make sure we haven't already loaded this. + if (plugin == null || _plugins.Any(p => p.Manifest.Equals(plugin.Manifest))) + { + return; + } + + _plugins.Add(plugin); + EnablePlugin(plugin); + } + + /// + /// Removes the plugin reference '. + /// + /// The plugin. + /// Outcome of the operation. + public bool RemovePlugin(LocalPlugin plugin) + { + if (plugin == null) + { + throw new ArgumentNullException(nameof(plugin)); + } + + plugin.Instance?.OnUninstalling(); + + if (DeletePlugin(plugin)) + { + return true; + } + + // Unable to delete, so disable. + return ChangePluginState(plugin, PluginStatus.Disabled); + } + + /// + /// Attempts to find the plugin with and id of . + /// + /// Id of plugin. + /// The version of the plugin to locate. + /// A if found, otherwise null. + /// Boolean value signifying the success of the search. + public bool TryGetPlugin(Guid id, Version? version, out LocalPlugin? plugin) + { + if (version == null) + { + // If no version is given, return the largest version number. (This is for backwards compatibility). + plugin = _plugins.Where(p => p.Id.Equals(id)).OrderByDescending(p => p.Version).FirstOrDefault(); + } + else + { + plugin = _plugins.FirstOrDefault(p => p.Id.Equals(id) && p.Version.Equals(version)); + } + + return plugin != null; + } + + /// + /// Enables the plugin, disabling all other versions. + /// + /// The of the plug to disable. + public void EnablePlugin(LocalPlugin plugin) + { + if (plugin == null) + { + throw new ArgumentNullException(nameof(plugin)); + } + + if (ChangePluginState(plugin, PluginStatus.Active)) + { + UpdateSuccessors(plugin); + } + } + + /// + /// Disable the plugin. + /// + /// The of the plug to disable. + public void DisablePlugin(LocalPlugin plugin) + { + if (plugin == null) + { + throw new ArgumentNullException(nameof(plugin)); + } + + // Update the manifest on disk + if (ChangePluginState(plugin, PluginStatus.Disabled)) + { + UpdateSuccessors(plugin); + } + } + + /// + /// Changes the status of the other versions of the plugin to "Superceded". + /// + /// The that's master. + private void UpdateSuccessors(LocalPlugin plugin) + { + // This value is memory only - so that the web will show restart required. + plugin.Manifest.Status = PluginStatus.RestartRequired; + + // Detect whether there is another version of this plugin that needs disabling. + var predecessor = _plugins.OrderByDescending(p => p.Version) + .FirstOrDefault( + p => p.Id.Equals(plugin.Id) + && p.Name.Equals(plugin.Name, StringComparison.OrdinalIgnoreCase) + && p.IsEnabledAndSupported + && p.Version != plugin.Version); + + if (predecessor == null) + { + return; + } + + if (!ChangePluginState(predecessor, PluginStatus.Superceded)) + { + _logger.LogError("Unable to disable version {Version} of {Name}", predecessor.Version, predecessor.Name); + } + } + + /// + /// Disable the plugin. + /// + /// The of the plug to disable. + public void FailPlugin(Assembly assembly) + { + // Only save if disabled. + if (assembly == null) + { + throw new ArgumentNullException(nameof(assembly)); + } + + var plugin = _plugins.Where(p => assembly.Equals(p.Assembly)).FirstOrDefault(); + if (plugin == null) + { + // A plugin's assembly didn't cause this issue, so ignore it. + return; + } + + ChangePluginState(plugin, PluginStatus.Malfunction); + } + + /// + /// Saves the manifest back to disk. + /// + /// The to save. + /// The path where to save the manifest. + /// True if successful. + public bool SaveManifest(PluginManifest manifest, string path) + { + if (manifest == null) + { + return false; + } + + try + { + var data = JsonSerializer.Serialize(manifest, _jsonOptions); + File.WriteAllText(Path.Combine(path, "meta.json"), data, Encoding.UTF8); + return true; + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception e) +#pragma warning restore CA1031 // Do not catch general exception types + { + _logger.LogWarning(e, "Unable to save plugin manifest. {Path}", path); + return false; + } + } + + /// + /// Changes a plugin's load status. + /// + /// The instance. + /// The of the plugin. + /// Success of the task. + private bool ChangePluginState(LocalPlugin plugin, PluginStatus state) + { + if (plugin.Manifest.Status == state || string.IsNullOrEmpty(plugin.Path)) + { + // No need to save as the state hasn't changed. + return true; + } + + plugin.Manifest.Status = state; + SaveManifest(plugin.Manifest, plugin.Path); + try + { + var data = JsonSerializer.Serialize(plugin.Manifest, _jsonOptions); + File.WriteAllText(Path.Combine(plugin.Path, "meta.json"), data, Encoding.UTF8); + return true; + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception e) +#pragma warning restore CA1031 // Do not catch general exception types + { + _logger.LogWarning(e, "Unable to disable plugin {Path}", plugin.Path); + return false; + } + } + + /// + /// Finds the plugin record using the type. + /// + /// The being sought. + /// The matching record, or null if not found. + private LocalPlugin? GetPluginByType(Type type) + { + // Find which plugin it is by the path. + return _plugins.FirstOrDefault(p => string.Equals(p.Path, Path.GetDirectoryName(type.Assembly.Location), StringComparison.Ordinal)); + } + + /// + /// Creates the instance safe. + /// + /// The type. + /// System.Object. + private object? CreatePluginInstance(Type type) + { + // Find the record for this plugin. + var plugin = GetPluginByType(type); + + if (plugin != null) + { + CheckIfStillSuperceded(plugin); + + if (plugin.IsEnabledAndSupported == true) + { + _logger.LogInformation("Skipping disabled plugin {Version} of {Name} ", plugin.Version, plugin.Name); + return null; + } + } + + try + { + _logger.LogDebug("Creating instance of {Type}", type); + var instance = ActivatorUtilities.CreateInstance(_appHost.ServiceProvider, type); + if (plugin == null) + { + // Create a dummy record for the providers. + var pInstance = (IPlugin)instance; + plugin = new LocalPlugin( + pInstance.AssemblyFilePath, + true, + new PluginManifest + { + Guid = pInstance.Id, + Status = PluginStatus.Active, + Name = pInstance.Name, + Version = pInstance.Version.ToString(), + MaxAbi = _nextVersion.ToString() + }) + { + Instance = pInstance + }; + + _plugins.Add(plugin); + + plugin.Manifest.Status = PluginStatus.Active; + } + else + { + plugin.Instance = (IPlugin)instance; + var manifest = plugin.Manifest; + var pluginStr = plugin.Instance.Version.ToString(); + if (string.Equals(manifest.Version, pluginStr, StringComparison.Ordinal)) + { + // If a plugin without a manifest failed to load due to an external issue (eg config), + // this updates the manifest to the actual plugin values. + manifest.Version = pluginStr; + manifest.Name = plugin.Instance.Name; + manifest.Description = plugin.Instance.Description; + } + + manifest.Status = PluginStatus.Active; + SaveManifest(manifest, plugin.Path); + } + + _logger.LogInformation("Loaded plugin: {PluginName} {PluginVersion}", plugin.Name, plugin.Version); + + return instance; + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception ex) +#pragma warning restore CA1031 // Do not catch general exception types + { + _logger.LogError(ex, "Error creating {Type}", type.FullName); + if (plugin != null) + { + if (ChangePluginState(plugin, PluginStatus.Malfunction)) + { + _logger.LogInformation("Plugin {Path} has been disabled.", plugin.Path); + return null; + } + } + + _logger.LogDebug("Unable to auto-disable."); + return null; + } + } + + private void CheckIfStillSuperceded(LocalPlugin plugin) + { + if (plugin.Manifest.Status != PluginStatus.Superceded) + { + return; + } + + var predecessor = _plugins.OrderByDescending(p => p.Version) + .FirstOrDefault(p => p.Id.Equals(plugin.Id) && p.IsEnabledAndSupported && p.Version != plugin.Version); + if (predecessor != null) + { + return; + } + + plugin.Manifest.Status = PluginStatus.Active; + } + + /// + /// Attempts to delete a plugin. + /// + /// A instance to delete. + /// True if successful. + private bool DeletePlugin(LocalPlugin plugin) + { + // Attempt a cleanup of old folders. + try + { + _logger.LogDebug("Deleting {Path}", plugin.Path); + Directory.Delete(plugin.Path, true); + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception e) +#pragma warning restore CA1031 // Do not catch general exception types + { + _logger.LogWarning(e, "Unable to delete {Path}", plugin.Path); + return false; + } + + return _plugins.Remove(plugin); + } + + private LocalPlugin? LoadManifest(string dir) + { + try + { + Version? version; + PluginManifest? manifest = null; + var metafile = Path.Combine(dir, "meta.json"); + if (File.Exists(metafile)) + { + try + { + var data = File.ReadAllText(metafile, Encoding.UTF8); + manifest = JsonSerializer.Deserialize(data, _jsonOptions); + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception ex) +#pragma warning restore CA1031 // Do not catch general exception types + { + _logger.LogError(ex, "Error deserializing {Path}.", dir); + } + } + + if (manifest != null) + { + if (!Version.TryParse(manifest.TargetAbi, out var targetAbi)) + { + targetAbi = _minimumVersion; + } + + if (!Version.TryParse(manifest.MaxAbi, out var maxAbi)) + { + maxAbi = _appVersion; + } + + if (!Version.TryParse(manifest.Version, out version)) + { + manifest.Version = _minimumVersion.ToString(); + } + + return new LocalPlugin(dir, _appVersion >= targetAbi && _appVersion <= maxAbi, manifest); + } + + // No metafile, so lets see if the folder is versioned. + // TODO: Phase this support out in future versions. + metafile = dir.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)[^1]; + int versionIndex = dir.LastIndexOf('_'); + if (versionIndex != -1) + { + // Get the version number from the filename if possible. + metafile = Path.GetFileName(dir[..versionIndex]) ?? dir[..versionIndex]; + version = Version.TryParse(dir.AsSpan()[(versionIndex + 1)..], out Version? parsedVersion) ? parsedVersion : _appVersion; + } + else + { + // Un-versioned folder - Add it under the path name and version it suitable for this instance. + version = _appVersion; + } + + // Auto-create a plugin manifest, so we can disable it, if it fails to load. + // NOTE: This Plugin is marked as valid for two upgrades, at which point, it can be assumed the + // code base will have changed sufficiently to make it invalid. + manifest = new PluginManifest + { + Status = PluginStatus.RestartRequired, + Name = metafile, + AutoUpdate = false, + Guid = metafile.GetMD5(), + TargetAbi = _appVersion.ToString(), + MaxAbi = _nextVersion.ToString(), + Version = version.ToString() + }; + + return new LocalPlugin(dir, true, manifest); + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception ex) +#pragma warning restore CA1031 // Do not catch general exception types + { + _logger.LogError(ex, "Something went wrong!"); + return null; + } + } + + /// + /// Gets the list of local plugins. + /// + /// Enumerable of local plugins. + private IEnumerable DiscoverPlugins() + { + var versions = new List(); + + if (!Directory.Exists(_pluginsPath)) + { + // Plugin path doesn't exist, don't try to enumerate sub-folders. + return Enumerable.Empty(); + } + + var directories = Directory.EnumerateDirectories(_pluginsPath, "*.*", SearchOption.TopDirectoryOnly); + LocalPlugin? entry; + foreach (var dir in directories) + { + entry = LoadManifest(dir); + if (entry != null) + { + versions.Add(entry); + } + } + + string lastName = string.Empty; + versions.Sort(LocalPlugin.Compare); + // Traverse backwards through the list. + // The first item will be the latest version. + for (int x = versions.Count - 1; x >= 0; x--) + { + entry = versions[x]; + if (!string.Equals(lastName, entry.Name, StringComparison.OrdinalIgnoreCase)) + { + entry.DllFiles.AddRange(Directory.EnumerateFiles(entry.Path, "*.dll", SearchOption.AllDirectories)); + if (entry.IsEnabledAndSupported) + { + lastName = entry.Name; + continue; + } + } + + if (string.IsNullOrEmpty(lastName)) + { + continue; + } + + var manifest = entry.Manifest; + var cleaned = false; + var path = entry.Path; + if (_config.RemoveOldPlugins) + { + // Attempt a cleanup of old folders. + try + { + _logger.LogDebug("Deleting {Path}", path); + Directory.Delete(path, true); + cleaned = true; + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception e) +#pragma warning restore CA1031 // Do not catch general exception types + { + _logger.LogWarning(e, "Unable to delete {Path}", path); + } + + versions.RemoveAt(x); + } + + if (!cleaned) + { + if (manifest == null) + { + _logger.LogWarning("Unable to disable plugin {Path}", entry.Path); + continue; + } + + // Update the manifest so its not loaded next time. + manifest.Status = PluginStatus.Disabled; + SaveManifest(manifest, entry.Path); + } + } + + // Only want plugin folders which have files. + return versions.Where(p => p.DllFiles.Count != 0); + } + } +} diff --git a/Emby.Server.Implementations/Plugins/PluginManifest.cs b/Emby.Server.Implementations/Plugins/PluginManifest.cs deleted file mode 100644 index 33762791b..000000000 --- a/Emby.Server.Implementations/Plugins/PluginManifest.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; - -namespace Emby.Server.Implementations.Plugins -{ - /// - /// Defines a Plugin manifest file. - /// - public class PluginManifest - { - /// - /// Gets or sets the category of the plugin. - /// - public string Category { get; set; } - - /// - /// Gets or sets the changelog information. - /// - public string Changelog { get; set; } - - /// - /// Gets or sets the description of the plugin. - /// - public string Description { get; set; } - - /// - /// Gets or sets the Global Unique Identifier for the plugin. - /// - public Guid Guid { get; set; } - - /// - /// Gets or sets the Name of the plugin. - /// - public string Name { get; set; } - - /// - /// Gets or sets an overview of the plugin. - /// - public string Overview { get; set; } - - /// - /// Gets or sets the owner of the plugin. - /// - public string Owner { get; set; } - - /// - /// Gets or sets the compatibility version for the plugin. - /// - public string TargetAbi { get; set; } - - /// - /// Gets or sets the timestamp of the plugin. - /// - public DateTime Timestamp { get; set; } - - /// - /// Gets or sets the Version number of the plugin. - /// - public string Version { get; set; } - } -} diff --git a/Emby.Server.Implementations/Plugins/RestartRequired.png b/Emby.Server.Implementations/Plugins/RestartRequired.png new file mode 100644 index 000000000..65fd102a2 Binary files /dev/null and b/Emby.Server.Implementations/Plugins/RestartRequired.png differ diff --git a/Emby.Server.Implementations/Plugins/Superceded.png b/Emby.Server.Implementations/Plugins/Superceded.png new file mode 100644 index 000000000..251e70535 Binary files /dev/null and b/Emby.Server.Implementations/Plugins/Superceded.png differ diff --git a/Emby.Server.Implementations/Plugins/blank.png b/Emby.Server.Implementations/Plugins/blank.png new file mode 100644 index 000000000..f81ae3243 Binary files /dev/null and b/Emby.Server.Implementations/Plugins/blank.png differ diff --git a/Emby.Server.Implementations/Plugins/disabled.png b/Emby.Server.Implementations/Plugins/disabled.png new file mode 100644 index 000000000..eeb8ffefc Binary files /dev/null and b/Emby.Server.Implementations/Plugins/disabled.png differ -- cgit v1.2.3 From a246a77ada21466587eb7fe02cc50033ab91c2e3 Mon Sep 17 00:00:00 2001 From: Greenback Date: Mon, 14 Dec 2020 23:08:04 +0000 Subject: Delete plugin working. --- .../Plugins/PluginManager.cs | 51 ++++++++++++++-------- Jellyfin.Api/Controllers/PackageController.cs | 3 -- Jellyfin.Api/Controllers/PluginsController.cs | 32 ++++++-------- MediaBrowser.Model/Plugins/PluginStatus.cs | 3 +- 4 files changed, 48 insertions(+), 41 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 8596dfcf8..1377c80ea 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -78,8 +78,27 @@ namespace Emby.Server.Implementations /// An IEnumerable{Assembly}. public IEnumerable LoadAssemblies() { + // Attempt to remove any deleted plugins and change any successors to be active. + for (int a = _plugins.Count - 1; a >= 0; a--) + { + var plugin = _plugins[a]; + if (plugin.Manifest.Status == PluginStatus.DeleteOnStartup && DeletePlugin(plugin)) + { + UpdateSuccessors(plugin); + } + } + + // Now load the assemblies.. foreach (var plugin in _plugins) { + CheckIfStillSuperceded(plugin); + + if (plugin.IsEnabledAndSupported == false) + { + _logger.LogInformation("Skipping disabled plugin {Version} of {Name} ", plugin.Version, plugin.Name); + continue; + } + foreach (var file in plugin.DllFiles) { try @@ -183,15 +202,13 @@ namespace Emby.Server.Implementations throw new ArgumentNullException(nameof(plugin)); } - plugin.Instance?.OnUninstalling(); - if (DeletePlugin(plugin)) { return true; } // Unable to delete, so disable. - return ChangePluginState(plugin, PluginStatus.Disabled); + return ChangePluginState(plugin, PluginStatus.DeleteOnStartup); } /// @@ -205,11 +222,18 @@ namespace Emby.Server.Implementations { if (version == null) { - // If no version is given, return the largest version number. (This is for backwards compatibility). - plugin = _plugins.Where(p => p.Id.Equals(id)).OrderByDescending(p => p.Version).FirstOrDefault(); + // If no version is given, return the current instance. + var plugins = _plugins.Where(p => p.Id.Equals(id)); + + plugin = plugins.FirstOrDefault(p => p.Instance != null); + if (plugin == null) + { + plugin = plugins.OrderByDescending(p => p.Version).FirstOrDefault(); + } } else { + // Match id and version number. plugin = _plugins.FirstOrDefault(p => p.Id.Equals(id) && p.Version.Equals(version)); } @@ -264,7 +288,6 @@ namespace Emby.Server.Implementations var predecessor = _plugins.OrderByDescending(p => p.Version) .FirstOrDefault( p => p.Id.Equals(plugin.Id) - && p.Name.Equals(plugin.Name, StringComparison.OrdinalIgnoreCase) && p.IsEnabledAndSupported && p.Version != plugin.Version); @@ -381,17 +404,6 @@ namespace Emby.Server.Implementations // Find the record for this plugin. var plugin = GetPluginByType(type); - if (plugin != null) - { - CheckIfStillSuperceded(plugin); - - if (plugin.IsEnabledAndSupported == true) - { - _logger.LogInformation("Skipping disabled plugin {Version} of {Name} ", plugin.Version, plugin.Name); - return null; - } - } - try { _logger.LogDebug("Creating instance of {Type}", type); @@ -489,6 +501,7 @@ namespace Emby.Server.Implementations { _logger.LogDebug("Deleting {Path}", plugin.Path); Directory.Delete(plugin.Path, true); + _plugins.Remove(plugin); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) @@ -661,8 +674,8 @@ namespace Emby.Server.Implementations continue; } - // Update the manifest so its not loaded next time. - manifest.Status = PluginStatus.Disabled; + manifest.Status = PluginStatus.DeleteOnStartup; + SaveManifest(manifest, entry.Path); } } diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs index 622a0fe00..d139159aa 100644 --- a/Jellyfin.Api/Controllers/PackageController.cs +++ b/Jellyfin.Api/Controllers/PackageController.cs @@ -46,7 +46,6 @@ namespace Jellyfin.Api.Controllers /// A containing package information. [HttpGet("Packages/{name}")] [ProducesResponseType(StatusCodes.Status200OK)] - [Produces(JsonDefaults.CamelCaseMediaType)] public async Task> GetPackageInfo( [FromRoute, Required] string name, [FromQuery] Guid? assemblyGuid) @@ -73,7 +72,6 @@ namespace Jellyfin.Api.Controllers /// An containing available packages information. [HttpGet("Packages")] [ProducesResponseType(StatusCodes.Status200OK)] - [Produces(JsonDefaults.CamelCaseMediaType)] public async Task> GetPackages() { IEnumerable packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); @@ -148,7 +146,6 @@ namespace Jellyfin.Api.Controllers /// An containing the list of package repositories. [HttpGet("Repositories")] [ProducesResponseType(StatusCodes.Status200OK)] - [Produces(JsonDefaults.CamelCaseMediaType)] public ActionResult> GetRepositories() { return _serverConfigurationManager.Configuration.PluginRepositories; diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index 3f366dd79..d7a67389d 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -14,7 +14,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Json; using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Updates; -using MediaBrowser.Controller.Drawing; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Net; using MediaBrowser.Model.Plugins; @@ -130,7 +129,7 @@ namespace Jellyfin.Api.Controllers /// Plugin enabled. /// Plugin not found. /// An on success, or a if the file could not be found. - [HttpPost("{pluginId}/Enable")] + [HttpPost("{pluginId}/{version}/Enable")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] @@ -153,7 +152,7 @@ namespace Jellyfin.Api.Controllers /// Plugin disabled. /// Plugin not found. /// An on success, or a if the file could not be found. - [HttpPost("{pluginId}/Disable")] + [HttpPost("{pluginId}/{version}/Disable")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] @@ -176,11 +175,11 @@ namespace Jellyfin.Api.Controllers /// Plugin uninstalled. /// Plugin not found. /// An on success, or a if the file could not be found. - [HttpDelete("{pluginId}")] + [HttpDelete("{pluginId}/{version}")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult UninstallPlugin([FromRoute, Required] Guid pluginId, Version version) + public ActionResult UninstallPlugin([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version) { if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin)) { @@ -195,7 +194,6 @@ namespace Jellyfin.Api.Controllers /// Gets plugin configuration. /// /// Plugin id. - /// Plugin version. /// Plugin configuration returned. /// Plugin not found or plugin configuration not found. /// Plugin configuration. @@ -203,9 +201,9 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesFile(MediaTypeNames.Application.Json)] - public ActionResult GetPluginConfiguration([FromRoute, Required] Guid pluginId, [FromRoute] Version? version) + public ActionResult GetPluginConfiguration([FromRoute, Required] Guid pluginId) { - if (_pluginManager.TryGetPlugin(pluginId, version, out var plugin) + if (_pluginManager.TryGetPlugin(pluginId, null, out var plugin) && plugin!.Instance is IHasPluginConfiguration configPlugin) { return configPlugin.Configuration; @@ -221,7 +219,6 @@ namespace Jellyfin.Api.Controllers /// Accepts plugin configuration as JSON body. /// /// Plugin id. - /// Plugin version. /// Plugin configuration updated. /// Plugin not found or plugin does not have configuration. /// @@ -232,9 +229,9 @@ namespace Jellyfin.Api.Controllers [HttpPost("{pluginId}/Configuration")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task UpdatePluginConfiguration([FromRoute, Required] Guid pluginId, [FromRoute] Version? version) + public async Task UpdatePluginConfiguration([FromRoute, Required] Guid pluginId) { - if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin) + if (!_pluginManager.TryGetPlugin(pluginId, null, out var plugin) || plugin?.Instance is not IHasPluginConfiguration configPlugin) { return NotFound(); @@ -258,12 +255,12 @@ namespace Jellyfin.Api.Controllers /// Plugin version. /// Plugin image returned. /// Plugin's image. - [HttpGet("{pluginId}/Image")] + [HttpGet("{pluginId}/{version}/Image")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesImageFile] [AllowAnonymous] - public ActionResult GetPluginImage([FromRoute, Required] Guid pluginId, [FromRoute] Version? version) + public ActionResult GetPluginImage([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version) { if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin)) { @@ -292,12 +289,12 @@ namespace Jellyfin.Api.Controllers /// Plugin version. /// Plugin image returned. /// Plugin's image. - [HttpGet("{pluginId}/StatusImage")] + [HttpGet("{pluginId}/{version}/StatusImage")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesImageFile] [AllowAnonymous] - public ActionResult GetPluginStatusImage([FromRoute, Required] Guid pluginId, [FromRoute] Version? version) + public ActionResult GetPluginStatusImage([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version) { if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin)) { @@ -316,7 +313,6 @@ namespace Jellyfin.Api.Controllers /// Gets a plugin's manifest. /// /// Plugin id. - /// Plugin version. /// Plugin manifest returned. /// Plugin not found. /// @@ -328,9 +324,9 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesFile(MediaTypeNames.Application.Json)] - public ActionResult GetPluginManifest([FromRoute, Required] Guid pluginId, [FromRoute] Version? version) + public ActionResult GetPluginManifest([FromRoute, Required] Guid pluginId) { - if (_pluginManager.TryGetPlugin(pluginId, version, out var plugin)) + if (_pluginManager.TryGetPlugin(pluginId, null, out var plugin)) { return Ok(plugin!.Manifest); } diff --git a/MediaBrowser.Model/Plugins/PluginStatus.cs b/MediaBrowser.Model/Plugins/PluginStatus.cs index 439968ba8..a953206e8 100644 --- a/MediaBrowser.Model/Plugins/PluginStatus.cs +++ b/MediaBrowser.Model/Plugins/PluginStatus.cs @@ -12,6 +12,7 @@ namespace MediaBrowser.Model.Plugins Disabled = -1, NotSupported = -2, Malfunction = -3, - Superceded = -4 + Superceded = -4, + DeleteOnStartup = -5 } } -- cgit v1.2.3 From fbb20ebef6dee03de27e20d7e110e709ba2f20e9 Mon Sep 17 00:00:00 2001 From: Greenback Date: Tue, 15 Dec 2020 00:42:59 +0000 Subject: Plugin setting migration to folders. --- Emby.Server.Implementations/ApplicationHost.cs | 5 +-- .../Plugins/PluginManager.cs | 11 ++++-- MediaBrowser.Common/Plugins/BasePlugin.cs | 42 ++++++++++++++++++++-- 3 files changed, 50 insertions(+), 8 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8df1ec300..ddb48ff6e 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -406,10 +406,7 @@ namespace Emby.Server.Implementations Logger.LogError("Called from: {stack}", entry.FullName); } - if (type is IPlugin) - { - _pluginManager.FailPlugin(type.Assembly); - } + _pluginManager.FailPlugin(type.Assembly); throw new ExternalException("DI Loop detected."); } diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 1377c80ea..07b729748 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -296,7 +296,7 @@ namespace Emby.Server.Implementations return; } - if (!ChangePluginState(predecessor, PluginStatus.Superceded)) + if (predecessor.Manifest.Status == PluginStatus.Active && !ChangePluginState(predecessor, PluginStatus.Superceded)) { _logger.LogError("Unable to disable version {Version} of {Name}", predecessor.Version, predecessor.Name); } @@ -314,7 +314,10 @@ namespace Emby.Server.Implementations throw new ArgumentNullException(nameof(assembly)); } - var plugin = _plugins.Where(p => assembly.Equals(p.Assembly)).FirstOrDefault(); + var plugin = _plugins.Where( + p => assembly.Equals(p.Assembly) + || string.Equals(assembly.Location, assembly.Location, StringComparison.OrdinalIgnoreCase)) + .FirstOrDefault(); if (plugin == null) { // A plugin's assembly didn't cause this issue, so ignore it. @@ -403,6 +406,10 @@ namespace Emby.Server.Implementations { // Find the record for this plugin. var plugin = GetPluginByType(type); + if (plugin?.Manifest.Status < PluginStatus.Active) + { + return null; + } try { diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index b918fc4f6..a0d6b8f83 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -134,7 +134,26 @@ namespace MediaBrowser.Common.Plugins var assemblyName = assembly.GetName(); var assemblyFilePath = assembly.Location; - var dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(assemblyFilePath)); + // Find out the plugin folder. + bool inPluginFolder = assemblyFilePath.StartsWith(ApplicationPaths.PluginsPath, StringComparison.OrdinalIgnoreCase); + string path, dataFolderPath; + + var configurationFileName = Path.ChangeExtension(Path.GetFileName(assemblyFilePath), ".xml"); + if (inPluginFolder) + { + // Normal plugin. + path = assemblyFilePath.Substring(ApplicationPaths.PluginsPath.Length).Split('\\', StringSplitOptions.RemoveEmptyEntries)[0]; + dataFolderPath = Path.Combine( + Path.Combine(ApplicationPaths.PluginsPath, path), + configurationFileName); + ConfigurationFilePath = dataFolderPath; + } + else + { + // Provider + dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(assemblyFilePath)); + ConfigurationFilePath = Path.Combine(ApplicationPaths.PluginConfigurationsPath, configurationFileName); + } assemblyPlugin.SetAttributes(assemblyFilePath, dataFolderPath, assemblyName.Version); @@ -146,6 +165,25 @@ namespace MediaBrowser.Common.Plugins assemblyPlugin.SetId(assemblyId); } + + // TODO : Simplify this, once migration support is ceased. + if (inPluginFolder) + { + var oldConfigFilePath = Path.Combine(ApplicationPaths.PluginConfigurationsPath, ConfigurationFileName); + + if (!File.Exists(ConfigurationFilePath) && File.Exists(oldConfigFilePath)) + { + // Migrate settings, as different plugin versions may have different settings. + try + { + File.Copy(oldConfigFilePath, ConfigurationFilePath); + } + catch + { + // Unable to migrate settings. + } + } + } } if (this is IHasPluginConfiguration hasPluginConfiguration) @@ -219,7 +257,7 @@ namespace MediaBrowser.Common.Plugins /// Gets the full path to the configuration file. /// /// The configuration file path. - public string ConfigurationFilePath => Path.Combine(ApplicationPaths.PluginConfigurationsPath, ConfigurationFileName); + public string ConfigurationFilePath { get; } /// /// Gets the plugin configuration. -- cgit v1.2.3 From 2bb12793b29dc078b3f1597afc4ab8e366f098a7 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 15 Dec 2020 01:31:56 +0000 Subject: Add files via upload --- Emby.Server.Implementations/Plugins/Disabled.png | Bin 0 -> 1790 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Emby.Server.Implementations/Plugins/Disabled.png (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/Disabled.png b/Emby.Server.Implementations/Plugins/Disabled.png new file mode 100644 index 000000000..eeb8ffefc Binary files /dev/null and b/Emby.Server.Implementations/Plugins/Disabled.png differ -- cgit v1.2.3 From 3cff64ee320b94ec915ba96d52d946701c1a7ff1 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 15 Dec 2020 01:32:43 +0000 Subject: Delete disabled.png Should have a capital letter --- Emby.Server.Implementations/Plugins/disabled.png | Bin 1790 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Emby.Server.Implementations/Plugins/disabled.png (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/disabled.png b/Emby.Server.Implementations/Plugins/disabled.png deleted file mode 100644 index eeb8ffefc..000000000 Binary files a/Emby.Server.Implementations/Plugins/disabled.png and /dev/null differ -- cgit v1.2.3 From dddcfa6dbbca04ed69597ec335007612e2e2b8e8 Mon Sep 17 00:00:00 2001 From: Greenback Date: Tue, 15 Dec 2020 09:29:51 +0000 Subject: Suggested changes. --- Emby.Server.Implementations/ApplicationHost.cs | 3 +- .../Emby.Server.Implementations.csproj | 7 --- Emby.Server.Implementations/Plugins/Active.png | Bin 1422 -> 0 bytes Emby.Server.Implementations/Plugins/Disabled.png | Bin 1790 -> 0 bytes .../Plugins/Malfunction.png | Bin 2091 -> 0 bytes .../Plugins/NotSupported.png | Bin 2046 -> 0 bytes .../Plugins/PluginManager.cs | 3 -- .../Plugins/RestartRequired.png | Bin 1996 -> 0 bytes Emby.Server.Implementations/Plugins/Superceded.png | Bin 2136 -> 0 bytes Emby.Server.Implementations/Plugins/blank.png | Bin 120 -> 0 bytes Jellyfin.Api/Controllers/PluginsController.cs | 60 +++++++++++---------- 11 files changed, 32 insertions(+), 41 deletions(-) delete mode 100644 Emby.Server.Implementations/Plugins/Active.png delete mode 100644 Emby.Server.Implementations/Plugins/Disabled.png delete mode 100644 Emby.Server.Implementations/Plugins/Malfunction.png delete mode 100644 Emby.Server.Implementations/Plugins/NotSupported.png delete mode 100644 Emby.Server.Implementations/Plugins/RestartRequired.png delete mode 100644 Emby.Server.Implementations/Plugins/Superceded.png delete mode 100644 Emby.Server.Implementations/Plugins/blank.png (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 404e28bdc..17cccdaf9 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -393,8 +393,7 @@ namespace Emby.Server.Implementations if (_creatingInstances.IndexOf(type) != -1) { - Logger.LogError("DI Loop detected."); - Logger.LogError("Attempted creation of {Type}", type.FullName); + Logger.LogError("DI Loop detected in the attempted creation of {Type}", type.FullName); foreach (var entry in _creatingInstances) { Logger.LogError("Called from: {stack}", entry.FullName); diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 7e0be7899..0c94f937c 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -73,12 +73,5 @@ - - - - - - - diff --git a/Emby.Server.Implementations/Plugins/Active.png b/Emby.Server.Implementations/Plugins/Active.png deleted file mode 100644 index 3722ee520..000000000 Binary files a/Emby.Server.Implementations/Plugins/Active.png and /dev/null differ diff --git a/Emby.Server.Implementations/Plugins/Disabled.png b/Emby.Server.Implementations/Plugins/Disabled.png deleted file mode 100644 index eeb8ffefc..000000000 Binary files a/Emby.Server.Implementations/Plugins/Disabled.png and /dev/null differ diff --git a/Emby.Server.Implementations/Plugins/Malfunction.png b/Emby.Server.Implementations/Plugins/Malfunction.png deleted file mode 100644 index d4726150e..000000000 Binary files a/Emby.Server.Implementations/Plugins/Malfunction.png and /dev/null differ diff --git a/Emby.Server.Implementations/Plugins/NotSupported.png b/Emby.Server.Implementations/Plugins/NotSupported.png deleted file mode 100644 index a13c1f7c1..000000000 Binary files a/Emby.Server.Implementations/Plugins/NotSupported.png and /dev/null differ diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 07b729748..cf25ccf48 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -1,7 +1,6 @@ #nullable enable using System; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; using System.Reflection; @@ -23,8 +22,6 @@ namespace Emby.Server.Implementations /// public class PluginManager : IPluginManager { - private const int OffsetFromTopRightCorner = 38; - private readonly string _pluginsPath; private readonly Version _appVersion; private readonly JsonSerializerOptions _jsonOptions; diff --git a/Emby.Server.Implementations/Plugins/RestartRequired.png b/Emby.Server.Implementations/Plugins/RestartRequired.png deleted file mode 100644 index 65fd102a2..000000000 Binary files a/Emby.Server.Implementations/Plugins/RestartRequired.png and /dev/null differ diff --git a/Emby.Server.Implementations/Plugins/Superceded.png b/Emby.Server.Implementations/Plugins/Superceded.png deleted file mode 100644 index 251e70535..000000000 Binary files a/Emby.Server.Implementations/Plugins/Superceded.png and /dev/null differ diff --git a/Emby.Server.Implementations/Plugins/blank.png b/Emby.Server.Implementations/Plugins/blank.png deleted file mode 100644 index f81ae3243..000000000 Binary files a/Emby.Server.Implementations/Plugins/blank.png and /dev/null differ diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index 36e37b7ad..c84dc6a13 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -167,7 +167,7 @@ namespace Jellyfin.Api.Controllers } /// - /// Uninstalls a plugin. + /// Uninstalls a plugin by version. /// /// Plugin id. /// Plugin version. @@ -178,7 +178,7 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult UninstallPlugin([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version) + public ActionResult UninstallPluginByVersion([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version) { if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin)) { @@ -189,6 +189,35 @@ namespace Jellyfin.Api.Controllers return NoContent(); } + /// + /// Uninstalls a plugin. + /// + /// Plugin id. + /// Plugin uninstalled. + /// Plugin not found. + /// An on success, or a if the file could not be found. + [HttpDelete("{pluginId}")] + [Authorize(Policy = Policies.RequiresElevation)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [Obsolete("Please use the UninstallByVersion API.")] + public ActionResult UninstallPlugin([FromRoute, Required] Guid pluginId) + { + // If no version is given, return the current instance. + var plugins = _pluginManager.Plugins.Where(p => p.Id.Equals(pluginId)); + + // Select the un-instanced one first. + var plugin = plugins.FirstOrDefault(p => p.Instance != null); + if (plugin == null) + { + // Then by the status. + plugin = plugins.OrderBy(p => p.Manifest.Status).FirstOrDefault(); + } + + _installationManager.UninstallPlugin(plugin!); + return NoContent(); + } + /// /// Gets plugin configuration. /// @@ -281,33 +310,6 @@ namespace Jellyfin.Api.Controllers return PhysicalFile(imgPath, MimeTypes.GetMimeType(imgPath)); } - /// - /// Gets a plugin's status image. - /// - /// Plugin id. - /// Plugin version. - /// Plugin image returned. - /// Plugin's image. - [HttpGet("{pluginId}/{version}/StatusImage")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesImageFile] - [AllowAnonymous] - public ActionResult GetPluginStatusImage([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version) - { - if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin)) - { - return NotFound(); - } - - // Icons from http://www.fatcow.com/free-icons - var status = plugin!.Manifest.Status; - - var type = _pluginManager.GetType(); - var stream = type.Assembly.GetManifestResourceStream($"{type.Namespace}.Plugins.{status}.png"); - return File(stream, "image/png"); - } - /// /// Gets a plugin's manifest. /// -- cgit v1.2.3 From 208d545cfefd5ce7a2092f4ac669e58cae115d37 Mon Sep 17 00:00:00 2001 From: Greenback Date: Tue, 15 Dec 2020 10:05:04 +0000 Subject: Changed as suggested. --- .../Plugins/PluginManager.cs | 27 ++++++++++-------- .../Updates/InstallationManager.cs | 3 +- Jellyfin.Api/Controllers/PluginsController.cs | 2 +- MediaBrowser.Common/Json/JsonDefaults.cs | 1 + MediaBrowser.Model/Plugins/PluginStatus.cs | 33 ++++++++++++++++++++-- 5 files changed, 50 insertions(+), 16 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index cf25ccf48..010d2829c 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -53,9 +53,7 @@ namespace Emby.Server.Implementations _logger = loggerfactory.CreateLogger(); _pluginsPath = pluginsPath; _appVersion = appVersion ?? throw new ArgumentNullException(nameof(appVersion)); - _jsonOptions = JsonDefaults.GetOptions(); - _jsonOptions.PropertyNameCaseInsensitive = true; - _jsonOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + _jsonOptions = JsonDefaults.GetCamelCaseOptions(); _config = config; _appHost = appHost; _imagesPath = imagesPath; @@ -137,7 +135,8 @@ namespace Emby.Server.Implementations var plugin = GetPluginByType(pluginServiceRegistrator.Assembly.GetType()); if (plugin == null) { - throw new NullReferenceException(); + _logger.LogError("Unable to find plugin in assembly {Assembly}", pluginServiceRegistrator.Assembly.FullName); + continue; } CheckIfStillSuperceded(plugin); @@ -440,6 +439,7 @@ namespace Emby.Server.Implementations plugin.Instance = (IPlugin)instance; var manifest = plugin.Manifest; var pluginStr = plugin.Instance.Version.ToString(); + bool changed = false; if (string.Equals(manifest.Version, pluginStr, StringComparison.Ordinal)) { // If a plugin without a manifest failed to load due to an external issue (eg config), @@ -447,10 +447,16 @@ namespace Emby.Server.Implementations manifest.Version = pluginStr; manifest.Name = plugin.Instance.Name; manifest.Description = plugin.Instance.Description; + changed = true; } + changed = changed || manifest.Status != PluginStatus.Active; manifest.Status = PluginStatus.Active; - SaveManifest(manifest, plugin.Path); + + if (changed) + { + SaveManifest(manifest, plugin.Path); + } } _logger.LogInformation("Loaded plugin: {PluginName} {PluginVersion}", plugin.Name, plugin.Version); @@ -577,8 +583,6 @@ namespace Emby.Server.Implementations } // Auto-create a plugin manifest, so we can disable it, if it fails to load. - // NOTE: This Plugin is marked as valid for two upgrades, at which point, it can be assumed the - // code base will have changed sufficiently to make it invalid. manifest = new PluginManifest { Status = PluginStatus.RestartRequired, @@ -586,7 +590,6 @@ namespace Emby.Server.Implementations AutoUpdate = false, Guid = metafile.GetMD5(), TargetAbi = _appVersion.ToString(), - MaxAbi = _nextVersion.ToString(), Version = version.ToString() }; @@ -678,9 +681,11 @@ namespace Emby.Server.Implementations continue; } - manifest.Status = PluginStatus.DeleteOnStartup; - - SaveManifest(manifest, entry.Path); + if (manifest.Status != PluginStatus.DeleteOnStartup) + { + manifest.Status = PluginStatus.DeleteOnStartup; + SaveManifest(manifest, entry.Path); + } } } diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 75a9ca080..b7bbbd348 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -93,8 +93,7 @@ namespace Emby.Server.Implementations.Updates _httpClientFactory = httpClientFactory; _config = config; _zipClient = zipClient; - _jsonSerializerOptions = JsonDefaults.GetOptions(); - _jsonSerializerOptions.PropertyNameCaseInsensitive = true; + _jsonSerializerOptions = JsonDefaults.GetCamelCaseOptions(); _pluginManager = pluginManager; } diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index c84dc6a13..eb6b770d6 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -47,7 +47,7 @@ namespace Jellyfin.Api.Controllers { _installationManager = installationManager; _pluginManager = pluginManager; - _serializerOptions = JsonDefaults.GetOptions(); + _serializerOptions = JsonDefaults.GetCamelCaseOptions(); _config = config; } diff --git a/MediaBrowser.Common/Json/JsonDefaults.cs b/MediaBrowser.Common/Json/JsonDefaults.cs index b76edd2bc..50393b909 100644 --- a/MediaBrowser.Common/Json/JsonDefaults.cs +++ b/MediaBrowser.Common/Json/JsonDefaults.cs @@ -56,6 +56,7 @@ namespace MediaBrowser.Common.Json { var options = GetOptions(); options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + options.PropertyNameCaseInsensitive = true; return options; } diff --git a/MediaBrowser.Model/Plugins/PluginStatus.cs b/MediaBrowser.Model/Plugins/PluginStatus.cs index a953206e8..2acc56811 100644 --- a/MediaBrowser.Model/Plugins/PluginStatus.cs +++ b/MediaBrowser.Model/Plugins/PluginStatus.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member -#pragma warning disable SA1602 // Enumeration items should be documented namespace MediaBrowser.Model.Plugins { /// @@ -7,12 +5,43 @@ namespace MediaBrowser.Model.Plugins /// public enum PluginStatus { + /// + /// This plugin requires a restart in order for it to load. This is a memory only status. + /// The actual status of the plugin after reload is present in the manifest. + /// eg. A disabled plugin will still be active until the next restart, and so will have a memory status of RestartRequired, + /// but a disk manifest status of Disabled. + /// RestartRequired = 1, + + /// + /// This plugin is currently running. + /// Active = 0, + + /// + /// This plugin has been marked as disabled. + /// Disabled = -1, + + /// + /// This plugin does not meet the TargetAbi / MaxAbi requirements. + /// NotSupported = -2, + + /// + /// This plugin caused an error when instantiated. (Either DI loop, or exception) + /// Malfunction = -3, + + /// + /// This plugin has been superceded by another version. + /// Superceded = -4, + + /// + /// An attempt to remove this plugin from disk will happen at every restart. + /// It will not be loaded, if unable to do so. + /// DeleteOnStartup = -5 } } -- cgit v1.2.3 From eb2439f23b05a9b92a81ee96c7801d10ccfbb25d Mon Sep 17 00:00:00 2001 From: Greenback Date: Tue, 15 Dec 2020 16:37:11 +0000 Subject: Changes as recommended. --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- .../Plugins/PluginManager.cs | 59 +++++++++------------- .../Updates/InstallationManager.cs | 15 +----- Jellyfin.Api/Controllers/PackageController.cs | 2 - MediaBrowser.Common/Plugins/LocalPlugin.cs | 5 -- MediaBrowser.Model/Updates/PackageInfo.cs | 9 ++++ 6 files changed, 35 insertions(+), 57 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 17cccdaf9..216cb5e75 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -396,7 +396,7 @@ namespace Emby.Server.Implementations Logger.LogError("DI Loop detected in the attempted creation of {Type}", type.FullName); foreach (var entry in _creatingInstances) { - Logger.LogError("Called from: {stack}", entry.FullName); + Logger.LogError("Called from: {TypeName}", entry.FullName); } _pluginManager.FailPlugin(type.Assembly); diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 010d2829c..944b74652 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -96,9 +96,10 @@ namespace Emby.Server.Implementations foreach (var file in plugin.DllFiles) { + Assembly assembly; try { - plugin.Assembly = Assembly.LoadFrom(file); + assembly = Assembly.LoadFrom(file); } catch (FileLoadException ex) { @@ -107,8 +108,8 @@ namespace Emby.Server.Implementations continue; } - _logger.LogInformation("Loaded assembly {Assembly} from {Path}", plugin.Assembly.FullName, file); - yield return plugin.Assembly; + _logger.LogInformation("Loaded assembly {Assembly} from {Path}", assembly.FullName, file); + yield return assembly; } } } @@ -203,6 +204,7 @@ namespace Emby.Server.Implementations return true; } + _logger.LogWarning("Unable to delete {Path}, so marking as deleteOnStartup.", plugin.Path); // Unable to delete, so disable. return ChangePluginState(plugin, PluginStatus.DeleteOnStartup); } @@ -310,10 +312,7 @@ namespace Emby.Server.Implementations throw new ArgumentNullException(nameof(assembly)); } - var plugin = _plugins.Where( - p => assembly.Equals(p.Assembly) - || string.Equals(assembly.Location, assembly.Location, StringComparison.OrdinalIgnoreCase)) - .FirstOrDefault(); + var plugin = _plugins.Where(p => p.DllFiles.Contains(assembly.Location)).FirstOrDefault(); if (plugin == null) { // A plugin's assembly didn't cause this issue, so ignore it. @@ -366,20 +365,7 @@ namespace Emby.Server.Implementations } plugin.Manifest.Status = state; - SaveManifest(plugin.Manifest, plugin.Path); - try - { - var data = JsonSerializer.Serialize(plugin.Manifest, _jsonOptions); - File.WriteAllText(Path.Combine(plugin.Path, "meta.json"), data, Encoding.UTF8); - return true; - } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception e) -#pragma warning restore CA1031 // Do not catch general exception types - { - _logger.LogWarning(e, "Unable to disable plugin {Path}", plugin.Path); - return false; - } + return SaveManifest(plugin.Manifest, plugin.Path); } /// @@ -509,15 +495,14 @@ namespace Emby.Server.Implementations // Attempt a cleanup of old folders. try { - _logger.LogDebug("Deleting {Path}", plugin.Path); Directory.Delete(plugin.Path, true); + _logger.LogDebug("Deleted {Path}", plugin.Path); _plugins.Remove(plugin); } #pragma warning disable CA1031 // Do not catch general exception types - catch (Exception e) + catch #pragma warning restore CA1031 // Do not catch general exception types { - _logger.LogWarning(e, "Unable to delete {Path}", plugin.Path); return false; } @@ -670,21 +655,23 @@ namespace Emby.Server.Implementations _logger.LogWarning(e, "Unable to delete {Path}", path); } - versions.RemoveAt(x); - } - - if (!cleaned) - { - if (manifest == null) + if (cleaned) { - _logger.LogWarning("Unable to disable plugin {Path}", entry.Path); - continue; + versions.RemoveAt(x); } - - if (manifest.Status != PluginStatus.DeleteOnStartup) + else { - manifest.Status = PluginStatus.DeleteOnStartup; - SaveManifest(manifest, entry.Path); + if (manifest == null) + { + _logger.LogWarning("Unable to disable plugin {Path}", entry.Path); + continue; + } + + if (manifest.Status != PluginStatus.DeleteOnStartup) + { + manifest.Status = PluginStatus.DeleteOnStartup; + SaveManifest(manifest, entry.Path); + } } } } diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index b7bbbd348..fc80bdd75 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Net.Http; using System.Net.Http.Json; using System.Security.Cryptography; -using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -106,18 +105,8 @@ namespace Emby.Server.Implementations.Updates try { List? packages; - var uri = new Uri(manifest); - if (uri.Scheme.StartsWith("http", StringComparison.OrdinalIgnoreCase)) - { - packages = await _httpClientFactory.CreateClient(NamedClient.Default) - .GetFromJsonAsync>(uri, _jsonSerializerOptions, cancellationToken).ConfigureAwait(false); - } - else - { - // Local Packages - var data = File.ReadAllText(manifest, Encoding.UTF8); - packages = JsonSerializer.Deserialize>(data, _jsonSerializerOptions); - } + packages = await _httpClientFactory.CreateClient(NamedClient.Default) + .GetFromJsonAsync>(new Uri(manifest), _jsonSerializerOptions, cancellationToken).ConfigureAwait(false); if (packages == null) { diff --git a/Jellyfin.Api/Controllers/PackageController.cs b/Jellyfin.Api/Controllers/PackageController.cs index 906188026..9ab8e0bdc 100644 --- a/Jellyfin.Api/Controllers/PackageController.cs +++ b/Jellyfin.Api/Controllers/PackageController.cs @@ -44,7 +44,6 @@ namespace Jellyfin.Api.Controllers /// A containing package information. [HttpGet("Packages/{name}")] [ProducesResponseType(StatusCodes.Status200OK)] - [Produces(JsonDefaults.CamelCaseMediaType)] public async Task> GetPackageInfo( [FromRoute, Required] string name, [FromQuery] Guid? assemblyGuid) @@ -71,7 +70,6 @@ namespace Jellyfin.Api.Controllers /// An containing available packages information. [HttpGet("Packages")] [ProducesResponseType(StatusCodes.Status200OK)] - [Produces(JsonDefaults.CamelCaseMediaType)] public async Task> GetPackages() { IEnumerable packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); diff --git a/MediaBrowser.Common/Plugins/LocalPlugin.cs b/MediaBrowser.Common/Plugins/LocalPlugin.cs index ef9ab7a7d..e48ebbfa5 100644 --- a/MediaBrowser.Common/Plugins/LocalPlugin.cs +++ b/MediaBrowser.Common/Plugins/LocalPlugin.cs @@ -80,11 +80,6 @@ namespace MediaBrowser.Common.Plugins /// public PluginManifest Manifest { get; } - /// - /// Gets or sets a value indicating the assembly of the plugin. - /// - public Assembly? Assembly { get; set; } - /// /// Compare two . /// diff --git a/MediaBrowser.Model/Updates/PackageInfo.cs b/MediaBrowser.Model/Updates/PackageInfo.cs index 77e2d8d88..63fd71742 100644 --- a/MediaBrowser.Model/Updates/PackageInfo.cs +++ b/MediaBrowser.Model/Updates/PackageInfo.cs @@ -1,6 +1,7 @@ #nullable enable using System; using System.Collections.Generic; +using System.Text.Json.Serialization; namespace MediaBrowser.Model.Updates { @@ -27,30 +28,35 @@ namespace MediaBrowser.Model.Updates /// Gets or sets the name. /// /// The name. + [JsonPropertyName("name")] public string Name { get; set; } /// /// Gets or sets a long description of the plugin containing features or helpful explanations. /// /// The description. + /// [JsonPropertyName("description")] public string Description { get; set; } /// /// Gets or sets a short overview of what the plugin does. /// /// The overview. + [JsonPropertyName("overview")] public string Overview { get; set; } /// /// Gets or sets the owner. /// /// The owner. + [JsonPropertyName("owner")] public string Owner { get; set; } /// /// Gets or sets the category. /// /// The category. + [JsonPropertyName("category")] public string Category { get; set; } /// @@ -58,6 +64,7 @@ namespace MediaBrowser.Model.Updates /// This is used to identify the proper item for automatic updates. /// /// The name. + [JsonPropertyName("guid")] #pragma warning disable CA1720 // Identifier contains type name public string Guid { get; set; } #pragma warning restore CA1720 // Identifier contains type name @@ -66,6 +73,7 @@ namespace MediaBrowser.Model.Updates /// Gets or sets the versions. /// /// The versions. + [JsonPropertyName("versions")] #pragma warning disable CA2227 // Collection properties should be read only public IList Versions { get; set; } #pragma warning restore CA2227 // Collection properties should be read only @@ -73,6 +81,7 @@ namespace MediaBrowser.Model.Updates /// /// Gets or sets the image url for the package. /// + [JsonPropertyName("imageUrl")] public string? ImageUrl { get; set; } } } -- cgit v1.2.3 From 532388754053957a1b3066900b7b54e1894206f3 Mon Sep 17 00:00:00 2001 From: Greenback Date: Tue, 15 Dec 2020 20:27:42 +0000 Subject: Replaced TryGetPlugin with GetPlugin --- .../Plugins/PluginManager.cs | 13 +++++---- .../Updates/InstallationManager.cs | 5 ++-- Jellyfin.Api/Controllers/PluginsController.cs | 34 +++++++++++++--------- MediaBrowser.Common/Plugins/IPluginManager.cs | 5 ++-- 4 files changed, 32 insertions(+), 25 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 944b74652..26a029f71 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -212,12 +212,13 @@ namespace Emby.Server.Implementations /// /// Attempts to find the plugin with and id of . /// - /// Id of plugin. - /// The version of the plugin to locate. - /// A if found, otherwise null. - /// Boolean value signifying the success of the search. - public bool TryGetPlugin(Guid id, Version? version, out LocalPlugin? plugin) + /// The of plugin. + /// Optional of the plugin to locate. + /// A if located, or null if not. + public LocalPlugin? GetPlugin(Guid id, Version? version = null) { + LocalPlugin? plugin; + if (version == null) { // If no version is given, return the current instance. @@ -235,7 +236,7 @@ namespace Emby.Server.Implementations plugin = _plugins.FirstOrDefault(p => p.Id.Equals(id) && p.Version.Equals(version)); } - return plugin != null; + return plugin; } /// diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index fc80bdd75..7cab77c85 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -197,10 +197,11 @@ namespace Emby.Server.Implementations.Updates { var version = package.Versions[i]; + var plugin = _pluginManager.GetPlugin(packageGuid, version.VersionNumber); // Update the manifests, if anything changes. - if (_pluginManager.TryGetPlugin(packageGuid, version.VersionNumber, out LocalPlugin? plugin)) + if (plugin != null) { - bool noChange = string.Equals(plugin!.Manifest.MaxAbi, version.MaxAbi, StringComparison.Ordinal) + bool noChange = string.Equals(plugin.Manifest.MaxAbi, version.MaxAbi, StringComparison.Ordinal) || string.Equals(plugin.Manifest.TargetAbi, version.TargetAbi, StringComparison.Ordinal); if (!noChange) { diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index b5976fbbd..49ccac137 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -134,12 +134,13 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult EnablePlugin([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version) { - if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin)) + var plugin = _pluginManager.GetPlugin(pluginId, version); + if (plugin == null) { return NotFound(); } - _pluginManager.EnablePlugin(plugin!); + _pluginManager.EnablePlugin(plugin); return NoContent(); } @@ -157,12 +158,13 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult DisablePlugin([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version) { - if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin)) + var plugin = _pluginManager.GetPlugin(pluginId, version); + if (plugin == null) { return NotFound(); } - _pluginManager.DisablePlugin(plugin!); + _pluginManager.DisablePlugin(plugin); return NoContent(); } @@ -180,7 +182,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult UninstallPluginByVersion([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version) { - if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin)) + var plugin = _pluginManager.GetPlugin(pluginId, version); + if (plugin == null) { return NotFound(); } @@ -230,8 +233,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GetPluginConfiguration([FromRoute, Required] Guid pluginId) { - if (_pluginManager.TryGetPlugin(pluginId, null, out var plugin) - && plugin!.Instance is IHasPluginConfiguration configPlugin) + var plugin = _pluginManager.GetPlugin(pluginId); + if (plugin?.Instance is IHasPluginConfiguration configPlugin) { return configPlugin.Configuration; } @@ -258,8 +261,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task UpdatePluginConfiguration([FromRoute, Required] Guid pluginId) { - if (!_pluginManager.TryGetPlugin(pluginId, null, out var plugin) - || plugin?.Instance is not IHasPluginConfiguration configPlugin) + var plugin = _pluginManager.GetPlugin(pluginId); + if (plugin?.Instance is not IHasPluginConfiguration configPlugin) { return NotFound(); } @@ -289,14 +292,15 @@ namespace Jellyfin.Api.Controllers [AllowAnonymous] public ActionResult GetPluginImage([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version) { - if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin)) + var plugin = _pluginManager.GetPlugin(pluginId, version); + if (plugin == null) { return NotFound(); } - var imgPath = Path.Combine(plugin!.Path, plugin!.Manifest.ImageUrl ?? string.Empty); + var imgPath = Path.Combine(plugin.Path, plugin.Manifest.ImageUrl ?? string.Empty); if (((ServerConfiguration)_config.CommonConfiguration).DisablePluginImages - || plugin!.Manifest.ImageUrl == null + || plugin.Manifest.ImageUrl == null || !System.IO.File.Exists(imgPath)) { // Use a blank image. @@ -325,9 +329,11 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GetPluginManifest([FromRoute, Required] Guid pluginId) { - if (_pluginManager.TryGetPlugin(pluginId, null, out var plugin)) + var plugin = _pluginManager.GetPlugin(pluginId); + + if (plugin != null) { - return Ok(plugin!.Manifest); + return Ok(plugin.Manifest); } return NotFound(); diff --git a/MediaBrowser.Common/Plugins/IPluginManager.cs b/MediaBrowser.Common/Plugins/IPluginManager.cs index 071b51969..7f7381b03 100644 --- a/MediaBrowser.Common/Plugins/IPluginManager.cs +++ b/MediaBrowser.Common/Plugins/IPluginManager.cs @@ -72,9 +72,8 @@ namespace MediaBrowser.Common.Plugins /// /// Id of plugin. /// The version of the plugin to locate. - /// A if found, otherwise null. - /// Boolean value signifying the success of the search. - bool TryGetPlugin(Guid id, Version? version, out LocalPlugin? plugin); + /// A if located, or null if not. + LocalPlugin? GetPlugin(Guid id, Version? version = null); /// /// Removes the plugin. -- cgit v1.2.3 From d9aaba36ec807b12d58fdf9498ee60574ba44a54 Mon Sep 17 00:00:00 2001 From: Greenback Date: Wed, 16 Dec 2020 23:19:09 +0000 Subject: Copy previous plugin settings if they don't exist. --- .../Plugins/PluginManager.cs | 29 ++++++++++++++++++++++ MediaBrowser.Common/Plugins/BasePlugin.cs | 4 +-- 2 files changed, 31 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 26a029f71..e7589a0f9 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -274,6 +274,32 @@ namespace Emby.Server.Implementations } } + private void CopyFiles(string source, string destination, bool overwrite, string searchPattern) + { + FileInfo[] files; + try + { + files = new DirectoryInfo(source).GetFiles(searchPattern); + } + catch (Exception ex) + { + _logger.LogDebug(ex, "Error retrieving file list."); + return; + } + + foreach (FileInfo file in files) + { + try + { + file.CopyTo(Path.Combine(destination, file.Name), overwrite); + } + catch (Exception ex) + { + _logger.LogDebug(ex, "Error copying file {Name}", file.Name); + } + } + } + /// /// Changes the status of the other versions of the plugin to "Superceded". /// @@ -295,6 +321,9 @@ namespace Emby.Server.Implementations return; } + // migrate settings across from the last active version if they don't exist. + CopyFiles(predecessor.Path, plugin.Path, false, "*.xml"); + if (predecessor.Manifest.Status == PluginStatus.Active && !ChangePluginState(predecessor, PluginStatus.Superceded)) { _logger.LogError("Unable to disable version {Version} of {Name}", predecessor.Version, predecessor.Name); diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index a0d6b8f83..5756f8852 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -166,14 +166,14 @@ namespace MediaBrowser.Common.Plugins assemblyPlugin.SetId(assemblyId); } - // TODO : Simplify this, once migration support is ceased. + // TODO : Remove this, once migration support is ceased. if (inPluginFolder) { var oldConfigFilePath = Path.Combine(ApplicationPaths.PluginConfigurationsPath, ConfigurationFileName); if (!File.Exists(ConfigurationFilePath) && File.Exists(oldConfigFilePath)) { - // Migrate settings, as different plugin versions may have different settings. + // Migrate pre 10.7 settings, as different plugin versions may have different settings. try { File.Copy(oldConfigFilePath, ConfigurationFilePath); -- cgit v1.2.3 From a4a40407a047de2f10aa0f9d0ba9fe0f600ffdb0 Mon Sep 17 00:00:00 2001 From: Greenback Date: Thu, 17 Dec 2020 13:44:38 +0000 Subject: Change PluginStatus states. --- Emby.Server.Implementations/Plugins/PluginManager.cs | 20 ++++++++++---------- MediaBrowser.Model/Plugins/PluginStatus.cs | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index e7589a0f9..975b70843 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -77,7 +77,7 @@ namespace Emby.Server.Implementations for (int a = _plugins.Count - 1; a >= 0; a--) { var plugin = _plugins[a]; - if (plugin.Manifest.Status == PluginStatus.DeleteOnStartup && DeletePlugin(plugin)) + if (plugin.Manifest.Status == PluginStatus.Deleted && DeletePlugin(plugin)) { UpdateSuccessors(plugin); } @@ -104,7 +104,7 @@ namespace Emby.Server.Implementations catch (FileLoadException ex) { _logger.LogError(ex, "Failed to load assembly {Path}. Disabling plugin.", file); - ChangePluginState(plugin, PluginStatus.Malfunction); + ChangePluginState(plugin, PluginStatus.Malfunctioned); continue; } @@ -156,7 +156,7 @@ namespace Emby.Server.Implementations #pragma warning restore CA1031 // Do not catch general exception types { _logger.LogError(ex, "Error registering plugin services from {Assembly}.", pluginServiceRegistrator.Assembly.FullName); - if (ChangePluginState(plugin, PluginStatus.Malfunction)) + if (ChangePluginState(plugin, PluginStatus.Malfunctioned)) { _logger.LogInformation("Disabling plugin {Path}", plugin.Path); } @@ -206,7 +206,7 @@ namespace Emby.Server.Implementations _logger.LogWarning("Unable to delete {Path}, so marking as deleteOnStartup.", plugin.Path); // Unable to delete, so disable. - return ChangePluginState(plugin, PluginStatus.DeleteOnStartup); + return ChangePluginState(plugin, PluginStatus.Deleted); } /// @@ -307,7 +307,7 @@ namespace Emby.Server.Implementations private void UpdateSuccessors(LocalPlugin plugin) { // This value is memory only - so that the web will show restart required. - plugin.Manifest.Status = PluginStatus.RestartRequired; + plugin.Manifest.Status = PluginStatus.Restart; // Detect whether there is another version of this plugin that needs disabling. var predecessor = _plugins.OrderByDescending(p => p.Version) @@ -349,7 +349,7 @@ namespace Emby.Server.Implementations return; } - ChangePluginState(plugin, PluginStatus.Malfunction); + ChangePluginState(plugin, PluginStatus.Malfunctioned); } /// @@ -486,7 +486,7 @@ namespace Emby.Server.Implementations _logger.LogError(ex, "Error creating {Type}", type.FullName); if (plugin != null) { - if (ChangePluginState(plugin, PluginStatus.Malfunction)) + if (ChangePluginState(plugin, PluginStatus.Malfunctioned)) { _logger.LogInformation("Plugin {Path} has been disabled.", plugin.Path); return null; @@ -600,7 +600,7 @@ namespace Emby.Server.Implementations // Auto-create a plugin manifest, so we can disable it, if it fails to load. manifest = new PluginManifest { - Status = PluginStatus.RestartRequired, + Status = PluginStatus.Restart, Name = metafile, AutoUpdate = false, Guid = metafile.GetMD5(), @@ -697,9 +697,9 @@ namespace Emby.Server.Implementations continue; } - if (manifest.Status != PluginStatus.DeleteOnStartup) + if (manifest.Status != PluginStatus.Deleted) { - manifest.Status = PluginStatus.DeleteOnStartup; + manifest.Status = PluginStatus.Deleted; SaveManifest(manifest, entry.Path); } } diff --git a/MediaBrowser.Model/Plugins/PluginStatus.cs b/MediaBrowser.Model/Plugins/PluginStatus.cs index 2acc56811..3ea05174f 100644 --- a/MediaBrowser.Model/Plugins/PluginStatus.cs +++ b/MediaBrowser.Model/Plugins/PluginStatus.cs @@ -8,10 +8,10 @@ namespace MediaBrowser.Model.Plugins /// /// This plugin requires a restart in order for it to load. This is a memory only status. /// The actual status of the plugin after reload is present in the manifest. - /// eg. A disabled plugin will still be active until the next restart, and so will have a memory status of RestartRequired, + /// eg. A disabled plugin will still be active until the next restart, and so will have a memory status of Restart, /// but a disk manifest status of Disabled. /// - RestartRequired = 1, + Restart = 1, /// /// This plugin is currently running. @@ -31,7 +31,7 @@ namespace MediaBrowser.Model.Plugins /// /// This plugin caused an error when instantiated. (Either DI loop, or exception) /// - Malfunction = -3, + Malfunctioned = -3, /// /// This plugin has been superceded by another version. @@ -42,6 +42,6 @@ namespace MediaBrowser.Model.Plugins /// An attempt to remove this plugin from disk will happen at every restart. /// It will not be loaded, if unable to do so. /// - DeleteOnStartup = -5 + Deleted = -5 } } -- cgit v1.2.3 From 3a8d395c9c88fb5a6e170504ee8d865d880d7ed6 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 08:23:46 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 975b70843..34e8219e1 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -27,7 +27,6 @@ namespace Emby.Server.Implementations private readonly JsonSerializerOptions _jsonOptions; private readonly ILogger _logger; private readonly IApplicationHost _appHost; - private readonly string _imagesPath; private readonly ServerConfiguration _config; private readonly IList _plugins; private readonly Version _nextVersion; -- cgit v1.2.3 From 2d094bedf5d8b8e0e33e5bc0f59f9f39cb7b40c7 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 08:24:00 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 34e8219e1..66a233fbe 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -425,7 +425,7 @@ namespace Emby.Server.Implementations try { _logger.LogDebug("Creating instance of {Type}", type); - var instance = ActivatorUtilities.CreateInstance(_appHost.ServiceProvider, type); + var instance = (IPlugin)ActivatorUtilities.CreateInstance(_appHost.ServiceProvider, type); if (plugin == null) { // Create a dummy record for the providers. -- cgit v1.2.3 From 30645e72654e0d4918c86b610cbe9e8c2e4f4907 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 08:24:12 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 66a233fbe..6eeb8613c 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -429,7 +429,6 @@ namespace Emby.Server.Implementations if (plugin == null) { // Create a dummy record for the providers. - var pInstance = (IPlugin)instance; plugin = new LocalPlugin( pInstance.AssemblyFilePath, true, -- cgit v1.2.3 From 591ad3b04b7816d447ccd60c096a7fe730b3dea6 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 08:24:26 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 6eeb8613c..e92b02191 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -450,7 +450,7 @@ namespace Emby.Server.Implementations } else { - plugin.Instance = (IPlugin)instance; + plugin.Instance = instance; var manifest = plugin.Manifest; var pluginStr = plugin.Instance.Version.ToString(); bool changed = false; -- cgit v1.2.3 From 8ce765c4d1cd289c88673f79a8137bf2f5cbc241 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 08:25:04 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index e92b02191..8c0cd9a36 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -15,7 +15,7 @@ using MediaBrowser.Model.Plugins; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Emby.Server.Implementations +namespace Emby.Server.Implementations.Plugins { /// /// Defines the . -- cgit v1.2.3 From 0dcf6b09c1ad7913a27bf56b19716a0da957054e Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 08:25:39 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 8c0cd9a36..874e88c57 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -42,7 +42,7 @@ namespace Emby.Server.Implementations.Plugins /// The image cache path. /// The application version. public PluginManager( - ILoggerFactory loggerfactory, + ILogger logger, IApplicationHost appHost, ServerConfiguration config, string pluginsPath, -- cgit v1.2.3 From 4153551dfcd498114d240b0311b20df8799c1593 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 08:26:11 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 874e88c57..2e4b23bcf 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -413,7 +413,7 @@ namespace Emby.Server.Implementations.Plugins /// /// The type. /// System.Object. - private object? CreatePluginInstance(Type type) + private IPlugin? CreatePluginInstance(Type type) { // Find the record for this plugin. var plugin = GetPluginByType(type); -- cgit v1.2.3 From 5a3efc526631b7f774b17ea5a8a54130696b6e25 Mon Sep 17 00:00:00 2001 From: Greenback Date: Fri, 18 Dec 2020 09:04:40 +0000 Subject: Changes as required. --- Emby.Server.Implementations/ApplicationHost.cs | 3 +- .../Plugins/PluginManager.cs | 102 ++++++++------------- MediaBrowser.Common/Plugins/BasePlugin.cs | 41 +-------- 3 files changed, 42 insertions(+), 104 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 216cb5e75..d7bc83f3a 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -35,6 +35,7 @@ using Emby.Server.Implementations.LiveTv; using Emby.Server.Implementations.Localization; using Emby.Server.Implementations.Net; using Emby.Server.Implementations.Playlists; +using Emby.Server.Implementations.Plugins; using Emby.Server.Implementations.QuickConnect; using Emby.Server.Implementations.ScheduledTasks; using Emby.Server.Implementations.Security; @@ -281,7 +282,7 @@ namespace Emby.Server.Implementations ApplicationUserAgent = Name.Replace(' ', '-') + "/" + ApplicationVersionString; _pluginManager = new PluginManager( - LoggerFactory, + LoggerFactory.CreateLogger(), this, ServerConfigurationManager.Configuration, ApplicationPaths.PluginsPath, diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 2e4b23bcf..151e2c203 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -35,7 +35,7 @@ namespace Emby.Server.Implementations.Plugins /// /// Initializes a new instance of the class. /// - /// The . + /// The . /// The . /// The . /// The plugin path. @@ -49,13 +49,12 @@ namespace Emby.Server.Implementations.Plugins string imagesPath, Version appVersion) { - _logger = loggerfactory.CreateLogger(); + _logger = _logger ?? throw new ArgumentNullException(nameof(logger)); _pluginsPath = pluginsPath; _appVersion = appVersion ?? throw new ArgumentNullException(nameof(appVersion)); - _jsonOptions = JsonDefaults.GetCamelCaseOptions(); + _jsonOptions = JsonDefaults.GetOptions(); _config = config; _appHost = appHost; - _imagesPath = imagesPath; _nextVersion = new Version(_appVersion.Major, _appVersion.Minor + 2, _appVersion.Build, _appVersion.Revision); _minimumVersion = new Version(0, 0, 0, 1); _plugins = Directory.Exists(_pluginsPath) ? DiscoverPlugins().ToList() : new List(); @@ -273,62 +272,6 @@ namespace Emby.Server.Implementations.Plugins } } - private void CopyFiles(string source, string destination, bool overwrite, string searchPattern) - { - FileInfo[] files; - try - { - files = new DirectoryInfo(source).GetFiles(searchPattern); - } - catch (Exception ex) - { - _logger.LogDebug(ex, "Error retrieving file list."); - return; - } - - foreach (FileInfo file in files) - { - try - { - file.CopyTo(Path.Combine(destination, file.Name), overwrite); - } - catch (Exception ex) - { - _logger.LogDebug(ex, "Error copying file {Name}", file.Name); - } - } - } - - /// - /// Changes the status of the other versions of the plugin to "Superceded". - /// - /// The that's master. - private void UpdateSuccessors(LocalPlugin plugin) - { - // This value is memory only - so that the web will show restart required. - plugin.Manifest.Status = PluginStatus.Restart; - - // Detect whether there is another version of this plugin that needs disabling. - var predecessor = _plugins.OrderByDescending(p => p.Version) - .FirstOrDefault( - p => p.Id.Equals(plugin.Id) - && p.IsEnabledAndSupported - && p.Version != plugin.Version); - - if (predecessor == null) - { - return; - } - - // migrate settings across from the last active version if they don't exist. - CopyFiles(predecessor.Path, plugin.Path, false, "*.xml"); - - if (predecessor.Manifest.Status == PluginStatus.Active && !ChangePluginState(predecessor, PluginStatus.Superceded)) - { - _logger.LogError("Unable to disable version {Version} of {Name}", predecessor.Version, predecessor.Name); - } - } - /// /// Disable the plugin. /// @@ -429,19 +372,19 @@ namespace Emby.Server.Implementations.Plugins if (plugin == null) { // Create a dummy record for the providers. + // TODO: remove this code, if all provided have been released as separate plugins. plugin = new LocalPlugin( - pInstance.AssemblyFilePath, + instance.AssemblyFilePath, true, new PluginManifest { - Guid = pInstance.Id, + Guid = instance.Id, Status = PluginStatus.Active, - Name = pInstance.Name, - Version = pInstance.Version.ToString(), - MaxAbi = _nextVersion.ToString() + Name = instance.Name, + Version = instance.Version.ToString() }) { - Instance = pInstance + Instance = instance }; _plugins.Add(plugin); @@ -707,5 +650,32 @@ namespace Emby.Server.Implementations.Plugins // Only want plugin folders which have files. return versions.Where(p => p.DllFiles.Count != 0); } + + /// + /// Changes the status of the other versions of the plugin to "Superceded". + /// + /// The that's master. + private void UpdateSuccessors(LocalPlugin plugin) + { + // This value is memory only - so that the web will show restart required. + plugin.Manifest.Status = PluginStatus.Restart; + + // Detect whether there is another version of this plugin that needs disabling. + var predecessor = _plugins.OrderByDescending(p => p.Version) + .FirstOrDefault( + p => p.Id.Equals(plugin.Id) + && p.IsEnabledAndSupported + && p.Version != plugin.Version); + + if (predecessor == null) + { + return; + } + + if (predecessor.Manifest.Status == PluginStatus.Active && !ChangePluginState(predecessor, PluginStatus.Superceded)) + { + _logger.LogError("Unable to disable version {Version} of {Name}", predecessor.Version, predecessor.Name); + } + } } } diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index 5756f8852..5750c59c4 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -134,25 +134,11 @@ namespace MediaBrowser.Common.Plugins var assemblyName = assembly.GetName(); var assemblyFilePath = assembly.Location; - // Find out the plugin folder. - bool inPluginFolder = assemblyFilePath.StartsWith(ApplicationPaths.PluginsPath, StringComparison.OrdinalIgnoreCase); - string path, dataFolderPath; - - var configurationFileName = Path.ChangeExtension(Path.GetFileName(assemblyFilePath), ".xml"); - if (inPluginFolder) - { - // Normal plugin. - path = assemblyFilePath.Substring(ApplicationPaths.PluginsPath.Length).Split('\\', StringSplitOptions.RemoveEmptyEntries)[0]; - dataFolderPath = Path.Combine( - Path.Combine(ApplicationPaths.PluginsPath, path), - configurationFileName); - ConfigurationFilePath = dataFolderPath; - } - else + var dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(assemblyFilePath)); + if (!Directory.Exists(dataFolderPath)) { - // Provider - dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(assemblyFilePath)); - ConfigurationFilePath = Path.Combine(ApplicationPaths.PluginConfigurationsPath, configurationFileName); + // Try again with the version number appended to the folder name. + dataFolderPath = dataFolderPath + "_" + Version.ToString(); } assemblyPlugin.SetAttributes(assemblyFilePath, dataFolderPath, assemblyName.Version); @@ -165,25 +151,6 @@ namespace MediaBrowser.Common.Plugins assemblyPlugin.SetId(assemblyId); } - - // TODO : Remove this, once migration support is ceased. - if (inPluginFolder) - { - var oldConfigFilePath = Path.Combine(ApplicationPaths.PluginConfigurationsPath, ConfigurationFileName); - - if (!File.Exists(ConfigurationFilePath) && File.Exists(oldConfigFilePath)) - { - // Migrate pre 10.7 settings, as different plugin versions may have different settings. - try - { - File.Copy(oldConfigFilePath, ConfigurationFilePath); - } - catch - { - // Unable to migrate settings. - } - } - } } if (this is IHasPluginConfiguration hasPluginConfiguration) -- cgit v1.2.3 From 486148dd6b18ec336ca076b8ec0a23d257789683 Mon Sep 17 00:00:00 2001 From: Greenback Date: Fri, 18 Dec 2020 09:44:57 +0000 Subject: Removed maxAbi --- Emby.Server.Implementations/ApplicationHost.cs | 1 - .../Plugins/PluginManager.cs | 11 +- .../Updates/InstallationManager.cs | 18 +- MediaBrowser.Common/Plugins/BasePlugin.cs | 210 -------------------- MediaBrowser.Common/Plugins/BasePluginOfT.cs | 218 +++++++++++++++++++++ MediaBrowser.Model/Updates/VersionInfo.cs | 7 - 6 files changed, 224 insertions(+), 241 deletions(-) create mode 100644 MediaBrowser.Common/Plugins/BasePluginOfT.cs (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index d7bc83f3a..b91ba6b6c 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -286,7 +286,6 @@ namespace Emby.Server.Implementations this, ServerConfigurationManager.Configuration, ApplicationPaths.PluginsPath, - ApplicationPaths.CachePath, ApplicationVersion); } diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 151e2c203..4c508279c 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -39,17 +39,15 @@ namespace Emby.Server.Implementations.Plugins /// The . /// The . /// The plugin path. - /// The image cache path. /// The application version. public PluginManager( ILogger logger, IApplicationHost appHost, ServerConfiguration config, string pluginsPath, - string imagesPath, Version appVersion) { - _logger = _logger ?? throw new ArgumentNullException(nameof(logger)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _pluginsPath = pluginsPath; _appVersion = appVersion ?? throw new ArgumentNullException(nameof(appVersion)); _jsonOptions = JsonDefaults.GetOptions(); @@ -509,17 +507,12 @@ namespace Emby.Server.Implementations.Plugins targetAbi = _minimumVersion; } - if (!Version.TryParse(manifest.MaxAbi, out var maxAbi)) - { - maxAbi = _appVersion; - } - if (!Version.TryParse(manifest.Version, out version)) { manifest.Version = _minimumVersion.ToString(); } - return new LocalPlugin(dir, _appVersion >= targetAbi && _appVersion <= maxAbi, manifest); + return new LocalPlugin(dir, _appVersion >= targetAbi, manifest); } // No metafile, so lets see if the folder is versioned. diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 70424369b..cf059fb97 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -132,13 +132,8 @@ namespace Emby.Server.Implementations.Updates targetAbi = minimumVersion; } - if (!Version.TryParse(ver.MaxAbi, out var maxAbi)) - { - maxAbi = _applicationHost.ApplicationVersion; - } - // Only show plugins that fall between targetAbi and maxAbi - if (_applicationHost.ApplicationVersion >= targetAbi && _applicationHost.ApplicationVersion <= maxAbi) + if (_applicationHost.ApplicationVersion >= targetAbi) { continue; } @@ -200,19 +195,15 @@ namespace Emby.Server.Implementations.Updates // Update the manifests, if anything changes. if (plugin != null) { - bool noChange = string.Equals(plugin.Manifest.MaxAbi, version.MaxAbi, StringComparison.Ordinal) - || string.Equals(plugin.Manifest.TargetAbi, version.TargetAbi, StringComparison.Ordinal); - if (!noChange) + if (!string.Equals(plugin.Manifest.TargetAbi, version.TargetAbi, StringComparison.Ordinal)) { - plugin.Manifest.MaxAbi = version.MaxAbi ?? string.Empty; plugin.Manifest.TargetAbi = version.TargetAbi ?? string.Empty; _pluginManager.SaveManifest(plugin.Manifest, plugin.Path); } } // Remove versions with a target abi that is greater then the current application version. - if ((Version.TryParse(version.TargetAbi, out var targetAbi) && _applicationHost.ApplicationVersion < targetAbi) - || (Version.TryParse(version.MaxAbi, out var maxAbi) && _applicationHost.ApplicationVersion > maxAbi)) + if (Version.TryParse(version.TargetAbi, out var targetAbi) && _applicationHost.ApplicationVersion < targetAbi) { package.Versions.RemoveAt(i); } @@ -283,8 +274,7 @@ namespace Emby.Server.Implementations.Updates var appVer = _applicationHost.ApplicationVersion; var availableVersions = package.Versions - .Where(x => (string.IsNullOrEmpty(x.TargetAbi) || Version.Parse(x.TargetAbi) <= appVer) - && (string.IsNullOrEmpty(x.MaxAbi) || Version.Parse(x.MaxAbi) >= appVer)); + .Where(x => string.IsNullOrEmpty(x.TargetAbi) || Version.Parse(x.TargetAbi) <= appVer); if (specificVersion != null) { diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index 5750c59c4..e228ae7ec 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -1,5 +1,3 @@ -#pragma warning disable SA1402 - using System; using System.IO; using System.Reflection; @@ -94,212 +92,4 @@ namespace MediaBrowser.Common.Plugins Id = assemblyId; } } - - /// - /// Provides a common base class for all plugins. - /// - /// The type of the T configuration type. - public abstract class BasePlugin : BasePlugin, IHasPluginConfiguration - where TConfigurationType : BasePluginConfiguration - { - /// - /// The configuration sync lock. - /// - private readonly object _configurationSyncLock = new object(); - - /// - /// The configuration save lock. - /// - private readonly object _configurationSaveLock = new object(); - - private Action _directoryCreateFn; - - /// - /// The configuration. - /// - private TConfigurationType _configuration; - - /// - /// Initializes a new instance of the class. - /// - /// The application paths. - /// The XML serializer. - protected BasePlugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) - { - ApplicationPaths = applicationPaths; - XmlSerializer = xmlSerializer; - if (this is IPluginAssembly assemblyPlugin) - { - var assembly = GetType().Assembly; - var assemblyName = assembly.GetName(); - var assemblyFilePath = assembly.Location; - - var dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(assemblyFilePath)); - if (!Directory.Exists(dataFolderPath)) - { - // Try again with the version number appended to the folder name. - dataFolderPath = dataFolderPath + "_" + Version.ToString(); - } - - assemblyPlugin.SetAttributes(assemblyFilePath, dataFolderPath, assemblyName.Version); - - var idAttributes = assembly.GetCustomAttributes(typeof(GuidAttribute), true); - if (idAttributes.Length > 0) - { - var attribute = (GuidAttribute)idAttributes[0]; - var assemblyId = new Guid(attribute.Value); - - assemblyPlugin.SetId(assemblyId); - } - } - - if (this is IHasPluginConfiguration hasPluginConfiguration) - { - hasPluginConfiguration.SetStartupInfo(s => Directory.CreateDirectory(s)); - } - } - - /// - /// Gets the application paths. - /// - /// The application paths. - protected IApplicationPaths ApplicationPaths { get; private set; } - - /// - /// Gets the XML serializer. - /// - /// The XML serializer. - protected IXmlSerializer XmlSerializer { get; private set; } - - /// - /// Gets the type of configuration this plugin uses. - /// - /// The type of the configuration. - public Type ConfigurationType => typeof(TConfigurationType); - - /// - /// Gets or sets the event handler that is triggered when this configuration changes. - /// - public EventHandler ConfigurationChanged { get; set; } - - /// - /// Gets the name the assembly file. - /// - /// The name of the assembly file. - protected string AssemblyFileName => Path.GetFileName(AssemblyFilePath); - - /// - /// Gets or sets the plugin configuration. - /// - /// The configuration. - public TConfigurationType Configuration - { - get - { - // Lazy load - if (_configuration == null) - { - lock (_configurationSyncLock) - { - if (_configuration == null) - { - _configuration = LoadConfiguration(); - } - } - } - - return _configuration; - } - - protected set => _configuration = value; - } - - /// - /// Gets the name of the configuration file. Subclasses should override. - /// - /// The name of the configuration file. - public virtual string ConfigurationFileName => Path.ChangeExtension(AssemblyFileName, ".xml"); - - /// - /// Gets the full path to the configuration file. - /// - /// The configuration file path. - public string ConfigurationFilePath { get; } - - /// - /// Gets the plugin configuration. - /// - /// The configuration. - BasePluginConfiguration IHasPluginConfiguration.Configuration => Configuration; - - /// - public void SetStartupInfo(Action directoryCreateFn) - { - // hack alert, until the .net core transition is complete - _directoryCreateFn = directoryCreateFn; - } - - private TConfigurationType LoadConfiguration() - { - var path = ConfigurationFilePath; - - try - { - return (TConfigurationType)XmlSerializer.DeserializeFromFile(typeof(TConfigurationType), path); - } - catch - { - var config = (TConfigurationType)Activator.CreateInstance(typeof(TConfigurationType)); - SaveConfiguration(config); - return config; - } - } - - /// - /// Saves the current configuration to the file system. - /// - /// Configuration to save. - public virtual void SaveConfiguration(TConfigurationType config) - { - lock (_configurationSaveLock) - { - _directoryCreateFn(Path.GetDirectoryName(ConfigurationFilePath)); - - XmlSerializer.SerializeToFile(config, ConfigurationFilePath); - } - } - - /// - /// Saves the current configuration to the file system. - /// - public virtual void SaveConfiguration() - { - SaveConfiguration(Configuration); - } - - /// - public virtual void UpdateConfiguration(BasePluginConfiguration configuration) - { - if (configuration == null) - { - throw new ArgumentNullException(nameof(configuration)); - } - - Configuration = (TConfigurationType)configuration; - - SaveConfiguration(Configuration); - - ConfigurationChanged?.Invoke(this, configuration); - } - - /// - public override PluginInfo GetPluginInfo() - { - var info = base.GetPluginInfo(); - - info.ConfigurationFileName = ConfigurationFileName; - - return info; - } - } } diff --git a/MediaBrowser.Common/Plugins/BasePluginOfT.cs b/MediaBrowser.Common/Plugins/BasePluginOfT.cs new file mode 100644 index 000000000..66aec92ab --- /dev/null +++ b/MediaBrowser.Common/Plugins/BasePluginOfT.cs @@ -0,0 +1,218 @@ +#pragma warning disable SA1649 // File name should match first type name +using System; +using System.IO; +using System.Runtime.InteropServices; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Model.Plugins; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Common.Plugins +{ + /// + /// Provides a common base class for all plugins. + /// + /// The type of the T configuration type. + public abstract class BasePlugin : BasePlugin, IHasPluginConfiguration + where TConfigurationType : BasePluginConfiguration + { + /// + /// The configuration sync lock. + /// + private readonly object _configurationSyncLock = new object(); + + /// + /// The configuration save lock. + /// + private readonly object _configurationSaveLock = new object(); + + private Action _directoryCreateFn; + + /// + /// The configuration. + /// + private TConfigurationType _configuration; + + /// + /// Initializes a new instance of the class. + /// + /// The application paths. + /// The XML serializer. + protected BasePlugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) + { + ApplicationPaths = applicationPaths; + XmlSerializer = xmlSerializer; + if (this is IPluginAssembly assemblyPlugin) + { + var assembly = GetType().Assembly; + var assemblyName = assembly.GetName(); + var assemblyFilePath = assembly.Location; + + var dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(assemblyFilePath)); + if (!Directory.Exists(dataFolderPath)) + { + // Try again with the version number appended to the folder name. + dataFolderPath = dataFolderPath + "_" + Version.ToString(); + } + + assemblyPlugin.SetAttributes(assemblyFilePath, dataFolderPath, assemblyName.Version); + + var idAttributes = assembly.GetCustomAttributes(typeof(GuidAttribute), true); + if (idAttributes.Length > 0) + { + var attribute = (GuidAttribute)idAttributes[0]; + var assemblyId = new Guid(attribute.Value); + + assemblyPlugin.SetId(assemblyId); + } + } + + if (this is IHasPluginConfiguration hasPluginConfiguration) + { + hasPluginConfiguration.SetStartupInfo(s => Directory.CreateDirectory(s)); + } + } + + /// + /// Gets the application paths. + /// + /// The application paths. + protected IApplicationPaths ApplicationPaths { get; private set; } + + /// + /// Gets the XML serializer. + /// + /// The XML serializer. + protected IXmlSerializer XmlSerializer { get; private set; } + + /// + /// Gets the type of configuration this plugin uses. + /// + /// The type of the configuration. + public Type ConfigurationType => typeof(TConfigurationType); + + /// + /// Gets or sets the event handler that is triggered when this configuration changes. + /// + public EventHandler ConfigurationChanged { get; set; } + + /// + /// Gets the name the assembly file. + /// + /// The name of the assembly file. + protected string AssemblyFileName => Path.GetFileName(AssemblyFilePath); + + /// + /// Gets or sets the plugin configuration. + /// + /// The configuration. + public TConfigurationType Configuration + { + get + { + // Lazy load + if (_configuration == null) + { + lock (_configurationSyncLock) + { + if (_configuration == null) + { + _configuration = LoadConfiguration(); + } + } + } + + return _configuration; + } + + protected set => _configuration = value; + } + + /// + /// Gets the name of the configuration file. Subclasses should override. + /// + /// The name of the configuration file. + public virtual string ConfigurationFileName => Path.ChangeExtension(AssemblyFileName, ".xml"); + + /// + /// Gets the full path to the configuration file. + /// + /// The configuration file path. + public string ConfigurationFilePath { get; } + + /// + /// Gets the plugin configuration. + /// + /// The configuration. + BasePluginConfiguration IHasPluginConfiguration.Configuration => Configuration; + + /// + public void SetStartupInfo(Action directoryCreateFn) + { + // hack alert, until the .net core transition is complete + _directoryCreateFn = directoryCreateFn; + } + + /// + /// Saves the current configuration to the file system. + /// + /// Configuration to save. + public virtual void SaveConfiguration(TConfigurationType config) + { + lock (_configurationSaveLock) + { + _directoryCreateFn(Path.GetDirectoryName(ConfigurationFilePath)); + + XmlSerializer.SerializeToFile(config, ConfigurationFilePath); + } + } + + /// + /// Saves the current configuration to the file system. + /// + public virtual void SaveConfiguration() + { + SaveConfiguration(Configuration); + } + + /// + public virtual void UpdateConfiguration(BasePluginConfiguration configuration) + { + if (configuration == null) + { + throw new ArgumentNullException(nameof(configuration)); + } + + Configuration = (TConfigurationType)configuration; + + SaveConfiguration(Configuration); + + ConfigurationChanged?.Invoke(this, configuration); + } + + /// + public override PluginInfo GetPluginInfo() + { + var info = base.GetPluginInfo(); + + info.ConfigurationFileName = ConfigurationFileName; + + return info; + } + + private TConfigurationType LoadConfiguration() + { + var path = ConfigurationFilePath; + + try + { + return (TConfigurationType)XmlSerializer.DeserializeFromFile(typeof(TConfigurationType), path); + } + catch + { + var config = (TConfigurationType)Activator.CreateInstance(typeof(TConfigurationType)); + SaveConfiguration(config); + return config; + } + } + } +} diff --git a/MediaBrowser.Model/Updates/VersionInfo.cs b/MediaBrowser.Model/Updates/VersionInfo.cs index 503dba0a1..209092265 100644 --- a/MediaBrowser.Model/Updates/VersionInfo.cs +++ b/MediaBrowser.Model/Updates/VersionInfo.cs @@ -43,13 +43,6 @@ namespace MediaBrowser.Model.Updates [JsonPropertyName("targetAbi")] public string? TargetAbi { get; set; } - /// - /// Gets or sets the maximum ABI that this version will work with. - /// - /// The target ABI version. - [JsonPropertyName("maxAbi")] - public string? MaxAbi { get; set; } - /// /// Gets or sets the source URL. /// -- cgit v1.2.3 From ce19f2be55c7484488bebfd29bd42c1f082ae888 Mon Sep 17 00:00:00 2001 From: Greenback Date: Fri, 18 Dec 2020 20:37:35 +0000 Subject: Renamed Guid property to Id --- .../Plugins/PluginManager.cs | 4 +-- .../Updates/InstallationManager.cs | 12 ++++---- MediaBrowser.Common/Plugins/BasePluginOfT.cs | 17 +++++++++-- MediaBrowser.Common/Plugins/LocalPlugin.cs | 6 ++-- MediaBrowser.Common/Plugins/PluginManifest.cs | 6 ++-- MediaBrowser.Model/Plugins/PluginPageInfo.cs | 34 +++++++++++++++++----- MediaBrowser.Model/Updates/InstallationInfo.cs | 8 +++-- MediaBrowser.Model/Updates/PackageInfo.cs | 6 ++-- MediaBrowser.Providers/Plugins/AudioDb/Plugin.cs | 2 +- .../Plugins/MusicBrainz/Plugin.cs | 2 +- MediaBrowser.Providers/Plugins/Omdb/Plugin.cs | 2 +- 11 files changed, 65 insertions(+), 34 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 4c508279c..613e610d3 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -376,7 +376,7 @@ namespace Emby.Server.Implementations.Plugins true, new PluginManifest { - Guid = instance.Id, + Id = instance.Id, Status = PluginStatus.Active, Name = instance.Name, Version = instance.Version.ToString() @@ -537,7 +537,7 @@ namespace Emby.Server.Implementations.Plugins Status = PluginStatus.Restart, Name = metafile, AutoUpdate = false, - Guid = metafile.GetMD5(), + Id = metafile.GetMD5(), TargetAbi = _appVersion.ToString(), Version = version.ToString() }; diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index cf059fb97..267a33875 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -178,7 +178,7 @@ namespace Emby.Server.Implementations.Updates // Where repositories have the same content, the details from the first is taken. foreach (var package in await GetPackages(repository.Name ?? "Unnamed Repo", repository.Url, true, cancellationToken).ConfigureAwait(true)) { - if (!Guid.TryParse(package.Guid, out var packageGuid)) + if (!Guid.TryParse(package.Id, out var packageGuid)) { // Package doesn't have a valid GUID, skip. continue; @@ -245,7 +245,7 @@ namespace Emby.Server.Implementations.Updates if (guid != Guid.Empty) { - availablePackages = availablePackages.Where(x => Guid.Parse(x.Guid) == guid); + availablePackages = availablePackages.Where(x => Guid.Parse(x.Id) == guid); } if (specificVersion != null) @@ -290,7 +290,7 @@ namespace Emby.Server.Implementations.Updates yield return new InstallationInfo { Changelog = v.Changelog, - Guid = new Guid(package.Guid), + Id = new Guid(package.Id), Name = package.Name, Version = v.VersionNumber, SourceUrl = v.SourceUrl, @@ -414,7 +414,7 @@ namespace Emby.Server.Implementations.Updates { lock (_currentInstallationsLock) { - var install = _currentInstallations.Find(x => x.info.Guid == id); + var install = _currentInstallations.Find(x => x.info.Id == id); if (install == default((InstallationInfo, CancellationTokenSource))) { return false; @@ -512,7 +512,7 @@ namespace Emby.Server.Implementations.Updates var compatibleVersions = GetCompatibleVersions(pluginCatalog, plugin.Name, plugin.Id, minVersion: plugin.Version); var version = compatibleVersions.FirstOrDefault(y => y.Version > plugin.Version); - if (version != null && CompletedInstallations.All(x => x.Guid != version.Guid)) + if (version != null && CompletedInstallations.All(x => x.Id != version.Id)) { yield return version; } @@ -577,7 +577,7 @@ namespace Emby.Server.Implementations.Updates private async Task InstallPackageInternal(InstallationInfo package, CancellationToken cancellationToken) { // Set last update time if we were installed before - LocalPlugin? plugin = _pluginManager.Plugins.FirstOrDefault(p => p.Id.Equals(package.Guid) && p.Version.Equals(package.Version)) + LocalPlugin? plugin = _pluginManager.Plugins.FirstOrDefault(p => p.Id.Equals(package.Id) && p.Version.Equals(package.Version)) ?? _pluginManager.Plugins.FirstOrDefault(p => p.Name.Equals(package.Name, StringComparison.OrdinalIgnoreCase) && p.Version.Equals(package.Version)); if (plugin != null) { diff --git a/MediaBrowser.Common/Plugins/BasePluginOfT.cs b/MediaBrowser.Common/Plugins/BasePluginOfT.cs index 66aec92ab..e4e766472 100644 --- a/MediaBrowser.Common/Plugins/BasePluginOfT.cs +++ b/MediaBrowser.Common/Plugins/BasePluginOfT.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Common.Plugins var assemblyFilePath = assembly.Location; var dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(assemblyFilePath)); - if (!Directory.Exists(dataFolderPath)) + if (!Directory.Exists(dataFolderPath) && Version != null) { // Try again with the version number appended to the folder name. dataFolderPath = dataFolderPath + "_" + Version.ToString(); @@ -137,7 +137,20 @@ namespace MediaBrowser.Common.Plugins /// Gets the full path to the configuration file. /// /// The configuration file path. - public string ConfigurationFilePath { get; } + public string ConfigurationFilePath + { + get + { + var dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(AssemblyFilePath)); + if (!Directory.Exists(dataFolderPath) && Version != null) + { + // Try again with the version number appended to the folder name. + return dataFolderPath + "_" + Version.ToString(); + } + + return dataFolderPath; + } + } /// /// Gets the plugin configuration. diff --git a/MediaBrowser.Common/Plugins/LocalPlugin.cs b/MediaBrowser.Common/Plugins/LocalPlugin.cs index 8aded8b9b..40ecb0a67 100644 --- a/MediaBrowser.Common/Plugins/LocalPlugin.cs +++ b/MediaBrowser.Common/Plugins/LocalPlugin.cs @@ -1,8 +1,6 @@ #nullable enable using System; using System.Collections.Generic; -using System.Globalization; -using System.Reflection; using MediaBrowser.Model.Plugins; namespace MediaBrowser.Common.Plugins @@ -32,7 +30,7 @@ namespace MediaBrowser.Common.Plugins /// /// Gets the plugin id. /// - public Guid Id => Manifest.Guid; + public Guid Id => Manifest.Id; /// /// Gets the plugin name. @@ -110,7 +108,7 @@ namespace MediaBrowser.Common.Plugins /// A instance containing the information. public PluginInfo GetPluginInfo() { - var inst = Instance?.GetPluginInfo() ?? new PluginInfo(Manifest.Name, Version, Manifest.Description, Manifest.Guid, true); + var inst = Instance?.GetPluginInfo() ?? new PluginInfo(Manifest.Name, Version, Manifest.Description, Manifest.Id, true); inst.Status = Manifest.Status; inst.HasImage = !string.IsNullOrEmpty(Manifest.ImageUrl); return inst; diff --git a/MediaBrowser.Common/Plugins/PluginManifest.cs b/MediaBrowser.Common/Plugins/PluginManifest.cs index 1bd17933c..39ee450a6 100644 --- a/MediaBrowser.Common/Plugins/PluginManifest.cs +++ b/MediaBrowser.Common/Plugins/PluginManifest.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.Text.Json.Serialization; using MediaBrowser.Model.Plugins; namespace MediaBrowser.Common.Plugins @@ -27,9 +28,8 @@ namespace MediaBrowser.Common.Plugins /// /// Gets or sets the Global Unique Identifier for the plugin. /// -#pragma warning disable CA1720 // Identifier contains type name - public Guid Guid { get; set; } -#pragma warning restore CA1720 // Identifier contains type name + [JsonPropertyName("Guid")] + public Guid Id { get; set; } /// /// Gets or sets the Name of the plugin. diff --git a/MediaBrowser.Model/Plugins/PluginPageInfo.cs b/MediaBrowser.Model/Plugins/PluginPageInfo.cs index ca72e19ee..85c0aa204 100644 --- a/MediaBrowser.Model/Plugins/PluginPageInfo.cs +++ b/MediaBrowser.Model/Plugins/PluginPageInfo.cs @@ -1,20 +1,40 @@ -#nullable disable -#pragma warning disable CS1591 +#nullable enable namespace MediaBrowser.Model.Plugins { + /// + /// Defines the . + /// public class PluginPageInfo { - public string Name { get; set; } + /// + /// Gets or sets the name. + /// + public string Name { get; set; } = string.Empty; - public string DisplayName { get; set; } + /// + /// Gets or sets the display name. + /// + public string? DisplayName { get; set; } - public string EmbeddedResourcePath { get; set; } + /// + /// Gets or sets the resource path. + /// + public string EmbeddedResourcePath { get; set; } = string.Empty; + /// + /// Gets or sets a value indicating whether this plugin should appear in the main menu. + /// public bool EnableInMainMenu { get; set; } - public string MenuSection { get; set; } + /// + /// Gets or sets the menu section. + /// + public string? MenuSection { get; set; } - public string MenuIcon { get; set; } + /// + /// Gets or sets the menu icon. + /// + public string? MenuIcon { get; set; } } } diff --git a/MediaBrowser.Model/Updates/InstallationInfo.cs b/MediaBrowser.Model/Updates/InstallationInfo.cs index a6d80dba6..eebe1a903 100644 --- a/MediaBrowser.Model/Updates/InstallationInfo.cs +++ b/MediaBrowser.Model/Updates/InstallationInfo.cs @@ -1,5 +1,6 @@ #nullable disable using System; +using System.Text.Json.Serialization; namespace MediaBrowser.Model.Updates { @@ -9,10 +10,11 @@ namespace MediaBrowser.Model.Updates public class InstallationInfo { /// - /// Gets or sets the guid. + /// Gets or sets the Id. /// - /// The guid. - public Guid Guid { get; set; } + /// The Id. + [JsonPropertyName("Guid")] + public Guid Id { get; set; } /// /// Gets or sets the name. diff --git a/MediaBrowser.Model/Updates/PackageInfo.cs b/MediaBrowser.Model/Updates/PackageInfo.cs index 63fd71742..2d05ed636 100644 --- a/MediaBrowser.Model/Updates/PackageInfo.cs +++ b/MediaBrowser.Model/Updates/PackageInfo.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Model.Updates public PackageInfo() { Versions = Array.Empty(); - Guid = string.Empty; + Id = string.Empty; Category = string.Empty; Name = string.Empty; Overview = string.Empty; @@ -65,9 +65,7 @@ namespace MediaBrowser.Model.Updates /// /// The name. [JsonPropertyName("guid")] -#pragma warning disable CA1720 // Identifier contains type name - public string Guid { get; set; } -#pragma warning restore CA1720 // Identifier contains type name + public string Id { get; set; } /// /// Gets or sets the versions. diff --git a/MediaBrowser.Providers/Plugins/AudioDb/Plugin.cs b/MediaBrowser.Providers/Plugins/AudioDb/Plugin.cs index b5bd72ff0..ba0d7b569 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/Plugin.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/Plugin.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 using System; using System.Collections.Generic; diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs index 90266e440..43bd3a472 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 using System; using System.Collections.Generic; diff --git a/MediaBrowser.Providers/Plugins/Omdb/Plugin.cs b/MediaBrowser.Providers/Plugins/Omdb/Plugin.cs index 41ca56164..d7f6781e5 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/Plugin.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/Plugin.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 using System; using System.Collections.Generic; -- cgit v1.2.3 From 3708ca8dbb0eff2eaa6c39b22cc1a2fd6e197dff Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 21:56:03 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 613e610d3..6ed9623f9 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -29,7 +29,6 @@ namespace Emby.Server.Implementations.Plugins private readonly IApplicationHost _appHost; private readonly ServerConfiguration _config; private readonly IList _plugins; - private readonly Version _nextVersion; private readonly Version _minimumVersion; /// -- cgit v1.2.3 From 09f219bbcee78569537bb417de27f842879f2233 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 21:56:15 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 6ed9623f9..dc2eca4a1 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -52,7 +52,6 @@ namespace Emby.Server.Implementations.Plugins _jsonOptions = JsonDefaults.GetOptions(); _config = config; _appHost = appHost; - _nextVersion = new Version(_appVersion.Major, _appVersion.Minor + 2, _appVersion.Build, _appVersion.Revision); _minimumVersion = new Version(0, 0, 0, 1); _plugins = Directory.Exists(_pluginsPath) ? DiscoverPlugins().ToList() : new List(); } -- cgit v1.2.3 From 5c3ebb63e62948ce9d405f7cbb82d4579e568833 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 21:56:35 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index dc2eca4a1..be08d8515 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -113,7 +113,7 @@ namespace Emby.Server.Implementations.Plugins /// public void CreatePlugins() { - var createdPlugins = _appHost.GetExports(CreatePluginInstance) + _ = _appHost.GetExports(CreatePluginInstance) .Where(i => i != null) .ToArray(); } -- cgit v1.2.3 From a293024efd5ebf8d04b53de0999da78a64a857e5 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 21:56:54 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index be08d8515..1fd87273f 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -280,7 +280,7 @@ namespace Emby.Server.Implementations.Plugins throw new ArgumentNullException(nameof(assembly)); } - var plugin = _plugins.Where(p => p.DllFiles.Contains(assembly.Location)).FirstOrDefault(); + var plugin = _plugins.FirstOrDefault(p => p.DllFiles.Contains(assembly.Location)); if (plugin == null) { // A plugin's assembly didn't cause this issue, so ignore it. -- cgit v1.2.3 From 9bf970e5c6d67a7e55c9faceda042e45ad06b532 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 18 Dec 2020 21:59:14 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 1fd87273f..d7292f21b 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -629,11 +629,7 @@ namespace Emby.Server.Implementations.Plugins continue; } - if (manifest.Status != PluginStatus.Deleted) - { - manifest.Status = PluginStatus.Deleted; - SaveManifest(manifest, entry.Path); - } + ChangePluginState(entry, PluginStatus.Deleted); } } } -- cgit v1.2.3 From d34428f2f779dcd033f6cd060dc773515d2fbc6a Mon Sep 17 00:00:00 2001 From: Greenback Date: Fri, 18 Dec 2020 22:17:46 +0000 Subject: removed exception --- .../Plugins/PluginManager.cs | 120 +++++++++------------ 1 file changed, 52 insertions(+), 68 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index d7292f21b..32646d1bf 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -80,7 +80,7 @@ namespace Emby.Server.Implementations.Plugins // Now load the assemblies.. foreach (var plugin in _plugins) { - CheckIfStillSuperceded(plugin); + UpdatePluginSuperceedStatus(plugin); if (plugin.IsEnabledAndSupported == false) { @@ -134,7 +134,7 @@ namespace Emby.Server.Implementations.Plugins continue; } - CheckIfStillSuperceded(plugin); + UpdatePluginSuperceedStatus(plugin); if (!plugin.IsEnabledAndSupported) { continue; @@ -172,7 +172,7 @@ namespace Emby.Server.Implementations.Plugins // Load the plugin. var plugin = LoadManifest(folder); // Make sure we haven't already loaded this. - if (plugin == null || _plugins.Any(p => p.Manifest.Equals(plugin.Manifest))) + if (_plugins.Any(p => p.Manifest.Equals(plugin.Manifest))) { return; } @@ -435,7 +435,7 @@ namespace Emby.Server.Implementations.Plugins } } - private void CheckIfStillSuperceded(LocalPlugin plugin) + private void UpdatePluginSuperceedStatus(LocalPlugin plugin) { if (plugin.Manifest.Status != PluginStatus.Superceded) { @@ -464,7 +464,6 @@ namespace Emby.Server.Implementations.Plugins { Directory.Delete(plugin.Path, true); _logger.LogDebug("Deleted {Path}", plugin.Path); - _plugins.Remove(plugin); } #pragma warning disable CA1031 // Do not catch general exception types catch @@ -476,79 +475,69 @@ namespace Emby.Server.Implementations.Plugins return _plugins.Remove(plugin); } - private LocalPlugin? LoadManifest(string dir) + private LocalPlugin LoadManifest(string dir) { - try + Version? version; + PluginManifest? manifest = null; + var metafile = Path.Combine(dir, "meta.json"); + if (File.Exists(metafile)) { - Version? version; - PluginManifest? manifest = null; - var metafile = Path.Combine(dir, "meta.json"); - if (File.Exists(metafile)) + try { - try - { - var data = File.ReadAllText(metafile, Encoding.UTF8); - manifest = JsonSerializer.Deserialize(data, _jsonOptions); - } + var data = File.ReadAllText(metafile, Encoding.UTF8); + manifest = JsonSerializer.Deserialize(data, _jsonOptions); + } #pragma warning disable CA1031 // Do not catch general exception types - catch (Exception ex) + catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types - { - _logger.LogError(ex, "Error deserializing {Path}.", dir); - } - } - - if (manifest != null) { - if (!Version.TryParse(manifest.TargetAbi, out var targetAbi)) - { - targetAbi = _minimumVersion; - } - - if (!Version.TryParse(manifest.Version, out version)) - { - manifest.Version = _minimumVersion.ToString(); - } - - return new LocalPlugin(dir, _appVersion >= targetAbi, manifest); + _logger.LogError(ex, "Error deserializing {Path}.", dir); } + } - // No metafile, so lets see if the folder is versioned. - // TODO: Phase this support out in future versions. - metafile = dir.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)[^1]; - int versionIndex = dir.LastIndexOf('_'); - if (versionIndex != -1) + if (manifest != null) + { + if (!Version.TryParse(manifest.TargetAbi, out var targetAbi)) { - // Get the version number from the filename if possible. - metafile = Path.GetFileName(dir[..versionIndex]) ?? dir[..versionIndex]; - version = Version.TryParse(dir.AsSpan()[(versionIndex + 1)..], out Version? parsedVersion) ? parsedVersion : _appVersion; + targetAbi = _minimumVersion; } - else + + if (!Version.TryParse(manifest.Version, out version)) { - // Un-versioned folder - Add it under the path name and version it suitable for this instance. - version = _appVersion; + manifest.Version = _minimumVersion.ToString(); } - // Auto-create a plugin manifest, so we can disable it, if it fails to load. - manifest = new PluginManifest - { - Status = PluginStatus.Restart, - Name = metafile, - AutoUpdate = false, - Id = metafile.GetMD5(), - TargetAbi = _appVersion.ToString(), - Version = version.ToString() - }; + return new LocalPlugin(dir, _appVersion >= targetAbi, manifest); + } - return new LocalPlugin(dir, true, manifest); + // No metafile, so lets see if the folder is versioned. + // TODO: Phase this support out in future versions. + metafile = dir.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)[^1]; + int versionIndex = dir.LastIndexOf('_'); + if (versionIndex != -1) + { + // Get the version number from the filename if possible. + metafile = Path.GetFileName(dir[..versionIndex]) ?? dir[..versionIndex]; + version = Version.TryParse(dir.AsSpan()[(versionIndex + 1)..], out Version? parsedVersion) ? parsedVersion : _appVersion; } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception ex) -#pragma warning restore CA1031 // Do not catch general exception types + else { - _logger.LogError(ex, "Something went wrong!"); - return null; + // Un-versioned folder - Add it under the path name and version it suitable for this instance. + version = _appVersion; } + + // Auto-create a plugin manifest, so we can disable it, if it fails to load. + manifest = new PluginManifest + { + Status = PluginStatus.Restart, + Name = metafile, + AutoUpdate = false, + Id = metafile.GetMD5(), + TargetAbi = _appVersion.ToString(), + Version = version.ToString() + }; + + return new LocalPlugin(dir, true, manifest); } /// @@ -566,14 +555,9 @@ namespace Emby.Server.Implementations.Plugins } var directories = Directory.EnumerateDirectories(_pluginsPath, "*.*", SearchOption.TopDirectoryOnly); - LocalPlugin? entry; foreach (var dir in directories) { - entry = LoadManifest(dir); - if (entry != null) - { - versions.Add(entry); - } + versions.Add(LoadManifest(dir)); } string lastName = string.Empty; @@ -582,7 +566,7 @@ namespace Emby.Server.Implementations.Plugins // The first item will be the latest version. for (int x = versions.Count - 1; x >= 0; x--) { - entry = versions[x]; + var entry = versions[x]; if (!string.Equals(lastName, entry.Name, StringComparison.OrdinalIgnoreCase)) { entry.DllFiles.AddRange(Directory.EnumerateFiles(entry.Path, "*.dll", SearchOption.AllDirectories)); -- cgit v1.2.3 From 7a667619819bec314fdb6d0b4fd0c3290566297e Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sun, 20 Dec 2020 19:30:48 +0000 Subject: write json files indented. --- Emby.Server.Implementations/Plugins/PluginManager.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 32646d1bf..2497cddd9 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -50,6 +50,7 @@ namespace Emby.Server.Implementations.Plugins _pluginsPath = pluginsPath; _appVersion = appVersion ?? throw new ArgumentNullException(nameof(appVersion)); _jsonOptions = JsonDefaults.GetOptions(); + _jsonOptions.WriteIndented = true; _config = config; _appHost = appHost; _minimumVersion = new Version(0, 0, 0, 1); -- cgit v1.2.3 From 3633996a53385d78601df33286b47415475ae3bb Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 21 Dec 2020 09:01:59 +0000 Subject: New json converter implemented. --- .../Plugins/PluginManager.cs | 2 ++ .../Json/Converters/JsonGuidDashConverter.cs | 26 ++++++++++++++++++++++ MediaBrowser.Common/Plugins/PluginManifest.cs | 2 ++ 3 files changed, 30 insertions(+) create mode 100644 MediaBrowser.Common/Json/Converters/JsonGuidDashConverter.cs (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 2497cddd9..b46c19995 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -9,6 +9,7 @@ using System.Text.Json; using MediaBrowser.Common; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Json; +using MediaBrowser.Common.Json.Converters; using MediaBrowser.Common.Plugins; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Plugins; @@ -50,6 +51,7 @@ namespace Emby.Server.Implementations.Plugins _pluginsPath = pluginsPath; _appVersion = appVersion ?? throw new ArgumentNullException(nameof(appVersion)); _jsonOptions = JsonDefaults.GetOptions(); + _jsonOptions.Converters.Add(new JsonGuidDashConverter()); _jsonOptions.WriteIndented = true; _config = config; _appHost = appHost; diff --git a/MediaBrowser.Common/Json/Converters/JsonGuidDashConverter.cs b/MediaBrowser.Common/Json/Converters/JsonGuidDashConverter.cs new file mode 100644 index 000000000..75bab5875 --- /dev/null +++ b/MediaBrowser.Common/Json/Converters/JsonGuidDashConverter.cs @@ -0,0 +1,26 @@ +using System; +using System.Globalization; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace MediaBrowser.Common.Json.Converters +{ + /// + /// Converts a GUID object or value to/from JSON. + /// + public class JsonGuidDashConverter : JsonConverter + { + /// + public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var guidStr = reader.GetString(); + return guidStr == null ? Guid.Empty : new Guid(guidStr); + } + + /// + public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString()); + } + } +} diff --git a/MediaBrowser.Common/Plugins/PluginManifest.cs b/MediaBrowser.Common/Plugins/PluginManifest.cs index f93821429..956a91f85 100644 --- a/MediaBrowser.Common/Plugins/PluginManifest.cs +++ b/MediaBrowser.Common/Plugins/PluginManifest.cs @@ -1,6 +1,7 @@ #nullable enable using System; using System.Text.Json.Serialization; +using MediaBrowser.Common.Json.Converters; using MediaBrowser.Model.Plugins; namespace MediaBrowser.Common.Plugins @@ -32,6 +33,7 @@ namespace MediaBrowser.Common.Plugins /// Gets or sets the Global Unique Identifier for the plugin. /// [JsonPropertyName("guid")] + [JsonConverter(typeof(JsonGuidDashConverter))] public Guid Id { get; set; } /// -- cgit v1.2.3 From 621e6d28cda49fac580cf8c9c672b5fdfd3f743b Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 22 Dec 2020 14:07:01 +0000 Subject: Fallback to default guid --- .../Plugins/PluginManager.cs | 12 ++++++- .../Json/Converters/JsonGuidDashConverter.cs | 26 -------------- MediaBrowser.Common/Plugins/PluginManifest.cs | 40 ++++++++++++++++------ 3 files changed, 40 insertions(+), 38 deletions(-) delete mode 100644 MediaBrowser.Common/Json/Converters/JsonGuidDashConverter.cs (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index b46c19995..33faa5e9d 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -51,8 +51,18 @@ namespace Emby.Server.Implementations.Plugins _pluginsPath = pluginsPath; _appVersion = appVersion ?? throw new ArgumentNullException(nameof(appVersion)); _jsonOptions = JsonDefaults.GetOptions(); - _jsonOptions.Converters.Add(new JsonGuidDashConverter()); _jsonOptions.WriteIndented = true; + + // We need to use the default GUID converter, so we need to remove any custom ones. + for (int a = _jsonOptions.Converters.Count - 1; a >= 0; a--) + { + if (_jsonOptions.Converters[a] is JsonGuidConverter convertor) + { + _jsonOptions.Converters.Remove(convertor); + break; + } + } + _config = config; _appHost = appHost; _minimumVersion = new Version(0, 0, 0, 1); diff --git a/MediaBrowser.Common/Json/Converters/JsonGuidDashConverter.cs b/MediaBrowser.Common/Json/Converters/JsonGuidDashConverter.cs deleted file mode 100644 index 75bab5875..000000000 --- a/MediaBrowser.Common/Json/Converters/JsonGuidDashConverter.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Globalization; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace MediaBrowser.Common.Json.Converters -{ - /// - /// Converts a GUID object or value to/from JSON. - /// - public class JsonGuidDashConverter : JsonConverter - { - /// - public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var guidStr = reader.GetString(); - return guidStr == null ? Guid.Empty : new Guid(guidStr); - } - - /// - public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.ToString()); - } - } -} diff --git a/MediaBrowser.Common/Plugins/PluginManifest.cs b/MediaBrowser.Common/Plugins/PluginManifest.cs index 956a91f85..334c8d908 100644 --- a/MediaBrowser.Common/Plugins/PluginManifest.cs +++ b/MediaBrowser.Common/Plugins/PluginManifest.cs @@ -1,7 +1,7 @@ #nullable enable + using System; using System.Text.Json.Serialization; -using MediaBrowser.Common.Json.Converters; using MediaBrowser.Model.Plugins; namespace MediaBrowser.Common.Plugins @@ -11,54 +11,71 @@ namespace MediaBrowser.Common.Plugins /// public class PluginManifest { + /// + /// Initializes a new instance of the class. + /// + public PluginManifest() + { + Category = string.Empty; + Changelog = string.Empty; + Description = string.Empty; + Status = PluginStatus.Active; + Id = Guid.Empty; + Name = string.Empty; + Owner = string.Empty; + Overview = string.Empty; + TargetAbi = string.Empty; + Version = string.Empty; + AutoUpdate = true; + } + /// /// Gets or sets the category of the plugin. /// [JsonPropertyName("category")] - public string Category { get; set; } = string.Empty; + public string Category { get; set; } /// /// Gets or sets the changelog information. /// [JsonPropertyName("changelog")] - public string Changelog { get; set; } = string.Empty; + public string Changelog { get; set; } /// /// Gets or sets the description of the plugin. /// [JsonPropertyName("description")] - public string Description { get; set; } = string.Empty; + public string Description { get; set; } /// /// Gets or sets the Global Unique Identifier for the plugin. /// [JsonPropertyName("guid")] - [JsonConverter(typeof(JsonGuidDashConverter))] public Guid Id { get; set; } /// /// Gets or sets the Name of the plugin. /// [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + public string Name { get; set; } /// /// Gets or sets an overview of the plugin. /// [JsonPropertyName("overview")] - public string Overview { get; set; } = string.Empty; + public string Overview { get; set; } /// /// Gets or sets the owner of the plugin. /// [JsonPropertyName("owner")] - public string Owner { get; set; } = string.Empty; + public string Owner { get; set; } /// /// Gets or sets the compatibility version for the plugin. /// [JsonPropertyName("targetAbi")] - public string TargetAbi { get; set; } = string.Empty; + public string TargetAbi { get; set; } /// /// Gets or sets the timestamp of the plugin. @@ -70,7 +87,7 @@ namespace MediaBrowser.Common.Plugins /// Gets or sets the Version number of the plugin. /// [JsonPropertyName("version")] - public string Version { get; set; } = string.Empty; + public string Version { get; set; } /// /// Gets or sets a value indicating the operational status of this plugin. @@ -82,9 +99,10 @@ namespace MediaBrowser.Common.Plugins /// Gets or sets a value indicating whether this plugin should automatically update. /// [JsonPropertyName("autoUpdate")] - public bool AutoUpdate { get; set; } = true; + public bool AutoUpdate { get; set; } /// + /// Gets or sets the ImagePath /// Gets or sets a value indicating whether this plugin has an image. /// Image must be located in the local plugin folder. /// -- cgit v1.2.3 From 1f2ecd0775f291457e780733339bb5009ebb8408 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 22 Dec 2020 15:01:26 +0000 Subject: Fix for DI. --- Emby.Server.Implementations/Plugins/PluginManager.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 33faa5e9d..fbb092a7c 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -140,7 +140,7 @@ namespace Emby.Server.Implementations.Plugins { foreach (var pluginServiceRegistrator in _appHost.GetExportTypes()) { - var plugin = GetPluginByType(pluginServiceRegistrator.Assembly.GetType()); + var plugin = GetPluginByAssembly(pluginServiceRegistrator.Assembly); if (plugin == null) { _logger.LogError("Unable to find plugin in assembly {Assembly}", pluginServiceRegistrator.Assembly.FullName); @@ -350,14 +350,14 @@ namespace Emby.Server.Implementations.Plugins } /// - /// Finds the plugin record using the type. + /// Finds the plugin record using the assembly. /// - /// The being sought. + /// The being sought. /// The matching record, or null if not found. - private LocalPlugin? GetPluginByType(Type type) + private LocalPlugin? GetPluginByAssembly(Assembly assembly) { // Find which plugin it is by the path. - return _plugins.FirstOrDefault(p => string.Equals(p.Path, Path.GetDirectoryName(type.Assembly.Location), StringComparison.Ordinal)); + return _plugins.FirstOrDefault(p => string.Equals(p.Path, Path.GetDirectoryName(assembly.Location), StringComparison.Ordinal)); } /// @@ -368,7 +368,7 @@ namespace Emby.Server.Implementations.Plugins private IPlugin? CreatePluginInstance(Type type) { // Find the record for this plugin. - var plugin = GetPluginByType(type); + var plugin = GetPluginByAssembly(type.Assembly); if (plugin?.Manifest.Status < PluginStatus.Active) { return null; -- cgit v1.2.3 From 4ba4eefeeb145d03c1599c12a1ef61b4f87f67fb Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 23 Dec 2020 10:26:02 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Claus Vium --- Emby.Server.Implementations/Plugins/PluginManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index fbb092a7c..2609f6fca 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -232,9 +232,9 @@ namespace Emby.Server.Implementations.Plugins var plugins = _plugins.Where(p => p.Id.Equals(id)); plugin = plugins.FirstOrDefault(p => p.Instance != null); - if (plugin == null) + if (plugin == null && plugins.Length > 0) { - plugin = plugins.OrderByDescending(p => p.Version).FirstOrDefault(); + plugin = plugins.OrderByDescending(p => p.Version)[0]; } } else -- cgit v1.2.3 From 9a97933499d4171e6ff7d2d860845c1cc54ef7d8 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 23 Dec 2020 10:29:21 +0000 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Claus Vium --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 2609f6fca..dac3100af 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -229,7 +229,7 @@ namespace Emby.Server.Implementations.Plugins if (version == null) { // If no version is given, return the current instance. - var plugins = _plugins.Where(p => p.Id.Equals(id)); + var plugins = _plugins.Where(p => p.Id.Equals(id)).ToList(); plugin = plugins.FirstOrDefault(p => p.Instance != null); if (plugin == null && plugins.Length > 0) -- cgit v1.2.3 From e8df9551ef392785c0fb7269b9e187cd199390d8 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 23 Dec 2020 10:31:11 +0000 Subject: Update PluginManager.cs Changed a to i --- Emby.Server.Implementations/Plugins/PluginManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index dac3100af..629975abb 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -81,9 +81,9 @@ namespace Emby.Server.Implementations.Plugins public IEnumerable LoadAssemblies() { // Attempt to remove any deleted plugins and change any successors to be active. - for (int a = _plugins.Count - 1; a >= 0; a--) + for (int i = _plugins.Count - 1; i >= 0; i--) { - var plugin = _plugins[a]; + var plugin = _plugins[i]; if (plugin.Manifest.Status == PluginStatus.Deleted && DeletePlugin(plugin)) { UpdateSuccessors(plugin); -- cgit v1.2.3 From 62702fa3eb5070ce8c57dc4e39551bcc4e64fa74 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 23 Dec 2020 16:28:50 +0000 Subject: Changes as requested --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- .../Plugins/PluginManager.cs | 45 +++++++++++++++------- Jellyfin.Api/Controllers/PluginsController.cs | 16 ++------ Jellyfin.Api/Models/ConfigurationPageInfo.cs | 1 - MediaBrowser.Common/Plugins/BasePluginOfT.cs | 20 +++------- .../Plugins/IHasPluginConfiguration.cs | 6 --- MediaBrowser.Common/Plugins/IPluginManager.cs | 1 + MediaBrowser.Common/Plugins/PluginManifest.cs | 4 +- 8 files changed, 43 insertions(+), 52 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index f73cd1ea4..b91ba6b6c 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -462,7 +462,7 @@ namespace Emby.Server.Implementations { // Convert to list so this isn't executed for each iteration var parts = GetExportTypes() - .Select(defaultFunc) + .Select(i => defaultFunc(i)) .Where(i => i != null) .Cast() .ToList(); diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 629975abb..c06359757 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Reflection; using System.Text; using System.Text.Json; +using System.Threading.Tasks; using MediaBrowser.Common; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Json; @@ -86,7 +87,8 @@ namespace Emby.Server.Implementations.Plugins var plugin = _plugins[i]; if (plugin.Manifest.Status == PluginStatus.Deleted && DeletePlugin(plugin)) { - UpdateSuccessors(plugin); + // See if there is another version, and if so make that active. + ProcessAlternative(plugin); } } @@ -208,12 +210,19 @@ namespace Emby.Server.Implementations.Plugins if (DeletePlugin(plugin)) { + ProcessAlternative(plugin); return true; } _logger.LogWarning("Unable to delete {Path}, so marking as deleteOnStartup.", plugin.Path); // Unable to delete, so disable. - return ChangePluginState(plugin, PluginStatus.Deleted); + if (ChangePluginState(plugin, PluginStatus.Deleted)) + { + ProcessAlternative(plugin); + return true; + } + + return false; } /// @@ -232,9 +241,9 @@ namespace Emby.Server.Implementations.Plugins var plugins = _plugins.Where(p => p.Id.Equals(id)).ToList(); plugin = plugins.FirstOrDefault(p => p.Instance != null); - if (plugin == null && plugins.Length > 0) + if (plugin == null) { - plugin = plugins.OrderByDescending(p => p.Version)[0]; + plugin = plugins.OrderByDescending(p => p.Version).FirstOrDefault(); } } else @@ -259,7 +268,8 @@ namespace Emby.Server.Implementations.Plugins if (ChangePluginState(plugin, PluginStatus.Active)) { - UpdateSuccessors(plugin); + // See if there is another version, and if so, supercede it. + ProcessAlternative(plugin); } } @@ -277,7 +287,8 @@ namespace Emby.Server.Implementations.Plugins // Update the manifest on disk if (ChangePluginState(plugin, PluginStatus.Disabled)) { - UpdateSuccessors(plugin); + // If there is another version, activate it. + ProcessAlternative(plugin); } } @@ -639,27 +650,33 @@ namespace Emby.Server.Implementations.Plugins /// Changes the status of the other versions of the plugin to "Superceded". /// /// The that's master. - private void UpdateSuccessors(LocalPlugin plugin) + private void ProcessAlternative(LocalPlugin plugin) { - // This value is memory only - so that the web will show restart required. - plugin.Manifest.Status = PluginStatus.Restart; - // Detect whether there is another version of this plugin that needs disabling. - var predecessor = _plugins.OrderByDescending(p => p.Version) + var previousVersion = _plugins.OrderByDescending(p => p.Version) .FirstOrDefault( p => p.Id.Equals(plugin.Id) && p.IsEnabledAndSupported && p.Version != plugin.Version); - if (predecessor == null) + if (previousVersion == null) { + // This value is memory only - so that the web will show restart required. + plugin.Manifest.Status = PluginStatus.Restart; return; } - if (predecessor.Manifest.Status == PluginStatus.Active && !ChangePluginState(predecessor, PluginStatus.Superceded)) + if (plugin.Manifest.Status == PluginStatus.Active && !ChangePluginState(previousVersion, PluginStatus.Superceded)) + { + _logger.LogError("Unable to enable version {Version} of {Name}", previousVersion.Version, previousVersion.Name); + } + else if (plugin.Manifest.Status == PluginStatus.Superceded && !ChangePluginState(previousVersion, PluginStatus.Active)) { - _logger.LogError("Unable to disable version {Version} of {Name}", predecessor.Version, predecessor.Name); + _logger.LogError("Unable to supercede version {Version} of {Name}", previousVersion.Version, previousVersion.Name); } + + // This value is memory only - so that the web will show restart required. + plugin.Manifest.Status = PluginStatus.Restart; } } } diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index 365bb2248..b73611c97 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -198,7 +198,7 @@ namespace Jellyfin.Api.Controllers /// Plugin id. /// Plugin uninstalled. /// Plugin not found. - /// An on success, or a if the file could not be found. + /// An on success, or a if the plugin could not be found. [HttpDelete("{pluginId}")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -210,7 +210,7 @@ namespace Jellyfin.Api.Controllers var plugins = _pluginManager.Plugins.Where(p => p.Id.Equals(pluginId)); // Select the un-instanced one first. - var plugin = plugins.FirstOrDefault(p => p.Instance != null); + var plugin = plugins.FirstOrDefault(p => p.Instance == null); if (plugin == null) { // Then by the status. @@ -256,11 +256,7 @@ namespace Jellyfin.Api.Controllers /// Plugin id. /// Plugin configuration updated. /// Plugin not found or plugin does not have configuration. - /// - /// A that represents the asynchronous operation to update plugin configuration. - /// The task result contains an indicating success, or - /// when plugin not found or plugin doesn't have configuration. - /// + /// An on success, or a if the plugin could not be found. [HttpPost("{pluginId}/Configuration")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] @@ -321,11 +317,7 @@ namespace Jellyfin.Api.Controllers /// Plugin id. /// Plugin manifest returned. /// Plugin not found. - /// - /// A that represents the asynchronous operation to get the plugin's manifest. - /// The task result contains an indicating success, or - /// when plugin not found. - /// + /// A on success, or a if the plugin could not be found. [HttpPost("{pluginId}/Manifest")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] diff --git a/Jellyfin.Api/Models/ConfigurationPageInfo.cs b/Jellyfin.Api/Models/ConfigurationPageInfo.cs index c15ed05d3..f56ef5976 100644 --- a/Jellyfin.Api/Models/ConfigurationPageInfo.cs +++ b/Jellyfin.Api/Models/ConfigurationPageInfo.cs @@ -23,7 +23,6 @@ namespace Jellyfin.Api.Models if (page.Plugin != null) { DisplayName = page.Plugin.Name; - // Don't use "N" because it needs to match Plugin.Id PluginId = page.Plugin.Id; } } diff --git a/MediaBrowser.Common/Plugins/BasePluginOfT.cs b/MediaBrowser.Common/Plugins/BasePluginOfT.cs index ea05a722b..d5c780851 100644 --- a/MediaBrowser.Common/Plugins/BasePluginOfT.cs +++ b/MediaBrowser.Common/Plugins/BasePluginOfT.cs @@ -25,8 +25,6 @@ namespace MediaBrowser.Common.Plugins /// private readonly object _configurationSaveLock = new object(); - private Action _directoryCreateFn; - /// /// The configuration. /// @@ -65,11 +63,6 @@ namespace MediaBrowser.Common.Plugins assemblyPlugin.SetId(assemblyId); } } - - if (this is IHasPluginConfiguration hasPluginConfiguration) - { - hasPluginConfiguration.SetStartupInfo(s => Directory.CreateDirectory(s)); - } } /// @@ -145,13 +138,6 @@ namespace MediaBrowser.Common.Plugins /// The configuration. BasePluginConfiguration IHasPluginConfiguration.Configuration => Configuration; - /// - public void SetStartupInfo(Action directoryCreateFn) - { - // hack alert, until the .net core transition is complete - _directoryCreateFn = directoryCreateFn; - } - /// /// Saves the current configuration to the file system. /// @@ -160,7 +146,11 @@ namespace MediaBrowser.Common.Plugins { lock (_configurationSaveLock) { - _directoryCreateFn(Path.GetDirectoryName(ConfigurationFilePath)); + var folder = Path.GetDirectoryName(ConfigurationFilePath); + if (!Directory.Exists(folder)) + { + Directory.CreateDirectory(folder); + } XmlSerializer.SerializeToFile(config, ConfigurationFilePath); } diff --git a/MediaBrowser.Common/Plugins/IHasPluginConfiguration.cs b/MediaBrowser.Common/Plugins/IHasPluginConfiguration.cs index 42ad85dd3..af9272caa 100644 --- a/MediaBrowser.Common/Plugins/IHasPluginConfiguration.cs +++ b/MediaBrowser.Common/Plugins/IHasPluginConfiguration.cs @@ -23,11 +23,5 @@ namespace MediaBrowser.Common.Plugins /// /// The configuration. void UpdateConfiguration(BasePluginConfiguration configuration); - - /// - /// Sets the startup directory creation function. - /// - /// The directory function used to create the configuration folder. - void SetStartupInfo(Action directoryCreateFn); } } diff --git a/MediaBrowser.Common/Plugins/IPluginManager.cs b/MediaBrowser.Common/Plugins/IPluginManager.cs index 7f7381b03..3da34d8bb 100644 --- a/MediaBrowser.Common/Plugins/IPluginManager.cs +++ b/MediaBrowser.Common/Plugins/IPluginManager.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; namespace MediaBrowser.Common.Plugins diff --git a/MediaBrowser.Common/Plugins/PluginManifest.cs b/MediaBrowser.Common/Plugins/PluginManifest.cs index 334c8d908..4c724f694 100644 --- a/MediaBrowser.Common/Plugins/PluginManifest.cs +++ b/MediaBrowser.Common/Plugins/PluginManifest.cs @@ -19,14 +19,12 @@ namespace MediaBrowser.Common.Plugins Category = string.Empty; Changelog = string.Empty; Description = string.Empty; - Status = PluginStatus.Active; Id = Guid.Empty; Name = string.Empty; Owner = string.Empty; Overview = string.Empty; TargetAbi = string.Empty; Version = string.Empty; - AutoUpdate = true; } /// @@ -99,7 +97,7 @@ namespace MediaBrowser.Common.Plugins /// Gets or sets a value indicating whether this plugin should automatically update. /// [JsonPropertyName("autoUpdate")] - public bool AutoUpdate { get; set; } + public bool AutoUpdate { get; set; } = true; // DO NOT MOVE THIS INTO THE CONSTRUCTOR. /// /// Gets or sets the ImagePath -- cgit v1.2.3 From 21f6d3943264b0f6a59f3312e9ec34a3b6269af2 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 23 Dec 2020 17:43:29 +0000 Subject: copy constructor --- Emby.Server.Implementations/Plugins/PluginManager.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index c06359757..51a75f6a3 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -51,8 +51,10 @@ namespace Emby.Server.Implementations.Plugins _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _pluginsPath = pluginsPath; _appVersion = appVersion ?? throw new ArgumentNullException(nameof(appVersion)); - _jsonOptions = JsonDefaults.GetOptions(); - _jsonOptions.WriteIndented = true; + _jsonOptions = new JsonSerializerOptions(JsonDefaults.GetOptions()) + { + WriteIndented = true + }; // We need to use the default GUID converter, so we need to remove any custom ones. for (int a = _jsonOptions.Converters.Count - 1; a >= 0; a--) -- cgit v1.2.3 From 149c2b2169192da29d82c440175d8d9049dea8b3 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Thu, 31 Dec 2020 11:39:34 +0000 Subject: Added referenced assembly failure detection, and DI failure protection. --- Emby.Server.Implementations/ApplicationHost.cs | 2 ++ Emby.Server.Implementations/Plugins/PluginManager.cs | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 094134318..1b9bb86bb 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -413,6 +413,8 @@ namespace Emby.Server.Implementations catch (Exception ex) { Logger.LogError(ex, "Error creating {Type}", type); + // If this is a plugin fail it. + _pluginManager.FailPlugin(type.Assembly); return null; } finally diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 51a75f6a3..1ab01252d 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -111,6 +111,10 @@ namespace Emby.Server.Implementations.Plugins try { assembly = Assembly.LoadFrom(file); + + // This force loads all reference dll's that the plugin uses in the try..catch block. + // Removing this will cause JF to bomb out if referenced dll's cause issues. + assembly.GetExportedTypes(); } catch (FileLoadException ex) { -- cgit v1.2.3 From 1ea2b200c0b38f9d9a058f5e4b6e27815a016860 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Tue, 12 Jan 2021 15:28:02 +0100 Subject: JsonSerializer deserialize from bytes where possible This is faster and uses way less memory ``` BenchmarkDotNet=v0.12.1, OS=fedora 32 Intel Core i7-6700HQ CPU 2.60GHz (Skylake), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=5.0.100 [Host] : .NET Core 5.0.0 (CoreCLR 5.0.20.51904, CoreFX 5.0.20.51904), X64 RyuJIT DefaultJob : .NET Core 5.0.0 (CoreCLR 5.0.20.51904, CoreFX 5.0.20.51904), X64 RyuJIT | Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated | |------- |---------:|--------:|--------:|--------:|------:|------:|----------:| | Bytes | 158.4 us | 2.56 us | 2.14 us | 16.8457 | - | - | 52.08 KB | | String | 172.8 us | 0.78 us | 0.70 us | 41.5039 | - | - | 127.82 KB | | Custom | 155.5 us | 2.95 us | 2.76 us | 10.0098 | - | - | 31.27 KB | ``` --- .../Channels/ChannelManager.cs | 10 +++++----- .../LiveTv/EmbyTV/ItemDataProvider.cs | 6 +++--- Emby.Server.Implementations/Plugins/PluginManager.cs | 6 ++---- .../ScheduledTasks/ScheduledTaskWorker.cs | 20 ++++++++++---------- .../Routines/MigrateDisplayPreferencesDb.cs | 2 +- 5 files changed, 21 insertions(+), 23 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 2d5b19fa6..8c5fa09f6 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -336,19 +336,19 @@ namespace Emby.Server.Implementations.Channels return GetChannel(GetInternalChannelId(channel.Name)) ?? GetChannel(channel, CancellationToken.None).Result; } - private List GetSavedMediaSources(BaseItem item) + private MediaSourceInfo[] GetSavedMediaSources(BaseItem item) { var path = Path.Combine(item.GetInternalMetadataPath(), "channelmediasourceinfos.json"); try { - var jsonString = File.ReadAllText(path, Encoding.UTF8); - return JsonSerializer.Deserialize>(jsonString, _jsonOptions) - ?? new List(); + var bytes = File.ReadAllBytes(path); + return JsonSerializer.Deserialize(bytes, _jsonOptions) + ?? Array.Empty(); } catch { - return new List(); + return Array.Empty(); } } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs index c80ecd6b3..57424f043 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs @@ -47,11 +47,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV try { - var jsonString = File.ReadAllText(_dataPath, Encoding.UTF8); - _items = JsonSerializer.Deserialize(jsonString, _jsonOptions); + var bytes = File.ReadAllBytes(_dataPath); + _items = JsonSerializer.Deserialize(bytes, _jsonOptions); return; } - catch (Exception ex) + catch (JsonException ex) { Logger.LogError(ex, "Error deserializing {Path}", _dataPath); } diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 1ab01252d..e7fcc1f58 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -514,12 +514,10 @@ namespace Emby.Server.Implementations.Plugins { try { - var data = File.ReadAllText(metafile, Encoding.UTF8); + var data = File.ReadAllBytes(metafile); manifest = JsonSerializer.Deserialize(data, _jsonOptions); } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception ex) -#pragma warning restore CA1031 // Do not catch general exception types + catch (JsonException ex) { _logger.LogError(ex, "Error deserializing {Path}.", dir); } diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index 29440b64a..1d93b63a8 100644 --- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -143,21 +143,21 @@ namespace Emby.Server.Implementations.ScheduledTasks { if (File.Exists(path)) { - try + var bytes = File.ReadAllBytes(path); + if (bytes.Length > 0) { - var jsonString = File.ReadAllText(path, Encoding.UTF8); - if (!string.IsNullOrWhiteSpace(jsonString)) + try { - _lastExecutionResult = JsonSerializer.Deserialize(jsonString, _jsonOptions); + _lastExecutionResult = JsonSerializer.Deserialize(bytes, _jsonOptions); } - else + catch (JsonException ex) { - _logger.LogDebug("Scheduled Task history file {Path} is empty. Skipping deserialization.", path); + _logger.LogError(ex, "Error deserializing {File}", path); } } - catch (Exception ex) + else { - _logger.LogError(ex, "Error deserializing {File}", path); + _logger.LogDebug("Scheduled Task history file {Path} is empty. Skipping deserialization.", path); } } @@ -541,8 +541,8 @@ namespace Emby.Server.Implementations.ScheduledTasks TaskTriggerInfo[] list = null; if (File.Exists(path)) { - var jsonString = File.ReadAllText(path, Encoding.UTF8); - list = JsonSerializer.Deserialize(jsonString, _jsonOptions); + var bytes = File.ReadAllBytes(path); + list = JsonSerializer.Deserialize(bytes, _jsonOptions); } // Return defaults if file doesn't exist. diff --git a/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs index f4040748d..07829c696 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs @@ -90,7 +90,7 @@ namespace Jellyfin.Server.Migrations.Routines var results = connection.Query("SELECT * FROM userdisplaypreferences"); foreach (var result in results) { - var dto = JsonSerializer.Deserialize(result[3].ToString(), _jsonOptions); + var dto = JsonSerializer.Deserialize(result[3].ToBlob(), _jsonOptions); if (dto == null) { continue; -- cgit v1.2.3 From 1fdd2d6e0527a7b112ed6d79d8854f6fbe6fdaca Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Tue, 12 Jan 2021 16:03:13 +0100 Subject: Handle IO errors in LoadManifest --- .../Plugins/PluginManager.cs | 32 +++++++++++++--------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index e7fcc1f58..c4598f281 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -512,30 +512,36 @@ namespace Emby.Server.Implementations.Plugins var metafile = Path.Combine(dir, "meta.json"); if (File.Exists(metafile)) { + // Only path where this stays null is when File.ReadAllBytes throws an IOException + byte[] data = null!; try { - var data = File.ReadAllBytes(metafile); + data = File.ReadAllBytes(metafile); manifest = JsonSerializer.Deserialize(data, _jsonOptions); } - catch (JsonException ex) + catch (IOException ex) { - _logger.LogError(ex, "Error deserializing {Path}.", dir); + _logger.LogError(ex, "Error reading file {Path}.", dir); } - } - - if (manifest != null) - { - if (!Version.TryParse(manifest.TargetAbi, out var targetAbi)) + catch (JsonException ex) { - targetAbi = _minimumVersion; + _logger.LogError(ex, "Error deserializing {Json}.", Encoding.UTF8.GetString(data!)); } - if (!Version.TryParse(manifest.Version, out version)) + if (manifest != null) { - manifest.Version = _minimumVersion.ToString(); - } + if (!Version.TryParse(manifest.TargetAbi, out var targetAbi)) + { + targetAbi = _minimumVersion; + } + + if (!Version.TryParse(manifest.Version, out version)) + { + manifest.Version = _minimumVersion.ToString(); + } - return new LocalPlugin(dir, _appVersion >= targetAbi, manifest); + return new LocalPlugin(dir, _appVersion >= targetAbi, manifest); + } } // No metafile, so lets see if the folder is versioned. -- cgit v1.2.3 From 89046e1d97f5d01dfbacab64bc7713d6487f3de9 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 19 Jan 2021 21:15:40 +0000 Subject: Bug fixes --- Emby.Server.Implementations/Plugins/PluginManager.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 1ab01252d..9f597f3ef 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -374,7 +374,7 @@ namespace Emby.Server.Implementations.Plugins private LocalPlugin? GetPluginByAssembly(Assembly assembly) { // Find which plugin it is by the path. - return _plugins.FirstOrDefault(p => string.Equals(p.Path, Path.GetDirectoryName(assembly.Location), StringComparison.Ordinal)); + return _plugins.FirstOrDefault(p => p.DllFiles.Contains(assembly.Location, StringComparer.Ordinal)); } /// @@ -421,15 +421,17 @@ namespace Emby.Server.Implementations.Plugins { plugin.Instance = instance; var manifest = plugin.Manifest; - var pluginStr = plugin.Instance.Version.ToString(); + var pluginStr = instance.Version.ToString(); bool changed = false; - if (string.Equals(manifest.Version, pluginStr, StringComparison.Ordinal)) + if (string.Equals(manifest.Version, pluginStr, StringComparison.Ordinal) + || manifest.Id != instance.Id) { // If a plugin without a manifest failed to load due to an external issue (eg config), // this updates the manifest to the actual plugin values. manifest.Version = pluginStr; manifest.Name = plugin.Instance.Name; manifest.Description = plugin.Instance.Description; + manifest.Id = plugin.Instance.Id; changed = true; } @@ -559,7 +561,7 @@ namespace Emby.Server.Implementations.Plugins // Auto-create a plugin manifest, so we can disable it, if it fails to load. manifest = new PluginManifest { - Status = PluginStatus.Restart, + Status = PluginStatus.Active, Name = metafile, AutoUpdate = false, Id = metafile.GetMD5(), -- cgit v1.2.3 From 4adbbb9f5111d2386f1f0a9c5aaa173d041e9c90 Mon Sep 17 00:00:00 2001 From: David Ullmer Date: Sun, 24 Jan 2021 00:57:37 +0100 Subject: Catch TypeLoadException during plugin loading --- Emby.Server.Implementations/Plugins/PluginManager.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 9f597f3ef..42c76bd66 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -122,6 +122,12 @@ namespace Emby.Server.Implementations.Plugins ChangePluginState(plugin, PluginStatus.Malfunctioned); continue; } + catch (TypeLoadException ex) + { + _logger.LogError(ex, "Failed to load assembly {Path}. Disabling plugin. This is probably caused by an incompatible plugin version.", file); + ChangePluginState(plugin, PluginStatus.Malfunctioned); + continue; + } _logger.LogInformation("Loaded assembly {Assembly} from {Path}", assembly.FullName, file); yield return assembly; -- cgit v1.2.3 From 80f3e20394bc249914ddcb430b4f6d63761ebd29 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 24 Jan 2021 13:22:04 +0100 Subject: Change plugin error message --- Emby.Server.Implementations/Plugins/PluginManager.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 42c76bd66..9621b34b6 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -112,9 +112,16 @@ namespace Emby.Server.Implementations.Plugins { assembly = Assembly.LoadFrom(file); - // This force loads all reference dll's that the plugin uses in the try..catch block. - // Removing this will cause JF to bomb out if referenced dll's cause issues. - assembly.GetExportedTypes(); + try + { + assembly.GetExportedTypes(); + } + catch (TypeLoadException ex) // Undocumented exception + { + _logger.LogError(ex, "Failed to load assembly {Path}. This error occurs when a plugin references an incompatible version of one of the shared libraries. Disabling plugin.", file); + ChangePluginState(plugin, PluginStatus.NotSupported); + continue; + } } catch (FileLoadException ex) { @@ -122,12 +129,6 @@ namespace Emby.Server.Implementations.Plugins ChangePluginState(plugin, PluginStatus.Malfunctioned); continue; } - catch (TypeLoadException ex) - { - _logger.LogError(ex, "Failed to load assembly {Path}. Disabling plugin. This is probably caused by an incompatible plugin version.", file); - ChangePluginState(plugin, PluginStatus.Malfunctioned); - continue; - } _logger.LogInformation("Loaded assembly {Assembly} from {Path}", assembly.FullName, file); yield return assembly; -- cgit v1.2.3 From 677bba742e343271be39d4da6d10eca9720c0403 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 24 Jan 2021 13:34:22 +0100 Subject: Remove try-catch nesting --- Emby.Server.Implementations/Plugins/PluginManager.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 9621b34b6..de4b71433 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -112,16 +112,7 @@ namespace Emby.Server.Implementations.Plugins { assembly = Assembly.LoadFrom(file); - try - { - assembly.GetExportedTypes(); - } - catch (TypeLoadException ex) // Undocumented exception - { - _logger.LogError(ex, "Failed to load assembly {Path}. This error occurs when a plugin references an incompatible version of one of the shared libraries. Disabling plugin.", file); - ChangePluginState(plugin, PluginStatus.NotSupported); - continue; - } + assembly.GetExportedTypes(); } catch (FileLoadException ex) { @@ -129,6 +120,12 @@ namespace Emby.Server.Implementations.Plugins ChangePluginState(plugin, PluginStatus.Malfunctioned); continue; } + catch (TypeLoadException ex) // Undocumented exception + { + _logger.LogError(ex, "Failed to load assembly {Path}. This error occurs when a plugin references an incompatible version of one of the shared libraries. Disabling plugin.", file); + ChangePluginState(plugin, PluginStatus.NotSupported); + continue; + } _logger.LogInformation("Loaded assembly {Assembly} from {Path}", assembly.FullName, file); yield return assembly; -- cgit v1.2.3 From b014f2309d546779d7e9530daa1ddd55741cbb32 Mon Sep 17 00:00:00 2001 From: David Ullmer Date: Mon, 25 Jan 2021 09:44:06 +0100 Subject: Update Emby.Server.Implementations/Plugins/PluginManager.cs Co-authored-by: Claus Vium --- Emby.Server.Implementations/Plugins/PluginManager.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index de4b71433..adf62124a 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -126,6 +126,14 @@ namespace Emby.Server.Implementations.Plugins ChangePluginState(plugin, PluginStatus.NotSupported); continue; } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception ex) +#pragma warning restore CA1031 // Do not catch general exception types + { + _logger.LogError(ex, "Failed to load assembly {Path}. Unknown exception was thrown. Disabling plugin.", file); + ChangePluginState(plugin, PluginStatus.Malfunctioned); + continue; + } _logger.LogInformation("Loaded assembly {Assembly} from {Path}", assembly.FullName, file); yield return assembly; -- cgit v1.2.3 From 311b2f50122237d96fc93fc48c3658f4970de5a2 Mon Sep 17 00:00:00 2001 From: cvium Date: Mon, 8 Feb 2021 15:38:06 +0100 Subject: Exclude BOM when writing meta.json plugin manifest --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 8e5987026..2e2b3f332 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -348,7 +348,7 @@ namespace Emby.Server.Implementations.Plugins try { var data = JsonSerializer.Serialize(manifest, _jsonOptions); - File.WriteAllText(Path.Combine(path, "meta.json"), data, Encoding.UTF8); + File.WriteAllText(Path.Combine(path, "meta.json"), data); return true; } #pragma warning disable CA1031 // Do not catch general exception types -- cgit v1.2.3 From 13c1c2815f82be2bd316f73fe377b1ff3587e24f Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 8 Feb 2021 17:10:20 +0100 Subject: Add regression test for PluginManager.SaveManifest --- .../Plugins/PluginManager.cs | 2 +- .../Plugins/PluginManagerTests.cs | 45 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/Jellyfin.Server.Implementations.Tests/Plugins/PluginManagerTests.cs (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 2e2b3f332..c26ccfd88 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -519,7 +519,7 @@ namespace Emby.Server.Implementations.Plugins return _plugins.Remove(plugin); } - private LocalPlugin LoadManifest(string dir) + internal LocalPlugin LoadManifest(string dir) { Version? version; PluginManifest? manifest = null; diff --git a/tests/Jellyfin.Server.Implementations.Tests/Plugins/PluginManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Plugins/PluginManagerTests.cs new file mode 100644 index 000000000..bc6a44741 --- /dev/null +++ b/tests/Jellyfin.Server.Implementations.Tests/Plugins/PluginManagerTests.cs @@ -0,0 +1,45 @@ +using System; +using System.IO; +using Emby.Server.Implementations.Plugins; +using MediaBrowser.Common.Plugins; +using Microsoft.Extensions.Logging.Abstractions; +using Xunit; + +namespace Jellyfin.Server.Implementations.Tests.Plugins +{ + public class PluginManagerTests + { + private static readonly string _testPathRoot = Path.Combine(Path.GetTempPath(), "jellyfin-test-data"); + + [Fact] + public void SaveManifest_RoundTrip_Success() + { + var pluginManager = new PluginManager(new NullLogger(), null!, null!, null!, new Version(1, 0)); + var manifest = new PluginManifest() + { + Version = "1.0" + }; + + var tempPath = Path.Combine(_testPathRoot, "manifest-" + Path.GetRandomFileName()); + Directory.CreateDirectory(tempPath); + + Assert.True(pluginManager.SaveManifest(manifest, tempPath)); + + var res = pluginManager.LoadManifest(tempPath); + + Assert.Equal(manifest.Category, res.Manifest.Category); + Assert.Equal(manifest.Changelog, res.Manifest.Changelog); + Assert.Equal(manifest.Description, res.Manifest.Description); + Assert.Equal(manifest.Id, res.Manifest.Id); + Assert.Equal(manifest.Name, res.Manifest.Name); + Assert.Equal(manifest.Overview, res.Manifest.Overview); + Assert.Equal(manifest.Owner, res.Manifest.Owner); + Assert.Equal(manifest.TargetAbi, res.Manifest.TargetAbi); + Assert.Equal(manifest.Timestamp, res.Manifest.Timestamp); + Assert.Equal(manifest.Version, res.Manifest.Version); + Assert.Equal(manifest.Status, res.Manifest.Status); + Assert.Equal(manifest.AutoUpdate, res.Manifest.AutoUpdate); + Assert.Equal(manifest.ImagePath, res.Manifest.ImagePath); + } + } +} -- cgit v1.2.3 From 9caf3119257544d6fb8fd3e1f1cb2b50eba7bd39 Mon Sep 17 00:00:00 2001 From: dkanada Date: Fri, 12 Feb 2021 22:33:10 +0900 Subject: handle plugin manifests automatically --- .../Plugins/PluginManager.cs | 56 +++++++++++++++------- .../Updates/InstallationManager.cs | 22 ++------- MediaBrowser.Common/Plugins/IPluginManager.cs | 10 ++++ MediaBrowser.Model/Updates/InstallationInfo.cs | 7 +++ 4 files changed, 61 insertions(+), 34 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index c26ccfd88..696133c9f 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -1,12 +1,13 @@ #nullable enable + using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; using System.Reflection; using System.Text; using System.Text.Json; -using System.Threading.Tasks; using MediaBrowser.Common; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Json; @@ -14,6 +15,7 @@ using MediaBrowser.Common.Json.Converters; using MediaBrowser.Common.Plugins; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Plugins; +using MediaBrowser.Model.Updates; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -332,34 +334,54 @@ namespace Emby.Server.Implementations.Plugins ChangePluginState(plugin, PluginStatus.Malfunctioned); } - /// - /// Saves the manifest back to disk. - /// - /// The to save. - /// The path where to save the manifest. - /// True if successful. + /// public bool SaveManifest(PluginManifest manifest, string path) { - if (manifest == null) - { - return false; - } - try { var data = JsonSerializer.Serialize(manifest, _jsonOptions); File.WriteAllText(Path.Combine(path, "meta.json"), data); return true; } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception e) -#pragma warning restore CA1031 // Do not catch general exception types + catch (ArgumentException e) { - _logger.LogWarning(e, "Unable to save plugin manifest. {Path}", path); + _logger.LogWarning(e, "Unable to save plugin manifest due to invalid value. {Path}", path); return false; } } + /// + public bool GenerateManifest(PackageInfo packageInfo, Version version, string path) + { + var versionInfo = packageInfo.Versions.First(v => v.Version == version.ToString()); + var url = packageInfo.ImageUrl ?? string.Empty; + var imageFilename = url.Substring(url.LastIndexOf('/') + 1, url.Length); + + using (var client = new WebClient()) + { + client.DownloadFile(url, Path.Join(path, imageFilename)); + } + + var manifest = new PluginManifest + { + Category = packageInfo.Category, + Changelog = versionInfo.Changelog ?? string.Empty, + Description = packageInfo.Description, + Id = new Guid(packageInfo.Id), + Name = packageInfo.Name, + Overview = packageInfo.Overview, + Owner = packageInfo.Owner, + TargetAbi = versionInfo.TargetAbi ?? string.Empty, + Timestamp = DateTime.Parse(versionInfo.Timestamp ?? string.Empty), + Version = versionInfo.Version, + Status = PluginStatus.Active, + AutoUpdate = true, + ImagePath = Path.Join(path, imageFilename) + }; + + return SaveManifest(manifest, path); + } + /// /// Changes a plugin's load status. /// @@ -410,7 +432,7 @@ namespace Emby.Server.Implementations.Plugins if (plugin == null) { // Create a dummy record for the providers. - // TODO: remove this code, if all provided have been released as separate plugins. + // TODO: remove this code once all provided have been released as separate plugins. plugin = new LocalPlugin( instance.AssemblyFilePath, true, diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index abcb4313f..534c0aa4b 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -192,17 +192,12 @@ namespace Emby.Server.Implementations.Updates var version = package.Versions[i]; var plugin = _pluginManager.GetPlugin(packageGuid, version.VersionNumber); - // Update the manifests, if anything changes. if (plugin != null) { - if (!string.Equals(plugin.Manifest.TargetAbi, version.TargetAbi, StringComparison.Ordinal)) - { - plugin.Manifest.TargetAbi = version.TargetAbi ?? string.Empty; - _pluginManager.SaveManifest(plugin.Manifest, plugin.Path); - } + _pluginManager.GenerateManifest(package, version.VersionNumber, plugin.Path); } - // Remove versions with a target abi that is greater then the current application version. + // Remove versions with a target ABI greater then the current application version. if (Version.TryParse(version.TargetAbi, out var targetAbi) && _applicationHost.ApplicationVersion < targetAbi) { package.Versions.RemoveAt(i); @@ -294,7 +289,8 @@ namespace Emby.Server.Implementations.Updates Name = package.Name, Version = v.VersionNumber, SourceUrl = v.SourceUrl, - Checksum = v.Checksum + Checksum = v.Checksum, + PackageInfo = package }; } } @@ -571,24 +567,16 @@ namespace Emby.Server.Implementations.Updates stream.Position = 0; _zipClient.ExtractAllFromZip(stream, targetDir, true); + _pluginManager.GenerateManifest(package.PackageInfo, package.Version, targetDir); _pluginManager.ImportPluginFrom(targetDir); } private async Task InstallPackageInternal(InstallationInfo package, CancellationToken cancellationToken) { - // Set last update time if we were installed before LocalPlugin? plugin = _pluginManager.Plugins.FirstOrDefault(p => p.Id.Equals(package.Id) && p.Version.Equals(package.Version)) ?? _pluginManager.Plugins.FirstOrDefault(p => p.Name.Equals(package.Name, StringComparison.OrdinalIgnoreCase) && p.Version.Equals(package.Version)); - if (plugin != null) - { - plugin.Manifest.Timestamp = DateTime.UtcNow; - _pluginManager.SaveManifest(plugin.Manifest, plugin.Path); - } - // Do the install await PerformPackageInstallation(package, cancellationToken).ConfigureAwait(false); - - // Do plugin-specific processing _logger.LogInformation(plugin == null ? "New plugin installed: {PluginName} {PluginVersion}" : "Plugin updated: {PluginName} {PluginVersion}", package.Name, package.Version); return plugin != null; diff --git a/MediaBrowser.Common/Plugins/IPluginManager.cs b/MediaBrowser.Common/Plugins/IPluginManager.cs index 3da34d8bb..6f0a0fbfc 100644 --- a/MediaBrowser.Common/Plugins/IPluginManager.cs +++ b/MediaBrowser.Common/Plugins/IPluginManager.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Threading.Tasks; +using MediaBrowser.Model.Updates; using Microsoft.Extensions.DependencyInjection; namespace MediaBrowser.Common.Plugins @@ -44,6 +45,15 @@ namespace MediaBrowser.Common.Plugins /// True if successful. bool SaveManifest(PluginManifest manifest, string path); + /// + /// Generates a manifest from repository data. + /// + /// The used to generate a manifest. + /// Version to be installed. + /// The path where to save the manifest. + /// True if successful. + bool GenerateManifest(PackageInfo packageInfo, Version version, string path); + /// /// Imports plugin details from a folder. /// diff --git a/MediaBrowser.Model/Updates/InstallationInfo.cs b/MediaBrowser.Model/Updates/InstallationInfo.cs index eebe1a903..cc600de9d 100644 --- a/MediaBrowser.Model/Updates/InstallationInfo.cs +++ b/MediaBrowser.Model/Updates/InstallationInfo.cs @@ -1,4 +1,5 @@ #nullable disable + using System; using System.Text.Json.Serialization; @@ -45,5 +46,11 @@ namespace MediaBrowser.Model.Updates /// /// The checksum. public string Checksum { get; set; } + + /// + /// Gets or sets package information for the installation. + /// + /// The package information. + public PackageInfo PackageInfo { get; set; } } } -- cgit v1.2.3 From b18bb3d0de5e459b9bafbc3a67afe6204eca1b08 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 23 Feb 2021 19:22:20 +0900 Subject: update timestamp parse for plugins --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 696133c9f..fec7bcb87 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -372,7 +372,7 @@ namespace Emby.Server.Implementations.Plugins Overview = packageInfo.Overview, Owner = packageInfo.Owner, TargetAbi = versionInfo.TargetAbi ?? string.Empty, - Timestamp = DateTime.Parse(versionInfo.Timestamp ?? string.Empty), + Timestamp = string.IsNullOrEmpty(versionInfo.Timestamp) ? DateTime.MinValue : DateTime.Parse(versionInfo.Timestamp), Version = versionInfo.Version, Status = PluginStatus.Active, AutoUpdate = true, -- cgit v1.2.3 From 64cc5889f2be0dae6b0425c569bd84f996a0e435 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 23 Feb 2021 23:11:17 +0900 Subject: add suggested changes --- .../Plugins/PluginManager.cs | 45 ++++++++++++++++++---- .../Updates/InstallationManager.cs | 4 +- MediaBrowser.Common/Plugins/IPluginManager.cs | 2 +- 3 files changed, 41 insertions(+), 10 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index fec7bcb87..b4ab55157 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -4,14 +4,16 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Net; +using System.Net.Http; using System.Reflection; using System.Text; using System.Text.Json; +using System.Threading.Tasks; using MediaBrowser.Common; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Json; using MediaBrowser.Common.Json.Converters; +using MediaBrowser.Common.Net; using MediaBrowser.Common.Plugins; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Plugins; @@ -35,6 +37,21 @@ namespace Emby.Server.Implementations.Plugins private readonly IList _plugins; private readonly Version _minimumVersion; + private IHttpClientFactory? _httpClientFactory; + + private IHttpClientFactory HttpClientFactory + { + get + { + if (_httpClientFactory == null) + { + _httpClientFactory = _appHost.Resolve(); + } + + return _httpClientFactory; + } + } + /// /// Initializes a new instance of the class. /// @@ -351,15 +368,29 @@ namespace Emby.Server.Implementations.Plugins } /// - public bool GenerateManifest(PackageInfo packageInfo, Version version, string path) + public async Task GenerateManifest(PackageInfo packageInfo, Version version, string path) { + if (packageInfo == null) + { + return false; + } + var versionInfo = packageInfo.Versions.First(v => v.Version == version.ToString()); - var url = packageInfo.ImageUrl ?? string.Empty; - var imageFilename = url.Substring(url.LastIndexOf('/') + 1, url.Length); + var imagePath = string.Empty; - using (var client = new WebClient()) + if (!string.IsNullOrEmpty(packageInfo.ImageUrl)) { - client.DownloadFile(url, Path.Join(path, imageFilename)); + var url = new Uri(packageInfo.ImageUrl); + imagePath = Path.Join(path, url.Segments.Last()); + + await using var fileStream = File.OpenWrite(imagePath); + var downloadStream = await HttpClientFactory + .CreateClient(NamedClient.Default) + .GetStreamAsync(url) + .ConfigureAwait(false); + + await downloadStream.CopyToAsync(fileStream).ConfigureAwait(false); + await fileStream.DisposeAsync(); } var manifest = new PluginManifest @@ -376,7 +407,7 @@ namespace Emby.Server.Implementations.Plugins Version = versionInfo.Version, Status = PluginStatus.Active, AutoUpdate = true, - ImagePath = Path.Join(path, imageFilename) + ImagePath = imagePath }; return SaveManifest(manifest, path); diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 534c0aa4b..7af52ea65 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -194,7 +194,7 @@ namespace Emby.Server.Implementations.Updates var plugin = _pluginManager.GetPlugin(packageGuid, version.VersionNumber); if (plugin != null) { - _pluginManager.GenerateManifest(package, version.VersionNumber, plugin.Path); + await _pluginManager.GenerateManifest(package, version.VersionNumber, plugin.Path); } // Remove versions with a target ABI greater then the current application version. @@ -567,7 +567,7 @@ namespace Emby.Server.Implementations.Updates stream.Position = 0; _zipClient.ExtractAllFromZip(stream, targetDir, true); - _pluginManager.GenerateManifest(package.PackageInfo, package.Version, targetDir); + await _pluginManager.GenerateManifest(package.PackageInfo, package.Version, targetDir); _pluginManager.ImportPluginFrom(targetDir); } diff --git a/MediaBrowser.Common/Plugins/IPluginManager.cs b/MediaBrowser.Common/Plugins/IPluginManager.cs index 6f0a0fbfc..fc2fcb517 100644 --- a/MediaBrowser.Common/Plugins/IPluginManager.cs +++ b/MediaBrowser.Common/Plugins/IPluginManager.cs @@ -52,7 +52,7 @@ namespace MediaBrowser.Common.Plugins /// Version to be installed. /// The path where to save the manifest. /// True if successful. - bool GenerateManifest(PackageInfo packageInfo, Version version, string path); + Task GenerateManifest(PackageInfo packageInfo, Version version, string path); /// /// Imports plugin details from a folder. -- cgit v1.2.3 From 454deece13b138e5bcb694732b622be27cb6d204 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 23 Feb 2021 23:36:49 +0900 Subject: improve performance in the wrong place Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index b4ab55157..4dc2985d3 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -381,7 +381,7 @@ namespace Emby.Server.Implementations.Plugins if (!string.IsNullOrEmpty(packageInfo.ImageUrl)) { var url = new Uri(packageInfo.ImageUrl); - imagePath = Path.Join(path, url.Segments.Last()); + imagePath = Path.Join(path, url.Segments[^1]); await using var fileStream = File.OpenWrite(imagePath); var downloadStream = await HttpClientFactory -- cgit v1.2.3 From e9030a62fb9bc48f52b9f961d20e972ad300abeb Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 23 Feb 2021 23:37:32 +0900 Subject: remove useless call to dispose Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 4dc2985d3..b0a8aba16 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -390,7 +390,6 @@ namespace Emby.Server.Implementations.Plugins .ConfigureAwait(false); await downloadStream.CopyToAsync(fileStream).ConfigureAwait(false); - await fileStream.DisposeAsync(); } var manifest = new PluginManifest -- cgit v1.2.3 From fb2d17824225e9849a45bc146fa6e09f3c71b1fb Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 23 Feb 2021 23:39:33 +0900 Subject: add await directive for image download Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Plugins/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index b0a8aba16..d8dac6599 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -384,7 +384,7 @@ namespace Emby.Server.Implementations.Plugins imagePath = Path.Join(path, url.Segments[^1]); await using var fileStream = File.OpenWrite(imagePath); - var downloadStream = await HttpClientFactory + await using var downloadStream = await HttpClientFactory .CreateClient(NamedClient.Default) .GetStreamAsync(url) .ConfigureAwait(false); -- cgit v1.2.3 From 9bfe945f6c1f41ea3456ae27b1ad31a04f3cea3f Mon Sep 17 00:00:00 2001 From: dkanada Date: Wed, 24 Feb 2021 00:03:26 +0900 Subject: catch http exception and fix possible issues --- Emby.Server.Implementations/Plugins/PluginManager.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index d8dac6599..7bc9f0a7e 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -384,12 +384,21 @@ namespace Emby.Server.Implementations.Plugins imagePath = Path.Join(path, url.Segments[^1]); await using var fileStream = File.OpenWrite(imagePath); - await using var downloadStream = await HttpClientFactory - .CreateClient(NamedClient.Default) - .GetStreamAsync(url) - .ConfigureAwait(false); - await downloadStream.CopyToAsync(fileStream).ConfigureAwait(false); + try + { + await using var downloadStream = await HttpClientFactory + .CreateClient(NamedClient.Default) + .GetStreamAsync(url) + .ConfigureAwait(false); + + await downloadStream.CopyToAsync(fileStream).ConfigureAwait(false); + } + catch (HttpRequestException ex) + { + _logger.LogError(ex, "Failed to download image to path {Path} on disk.", imagePath); + imagePath = string.Empty; + } } var manifest = new PluginManifest -- cgit v1.2.3 From a6d0db5d0409f72e2abb02291268b6971eaf1fcf Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 5 Mar 2021 11:15:14 +0100 Subject: 100% branch coverage for DashboardController --- Emby.Server.Implementations/Plugins/PluginManager.cs | 4 ++-- Jellyfin.Api/Controllers/DashboardController.cs | 4 ++-- MediaBrowser.Common/Plugins/IPluginManager.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 7bc9f0a7e..c579fc8cb 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -34,7 +34,7 @@ namespace Emby.Server.Implementations.Plugins private readonly ILogger _logger; private readonly IApplicationHost _appHost; private readonly ServerConfiguration _config; - private readonly IList _plugins; + private readonly List _plugins; private readonly Version _minimumVersion; private IHttpClientFactory? _httpClientFactory; @@ -94,7 +94,7 @@ namespace Emby.Server.Implementations.Plugins /// /// Gets the Plugins. /// - public IList Plugins => _plugins; + public IReadOnlyList Plugins => _plugins; /// /// Returns all the assemblies. diff --git a/Jellyfin.Api/Controllers/DashboardController.cs b/Jellyfin.Api/Controllers/DashboardController.cs index a2c2ecd66..445733c24 100644 --- a/Jellyfin.Api/Controllers/DashboardController.cs +++ b/Jellyfin.Api/Controllers/DashboardController.cs @@ -95,9 +95,9 @@ namespace Jellyfin.Api.Controllers return GetPluginPages(plugin).Select(i => new ConfigurationPageInfo(plugin.Instance, i.Item1)); } - private IEnumerable> GetPluginPages(LocalPlugin? plugin) + private IEnumerable> GetPluginPages(LocalPlugin plugin) { - if (plugin?.Instance is not IHasWebPages hasWebPages) + if (plugin.Instance is not IHasWebPages hasWebPages) { return Enumerable.Empty>(); } diff --git a/MediaBrowser.Common/Plugins/IPluginManager.cs b/MediaBrowser.Common/Plugins/IPluginManager.cs index fc2fcb517..f9a8fb6f7 100644 --- a/MediaBrowser.Common/Plugins/IPluginManager.cs +++ b/MediaBrowser.Common/Plugins/IPluginManager.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Common.Plugins /// /// Gets the Plugins. /// - IList Plugins { get; } + IReadOnlyList Plugins { get; } /// /// Creates the plugins. -- cgit v1.2.3 From a8ed753f6c890f74d3a70c2653ac5548d2399737 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Tue, 9 Mar 2021 05:57:38 +0100 Subject: FxCop -> Net Analyzers (part 2) --- Emby.Dlna/DlnaManager.cs | 2 +- Emby.Server.Implementations/ApplicationHost.cs | 5 +- .../Channels/ChannelManager.cs | 2 +- .../Data/SqliteItemRepository.cs | 2 +- .../HttpServer/WebSocketConnection.cs | 2 +- .../Library/LiveStreamHelper.cs | 2 +- .../Library/MediaSourceManager.cs | 2 +- .../LiveTv/EmbyTV/EncodedRecorder.cs | 2 +- .../LiveTv/EmbyTV/ItemDataProvider.cs | 2 +- .../LiveTv/Listings/SchedulesDirect.cs | 2 +- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 2 +- .../Localization/LocalizationManager.cs | 2 +- .../Plugins/PluginManager.cs | 4 +- .../ScheduledTasks/ScheduledTaskWorker.cs | 2 +- .../Updates/InstallationManager.cs | 2 +- .../Controllers/ConfigurationController.cs | 2 +- Jellyfin.Api/Controllers/PluginsController.cs | 2 +- Jellyfin.Data/DayOfWeekHelper.cs | 60 +++------------------- Jellyfin.Data/Entities/Libraries/Collection.cs | 1 + .../Entities/Libraries/MediaFileStream.cs | 2 + Jellyfin.Data/Entities/Permission.cs | 2 + Jellyfin.Data/Jellyfin.Data.csproj | 6 +-- Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj | 11 ++-- Jellyfin.Drawing.Skia/SkiaEncoder.cs | 13 ++--- Jellyfin.Networking/Jellyfin.Networking.csproj | 6 +-- .../Security/AuthenticationSucceededLogger.cs | 8 +-- .../Events/Consumers/System/TaskCompletedLogger.cs | 14 ++--- .../Consumers/Updates/PluginUninstalledLogger.cs | 4 +- .../Events/Consumers/Users/UserUpdatedNotifier.cs | 6 +-- .../Jellyfin.Server.Implementations.csproj | 2 + .../Users/DefaultPasswordResetProvider.cs | 2 +- .../Users/DisplayPreferencesManager.cs | 3 +- .../Extensions/ApiServiceCollectionExtensions.cs | 2 +- .../Formatters/CamelCaseJsonProfileFormatter.cs | 2 +- .../Formatters/PascalCaseJsonProfileFormatter.cs | 2 +- Jellyfin.Server/Jellyfin.Server.csproj | 8 ++- Jellyfin.Server/Migrations/MigrationOptions.cs | 3 ++ .../Migrations/Routines/MigrateUserDb.cs | 2 +- Jellyfin.Server/Program.cs | 4 +- MediaBrowser.Common/IApplicationHost.cs | 4 +- MediaBrowser.Common/Json/JsonDefaults.cs | 6 +-- MediaBrowser.Common/MediaBrowser.Common.csproj | 6 +-- MediaBrowser.Common/Net/IPHost.cs | 2 +- MediaBrowser.Common/Net/IPNetAddress.cs | 6 +-- MediaBrowser.Common/Plugins/BasePlugin.cs | 2 +- MediaBrowser.Common/Plugins/BasePluginOfT.cs | 36 ++++++------- MediaBrowser.Common/Plugins/LocalPlugin.cs | 6 +-- MediaBrowser.Common/Progress/ActionableProgress.cs | 1 + MediaBrowser.Common/Progress/SimpleProgress.cs | 1 + .../Entities/CollectionFolder.cs | 2 +- .../MediaBrowser.Controller.csproj | 6 +-- .../Providers/ILocalImageProvider.cs | 2 +- .../Images/CollectionFolderLocalImageProvider.cs | 2 +- .../Images/EpisodeLocalImageProvider.cs | 2 +- .../Images/InternalMetadataFolderImageProvider.cs | 7 +-- .../Images/LocalImageProvider.cs | 14 +++-- .../MediaBrowser.LocalMetadata.csproj | 6 +-- .../Parsers/BaseItemXmlParser.cs | 4 +- .../Parsers/BoxSetXmlParser.cs | 6 +-- .../Parsers/PlaylistXmlParser.cs | 6 +-- MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs | 17 ++---- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 2 +- .../Plugins/AudioDb/AlbumImageProvider.cs | 2 +- .../Plugins/AudioDb/AlbumProvider.cs | 2 +- .../Plugins/AudioDb/ArtistImageProvider.cs | 2 +- .../Plugins/AudioDb/ArtistProvider.cs | 2 +- .../Plugins/Omdb/OmdbItemProvider.cs | 2 +- .../Plugins/Omdb/OmdbProvider.cs | 2 +- .../FFprobeParserTests.cs | 2 +- .../Controllers/DashboardControllerTests.cs | 2 +- 70 files changed, 151 insertions(+), 213 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index d7b75f979..552cd501b 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -36,7 +36,7 @@ namespace Emby.Dlna private readonly ILogger _logger; private readonly IServerApplicationHost _appHost; private static readonly Assembly _assembly = typeof(DlnaManager).Assembly; - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; private readonly Dictionary> _profiles = new Dictionary>(StringComparer.Ordinal); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 835dc33b0..164e6d49d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -10,8 +10,6 @@ using System.Net; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Emby.Dlna; @@ -51,7 +49,6 @@ using Jellyfin.Networking.Manager; using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; -using MediaBrowser.Common.Json; using MediaBrowser.Common.Net; using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Updates; @@ -470,7 +467,7 @@ namespace Emby.Server.Implementations } /// - public IReadOnlyCollection GetExports(CreationDelegate defaultFunc, bool manageLifetime = true) + public IReadOnlyCollection GetExports(CreationDelegateFactory defaultFunc, bool manageLifetime = true) { // Convert to list so this isn't executed for each iteration var parts = GetExportTypes() diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 8c5fa09f6..87ebe960a 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -49,7 +49,7 @@ namespace Emby.Server.Implementations.Channels private readonly IProviderManager _providerManager; private readonly IMemoryCache _memoryCache; private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1); - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; /// /// Initializes a new instance of the class. diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index d78b93bd7..2ae805447 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -88,7 +88,7 @@ namespace Emby.Server.Implementations.Data _imageProcessor = imageProcessor; _typeMapper = new TypeMapper(); - _jsonOptions = JsonDefaults.GetOptions(); + _jsonOptions = JsonDefaults.Options; DbFilePath = Path.Combine(_config.ApplicationPaths.DataPath, "library.db"); } diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index 7e0c2c1da..06acb5606 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -56,7 +56,7 @@ namespace Emby.Server.Implementations.HttpServer RemoteEndPoint = remoteEndPoint; QueryString = query; - _jsonOptions = JsonDefaults.GetOptions(); + _jsonOptions = JsonDefaults.Options; LastActivityDate = DateTime.Now; } diff --git a/Emby.Server.Implementations/Library/LiveStreamHelper.cs b/Emby.Server.Implementations/Library/LiveStreamHelper.cs index 2070df31e..c2951dd15 100644 --- a/Emby.Server.Implementations/Library/LiveStreamHelper.cs +++ b/Emby.Server.Implementations/Library/LiveStreamHelper.cs @@ -25,7 +25,7 @@ namespace Emby.Server.Implementations.Library private readonly IMediaEncoder _mediaEncoder; private readonly ILogger _logger; private readonly IApplicationPaths _appPaths; - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; public LiveStreamHelper(IMediaEncoder mediaEncoder, ILogger logger, IApplicationPaths appPaths) { diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index c63eb7017..b2943020c 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -46,7 +46,7 @@ namespace Emby.Server.Implementations.Library private readonly ConcurrentDictionary _openStreams = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); private readonly SemaphoreSlim _liveStreamSemaphore = new SemaphoreSlim(1, 1); - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; private IMediaSourceProvider[] _providers; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 78a82118e..44a8cdee4 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -28,7 +28,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private readonly IServerApplicationPaths _appPaths; private readonly TaskCompletionSource _taskCompletionSource = new TaskCompletionSource(); private readonly IServerConfigurationManager _serverConfigurationManager; - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; private bool _hasExited; private Stream _logFileStream; private string _targetPath; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs index 57424f043..c20b08088 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs @@ -17,7 +17,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { private readonly string _dataPath; private readonly object _fileDataLock = new object(); - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; private T[] _items; public ItemDataProvider( diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 6d7c5ac6e..1926e738f 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -35,7 +35,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings private readonly ICryptoProvider _cryptoProvider; private readonly ConcurrentDictionary _tokens = new ConcurrentDictionary(); - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; private DateTime _lastErrorResponse; public SchedulesDirect( diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 0760e8127..68173a0ef 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -61,7 +61,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun _networkManager = networkManager; _streamHelper = streamHelper; - _jsonOptions = JsonDefaults.GetOptions(); + _jsonOptions = JsonDefaults.Options; } public string Name => "HD Homerun"; diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index 3f9e22106..98de848bc 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -36,7 +36,7 @@ namespace Emby.Server.Implementations.Localization private List _cultures; - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; /// /// Initializes a new instance of the class. diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index c579fc8cb..700396c4c 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -70,7 +70,7 @@ namespace Emby.Server.Implementations.Plugins _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _pluginsPath = pluginsPath; _appVersion = appVersion ?? throw new ArgumentNullException(nameof(appVersion)); - _jsonOptions = new JsonSerializerOptions(JsonDefaults.GetOptions()) + _jsonOptions = new JsonSerializerOptions(JsonDefaults.Options) { WriteIndented = true }; @@ -678,7 +678,7 @@ namespace Emby.Server.Implementations.Plugins var entry = versions[x]; if (!string.Equals(lastName, entry.Name, StringComparison.OrdinalIgnoreCase)) { - entry.DllFiles.AddRange(Directory.EnumerateFiles(entry.Path, "*.dll", SearchOption.AllDirectories)); + entry.DllFiles = Directory.GetFiles(entry.Path, "*.dll", SearchOption.AllDirectories); if (entry.IsEnabledAndSupported) { lastName = entry.Name; diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index b302303f8..a145a8423 100644 --- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -69,7 +69,7 @@ namespace Emby.Server.Implementations.ScheduledTasks /// /// The options for the json Serializer. /// - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; /// /// Initializes a new instance of the class. diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 7af52ea65..fc34f93cd 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -92,7 +92,7 @@ namespace Emby.Server.Implementations.Updates _httpClientFactory = httpClientFactory; _config = config; _zipClient = zipClient; - _jsonSerializerOptions = JsonDefaults.GetOptions(); + _jsonSerializerOptions = JsonDefaults.Options; _pluginManager = pluginManager; } diff --git a/Jellyfin.Api/Controllers/ConfigurationController.cs b/Jellyfin.Api/Controllers/ConfigurationController.cs index e1c9f69f6..049a4bed7 100644 --- a/Jellyfin.Api/Controllers/ConfigurationController.cs +++ b/Jellyfin.Api/Controllers/ConfigurationController.cs @@ -25,7 +25,7 @@ namespace Jellyfin.Api.Controllers private readonly IServerConfigurationManager _configurationManager; private readonly IMediaEncoder _mediaEncoder; - private readonly JsonSerializerOptions _serializerOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _serializerOptions = JsonDefaults.Options; /// /// Initializes a new instance of the class. diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index a5aa9bfca..24285bfb9 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -45,7 +45,7 @@ namespace Jellyfin.Api.Controllers { _installationManager = installationManager; _pluginManager = pluginManager; - _serializerOptions = JsonDefaults.GetOptions(); + _serializerOptions = JsonDefaults.Options; _config = config; } diff --git a/Jellyfin.Data/DayOfWeekHelper.cs b/Jellyfin.Data/DayOfWeekHelper.cs index 4e75f4cfd..8d760a155 100644 --- a/Jellyfin.Data/DayOfWeekHelper.cs +++ b/Jellyfin.Data/DayOfWeekHelper.cs @@ -1,67 +1,21 @@ #pragma warning disable CS1591 using System; -using System.Collections.Generic; using Jellyfin.Data.Enums; namespace Jellyfin.Data { public static class DayOfWeekHelper { - public static List GetDaysOfWeek(DynamicDayOfWeek day) + public static DayOfWeek[] GetDaysOfWeek(DynamicDayOfWeek day) { - var days = new List(7); - - if (day == DynamicDayOfWeek.Sunday - || day == DynamicDayOfWeek.Weekend - || day == DynamicDayOfWeek.Everyday) - { - days.Add(DayOfWeek.Sunday); - } - - if (day == DynamicDayOfWeek.Monday - || day == DynamicDayOfWeek.Weekday - || day == DynamicDayOfWeek.Everyday) - { - days.Add(DayOfWeek.Monday); - } - - if (day == DynamicDayOfWeek.Tuesday - || day == DynamicDayOfWeek.Weekday - || day == DynamicDayOfWeek.Everyday) - { - days.Add(DayOfWeek.Tuesday); - } - - if (day == DynamicDayOfWeek.Wednesday - || day == DynamicDayOfWeek.Weekday - || day == DynamicDayOfWeek.Everyday) + return day switch { - days.Add(DayOfWeek.Wednesday); - } - - if (day == DynamicDayOfWeek.Thursday - || day == DynamicDayOfWeek.Weekday - || day == DynamicDayOfWeek.Everyday) - { - days.Add(DayOfWeek.Thursday); - } - - if (day == DynamicDayOfWeek.Friday - || day == DynamicDayOfWeek.Weekday - || day == DynamicDayOfWeek.Everyday) - { - days.Add(DayOfWeek.Friday); - } - - if (day == DynamicDayOfWeek.Saturday - || day == DynamicDayOfWeek.Weekend - || day == DynamicDayOfWeek.Everyday) - { - days.Add(DayOfWeek.Saturday); - } - - return days; + DynamicDayOfWeek.Everyday => new[] { DayOfWeek.Sunday, DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday }, + DynamicDayOfWeek.Weekday => new[] { DayOfWeek.Sunday, DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday }, + DynamicDayOfWeek.Weekend => new[] { DayOfWeek.Saturday, DayOfWeek.Sunday }, + _ => new[] { (DayOfWeek)day } + }; } } } diff --git a/Jellyfin.Data/Entities/Libraries/Collection.cs b/Jellyfin.Data/Entities/Libraries/Collection.cs index 39eded752..854f17f80 100644 --- a/Jellyfin.Data/Entities/Libraries/Collection.cs +++ b/Jellyfin.Data/Entities/Libraries/Collection.cs @@ -1,3 +1,4 @@ +#pragma warning disable CA1711 // Identifiers should not have incorrect suffix #pragma warning disable CA2227 using System.Collections.Generic; diff --git a/Jellyfin.Data/Entities/Libraries/MediaFileStream.cs b/Jellyfin.Data/Entities/Libraries/MediaFileStream.cs index 5b03e260e..5e27156a4 100644 --- a/Jellyfin.Data/Entities/Libraries/MediaFileStream.cs +++ b/Jellyfin.Data/Entities/Libraries/MediaFileStream.cs @@ -1,3 +1,5 @@ +#pragma warning disable CA1711 // Identifiers should not have incorrect suffix + using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; diff --git a/Jellyfin.Data/Entities/Permission.cs b/Jellyfin.Data/Entities/Permission.cs index d92e5d9d2..0162e1acf 100644 --- a/Jellyfin.Data/Entities/Permission.cs +++ b/Jellyfin.Data/Entities/Permission.cs @@ -1,3 +1,5 @@ +#pragma warning disable CA1711 // Identifiers should not have incorrect suffix + using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Jellyfin.Data.Enums; diff --git a/Jellyfin.Data/Jellyfin.Data.csproj b/Jellyfin.Data/Jellyfin.Data.csproj index 42731bb11..0340cda01 100644 --- a/Jellyfin.Data/Jellyfin.Data.csproj +++ b/Jellyfin.Data/Jellyfin.Data.csproj @@ -5,6 +5,8 @@ false true true + AllEnabledByDefault + ../jellyfin.ruleset true true true @@ -24,10 +26,6 @@ GPL-3.0-only - - ../jellyfin.ruleset - - diff --git a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj index 1a8415ae0..3fc44640b 100644 --- a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj +++ b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj @@ -11,6 +11,8 @@ true true enable + AllEnabledByDefault + ../jellyfin.ruleset @@ -30,6 +32,11 @@ + + + + + @@ -37,8 +44,4 @@ - - ../jellyfin.ruleset - - diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs index eab5777d5..fd7cb5ec5 100644 --- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs +++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs @@ -274,8 +274,8 @@ namespace Jellyfin.Drawing.Skia if (requiresTransparencyHack || forceCleanBitmap) { - using var codec = SKCodec.Create(NormalizePath(path)); - if (codec == null) + using SKCodec codec = SKCodec.Create(NormalizePath(path), out SKCodecResult res); + if (res != SKCodecResult.Success) { origin = GetSKEncodedOrigin(orientation); return null; @@ -345,11 +345,6 @@ namespace Jellyfin.Drawing.Skia private SKBitmap OrientImage(SKBitmap bitmap, SKEncodedOrigin origin) { - if (origin == SKEncodedOrigin.Default) - { - return bitmap; - } - var needsFlip = origin == SKEncodedOrigin.LeftBottom || origin == SKEncodedOrigin.LeftTop || origin == SKEncodedOrigin.RightBottom @@ -447,7 +442,7 @@ namespace Jellyfin.Drawing.Skia } /// - public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat outputFormat) { if (inputPath.Length == 0) { @@ -459,7 +454,7 @@ namespace Jellyfin.Drawing.Skia throw new ArgumentException("String can't be empty.", nameof(outputPath)); } - var skiaOutputFormat = GetImageFormat(selectedOutputFormat); + var skiaOutputFormat = GetImageFormat(outputFormat); var hasBackgroundColor = !string.IsNullOrWhiteSpace(options.BackgroundColor); var hasForegroundColor = !string.IsNullOrWhiteSpace(options.ForegroundLayer); diff --git a/Jellyfin.Networking/Jellyfin.Networking.csproj b/Jellyfin.Networking/Jellyfin.Networking.csproj index f89a18426..63557e91f 100644 --- a/Jellyfin.Networking/Jellyfin.Networking.csproj +++ b/Jellyfin.Networking/Jellyfin.Networking.csproj @@ -5,6 +5,8 @@ true true enable + AllEnabledByDefault + ../jellyfin.ruleset @@ -18,10 +20,6 @@ - - ../jellyfin.ruleset - - diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs index 2f9f44ed6..8b0bd84c6 100644 --- a/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs +++ b/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs @@ -29,20 +29,20 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Security } /// - public async Task OnEvent(GenericEventArgs e) + public async Task OnEvent(GenericEventArgs eventArgs) { await _activityManager.CreateAsync(new ActivityLog( string.Format( CultureInfo.InvariantCulture, _localizationManager.GetLocalizedString("AuthenticationSucceededWithUserName"), - e.Argument.User.Name), + eventArgs.Argument.User.Name), "AuthenticationSucceeded", - e.Argument.User.Id) + eventArgs.Argument.User.Id) { ShortOverview = string.Format( CultureInfo.InvariantCulture, _localizationManager.GetLocalizedString("LabelIpAddressValue"), - e.Argument.SessionInfo.RemoteEndPoint), + eventArgs.Argument.SessionInfo.RemoteEndPoint), }).ConfigureAwait(false); } } diff --git a/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs index 05201a346..cbc9f3017 100644 --- a/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs +++ b/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs @@ -33,10 +33,10 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.System } /// - public async Task OnEvent(TaskCompletionEventArgs e) + public async Task OnEvent(TaskCompletionEventArgs eventArgs) { - var result = e.Result; - var task = e.Task; + var result = eventArgs.Result; + var task = eventArgs.Task; if (task.ScheduledTask is IConfigurableScheduledTask activityTask && !activityTask.IsLogged) @@ -54,14 +54,14 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.System { var vals = new List(); - if (!string.IsNullOrEmpty(e.Result.ErrorMessage)) + if (!string.IsNullOrEmpty(eventArgs.Result.ErrorMessage)) { - vals.Add(e.Result.ErrorMessage); + vals.Add(eventArgs.Result.ErrorMessage); } - if (!string.IsNullOrEmpty(e.Result.LongErrorMessage)) + if (!string.IsNullOrEmpty(eventArgs.Result.LongErrorMessage)) { - vals.Add(e.Result.LongErrorMessage); + vals.Add(eventArgs.Result.LongErrorMessage); } await _activityManager.CreateAsync(new ActivityLog( diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs index 91a30069e..eb7572ac6 100644 --- a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs +++ b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs @@ -30,13 +30,13 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Updates } /// - public async Task OnEvent(PluginUninstalledEventArgs e) + public async Task OnEvent(PluginUninstalledEventArgs eventArgs) { await _activityManager.CreateAsync(new ActivityLog( string.Format( CultureInfo.InvariantCulture, _localizationManager.GetLocalizedString("PluginUninstalledWithName"), - e.Argument.Name), + eventArgs.Argument.Name), NotificationType.PluginUninstalled.ToString(), Guid.Empty)) .ConfigureAwait(false); diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Users/UserUpdatedNotifier.cs b/Jellyfin.Server.Implementations/Events/Consumers/Users/UserUpdatedNotifier.cs index a14911b94..9beb6f2f2 100644 --- a/Jellyfin.Server.Implementations/Events/Consumers/Users/UserUpdatedNotifier.cs +++ b/Jellyfin.Server.Implementations/Events/Consumers/Users/UserUpdatedNotifier.cs @@ -30,12 +30,12 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Users } /// - public async Task OnEvent(UserUpdatedEventArgs e) + public async Task OnEvent(UserUpdatedEventArgs eventArgs) { await _sessionManager.SendMessageToUserSessions( - new List { e.Argument.Id }, + new List { eventArgs.Argument.Id }, SessionMessageType.UserUpdated, - _userManager.GetUserDto(e.Argument), + _userManager.GetUserDto(eventArgs.Argument), CancellationToken.None).ConfigureAwait(false); } } diff --git a/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj index 19c7ac567..5a5992bd6 100644 --- a/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj +++ b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj @@ -6,6 +6,8 @@ true true enable + AllEnabledByDefault + ../jellyfin.ruleset diff --git a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs index 9cc1c3e5e..c99c5e4ef 100644 --- a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs +++ b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs @@ -66,7 +66,7 @@ namespace Jellyfin.Server.Implementations.Users else if (string.Equals( spr.Pin.Replace("-", string.Empty, StringComparison.Ordinal), pin.Replace("-", string.Empty, StringComparison.Ordinal), - StringComparison.InvariantCultureIgnoreCase)) + StringComparison.OrdinalIgnoreCase)) { var resetUser = userManager.GetUserByName(spr.UserName) ?? throw new ResourceNotFoundException($"User with a username of {spr.UserName} not found"); diff --git a/Jellyfin.Server.Implementations/Users/DisplayPreferencesManager.cs b/Jellyfin.Server.Implementations/Users/DisplayPreferencesManager.cs index c8a589cab..a3e9516b9 100644 --- a/Jellyfin.Server.Implementations/Users/DisplayPreferencesManager.cs +++ b/Jellyfin.Server.Implementations/Users/DisplayPreferencesManager.cs @@ -1,4 +1,5 @@ #pragma warning disable CA1307 +#pragma warning disable CA1309 using System; using System.Collections.Generic; @@ -35,7 +36,7 @@ namespace Jellyfin.Server.Implementations.Users if (prefs == null) { - prefs = new DisplayPreferences(userId, itemId, client); + prefs = new DisplayPreferences(userId, itemId, client); _dbContext.DisplayPreferences.Add(prefs); } diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs index 1828f1a7e..a3f49e6cb 100644 --- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs @@ -225,7 +225,7 @@ namespace Jellyfin.Server.Extensions .AddJsonOptions(options => { // Update all properties that are set in JsonDefaults - var jsonOptions = JsonDefaults.GetPascalCaseOptions(); + var jsonOptions = JsonDefaults.PascalCaseOptions; // From JsonDefaults options.JsonSerializerOptions.ReadCommentHandling = jsonOptions.ReadCommentHandling; diff --git a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs index 8043989b1..c349e3dca 100644 --- a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs @@ -12,7 +12,7 @@ namespace Jellyfin.Server.Formatters /// /// Initializes a new instance of the class. /// - public CamelCaseJsonProfileFormatter() : base(JsonDefaults.GetCamelCaseOptions()) + public CamelCaseJsonProfileFormatter() : base(JsonDefaults.CamelCaseOptions) { SupportedMediaTypes.Clear(); SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(JsonDefaults.CamelCaseMediaType)); diff --git a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs index d0110b125..0480f5e0e 100644 --- a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs @@ -13,7 +13,7 @@ namespace Jellyfin.Server.Formatters /// /// Initializes a new instance of the class. /// - public PascalCaseJsonProfileFormatter() : base(JsonDefaults.GetPascalCaseOptions()) + public PascalCaseJsonProfileFormatter() : base(JsonDefaults.PascalCaseOptions) { SupportedMediaTypes.Clear(); // Add application/json for default formatter diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj index 6bfb5b878..09799307b 100644 --- a/Jellyfin.Server/Jellyfin.Server.csproj +++ b/Jellyfin.Server/Jellyfin.Server.csproj @@ -13,7 +13,9 @@ true true enable - true + AllEnabledByDefault + ../jellyfin.ruleset + @@ -31,10 +33,6 @@ - - ../jellyfin.ruleset - - diff --git a/Jellyfin.Server/Migrations/MigrationOptions.cs b/Jellyfin.Server/Migrations/MigrationOptions.cs index 816dd9ee7..c9710f1fd 100644 --- a/Jellyfin.Server/Migrations/MigrationOptions.cs +++ b/Jellyfin.Server/Migrations/MigrationOptions.cs @@ -16,9 +16,12 @@ namespace Jellyfin.Server.Migrations Applied = new List<(Guid Id, string Name)>(); } +// .Net xml serializer can't handle interfaces +#pragma warning disable CA1002 // Do not expose generic lists /// /// Gets the list of applied migration routine names. /// public List<(Guid Id, string Name)> Applied { get; } +#pragma warning restore CA1002 } } diff --git a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs index 33f039c39..d61c04447 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs @@ -76,7 +76,7 @@ namespace Jellyfin.Server.Migrations.Routines foreach (var entry in queryResult) { - UserMockup? mockup = JsonSerializer.Deserialize(entry[2].ToBlob(), JsonDefaults.GetOptions()); + UserMockup? mockup = JsonSerializer.Deserialize(entry[2].ToBlob(), JsonDefaults.Options); if (mockup == null) { continue; diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 6ae0542c0..4f203b7a9 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -222,7 +222,7 @@ namespace Jellyfin.Server } finally { - appHost?.Dispose(); + appHost.Dispose(); } if (_restartOnShutdown) @@ -623,7 +623,7 @@ namespace Jellyfin.Server string commandLineArgsString; if (options.RestartArgs != null) { - commandLineArgsString = options.RestartArgs ?? string.Empty; + commandLineArgsString = options.RestartArgs; } else { diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs index ddcf2ac17..c3e4ed6db 100644 --- a/MediaBrowser.Common/IApplicationHost.cs +++ b/MediaBrowser.Common/IApplicationHost.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Common /// /// Type to create. /// New instance of type type. - public delegate object CreationDelegate(Type type); + public delegate object CreationDelegateFactory(Type type); /// /// An interface to be implemented by the applications hosting a kernel. @@ -112,7 +112,7 @@ namespace MediaBrowser.Common /// Delegate function that gets called to create the object. /// If set to true [manage lifetime]. /// . - IReadOnlyCollection GetExports(CreationDelegate defaultFunc, bool manageLifetime = true); + IReadOnlyCollection GetExports(CreationDelegateFactory defaultFunc, bool manageLifetime = true); /// /// Gets the export types. diff --git a/MediaBrowser.Common/Json/JsonDefaults.cs b/MediaBrowser.Common/Json/JsonDefaults.cs index 2ef24a884..177ad39fa 100644 --- a/MediaBrowser.Common/Json/JsonDefaults.cs +++ b/MediaBrowser.Common/Json/JsonDefaults.cs @@ -61,7 +61,7 @@ namespace MediaBrowser.Common.Json /// If the defaults must be modified the author must use the copy constructor. /// /// The default options. - public static JsonSerializerOptions GetOptions() + public static JsonSerializerOptions Options => _jsonSerializerOptions; /// @@ -72,7 +72,7 @@ namespace MediaBrowser.Common.Json /// If the defaults must be modified the author must use the copy constructor. /// /// The camelCase options. - public static JsonSerializerOptions GetCamelCaseOptions() + public static JsonSerializerOptions CamelCaseOptions => _camelCaseJsonSerializerOptions; /// @@ -83,7 +83,7 @@ namespace MediaBrowser.Common.Json /// If the defaults must be modified the author must use the copy constructor. /// /// The PascalCase options. - public static JsonSerializerOptions GetPascalCaseOptions() + public static JsonSerializerOptions PascalCaseOptions => _pascalCaseJsonSerializerOptions; } } diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 34e1934e2..0d9f78704 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -33,6 +33,8 @@ false true true + AllEnabledByDefault + ../jellyfin.ruleset true true true @@ -51,10 +53,6 @@ - - ../jellyfin.ruleset - - <_Parameter1>Jellyfin.Common.Tests diff --git a/MediaBrowser.Common/Net/IPHost.cs b/MediaBrowser.Common/Net/IPHost.cs index 4a7c70190..d67b6b8e1 100644 --- a/MediaBrowser.Common/Net/IPHost.cs +++ b/MediaBrowser.Common/Net/IPHost.cs @@ -406,7 +406,7 @@ namespace MediaBrowser.Common.Net } // If we haven't resolved before, or our timer has run out... - if ((_addresses.Length == 0 && !Resolved) || (DateTime.UtcNow > _lastResolved?.AddMinutes(Timeout))) + if ((_addresses.Length == 0 && !Resolved) || (DateTime.UtcNow > _lastResolved.Value.AddMinutes(Timeout))) { _lastResolved = DateTime.UtcNow; ResolveHostInternal().GetAwaiter().GetResult(); diff --git a/MediaBrowser.Common/Net/IPNetAddress.cs b/MediaBrowser.Common/Net/IPNetAddress.cs index 5fab52eac..59e37a5c6 100644 --- a/MediaBrowser.Common/Net/IPNetAddress.cs +++ b/MediaBrowser.Common/Net/IPNetAddress.cs @@ -216,11 +216,11 @@ namespace MediaBrowser.Common.Net } /// - public override bool Equals(IPAddress address) + public override bool Equals(IPAddress ip) { - if (address != null && !address.Equals(IPAddress.None) && !Address.Equals(IPAddress.None)) + if (ip != null && !ip.Equals(IPAddress.None) && !Address.Equals(IPAddress.None)) { - return address.Equals(Address); + return ip.Equals(Address); } return false; diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index 7b162c0e1..ad5a7338d 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -50,7 +50,7 @@ namespace MediaBrowser.Common.Plugins /// Gets a value indicating whether the plugin can be uninstalled. /// public bool CanUninstall => !Path.GetDirectoryName(AssemblyFilePath) - .Equals(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), StringComparison.InvariantCulture); + .Equals(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), StringComparison.Ordinal); /// /// Gets the plugin info. diff --git a/MediaBrowser.Common/Plugins/BasePluginOfT.cs b/MediaBrowser.Common/Plugins/BasePluginOfT.cs index d5c780851..99c226f50 100644 --- a/MediaBrowser.Common/Plugins/BasePluginOfT.cs +++ b/MediaBrowser.Common/Plugins/BasePluginOfT.cs @@ -39,29 +39,27 @@ namespace MediaBrowser.Common.Plugins { ApplicationPaths = applicationPaths; XmlSerializer = xmlSerializer; - if (this is IPluginAssembly assemblyPlugin) - { - var assembly = GetType().Assembly; - var assemblyName = assembly.GetName(); - var assemblyFilePath = assembly.Location; - var dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(assemblyFilePath)); - if (!Directory.Exists(dataFolderPath) && Version != null) - { - // Try again with the version number appended to the folder name. - dataFolderPath = dataFolderPath + "_" + Version.ToString(); - } + var assembly = GetType().Assembly; + var assemblyName = assembly.GetName(); + var assemblyFilePath = assembly.Location; - assemblyPlugin.SetAttributes(assemblyFilePath, dataFolderPath, assemblyName.Version); + var dataFolderPath = Path.Combine(ApplicationPaths.PluginsPath, Path.GetFileNameWithoutExtension(assemblyFilePath)); + if (!Directory.Exists(dataFolderPath) && Version != null) + { + // Try again with the version number appended to the folder name. + dataFolderPath = dataFolderPath + "_" + Version.ToString(); + } - var idAttributes = assembly.GetCustomAttributes(typeof(GuidAttribute), true); - if (idAttributes.Length > 0) - { - var attribute = (GuidAttribute)idAttributes[0]; - var assemblyId = new Guid(attribute.Value); + SetAttributes(assemblyFilePath, dataFolderPath, assemblyName.Version); - assemblyPlugin.SetId(assemblyId); - } + var idAttributes = assembly.GetCustomAttributes(typeof(GuidAttribute), true); + if (idAttributes.Length > 0) + { + var attribute = (GuidAttribute)idAttributes[0]; + var assemblyId = new Guid(attribute.Value); + + SetId(assemblyId); } } diff --git a/MediaBrowser.Common/Plugins/LocalPlugin.cs b/MediaBrowser.Common/Plugins/LocalPlugin.cs index 23b6cfa81..12a1ad1ec 100644 --- a/MediaBrowser.Common/Plugins/LocalPlugin.cs +++ b/MediaBrowser.Common/Plugins/LocalPlugin.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Common.Plugins public LocalPlugin(string path, bool isSupported, PluginManifest manifest) { Path = path; - DllFiles = new List(); + DllFiles = Array.Empty(); _supported = isSupported; Manifest = manifest; } @@ -59,9 +59,9 @@ namespace MediaBrowser.Common.Plugins public string Path { get; } /// - /// Gets the list of dll files for this plugin. + /// Gets or sets the list of dll files for this plugin. /// - public List DllFiles { get; } + public IReadOnlyList DllFiles { get; set; } /// /// Gets or sets the instance of this plugin. diff --git a/MediaBrowser.Common/Progress/ActionableProgress.cs b/MediaBrowser.Common/Progress/ActionableProgress.cs index d5bcd5be9..fe7cb1078 100644 --- a/MediaBrowser.Common/Progress/ActionableProgress.cs +++ b/MediaBrowser.Common/Progress/ActionableProgress.cs @@ -1,4 +1,5 @@ #pragma warning disable CS1591 +#pragma warning disable CA1003 using System; diff --git a/MediaBrowser.Common/Progress/SimpleProgress.cs b/MediaBrowser.Common/Progress/SimpleProgress.cs index d75675bf1..988d8ad34 100644 --- a/MediaBrowser.Common/Progress/SimpleProgress.cs +++ b/MediaBrowser.Common/Progress/SimpleProgress.cs @@ -1,4 +1,5 @@ #pragma warning disable CS1591 +#pragma warning disable CA1003 using System; diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 65fd1654c..76b6d39a9 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.Entities /// public class CollectionFolder : Folder, ICollectionFolder { - private static readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private static readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; public static IXmlSerializer XmlSerializer { get; set; } public static IServerApplicationHost ApplicationHost { get; set; } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index d487a324f..8c68b47dd 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -34,6 +34,8 @@ false true true + AllEnabledByDefault + ../jellyfin.ruleset true true true @@ -52,8 +54,4 @@ - - ../jellyfin.ruleset - - diff --git a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs index c129eddb3..f78bd6ddf 100644 --- a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs +++ b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs @@ -10,6 +10,6 @@ namespace MediaBrowser.Controller.Providers /// public interface ILocalImageProvider : IImageProvider { - List GetImages(BaseItem item, IDirectoryService directoryService); + IEnumerable GetImages(BaseItem item, IDirectoryService directoryService); } } diff --git a/MediaBrowser.LocalMetadata/Images/CollectionFolderLocalImageProvider.cs b/MediaBrowser.LocalMetadata/Images/CollectionFolderLocalImageProvider.cs index 556bb6a0e..b6189bcdd 100644 --- a/MediaBrowser.LocalMetadata/Images/CollectionFolderLocalImageProvider.cs +++ b/MediaBrowser.LocalMetadata/Images/CollectionFolderLocalImageProvider.cs @@ -35,7 +35,7 @@ namespace MediaBrowser.LocalMetadata.Images } /// - public List GetImages(BaseItem item, IDirectoryService directoryService) + public IEnumerable GetImages(BaseItem item, IDirectoryService directoryService) { var collectionFolder = (CollectionFolder)item; diff --git a/MediaBrowser.LocalMetadata/Images/EpisodeLocalImageProvider.cs b/MediaBrowser.LocalMetadata/Images/EpisodeLocalImageProvider.cs index 393ad2efb..2d3b2d889 100644 --- a/MediaBrowser.LocalMetadata/Images/EpisodeLocalImageProvider.cs +++ b/MediaBrowser.LocalMetadata/Images/EpisodeLocalImageProvider.cs @@ -39,7 +39,7 @@ namespace MediaBrowser.LocalMetadata.Images } /// - public List GetImages(BaseItem item, IDirectoryService directoryService) + public IEnumerable GetImages(BaseItem item, IDirectoryService directoryService) { var parentPath = Path.GetDirectoryName(item.Path); diff --git a/MediaBrowser.LocalMetadata/Images/InternalMetadataFolderImageProvider.cs b/MediaBrowser.LocalMetadata/Images/InternalMetadataFolderImageProvider.cs index 509b5d700..10d691b3e 100644 --- a/MediaBrowser.LocalMetadata/Images/InternalMetadataFolderImageProvider.cs +++ b/MediaBrowser.LocalMetadata/Images/InternalMetadataFolderImageProvider.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using System.Linq; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -69,13 +70,13 @@ namespace MediaBrowser.LocalMetadata.Images } /// - public List GetImages(BaseItem item, IDirectoryService directoryService) + public IEnumerable GetImages(BaseItem item, IDirectoryService directoryService) { var path = item.GetInternalMetadataPath(); if (!Directory.Exists(path)) { - return new List(); + return Enumerable.Empty(); } try @@ -85,7 +86,7 @@ namespace MediaBrowser.LocalMetadata.Images catch (IOException ex) { _logger.LogError(ex, "Error while getting images for {Library}", item.Name); - return new List(); + return Enumerable.Empty(); } } } diff --git a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs index 84c3ed8b0..7ad8c24e8 100644 --- a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs +++ b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs @@ -108,7 +108,7 @@ namespace MediaBrowser.LocalMetadata.Images { if (!item.IsFileProtocol) { - return new List(); + return Enumerable.Empty(); } var path = item.ContainingFolderPath; @@ -116,7 +116,7 @@ namespace MediaBrowser.LocalMetadata.Images // Exit if the cache dir does not exist, alternative solution is to create it, but that's a lot of empty dirs... if (!Directory.Exists(path)) { - return Array.Empty(); + return Enumerable.Empty(); } if (includeDirectories) @@ -133,7 +133,7 @@ namespace MediaBrowser.LocalMetadata.Images } /// - public List GetImages(BaseItem item, IDirectoryService directoryService) + public IEnumerable GetImages(BaseItem item, IDirectoryService directoryService) { var files = GetFiles(item, true, directoryService).ToList(); @@ -151,7 +151,7 @@ namespace MediaBrowser.LocalMetadata.Images /// The images path. /// Instance of the interface. /// The local image info. - public List GetImages(BaseItem item, string path, IDirectoryService directoryService) + public IEnumerable GetImages(BaseItem item, string path, IDirectoryService directoryService) { return GetImages(item, new[] { path }, directoryService); } @@ -163,7 +163,7 @@ namespace MediaBrowser.LocalMetadata.Images /// The image paths. /// Instance of the interface. /// The local image info. - public List GetImages(BaseItem item, IEnumerable paths, IDirectoryService directoryService) + public IEnumerable GetImages(BaseItem item, IEnumerable paths, IDirectoryService directoryService) { IEnumerable files = paths.SelectMany(i => _fileSystem.GetFiles(i, BaseItem.SupportedImageExtensions, true, false)); @@ -181,9 +181,7 @@ namespace MediaBrowser.LocalMetadata.Images { if (supportParentSeriesFiles) { - var season = item as Season; - - if (season != null) + if (item is Season season) { PopulateSeasonImagesFromSeriesFolder(season, images, directoryService); } diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index 1792f1d9b..eb2077a5f 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -16,6 +16,8 @@ true true enable + AllEnabledByDefault + ../jellyfin.ruleset @@ -29,8 +31,4 @@ - - ../jellyfin.ruleset - - diff --git a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs index b0afb834b..5f620634f 100644 --- a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs @@ -1275,8 +1275,8 @@ namespace MediaBrowser.LocalMetadata.Parsers // Only split by comma if there is no pipe in the string // We have to be careful to not split names like Matthew, Jr. - var separator = value.IndexOf('|', StringComparison.Ordinal) == -1 - && value.IndexOf(';', StringComparison.Ordinal) == -1 ? new[] { ',' } : new[] { '|', ';' }; + var separator = !value.Contains('|', StringComparison.Ordinal) + && !value.Contains(';', StringComparison.Ordinal) ? new[] { ',' } : new[] { '|', ';' }; value = value.Trim().Trim(separator); diff --git a/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs index ff846830b..7df800971 100644 --- a/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs @@ -23,7 +23,7 @@ namespace MediaBrowser.LocalMetadata.Parsers } /// - protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult item) + protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult itemResult) { switch (reader.Name) { @@ -33,7 +33,7 @@ namespace MediaBrowser.LocalMetadata.Parsers { using (var subReader = reader.ReadSubtree()) { - FetchFromCollectionItemsNode(subReader, item); + FetchFromCollectionItemsNode(subReader, itemResult); } } else @@ -44,7 +44,7 @@ namespace MediaBrowser.LocalMetadata.Parsers break; default: - base.FetchDataFromXmlNode(reader, item); + base.FetchDataFromXmlNode(reader, itemResult); break; } } diff --git a/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs index 78c0fa8ad..b84307cb2 100644 --- a/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs @@ -23,9 +23,9 @@ namespace MediaBrowser.LocalMetadata.Parsers } /// - protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult result) + protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult itemResult) { - var item = result.Item; + var item = itemResult.Item; switch (reader.Name) { @@ -53,7 +53,7 @@ namespace MediaBrowser.LocalMetadata.Parsers break; default: - base.FetchDataFromXmlNode(reader, result); + base.FetchDataFromXmlNode(reader, itemResult); break; } } diff --git a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs index e59fcb965..dfbce5f49 100644 --- a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Xml; -using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; @@ -37,7 +36,7 @@ namespace MediaBrowser.LocalMetadata.Savers /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. - public BaseXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger) + protected BaseXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger) { FileSystem = fileSystem; ConfigurationManager = configurationManager; @@ -421,20 +420,17 @@ namespace MediaBrowser.LocalMetadata.Savers writer.WriteEndElement(); } - var boxset = item as BoxSet; - if (boxset != null) + if (item is BoxSet boxset) { AddLinkedChildren(boxset, writer, "CollectionItems", "CollectionItem"); } - var playlist = item as Playlist; - if (playlist != null && !Playlist.IsPlaylistFile(playlist.Path)) + if (item is Playlist playlist && !Playlist.IsPlaylistFile(playlist.Path)) { AddLinkedChildren(playlist, writer, "PlaylistItems", "PlaylistItem"); } - var hasShares = item as IHasShares; - if (hasShares != null) + if (item is IHasShares hasShares) { AddShares(hasShares, writer); } @@ -542,10 +538,5 @@ namespace MediaBrowser.LocalMetadata.Savers writer.WriteEndElement(); } - - private bool IsPersonType(PersonInfo person, string type) - { - return string.Equals(person.Type, type, StringComparison.OrdinalIgnoreCase) || string.Equals(person.Role, type, StringComparison.OrdinalIgnoreCase); - } } } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 8a25a64c7..47cf020b4 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -86,7 +86,7 @@ namespace MediaBrowser.MediaEncoding.Encoder _localization = localization; _encodingHelperFactory = encodingHelperFactory; _startupOptionFFmpegPath = config.GetValue(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? string.Empty; - _jsonSerializerOptions = JsonDefaults.GetOptions(); + _jsonSerializerOptions = JsonDefaults.Options; } /// diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AlbumImageProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AlbumImageProvider.cs index cd9e47743..2adb11908 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AlbumImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AlbumImageProvider.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb { private readonly IServerConfigurationManager _config; private readonly IHttpClientFactory _httpClientFactory; - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; public AudioDbAlbumImageProvider(IServerConfigurationManager config, IHttpClientFactory httpClientFactory) { diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AlbumProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AlbumProvider.cs index 0a79f5bb5..00feeec1f 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AlbumProvider.cs @@ -29,7 +29,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; private readonly IHttpClientFactory _httpClientFactory; - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; public static AudioDbAlbumProvider Current; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ArtistImageProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/ArtistImageProvider.cs index 36700d191..b8095ff04 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ArtistImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/ArtistImageProvider.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb { private readonly IServerConfigurationManager _config; private readonly IHttpClientFactory _httpClientFactory; - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; public AudioDbArtistImageProvider(IServerConfigurationManager config, IHttpClientFactory httpClientFactory) { diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ArtistProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/ArtistProvider.cs index 4b1d91567..59ecbc017 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ArtistProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/ArtistProvider.cs @@ -31,7 +31,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; private readonly IHttpClientFactory _httpClientFactory; - private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; public AudioDbArtistProvider(IServerConfigurationManager config, IFileSystem fileSystem, IHttpClientFactory httpClientFactory) { diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs index 97fcbfb6f..428b0ded1 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb _configurationManager = configurationManager; _appHost = appHost; - _jsonOptions = new JsonSerializerOptions(JsonDefaults.GetOptions()); + _jsonOptions = new JsonSerializerOptions(JsonDefaults.Options); _jsonOptions.Converters.Add(new JsonOmdbNotAvailableStringConverter()); _jsonOptions.Converters.Add(new JsonOmdbNotAvailableInt32Converter()); } diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs index e3301ff32..d35805a84 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs @@ -39,7 +39,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb _configurationManager = configurationManager; _appHost = appHost; - _jsonOptions = new JsonSerializerOptions(JsonDefaults.GetOptions()); + _jsonOptions = new JsonSerializerOptions(JsonDefaults.Options); _jsonOptions.Converters.Add(new JsonOmdbNotAvailableStringConverter()); _jsonOptions.Converters.Add(new JsonOmdbNotAvailableInt32Converter()); } diff --git a/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs b/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs index c39ef0ce9..415682e85 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs @@ -16,7 +16,7 @@ namespace Jellyfin.MediaEncoding.Tests var path = Path.Join("Test Data", fileName); using (var stream = File.OpenRead(path)) { - await JsonSerializer.DeserializeAsync(stream, JsonDefaults.GetOptions()).ConfigureAwait(false); + await JsonSerializer.DeserializeAsync(stream, JsonDefaults.Options).ConfigureAwait(false); } } } diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs index 86d6326d8..f5411dcb8 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs @@ -13,7 +13,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers public sealed class DashboardControllerTests : IClassFixture { private readonly JellyfinApplicationFactory _factory; - private readonly JsonSerializerOptions _jsonOpions = JsonDefaults.GetOptions(); + private readonly JsonSerializerOptions _jsonOpions = JsonDefaults.Options; public DashboardControllerTests(JellyfinApplicationFactory factory) { -- cgit v1.2.3 From 65f880be323e154655505c702822ce381fc5569e Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 6 Apr 2021 20:59:47 +0100 Subject: Keep plugin status after update. --- Emby.Server.Implementations/Plugins/PluginManager.cs | 7 ++++--- Emby.Server.Implementations/Updates/InstallationManager.cs | 12 +++++++----- MediaBrowser.Common/Plugins/IPluginManager.cs | 4 +++- 3 files changed, 14 insertions(+), 9 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 700396c4c..3a8296455 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; @@ -368,7 +369,7 @@ namespace Emby.Server.Implementations.Plugins } /// - public async Task GenerateManifest(PackageInfo packageInfo, Version version, string path) + public async Task GenerateManifest(PackageInfo packageInfo, Version version, string path, PluginStatus status) { if (packageInfo == null) { @@ -411,9 +412,9 @@ namespace Emby.Server.Implementations.Plugins Overview = packageInfo.Overview, Owner = packageInfo.Owner, TargetAbi = versionInfo.TargetAbi ?? string.Empty, - Timestamp = string.IsNullOrEmpty(versionInfo.Timestamp) ? DateTime.MinValue : DateTime.Parse(versionInfo.Timestamp), + Timestamp = string.IsNullOrEmpty(versionInfo.Timestamp) ? DateTime.MinValue : DateTime.Parse(versionInfo.Timestamp, CultureInfo.InvariantCulture), Version = versionInfo.Version, - Status = PluginStatus.Active, + Status = status == PluginStatus.Disabled ? PluginStatus.Disabled : PluginStatus.Active, // Keep disabled state. AutoUpdate = true, ImagePath = imagePath }; diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index fc34f93cd..e7307aefe 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -22,6 +22,7 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Events; using MediaBrowser.Controller.Events.Updates; using MediaBrowser.Model.IO; +using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Updates; using Microsoft.Extensions.Logging; @@ -194,7 +195,7 @@ namespace Emby.Server.Implementations.Updates var plugin = _pluginManager.GetPlugin(packageGuid, version.VersionNumber); if (plugin != null) { - await _pluginManager.GenerateManifest(package, version.VersionNumber, plugin.Path); + await _pluginManager.GenerateManifest(package, version.VersionNumber, plugin.Path, plugin.Manifest.Status).ConfigureAwait(false); } // Remove versions with a target ABI greater then the current application version. @@ -500,7 +501,8 @@ namespace Emby.Server.Implementations.Updates var plugins = _pluginManager.Plugins; foreach (var plugin in plugins) { - if (plugin.Manifest?.AutoUpdate == false) + // Don't auto update when plugin marked not to, or when it's disabled. + if (plugin.Manifest?.AutoUpdate == false || plugin.Manifest?.Status == MediaBrowser.Model.Plugins.PluginStatus.Disabled) { continue; } @@ -515,7 +517,7 @@ namespace Emby.Server.Implementations.Updates } } - private async Task PerformPackageInstallation(InstallationInfo package, CancellationToken cancellationToken) + private async Task PerformPackageInstallation(InstallationInfo package, PluginStatus status, CancellationToken cancellationToken) { var extension = Path.GetExtension(package.SourceUrl); if (!string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase)) @@ -567,7 +569,7 @@ namespace Emby.Server.Implementations.Updates stream.Position = 0; _zipClient.ExtractAllFromZip(stream, targetDir, true); - await _pluginManager.GenerateManifest(package.PackageInfo, package.Version, targetDir); + await _pluginManager.GenerateManifest(package.PackageInfo, package.Version, targetDir, status).ConfigureAwait(false); _pluginManager.ImportPluginFrom(targetDir); } @@ -576,7 +578,7 @@ namespace Emby.Server.Implementations.Updates LocalPlugin? plugin = _pluginManager.Plugins.FirstOrDefault(p => p.Id.Equals(package.Id) && p.Version.Equals(package.Version)) ?? _pluginManager.Plugins.FirstOrDefault(p => p.Name.Equals(package.Name, StringComparison.OrdinalIgnoreCase) && p.Version.Equals(package.Version)); - await PerformPackageInstallation(package, cancellationToken).ConfigureAwait(false); + await PerformPackageInstallation(package, plugin?.Manifest.Status ?? PluginStatus.Active, cancellationToken).ConfigureAwait(false); _logger.LogInformation(plugin == null ? "New plugin installed: {PluginName} {PluginVersion}" : "Plugin updated: {PluginName} {PluginVersion}", package.Name, package.Version); return plugin != null; diff --git a/MediaBrowser.Common/Plugins/IPluginManager.cs b/MediaBrowser.Common/Plugins/IPluginManager.cs index f9a8fb6f7..0e2e814cb 100644 --- a/MediaBrowser.Common/Plugins/IPluginManager.cs +++ b/MediaBrowser.Common/Plugins/IPluginManager.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Threading.Tasks; +using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Updates; using Microsoft.Extensions.DependencyInjection; @@ -51,8 +52,9 @@ namespace MediaBrowser.Common.Plugins /// The used to generate a manifest. /// Version to be installed. /// The path where to save the manifest. + /// Initial status of the plugin. /// True if successful. - Task GenerateManifest(PackageInfo packageInfo, Version version, string path); + Task GenerateManifest(PackageInfo packageInfo, Version version, string path, PluginStatus status); /// /// Imports plugin details from a folder. -- cgit v1.2.3 From bcba501dfbe1e0f422829f26159d9a9625530231 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sun, 2 May 2021 19:25:04 +0100 Subject: minor optimization. --- Emby.Server.Implementations/Plugins/PluginManager.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 3a8296455..fd2ee6b7a 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -166,9 +166,7 @@ namespace Emby.Server.Implementations.Plugins /// public void CreatePlugins() { - _ = _appHost.GetExports(CreatePluginInstance) - .Where(i => i != null) - .ToArray(); + _ = _appHost.GetExports(CreatePluginInstance); } /// -- cgit v1.2.3 From 2e98de90628e9a4e42fb182f2d5a2a296acfd827 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 5 May 2021 12:51:14 +0100 Subject: Code Clean up: Convert to null-coalescing operator ?? (#5845) Co-authored-by: Cody Robibero Co-authored-by: Patrick Barron <18354464+barronpm@users.noreply.github.com> --- Emby.Server.Implementations/ApplicationHost.cs | 10 +---- Emby.Server.Implementations/Dto/DtoService.cs | 15 ++------ .../Library/LibraryManager.cs | 5 +-- .../Library/Resolvers/TV/EpisodeResolver.cs | 14 ++----- .../LiveTv/EmbyTV/EmbyTV.cs | 10 ++--- .../LiveTv/Listings/SchedulesDirect.cs | 7 +--- .../LiveTv/LiveTvManager.cs | 15 ++------ .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 5 +-- .../Plugins/PluginManager.cs | 13 +------ .../ScheduledTasks/ScheduledTaskWorker.cs | 7 +--- .../Session/SessionManager.cs | 5 +-- Jellyfin.Api/Controllers/PluginsController.cs | 7 +--- Jellyfin.Api/Controllers/SearchController.cs | 5 +-- Jellyfin.Api/Helpers/StreamingHelpers.cs | 5 +-- MediaBrowser.Common/Net/IPHost.cs | 5 +-- MediaBrowser.Common/Plugins/BasePluginOfT.cs | 5 +-- MediaBrowser.Controller/Entities/BaseItem.cs | 26 ++++--------- MediaBrowser.Controller/Entities/UserView.cs | 5 +-- MediaBrowser.Controller/Library/ItemResolveArgs.cs | 5 +-- MediaBrowser.Controller/Playlists/Playlist.cs | 5 +-- .../Providers/MetadataRefreshOptions.cs | 5 +-- .../Providers/MetadataResult.cs | 16 +++----- .../Probing/ProbeResultNormalizer.cs | 45 ++++++---------------- .../Entities/ProviderIdsExtensions.cs | 5 +-- .../MediaInfo/FFProbeVideoInfo.cs | 5 +-- .../Subtitles/SubtitleManager.cs | 5 +-- RSSDP/SsdpCommunicationsServer.cs | 5 +-- 27 files changed, 60 insertions(+), 200 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 703f8d20d..75d8fc113 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -335,10 +335,7 @@ namespace Emby.Server.Implementations { get { - if (_deviceId == null) - { - _deviceId = new DeviceId(ApplicationPaths, LoggerFactory); - } + _deviceId ??= new DeviceId(ApplicationPaths, LoggerFactory); return _deviceId.Value; } @@ -370,10 +367,7 @@ namespace Emby.Server.Implementations /// System.Object. protected object CreateInstanceSafe(Type type) { - if (_creatingInstances == null) - { - _creatingInstances = new List(); - } + _creatingInstances ??= new List(); if (_creatingInstances.IndexOf(type) != -1) { diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 54b18a8c8..4ae35039a 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -665,10 +665,7 @@ namespace Emby.Server.Implementations.Dto var tag = GetImageCacheTag(item, image); if (!string.IsNullOrEmpty(image.BlurHash)) { - if (dto.ImageBlurHashes == null) - { - dto.ImageBlurHashes = new Dictionary>(); - } + dto.ImageBlurHashes ??= new Dictionary>(); if (!dto.ImageBlurHashes.ContainsKey(image.Type)) { @@ -702,10 +699,7 @@ namespace Emby.Server.Implementations.Dto if (hashes.Count > 0) { - if (dto.ImageBlurHashes == null) - { - dto.ImageBlurHashes = new Dictionary>(); - } + dto.ImageBlurHashes ??= new Dictionary>(); dto.ImageBlurHashes[imageType] = hashes; } @@ -898,10 +892,7 @@ namespace Emby.Server.Implementations.Dto dto.Taglines = new string[] { item.Tagline }; } - if (dto.Taglines == null) - { - dto.Taglines = Array.Empty(); - } + dto.Taglines ??= Array.Empty(); } dto.Type = item.GetBaseItemKind(); diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index a44edad16..4d207471a 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -176,10 +176,7 @@ namespace Emby.Server.Implementations.Library { lock (_rootFolderSyncLock) { - if (_rootFolder == null) - { - _rootFolder = CreateRootFolder(); - } + _rootFolder ??= CreateRootFolder(); } } diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs index 9b4cd7a3d..6f29bc649 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -35,14 +35,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV return null; } - var season = parent as Season; - // Just in case the user decided to nest episodes. // Not officially supported but in some cases we can handle it. - if (season == null) - { - season = parent.GetParents().OfType().FirstOrDefault(); - } + + var season = parent as Season ?? parent.GetParents().OfType().FirstOrDefault(); // If the parent is a Season or Series and the parent is not an extras folder, then this is an Episode if the VideoResolver returns something // Also handle flat tv folders @@ -55,11 +51,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV if (episode != null) { - var series = parent as Series; - if (series == null) - { - series = parent.GetParents().OfType().FirstOrDefault(); - } + var series = parent as Series ?? parent.GetParents().OfType().FirstOrDefault(); if (series != null) { diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 665fbfa0f..28a2095e1 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -2237,14 +2237,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV var enabledTimersForSeries = new List(); foreach (var timer in allTimers) { - var existingTimer = _timerProvider.GetTimer(timer.Id); - - if (existingTimer == null) - { - existingTimer = string.IsNullOrWhiteSpace(timer.ProgramId) + var existingTimer = _timerProvider.GetTimer(timer.Id) + ?? (string.IsNullOrWhiteSpace(timer.ProgramId) ? null - : _timerProvider.GetTimerByProgramId(timer.ProgramId); - } + : _timerProvider.GetTimerByProgramId(timer.ProgramId)); if (existingTimer == null) { diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 1926e738f..9af65cabb 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -787,14 +787,11 @@ namespace Emby.Server.Implementations.LiveTv.Listings { var channelNumber = GetChannelNumber(channel); - var station = allStations.Find(item => string.Equals(item.stationID, channel.stationID, StringComparison.OrdinalIgnoreCase)); - if (station == null) - { - station = new ScheduleDirect.Station + var station = allStations.Find(item => string.Equals(item.stationID, channel.stationID, StringComparison.OrdinalIgnoreCase)) + ?? new ScheduleDirect.Station { stationID = channel.stationID }; - } var channelInfo = new ChannelInfo { diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 63a3146aa..1145d8aa1 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -987,10 +987,7 @@ namespace Emby.Server.Implementations.LiveTv var externalProgramId = programTuple.Item2; string externalSeriesId = programTuple.Item3; - if (timerList == null) - { - timerList = (await GetTimersInternal(new TimerQuery(), cancellationToken).ConfigureAwait(false)).Items; - } + timerList ??= (await GetTimersInternal(new TimerQuery(), cancellationToken).ConfigureAwait(false)).Items; var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, externalProgramId, StringComparison.OrdinalIgnoreCase)); var foundSeriesTimer = false; @@ -1018,10 +1015,7 @@ namespace Emby.Server.Implementations.LiveTv continue; } - if (seriesTimerList == null) - { - seriesTimerList = (await GetSeriesTimersInternal(new SeriesTimerQuery(), cancellationToken).ConfigureAwait(false)).Items; - } + seriesTimerList ??= (await GetSeriesTimersInternal(new SeriesTimerQuery(), cancellationToken).ConfigureAwait(false)).Items; var seriesTimer = seriesTimerList.FirstOrDefault(i => string.Equals(i.SeriesId, externalSeriesId, StringComparison.OrdinalIgnoreCase)); @@ -1974,10 +1968,7 @@ namespace Emby.Server.Implementations.LiveTv }; } - if (service == null) - { - service = _services[0]; - } + service ??= _services[0]; var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index c32ca2fb6..4aa5832b1 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -421,10 +421,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun string audioCodec = channelInfo.AudioCodec; - if (!videoBitrate.HasValue) - { - videoBitrate = isHd ? 15000000 : 2000000; - } + videoBitrate ??= isHd ? 15000000 : 2000000; int? audioBitrate = isHd ? 448000 : 192000; diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index fd2ee6b7a..14df20936 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -44,12 +44,7 @@ namespace Emby.Server.Implementations.Plugins { get { - if (_httpClientFactory == null) - { - _httpClientFactory = _appHost.Resolve(); - } - - return _httpClientFactory; + return _httpClientFactory ?? (_httpClientFactory = _appHost.Resolve()); } } @@ -276,11 +271,7 @@ namespace Emby.Server.Implementations.Plugins // If no version is given, return the current instance. var plugins = _plugins.Where(p => p.Id.Equals(id)).ToList(); - plugin = plugins.FirstOrDefault(p => p.Instance != null); - if (plugin == null) - { - plugin = plugins.OrderByDescending(p => p.Version).FirstOrDefault(); - } + plugin = plugins.FirstOrDefault(p => p.Instance != null) ?? plugins.OrderByDescending(p => p.Version).FirstOrDefault(); } else { diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index 61dccaa19..101d9b537 100644 --- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -301,12 +301,7 @@ namespace Emby.Server.Implementations.ScheduledTasks { get { - if (_id == null) - { - _id = ScheduledTask.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture); - } - - return _id; + return _id ??= ScheduledTask.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture); } } diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 6f21ec31e..6844152ea 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1475,10 +1475,7 @@ namespace Emby.Server.Implementations.Session user = _userManager.GetUserById(request.UserId); } - if (user == null) - { - user = _userManager.GetUserByName(request.Username); - } + user ??= _userManager.GetUserByName(request.Username); if (enforcePassword) { diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index adec86a10..7a6130719 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -207,12 +207,7 @@ namespace Jellyfin.Api.Controllers var plugins = _pluginManager.Plugins.Where(p => p.Id.Equals(pluginId)); // Select the un-instanced one first. - var plugin = plugins.FirstOrDefault(p => p.Instance == null); - if (plugin == null) - { - // Then by the status. - plugin = plugins.OrderBy(p => p.Manifest.Status).FirstOrDefault(); - } + var plugin = plugins.FirstOrDefault(p => p.Instance == null) ?? plugins.OrderBy(p => p.Manifest.Status).FirstOrDefault(); if (plugin != null) { diff --git a/Jellyfin.Api/Controllers/SearchController.cs b/Jellyfin.Api/Controllers/SearchController.cs index 6c22050a7..73bdf9018 100644 --- a/Jellyfin.Api/Controllers/SearchController.cs +++ b/Jellyfin.Api/Controllers/SearchController.cs @@ -228,10 +228,7 @@ namespace Jellyfin.Api.Controllers itemWithImage = GetParentWithImage(item, ImageType.Thumb); } - if (itemWithImage == null) - { - itemWithImage = GetParentWithImage(item, ImageType.Thumb); - } + itemWithImage ??= GetParentWithImage(item, ImageType.Thumb); if (itemWithImage != null) { diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs index 583e613b4..8cffe9c4c 100644 --- a/Jellyfin.Api/Helpers/StreamingHelpers.cs +++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs @@ -292,10 +292,7 @@ namespace Jellyfin.Api.Helpers } } - if (profile == null) - { - profile = dlnaManager.GetDefaultProfile(); - } + profile ??= dlnaManager.GetDefaultProfile(); var audioCodec = state.ActualOutputAudioCodec; diff --git a/MediaBrowser.Common/Net/IPHost.cs b/MediaBrowser.Common/Net/IPHost.cs index fb3ef9b12..7156ce618 100644 --- a/MediaBrowser.Common/Net/IPHost.cs +++ b/MediaBrowser.Common/Net/IPHost.cs @@ -400,10 +400,7 @@ namespace MediaBrowser.Common.Net private bool ResolveHost() { // When was the last time we resolved? - if (_lastResolved == null) - { - _lastResolved = DateTime.UtcNow; - } + _lastResolved ??= DateTime.UtcNow; // If we haven't resolved before, or our timer has run out... if ((_addresses.Length == 0 && !Resolved) || (DateTime.UtcNow > _lastResolved.Value.AddMinutes(Timeout))) diff --git a/MediaBrowser.Common/Plugins/BasePluginOfT.cs b/MediaBrowser.Common/Plugins/BasePluginOfT.cs index 99c226f50..e074cc6a0 100644 --- a/MediaBrowser.Common/Plugins/BasePluginOfT.cs +++ b/MediaBrowser.Common/Plugins/BasePluginOfT.cs @@ -105,10 +105,7 @@ namespace MediaBrowser.Common.Plugins { lock (_configurationSyncLock) { - if (_configuration == null) - { - _configuration = LoadConfiguration(); - } + _configuration ??= LoadConfiguration(); } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 1b69c6646..32ae15498 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -106,15 +106,10 @@ namespace MediaBrowser.Controller.Entities { get { - if (_themeSongIds == null) - { - _themeSongIds = GetExtras() - .Where(extra => extra.ExtraType == Model.Entities.ExtraType.ThemeSong) - .Select(song => song.Id) - .ToArray(); - } - - return _themeSongIds; + return _themeSongIds ??= GetExtras() + .Where(extra => extra.ExtraType == Model.Entities.ExtraType.ThemeSong) + .Select(song => song.Id) + .ToArray(); } private set @@ -128,15 +123,10 @@ namespace MediaBrowser.Controller.Entities { get { - if (_themeVideoIds == null) - { - _themeVideoIds = GetExtras() - .Where(extra => extra.ExtraType == Model.Entities.ExtraType.ThemeVideo) - .Select(song => song.Id) - .ToArray(); - } - - return _themeVideoIds; + return _themeVideoIds ??= GetExtras() + .Where(extra => extra.ExtraType == Model.Entities.ExtraType.ThemeVideo) + .Select(song => song.Id) + .ToArray(); } private set diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index b1da4d64c..fec83dd94 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -75,10 +75,7 @@ namespace MediaBrowser.Controller.Entities public override List GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query) { - if (query == null) - { - query = new InternalItemsQuery(user); - } + query ??= new InternalItemsQuery(user); query.EnableTotalRecordCount = false; var result = GetItemList(query); diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index f86f7df25..f9086066d 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -147,10 +147,7 @@ namespace MediaBrowser.Controller.Library throw new ArgumentException("The path was empty or null.", nameof(path)); } - if (AdditionalLocations == null) - { - AdditionalLocations = new List(); - } + AdditionalLocations ??= new List(); AdditionalLocations.Add(path); } diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index c9c168c4c..3c93cfc79 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -126,10 +126,7 @@ namespace MediaBrowser.Controller.Playlists private List GetPlayableItems(User user, InternalItemsQuery query) { - if (query == null) - { - query = new InternalItemsQuery(user); - } + query ??= new InternalItemsQuery(user); query.IsFolder = false; diff --git a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs index b92b83701..db0ef7072 100644 --- a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs +++ b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs @@ -45,10 +45,7 @@ namespace MediaBrowser.Controller.Providers if (copy.RefreshPaths != null && copy.RefreshPaths.Length > 0) { - if (RefreshPaths == null) - { - RefreshPaths = Array.Empty(); - } + RefreshPaths ??= Array.Empty(); RefreshPaths = copy.RefreshPaths.ToArray(); } diff --git a/MediaBrowser.Controller/Providers/MetadataResult.cs b/MediaBrowser.Controller/Providers/MetadataResult.cs index 864cb3050..98c7eadfe 100644 --- a/MediaBrowser.Controller/Providers/MetadataResult.cs +++ b/MediaBrowser.Controller/Providers/MetadataResult.cs @@ -37,10 +37,7 @@ namespace MediaBrowser.Controller.Providers public void AddPerson(PersonInfo p) { - if (People == null) - { - People = new List(); - } + People ??= new List(); PeopleHelper.AddPerson(People, p); } @@ -54,16 +51,15 @@ namespace MediaBrowser.Controller.Providers { People = new List(); } - - People.Clear(); + else + { + People.Clear(); + } } public UserItemData GetOrAddUserData(string userId) { - if (UserDataList == null) - { - UserDataList = new List(); - } + UserDataList ??= new List(); UserItemData userData = null; diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index ee2e5fcde..2e96f8cb0 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -1187,43 +1187,28 @@ namespace MediaBrowser.MediaEncoding.Probing FetchStudios(audio, tags, "label"); // These support mulitple values, but for now we only store the first. - var mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id")); - if (mb == null) - { - mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMARTISTID")); - } + var mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id")) + ?? GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMARTISTID")); audio.SetProviderId(MetadataProvider.MusicBrainzAlbumArtist, mb); - mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id")); - if (mb == null) - { - mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ARTISTID")); - } + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id")) + ?? GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ARTISTID")); audio.SetProviderId(MetadataProvider.MusicBrainzArtist, mb); - mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id")); - if (mb == null) - { - mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMID")); - } + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id")) + ?? GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMID")); audio.SetProviderId(MetadataProvider.MusicBrainzAlbum, mb); - mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id")); - if (mb == null) - { - mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASEGROUPID")); - } + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id")) + ?? GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASEGROUPID")); audio.SetProviderId(MetadataProvider.MusicBrainzReleaseGroup, mb); - mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Track Id")); - if (mb == null) - { - mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASETRACKID")); - } + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Track Id")) + ?? GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASETRACKID")); audio.SetProviderId(MetadataProvider.MusicBrainzTrack, mb); } @@ -1290,15 +1275,7 @@ namespace MediaBrowser.MediaEncoding.Probing private IEnumerable GetSplitWhitelist() { - if (_splitWhiteList == null) - { - _splitWhiteList = new List - { - "AC/DC" - }; - } - - return _splitWhiteList; + return _splitWhiteList ??= new List { "AC/DC" }; } /// diff --git a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs index 09d14dc6a..ce4b0ec92 100644 --- a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs +++ b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs @@ -123,10 +123,7 @@ namespace MediaBrowser.Model.Entities else { // Ensure it exists - if (instance.ProviderIds == null) - { - instance.ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); - } + instance.ProviderIds ??= new Dictionary(StringComparer.OrdinalIgnoreCase); instance.ProviderIds[name] = value; } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 74849a522..f049cc81f 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -111,10 +111,7 @@ namespace MediaBrowser.Providers.MediaInfo } } - if (streamFileNames == null) - { - streamFileNames = Array.Empty(); - } + streamFileNames ??= Array.Empty(); mediaInfoResult = await GetMediaInfo(item, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs index 1f3d9acff..8d62343cb 100644 --- a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs +++ b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs @@ -256,10 +256,7 @@ namespace MediaBrowser.Providers.Subtitles } catch (Exception ex) { - if (exceptionToThrow == null) - { - exceptionToThrow = ex; - } + exceptionToThrow ??= ex; } finally { diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 8f1f0fa61..f448ad38b 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -415,10 +415,7 @@ namespace Rssdp.Infrastructure { lock (_SendSocketSynchroniser) { - if (_sendSockets == null) - { - _sendSockets = CreateSocketAndListenForResponsesAsync(); - } + _sendSockets ??= CreateSocketAndListenForResponsesAsync(); } } } -- cgit v1.2.3 From 7e8428e588b3f0a0574da44081098c64fe1a47d7 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Thu, 20 May 2021 21:28:18 +0200 Subject: Enable nullable reference types for Emby.Server.Implementations --- .../AppBase/BaseApplicationPaths.cs | 8 ++------ .../AppBase/BaseConfigurationManager.cs | 2 ++ .../AppBase/ConfigurationHelper.cs | 2 -- Emby.Server.Implementations/ApplicationHost.cs | 2 ++ .../Channels/ChannelManager.cs | 2 ++ .../Collections/CollectionImageProvider.cs | 4 ++-- .../Collections/CollectionManager.cs | 2 ++ .../Configuration/ServerConfigurationManager.cs | 2 ++ .../Cryptography/CryptographyProvider.cs | 2 -- .../Data/BaseSqliteRepository.cs | 2 ++ .../Data/ManagedConnection.cs | 2 +- Emby.Server.Implementations/Data/SqliteExtensions.cs | 1 + .../Data/SqliteItemRepository.cs | 2 ++ .../Data/SqliteUserDataRepository.cs | 2 ++ Emby.Server.Implementations/Data/TypeMapper.cs | 6 +++--- Emby.Server.Implementations/Devices/DeviceId.cs | 2 ++ Emby.Server.Implementations/Devices/DeviceManager.cs | 2 ++ Emby.Server.Implementations/Dto/DtoService.cs | 2 ++ .../Emby.Server.Implementations.csproj | 1 + .../EntryPoints/ExternalPortForwarding.cs | 2 ++ .../EntryPoints/LibraryChangedNotifier.cs | 2 ++ .../EntryPoints/RecordingNotifier.cs | 2 ++ .../EntryPoints/UdpServerEntryPoint.cs | 2 -- .../EntryPoints/UserDataChangeNotifier.cs | 2 ++ .../HttpServer/Security/AuthorizationContext.cs | 20 ++++++++++---------- .../HttpServer/Security/SessionContext.cs | 4 ++-- .../HttpServer/WebSocketConnection.cs | 2 -- .../HttpServer/WebSocketManager.cs | 2 ++ Emby.Server.Implementations/IO/FileRefresher.cs | 2 ++ Emby.Server.Implementations/IO/LibraryMonitor.cs | 2 ++ Emby.Server.Implementations/IO/ManagedFileSystem.cs | 6 +++--- .../IO/MbLinkShortcutHandler.cs | 2 +- Emby.Server.Implementations/IO/StreamHelper.cs | 2 +- Emby.Server.Implementations/IStartupOptions.cs | 1 - .../Images/BaseDynamicImageProvider.cs | 2 ++ .../Images/CollectionFolderImageProvider.cs | 2 ++ .../Images/DynamicImageProvider.cs | 2 ++ .../Images/FolderImageProvider.cs | 2 ++ .../Images/GenreImageProvider.cs | 2 ++ .../Images/PlaylistImageProvider.cs | 2 ++ .../Library/ExclusiveLiveStream.cs | 2 ++ .../Library/IgnorePatterns.cs | 2 -- .../Library/LibraryManager.cs | 2 ++ .../Library/LiveStreamHelper.cs | 2 ++ .../Library/MediaSourceManager.cs | 2 ++ .../Library/MediaStreamSelector.cs | 2 ++ Emby.Server.Implementations/Library/MusicManager.cs | 2 ++ .../Library/PathExtensions.cs | 2 -- .../Library/ResolverHelper.cs | 2 -- .../Library/Resolvers/Audio/AudioResolver.cs | 2 ++ .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 2 ++ .../Library/Resolvers/Audio/MusicArtistResolver.cs | 2 ++ .../Library/Resolvers/BaseVideoResolver.cs | 2 ++ .../Library/Resolvers/Books/BookResolver.cs | 2 ++ .../Library/Resolvers/FolderResolver.cs | 2 ++ .../Library/Resolvers/ItemResolver.cs | 2 ++ .../Library/Resolvers/Movies/BoxSetResolver.cs | 2 ++ .../Library/Resolvers/Movies/MovieResolver.cs | 2 ++ .../Library/Resolvers/PhotoAlbumResolver.cs | 2 ++ .../Library/Resolvers/PhotoResolver.cs | 2 ++ .../Library/Resolvers/PlaylistResolver.cs | 2 ++ .../Library/Resolvers/SpecialFolderResolver.cs | 2 ++ .../Library/Resolvers/TV/EpisodeResolver.cs | 2 ++ .../Library/Resolvers/TV/SeasonResolver.cs | 2 ++ .../Library/Resolvers/TV/SeriesResolver.cs | 2 ++ .../Library/Resolvers/VideoResolver.cs | 2 ++ Emby.Server.Implementations/Library/SearchEngine.cs | 2 ++ .../Library/UserDataManager.cs | 2 ++ .../Library/UserViewManager.cs | 2 ++ .../LiveTv/EmbyTV/DirectRecorder.cs | 2 ++ Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 2 ++ .../LiveTv/EmbyTV/EncodedRecorder.cs | 2 ++ .../LiveTv/EmbyTV/EpgChannelData.cs | 7 +++---- .../LiveTv/EmbyTV/ItemDataProvider.cs | 2 ++ .../LiveTv/EmbyTV/RecordingHelper.cs | 2 ++ .../LiveTv/EmbyTV/TimerManager.cs | 2 ++ .../LiveTv/Listings/SchedulesDirect.cs | 2 ++ .../LiveTv/Listings/XmlTvListingsProvider.cs | 2 ++ .../LiveTv/LiveTvDtoService.cs | 2 ++ Emby.Server.Implementations/LiveTv/LiveTvManager.cs | 2 ++ .../LiveTv/LiveTvMediaSourceProvider.cs | 2 ++ .../LiveTv/TunerHosts/BaseTunerHost.cs | 2 ++ .../LiveTv/TunerHosts/HdHomerun/Channels.cs | 2 ++ .../LiveTv/TunerHosts/HdHomerun/DiscoverResponse.cs | 2 ++ .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 2 ++ .../LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs | 2 ++ .../TunerHosts/HdHomerun/HdHomerunUdpStream.cs | 2 ++ .../LiveTv/TunerHosts/LiveStream.cs | 2 ++ .../LiveTv/TunerHosts/M3UTunerHost.cs | 2 ++ .../LiveTv/TunerHosts/M3uParser.cs | 2 ++ .../LiveTv/TunerHosts/SharedHttpStream.cs | 2 ++ .../Localization/LocalizationManager.cs | 2 ++ .../MediaEncoder/EncodingManager.cs | 2 ++ Emby.Server.Implementations/Net/SocketFactory.cs | 2 ++ Emby.Server.Implementations/Net/UdpSocket.cs | 2 ++ .../Playlists/PlaylistManager.cs | 2 ++ Emby.Server.Implementations/Plugins/PluginManager.cs | 2 -- .../QuickConnect/QuickConnectManager.cs | 2 ++ .../ScheduledTasks/ScheduledTaskWorker.cs | 2 ++ .../ScheduledTasks/TaskManager.cs | 2 ++ .../ScheduledTasks/Tasks/ChapterImagesTask.cs | 6 ++++-- .../ScheduledTasks/Tasks/CleanActivityLogTask.cs | 4 ++-- .../ScheduledTasks/Triggers/DailyTrigger.cs | 2 ++ .../ScheduledTasks/Triggers/IntervalTrigger.cs | 2 ++ .../ScheduledTasks/Triggers/StartupTrigger.cs | 2 ++ .../ScheduledTasks/Triggers/WeeklyTrigger.cs | 2 ++ .../Security/AuthenticationRepository.cs | 2 ++ .../Serialization/MyXmlSerializer.cs | 10 ++++++---- .../Session/SessionManager.cs | 2 ++ .../Session/SessionWebSocketListener.cs | 2 ++ .../Session/WebSocketController.cs | 1 - .../Sorting/AiredEpisodeOrderComparer.cs | 2 +- .../Sorting/AlbumArtistComparer.cs | 4 ++-- Emby.Server.Implementations/Sorting/AlbumComparer.cs | 4 ++-- .../Sorting/ArtistComparer.cs | 4 ++-- .../Sorting/CommunityRatingComparer.cs | 2 +- .../Sorting/CriticRatingComparer.cs | 6 +++--- .../Sorting/DateCreatedComparer.cs | 2 +- .../Sorting/DateLastMediaAddedComparer.cs | 1 + .../Sorting/DatePlayedComparer.cs | 2 ++ .../Sorting/IsFavoriteOrLikeComparer.cs | 1 + .../Sorting/IsFolderComparer.cs | 6 +++--- .../Sorting/IsPlayedComparer.cs | 2 ++ .../Sorting/IsUnplayedComparer.cs | 2 ++ Emby.Server.Implementations/Sorting/NameComparer.cs | 2 +- .../Sorting/OfficialRatingComparer.cs | 2 +- .../Sorting/PlayCountComparer.cs | 2 ++ .../Sorting/PremiereDateComparer.cs | 9 +++++++-- .../Sorting/ProductionYearComparer.cs | 9 +++++++-- .../Sorting/RandomComparer.cs | 2 +- .../Sorting/RuntimeComparer.cs | 2 ++ .../Sorting/SeriesSortNameComparer.cs | 2 ++ .../Sorting/SortNameComparer.cs | 2 ++ .../Sorting/StartDateComparer.cs | 2 ++ .../Sorting/StudioComparer.cs | 2 ++ Emby.Server.Implementations/SyncPlay/Group.cs | 2 ++ .../SyncPlay/SyncPlayManager.cs | 2 ++ Emby.Server.Implementations/TV/TVSeriesManager.cs | 2 ++ Emby.Server.Implementations/Udp/UdpServer.cs | 2 ++ .../Updates/InstallationManager.cs | 2 ++ Jellyfin.Api/Controllers/DynamicHlsController.cs | 4 ++-- Jellyfin.Api/Helpers/TranscodingJobHelper.cs | 4 +++- .../Models/PlaybackDtos/TranscodingThrottler.cs | 3 ++- Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs | 11 +++++++---- .../Extensions/StringExtensions.cs | 1 + MediaBrowser.Controller/Net/ISessionContext.cs | 4 ++-- MediaBrowser.Controller/Sorting/IBaseItemComparer.cs | 2 +- MediaBrowser.Model/IO/IFileSystem.cs | 7 +++---- MediaBrowser.Model/IO/IShortcutHandler.cs | 2 +- MediaBrowser.Model/IO/IStreamHelper.cs | 2 +- MediaBrowser.Model/Tasks/ITaskTrigger.cs | 2 +- 151 files changed, 300 insertions(+), 99 deletions(-) (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs index 660bbb2de..6edfad575 100644 --- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs +++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs @@ -33,7 +33,7 @@ namespace Emby.Server.Implementations.AppBase CachePath = cacheDirectoryPath; WebPath = webDirectoryPath; - DataPath = Path.Combine(ProgramDataPath, "data"); + _dataPath = Directory.CreateDirectory(Path.Combine(ProgramDataPath, "data")).FullName; } /// @@ -55,11 +55,7 @@ namespace Emby.Server.Implementations.AppBase /// Gets the folder path to the data directory. /// /// The data directory. - public string DataPath - { - get => _dataPath; - private set => _dataPath = Directory.CreateDirectory(value).FullName; - } + public string DataPath => _dataPath; /// public string VirtualDataPath => "%AppDataPath%"; diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs index 4f72c8ce1..8c919db43 100644 --- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs +++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs index 29bac6634..de770f59e 100644 --- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs +++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.IO; using System.Linq; diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 75d8fc113..82995deb3 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 7324b0ee9..448f12403 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using System.Globalization; diff --git a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs index c69a07e83..ca8409402 100644 --- a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs +++ b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs @@ -82,9 +82,9 @@ namespace Emby.Server.Implementations.Collections return null; }) .Where(i => i != null) - .GroupBy(x => x.Id) + .GroupBy(x => x!.Id) // We removed the null values .Select(x => x.First()) - .ToList(); + .ToList()!; // Again... the list doesn't contain any null values } /// diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs index c56f33448..82d80fc83 100644 --- a/Emby.Server.Implementations/Collections/CollectionManager.cs +++ b/Emby.Server.Implementations/Collections/CollectionManager.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using System.IO; diff --git a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs index 7a8ed8c29..ff5602f24 100644 --- a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Globalization; using System.IO; diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs index 12a9e44e7..4a9b28085 100644 --- a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs +++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Collections.Generic; using System.Security.Cryptography; diff --git a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs index c331a6112..6f23a0888 100644 --- a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs +++ b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Data/ManagedConnection.cs b/Emby.Server.Implementations/Data/ManagedConnection.cs index 5c094ddd2..10c6f837e 100644 --- a/Emby.Server.Implementations/Data/ManagedConnection.cs +++ b/Emby.Server.Implementations/Data/ManagedConnection.cs @@ -9,7 +9,7 @@ namespace Emby.Server.Implementations.Data { public class ManagedConnection : IDisposable { - private SQLiteDatabaseConnection _db; + private SQLiteDatabaseConnection? _db; private readonly SemaphoreSlim _writeLock; private bool _disposed = false; diff --git a/Emby.Server.Implementations/Data/SqliteExtensions.cs b/Emby.Server.Implementations/Data/SqliteExtensions.cs index a8f3feb58..e532825af 100644 --- a/Emby.Server.Implementations/Data/SqliteExtensions.cs +++ b/Emby.Server.Implementations/Data/SqliteExtensions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index b3d8860a9..5b4bbb339 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs index e0ebd0a6c..1756bcae0 100644 --- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Data/TypeMapper.cs b/Emby.Server.Implementations/Data/TypeMapper.cs index 7044b1d19..7f1306d15 100644 --- a/Emby.Server.Implementations/Data/TypeMapper.cs +++ b/Emby.Server.Implementations/Data/TypeMapper.cs @@ -13,7 +13,7 @@ namespace Emby.Server.Implementations.Data /// This holds all the types in the running assemblies /// so that we can de-serialize properly when we don't have strong types. /// - private readonly ConcurrentDictionary _typeMap = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _typeMap = new ConcurrentDictionary(); /// /// Gets the type. @@ -21,7 +21,7 @@ namespace Emby.Server.Implementations.Data /// Name of the type. /// Type. /// typeName is null. - public Type GetType(string typeName) + public Type? GetType(string typeName) { if (string.IsNullOrEmpty(typeName)) { @@ -36,7 +36,7 @@ namespace Emby.Server.Implementations.Data /// /// Name of the type. /// Type. - private Type LookupType(string typeName) + private Type? LookupType(string typeName) { return AppDomain.CurrentDomain.GetAssemblies() .Select(a => a.GetType(typeName)) diff --git a/Emby.Server.Implementations/Devices/DeviceId.cs b/Emby.Server.Implementations/Devices/DeviceId.cs index fa6ac95fd..3d15b3e76 100644 --- a/Emby.Server.Implementations/Devices/DeviceId.cs +++ b/Emby.Server.Implementations/Devices/DeviceId.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs index da5047d24..2637addce 100644 --- a/Emby.Server.Implementations/Devices/DeviceManager.cs +++ b/Emby.Server.Implementations/Devices/DeviceManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 4ae35039a..7411239a1 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 14f6f565c..113863519 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -44,6 +44,7 @@ false true true + enable AD0001 AllEnabledByDefault diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 14201ead2..cc3e4a2c2 100644 --- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index ae1b51b4c..5bb4100ba 100644 --- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs index 824bb85f4..e0ca02d98 100644 --- a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index 3624e079f..211941f44 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Net.Sockets; using System.Threading; diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index 1989e9ed2..332fb3385 100644 --- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs index fbf9254d1..c87f7dbbd 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs @@ -27,7 +27,7 @@ namespace Emby.Server.Implementations.HttpServer.Security { if (requestContext.Request.HttpContext.Items.TryGetValue("AuthorizationInfo", out var cached)) { - return (AuthorizationInfo)cached; + return (AuthorizationInfo)cached!; // Cache should never contain null } return GetAuthorization(requestContext); @@ -55,15 +55,15 @@ namespace Emby.Server.Implementations.HttpServer.Security } private AuthorizationInfo GetAuthorizationInfoFromDictionary( - in Dictionary auth, + in Dictionary? auth, in IHeaderDictionary headers, in IQueryCollection queryString) { - string deviceId = null; - string device = null; - string client = null; - string version = null; - string token = null; + string? deviceId = null; + string? device = null; + string? client = null; + string? version = null; + string? token = null; if (auth != null) { @@ -206,7 +206,7 @@ namespace Emby.Server.Implementations.HttpServer.Security /// /// The HTTP req. /// Dictionary{System.StringSystem.String}. - private Dictionary GetAuthorizationDictionary(HttpContext httpReq) + private Dictionary? GetAuthorizationDictionary(HttpContext httpReq) { var auth = httpReq.Request.Headers["X-Emby-Authorization"]; @@ -223,7 +223,7 @@ namespace Emby.Server.Implementations.HttpServer.Security /// /// The HTTP req. /// Dictionary{System.StringSystem.String}. - private Dictionary GetAuthorizationDictionary(HttpRequest httpReq) + private Dictionary? GetAuthorizationDictionary(HttpRequest httpReq) { var auth = httpReq.Headers["X-Emby-Authorization"]; @@ -240,7 +240,7 @@ namespace Emby.Server.Implementations.HttpServer.Security /// /// The authorization header. /// Dictionary{System.StringSystem.String}. - private Dictionary GetAuthorization(ReadOnlySpan authorizationHeader) + private Dictionary? GetAuthorization(ReadOnlySpan authorizationHeader) { if (authorizationHeader == null) { diff --git a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs index dd77b45d8..c375f36ce 100644 --- a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs +++ b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs @@ -36,14 +36,14 @@ namespace Emby.Server.Implementations.HttpServer.Security return GetSession((HttpContext)requestContext); } - public User GetUser(HttpContext requestContext) + public User? GetUser(HttpContext requestContext) { var session = GetSession(requestContext); return session == null || session.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(session.UserId); } - public User GetUser(object requestContext) + public User? GetUser(object requestContext) { return GetUser(((HttpRequest)requestContext).HttpContext); } diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index 06acb5606..8f7d60669 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Buffers; using System.IO.Pipelines; diff --git a/Emby.Server.Implementations/HttpServer/WebSocketManager.cs b/Emby.Server.Implementations/HttpServer/WebSocketManager.cs index 1bee1ac31..861c0a95e 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketManager.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs index 7435e9d0b..47a83d77c 100644 --- a/Emby.Server.Implementations/IO/FileRefresher.cs +++ b/Emby.Server.Implementations/IO/FileRefresher.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs index 3353fae9d..aa80bccd7 100644 --- a/Emby.Server.Implementations/IO/LibraryMonitor.cs +++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 27096ed33..6a554e68a 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -61,7 +61,7 @@ namespace Emby.Server.Implementations.IO /// The filename. /// System.String. /// filename - public virtual string ResolveShortcut(string filename) + public virtual string? ResolveShortcut(string filename) { if (string.IsNullOrEmpty(filename)) { @@ -601,7 +601,7 @@ namespace Emby.Server.Implementations.IO return GetFiles(path, null, false, recursive); } - public virtual IEnumerable GetFiles(string path, IReadOnlyList extensions, bool enableCaseSensitiveExtensions, bool recursive = false) + public virtual IEnumerable GetFiles(string path, IReadOnlyList? extensions, bool enableCaseSensitiveExtensions, bool recursive = false) { var enumerationOptions = GetEnumerationOptions(recursive); @@ -655,7 +655,7 @@ namespace Emby.Server.Implementations.IO return GetFilePaths(path, null, false, recursive); } - public virtual IEnumerable GetFilePaths(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) + public virtual IEnumerable GetFilePaths(string path, string[]? extensions, bool enableCaseSensitiveExtensions, bool recursive = false) { var enumerationOptions = GetEnumerationOptions(recursive); diff --git a/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs b/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs index e6696b8c4..76c58d5dc 100644 --- a/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs +++ b/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs @@ -17,7 +17,7 @@ namespace Emby.Server.Implementations.IO public string Extension => ".mblink"; - public string Resolve(string shortcutPath) + public string? Resolve(string shortcutPath) { if (string.IsNullOrEmpty(shortcutPath)) { diff --git a/Emby.Server.Implementations/IO/StreamHelper.cs b/Emby.Server.Implementations/IO/StreamHelper.cs index c16ebd61b..e4f5f4cf0 100644 --- a/Emby.Server.Implementations/IO/StreamHelper.cs +++ b/Emby.Server.Implementations/IO/StreamHelper.cs @@ -11,7 +11,7 @@ namespace Emby.Server.Implementations.IO { public class StreamHelper : IStreamHelper { - public async Task CopyToAsync(Stream source, Stream destination, int bufferSize, Action onStarted, CancellationToken cancellationToken) + public async Task CopyToAsync(Stream source, Stream destination, int bufferSize, Action? onStarted, CancellationToken cancellationToken) { byte[] buffer = ArrayPool.Shared.Rent(bufferSize); try diff --git a/Emby.Server.Implementations/IStartupOptions.cs b/Emby.Server.Implementations/IStartupOptions.cs index f719dc5f8..a430b9e72 100644 --- a/Emby.Server.Implementations/IStartupOptions.cs +++ b/Emby.Server.Implementations/IStartupOptions.cs @@ -1,5 +1,4 @@ #pragma warning disable CS1591 -#nullable enable namespace Emby.Server.Implementations { diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs index 6fa3c1c61..833fb0b7a 100644 --- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs b/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs index 161b4c452..ff5f26ce0 100644 --- a/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs +++ b/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Images/DynamicImageProvider.cs b/Emby.Server.Implementations/Images/DynamicImageProvider.cs index 50c531482..900b3fd9c 100644 --- a/Emby.Server.Implementations/Images/DynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/DynamicImageProvider.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Images/FolderImageProvider.cs b/Emby.Server.Implementations/Images/FolderImageProvider.cs index 0224ab32a..859017f86 100644 --- a/Emby.Server.Implementations/Images/FolderImageProvider.cs +++ b/Emby.Server.Implementations/Images/FolderImageProvider.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System.Collections.Generic; diff --git a/Emby.Server.Implementations/Images/GenreImageProvider.cs b/Emby.Server.Implementations/Images/GenreImageProvider.cs index 381788231..6da431c68 100644 --- a/Emby.Server.Implementations/Images/GenreImageProvider.cs +++ b/Emby.Server.Implementations/Images/GenreImageProvider.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System.Collections.Generic; diff --git a/Emby.Server.Implementations/Images/PlaylistImageProvider.cs b/Emby.Server.Implementations/Images/PlaylistImageProvider.cs index a4c106e87..b8f0f0d65 100644 --- a/Emby.Server.Implementations/Images/PlaylistImageProvider.cs +++ b/Emby.Server.Implementations/Images/PlaylistImageProvider.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System.Collections.Generic; diff --git a/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs b/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs index 236453e80..6c65b5899 100644 --- a/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs +++ b/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/IgnorePatterns.cs b/Emby.Server.Implementations/Library/IgnorePatterns.cs index e30a67593..5384c04b3 100644 --- a/Emby.Server.Implementations/Library/IgnorePatterns.cs +++ b/Emby.Server.Implementations/Library/IgnorePatterns.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Linq; using DotNet.Globbing; diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 4d207471a..f8d8197d4 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/LiveStreamHelper.cs b/Emby.Server.Implementations/Library/LiveStreamHelper.cs index c2951dd15..4ef7923db 100644 --- a/Emby.Server.Implementations/Library/LiveStreamHelper.cs +++ b/Emby.Server.Implementations/Library/LiveStreamHelper.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 85d6d3043..38e81d14c 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/MediaStreamSelector.cs b/Emby.Server.Implementations/Library/MediaStreamSelector.cs index 28fa06239..b833122ea 100644 --- a/Emby.Server.Implementations/Library/MediaStreamSelector.cs +++ b/Emby.Server.Implementations/Library/MediaStreamSelector.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/MusicManager.cs b/Emby.Server.Implementations/Library/MusicManager.cs index f8bae4fd1..06300adeb 100644 --- a/Emby.Server.Implementations/Library/MusicManager.cs +++ b/Emby.Server.Implementations/Library/MusicManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/PathExtensions.cs b/Emby.Server.Implementations/Library/PathExtensions.cs index 0de4edb7e..86b8039fa 100644 --- a/Emby.Server.Implementations/Library/PathExtensions.cs +++ b/Emby.Server.Implementations/Library/PathExtensions.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Diagnostics.CodeAnalysis; using MediaBrowser.Common.Providers; diff --git a/Emby.Server.Implementations/Library/ResolverHelper.cs b/Emby.Server.Implementations/Library/ResolverHelper.cs index 1d9b44874..ac75e5d3a 100644 --- a/Emby.Server.Implementations/Library/ResolverHelper.cs +++ b/Emby.Server.Implementations/Library/ResolverHelper.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.IO; using System.Linq; diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs index 4ad84579d..e893d6335 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index bf32381eb..8e1eccb10 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using System.Linq; diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs index 60f82806f..3d2ae95d2 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Linq; using System.Threading.Tasks; diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index 16050185f..a3dcdc944 100644 --- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs index 0525c7e30..68076730b 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/Resolvers/FolderResolver.cs b/Emby.Server.Implementations/Library/Resolvers/FolderResolver.cs index 7dbce7a6e..7aaee017d 100644 --- a/Emby.Server.Implementations/Library/Resolvers/FolderResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/FolderResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; diff --git a/Emby.Server.Implementations/Library/Resolvers/ItemResolver.cs b/Emby.Server.Implementations/Library/Resolvers/ItemResolver.cs index 92fb2a753..fa45ccf84 100644 --- a/Emby.Server.Implementations/Library/Resolvers/ItemResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/ItemResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs index 295e9e120..69d71d0d9 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.IO; using MediaBrowser.Controller.Entities; diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 16bf4dc4a..02c528764 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using System.IO; diff --git a/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs index 204c8a62e..534bc80dd 100644 --- a/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; diff --git a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs index 3cb6542cf..57bf40e9e 100644 --- a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs index 5f051321f..ecd44be47 100644 --- a/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs index 99f304190..7b4e14334 100644 --- a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs index 6f29bc649..d6ae91056 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Linq; using MediaBrowser.Controller.Entities; diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs index 768e2e4f5..7d707df18 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + using System.Globalization; using Emby.Naming.TV; using MediaBrowser.Controller.Entities.TV; diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index 8fc3e3e75..a1562abd3 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs index 62268fce9..9599faea4 100644 --- a/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using MediaBrowser.Controller.Entities; diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs index bcdf854ca..26e615fa0 100644 --- a/Emby.Server.Implementations/Library/SearchEngine.cs +++ b/Emby.Server.Implementations/Library/SearchEngine.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs index 827e3c64b..667e46613 100644 --- a/Emby.Server.Implementations/Library/UserDataManager.cs +++ b/Emby.Server.Implementations/Library/UserDataManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs index ac041bcf6..e2da672a3 100644 --- a/Emby.Server.Implementations/Library/UserViewManager.cs +++ b/Emby.Server.Implementations/Library/UserViewManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs index 7a6b1d8b6..3fcadf5b1 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 28a2095e1..797063120 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 9372b0f6c..26e4ef1ed 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EpgChannelData.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EpgChannelData.cs index 8c27ca76e..0ec52a959 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EpgChannelData.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EpgChannelData.cs @@ -6,7 +6,6 @@ using MediaBrowser.Controller.LiveTv; namespace Emby.Server.Implementations.LiveTv.EmbyTV { - internal class EpgChannelData { @@ -39,13 +38,13 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } } - public ChannelInfo GetChannelById(string id) + public ChannelInfo? GetChannelById(string id) => _channelsById.GetValueOrDefault(id); - public ChannelInfo GetChannelByNumber(string number) + public ChannelInfo? GetChannelByNumber(string number) => _channelsByNumber.GetValueOrDefault(number); - public ChannelInfo GetChannelByName(string name) + public ChannelInfo? GetChannelByName(string name) => _channelsByName.GetValueOrDefault(name); public static string NormalizeName(string value) diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs index 1cac9cb96..bdab8c3e4 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 32245f899..108863869 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs index 1efa90e25..6c52a9a73 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 9af65cabb..00d02873c 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs index 6824aa442..ebad4eddf 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs index 6af49dd45..21e1409ac 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 1145d8aa1..1f1628900 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index 3a738fd5d..ecd28097d 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index fbcd4ef37..00a37bb02 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/Channels.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/Channels.cs index 740cbb66e..0f0453189 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/Channels.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/Channels.cs @@ -1,3 +1,5 @@ +#nullable disable + namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { internal class Channels diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/DiscoverResponse.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/DiscoverResponse.cs index 09d77f838..42068cd34 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/DiscoverResponse.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/DiscoverResponse.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index bbac6e055..c5700db71 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs index a7fda1d72..3016eeda2 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index b16ccc561..50a2d9abb 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs index f8baf55da..96a678c1d 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 4b170b2e4..69035dac9 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 84d416149..48a0c3cd3 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index eeb2426f4..137ed27e2 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index 220e423bf..dd5dee1d1 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs index 031b5d2e7..8aaa1f7bb 100644 --- a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs +++ b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index 0781a0e33..137728616 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Net/UdpSocket.cs b/Emby.Server.Implementations/Net/UdpSocket.cs index 4e25768cf..a8b18d292 100644 --- a/Emby.Server.Implementations/Net/UdpSocket.cs +++ b/Emby.Server.Implementations/Net/UdpSocket.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs index 2d1a559f1..9a1ca9946 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 14df20936..48281b75f 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Collections.Generic; using System.Globalization; diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs index 0259dc436..7cfd1fced 100644 --- a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs +++ b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Concurrent; using System.Globalization; diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index 101d9b537..ccbd4289e 100644 --- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs index af316e108..4f0df75bf 100644 --- a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs +++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs index 2312c85d9..baeb86a22 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs @@ -140,8 +140,10 @@ namespace Emby.Server.Implementations.ScheduledTasks previouslyFailedImages.Add(key); var parentPath = Path.GetDirectoryName(failHistoryPath); - - Directory.CreateDirectory(parentPath); + if (parentPath != null) + { + Directory.CreateDirectory(parentPath); + } string text = string.Join('|', previouslyFailedImages); File.WriteAllText(failHistoryPath, text); diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanActivityLogTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanActivityLogTask.cs index 4abbf784b..50ba9bc89 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanActivityLogTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanActivityLogTask.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -75,4 +75,4 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks return Enumerable.Empty(); } } -} \ No newline at end of file +} diff --git a/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs index 3b40320ab..3b63536a4 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Threading; using MediaBrowser.Model.Tasks; diff --git a/Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs index b04fd7c7e..e13782fe0 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Linq; using System.Threading; diff --git a/Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs index 7cd5493da..ced14195b 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs index 0c0ebec08..a67f940b7 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Threading; using MediaBrowser.Model.Tasks; diff --git a/Emby.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Implementations/Security/AuthenticationRepository.cs index 76f863c95..30823ab8f 100644 --- a/Emby.Server.Implementations/Security/AuthenticationRepository.cs +++ b/Emby.Server.Implementations/Security/AuthenticationRepository.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs b/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs index 27024e4e1..8d8b82f0a 100644 --- a/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs +++ b/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs @@ -19,7 +19,9 @@ namespace Emby.Server.Implementations.Serialization new ConcurrentDictionary(); private static XmlSerializer GetSerializer(Type type) - => _serializers.GetOrAdd(type.FullName, _ => new XmlSerializer(type)); + => _serializers.GetOrAdd( + type.FullName ?? throw new ArgumentException($"Invalid type {type}."), + _ => new XmlSerializer(type)); /// /// Serializes to writer. @@ -38,7 +40,7 @@ namespace Emby.Server.Implementations.Serialization /// The type. /// The stream. /// System.Object. - public object DeserializeFromStream(Type type, Stream stream) + public object? DeserializeFromStream(Type type, Stream stream) { using (var reader = XmlReader.Create(stream)) { @@ -81,7 +83,7 @@ namespace Emby.Server.Implementations.Serialization /// The type. /// The file. /// System.Object. - public object DeserializeFromFile(Type type, string file) + public object? DeserializeFromFile(Type type, string file) { using (var stream = File.OpenRead(file)) { @@ -95,7 +97,7 @@ namespace Emby.Server.Implementations.Serialization /// The type. /// The buffer. /// System.Object. - public object DeserializeFromBytes(Type type, byte[] buffer) + public object? DeserializeFromBytes(Type type, byte[] buffer) { using (var stream = new MemoryStream(buffer, 0, buffer.Length, false, true)) { diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 6844152ea..ef467da7e 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs index 39c369a01..e9e3ca7f4 100644 --- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using System.Linq; diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index a653b58c2..ed1dfca59 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -1,6 +1,5 @@ #pragma warning disable CS1591 #pragma warning disable SA1600 -#nullable enable using System; using System.Collections.Generic; diff --git a/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs b/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs index 60698e803..2b0ab536f 100644 --- a/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs +++ b/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs @@ -16,7 +16,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { if (x == null) { diff --git a/Emby.Server.Implementations/Sorting/AlbumArtistComparer.cs b/Emby.Server.Implementations/Sorting/AlbumArtistComparer.cs index 7657cc74e..42e644970 100644 --- a/Emby.Server.Implementations/Sorting/AlbumArtistComparer.cs +++ b/Emby.Server.Implementations/Sorting/AlbumArtistComparer.cs @@ -18,7 +18,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase); } @@ -28,7 +28,7 @@ namespace Emby.Server.Implementations.Sorting /// /// The x. /// System.String. - private static string GetValue(BaseItem x) + private static string? GetValue(BaseItem? x) { var audio = x as IHasAlbumArtist; diff --git a/Emby.Server.Implementations/Sorting/AlbumComparer.cs b/Emby.Server.Implementations/Sorting/AlbumComparer.cs index 7dfdd9ecf..1db3f5e9c 100644 --- a/Emby.Server.Implementations/Sorting/AlbumComparer.cs +++ b/Emby.Server.Implementations/Sorting/AlbumComparer.cs @@ -17,7 +17,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase); } @@ -27,7 +27,7 @@ namespace Emby.Server.Implementations.Sorting /// /// The x. /// System.String. - private static string GetValue(BaseItem x) + private static string? GetValue(BaseItem? x) { var audio = x as Audio; diff --git a/Emby.Server.Implementations/Sorting/ArtistComparer.cs b/Emby.Server.Implementations/Sorting/ArtistComparer.cs index 756d3c5b6..98bee3fd9 100644 --- a/Emby.Server.Implementations/Sorting/ArtistComparer.cs +++ b/Emby.Server.Implementations/Sorting/ArtistComparer.cs @@ -15,7 +15,7 @@ namespace Emby.Server.Implementations.Sorting public string Name => ItemSortBy.Artist; /// - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase); } @@ -25,7 +25,7 @@ namespace Emby.Server.Implementations.Sorting /// /// The x. /// System.String. - private static string GetValue(BaseItem x) + private static string? GetValue(BaseItem? x) { if (!(x is Audio audio)) { diff --git a/Emby.Server.Implementations/Sorting/CommunityRatingComparer.cs b/Emby.Server.Implementations/Sorting/CommunityRatingComparer.cs index 980954ba0..5f142fa4b 100644 --- a/Emby.Server.Implementations/Sorting/CommunityRatingComparer.cs +++ b/Emby.Server.Implementations/Sorting/CommunityRatingComparer.cs @@ -21,7 +21,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { if (x == null) { diff --git a/Emby.Server.Implementations/Sorting/CriticRatingComparer.cs b/Emby.Server.Implementations/Sorting/CriticRatingComparer.cs index fa136c36d..d20dedc2d 100644 --- a/Emby.Server.Implementations/Sorting/CriticRatingComparer.cs +++ b/Emby.Server.Implementations/Sorting/CriticRatingComparer.cs @@ -15,14 +15,14 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { return GetValue(x).CompareTo(GetValue(y)); } - private static float GetValue(BaseItem x) + private static float GetValue(BaseItem? x) { - return x.CriticRating ?? 0; + return x?.CriticRating ?? 0; } /// diff --git a/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs b/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs index cbca300d2..d3f10f78c 100644 --- a/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs +++ b/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs @@ -16,7 +16,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { if (x == null) { diff --git a/Emby.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs b/Emby.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs index 03ff19d21..b1cb123ce 100644 --- a/Emby.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs +++ b/Emby.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Sorting/DatePlayedComparer.cs b/Emby.Server.Implementations/Sorting/DatePlayedComparer.cs index 16bd2aff8..08a44319f 100644 --- a/Emby.Server.Implementations/Sorting/DatePlayedComparer.cs +++ b/Emby.Server.Implementations/Sorting/DatePlayedComparer.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using Jellyfin.Data.Entities; using MediaBrowser.Controller.Entities; diff --git a/Emby.Server.Implementations/Sorting/IsFavoriteOrLikeComparer.cs b/Emby.Server.Implementations/Sorting/IsFavoriteOrLikeComparer.cs index 0c4e82d01..73e628cf7 100644 --- a/Emby.Server.Implementations/Sorting/IsFavoriteOrLikeComparer.cs +++ b/Emby.Server.Implementations/Sorting/IsFavoriteOrLikeComparer.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using Jellyfin.Data.Entities; diff --git a/Emby.Server.Implementations/Sorting/IsFolderComparer.cs b/Emby.Server.Implementations/Sorting/IsFolderComparer.cs index a35192eff..3c5ddeefa 100644 --- a/Emby.Server.Implementations/Sorting/IsFolderComparer.cs +++ b/Emby.Server.Implementations/Sorting/IsFolderComparer.cs @@ -20,7 +20,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { return GetValue(x).CompareTo(GetValue(y)); } @@ -30,9 +30,9 @@ namespace Emby.Server.Implementations.Sorting /// /// The x. /// System.String. - private static int GetValue(BaseItem x) + private static int GetValue(BaseItem? x) { - return x.IsFolder ? 0 : 1; + return x?.IsFolder ?? true ? 0 : 1; } } } diff --git a/Emby.Server.Implementations/Sorting/IsPlayedComparer.cs b/Emby.Server.Implementations/Sorting/IsPlayedComparer.cs index d95948406..7d77a8bc5 100644 --- a/Emby.Server.Implementations/Sorting/IsPlayedComparer.cs +++ b/Emby.Server.Implementations/Sorting/IsPlayedComparer.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using Jellyfin.Data.Entities; diff --git a/Emby.Server.Implementations/Sorting/IsUnplayedComparer.cs b/Emby.Server.Implementations/Sorting/IsUnplayedComparer.cs index 1632c5a7a..926835f90 100644 --- a/Emby.Server.Implementations/Sorting/IsUnplayedComparer.cs +++ b/Emby.Server.Implementations/Sorting/IsUnplayedComparer.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using Jellyfin.Data.Entities; diff --git a/Emby.Server.Implementations/Sorting/NameComparer.cs b/Emby.Server.Implementations/Sorting/NameComparer.cs index da020d8d8..4de81a69e 100644 --- a/Emby.Server.Implementations/Sorting/NameComparer.cs +++ b/Emby.Server.Implementations/Sorting/NameComparer.cs @@ -16,7 +16,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { if (x == null) { diff --git a/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs b/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs index 76bb798b5..a81f78ebf 100644 --- a/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs +++ b/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs @@ -29,7 +29,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { if (x == null) { diff --git a/Emby.Server.Implementations/Sorting/PlayCountComparer.cs b/Emby.Server.Implementations/Sorting/PlayCountComparer.cs index 5c2830322..04e4865cb 100644 --- a/Emby.Server.Implementations/Sorting/PlayCountComparer.cs +++ b/Emby.Server.Implementations/Sorting/PlayCountComparer.cs @@ -1,3 +1,5 @@ +#nullable disable + using Jellyfin.Data.Entities; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; diff --git a/Emby.Server.Implementations/Sorting/PremiereDateComparer.cs b/Emby.Server.Implementations/Sorting/PremiereDateComparer.cs index 92ac04dc6..c98f97bf1 100644 --- a/Emby.Server.Implementations/Sorting/PremiereDateComparer.cs +++ b/Emby.Server.Implementations/Sorting/PremiereDateComparer.cs @@ -16,7 +16,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { return GetDate(x).CompareTo(GetDate(y)); } @@ -26,8 +26,13 @@ namespace Emby.Server.Implementations.Sorting /// /// The x. /// DateTime. - private static DateTime GetDate(BaseItem x) + private static DateTime GetDate(BaseItem? x) { + if (x == null) + { + return DateTime.MinValue; + } + if (x.PremiereDate.HasValue) { return x.PremiereDate.Value; diff --git a/Emby.Server.Implementations/Sorting/ProductionYearComparer.cs b/Emby.Server.Implementations/Sorting/ProductionYearComparer.cs index e2857df0b..df9f9957d 100644 --- a/Emby.Server.Implementations/Sorting/ProductionYearComparer.cs +++ b/Emby.Server.Implementations/Sorting/ProductionYearComparer.cs @@ -15,7 +15,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { return GetValue(x).CompareTo(GetValue(y)); } @@ -25,8 +25,13 @@ namespace Emby.Server.Implementations.Sorting /// /// The x. /// DateTime. - private static int GetValue(BaseItem x) + private static int GetValue(BaseItem? x) { + if (x == null) + { + return 0; + } + if (x.ProductionYear.HasValue) { return x.ProductionYear.Value; diff --git a/Emby.Server.Implementations/Sorting/RandomComparer.cs b/Emby.Server.Implementations/Sorting/RandomComparer.cs index 7739d0418..af3bc2750 100644 --- a/Emby.Server.Implementations/Sorting/RandomComparer.cs +++ b/Emby.Server.Implementations/Sorting/RandomComparer.cs @@ -16,7 +16,7 @@ namespace Emby.Server.Implementations.Sorting /// The x. /// The y. /// System.Int32. - public int Compare(BaseItem x, BaseItem y) + public int Compare(BaseItem? x, BaseItem? y) { return Guid.NewGuid().CompareTo(Guid.NewGuid()); } diff --git a/Emby.Server.Implementations/Sorting/RuntimeComparer.cs b/Emby.Server.Implementations/Sorting/RuntimeComparer.cs index dde44333d..129315303 100644 --- a/Emby.Server.Implementations/Sorting/RuntimeComparer.cs +++ b/Emby.Server.Implementations/Sorting/RuntimeComparer.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Sorting; diff --git a/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs b/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs index b9205ee07..4123a59f8 100644 --- a/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs +++ b/Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Sorting/SortNameComparer.cs b/Emby.Server.Implementations/Sorting/SortNameComparer.cs index f745e193b..8d30716d3 100644 --- a/Emby.Server.Implementations/Sorting/SortNameComparer.cs +++ b/Emby.Server.Implementations/Sorting/SortNameComparer.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Sorting; diff --git a/Emby.Server.Implementations/Sorting/StartDateComparer.cs b/Emby.Server.Implementations/Sorting/StartDateComparer.cs index 558a3d351..c3df7c47e 100644 --- a/Emby.Server.Implementations/Sorting/StartDateComparer.cs +++ b/Emby.Server.Implementations/Sorting/StartDateComparer.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Sorting/StudioComparer.cs b/Emby.Server.Implementations/Sorting/StudioComparer.cs index 5766dc542..01445c525 100644 --- a/Emby.Server.Implementations/Sorting/StudioComparer.cs +++ b/Emby.Server.Implementations/Sorting/StudioComparer.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/SyncPlay/Group.cs b/Emby.Server.Implementations/SyncPlay/Group.cs index 7c2ad2477..12efff261 100644 --- a/Emby.Server.Implementations/SyncPlay/Group.cs +++ b/Emby.Server.Implementations/SyncPlay/Group.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using System.Linq; diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs index 72c0a838e..993456196 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index 829df64bf..a837f09ca 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/Udp/UdpServer.cs b/Emby.Server.Implementations/Udp/UdpServer.cs index db5265e79..750f00168 100644 --- a/Emby.Server.Implementations/Udp/UdpServer.cs +++ b/Emby.Server.Implementations/Udp/UdpServer.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Net; using System.Net.Sockets; diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 653b1381b..2351b7d8c 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -1,3 +1,5 @@ +#nullable disable + #nullable enable using System; diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index b4154b361..45559fce9 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -1762,9 +1762,9 @@ namespace Jellyfin.Api.Controllers private static FileSystemMetadata? GetLastTranscodingFile(string playlist, string segmentExtension, IFileSystem fileSystem) { - var folder = Path.GetDirectoryName(playlist); + var folder = Path.GetDirectoryName(playlist) ?? throw new ArgumentException("Path can't be a root directory.", nameof(playlist)); - var filePrefix = Path.GetFileNameWithoutExtension(playlist) ?? string.Empty; + var filePrefix = Path.GetFileNameWithoutExtension(playlist); try { diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs index 0879cbd18..7cb015993 100644 --- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs +++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs @@ -380,7 +380,9 @@ namespace Jellyfin.Api.Helpers /// The output file path. private void DeleteHlsPartialStreamFiles(string outputFilePath) { - var directory = Path.GetDirectoryName(outputFilePath); + var directory = Path.GetDirectoryName(outputFilePath) + ?? throw new ArgumentException("Path can't be a root directory.", nameof(outputFilePath)); + var name = Path.GetFileNameWithoutExtension(outputFilePath); var filesToDelete = _fileSystem.GetFilePaths(directory) diff --git a/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs b/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs index e33e552ed..7b32d76ba 100644 --- a/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs +++ b/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs @@ -145,7 +145,8 @@ namespace Jellyfin.Api.Models.PlaybackDtos var transcodingPositionTicks = job.TranscodingPositionTicks ?? 0; var downloadPositionTicks = job.DownloadPositionTicks ?? 0; - var path = job.Path; + var path = job.Path ?? throw new ArgumentException("Path can't be null."); + var gapLengthInTicks = TimeSpan.FromSeconds(thresholdSeconds).Ticks; if (downloadPositionTicks > 0 && transcodingPositionTicks > 0) diff --git a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs index a15a38177..96bd2ccc4 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs @@ -82,11 +82,14 @@ namespace Jellyfin.Server.Migrations.Routines var userDataDir = Path.Combine(_paths.UserConfigurationDirectoryPath, mockup.Name); - var config = File.Exists(Path.Combine(userDataDir, "config.xml")) - ? (UserConfiguration)_xmlSerializer.DeserializeFromFile(typeof(UserConfiguration), Path.Combine(userDataDir, "config.xml")) + var configPath = Path.Combine(userDataDir, "config.xml"); + var config = File.Exists(configPath) + ? (UserConfiguration?)_xmlSerializer.DeserializeFromFile(typeof(UserConfiguration), configPath) ?? new UserConfiguration() : new UserConfiguration(); - var policy = File.Exists(Path.Combine(userDataDir, "policy.xml")) - ? (UserPolicy)_xmlSerializer.DeserializeFromFile(typeof(UserPolicy), Path.Combine(userDataDir, "policy.xml")) + + var policyPath = Path.Combine(userDataDir, "policy.xml"); + var policy = File.Exists(policyPath) + ? (UserPolicy?)_xmlSerializer.DeserializeFromFile(typeof(UserPolicy), policyPath) ?? new UserPolicy() : new UserPolicy(); policy.AuthenticationProviderId = policy.AuthenticationProviderId?.Replace( "Emby.Server.Implementations.Library", diff --git a/MediaBrowser.Controller/Extensions/StringExtensions.cs b/MediaBrowser.Controller/Extensions/StringExtensions.cs index 48bd9522a..1853896ee 100644 --- a/MediaBrowser.Controller/Extensions/StringExtensions.cs +++ b/MediaBrowser.Controller/Extensions/StringExtensions.cs @@ -1,6 +1,7 @@ #pragma warning disable CS1591 using System; +using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; diff --git a/MediaBrowser.Controller/Net/ISessionContext.cs b/MediaBrowser.Controller/Net/ISessionContext.cs index a60dc2ea1..6b896b41f 100644 --- a/MediaBrowser.Controller/Net/ISessionContext.cs +++ b/MediaBrowser.Controller/Net/ISessionContext.cs @@ -10,10 +10,10 @@ namespace MediaBrowser.Controller.Net { SessionInfo GetSession(object requestContext); - User GetUser(object requestContext); + User? GetUser(object requestContext); SessionInfo GetSession(HttpContext requestContext); - User GetUser(HttpContext requestContext); + User? GetUser(HttpContext requestContext); } } diff --git a/MediaBrowser.Controller/Sorting/IBaseItemComparer.cs b/MediaBrowser.Controller/Sorting/IBaseItemComparer.cs index 727cbe639..07fe1ea8a 100644 --- a/MediaBrowser.Controller/Sorting/IBaseItemComparer.cs +++ b/MediaBrowser.Controller/Sorting/IBaseItemComparer.cs @@ -6,7 +6,7 @@ namespace MediaBrowser.Controller.Sorting /// /// Interface IBaseItemComparer. /// - public interface IBaseItemComparer : IComparer + public interface IBaseItemComparer : IComparer { /// /// Gets the name. diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs index e5c26430a..be4f1e16b 100644 --- a/MediaBrowser.Model/IO/IFileSystem.cs +++ b/MediaBrowser.Model/IO/IFileSystem.cs @@ -1,4 +1,3 @@ -#nullable disable #pragma warning disable CS1591 using System; @@ -25,7 +24,7 @@ namespace MediaBrowser.Model.IO /// /// The filename. /// System.String. - string ResolveShortcut(string filename); + string? ResolveShortcut(string filename); /// /// Creates the shortcut. @@ -160,7 +159,7 @@ namespace MediaBrowser.Model.IO /// All found files. IEnumerable GetFiles(string path, bool recursive = false); - IEnumerable GetFiles(string path, IReadOnlyList extensions, bool enableCaseSensitiveExtensions, bool recursive); + IEnumerable GetFiles(string path, IReadOnlyList? extensions, bool enableCaseSensitiveExtensions, bool recursive); /// /// Gets the file system entries. @@ -186,7 +185,7 @@ namespace MediaBrowser.Model.IO /// IEnumerable<System.String>. IEnumerable GetFilePaths(string path, bool recursive = false); - IEnumerable GetFilePaths(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive); + IEnumerable GetFilePaths(string path, string[]? extensions, bool enableCaseSensitiveExtensions, bool recursive); /// /// Gets the file system entry paths. diff --git a/MediaBrowser.Model/IO/IShortcutHandler.cs b/MediaBrowser.Model/IO/IShortcutHandler.cs index 14d5c4b62..2c364a962 100644 --- a/MediaBrowser.Model/IO/IShortcutHandler.cs +++ b/MediaBrowser.Model/IO/IShortcutHandler.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Model.IO /// /// The shortcut path. /// System.String. - string Resolve(string shortcutPath); + string? Resolve(string shortcutPath); /// /// Creates the specified shortcut path. diff --git a/MediaBrowser.Model/IO/IStreamHelper.cs b/MediaBrowser.Model/IO/IStreamHelper.cs index 0e09db16e..f900da556 100644 --- a/MediaBrowser.Model/IO/IStreamHelper.cs +++ b/MediaBrowser.Model/IO/IStreamHelper.cs @@ -9,7 +9,7 @@ namespace MediaBrowser.Model.IO { public interface IStreamHelper { - Task CopyToAsync(Stream source, Stream destination, int bufferSize, Action onStarted, CancellationToken cancellationToken); + Task CopyToAsync(Stream source, Stream destination, int bufferSize, Action? onStarted, CancellationToken cancellationToken); Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken); diff --git a/MediaBrowser.Model/Tasks/ITaskTrigger.cs b/MediaBrowser.Model/Tasks/ITaskTrigger.cs index cbd60cca1..db9fba696 100644 --- a/MediaBrowser.Model/Tasks/ITaskTrigger.cs +++ b/MediaBrowser.Model/Tasks/ITaskTrigger.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Model.Tasks /// /// Fires when the trigger condition is satisfied and the task should run. /// - event EventHandler Triggered; + event EventHandler? Triggered; /// /// Gets or sets the options of this task. -- cgit v1.2.3 From 0bc06014427e36a770adeda66392d08147658ea8 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 28 May 2021 14:33:54 +0200 Subject: Fix some warnings --- .../AppBase/BaseConfigurationManager.cs | 10 +-- .../AppBase/ConfigurationHelper.cs | 3 +- .../EntryPoints/UdpServerEntryPoint.cs | 4 +- .../EntryPoints/UserDataChangeNotifier.cs | 10 ++- .../LiveTv/EmbyTV/RecordingHelper.cs | 2 - .../LiveTv/LiveTvConfigurationFactory.cs | 10 +-- .../LiveTv/LiveTvManager.cs | 8 +-- .../LiveTv/RefreshChannelsScheduledTask.cs | 63 ------------------ .../LiveTv/RefreshGuideScheduledTask.cs | 75 ++++++++++++++++++++++ .../LiveTv/TunerHosts/BaseTunerHost.cs | 1 + .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 2 - .../TunerHosts/HdHomerun/HdHomerunUdpStream.cs | 6 +- .../LiveTv/TunerHosts/M3UTunerHost.cs | 20 +++--- .../LiveTv/TunerHosts/M3uParser.cs | 8 +-- .../LiveTv/TunerHosts/SharedHttpStream.cs | 4 +- .../Plugins/PluginManager.cs | 3 +- .../ScheduledTasks/ScheduledTaskWorker.cs | 21 ++---- .../ScheduledTasks/Triggers/DailyTrigger.cs | 41 ++++++------ .../ScheduledTasks/Triggers/IntervalTrigger.cs | 40 ++++++------ .../ScheduledTasks/Triggers/StartupTrigger.cs | 28 ++++---- .../ScheduledTasks/Triggers/WeeklyTrigger.cs | 54 +++++++--------- .../Session/WebSocketController.cs | 1 - Emby.Server.Implementations/Udp/UdpServer.cs | 67 ++++++++++--------- .../Events/EventManager.cs | 7 +- MediaBrowser.Common/IApplicationHost.cs | 8 +-- .../Subtitles/ParserValues.cs | 9 --- MediaBrowser.Model/Tasks/ITaskTrigger.cs | 4 +- jellyfin.ruleset | 3 + 28 files changed, 247 insertions(+), 265 deletions(-) delete mode 100644 Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs create mode 100644 Emby.Server.Implementations/LiveTv/RefreshGuideScheduledTask.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs (limited to 'Emby.Server.Implementations/Plugins') diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs index 8c919db43..4c442a473 100644 --- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs +++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs @@ -25,6 +25,11 @@ namespace Emby.Server.Implementations.AppBase private readonly ConcurrentDictionary _configurations = new ConcurrentDictionary(); + /// + /// The _configuration sync lock. + /// + private readonly object _configurationSyncLock = new object(); + private ConfigurationStore[] _configurationStores = Array.Empty(); private IConfigurationFactory[] _configurationFactories = Array.Empty(); @@ -33,11 +38,6 @@ namespace Emby.Server.Implementations.AppBase /// private bool _configurationLoaded; - /// - /// The _configuration sync lock. - /// - private readonly object _configurationSyncLock = new object(); - /// /// The _configuration. /// diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs index de770f59e..0308a68e4 100644 --- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs +++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs @@ -33,7 +33,8 @@ namespace Emby.Server.Implementations.AppBase } catch (Exception) { - configuration = Activator.CreateInstance(type) ?? throw new ArgumentException($"Provided path ({type}) is not valid.", nameof(type)); + // Note: CreateInstance returns null for Nullable, e.g. CreateInstance(typeof(int?)) returns null. + configuration = Activator.CreateInstance(type)!; } using var stream = new MemoryStream(buffer?.Length ?? 0); diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index 211941f44..2e72b18f5 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -54,8 +54,8 @@ namespace Emby.Server.Implementations.EntryPoints try { - _udpServer = new UdpServer(_logger, _appHost, _config); - _udpServer.Start(PortNumber, _cancellationTokenSource.Token); + _udpServer = new UdpServer(_logger, _appHost, _config, PortNumber); + _udpServer.Start(_cancellationTokenSource.Token); } catch (SocketException ex) { diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index 332fb3385..d3bcd5e13 100644 --- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -1,5 +1,3 @@ -#nullable disable - #pragma warning disable CS1591 using System; @@ -28,7 +26,7 @@ namespace Emby.Server.Implementations.EntryPoints private readonly Dictionary> _changedItems = new Dictionary>(); private readonly object _syncLock = new object(); - private Timer _updateTimer; + private Timer? _updateTimer; public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, IUserManager userManager) { @@ -44,7 +42,7 @@ namespace Emby.Server.Implementations.EntryPoints return Task.CompletedTask; } - void OnUserDataManagerUserDataSaved(object sender, UserDataSaveEventArgs e) + private void OnUserDataManagerUserDataSaved(object? sender, UserDataSaveEventArgs e) { if (e.SaveReason == UserDataSaveReason.PlaybackProgress) { @@ -66,7 +64,7 @@ namespace Emby.Server.Implementations.EntryPoints _updateTimer.Change(UpdateDuration, Timeout.Infinite); } - if (!_changedItems.TryGetValue(e.UserId, out List keys)) + if (!_changedItems.TryGetValue(e.UserId, out List? keys)) { keys = new List(); _changedItems[e.UserId] = keys; @@ -89,7 +87,7 @@ namespace Emby.Server.Implementations.EntryPoints } } - private void UpdateTimerCallback(object state) + private void UpdateTimerCallback(object? state) { lock (_syncLock) { diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 108863869..32245f899 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -1,5 +1,3 @@ -#nullable disable - #pragma warning disable CS1591 using System; diff --git a/Emby.Server.Implementations/LiveTv/LiveTvConfigurationFactory.cs b/Emby.Server.Implementations/LiveTv/LiveTvConfigurationFactory.cs index ba916af38..098f193fb 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvConfigurationFactory.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvConfigurationFactory.cs @@ -1,21 +1,23 @@ -#pragma warning disable CS1591 - using System.Collections.Generic; using MediaBrowser.Common.Configuration; using MediaBrowser.Model.LiveTv; namespace Emby.Server.Implementations.LiveTv { + /// + /// implementation for . + /// public class LiveTvConfigurationFactory : IConfigurationFactory { + /// public IEnumerable GetConfigurations() { return new ConfigurationStore[] { new ConfigurationStore { - ConfigurationType = typeof(LiveTvOptions), - Key = "livetv" + ConfigurationType = typeof(LiveTvOptions), + Key = "livetv" } }; } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 1f1628900..d964769b5 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -2266,7 +2266,7 @@ namespace Emby.Server.Implementations.LiveTv if (dataSourceChanged) { - _taskManager.CancelIfRunningAndQueue(); + _taskManager.CancelIfRunningAndQueue(); } return info; @@ -2309,7 +2309,7 @@ namespace Emby.Server.Implementations.LiveTv _config.SaveConfiguration("livetv", config); - _taskManager.CancelIfRunningAndQueue(); + _taskManager.CancelIfRunningAndQueue(); return info; } @@ -2321,7 +2321,7 @@ namespace Emby.Server.Implementations.LiveTv config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToArray(); _config.SaveConfiguration("livetv", config); - _taskManager.CancelIfRunningAndQueue(); + _taskManager.CancelIfRunningAndQueue(); } public async Task SetChannelMapping(string providerId, string tunerChannelId, string providerChannelId) @@ -2355,7 +2355,7 @@ namespace Emby.Server.Implementations.LiveTv var tunerChannelMappings = tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList(); - _taskManager.CancelIfRunningAndQueue(); + _taskManager.CancelIfRunningAndQueue(); return tunerChannelMappings.First(i => string.Equals(i.Id, tunerChannelId, StringComparison.OrdinalIgnoreCase)); } diff --git a/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs b/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs deleted file mode 100644 index 582b64923..000000000 --- a/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs +++ /dev/null @@ -1,63 +0,0 @@ -#pragma warning disable CS1591 - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.LiveTv; -using MediaBrowser.Model.Tasks; - -namespace Emby.Server.Implementations.LiveTv -{ - public class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask - { - private readonly ILiveTvManager _liveTvManager; - private readonly IConfigurationManager _config; - - public RefreshChannelsScheduledTask(ILiveTvManager liveTvManager, IConfigurationManager config) - { - _liveTvManager = liveTvManager; - _config = config; - } - - public string Name => "Refresh Guide"; - - public string Description => "Downloads channel information from live tv services."; - - public string Category => "Live TV"; - - public Task Execute(System.Threading.CancellationToken cancellationToken, IProgress progress) - { - var manager = (LiveTvManager)_liveTvManager; - - return manager.RefreshChannels(progress, cancellationToken); - } - - /// - /// Creates the triggers that define when the task will run. - /// - /// IEnumerable{BaseTaskTrigger}. - public IEnumerable GetDefaultTriggers() - { - return new[] - { - // Every so often - new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks } - }; - } - - private LiveTvOptions GetConfiguration() - { - return _config.GetConfiguration("livetv"); - } - - public bool IsHidden => _liveTvManager.Services.Count == 1 && GetConfiguration().TunerHosts.Length == 0; - - public bool IsEnabled => true; - - public bool IsLogged => true; - - public string Key => "RefreshGuide"; - } -} diff --git a/Emby.Server.Implementations/LiveTv/RefreshGuideScheduledTask.cs b/Emby.Server.Implementations/LiveTv/RefreshGuideScheduledTask.cs new file mode 100644 index 000000000..15df0dcf1 --- /dev/null +++ b/Emby.Server.Implementations/LiveTv/RefreshGuideScheduledTask.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Tasks; + +namespace Emby.Server.Implementations.LiveTv +{ + /// + /// The "Refresh Guide" scheduled task. + /// + public class RefreshGuideScheduledTask : IScheduledTask, IConfigurableScheduledTask + { + private readonly ILiveTvManager _liveTvManager; + private readonly IConfigurationManager _config; + + /// + /// Initializes a new instance of the class. + /// + /// The live tv manager. + /// The configuration manager. + public RefreshGuideScheduledTask(ILiveTvManager liveTvManager, IConfigurationManager config) + { + _liveTvManager = liveTvManager; + _config = config; + } + + /// + public string Name => "Refresh Guide"; + + /// + public string Description => "Downloads channel information from live tv services."; + + /// + public string Category => "Live TV"; + + /// + public bool IsHidden => _liveTvManager.Services.Count == 1 && GetConfiguration().TunerHosts.Length == 0; + + /// + public bool IsEnabled => true; + + /// + public bool IsLogged => true; + + /// + public string Key => "RefreshGuide"; + + /// + public Task Execute(CancellationToken cancellationToken, IProgress progress) + { + var manager = (LiveTvManager)_liveTvManager; + + return manager.RefreshChannels(progress, cancellationToken); + } + + /// + public IEnumerable GetDefaultTriggers() + { + return new[] + { + // Every so often + new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks } + }; + } + + private LiveTvOptions GetConfiguration() + { + return _config.GetConfiguration("livetv"); + } + } +} diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index 00a37bb02..5941613cf 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -40,6 +40,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts public virtual bool IsSupported => true; protected abstract Task> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken); + public abstract string Type { get; } public async Task> GetChannels(TunerHostInfo tuner, bool enableCache, CancellationToken cancellationToken) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index c5700db71..54de841fe 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -583,7 +583,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun Logger, Config, _appHost, - _networkManager, _streamHelper); } @@ -624,7 +623,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun Logger, Config, _appHost, - _networkManager, _streamHelper); } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index 50a2d9abb..58e0c7448 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -12,7 +12,6 @@ using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; @@ -30,7 +29,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun private readonly IServerApplicationHost _appHost; private readonly IHdHomerunChannelCommands _channelCommands; private readonly int _numTuners; - private readonly INetworkManager _networkManager; public HdHomerunUdpStream( MediaSourceInfo mediaSource, @@ -42,12 +40,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun ILogger logger, IConfigurationManager configurationManager, IServerApplicationHost appHost, - INetworkManager networkManager, IStreamHelper streamHelper) : base(mediaSource, tunerHostInfo, fileSystem, logger, configurationManager, streamHelper) { _appHost = appHost; - _networkManager = networkManager; OriginalStreamId = originalStreamId; _channelCommands = channelCommands; _numTuners = numTuners; @@ -128,7 +124,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun using (udpClient) using (hdHomerunManager) { - if (!(ex is OperationCanceledException)) + if (ex is not OperationCanceledException) { Logger.LogError(ex, "Error opening live stream:"); } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 69035dac9..8fa6f5ad6 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -29,6 +29,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost { + private static readonly string[] _disallowedSharedStreamExtensions = + { + ".mkv", + ".mp4", + ".m3u8", + ".mpd" + }; + private readonly IHttpClientFactory _httpClientFactory; private readonly IServerApplicationHost _appHost; private readonly INetworkManager _networkManager; @@ -67,7 +75,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { var channelIdPrefix = GetFullChannelIdPrefix(info); - return await new M3uParser(Logger, _httpClientFactory, _appHost) + return await new M3uParser(Logger, _httpClientFactory) .Parse(info, channelIdPrefix, cancellationToken) .ConfigureAwait(false); } @@ -88,14 +96,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return Task.FromResult(list); } - private static readonly string[] _disallowedSharedStreamExtensions = - { - ".mkv", - ".mp4", - ".m3u8", - ".mpd" - }; - protected override async Task GetChannelStream(TunerHostInfo info, ChannelInfo channelInfo, string streamId, List currentLiveStreams, CancellationToken cancellationToken) { var tunerCount = info.TunerCount; @@ -130,7 +130,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts public async Task Validate(TunerHostInfo info) { - using (var stream = await new M3uParser(Logger, _httpClientFactory, _appHost).GetListingsStream(info, CancellationToken.None).ConfigureAwait(false)) + using (var stream = await new M3uParser(Logger, _httpClientFactory).GetListingsStream(info, CancellationToken.None).ConfigureAwait(false)) { } } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 48a0c3cd3..40a162890 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -21,15 +21,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { public class M3uParser { + private const string ExtInfPrefix = "#EXTINF:"; + private readonly ILogger _logger; private readonly IHttpClientFactory _httpClientFactory; - private readonly IServerApplicationHost _appHost; - public M3uParser(ILogger logger, IHttpClientFactory httpClientFactory, IServerApplicationHost appHost) + public M3uParser(ILogger logger, IHttpClientFactory httpClientFactory) { _logger = logger; _httpClientFactory = httpClientFactory; - _appHost = appHost; } public async Task> Parse(TunerHostInfo info, string channelIdPrefix, CancellationToken cancellationToken) @@ -61,8 +61,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return File.OpenRead(info.Url); } - private const string ExtInfPrefix = "#EXTINF:"; - private async Task> GetChannelsAsync(TextReader reader, string channelIdPrefix, string tunerHostId) { var channels = new List(); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index 137ed27e2..f572151b8 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -91,8 +91,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts var taskCompletionSource = new TaskCompletionSource(); - var now = DateTime.UtcNow; - _ = StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token); // OpenedMediaSource.Protocol = MediaProtocol.File; @@ -120,7 +118,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts if (!taskCompletionSource.Task.Result) { Logger.LogWarning("Zero bytes copied from stream {0} to {1} but no exception raised", GetType().Name, TempFilePath); - throw new EndOfStreamException(String.Format(CultureInfo.InvariantCulture, "Zero bytes copied from stream {0}", GetType().Name)); + throw new EndOfStreamException(string.Format(CultureInfo.InvariantCulture, "Zero bytes copied from stream {0}", GetType().Name)); } } diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 48281b75f..16a2bd615 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -455,7 +455,8 @@ namespace Emby.Server.Implementations.Plugins try { _logger.LogDebug("Creating instance of {Type}", type); - var instance = (IPlugin)ActivatorUtilities.CreateInstance(_appHost.ServiceProvider, type); + // _appHost.ServiceProvider is already assigned when we create the plugins + var instance = (IPlugin)ActivatorUtilities.CreateInstance(_appHost.ServiceProvider!, type); if (plugin == null) { // Create a dummy record for the providers. diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index ccbd4289e..d7e320754 100644 --- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -711,11 +711,7 @@ namespace Emby.Server.Implementations.ScheduledTasks throw new ArgumentException("Info did not contain a TimeOfDayTicks.", nameof(info)); } - return new DailyTrigger - { - TimeOfDay = TimeSpan.FromTicks(info.TimeOfDayTicks.Value), - TaskOptions = options - }; + return new DailyTrigger(TimeSpan.FromTicks(info.TimeOfDayTicks.Value), options); } if (info.Type.Equals(nameof(WeeklyTrigger), StringComparison.OrdinalIgnoreCase)) @@ -730,12 +726,7 @@ namespace Emby.Server.Implementations.ScheduledTasks throw new ArgumentException("Info did not contain a DayOfWeek.", nameof(info)); } - return new WeeklyTrigger - { - TimeOfDay = TimeSpan.FromTicks(info.TimeOfDayTicks.Value), - DayOfWeek = info.DayOfWeek.Value, - TaskOptions = options - }; + return new WeeklyTrigger(TimeSpan.FromTicks(info.TimeOfDayTicks.Value), info.DayOfWeek.Value, options); } if (info.Type.Equals(nameof(IntervalTrigger), StringComparison.OrdinalIgnoreCase)) @@ -745,16 +736,12 @@ namespace Emby.Server.Implementations.ScheduledTasks throw new ArgumentException("Info did not contain a IntervalTicks.", nameof(info)); } - return new IntervalTrigger - { - Interval = TimeSpan.FromTicks(info.IntervalTicks.Value), - TaskOptions = options - }; + return new IntervalTrigger(TimeSpan.FromTicks(info.IntervalTicks.Value), options); } if (info.Type.Equals(nameof(StartupTrigger), StringComparison.OrdinalIgnoreCase)) { - return new StartupTrigger(); + return new StartupTrigger(options); } throw new ArgumentException("Unrecognized trigger type: " + info.Type); diff --git a/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs index 3b63536a4..29ab6a73d 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Threading; using MediaBrowser.Model.Tasks; @@ -10,29 +8,31 @@ namespace Emby.Server.Implementations.ScheduledTasks /// /// Represents a task trigger that fires everyday. /// - public class DailyTrigger : ITaskTrigger + public sealed class DailyTrigger : ITaskTrigger { - /// - /// Occurs when [triggered]. - /// - public event EventHandler Triggered; + private readonly TimeSpan _timeOfDay; + private Timer? _timer; /// - /// Gets or sets the time of day to trigger the task to run. + /// Initializes a new instance of the class. /// - /// The time of day. - public TimeSpan TimeOfDay { get; set; } + /// The time of day to trigger the task to run. + /// The options of this task. + public DailyTrigger(TimeSpan timeofDay, TaskOptions taskOptions) + { + _timeOfDay = timeofDay; + TaskOptions = taskOptions; + } /// - /// Gets or sets the options of this task. + /// Occurs when [triggered]. /// - public TaskOptions TaskOptions { get; set; } + public event EventHandler? Triggered; /// - /// Gets or sets the timer. + /// Gets the options of this task. /// - /// The timer. - private Timer Timer { get; set; } + public TaskOptions TaskOptions { get; } /// /// Stars waiting for the trigger action. @@ -47,14 +47,14 @@ namespace Emby.Server.Implementations.ScheduledTasks var now = DateTime.Now; - var triggerDate = now.TimeOfDay > TimeOfDay ? now.Date.AddDays(1) : now.Date; - triggerDate = triggerDate.Add(TimeOfDay); + var triggerDate = now.TimeOfDay > _timeOfDay ? now.Date.AddDays(1) : now.Date; + triggerDate = triggerDate.Add(_timeOfDay); var dueTime = triggerDate - now; logger.LogInformation("Daily trigger for {Task} set to fire at {TriggerDate:yyyy-MM-dd HH:mm:ss.fff zzz}, which is {DueTime:c} from now.", taskName, triggerDate, dueTime); - Timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1)); + _timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1)); } /// @@ -70,10 +70,7 @@ namespace Emby.Server.Implementations.ScheduledTasks /// private void DisposeTimer() { - if (Timer != null) - { - Timer.Dispose(); - } + _timer?.Dispose(); } /// diff --git a/Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs index e13782fe0..30568e809 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Linq; using System.Threading; @@ -11,31 +9,32 @@ namespace Emby.Server.Implementations.ScheduledTasks /// /// Represents a task trigger that runs repeatedly on an interval. /// - public class IntervalTrigger : ITaskTrigger + public sealed class IntervalTrigger : ITaskTrigger { + private readonly TimeSpan _interval; private DateTime _lastStartDate; + private Timer? _timer; /// - /// Occurs when [triggered]. - /// - public event EventHandler Triggered; - - /// - /// Gets or sets the interval. + /// Initializes a new instance of the class. /// - /// The interval. - public TimeSpan Interval { get; set; } + /// The interval. + /// The options of this task. + public IntervalTrigger(TimeSpan interval, TaskOptions taskOptions) + { + _interval = interval; + TaskOptions = taskOptions; + } /// - /// Gets or sets the options of this task. + /// Occurs when [triggered]. /// - public TaskOptions TaskOptions { get; set; } + public event EventHandler? Triggered; /// - /// Gets or sets the timer. + /// Gets the options of this task. /// - /// The timer. - private Timer Timer { get; set; } + public TaskOptions TaskOptions { get; } /// /// Stars waiting for the trigger action. @@ -57,7 +56,7 @@ namespace Emby.Server.Implementations.ScheduledTasks } else { - triggerDate = new[] { lastResult.EndTimeUtc, _lastStartDate }.Max().Add(Interval); + triggerDate = new[] { lastResult.EndTimeUtc, _lastStartDate }.Max().Add(_interval); } if (DateTime.UtcNow > triggerDate) @@ -73,7 +72,7 @@ namespace Emby.Server.Implementations.ScheduledTasks dueTime = maxDueTime; } - Timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1)); + _timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1)); } /// @@ -89,10 +88,7 @@ namespace Emby.Server.Implementations.ScheduledTasks /// private void DisposeTimer() { - if (Timer != null) - { - Timer.Dispose(); - } + _timer?.Dispose(); } /// diff --git a/Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs index ced14195b..18b9a8b75 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs @@ -1,5 +1,3 @@ -#nullable disable - #pragma warning disable CS1591 using System; @@ -12,24 +10,28 @@ namespace Emby.Server.Implementations.ScheduledTasks /// /// Class StartupTaskTrigger. /// - public class StartupTrigger : ITaskTrigger + public sealed class StartupTrigger : ITaskTrigger { + public const int DelayMs = 3000; + /// - /// Occurs when [triggered]. + /// Initializes a new instance of the class. /// - public event EventHandler Triggered; - - public int DelayMs { get; set; } + /// The options of this task. + public StartupTrigger(TaskOptions taskOptions) + { + TaskOptions = taskOptions; + } /// - /// Gets or sets the options of this task. + /// Occurs when [triggered]. /// - public TaskOptions TaskOptions { get; set; } + public event EventHandler? Triggered; - public StartupTrigger() - { - DelayMs = 3000; - } + /// + /// Gets the options of this task. + /// + public TaskOptions TaskOptions { get; } /// /// Stars waiting for the trigger action. diff --git a/Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs index a67f940b7..36ae190b0 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Threading; using MediaBrowser.Model.Tasks; @@ -10,35 +8,34 @@ namespace Emby.Server.Implementations.ScheduledTasks /// /// Represents a task trigger that fires on a weekly basis. /// - public class WeeklyTrigger : ITaskTrigger + public sealed class WeeklyTrigger : ITaskTrigger { - /// - /// Occurs when [triggered]. - /// - public event EventHandler Triggered; - - /// - /// Gets or sets the time of day to trigger the task to run. - /// - /// The time of day. - public TimeSpan TimeOfDay { get; set; } + private readonly TimeSpan _timeOfDay; + private readonly DayOfWeek _dayOfWeek; + private Timer? _timer; /// - /// Gets or sets the day of week. + /// Initializes a new instance of the class. /// - /// The day of week. - public DayOfWeek DayOfWeek { get; set; } + /// The time of day to trigger the task to run. + /// The day of week. + /// The options of this task. + public WeeklyTrigger(TimeSpan timeofDay, DayOfWeek dayOfWeek, TaskOptions taskOptions) + { + _timeOfDay = timeofDay; + _dayOfWeek = dayOfWeek; + TaskOptions = taskOptions; + } /// - /// Gets or sets the options of this task. + /// Occurs when [triggered]. /// - public TaskOptions TaskOptions { get; set; } + public event EventHandler? Triggered; /// - /// Gets or sets the timer. + /// Gets the options of this task. /// - /// The timer. - private Timer Timer { get; set; } + public TaskOptions TaskOptions { get; } /// /// Stars waiting for the trigger action. @@ -53,7 +50,7 @@ namespace Emby.Server.Implementations.ScheduledTasks var triggerDate = GetNextTriggerDateTime(); - Timer = new Timer(state => OnTriggered(), null, triggerDate - DateTime.Now, TimeSpan.FromMilliseconds(-1)); + _timer = new Timer(state => OnTriggered(), null, triggerDate - DateTime.Now, TimeSpan.FromMilliseconds(-1)); } /// @@ -65,22 +62,22 @@ namespace Emby.Server.Implementations.ScheduledTasks var now = DateTime.Now; // If it's on the same day - if (now.DayOfWeek == DayOfWeek) + if (now.DayOfWeek == _dayOfWeek) { // It's either later today, or a week from now - return now.TimeOfDay < TimeOfDay ? now.Date.Add(TimeOfDay) : now.Date.AddDays(7).Add(TimeOfDay); + return now.TimeOfDay < _timeOfDay ? now.Date.Add(_timeOfDay) : now.Date.AddDays(7).Add(_timeOfDay); } var triggerDate = now.Date; // Walk the date forward until we get to the trigger day - while (triggerDate.DayOfWeek != DayOfWeek) + while (triggerDate.DayOfWeek != _dayOfWeek) { triggerDate = triggerDate.AddDays(1); } // Return the trigger date plus the time offset - return triggerDate.Add(TimeOfDay); + return triggerDate.Add(_timeOfDay); } /// @@ -96,10 +93,7 @@ namespace Emby.Server.Implementations.ScheduledTasks /// private void DisposeTimer() { - if (Timer != null) - { - Timer.Dispose(); - } + _timer?.Dispose(); } /// diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index ed1dfca59..9fa92a53a 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -1,5 +1,4 @@ #pragma warning disable CS1591 -#pragma warning disable SA1600 using System; using System.Collections.Generic; diff --git a/Emby.Server.Implementations/Udp/UdpServer.cs b/Emby.Server.Implementations/Udp/UdpServer.cs index 750f00168..8179e26c5 100644 --- a/Emby.Server.Implementations/Udp/UdpServer.cs +++ b/Emby.Server.Implementations/Udp/UdpServer.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Net; using System.Net.Sockets; @@ -19,6 +17,11 @@ namespace Emby.Server.Implementations.Udp /// public sealed class UdpServer : IDisposable { + /// + /// Address Override Configuration Key. + /// + public const string AddressOverrideConfigKey = "PublishedServerUrl"; + /// /// The _logger. /// @@ -26,11 +29,6 @@ namespace Emby.Server.Implementations.Udp private readonly IServerApplicationHost _appHost; private readonly IConfiguration _config; - /// - /// Address Override Configuration Key. - /// - public const string AddressOverrideConfigKey = "PublishedServerUrl"; - private Socket _udpSocket; private IPEndPoint _endpoint; private readonly byte[] _receiveBuffer = new byte[8192]; @@ -40,49 +38,58 @@ namespace Emby.Server.Implementations.Udp /// /// Initializes a new instance of the class. /// - public UdpServer(ILogger logger, IServerApplicationHost appHost, IConfiguration configuration) + /// The logger. + /// The application host. + /// The configuration manager. + /// The port. + public UdpServer( + ILogger logger, + IServerApplicationHost appHost, + IConfiguration configuration, + int port) { _logger = logger; _appHost = appHost; _config = configuration; + + _endpoint = new IPEndPoint(IPAddress.Any, port); + + _udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + _udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } private async Task RespondToV2Message(string messageText, EndPoint endpoint, CancellationToken cancellationToken) { - string localUrl = !string.IsNullOrEmpty(_config[AddressOverrideConfigKey]) - ? _config[AddressOverrideConfigKey] - : _appHost.GetSmartApiUrl(((IPEndPoint)endpoint).Address); + string? localUrl = _config[AddressOverrideConfigKey]; + if (string.IsNullOrEmpty(localUrl)) + { + localUrl = _appHost.GetSmartApiUrl(((IPEndPoint)endpoint).Address); + } - if (!string.IsNullOrEmpty(localUrl)) + if (string.IsNullOrEmpty(localUrl)) { - var response = new ServerDiscoveryInfo(localUrl, _appHost.SystemId, _appHost.FriendlyName); + _logger.LogWarning("Unable to respond to udp request because the local ip address could not be determined."); + return; + } - try - { - await _udpSocket.SendToAsync(JsonSerializer.SerializeToUtf8Bytes(response), SocketFlags.None, endpoint).ConfigureAwait(false); - } - catch (SocketException ex) - { - _logger.LogError(ex, "Error sending response message"); - } + var response = new ServerDiscoveryInfo(localUrl, _appHost.SystemId, _appHost.FriendlyName); + + try + { + await _udpSocket.SendToAsync(JsonSerializer.SerializeToUtf8Bytes(response), SocketFlags.None, endpoint).ConfigureAwait(false); } - else + catch (SocketException ex) { - _logger.LogWarning("Unable to respond to udp request because the local ip address could not be determined."); + _logger.LogError(ex, "Error sending response message"); } } /// /// Starts the specified port. /// - /// The port. /// The cancellation token to cancel operation. - public void Start(int port, CancellationToken cancellationToken) + public void Start(CancellationToken cancellationToken) { - _endpoint = new IPEndPoint(IPAddress.Any, port); - - _udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - _udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _udpSocket.Bind(_endpoint); _ = Task.Run(async () => await BeginReceiveAsync(cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); @@ -90,9 +97,9 @@ namespace Emby.Server.Implementations.Udp private async Task BeginReceiveAsync(CancellationToken cancellationToken) { + var infiniteTask = Task.Delay(-1, cancellationToken); while (!cancellationToken.IsCancellationRequested) { - var infiniteTask = Task.Delay(-1, cancellationToken); try { var task = _udpSocket.ReceiveFromAsync(_receiveBuffer, SocketFlags.None, _endpoint); diff --git a/Jellyfin.Server.Implementations/Events/EventManager.cs b/Jellyfin.Server.Implementations/Events/EventManager.cs index 707002442..c5e66112d 100644 --- a/Jellyfin.Server.Implementations/Events/EventManager.cs +++ b/Jellyfin.Server.Implementations/Events/EventManager.cs @@ -43,7 +43,12 @@ namespace Jellyfin.Server.Implementations.Events private async Task PublishInternal(T eventArgs) where T : EventArgs { - using var scope = _appHost.ServiceProvider.CreateScope(); + using var scope = _appHost.ServiceProvider?.CreateScope(); + if (scope == null) + { + return; + } + foreach (var service in scope.ServiceProvider.GetServices>()) { try diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs index 46d93e494..192a77611 100644 --- a/MediaBrowser.Common/IApplicationHost.cs +++ b/MediaBrowser.Common/IApplicationHost.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Collections.Generic; using System.Reflection; @@ -12,7 +10,7 @@ namespace MediaBrowser.Common /// /// Type to create. /// New instance of type type. - public delegate object CreationDelegateFactory(Type type); + public delegate object? CreationDelegateFactory(Type type); /// /// An interface to be implemented by the applications hosting a kernel. @@ -22,7 +20,7 @@ namespace MediaBrowser.Common /// /// Occurs when [has pending restart changed]. /// - event EventHandler HasPendingRestartChanged; + event EventHandler? HasPendingRestartChanged; /// /// Gets the name. @@ -63,7 +61,7 @@ namespace MediaBrowser.Common /// /// Gets or sets the service provider. /// - IServiceProvider ServiceProvider { get; set; } + IServiceProvider? ServiceProvider { get; set; } /// /// Gets the application version. diff --git a/MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs b/MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs deleted file mode 100644 index cec1aaf08..000000000 --- a/MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs +++ /dev/null @@ -1,9 +0,0 @@ -#pragma warning disable CS1591 - -namespace MediaBrowser.MediaEncoding.Subtitles -{ - public static class ParserValues - { - public const string NewLine = "\r\n"; - } -} diff --git a/MediaBrowser.Model/Tasks/ITaskTrigger.cs b/MediaBrowser.Model/Tasks/ITaskTrigger.cs index db9fba696..999db9605 100644 --- a/MediaBrowser.Model/Tasks/ITaskTrigger.cs +++ b/MediaBrowser.Model/Tasks/ITaskTrigger.cs @@ -14,9 +14,9 @@ namespace MediaBrowser.Model.Tasks event EventHandler? Triggered; /// - /// Gets or sets the options of this task. + /// Gets the options of this task. /// - TaskOptions TaskOptions { get; set; } + TaskOptions TaskOptions { get; } /// /// Stars waiting for the trigger action. diff --git a/jellyfin.ruleset b/jellyfin.ruleset index 1a9f2bf96..44bc34369 100644 --- a/jellyfin.ruleset +++ b/jellyfin.ruleset @@ -1,6 +1,9 @@ + + + -- cgit v1.2.3