mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-01 13:28:27 +01:00
Merge branch 'master' into installationmanager
This commit is contained in:
@@ -35,7 +35,7 @@ namespace Emby.Server.Implementations.AppBase
|
||||
/// <summary>
|
||||
/// The _configuration sync lock.
|
||||
/// </summary>
|
||||
private object _configurationSyncLock = new object();
|
||||
private readonly object _configurationSyncLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// The _configuration.
|
||||
@@ -98,16 +98,31 @@ namespace Emby.Server.Implementations.AppBase
|
||||
public IApplicationPaths CommonApplicationPaths { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the system configuration
|
||||
/// Gets the system configuration.
|
||||
/// </summary>
|
||||
/// <value>The configuration.</value>
|
||||
public BaseApplicationConfiguration CommonConfiguration
|
||||
{
|
||||
get
|
||||
{
|
||||
// Lazy load
|
||||
LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationLoaded, ref _configurationSyncLock, () => (BaseApplicationConfiguration)ConfigurationHelper.GetXmlConfiguration(ConfigurationType, CommonApplicationPaths.SystemConfigurationFilePath, XmlSerializer));
|
||||
return _configuration;
|
||||
if (_configurationLoaded)
|
||||
{
|
||||
return _configuration;
|
||||
}
|
||||
|
||||
lock (_configurationSyncLock)
|
||||
{
|
||||
if (_configurationLoaded)
|
||||
{
|
||||
return _configuration;
|
||||
}
|
||||
|
||||
_configuration = (BaseApplicationConfiguration)ConfigurationHelper.GetXmlConfiguration(ConfigurationType, CommonApplicationPaths.SystemConfigurationFilePath, XmlSerializer);
|
||||
|
||||
_configurationLoaded = true;
|
||||
|
||||
return _configuration;
|
||||
}
|
||||
}
|
||||
protected set
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Emby.Naming\Emby.Naming.csproj" />
|
||||
@@ -29,9 +29,9 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="ServiceStack.Text.Core" Version="5.6.0" />
|
||||
<PackageReference Include="sharpcompress" Version="0.24.0" />
|
||||
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.0.1" />
|
||||
@@ -47,16 +47,12 @@
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- We need at least C# 7.3 to compare tuples-->
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Code analysers-->
|
||||
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.4" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
|
||||
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
|
||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
|
||||
@@ -27,6 +27,11 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
private NatManager _natManager;
|
||||
|
||||
private readonly object _createdRulesLock = new object();
|
||||
private List<string> _createdRules = new List<string>();
|
||||
private readonly object _usnsHandledLock = new object();
|
||||
private List<string> _usnsHandled = new List<string>();
|
||||
|
||||
public ExternalPortForwarding(ILoggerFactory loggerFactory, IServerApplicationHost appHost, IServerConfigurationManager config, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient)
|
||||
{
|
||||
_logger = loggerFactory.CreateLogger("PortMapper");
|
||||
@@ -127,12 +132,13 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_usnsHandled)
|
||||
lock (_usnsHandledLock)
|
||||
{
|
||||
if (_usnsHandled.Contains(identifier))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_usnsHandled.Add(identifier);
|
||||
}
|
||||
|
||||
@@ -186,11 +192,12 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
private void ClearCreatedRules(object state)
|
||||
{
|
||||
lock (_createdRules)
|
||||
lock (_createdRulesLock)
|
||||
{
|
||||
_createdRules.Clear();
|
||||
}
|
||||
lock (_usnsHandled)
|
||||
|
||||
lock (_usnsHandledLock)
|
||||
{
|
||||
_usnsHandled.Clear();
|
||||
}
|
||||
@@ -216,8 +223,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> _createdRules = new List<string>();
|
||||
private List<string> _usnsHandled = new List<string>();
|
||||
private async void CreateRules(INatDevice device)
|
||||
{
|
||||
if (_disposed)
|
||||
@@ -231,7 +236,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
var addressString = address.ToString();
|
||||
|
||||
lock (_createdRules)
|
||||
lock (_createdRulesLock)
|
||||
{
|
||||
if (!_createdRules.Contains(addressString))
|
||||
{
|
||||
|
||||
@@ -539,6 +539,11 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (httpRes.StatusCode >= 500)
|
||||
{
|
||||
_logger.LogDebug("Sending HTTP Response 500 in response to {Url}", urlToLog);
|
||||
}
|
||||
|
||||
stopWatch.Stop();
|
||||
var elapsed = stopWatch.Elapsed;
|
||||
if (elapsed.TotalMilliseconds > 500)
|
||||
|
||||
@@ -2,11 +2,11 @@ using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common;
|
||||
using MediaBrowser.Common.Cryptography;
|
||||
using MediaBrowser.Controller.Authentication;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Cryptography;
|
||||
using static MediaBrowser.Common.HexHelper;
|
||||
|
||||
namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
@@ -122,7 +122,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
return string.IsNullOrEmpty(user.EasyPassword)
|
||||
? null
|
||||
: ToHexString(PasswordHash.Parse(user.EasyPassword).Hash);
|
||||
: Hex.Encode(PasswordHash.Parse(user.EasyPassword).Hash);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common;
|
||||
using MediaBrowser.Common.Cryptography;
|
||||
using MediaBrowser.Common.Events;
|
||||
using MediaBrowser.Common.Net;
|
||||
@@ -31,7 +32,6 @@ using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Model.Users;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static MediaBrowser.Common.HexHelper;
|
||||
|
||||
namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
@@ -490,7 +490,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
return string.IsNullOrEmpty(user.EasyPassword)
|
||||
? null
|
||||
: ToHexString(PasswordHash.Parse(user.EasyPassword).Hash);
|
||||
: Hex.Encode(PasswordHash.Parse(user.EasyPassword).Hash);
|
||||
}
|
||||
|
||||
private void ResetInvalidLoginAttemptCount(User user)
|
||||
|
||||
@@ -2304,8 +2304,10 @@ namespace Emby.Server.Implementations.LiveTv
|
||||
if (provider == null)
|
||||
{
|
||||
throw new ResourceNotFoundException(
|
||||
string.Format("Couldn't find provider of type: '{0}'", info.Type)
|
||||
);
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Couldn't find provider of type: '{0}'",
|
||||
info.Type));
|
||||
}
|
||||
|
||||
await provider.Validate(info, validateLogin, validateListings).ConfigureAwait(false);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"Artists": "Előadók",
|
||||
"AuthenticationSucceededWithUserName": "{0} sikeresen azonosítva",
|
||||
"Books": "Könyvek",
|
||||
"CameraImageUploadedFrom": "Új kamerakép került feltöltésre {0}",
|
||||
"CameraImageUploadedFrom": "Új kamerakép került feltöltésre innen: {0}",
|
||||
"Channels": "Csatornák",
|
||||
"ChapterNameValue": "Jelenet {0}",
|
||||
"Collections": "Gyűjtemények",
|
||||
@@ -15,14 +15,14 @@
|
||||
"Favorites": "Kedvencek",
|
||||
"Folders": "Könyvtárak",
|
||||
"Genres": "Műfajok",
|
||||
"HeaderAlbumArtists": "Album Előadók",
|
||||
"HeaderAlbumArtists": "Album előadók",
|
||||
"HeaderCameraUploads": "Kamera feltöltések",
|
||||
"HeaderContinueWatching": "Folyamatban lévő filmek",
|
||||
"HeaderFavoriteAlbums": "Kedvenc Albumok",
|
||||
"HeaderFavoriteArtists": "Kedvenc Előadók",
|
||||
"HeaderFavoriteEpisodes": "Kedvenc Epizódok",
|
||||
"HeaderFavoriteShows": "Kedvenc Sorozatok",
|
||||
"HeaderFavoriteSongs": "Kedvenc Dalok",
|
||||
"HeaderFavoriteAlbums": "Kedvenc albumok",
|
||||
"HeaderFavoriteArtists": "Kedvenc előadók",
|
||||
"HeaderFavoriteEpisodes": "Kedvenc epizódok",
|
||||
"HeaderFavoriteShows": "Kedvenc sorozatok",
|
||||
"HeaderFavoriteSongs": "Kedvenc dalok",
|
||||
"HeaderLiveTV": "Élő TV",
|
||||
"HeaderNextUp": "Következik",
|
||||
"HeaderRecordingGroups": "Felvételi csoportok",
|
||||
@@ -34,21 +34,21 @@
|
||||
"LabelRunningTimeValue": "Futási idő: {0}",
|
||||
"Latest": "Legújabb",
|
||||
"MessageApplicationUpdated": "Jellyfin Szerver frissítve",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin Szerver frissítve lett a következőre {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Szerver konfigurációs rész {0} frissítve",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin Szerver frissítve lett a következőre: {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Szerver konfigurációs rész frissítve: {0}",
|
||||
"MessageServerConfigurationUpdated": "Szerver konfiguráció frissítve",
|
||||
"MixedContent": "Vegyes tartalom",
|
||||
"Movies": "Filmek",
|
||||
"Music": "Zene",
|
||||
"MusicVideos": "Zenei Videók",
|
||||
"MusicVideos": "Zenei videók",
|
||||
"NameInstallFailed": "{0} sikertelen telepítés",
|
||||
"NameSeasonNumber": "Évad {0}",
|
||||
"NameSeasonUnknown": "Ismeretlen évad",
|
||||
"NewVersionIsAvailable": "Letölthető a Jellyfin Szerver új verziója.",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Új programfrissítés érhető el",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Programfrissítés telepítve",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Frissítés érhető el az alkalmazáshoz",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Alkalmazásfrissítés telepítve",
|
||||
"NotificationOptionAudioPlayback": "Audió lejátszás elkezdve",
|
||||
"NotificationOptionAudioPlaybackStopped": "Audió lejátszás befejezve",
|
||||
"NotificationOptionAudioPlaybackStopped": "Audió lejátszás leállítva",
|
||||
"NotificationOptionCameraImageUploaded": "Kamera kép feltöltve",
|
||||
"NotificationOptionInstallationFailed": "Telepítési hiba",
|
||||
"NotificationOptionNewLibraryContent": "Új tartalom hozzáadva",
|
||||
@@ -60,15 +60,15 @@
|
||||
"NotificationOptionTaskFailed": "Ütemezett feladat hiba",
|
||||
"NotificationOptionUserLockedOut": "Felhasználó tiltva",
|
||||
"NotificationOptionVideoPlayback": "Videó lejátszás elkezdve",
|
||||
"NotificationOptionVideoPlaybackStopped": "Videó lejátszás befejezve",
|
||||
"NotificationOptionVideoPlaybackStopped": "Videó lejátszás leállítva",
|
||||
"Photos": "Fényképek",
|
||||
"Playlists": "Lejátszási listák",
|
||||
"Plugin": "Bővítmény",
|
||||
"PluginInstalledWithName": "{0} telepítve",
|
||||
"PluginUninstalledWithName": "{0} eltávolítva",
|
||||
"PluginUpdatedWithName": "{0} frissítve",
|
||||
"ProviderValue": "Provider: {0}",
|
||||
"ScheduledTaskFailedWithName": "{0} hiba",
|
||||
"ProviderValue": "Szolgáltató: {0}",
|
||||
"ScheduledTaskFailedWithName": "{0} sikertelen",
|
||||
"ScheduledTaskStartedWithName": "{0} elkezdve",
|
||||
"ServerNameNeedsToBeRestarted": "{0}-t újra kell indítani",
|
||||
"Shows": "Műsorok",
|
||||
@@ -76,10 +76,10 @@
|
||||
"StartupEmbyServerIsLoading": "A Jellyfin Szerver betöltődik. Kérlek próbáld újra később.",
|
||||
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Nem sikerült a felirat letöltése innen: {0} ehhez: {1}",
|
||||
"SubtitlesDownloadedForItem": "Letöltött feliratok a következőhöz {0}",
|
||||
"SubtitlesDownloadedForItem": "Letöltött feliratok a következőhöz: {0}",
|
||||
"Sync": "Szinkronizál",
|
||||
"System": "Rendszer",
|
||||
"TvShows": "TV Műsorok",
|
||||
"TvShows": "TV műsorok",
|
||||
"User": "Felhasználó",
|
||||
"UserCreatedWithName": "{0} felhasználó létrehozva",
|
||||
"UserDeletedWithName": "{0} felhasználó törölve",
|
||||
@@ -88,7 +88,7 @@
|
||||
"UserOfflineFromDevice": "{0} kijelentkezett innen: {1}",
|
||||
"UserOnlineFromDevice": "{0} online itt: {1}",
|
||||
"UserPasswordChangedWithName": "Jelszó megváltozott a következő felhasználó számára: {0}",
|
||||
"UserPolicyUpdatedWithName": "A felhasználói házirend frissítve lett {0}",
|
||||
"UserPolicyUpdatedWithName": "A felhasználói házirend frissítve lett neki: {0}",
|
||||
"UserStartedPlayingItemWithValues": "{0} elkezdte játszani a következőt: {1} itt: {2}",
|
||||
"UserStoppedPlayingItemWithValues": "{0} befejezte a következőt: {1} itt: {2}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} hozzáadva a médiatárhoz",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"Artists": "艺术家",
|
||||
"AuthenticationSucceededWithUserName": "{0} 认证成功",
|
||||
"Books": "书籍",
|
||||
"CameraImageUploadedFrom": "已从 {0} 上传了一张新的相机图像",
|
||||
"CameraImageUploadedFrom": "已从 {0} 上传了一张新的相片",
|
||||
"Channels": "频道",
|
||||
"ChapterNameValue": "章节 {0}",
|
||||
"Collections": "合集",
|
||||
|
||||
@@ -20,6 +20,9 @@ namespace Emby.Server.Implementations.Networking
|
||||
private IPAddress[] _localIpAddresses;
|
||||
private readonly object _localIpAddressSyncLock = new object();
|
||||
|
||||
private readonly object _subnetLookupLock = new object();
|
||||
private Dictionary<string, List<string>> _subnetLookup = new Dictionary<string, List<string>>(StringComparer.Ordinal);
|
||||
|
||||
public NetworkManager(ILogger<NetworkManager> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
@@ -28,10 +31,10 @@ namespace Emby.Server.Implementations.Networking
|
||||
NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;
|
||||
}
|
||||
|
||||
public Func<string[]> LocalSubnetsFn { get; set; }
|
||||
|
||||
public event EventHandler NetworkChanged;
|
||||
|
||||
public Func<string[]> LocalSubnetsFn { get; set; }
|
||||
|
||||
private void OnNetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
|
||||
{
|
||||
_logger.LogDebug("NetworkAvailabilityChanged");
|
||||
@@ -179,10 +182,9 @@ namespace Emby.Server.Implementations.Networking
|
||||
return false;
|
||||
}
|
||||
|
||||
private Dictionary<string, List<string>> _subnetLookup = new Dictionary<string, List<string>>(StringComparer.Ordinal);
|
||||
private List<string> GetSubnets(string endpointFirstPart)
|
||||
{
|
||||
lock (_subnetLookup)
|
||||
lock (_subnetLookupLock)
|
||||
{
|
||||
if (_subnetLookup.TryGetValue(endpointFirstPart, out var subnets))
|
||||
{
|
||||
@@ -200,7 +202,11 @@ namespace Emby.Server.Implementations.Networking
|
||||
int subnet_Test = 0;
|
||||
foreach (string part in unicastIPAddressInformation.IPv4Mask.ToString().Split('.'))
|
||||
{
|
||||
if (part.Equals("0")) break;
|
||||
if (part.Equals("0", StringComparison.Ordinal))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
subnet_Test++;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,52 +19,18 @@ using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Model.Updates;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static MediaBrowser.Common.HexHelper;
|
||||
|
||||
namespace Emby.Server.Implementations.Updates
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages all install, uninstall and update operations (both plugins and system)
|
||||
/// Manages all install, uninstall and update operations (both plugins and system).
|
||||
/// </summary>
|
||||
public class InstallationManager : IInstallationManager
|
||||
{
|
||||
public event EventHandler<InstallationEventArgs> PackageInstalling;
|
||||
public event EventHandler<InstallationEventArgs> PackageInstallationCompleted;
|
||||
public event EventHandler<InstallationFailedEventArgs> PackageInstallationFailed;
|
||||
public event EventHandler<InstallationEventArgs> PackageInstallationCancelled;
|
||||
|
||||
/// <summary>
|
||||
/// The current installations
|
||||
/// </summary>
|
||||
private List<(InstallationInfo info, CancellationTokenSource token)> _currentInstallations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The completed installations
|
||||
/// </summary>
|
||||
private ConcurrentBag<InstallationInfo> _completedInstallationsInternal;
|
||||
|
||||
public IEnumerable<InstallationInfo> CompletedInstallations => _completedInstallationsInternal;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [plugin uninstalled].
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<IPlugin>> PluginUninstalled;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [plugin updated].
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<(IPlugin, PackageVersionInfo)>> PluginUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [plugin updated].
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<PackageVersionInfo>> PluginInstalled;
|
||||
|
||||
/// <summary>
|
||||
/// The _logger
|
||||
/// The _logger.
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
@@ -79,6 +45,18 @@ namespace Emby.Server.Implementations.Updates
|
||||
|
||||
private readonly IZipClient _zipClient;
|
||||
|
||||
private readonly object _currentInstallationsLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// The current installations.
|
||||
/// </summary>
|
||||
private List<(InstallationInfo info, CancellationTokenSource token)> _currentInstallations;
|
||||
|
||||
/// <summary>
|
||||
/// The completed installations.
|
||||
/// </summary>
|
||||
private ConcurrentBag<InstallationInfo> _completedInstallationsInternal;
|
||||
|
||||
public InstallationManager(
|
||||
ILogger<InstallationManager> logger,
|
||||
IApplicationHost appHost,
|
||||
@@ -107,6 +85,31 @@ namespace Emby.Server.Implementations.Updates
|
||||
_zipClient = zipClient;
|
||||
}
|
||||
|
||||
public event EventHandler<InstallationEventArgs> PackageInstalling;
|
||||
|
||||
public event EventHandler<InstallationEventArgs> PackageInstallationCompleted;
|
||||
|
||||
public event EventHandler<InstallationFailedEventArgs> PackageInstallationFailed;
|
||||
|
||||
public event EventHandler<InstallationEventArgs> PackageInstallationCancelled;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a plugin is uninstalled.
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<IPlugin>> PluginUninstalled;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a plugin plugin is updated.
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<(IPlugin, PackageVersionInfo)>> PluginUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a plugin plugin is installed.
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<PackageVersionInfo>> PluginInstalled;
|
||||
|
||||
public IEnumerable<InstallationInfo> CompletedInstallations => _completedInstallationsInternal;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -225,7 +228,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
var tuple = (installationInfo, innerCancellationTokenSource);
|
||||
|
||||
// Add it to the in-progress list
|
||||
lock (_currentInstallations)
|
||||
lock (_currentInstallationsLock)
|
||||
{
|
||||
_currentInstallations.Add(tuple);
|
||||
}
|
||||
@@ -244,7 +247,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
{
|
||||
await InstallPackageInternal(package, linkedToken).ConfigureAwait(false);
|
||||
|
||||
lock (_currentInstallations)
|
||||
lock (_currentInstallationsLock)
|
||||
{
|
||||
_currentInstallations.Remove(tuple);
|
||||
}
|
||||
@@ -255,7 +258,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
lock (_currentInstallations)
|
||||
lock (_currentInstallationsLock)
|
||||
{
|
||||
_currentInstallations.Remove(tuple);
|
||||
}
|
||||
@@ -270,7 +273,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
{
|
||||
_logger.LogError(ex, "Package installation failed");
|
||||
|
||||
lock (_currentInstallations)
|
||||
lock (_currentInstallationsLock)
|
||||
{
|
||||
_currentInstallations.Remove(tuple);
|
||||
}
|
||||
@@ -334,7 +337,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
// Always override the passed-in target (which is a file) and figure it out again
|
||||
string targetDir = Path.Combine(_appPaths.PluginsPath, package.name);
|
||||
|
||||
// CA5351: Do Not Use Broken Cryptographic Algorithms
|
||||
// CA5351: Do Not Use Broken Cryptographic Algorithms
|
||||
#pragma warning disable CA5351
|
||||
using (var res = await _httpClient.SendAsync(
|
||||
new HttpRequestOptions
|
||||
@@ -350,7 +353,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var hash = ToHexString(md5.ComputeHash(stream));
|
||||
var hash = Hex.Encode(md5.ComputeHash(stream));
|
||||
if (!string.Equals(package.checksum, hash, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_logger.LogError(
|
||||
@@ -430,7 +433,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
/// <inheritdoc/>
|
||||
public bool CancelInstallation(Guid id)
|
||||
{
|
||||
lock (_currentInstallations)
|
||||
lock (_currentInstallationsLock)
|
||||
{
|
||||
var install = _currentInstallations.Find(x => x.info.Id == id);
|
||||
if (install == default((InstallationInfo, CancellationTokenSource)))
|
||||
@@ -459,7 +462,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
{
|
||||
if (dispose)
|
||||
{
|
||||
lock (_currentInstallations)
|
||||
lock (_currentInstallationsLock)
|
||||
{
|
||||
foreach (var tuple in _currentInstallations)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user