mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-01 14:26:40 +01:00
Merge branch 'master' into network-rewrite
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@@ -33,15 +31,10 @@ namespace Emby.Server.Implementations.AppBase
|
||||
private ConfigurationStore[] _configurationStores = Array.Empty<ConfigurationStore>();
|
||||
private IConfigurationFactory[] _configurationFactories = Array.Empty<IConfigurationFactory>();
|
||||
|
||||
/// <summary>
|
||||
/// The _configuration loaded.
|
||||
/// </summary>
|
||||
private bool _configurationLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// The _configuration.
|
||||
/// </summary>
|
||||
private BaseApplicationConfiguration _configuration;
|
||||
private BaseApplicationConfiguration? _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseConfigurationManager" /> class.
|
||||
@@ -63,17 +56,17 @@ namespace Emby.Server.Implementations.AppBase
|
||||
/// <summary>
|
||||
/// Occurs when [configuration updated].
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> ConfigurationUpdated;
|
||||
public event EventHandler<EventArgs>? ConfigurationUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [configuration updating].
|
||||
/// </summary>
|
||||
public event EventHandler<ConfigurationUpdateEventArgs> NamedConfigurationUpdating;
|
||||
public event EventHandler<ConfigurationUpdateEventArgs>? NamedConfigurationUpdating;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [named configuration updated].
|
||||
/// </summary>
|
||||
public event EventHandler<ConfigurationUpdateEventArgs> NamedConfigurationUpdated;
|
||||
public event EventHandler<ConfigurationUpdateEventArgs>? NamedConfigurationUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the configuration.
|
||||
@@ -107,31 +100,25 @@ namespace Emby.Server.Implementations.AppBase
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_configurationLoaded)
|
||||
if (_configuration is not null)
|
||||
{
|
||||
return _configuration;
|
||||
}
|
||||
|
||||
lock (_configurationSyncLock)
|
||||
{
|
||||
if (_configurationLoaded)
|
||||
if (_configuration is not null)
|
||||
{
|
||||
return _configuration;
|
||||
}
|
||||
|
||||
_configuration = (BaseApplicationConfiguration)ConfigurationHelper.GetXmlConfiguration(ConfigurationType, CommonApplicationPaths.SystemConfigurationFilePath, XmlSerializer);
|
||||
|
||||
_configurationLoaded = true;
|
||||
|
||||
return _configuration;
|
||||
return _configuration = (BaseApplicationConfiguration)ConfigurationHelper.GetXmlConfiguration(ConfigurationType, CommonApplicationPaths.SystemConfigurationFilePath, XmlSerializer);
|
||||
}
|
||||
}
|
||||
|
||||
protected set
|
||||
{
|
||||
_configuration = value;
|
||||
|
||||
_configurationLoaded = value is not null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +170,7 @@ namespace Emby.Server.Implementations.AppBase
|
||||
Logger.LogInformation("Saving system configuration");
|
||||
var path = CommonApplicationPaths.SystemConfigurationFilePath;
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path) ?? throw new InvalidOperationException("Path can't be a root directory."));
|
||||
|
||||
lock (_configurationSyncLock)
|
||||
{
|
||||
@@ -323,25 +310,20 @@ namespace Emby.Server.Implementations.AppBase
|
||||
|
||||
private object LoadConfiguration(string path, Type configurationType)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return Activator.CreateInstance(configurationType);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return XmlSerializer.DeserializeFromFile(configurationType, path);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return XmlSerializer.DeserializeFromFile(configurationType, path);
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return Activator.CreateInstance(configurationType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception ex) when (ex is not IOException)
|
||||
{
|
||||
Logger.LogError(ex, "Error loading configuration file: {Path}", path);
|
||||
|
||||
return Activator.CreateInstance(configurationType);
|
||||
}
|
||||
|
||||
return Activator.CreateInstance(configurationType)
|
||||
?? throw new InvalidOperationException("Configuration type can't be Nullable<T>.");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -367,7 +349,7 @@ namespace Emby.Server.Implementations.AppBase
|
||||
_configurations.AddOrUpdate(key, configuration, (_, _) => configuration);
|
||||
|
||||
var path = GetConfigurationFile(key);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path) ?? throw new InvalidOperationException("Path can't be a root directory."));
|
||||
|
||||
lock (_configurationSyncLock)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,6 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -19,7 +18,6 @@ using Emby.Dlna;
|
||||
using Emby.Dlna.Main;
|
||||
using Emby.Dlna.Ssdp;
|
||||
using Emby.Naming.Common;
|
||||
using Emby.Notifications;
|
||||
using Emby.Photos;
|
||||
using Emby.Server.Implementations.Channels;
|
||||
using Emby.Server.Implementations.Collections;
|
||||
@@ -70,7 +68,6 @@ using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Controller.Lyrics;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Controller.Notifications;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Playlists;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
@@ -115,15 +112,11 @@ namespace Emby.Server.Implementations
|
||||
/// </summary>
|
||||
public abstract class ApplicationHost : IServerApplicationHost, IAsyncDisposable, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The environment variable prefixes to log at server startup.
|
||||
/// </summary>
|
||||
private static readonly string[] _relevantEnvVarPrefixes = { "JELLYFIN_", "DOTNET_", "ASPNETCORE_" };
|
||||
|
||||
/// <summary>
|
||||
/// The disposable parts.
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<IDisposable, byte> _disposableParts = new();
|
||||
private readonly DeviceId _deviceId;
|
||||
|
||||
private readonly IFileSystem _fileSystemManager;
|
||||
private readonly IConfiguration _startupConfig;
|
||||
@@ -132,7 +125,6 @@ namespace Emby.Server.Implementations
|
||||
private readonly IPluginManager _pluginManager;
|
||||
|
||||
private List<Type> _creatingInstances;
|
||||
private IMediaEncoder _mediaEncoder;
|
||||
private ISessionManager _sessionManager;
|
||||
|
||||
/// <summary>
|
||||
@@ -141,8 +133,6 @@ namespace Emby.Server.Implementations
|
||||
/// <value>All concrete types.</value>
|
||||
private Type[] _allConcreteTypes;
|
||||
|
||||
private DeviceId _deviceId;
|
||||
|
||||
private bool _disposed = false;
|
||||
|
||||
/// <summary>
|
||||
@@ -166,6 +156,7 @@ namespace Emby.Server.Implementations
|
||||
|
||||
Logger = LoggerFactory.CreateLogger<ApplicationHost>();
|
||||
_fileSystemManager.AddShortcutHandler(new MbLinkShortcutHandler(_fileSystemManager));
|
||||
_deviceId = new DeviceId(ApplicationPaths, LoggerFactory);
|
||||
|
||||
ApplicationVersion = typeof(ApplicationHost).Assembly.GetName().Version;
|
||||
ApplicationVersionString = ApplicationVersion.ToString(3);
|
||||
@@ -193,23 +184,9 @@ namespace Emby.Server.Implementations
|
||||
|
||||
public bool CoreStartupHasCompleted { get; private set; }
|
||||
|
||||
public virtual bool CanLaunchWebBrowser
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Environment.UserInteractive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_startupOptions.IsService)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return OperatingSystem.IsWindows() || OperatingSystem.IsMacOS();
|
||||
}
|
||||
}
|
||||
public virtual bool CanLaunchWebBrowser => Environment.UserInteractive
|
||||
&& !_startupOptions.IsService
|
||||
&& (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS());
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="INetworkManager"/> singleton instance.
|
||||
@@ -286,15 +263,7 @@ namespace Emby.Server.Implementations
|
||||
/// <value>The application name.</value>
|
||||
public string ApplicationProductName { get; } = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).ProductName;
|
||||
|
||||
public string SystemId
|
||||
{
|
||||
get
|
||||
{
|
||||
_deviceId ??= new DeviceId(ApplicationPaths, LoggerFactory);
|
||||
|
||||
return _deviceId.Value;
|
||||
}
|
||||
}
|
||||
public string SystemId => _deviceId.Value;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Name => ApplicationProductName;
|
||||
@@ -447,7 +416,7 @@ namespace Emby.Server.Implementations
|
||||
ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated;
|
||||
ConfigurationManager.NamedConfigurationUpdated += OnConfigurationUpdated;
|
||||
|
||||
_mediaEncoder.SetFFmpegPath();
|
||||
Resolve<IMediaEncoder>().SetFFmpegPath();
|
||||
|
||||
Logger.LogInformation("ServerId: {ServerId}", SystemId);
|
||||
|
||||
@@ -615,8 +584,6 @@ namespace Emby.Server.Implementations
|
||||
|
||||
serviceCollection.AddSingleton<IUserViewManager, UserViewManager>();
|
||||
|
||||
serviceCollection.AddSingleton<INotificationManager, NotificationManager>();
|
||||
|
||||
serviceCollection.AddSingleton<IDeviceDiscovery, DeviceDiscovery>();
|
||||
|
||||
serviceCollection.AddSingleton<IChapterManager, ChapterManager>();
|
||||
@@ -659,7 +626,6 @@ namespace Emby.Server.Implementations
|
||||
var localizationManager = (LocalizationManager)Resolve<ILocalizationManager>();
|
||||
await localizationManager.LoadAll().ConfigureAwait(false);
|
||||
|
||||
_mediaEncoder = Resolve<IMediaEncoder>();
|
||||
_sessionManager = Resolve<ISessionManager>();
|
||||
|
||||
SetStaticProperties();
|
||||
@@ -670,36 +636,6 @@ namespace Emby.Server.Implementations
|
||||
FindParts();
|
||||
}
|
||||
|
||||
public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths)
|
||||
{
|
||||
// Distinct these to prevent users from reporting problems that aren't actually problems
|
||||
var commandLineArgs = Environment
|
||||
.GetCommandLineArgs()
|
||||
.Distinct();
|
||||
|
||||
// Get all relevant environment variables
|
||||
var allEnvVars = Environment.GetEnvironmentVariables();
|
||||
var relevantEnvVars = new Dictionary<object, object>();
|
||||
foreach (var key in allEnvVars.Keys)
|
||||
{
|
||||
if (_relevantEnvVarPrefixes.Any(prefix => key.ToString().StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
relevantEnvVars.Add(key, allEnvVars[key]);
|
||||
}
|
||||
}
|
||||
|
||||
logger.LogInformation("Environment Variables: {EnvVars}", relevantEnvVars);
|
||||
logger.LogInformation("Arguments: {Args}", commandLineArgs);
|
||||
logger.LogInformation("Operating system: {OS}", MediaBrowser.Common.System.OperatingSystem.Name);
|
||||
logger.LogInformation("Architecture: {Architecture}", RuntimeInformation.OSArchitecture);
|
||||
logger.LogInformation("64-Bit Process: {Is64Bit}", Environment.Is64BitProcess);
|
||||
logger.LogInformation("User Interactive: {IsUserInteractive}", Environment.UserInteractive);
|
||||
logger.LogInformation("Processor count: {ProcessorCount}", Environment.ProcessorCount);
|
||||
logger.LogInformation("Program data path: {ProgramDataPath}", appPaths.ProgramDataPath);
|
||||
logger.LogInformation("Web resources path: {WebPath}", appPaths.WebPath);
|
||||
logger.LogInformation("Application directory: {ApplicationPath}", appPaths.ProgramSystemPath);
|
||||
}
|
||||
|
||||
private X509Certificate2 GetCertificate(string path, string password)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
@@ -786,13 +722,7 @@ namespace Emby.Server.Implementations
|
||||
|
||||
Resolve<ILiveTvManager>().AddParts(GetExports<ILiveTvService>(), GetExports<ITunerHost>(), GetExports<IListingsProvider>());
|
||||
|
||||
Resolve<ISubtitleManager>().AddParts(GetExports<ISubtitleProvider>());
|
||||
|
||||
Resolve<IChannelManager>().AddParts(GetExports<IChannel>());
|
||||
|
||||
Resolve<IMediaSourceManager>().AddParts(GetExports<IMediaSourceProvider>());
|
||||
|
||||
Resolve<INotificationManager>().AddParts(GetExports<INotificationService>(), GetExports<INotificationTypeFactory>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -991,9 +921,6 @@ namespace Emby.Server.Implementations
|
||||
// Local metadata
|
||||
yield return typeof(BoxSetXmlSaver).Assembly;
|
||||
|
||||
// Notifications
|
||||
yield return typeof(NotificationManager).Assembly;
|
||||
|
||||
// Xbmc
|
||||
yield return typeof(ArtistNfoProvider).Assembly;
|
||||
|
||||
@@ -1032,14 +959,11 @@ namespace Emby.Server.Implementations
|
||||
ItemsByNamePath = ApplicationPaths.InternalMetadataPath,
|
||||
InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
|
||||
CachePath = ApplicationPaths.CachePath,
|
||||
OperatingSystem = MediaBrowser.Common.System.OperatingSystem.Id.ToString(),
|
||||
OperatingSystemDisplayName = MediaBrowser.Common.System.OperatingSystem.Name,
|
||||
CanLaunchWebBrowser = CanLaunchWebBrowser,
|
||||
TranscodingTempPath = ConfigurationManager.GetTranscodePath(),
|
||||
ServerName = FriendlyName,
|
||||
LocalAddress = GetSmartApiUrl(request),
|
||||
SupportsLibraryMonitor = true,
|
||||
SystemArchitecture = RuntimeInformation.OSArchitecture,
|
||||
PackageName = _startupOptions.PackageName
|
||||
};
|
||||
}
|
||||
@@ -1051,7 +975,6 @@ namespace Emby.Server.Implementations
|
||||
Version = ApplicationVersionString,
|
||||
ProductName = ApplicationProductName,
|
||||
Id = SystemId,
|
||||
OperatingSystem = MediaBrowser.Common.System.OperatingSystem.Id.ToString(),
|
||||
ServerName = FriendlyName,
|
||||
LocalAddress = GetSmartApiUrl(request),
|
||||
StartupWizardCompleted = ConfigurationManager.CommonConfiguration.IsStartupWizardCompleted
|
||||
@@ -1263,10 +1186,13 @@ namespace Emby.Server.Implementations
|
||||
}
|
||||
}
|
||||
|
||||
// used for closing websockets
|
||||
foreach (var session in _sessionManager.Sessions)
|
||||
if (_sessionManager != null)
|
||||
{
|
||||
await session.DisposeAsync().ConfigureAwait(false);
|
||||
// used for closing websockets
|
||||
foreach (var session in _sessionManager.Sessions)
|
||||
{
|
||||
await session.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace Emby.Server.Implementations.Channels
|
||||
/// <param name="userDataManager">The user data manager.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
/// <param name="memoryCache">The memory cache.</param>
|
||||
/// <param name="channels">The channels.</param>
|
||||
public ChannelManager(
|
||||
IUserManager userManager,
|
||||
IDtoService dtoService,
|
||||
@@ -75,7 +76,8 @@ namespace Emby.Server.Implementations.Channels
|
||||
IFileSystem fileSystem,
|
||||
IUserDataManager userDataManager,
|
||||
IProviderManager providerManager,
|
||||
IMemoryCache memoryCache)
|
||||
IMemoryCache memoryCache,
|
||||
IEnumerable<IChannel> channels)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_dtoService = dtoService;
|
||||
@@ -86,18 +88,13 @@ namespace Emby.Server.Implementations.Channels
|
||||
_userDataManager = userDataManager;
|
||||
_providerManager = providerManager;
|
||||
_memoryCache = memoryCache;
|
||||
}
|
||||
|
||||
internal IChannel[] Channels { get; private set; }
|
||||
|
||||
private static TimeSpan CacheLength => TimeSpan.FromHours(3);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void AddParts(IEnumerable<IChannel> channels)
|
||||
{
|
||||
Channels = channels.ToArray();
|
||||
}
|
||||
|
||||
internal IChannel[] Channels { get; }
|
||||
|
||||
private static TimeSpan CacheLength => TimeSpan.FromHours(3);
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool EnableMediaSourceDisplay(BaseItem item)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@@ -36,7 +34,7 @@ namespace Emby.Server.Implementations.Configuration
|
||||
/// <summary>
|
||||
/// Configuration updating event.
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<ServerConfiguration>> ConfigurationUpdating;
|
||||
public event EventHandler<GenericEventArgs<ServerConfiguration>>? ConfigurationUpdating;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the configuration.
|
||||
|
||||
@@ -4477,6 +4477,24 @@ namespace Emby.Server.Implementations.Data
|
||||
}
|
||||
}
|
||||
|
||||
if (query.IncludeInheritedTags.Length > 0)
|
||||
{
|
||||
var paramName = "@IncludeInheritedTags";
|
||||
if (statement is null)
|
||||
{
|
||||
int index = 0;
|
||||
string includedTags = string.Join(',', query.IncludeInheritedTags.Select(_ => paramName + index++));
|
||||
whereClauses.Add("((select CleanValue from ItemValues where ItemId=Guid and Type=6 and cleanvalue in (" + includedTags + ")) is not null)");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int index = 0; index < query.IncludeInheritedTags.Length; index++)
|
||||
{
|
||||
statement.TryBind(paramName + index, GetCleanValue(query.IncludeInheritedTags[index]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (query.SeriesStatuses.Length > 0)
|
||||
{
|
||||
var statuses = new List<string>();
|
||||
@@ -5440,6 +5458,9 @@ AND Type = @InternalPersonType)");
|
||||
|
||||
list.AddRange(inheritedTags.Select(i => (6, i)));
|
||||
|
||||
// Remove all invalid values.
|
||||
list.RemoveAll(i => string.IsNullOrEmpty(i.Item2));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Emby.Naming\Emby.Naming.csproj" />
|
||||
<ProjectReference Include="..\Emby.Notifications\Emby.Notifications.csproj" />
|
||||
<ProjectReference Include="..\Jellyfin.Api\Jellyfin.Api.csproj" />
|
||||
<ProjectReference Include="..\Jellyfin.Server.Implementations\Jellyfin.Server.Implementations.csproj" />
|
||||
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
|
||||
@@ -23,17 +22,17 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DiscUtils.Udf" Version="0.16.13" />
|
||||
<PackageReference Include="Jellyfin.XmlTv" Version="10.8.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.2" />
|
||||
<PackageReference Include="Mono.Nat" Version="3.0.4" />
|
||||
<PackageReference Include="prometheus-net.DotNetRuntime" Version="4.4.0" />
|
||||
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="3.1.0" />
|
||||
<PackageReference Include="DotNet.Glob" Version="3.1.3" />
|
||||
<PackageReference Include="DiscUtils.Udf" />
|
||||
<PackageReference Include="Jellyfin.XmlTv" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" />
|
||||
<PackageReference Include="Mono.Nat" />
|
||||
<PackageReference Include="prometheus-net.DotNetRuntime" />
|
||||
<PackageReference Include="SQLitePCL.pretty.netstandard" />
|
||||
<PackageReference Include="DotNet.Glob" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -54,13 +53,13 @@
|
||||
|
||||
<!-- Code Analyzers-->
|
||||
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4">
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="All" />
|
||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||
<PackageReference Include="SerilogAnalyzer" PrivateAssets="All" />
|
||||
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="All" />
|
||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using MediaBrowser.Common.Configuration;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -137,32 +137,33 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||
|
||||
private static ProgramInfo GetProgramInfo(XmlTvProgram program, ListingsProviderInfo info)
|
||||
{
|
||||
string episodeTitle = program.Episode?.Title;
|
||||
string episodeTitle = program.Episode.Title;
|
||||
var programCategories = program.Categories.Where(c => !string.IsNullOrWhiteSpace(c)).ToList();
|
||||
|
||||
var programInfo = new ProgramInfo
|
||||
{
|
||||
ChannelId = program.ChannelId,
|
||||
EndDate = program.EndDate.UtcDateTime,
|
||||
EpisodeNumber = program.Episode?.Episode,
|
||||
EpisodeNumber = program.Episode.Episode,
|
||||
EpisodeTitle = episodeTitle,
|
||||
Genres = program.Categories,
|
||||
Genres = programCategories,
|
||||
StartDate = program.StartDate.UtcDateTime,
|
||||
Name = program.Title,
|
||||
Overview = program.Description,
|
||||
ProductionYear = program.CopyrightDate?.Year,
|
||||
SeasonNumber = program.Episode?.Series,
|
||||
IsSeries = program.Episode is not null,
|
||||
SeasonNumber = program.Episode.Series,
|
||||
IsSeries = program.Episode.Series is not null,
|
||||
IsRepeat = program.IsPreviouslyShown && !program.IsNew,
|
||||
IsPremiere = program.Premiere is not null,
|
||||
IsKids = program.Categories.Any(c => info.KidsCategories.Contains(c, StringComparison.OrdinalIgnoreCase)),
|
||||
IsMovie = program.Categories.Any(c => info.MovieCategories.Contains(c, StringComparison.OrdinalIgnoreCase)),
|
||||
IsNews = program.Categories.Any(c => info.NewsCategories.Contains(c, StringComparison.OrdinalIgnoreCase)),
|
||||
IsSports = program.Categories.Any(c => info.SportsCategories.Contains(c, StringComparison.OrdinalIgnoreCase)),
|
||||
IsKids = programCategories.Any(c => info.KidsCategories.Contains(c, StringComparison.OrdinalIgnoreCase)),
|
||||
IsMovie = programCategories.Any(c => info.MovieCategories.Contains(c, StringComparison.OrdinalIgnoreCase)),
|
||||
IsNews = programCategories.Any(c => info.NewsCategories.Contains(c, StringComparison.OrdinalIgnoreCase)),
|
||||
IsSports = programCategories.Any(c => info.SportsCategories.Contains(c, StringComparison.OrdinalIgnoreCase)),
|
||||
ImageUrl = string.IsNullOrEmpty(program.Icon?.Source) ? null : program.Icon.Source,
|
||||
HasImage = !string.IsNullOrEmpty(program.Icon?.Source),
|
||||
OfficialRating = string.IsNullOrEmpty(program.Rating?.Value) ? null : program.Rating.Value,
|
||||
CommunityRating = program.StarRating,
|
||||
SeriesId = program.Episode is null ? null : program.Title?.GetMD5().ToString("N", CultureInfo.InvariantCulture)
|
||||
SeriesId = program.Episode.Episode is null ? null : program.Title?.GetMD5().ToString("N", CultureInfo.InvariantCulture)
|
||||
};
|
||||
|
||||
if (string.IsNullOrWhiteSpace(program.ProgramId))
|
||||
@@ -243,7 +244,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||
{
|
||||
Id = c.Id,
|
||||
Name = c.DisplayName,
|
||||
ImageUrl = string.IsNullOrEmpty(c.Icon.Source) ? null : c.Icon.Source,
|
||||
ImageUrl = string.IsNullOrEmpty(c.Icon?.Source) ? null : c.Icon.Source,
|
||||
Number = string.IsNullOrWhiteSpace(c.Number) ? c.Id : c.Number
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Extensions;
|
||||
using Jellyfin.Extensions.Json;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller;
|
||||
@@ -58,7 +59,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
_socketFactory = socketFactory;
|
||||
_streamHelper = streamHelper;
|
||||
|
||||
_jsonOptions = JsonDefaults.Options;
|
||||
_jsonOptions = new JsonSerializerOptions(JsonDefaults.Options);
|
||||
_jsonOptions.Converters.Add(new JsonBoolNumberConverter());
|
||||
}
|
||||
|
||||
public string Name => "HD Homerun";
|
||||
|
||||
@@ -1,4 +1,127 @@
|
||||
{
|
||||
"Sync": "Сінхранізацыя",
|
||||
"Playlists": "Плэйліст"
|
||||
"Sync": "Сінхранізаваць",
|
||||
"Playlists": "Плэйлісты",
|
||||
"Latest": "Апошні",
|
||||
"LabelIpAddressValue": "IP-адрас: {0}",
|
||||
"ItemAddedWithName": "{0} быў дададзены ў бібліятэку",
|
||||
"MessageApplicationUpdated": "Сервер Jellyfin абноўлены",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Абнаўленне прыкладання ўсталявана",
|
||||
"PluginInstalledWithName": "{0} быў усталяваны",
|
||||
"UserCreatedWithName": "Карыстальнік {0} быў створаны",
|
||||
"Albums": "Альбомы",
|
||||
"Application": "Прыкладанне",
|
||||
"AuthenticationSucceededWithUserName": "{0} паспяхова аўтэнтыфікаваны",
|
||||
"Channels": "Каналы",
|
||||
"ChapterNameValue": "Раздзел {0}",
|
||||
"Collections": "Калекцыі",
|
||||
"Default": "Па змаўчанні",
|
||||
"FailedLoginAttemptWithUserName": "Няўдалая спроба ўваходу з {0}",
|
||||
"Folders": "Папкі",
|
||||
"Favorites": "Абранае",
|
||||
"External": "Знешні",
|
||||
"Genres": "Жанры",
|
||||
"HeaderContinueWatching": "Працягнуць прагляд",
|
||||
"HeaderFavoriteAlbums": "Абраныя альбомы",
|
||||
"HeaderFavoriteEpisodes": "Абраныя серыі",
|
||||
"HeaderFavoriteShows": "Абраныя шоу",
|
||||
"HeaderFavoriteSongs": "Абраныя песні",
|
||||
"HeaderLiveTV": "Прамы эфір",
|
||||
"HeaderAlbumArtists": "Выканаўцы альбома",
|
||||
"LabelRunningTimeValue": "Працягласць: {0}",
|
||||
"HomeVideos": "Хатнія відэа",
|
||||
"ItemRemovedWithName": "{0} быў выдалены з бібліятэкі",
|
||||
"MessageApplicationUpdatedTo": "Сервер Jellyfin абноўлены да {0}",
|
||||
"Movies": "Фільмы",
|
||||
"Music": "Музыка",
|
||||
"MusicVideos": "Музычныя кліпы",
|
||||
"NameInstallFailed": "Устаноўка {0} не атрымалася",
|
||||
"NameSeasonNumber": "Сезон {0}",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Даступна абнаўленне прыкладання",
|
||||
"NotificationOptionPluginInstalled": "Плагін усталяваны",
|
||||
"NotificationOptionPluginUpdateInstalled": "Абнаўленне плагіна усталявана",
|
||||
"NotificationOptionServerRestartRequired": "Патрабуецца перазапуск сервера",
|
||||
"Photos": "Фатаграфіі",
|
||||
"Plugin": "Плагін",
|
||||
"PluginUninstalledWithName": "{0} быў выдалены",
|
||||
"PluginUpdatedWithName": "{0} быў абноўлены",
|
||||
"ProviderValue": "Пастаўшчык: {0}",
|
||||
"Songs": "Песні",
|
||||
"System": "Сістэма",
|
||||
"User": "Карыстальнік",
|
||||
"UserDeletedWithName": "Карыстальнік {0} быў выдалены",
|
||||
"UserDownloadingItemWithValues": "{0} спампоўваецца {1}",
|
||||
"TaskOptimizeDatabase": "Аптымізаваць базу дадзеных",
|
||||
"Artists": "Выканаўцы",
|
||||
"UserOfflineFromDevice": "{0} адключыўся ад {1}",
|
||||
"UserPolicyUpdatedWithName": "Палітыка карыстальніка абноўлена для {0}",
|
||||
"TaskCleanActivityLogDescription": "Выдаляе старэйшыя за зададзены ўзрост запісы ў журнале актыўнасці.",
|
||||
"TaskRefreshChapterImagesDescription": "Стварае мініяцюры для відэа, якія маюць раздзелы.",
|
||||
"TaskCleanLogsDescription": "Выдаляе файлы журналу, якім больш за {0} дзён.",
|
||||
"TaskUpdatePluginsDescription": "Спампоўвае і ўсталёўвае абнаўленні для плагінаў, якія настроены на аўтаматычнае абнаўленне.",
|
||||
"TaskRefreshChannelsDescription": "Абнаўляе інфармацыю аб інтэрнэт-канале.",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Шукае ў інтэрнэце адсутныя субтытры на аснове канфігурацыі метададзеных.",
|
||||
"TaskOptimizeDatabaseDescription": "Ушчыльняе базу дадзеных і скарачае вольную прастору. Выкананне гэтай задачы пасля сканавання бібліятэкі або ўнясення іншых змяненняў, якія прадугледжваюць мадыфікацыю базы дадзеных, можа палепшыць прадукцыйнасць.",
|
||||
"TaskKeyframeExtractor": "Экстрактар ключавых кадраў",
|
||||
"TasksApplicationCategory": "Прыкладанне",
|
||||
"AppDeviceValues": "Прыкладанне: {0}, Прылада: {1}",
|
||||
"Books": "Кнігі",
|
||||
"CameraImageUploadedFrom": "Новая выява камеры была загружана з {0}",
|
||||
"DeviceOfflineWithName": "{0} адключыўся",
|
||||
"DeviceOnlineWithName": "{0} падлучаны",
|
||||
"Forced": "Прымусова",
|
||||
"HeaderRecordingGroups": "Групы запісаў",
|
||||
"HeaderNextUp": "Наступнае",
|
||||
"HeaderFavoriteArtists": "Абраныя выканаўцы",
|
||||
"HearingImpaired": "Са слабым слыхам",
|
||||
"Inherit": "Атрымаць у спадчыну",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Канфігурацыя сервера {0} абноўлена",
|
||||
"MessageServerConfigurationUpdated": "Канфігурацыя сервера абноўлена",
|
||||
"MixedContent": "Змешаны змест",
|
||||
"NameSeasonUnknown": "Невядомы сезон",
|
||||
"NotificationOptionInstallationFailed": "Збой усталёўкі",
|
||||
"NewVersionIsAvailable": "Новая версія сервера Jellyfin даступная для cпампоўкі.",
|
||||
"NotificationOptionCameraImageUploaded": "Выява камеры запампавана",
|
||||
"NotificationOptionAudioPlaybackStopped": "Прайграванне аўдыё спынена",
|
||||
"NotificationOptionAudioPlayback": "Прайграванне аўдыё пачалося",
|
||||
"NotificationOptionNewLibraryContent": "Дададзены новы кантэнт",
|
||||
"NotificationOptionPluginError": "Збой плагіна",
|
||||
"NotificationOptionPluginUninstalled": "Плагін выдалены",
|
||||
"NotificationOptionTaskFailed": "Збой запланаванага задання",
|
||||
"NotificationOptionUserLockedOut": "Карыстальнік заблакіраваны",
|
||||
"NotificationOptionVideoPlayback": "Пачалося прайграванне відэа",
|
||||
"NotificationOptionVideoPlaybackStopped": "Прайграванне відэа спынена",
|
||||
"ScheduledTaskFailedWithName": "{0} не атрымалася",
|
||||
"ScheduledTaskStartedWithName": "{0} пачалося",
|
||||
"ServerNameNeedsToBeRestarted": "{0} трэба перазапусціць",
|
||||
"Shows": "Шоу",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server загружаецца. Калі ласка, паўтарыце спробу крыху пазней.",
|
||||
"SubtitleDownloadFailureFromForItem": "Не атрымалася спампаваць субтытры з {0} для {1}",
|
||||
"TvShows": "ТБ-шоу",
|
||||
"Undefined": "Нявызначана",
|
||||
"UserLockedOutWithName": "Карыстальнік {0} быў заблакіраваны",
|
||||
"UserOnlineFromDevice": "{0} падключаны з {1}",
|
||||
"UserPasswordChangedWithName": "Пароль быў зменены для карыстальніка {0}",
|
||||
"UserStartedPlayingItemWithValues": "{0} грае {1} на {2}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} скончыў прайграванне {1} на {2}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} быў дададзены ў вашу медыятэку",
|
||||
"ValueSpecialEpisodeName": "Спецэпізод - {0}",
|
||||
"VersionNumber": "Версія {0}",
|
||||
"TasksMaintenanceCategory": "Абслугоўванне",
|
||||
"TasksLibraryCategory": "Медыятэка",
|
||||
"TasksChannelsCategory": "Інтэрнэт-каналы",
|
||||
"TaskCleanActivityLog": "Ачысціць журнал актыўнасці",
|
||||
"TaskCleanCache": "Ачысціць кэш",
|
||||
"TaskCleanCacheDescription": "Выдаляе файлы кэша, якія больш не патрэбныя сістэме.",
|
||||
"TaskRefreshChapterImages": "Выняць выявы раздзелаў",
|
||||
"TaskRefreshLibrary": "Сканіраваць медыятэку",
|
||||
"TaskRefreshLibraryDescription": "Сканіруе вашу медыятэку на наяўнасць новых файлаў і абнаўляе метададзеныя.",
|
||||
"TaskCleanLogs": "Ачысціць часопіс",
|
||||
"TaskRefreshPeople": "Абнавіць людзей",
|
||||
"TaskRefreshPeopleDescription": "Абнаўленне метаданых для акцёраў і рэжысёраў у вашай медыятэцы.",
|
||||
"TaskUpdatePlugins": "Абнавіць плагіны",
|
||||
"TaskCleanTranscode": "Ачысціць каталог перакадзіравання",
|
||||
"TaskCleanTranscodeDescription": "Выдаляе перакадзіраваныя файлы, старэйшыя за адзін дзень.",
|
||||
"TaskRefreshChannels": "Абнавіць каналы",
|
||||
"TaskDownloadMissingSubtitles": "Спампаваць адсутныя субтытры",
|
||||
"TaskKeyframeExtractorDescription": "Выдае ключавыя кадры з відэафайлаў для стварэння больш дакладных спісаў прайгравання HLS. Гэта задача можа працаваць у працягу доўгага часу."
|
||||
}
|
||||
|
||||
@@ -122,5 +122,6 @@
|
||||
"TaskOptimizeDatabase": "Optimizar base de datos",
|
||||
"External": "Externo",
|
||||
"TaskKeyframeExtractorDescription": "Extrae Fotogramas Clave de los archivos de vídeo para crear Listas de Reproducción HLS más precisas. Esta tarea puede durar mucho tiempo.",
|
||||
"TaskKeyframeExtractor": "Extractor de Fotogramas Clave"
|
||||
"TaskKeyframeExtractor": "Extractor de Fotogramas Clave",
|
||||
"HearingImpaired": "Discapacidad auditiva"
|
||||
}
|
||||
|
||||
@@ -123,5 +123,6 @@
|
||||
"TaskOptimizeDatabaseDescription": "فشرده سازی پایگاه داده و باز کردن فضای آزاد.اجرای این گزینه بعد از اسکن کردن کتابخانه یا تغییرات دیگر که روی پایگاه داده تأثیر میگذارند میتواند کارایی را بهبود ببخشد.",
|
||||
"TaskKeyframeExtractorDescription": "فریم های کلیدی را از فایل های ویدئویی استخراج می کند تا لیست های پخش HLS دقیق تری ایجاد کند. این کار ممکن است برای مدت طولانی اجرا شود.",
|
||||
"TaskKeyframeExtractor": "استخراج کننده فریم کلیدی",
|
||||
"External": "خارجی"
|
||||
"External": "خارجی",
|
||||
"HearingImpaired": "مشکل شنوایی"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"Albums": "Alben",
|
||||
"AppDeviceValues": "App: {0}, Gerät: {1}",
|
||||
"Application": "Anwendung",
|
||||
"Application": "Applikation",
|
||||
"Artists": "Künstler",
|
||||
"AuthenticationSucceededWithUserName": "{0} hat sich angemeldet",
|
||||
"Books": "Bücher",
|
||||
@@ -14,7 +14,7 @@
|
||||
"FailedLoginAttemptWithUserName": "Fehlgeschlagener Anmeldeversuch von {0}",
|
||||
"Favorites": "Favoriten",
|
||||
"Folders": "Ordner",
|
||||
"Genres": "Genres",
|
||||
"Genres": "Genre",
|
||||
"HeaderAlbumArtists": "Album-Künstler",
|
||||
"HeaderContinueWatching": "weiter schauen",
|
||||
"HeaderFavoriteAlbums": "Lieblingsalben",
|
||||
@@ -49,7 +49,7 @@
|
||||
"NotificationOptionAudioPlayback": "Audiowedergab gstartet",
|
||||
"NotificationOptionAudioPlaybackStopped": "Audiwedergab gstoppt",
|
||||
"NotificationOptionCameraImageUploaded": "Foti ueglade",
|
||||
"NotificationOptionInstallationFailed": "Installationsfehler",
|
||||
"NotificationOptionInstallationFailed": "Installationsfähler",
|
||||
"NotificationOptionNewLibraryContent": "Nöie Inhaut hinzuegfüegt",
|
||||
"NotificationOptionPluginError": "Plugin-Fäuer",
|
||||
"NotificationOptionPluginInstalled": "Plugin installiert",
|
||||
@@ -120,5 +120,9 @@
|
||||
"Forced": "Erzwungen",
|
||||
"Default": "Standard",
|
||||
"TaskOptimizeDatabase": "Datenbank optimieren",
|
||||
"External": "Extern"
|
||||
"External": "Extern",
|
||||
"TaskOptimizeDatabaseDescription": "Kompromiert d Datenbank und trennt freie Speicherplatz. Durch die Ufagb cha d Leistig nach em ne Scan vor Bibliothek oder andere Ufgabe verbesseret werde.",
|
||||
"HearingImpaired": "Hörgschädigti",
|
||||
"TaskKeyframeExtractor": "Keyframe-Extraktor",
|
||||
"TaskKeyframeExtractorDescription": "Extrahiert Keyframes us Videodateien zum erstelle vo genauere HLS Playliste. Die Ufgab cha für e langi Zyt laufe."
|
||||
}
|
||||
|
||||
@@ -19,5 +19,10 @@
|
||||
"FailedLoginAttemptWithUserName": "Ye failed to get in, try from {0}",
|
||||
"Favorites": "Finest Loot",
|
||||
"ItemRemovedWithName": "{0} was taken from yer treasure",
|
||||
"LabelIpAddressValue": "Ship's coordinates: {0}"
|
||||
"LabelIpAddressValue": "Ship's coordinates: {0}",
|
||||
"Genres": "types o' booty",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Scours the seven seas o' the internet for subtitles that be missin' based on the captain's map o' metadata.",
|
||||
"HeaderAlbumArtists": "Buccaneers o' the musical arts",
|
||||
"HeaderFavoriteAlbums": "Beloved booty o' musical adventures",
|
||||
"HeaderFavoriteArtists": "Treasured scallywags o' the creative seas"
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"PluginInstalledWithName": "{0} installerades",
|
||||
"PluginUninstalledWithName": "{0} avinstallerades",
|
||||
"PluginUpdatedWithName": "{0} uppdaterades",
|
||||
"ProviderValue": "Källa: {0}",
|
||||
"ProviderValue": "Leverantör: {0}",
|
||||
"ScheduledTaskFailedWithName": "{0} misslyckades",
|
||||
"ScheduledTaskStartedWithName": "{0} startades",
|
||||
"ServerNameNeedsToBeRestarted": "{0} behöver startas om",
|
||||
|
||||
@@ -123,41 +123,64 @@ namespace Emby.Server.Implementations.Plugins
|
||||
continue;
|
||||
}
|
||||
|
||||
var assemblyLoadContext = new PluginLoadContext(plugin.Path);
|
||||
_assemblyLoadContexts.Add(assemblyLoadContext);
|
||||
|
||||
var assemblies = new List<Assembly>(plugin.DllFiles.Count);
|
||||
var loadedAll = true;
|
||||
|
||||
foreach (var file in plugin.DllFiles)
|
||||
{
|
||||
Assembly assembly;
|
||||
try
|
||||
{
|
||||
var assemblyLoadContext = new PluginLoadContext(file);
|
||||
_assemblyLoadContexts.Add(assemblyLoadContext);
|
||||
|
||||
assembly = assemblyLoadContext.LoadFromAssemblyPath(file);
|
||||
|
||||
// Load all required types to verify that the plugin will load
|
||||
assembly.GetTypes();
|
||||
assemblies.Add(assemblyLoadContext.LoadFromAssemblyPath(file));
|
||||
}
|
||||
catch (FileLoadException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to load assembly {Path}. Disabling plugin.", file);
|
||||
_logger.LogError(ex, "Failed to load assembly {Path}. Disabling plugin", file);
|
||||
ChangePluginState(plugin, PluginStatus.Malfunctioned);
|
||||
continue;
|
||||
}
|
||||
catch (SystemException ex) when (ex is TypeLoadException or ReflectionTypeLoadException) // 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;
|
||||
loadedAll = false;
|
||||
break;
|
||||
}
|
||||
#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);
|
||||
_logger.LogError(ex, "Failed to load assembly {Path}. Unknown exception was thrown. Disabling plugin", file);
|
||||
ChangePluginState(plugin, PluginStatus.Malfunctioned);
|
||||
continue;
|
||||
loadedAll = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loadedAll)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Load all required types to verify that the plugin will load
|
||||
assembly.GetTypes();
|
||||
}
|
||||
catch (SystemException ex) when (ex is TypeLoadException or ReflectionTypeLoadException) // 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", assembly.Location);
|
||||
ChangePluginState(plugin, PluginStatus.NotSupported);
|
||||
break;
|
||||
}
|
||||
#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", assembly.Location);
|
||||
ChangePluginState(plugin, PluginStatus.Malfunctioned);
|
||||
break;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Loaded assembly {Assembly} from {Path}", assembly.FullName, file);
|
||||
_logger.LogInformation("Loaded assembly {Assembly} from {Path}", assembly.FullName, assembly.Location);
|
||||
yield return assembly;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user