diff options
Diffstat (limited to 'Emby.Server.Implementations')
30 files changed, 340 insertions, 338 deletions
diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs index 4832c19c4..7ec5252d0 100644 --- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs +++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs @@ -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 { diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index bcd99ffe4..ac37cfe07 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -364,7 +364,7 @@ namespace Emby.Server.Implementations { _configuration = configuration; - XmlSerializer = new MyXmlSerializer(fileSystem, loggerFactory); + XmlSerializer = new MyXmlSerializer(); NetworkManager = networkManager; networkManager.LocalSubnetsFn = GetConfiguredLocalSubnets; @@ -912,7 +912,7 @@ namespace Emby.Server.Implementations _displayPreferencesRepository.Initialize(); - var userDataRepo = new SqliteUserDataRepository(LoggerFactory, ApplicationPaths); + var userDataRepo = new SqliteUserDataRepository(LoggerFactory.CreateLogger<SqliteUserDataRepository>(), ApplicationPaths); SetStaticProperties(); diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 8e5f5b561..22681fb49 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -470,7 +470,7 @@ namespace Emby.Server.Implementations.Channels _libraryManager.CreateItem(item, null); } - await item.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) + await item.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { ForceSave = !isNew && forceUpdate }, cancellationToken); @@ -1156,7 +1156,7 @@ namespace Emby.Server.Implementations.Channels if (isNew || forceUpdate || item.DateLastRefreshed == default(DateTime)) { - _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), RefreshPriority.Normal); + _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal); } return item; diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs index bb5057b1c..6d414be73 100644 --- a/Emby.Server.Implementations/Collections/CollectionManager.cs +++ b/Emby.Server.Implementations/Collections/CollectionManager.cs @@ -149,7 +149,7 @@ namespace Emby.Server.Implementations.Collections if (options.ItemIdList.Length > 0) { - AddToCollection(collection.Id, options.ItemIdList, false, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) + AddToCollection(collection.Id, options.ItemIdList, false, new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { // The initial adding of items is going to create a local metadata file // This will cause internet metadata to be skipped as a result @@ -158,7 +158,7 @@ namespace Emby.Server.Implementations.Collections } else { - _providerManager.QueueRefresh(collection.Id, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), RefreshPriority.High); + _providerManager.QueueRefresh(collection.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.High); } CollectionCreated?.Invoke(this, new CollectionCreatedEventArgs @@ -178,12 +178,12 @@ namespace Emby.Server.Implementations.Collections public void AddToCollection(Guid collectionId, IEnumerable<string> ids) { - AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem))); + AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem))); } public void AddToCollection(Guid collectionId, IEnumerable<Guid> ids) { - AddToCollection(collectionId, ids.Select(i => i.ToString("N", CultureInfo.InvariantCulture)), true, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem))); + AddToCollection(collectionId, ids.Select(i => i.ToString("N", CultureInfo.InvariantCulture)), true, new MetadataRefreshOptions(new DirectoryService(_fileSystem))); } private void AddToCollection(Guid collectionId, IEnumerable<string> ids, bool fireEvent, MetadataRefreshOptions refreshOptions) @@ -287,7 +287,7 @@ namespace Emby.Server.Implementations.Collections } collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None); - _providerManager.QueueRefresh(collection.Id, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) + _providerManager.QueueRefresh(collection.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { ForceSave = true }, RefreshPriority.High); diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs index 2cd4d65b3..2f6c1288d 100644 --- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs @@ -110,8 +110,8 @@ namespace Emby.Server.Implementations.Data using (var statement = connection.PrepareStatement("replace into userdisplaypreferences (id, userid, client, data) values (@id, @userId, @client, @data)")) { - statement.TryBind("@id", displayPreferences.Id.ToGuidBlob()); - statement.TryBind("@userId", userId.ToGuidBlob()); + statement.TryBind("@id", new Guid(displayPreferences.Id).ToByteArray()); + statement.TryBind("@userId", userId.ToByteArray()); statement.TryBind("@client", client); statement.TryBind("@data", serialized); @@ -170,8 +170,8 @@ namespace Emby.Server.Implementations.Data { using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where id = @id and userId=@userId and client=@client")) { - statement.TryBind("@id", guidId.ToGuidBlob()); - statement.TryBind("@userId", userId.ToGuidBlob()); + statement.TryBind("@id", guidId.ToByteArray()); + statement.TryBind("@userId", userId.ToByteArray()); statement.TryBind("@client", client); foreach (var row in statement.ExecuteQuery()) @@ -200,7 +200,7 @@ namespace Emby.Server.Implementations.Data using (var connection = GetConnection(true)) using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where userId=@userId")) { - statement.TryBind("@userId", userId.ToGuidBlob()); + statement.TryBind("@userId", userId.ToByteArray()); foreach (var row in statement.ExecuteQuery()) { diff --git a/Emby.Server.Implementations/Data/SqliteExtensions.cs b/Emby.Server.Implementations/Data/SqliteExtensions.cs index e7c394b54..c76ae0cac 100644 --- a/Emby.Server.Implementations/Data/SqliteExtensions.cs +++ b/Emby.Server.Implementations/Data/SqliteExtensions.cs @@ -9,6 +9,47 @@ namespace Emby.Server.Implementations.Data { public static class SqliteExtensions { + private const string DatetimeFormatUtc = "yyyy-MM-dd HH:mm:ss.FFFFFFFK"; + private const string DatetimeFormatLocal = "yyyy-MM-dd HH:mm:ss.FFFFFFF"; + + /// <summary> + /// An array of ISO-8601 DateTime formats that we support parsing. + /// </summary> + private static readonly string[] _datetimeFormats = new string[] + { + "THHmmssK", + "THHmmK", + "HH:mm:ss.FFFFFFFK", + "HH:mm:ssK", + "HH:mmK", + DatetimeFormatUtc, + "yyyy-MM-dd HH:mm:ssK", + "yyyy-MM-dd HH:mmK", + "yyyy-MM-ddTHH:mm:ss.FFFFFFFK", + "yyyy-MM-ddTHH:mmK", + "yyyy-MM-ddTHH:mm:ssK", + "yyyyMMddHHmmssK", + "yyyyMMddHHmmK", + "yyyyMMddTHHmmssFFFFFFFK", + "THHmmss", + "THHmm", + "HH:mm:ss.FFFFFFF", + "HH:mm:ss", + "HH:mm", + DatetimeFormatLocal, + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-dd HH:mm", + "yyyy-MM-ddTHH:mm:ss.FFFFFFF", + "yyyy-MM-ddTHH:mm", + "yyyy-MM-ddTHH:mm:ss", + "yyyyMMddHHmmss", + "yyyyMMddHHmm", + "yyyyMMddTHHmmssFFFFFFF", + "yyyy-MM-dd", + "yyyyMMdd", + "yy-MM-dd" + }; + public static void RunQueries(this SQLiteDatabaseConnection connection, string[] queries) { if (queries == null) @@ -22,16 +63,6 @@ namespace Emby.Server.Implementations.Data }); } - public static byte[] ToGuidBlob(this string str) - { - return ToGuidBlob(new Guid(str)); - } - - public static byte[] ToGuidBlob(this Guid guid) - { - return guid.ToByteArray(); - } - public static Guid ReadGuidFromBlob(this IResultSetValue result) { return new Guid(result.ToBlob()); @@ -50,58 +81,16 @@ namespace Emby.Server.Implementations.Data CultureInfo.InvariantCulture); } - private static string GetDateTimeKindFormat( - DateTimeKind kind) - { - return (kind == DateTimeKind.Utc) ? _datetimeFormatUtc : _datetimeFormatLocal; - } - - /// <summary> - /// An array of ISO-8601 DateTime formats that we support parsing. - /// </summary> - private static string[] _datetimeFormats = new string[] { - "THHmmssK", - "THHmmK", - "HH:mm:ss.FFFFFFFK", - "HH:mm:ssK", - "HH:mmK", - "yyyy-MM-dd HH:mm:ss.FFFFFFFK", /* NOTE: UTC default (5). */ - "yyyy-MM-dd HH:mm:ssK", - "yyyy-MM-dd HH:mmK", - "yyyy-MM-ddTHH:mm:ss.FFFFFFFK", - "yyyy-MM-ddTHH:mmK", - "yyyy-MM-ddTHH:mm:ssK", - "yyyyMMddHHmmssK", - "yyyyMMddHHmmK", - "yyyyMMddTHHmmssFFFFFFFK", - "THHmmss", - "THHmm", - "HH:mm:ss.FFFFFFF", - "HH:mm:ss", - "HH:mm", - "yyyy-MM-dd HH:mm:ss.FFFFFFF", /* NOTE: Non-UTC default (19). */ - "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd HH:mm", - "yyyy-MM-ddTHH:mm:ss.FFFFFFF", - "yyyy-MM-ddTHH:mm", - "yyyy-MM-ddTHH:mm:ss", - "yyyyMMddHHmmss", - "yyyyMMddHHmm", - "yyyyMMddTHHmmssFFFFFFF", - "yyyy-MM-dd", - "yyyyMMdd", - "yy-MM-dd" - }; - - private static string _datetimeFormatUtc = _datetimeFormats[5]; - private static string _datetimeFormatLocal = _datetimeFormats[19]; + private static string GetDateTimeKindFormat(DateTimeKind kind) + => (kind == DateTimeKind.Utc) ? DatetimeFormatUtc : DatetimeFormatLocal; public static DateTime ReadDateTime(this IResultSetValue result) { var dateText = result.ToString(); return DateTime.ParseExact( - dateText, _datetimeFormats, + dateText, + _datetimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None).ToUniversalTime(); } @@ -139,7 +128,10 @@ namespace Emby.Server.Implementations.Data public static void Attach(SQLiteDatabaseConnection db, string path, string alias) { - var commandText = string.Format("attach @path as {0};", alias); + var commandText = string.Format( + CultureInfo.InvariantCulture, + "attach @path as {0};", + alias); using (var statement = db.PrepareStatement(commandText)) { @@ -186,10 +178,7 @@ namespace Emby.Server.Implementations.Data private static void CheckName(string name) { #if DEBUG - //if (!name.IndexOf("@", StringComparison.OrdinalIgnoreCase) != 0) - { - throw new Exception("Invalid param name: " + name); - } + throw new ArgumentException("Invalid param name: " + name, nameof(name)); #endif } @@ -264,7 +253,7 @@ namespace Emby.Server.Implementations.Data { if (statement.BindParameters.TryGetValue(name, out IBindParameter bindParam)) { - bindParam.Bind(value.ToGuidBlob()); + bindParam.Bind(value.ToByteArray()); } else { @@ -392,8 +381,7 @@ namespace Emby.Server.Implementations.Data } } - public static IEnumerable<IReadOnlyList<IResultSetValue>> ExecuteQuery( - this IStatement This) + public static IEnumerable<IReadOnlyList<IResultSetValue>> ExecuteQuery(this IStatement This) { while (This.MoveNext()) { diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index d02aa9b1f..08f53f0f5 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -563,7 +563,7 @@ namespace Emby.Server.Implementations.Data { using (var saveImagesStatement = base.PrepareStatement(db, "Update TypedBaseItems set Images=@Images where guid=@Id")) { - saveImagesStatement.TryBind("@Id", item.Id.ToGuidBlob()); + saveImagesStatement.TryBind("@Id", item.Id.ToByteArray()); saveImagesStatement.TryBind("@Images", SerializeImages(item)); saveImagesStatement.MoveNext(); @@ -2003,7 +2003,7 @@ namespace Emby.Server.Implementations.Data throw new ArgumentNullException(nameof(chapters)); } - var idBlob = id.ToGuidBlob(); + var idBlob = id.ToByteArray(); using (var connection = GetConnection()) { @@ -3782,7 +3782,7 @@ namespace Emby.Server.Implementations.Data if (statement != null) { - statement.TryBind(paramName, personId.ToGuidBlob()); + statement.TryBind(paramName, personId.ToByteArray()); } index++; } @@ -3993,7 +3993,7 @@ namespace Emby.Server.Implementations.Data clauses.Add("(guid in (select itemid from itemvalues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type<=1))"); if (statement != null) { - statement.TryBind(paramName, artistId.ToGuidBlob()); + statement.TryBind(paramName, artistId.ToByteArray()); } index++; } @@ -4012,7 +4012,7 @@ namespace Emby.Server.Implementations.Data clauses.Add("(guid in (select itemid from itemvalues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type=1))"); if (statement != null) { - statement.TryBind(paramName, artistId.ToGuidBlob()); + statement.TryBind(paramName, artistId.ToByteArray()); } index++; } @@ -4031,7 +4031,7 @@ namespace Emby.Server.Implementations.Data clauses.Add("((select CleanName from TypedBaseItems where guid=" + paramName + ") in (select CleanValue from itemvalues where ItemId=Guid and Type=0) AND (select CleanName from TypedBaseItems where guid=" + paramName + ") not in (select CleanValue from itemvalues where ItemId=Guid and Type=1))"); if (statement != null) { - statement.TryBind(paramName, artistId.ToGuidBlob()); + statement.TryBind(paramName, artistId.ToByteArray()); } index++; } @@ -4050,7 +4050,7 @@ namespace Emby.Server.Implementations.Data clauses.Add("Album in (select Name from typedbaseitems where guid=" + paramName + ")"); if (statement != null) { - statement.TryBind(paramName, albumId.ToGuidBlob()); + statement.TryBind(paramName, albumId.ToByteArray()); } index++; } @@ -4069,7 +4069,7 @@ namespace Emby.Server.Implementations.Data clauses.Add("(guid not in (select itemid from itemvalues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type<=1))"); if (statement != null) { - statement.TryBind(paramName, artistId.ToGuidBlob()); + statement.TryBind(paramName, artistId.ToByteArray()); } index++; } @@ -4088,7 +4088,7 @@ namespace Emby.Server.Implementations.Data clauses.Add("(guid in (select itemid from itemvalues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type=2))"); if (statement != null) { - statement.TryBind(paramName, genreId.ToGuidBlob()); + statement.TryBind(paramName, genreId.ToByteArray()); } index++; } @@ -4159,7 +4159,7 @@ namespace Emby.Server.Implementations.Data if (statement != null) { - statement.TryBind(paramName, studioId.ToGuidBlob()); + statement.TryBind(paramName, studioId.ToByteArray()); } index++; } @@ -4935,7 +4935,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type { connection.RunInTransaction(db => { - var idBlob = id.ToGuidBlob(); + var idBlob = id.ToByteArray(); // Delete people ExecuteWithSingleParam(db, "delete from People where ItemId=@Id", idBlob); @@ -5054,7 +5054,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type whereClauses.Add("ItemId=@ItemId"); if (statement != null) { - statement.TryBind("@ItemId", query.ItemId.ToGuidBlob()); + statement.TryBind("@ItemId", query.ItemId.ToByteArray()); } } if (!query.AppearsInItemId.Equals(Guid.Empty)) @@ -5062,7 +5062,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type whereClauses.Add("Name in (Select Name from People where ItemId=@AppearsInItemId)"); if (statement != null) { - statement.TryBind("@AppearsInItemId", query.AppearsInItemId.ToGuidBlob()); + statement.TryBind("@AppearsInItemId", query.AppearsInItemId.ToByteArray()); } } var queryPersonTypes = query.PersonTypes.Where(IsValidPersonType).ToList(); @@ -5131,7 +5131,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type CheckDisposed(); - var itemIdBlob = itemId.ToGuidBlob(); + var itemIdBlob = itemId.ToByteArray(); // First delete deleteAncestorsStatement.Reset(); @@ -5165,7 +5165,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type var ancestorId = ancestorIds[i]; - statement.TryBind("@AncestorId" + index, ancestorId.ToGuidBlob()); + statement.TryBind("@AncestorId" + index, ancestorId.ToByteArray()); statement.TryBind("@AncestorIdText" + index, ancestorId.ToString("N", CultureInfo.InvariantCulture)); } @@ -5630,7 +5630,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type CheckDisposed(); - var guidBlob = itemId.ToGuidBlob(); + var guidBlob = itemId.ToByteArray(); // First delete db.Execute("delete from ItemValues where ItemId=@Id", guidBlob); @@ -5654,10 +5654,13 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type { if (isSubsequentRow) { - insertText.Append(","); + insertText.Append(','); } - insertText.AppendFormat("(@ItemId, @Type{0}, @Value{0}, @CleanValue{0})", i.ToString(CultureInfo.InvariantCulture)); + insertText.AppendFormat( + CultureInfo.InvariantCulture, + "(@ItemId, @Type{0}, @Value{0}, @CleanValue{0})", + i); isSubsequentRow = true; } @@ -5710,7 +5713,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type { connection.RunInTransaction(db => { - var itemIdBlob = itemId.ToGuidBlob(); + var itemIdBlob = itemId.ToByteArray(); // First delete chapters db.Execute("delete from People where ItemId=@ItemId", itemIdBlob); @@ -5829,7 +5832,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type using (var statement = PrepareStatement(connection, cmdText)) { - statement.TryBind("@ItemId", query.ItemId.ToGuidBlob()); + statement.TryBind("@ItemId", query.ItemId.ToByteArray()); if (query.Type.HasValue) { @@ -5871,7 +5874,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type { connection.RunInTransaction(db => { - var itemIdBlob = id.ToGuidBlob(); + var itemIdBlob = id.ToByteArray(); // First delete chapters db.Execute("delete from mediastreams where ItemId=@ItemId", itemIdBlob); diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs index 9d4855bcf..26ac17bdc 100644 --- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Threading; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; @@ -15,23 +14,19 @@ namespace Emby.Server.Implementations.Data public class SqliteUserDataRepository : BaseSqliteRepository, IUserDataRepository { public SqliteUserDataRepository( - ILoggerFactory loggerFactory, + ILogger<SqliteUserDataRepository> logger, IApplicationPaths appPaths) - : base(loggerFactory.CreateLogger(nameof(SqliteUserDataRepository))) + : base(logger) { DbFilePath = Path.Combine(appPaths.DataPath, "library.db"); } - /// <summary> - /// Gets the name of the repository - /// </summary> - /// <value>The name.</value> + /// <inheritdoc /> public string Name => "SQLite"; /// <summary> - /// Opens the connection to the database + /// Opens the connection to the database. /// </summary> - /// <returns>Task.</returns> public void Initialize(IUserManager userManager, SemaphoreSlim dbLock, SQLiteDatabaseConnection dbConnection) { WriteLock.Dispose(); @@ -97,7 +92,7 @@ namespace Emby.Server.Implementations.Data continue; } - statement.TryBind("@UserId", user.Id.ToGuidBlob()); + statement.TryBind("@UserId", user.Id.ToByteArray()); statement.TryBind("@InternalUserId", user.InternalId); statement.MoveNext(); diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs index 80fe278f8..26798993b 100644 --- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserRepository.cs @@ -116,7 +116,7 @@ namespace Emby.Server.Implementations.Data { using (var statement = db.PrepareStatement("insert into LocalUsersv2 (guid, data) values (@guid, @data)")) { - statement.TryBind("@guid", user.Id.ToGuidBlob()); + statement.TryBind("@guid", user.Id.ToByteArray()); statement.TryBind("@data", serialized); statement.MoveNext(); diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index ea4444268..d6ca19e3f 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -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' "> diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index f26a70586..d55dc2f18 100644 --- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -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)) { diff --git a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs index b2328121e..3a7516dca 100644 --- a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs +++ b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs @@ -54,7 +54,7 @@ namespace Emby.Server.Implementations.EntryPoints { cancellationToken.ThrowIfCancellationRequested(); - await user.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), cancellationToken).ConfigureAwait(false); + await user.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem)), cancellationToken).ConfigureAwait(false); } } diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index e4f98acb9..cd2a7dcf0 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -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) diff --git a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs index c95b00ede..85110c21c 100644 --- a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs +++ b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs @@ -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> diff --git a/Emby.Server.Implementations/Library/InvalidAuthProvider.cs b/Emby.Server.Implementations/Library/InvalidAuthProvider.cs index 6956369dc..7913df5e4 100644 --- a/Emby.Server.Implementations/Library/InvalidAuthProvider.cs +++ b/Emby.Server.Implementations/Library/InvalidAuthProvider.cs @@ -1,7 +1,6 @@ using System.Threading.Tasks; using MediaBrowser.Controller.Authentication; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Net; namespace Emby.Server.Implementations.Library { diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 87e951f25..13857c1e8 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -519,7 +519,7 @@ namespace Emby.Server.Implementations.Library } public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null) - => ResolvePath(fileInfo, new DirectoryService(_logger, _fileSystem), null, parent); + => ResolvePath(fileInfo, new DirectoryService(_fileSystem), null, parent); private BaseItem ResolvePath( FileSystemMetadata fileInfo, @@ -1045,7 +1045,7 @@ namespace Emby.Server.Implementations.Library await RootFolder.ValidateChildren( new SimpleProgress<double>(), cancellationToken, - new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), + new MetadataRefreshOptions(new DirectoryService(_fileSystem)), recursive: false).ConfigureAwait(false); await GetUserRootFolder().RefreshMetadata(cancellationToken).ConfigureAwait(false); @@ -1053,7 +1053,7 @@ namespace Emby.Server.Implementations.Library await GetUserRootFolder().ValidateChildren( new SimpleProgress<double>(), cancellationToken, - new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), + new MetadataRefreshOptions(new DirectoryService(_fileSystem)), recursive: false).ConfigureAwait(false); // Quickly scan CollectionFolders for changes @@ -1074,7 +1074,7 @@ namespace Emby.Server.Implementations.Library innerProgress.RegisterAction(pct => progress.Report(pct * .96)); // Now validate the entire media library - await RootFolder.ValidateChildren(innerProgress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), recursive: true).ConfigureAwait(false); + await RootFolder.ValidateChildren(innerProgress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), recursive: true).ConfigureAwait(false); progress.Report(96); @@ -2135,7 +2135,7 @@ namespace Emby.Server.Implementations.Library if (refresh) { item.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None); - _providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), RefreshPriority.Normal); + _providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal); } return item; @@ -2193,7 +2193,7 @@ namespace Emby.Server.Implementations.Library { _providerManagerFactory().QueueRefresh( item.Id, - new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { // Need to force save to increment DateLastSaved ForceSave = true @@ -2261,7 +2261,7 @@ namespace Emby.Server.Implementations.Library { _providerManagerFactory().QueueRefresh( item.Id, - new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { // Need to force save to increment DateLastSaved ForceSave = true @@ -2338,7 +2338,7 @@ namespace Emby.Server.Implementations.Library { _providerManagerFactory().QueueRefresh( item.Id, - new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { // Need to force save to increment DateLastSaved ForceSave = true diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index e069ebd17..2e24b847b 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -160,12 +160,13 @@ namespace Emby.Server.Implementations.Library if (allowMediaProbe && mediaSources[0].Type != MediaSourceType.Placeholder && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Audio || i.Type == MediaStreamType.Video)) { - await item.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) - { - EnableRemoteContentProbe = true, - MetadataRefreshMode = MediaBrowser.Controller.Providers.MetadataRefreshMode.FullRefresh - - }, cancellationToken).ConfigureAwait(false); + await item.RefreshMetadata( + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) + { + EnableRemoteContentProbe = true, + MetadataRefreshMode = MetadataRefreshMode.FullRefresh + }, + cancellationToken).ConfigureAwait(false); mediaSources = GetStaticMediaSources(item, enablePathSubstitution, user); } diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index 52b2f56ff..60d16c8a0 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -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) @@ -639,7 +639,7 @@ namespace Emby.Server.Implementations.Library { foreach (var user in Users) { - await user.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)), cancellationToken).ConfigureAwait(false); + await user.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem)), cancellationToken).ConfigureAwait(false); } } diff --git a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs index d00c6cde1..137a010ec 100644 --- a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -11,16 +11,17 @@ using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Library.Validators { /// <summary> - /// Class PeopleValidator + /// Class PeopleValidator. /// </summary> public class PeopleValidator { /// <summary> - /// The _library manager + /// The _library manager. /// </summary> private readonly ILibraryManager _libraryManager; + /// <summary> - /// The _logger + /// The _logger. /// </summary> private readonly ILogger _logger; @@ -62,7 +63,7 @@ namespace Emby.Server.Implementations.Library.Validators { var item = _libraryManager.GetPerson(person); - var options = new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) + var options = new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { ImageRefreshMode = MetadataRefreshMode.ValidationOnly, MetadataRefreshMode = MetadataRefreshMode.ValidationOnly @@ -96,12 +97,19 @@ namespace Emby.Server.Implementations.Library.Validators foreach (var item in deadEntities) { - _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name, item.GetType().Name); - - _libraryManager.DeleteItem(item, new DeleteOptions - { - DeleteFileLocation = false - }, false); + _logger.LogInformation( + "Deleting dead {2} {0} {1}.", + item.Id.ToString("N", CultureInfo.InvariantCulture), + item.Name, + item.GetType().Name); + + _libraryManager.DeleteItem( + item, + new DeleteOptions + { + DeleteFileLocation = false + }, + false); } progress.Report(100); diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index da0013f12..687a178a6 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1489,16 +1489,18 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { _logger.LogInformation("Refreshing recording parent {path}", item.Path); - _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) - { - RefreshPaths = new string[] + _providerManager.QueueRefresh( + item.Id, + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { - path, - Path.GetDirectoryName(path), - Path.GetDirectoryName(Path.GetDirectoryName(path)) - } - - }, RefreshPriority.High); + RefreshPaths = new string[] + { + path, + Path.GetDirectoryName(path), + Path.GetDirectoryName(Path.GetDirectoryName(path)) + } + }, + RefreshPriority.High); } } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 89b92c999..d4bd598e3 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1226,12 +1226,13 @@ namespace Emby.Server.Implementations.LiveTv currentChannel.AddTag("Kids"); } - //currentChannel.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken); - await currentChannel.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) - { - ForceSave = true - - }, cancellationToken).ConfigureAwait(false); + currentChannel.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken); + await currentChannel.RefreshMetadata( + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) + { + ForceSave = true + }, + cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -1245,7 +1246,7 @@ namespace Emby.Server.Implementations.LiveTv numComplete++; double percent = numComplete / (double)allChannelsList.Count; - progress.Report(85 * percent + 15); + progress.Report((85 * percent) + 15); } progress.Report(100); @@ -1278,12 +1279,14 @@ namespace Emby.Server.Implementations.LiveTv if (item != null) { - _libraryManager.DeleteItem(item, new DeleteOptions - { - DeleteFileLocation = false, - DeleteFromExternalProvider = false - - }, false); + _libraryManager.DeleteItem( + item, + new DeleteOptions + { + DeleteFileLocation = false, + DeleteFromExternalProvider = false + }, + false); } } @@ -2301,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); diff --git a/Emby.Server.Implementations/Localization/Core/fr.json b/Emby.Server.Implementations/Localization/Core/fr.json index 6bfedb712..9805992be 100644 --- a/Emby.Server.Implementations/Localization/Core/fr.json +++ b/Emby.Server.Implementations/Localization/Core/fr.json @@ -5,7 +5,7 @@ "Artists": "Artistes", "AuthenticationSucceededWithUserName": "{0} s'est authentifié avec succès", "Books": "Livres", - "CameraImageUploadedFrom": "Une image de caméra a été chargée depuis {0}", + "CameraImageUploadedFrom": "Une nouvelle image de caméra a été chargée depuis {0}", "Channels": "Chaînes", "ChapterNameValue": "Chapitre {0}", "Collections": "Collections", @@ -17,7 +17,7 @@ "Genres": "Genres", "HeaderAlbumArtists": "Artistes de l'album", "HeaderCameraUploads": "Photos transférées", - "HeaderContinueWatching": "Reprendre", + "HeaderContinueWatching": "Continuer à regarder", "HeaderFavoriteAlbums": "Albums favoris", "HeaderFavoriteArtists": "Artistes favoris", "HeaderFavoriteEpisodes": "Épisodes favoris", @@ -34,14 +34,14 @@ "LabelRunningTimeValue": "Durée : {0}", "Latest": "Derniers", "MessageApplicationUpdated": "Le serveur Jellyfin a été mis à jour", - "MessageApplicationUpdatedTo": "Jellyfin Serveur a été mis à jour en version {0}", + "MessageApplicationUpdatedTo": "Le serveur Jellyfin a été mis à jour vers {0}", "MessageNamedServerConfigurationUpdatedWithValue": "La configuration de la section {0} du serveur a été mise à jour", "MessageServerConfigurationUpdated": "La configuration du serveur a été mise à jour", "MixedContent": "Contenu mixte", "Movies": "Films", "Music": "Musique", "MusicVideos": "Vidéos musicales", - "NameInstallFailed": "{0} échec d'installation", + "NameInstallFailed": "{0} échec de l'installation", "NameSeasonNumber": "Saison {0}", "NameSeasonUnknown": "Saison Inconnue", "NewVersionIsAvailable": "Une nouvelle version de Jellyfin Serveur est disponible au téléchargement.", @@ -50,7 +50,7 @@ "NotificationOptionAudioPlayback": "Lecture audio démarrée", "NotificationOptionAudioPlaybackStopped": "Lecture audio arrêtée", "NotificationOptionCameraImageUploaded": "L'image de l'appareil photo a été transférée", - "NotificationOptionInstallationFailed": "Échec d'installation", + "NotificationOptionInstallationFailed": "Échec de l'installation", "NotificationOptionNewLibraryContent": "Nouveau contenu ajouté", "NotificationOptionPluginError": "Erreur d'extension", "NotificationOptionPluginInstalled": "Extension installée", @@ -91,7 +91,7 @@ "UserPolicyUpdatedWithName": "La politique de l'utilisateur a été mise à jour pour {0}", "UserStartedPlayingItemWithValues": "{0} est en train de lire {1} sur {2}", "UserStoppedPlayingItemWithValues": "{0} vient d'arrêter la lecture de {1} sur {2}", - "ValueHasBeenAddedToLibrary": "{0} a été ajouté à votre librairie", + "ValueHasBeenAddedToLibrary": "{0} a été ajouté à votre médiathèque", "ValueSpecialEpisodeName": "Spécial - {0}", "VersionNumber": "Version {0}" } diff --git a/Emby.Server.Implementations/Localization/Core/hu.json b/Emby.Server.Implementations/Localization/Core/hu.json index a2fc126a2..3a6852321 100644 --- a/Emby.Server.Implementations/Localization/Core/hu.json +++ b/Emby.Server.Implementations/Localization/Core/hu.json @@ -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", diff --git a/Emby.Server.Implementations/Localization/Core/tr.json b/Emby.Server.Implementations/Localization/Core/tr.json index 3cc95e46e..3b5ce29c7 100644 --- a/Emby.Server.Implementations/Localization/Core/tr.json +++ b/Emby.Server.Implementations/Localization/Core/tr.json @@ -5,26 +5,26 @@ "Artists": "Sanatçılar", "AuthenticationSucceededWithUserName": "{0} kimlik başarıyla doğrulandı", "Books": "Kitaplar", - "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}", + "CameraImageUploadedFrom": "{0} 'den yeni bir kamera resmi yüklendi", "Channels": "Kanallar", - "ChapterNameValue": "Chapter {0}", - "Collections": "Collections", - "DeviceOfflineWithName": "{0} has disconnected", - "DeviceOnlineWithName": "{0} is connected", - "FailedLoginAttemptWithUserName": "Failed login attempt from {0}", - "Favorites": "Favorites", - "Folders": "Folders", - "Genres": "Genres", - "HeaderAlbumArtists": "Album Artists", - "HeaderCameraUploads": "Camera Uploads", + "ChapterNameValue": "Bölüm {0}", + "Collections": "Koleksiyonlar", + "DeviceOfflineWithName": "{0} bağlantısı kesildi", + "DeviceOnlineWithName": "{0} bağlı", + "FailedLoginAttemptWithUserName": "{0} adresinden giriş başarısız oldu", + "Favorites": "Favoriler", + "Folders": "Klasörler", + "Genres": "Türler", + "HeaderAlbumArtists": "Albüm Sanatçıları", + "HeaderCameraUploads": "Kamera Yüklemeleri", "HeaderContinueWatching": "İzlemeye Devam Et", "HeaderFavoriteAlbums": "Favori Albümler", - "HeaderFavoriteArtists": "Favorite Artists", - "HeaderFavoriteEpisodes": "Favorite Episodes", - "HeaderFavoriteShows": "Favori Showlar", - "HeaderFavoriteSongs": "Favorite Songs", - "HeaderLiveTV": "Live TV", - "HeaderNextUp": "Next Up", + "HeaderFavoriteArtists": "Favori Sanatçılar", + "HeaderFavoriteEpisodes": "Favori Bölümler", + "HeaderFavoriteShows": "Favori Diziler", + "HeaderFavoriteSongs": "Favori Şarkılar", + "HeaderLiveTV": "Canlı TV", + "HeaderNextUp": "Sonraki hafta", "HeaderRecordingGroups": "Recording Groups", "HomeVideos": "Home videos", "Inherit": "Inherit", @@ -38,7 +38,7 @@ "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated", "MessageServerConfigurationUpdated": "Server configuration has been updated", "MixedContent": "Mixed content", - "Movies": "Movies", + "Movies": "Filmler", "Music": "Müzik", "MusicVideos": "Müzik videoları", "NameInstallFailed": "{0} kurulum başarısız", @@ -61,8 +61,8 @@ "NotificationOptionUserLockedOut": "User locked out", "NotificationOptionVideoPlayback": "Video playback started", "NotificationOptionVideoPlaybackStopped": "Video playback stopped", - "Photos": "Photos", - "Playlists": "Playlists", + "Photos": "Fotoğraflar", + "Playlists": "Çalma listeleri", "Plugin": "Plugin", "PluginInstalledWithName": "{0} was installed", "PluginUninstalledWithName": "{0} was uninstalled", @@ -71,13 +71,13 @@ "ScheduledTaskFailedWithName": "{0} failed", "ScheduledTaskStartedWithName": "{0} started", "ServerNameNeedsToBeRestarted": "{0} needs to be restarted", - "Shows": "Shows", - "Songs": "Songs", + "Shows": "Diziler", + "Songs": "Şarkılar", "StartupEmbyServerIsLoading": "Jellyfin Server is loading. Please try again shortly.", "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}", "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}", "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}", - "Sync": "Sync", + "Sync": "Eşitle", "System": "System", "TvShows": "TV Shows", "User": "User", @@ -92,6 +92,6 @@ "UserStartedPlayingItemWithValues": "{0} is playing {1} on {2}", "UserStoppedPlayingItemWithValues": "{0} has finished playing {1} on {2}", "ValueHasBeenAddedToLibrary": "{0} has been added to your media library", - "ValueSpecialEpisodeName": "Special - {0}", + "ValueSpecialEpisodeName": "Özel -{0}", "VersionNumber": "Version {0}" } diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 7d85a0666..d948dad68 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -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++; } diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs index 40b568b40..0f58e43ed 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -90,8 +90,7 @@ namespace Emby.Server.Implementations.Playlists } else { - var folder = item as Folder; - if (folder != null) + if (item is Folder folder) { options.MediaType = folder.GetRecursiveChildren(i => !i.IsFolder && i.SupportsAddingToPlaylist) .Select(i => i.MediaType) @@ -140,7 +139,7 @@ namespace Emby.Server.Implementations.Playlists parentFolder.AddChild(playlist, CancellationToken.None); - await playlist.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) { ForceSave = true }, CancellationToken.None) + await playlist.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { ForceSave = true }, CancellationToken.None) .ConfigureAwait(false); if (options.ItemIdList.Length > 0) @@ -201,7 +200,7 @@ namespace Emby.Server.Implementations.Playlists var list = new List<LinkedChild>(); - var items = (GetPlaylistItems(itemIds, playlist.MediaType, user, options)) + var items = GetPlaylistItems(itemIds, playlist.MediaType, user, options) .Where(i => i.SupportsAddingToPlaylist) .ToList(); @@ -221,18 +220,18 @@ namespace Emby.Server.Implementations.Playlists SavePlaylistFile(playlist); } - _providerManager.QueueRefresh(playlist.Id, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) - { - ForceSave = true - - }, RefreshPriority.High); + _providerManager.QueueRefresh( + playlist.Id, + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) + { + ForceSave = true + }, + RefreshPriority.High); } public void RemoveFromPlaylist(string playlistId, IEnumerable<string> entryIds) { - var playlist = _libraryManager.GetItemById(playlistId) as Playlist; - - if (playlist == null) + if (!(_libraryManager.GetItemById(playlistId) is Playlist playlist)) { throw new ArgumentException("No Playlist exists with the supplied Id"); } @@ -254,7 +253,7 @@ namespace Emby.Server.Implementations.Playlists SavePlaylistFile(playlist); } - _providerManager.QueueRefresh(playlist.Id, new MetadataRefreshOptions(new DirectoryService(_logger, _fileSystem)) + _providerManager.QueueRefresh(playlist.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { ForceSave = true @@ -263,9 +262,7 @@ namespace Emby.Server.Implementations.Playlists public void MoveItem(string playlistId, string entryId, int newIndex) { - var playlist = _libraryManager.GetItemById(playlistId) as Playlist; - - if (playlist == null) + if (!(_libraryManager.GetItemById(playlistId) is Playlist playlist)) { throw new ArgumentException("No Playlist exists with the supplied Id"); } diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs index 2f07ff15a..ecd526251 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs @@ -19,16 +19,17 @@ using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.ScheduledTasks { /// <summary> - /// Class ChapterImagesTask + /// Class ChapterImagesTask. /// </summary> public class ChapterImagesTask : IScheduledTask { /// <summary> - /// The _logger + /// The _logger. /// </summary> private readonly ILogger _logger; + /// <summary> - /// The _library manager + /// The _library manager. /// </summary> private readonly ILibraryManager _libraryManager; @@ -53,12 +54,12 @@ namespace Emby.Server.Implementations.ScheduledTasks } /// <summary> - /// Creates the triggers that define when the task will run + /// Creates the triggers that define when the task will run. /// </summary> public IEnumerable<TaskTriggerInfo> GetDefaultTriggers() { - return new[] { - + return new[] + { new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerDaily, @@ -117,7 +118,7 @@ namespace Emby.Server.Implementations.ScheduledTasks previouslyFailedImages = new List<string>(); } - var directoryService = new DirectoryService(_logger, _fileSystem); + var directoryService = new DirectoryService(_fileSystem); foreach (var video in videos) { diff --git a/Emby.Server.Implementations/Serialization/XmlSerializer.cs b/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs index 6400ec16e..296822981 100644 --- a/Emby.Server.Implementations/Serialization/XmlSerializer.cs +++ b/Emby.Server.Implementations/Serialization/MyXmlSerializer.cs @@ -1,11 +1,9 @@ using System; -using System.Collections.Generic; +using System.Collections.Concurrent; using System.IO; using System.Xml; using System.Xml.Serialization; -using MediaBrowser.Model.IO; using MediaBrowser.Model.Serialization; -using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Serialization { @@ -14,35 +12,13 @@ namespace Emby.Server.Implementations.Serialization /// </summary> public class MyXmlSerializer : IXmlSerializer { - private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; - - public MyXmlSerializer( - IFileSystem fileSystem, - ILoggerFactory loggerFactory) - { - _fileSystem = fileSystem; - _logger = loggerFactory.CreateLogger("XmlSerializer"); - } - // Need to cache these // http://dotnetcodebox.blogspot.com/2013/01/xmlserializer-class-may-result-in.html - private readonly Dictionary<string, XmlSerializer> _serializers = - new Dictionary<string, XmlSerializer>(); + private static readonly ConcurrentDictionary<string, XmlSerializer> _serializers = + new ConcurrentDictionary<string, XmlSerializer>(); - private XmlSerializer GetSerializer(Type type) - { - var key = type.FullName; - lock (_serializers) - { - if (!_serializers.TryGetValue(key, out var serializer)) - { - serializer = new XmlSerializer(type); - _serializers[key] = serializer; - } - return serializer; - } - } + private static XmlSerializer GetSerializer(Type type) + => _serializers.GetOrAdd(type.FullName, _ => new XmlSerializer(type)); /// <summary> /// Serializes to writer. @@ -91,7 +67,6 @@ namespace Emby.Server.Implementations.Serialization /// <param name="file">The file.</param> public void SerializeToFile(object obj, string file) { - _logger.LogDebug("Serializing to file {0}", file); using (var stream = new FileStream(file, FileMode.Create)) { SerializeToStream(obj, stream); @@ -106,7 +81,6 @@ namespace Emby.Server.Implementations.Serialization /// <returns>System.Object.</returns> public object DeserializeFromFile(Type type, string file) { - _logger.LogDebug("Deserializing file {0}", file); using (var stream = File.OpenRead(file)) { return DeserializeFromStream(type, stream); diff --git a/Emby.Server.Implementations/ServerApplicationPaths.cs b/Emby.Server.Implementations/ServerApplicationPaths.cs index 2f5a8af80..46195cc74 100644 --- a/Emby.Server.Implementations/ServerApplicationPaths.cs +++ b/Emby.Server.Implementations/ServerApplicationPaths.cs @@ -6,7 +6,7 @@ using MediaBrowser.Controller; namespace Emby.Server.Implementations { /// <summary> - /// Extends BaseApplicationPaths to add paths that are only applicable on the server + /// Extends BaseApplicationPaths to add paths that are only applicable on the server. /// </summary> public class ServerApplicationPaths : BaseApplicationPaths, IServerApplicationPaths { diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 0c0c77cda..2de20829c 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; @@ -19,7 +18,6 @@ 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 { @@ -28,43 +26,10 @@ namespace Emby.Server.Implementations.Updates /// </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 +44,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 +84,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; + /// <summary> /// Gets all available packages. /// </summary> @@ -330,7 +332,7 @@ namespace Emby.Server.Implementations.Updates var tuple = (installationInfo, innerCancellationTokenSource); // Add it to the in-progress list - lock (_currentInstallations) + lock (_currentInstallationsLock) { _currentInstallations.Add(tuple); } @@ -349,7 +351,7 @@ namespace Emby.Server.Implementations.Updates { await InstallPackageInternal(package, linkedToken).ConfigureAwait(false); - lock (_currentInstallations) + lock (_currentInstallationsLock) { _currentInstallations.Remove(tuple); } @@ -360,7 +362,7 @@ namespace Emby.Server.Implementations.Updates } catch (OperationCanceledException) { - lock (_currentInstallations) + lock (_currentInstallationsLock) { _currentInstallations.Remove(tuple); } @@ -375,7 +377,7 @@ namespace Emby.Server.Implementations.Updates { _logger.LogError(ex, "Package installation failed"); - lock (_currentInstallations) + lock (_currentInstallationsLock) { _currentInstallations.Remove(tuple); } @@ -455,7 +457,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( @@ -535,7 +537,7 @@ namespace Emby.Server.Implementations.Updates /// <inheritdoc/> public bool CancelInstallation(Guid id) { - lock (_currentInstallations) + lock (_currentInstallationsLock) { var install = _currentInstallations.Find(x => x.Item1.Id == id); if (install == default((InstallationInfo, CancellationTokenSource))) @@ -563,7 +565,7 @@ namespace Emby.Server.Implementations.Updates { if (dispose) { - lock (_currentInstallations) + lock (_currentInstallationsLock) { foreach (var tuple in _currentInstallations) { |
