aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
authorGary Wilber <Spacetech326@gmail.com>2020-11-19 18:44:16 -0800
committerGary Wilber <Spacetech326@gmail.com>2020-11-19 18:44:16 -0800
commit4a22380565bbf5909ad064461ae9cb59a410a063 (patch)
tree6bbc22a8979d6544f2d373413f7f75255945e9a3 /Emby.Server.Implementations
parentd6585e7ff2e14234201e3fe6a75a5af2170c7804 (diff)
parent90e4066b12e3b39124f9f4efcb20a0e51499a038 (diff)
Merge remote-tracking branch 'upstream/master' into library_scan_speed
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs27
-rw-r--r--Emby.Server.Implementations/AppBase/ConfigurationHelper.cs6
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs80
-rw-r--r--Emby.Server.Implementations/Cryptography/CryptographyProvider.cs3
-rw-r--r--Emby.Server.Implementations/Data/SqliteExtensions.cs14
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs52
-rw-r--r--Emby.Server.Implementations/Dto/DtoService.cs2
-rw-r--r--Emby.Server.Implementations/Emby.Server.Implementations.csproj16
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs6
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs14
-rw-r--r--Emby.Server.Implementations/Library/MediaSourceManager.cs2
-rw-r--r--Emby.Server.Implementations/Library/MediaStreamSelector.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs7
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs13
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs36
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs4
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs10
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs10
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs2
-rw-r--r--Emby.Server.Implementations/Localization/Core/cs.json5
-rw-r--r--Emby.Server.Implementations/Localization/Core/de.json5
-rw-r--r--Emby.Server.Implementations/Localization/Core/en-GB.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/en-US.json3
-rw-r--r--Emby.Server.Implementations/Localization/Core/es-AR.json7
-rw-r--r--Emby.Server.Implementations/Localization/Core/es.json7
-rw-r--r--Emby.Server.Implementations/Localization/Core/fil.json29
-rw-r--r--Emby.Server.Implementations/Localization/Core/fr.json5
-rw-r--r--Emby.Server.Implementations/Localization/Core/he.json7
-rw-r--r--Emby.Server.Implementations/Localization/Core/hu.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/nb.json6
-rw-r--r--Emby.Server.Implementations/Localization/Core/nl.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/pl.json7
-rw-r--r--Emby.Server.Implementations/Localization/Core/pt-BR.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/ro.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/sr.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/ta.json7
-rw-r--r--Emby.Server.Implementations/Localization/Core/vi.json7
-rw-r--r--Emby.Server.Implementations/Localization/Core/zh-CN.json5
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs2
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/TaskManager.cs4
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs2
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs3
-rw-r--r--Emby.Server.Implementations/Session/WebSocketController.cs5
-rw-r--r--Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs2
-rw-r--r--Emby.Server.Implementations/Updates/InstallationManager.cs12
49 files changed, 301 insertions, 167 deletions
diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
index 4ab0a2a3f..4f72c8ce1 100644
--- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
+++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
@@ -134,6 +134,33 @@ namespace Emby.Server.Implementations.AppBase
}
/// <summary>
+ /// Manually pre-loads a factory so that it is available pre system initialisation.
+ /// </summary>
+ /// <typeparam name="T">Class to register.</typeparam>
+ public virtual void RegisterConfiguration<T>()
+ where T : IConfigurationFactory
+ {
+ IConfigurationFactory factory = Activator.CreateInstance<T>();
+
+ if (_configurationFactories == null)
+ {
+ _configurationFactories = new[] { factory };
+ }
+ else
+ {
+ var oldLen = _configurationFactories.Length;
+ var arr = new IConfigurationFactory[oldLen + 1];
+ _configurationFactories.CopyTo(arr, 0);
+ arr[oldLen] = factory;
+ _configurationFactories = arr;
+ }
+
+ _configurationStores = _configurationFactories
+ .SelectMany(i => i.GetConfigurations())
+ .ToArray();
+ }
+
+ /// <summary>
/// Adds parts.
/// </summary>
/// <param name="factories">The configuration factories.</param>
diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs
index 4c9ab33a7..77819c764 100644
--- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs
+++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs
@@ -3,6 +3,7 @@
using System;
using System.IO;
using System.Linq;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Model.Serialization;
namespace Emby.Server.Implementations.AppBase
@@ -35,7 +36,7 @@ namespace Emby.Server.Implementations.AppBase
}
catch (Exception)
{
- configuration = Activator.CreateInstance(type);
+ configuration = Activator.CreateInstance(type) ?? throw new ArgumentException($"Provided path ({type}) is not valid.", nameof(type));
}
using var stream = new MemoryStream(buffer?.Length ?? 0);
@@ -48,8 +49,9 @@ namespace Emby.Server.Implementations.AppBase
// If the file didn't exist before, or if something has changed, re-save
if (buffer == null || !newBytes.AsSpan(0, newBytesLen).SequenceEqual(buffer))
{
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ var directory = Path.GetDirectoryName(path) ?? throw new ArgumentException($"Provided path ({path}) is not valid.", nameof(path));
+ Directory.CreateDirectory(directory);
// Save it after load in case we got new items
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
{
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 9d5b651d9..5d47d1e40 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -94,7 +94,6 @@ using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Providers.Chapters;
using MediaBrowser.Providers.Manager;
-using MediaBrowser.Providers.Plugins.TheTvdb;
using MediaBrowser.Providers.Plugins.Tmdb;
using MediaBrowser.Providers.Subtitles;
using MediaBrowser.XbmcMetadata.Providers;
@@ -126,7 +125,6 @@ namespace Emby.Server.Implementations
private IMediaEncoder _mediaEncoder;
private ISessionManager _sessionManager;
private IHttpClientFactory _httpClientFactory;
-
private string[] _urlPrefixes;
/// <summary>
@@ -497,24 +495,11 @@ namespace Emby.Server.Implementations
HttpsPort = ServerConfiguration.DefaultHttpsPort;
}
- if (Plugins != null)
- {
- var pluginBuilder = new StringBuilder();
-
- foreach (var plugin in Plugins)
- {
- pluginBuilder.Append(plugin.Name)
- .Append(' ')
- .Append(plugin.Version)
- .AppendLine();
- }
-
- Logger.LogInformation("Plugins: {Plugins}", pluginBuilder.ToString());
- }
-
DiscoverTypes();
RegisterServices();
+
+ RegisterPluginServices();
}
/// <summary>
@@ -534,7 +519,6 @@ namespace Emby.Server.Implementations
ServiceCollection.AddSingleton<IJsonSerializer, JsonSerializer>();
ServiceCollection.AddSingleton(_fileSystemManager);
- ServiceCollection.AddSingleton<TvdbClientManager>();
ServiceCollection.AddSingleton<TmdbClientManager>();
ServiceCollection.AddSingleton(_networkManager);
@@ -779,10 +763,24 @@ namespace Emby.Server.Implementations
ConfigurationManager.AddParts(GetExports<IConfigurationFactory>());
_plugins = GetExports<IPlugin>()
- .Select(LoadPlugin)
.Where(i => i != null)
.ToArray();
+ if (Plugins != null)
+ {
+ var pluginBuilder = new StringBuilder();
+
+ foreach (var plugin in Plugins)
+ {
+ pluginBuilder.Append(plugin.Name)
+ .Append(' ')
+ .Append(plugin.Version)
+ .AppendLine();
+ }
+
+ Logger.LogInformation("Plugins: {Plugins}", pluginBuilder.ToString());
+ }
+
_urlPrefixes = GetUrlPrefixes().ToArray();
Resolve<ILibraryManager>().AddParts(
@@ -812,21 +810,6 @@ namespace Emby.Server.Implementations
Resolve<IIsoManager>().AddParts(GetExports<IIsoMounter>());
}
- private IPlugin LoadPlugin(IPlugin plugin)
- {
- try
- {
- plugin.RegisterServices(ServiceCollection);
- }
- catch (Exception ex)
- {
- Logger.LogError(ex, "Error loading plugin {PluginName}", plugin.GetType().FullName);
- return null;
- }
-
- return plugin;
- }
-
/// <summary>
/// Discovers the types.
/// </summary>
@@ -837,6 +820,22 @@ namespace Emby.Server.Implementations
_allConcreteTypes = GetTypes(GetComposablePartAssemblies()).ToArray();
}
+ private void RegisterPluginServices()
+ {
+ foreach (var pluginServiceRegistrator in GetExportTypes<IPluginServiceRegistrator>())
+ {
+ try
+ {
+ var instance = (IPluginServiceRegistrator)Activator.CreateInstance(pluginServiceRegistrator);
+ instance.RegisterServices(ServiceCollection);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError(ex, "Error registering plugin services from {Assembly}.", pluginServiceRegistrator.Assembly);
+ }
+ }
+ }
+
private IEnumerable<Type> GetTypes(IEnumerable<Assembly> assemblies)
{
foreach (var ass in assemblies)
@@ -996,6 +995,12 @@ namespace Emby.Server.Implementations
{
var minimumVersion = new Version(0, 0, 0, 1);
var versions = new List<LocalPlugin>();
+ if (!Directory.Exists(path))
+ {
+ // Plugin path doesn't exist, don't try to enumerate subfolders.
+ return Enumerable.Empty<LocalPlugin>();
+ }
+
var directories = Directory.EnumerateDirectories(path, "*.*", SearchOption.TopDirectoryOnly);
foreach (var dir in directories)
@@ -1026,7 +1031,7 @@ namespace Emby.Server.Implementations
else
{
// No metafile, so lets see if the folder is versioned.
- metafile = dir.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries)[^1];
+ metafile = dir.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)[^1];
int versionIndex = dir.LastIndexOf('_');
if (versionIndex != -1 && Version.TryParse(dir.Substring(versionIndex + 1), out Version parsedVersion))
@@ -1063,7 +1068,6 @@ namespace Emby.Server.Implementations
if (!string.IsNullOrEmpty(lastName) && cleanup)
{
// Attempt a cleanup of old folders.
- versions.RemoveAt(x);
try
{
Logger.LogDebug("Deleting {Path}", versions[x].Path);
@@ -1073,6 +1077,8 @@ namespace Emby.Server.Implementations
{
Logger.LogWarning(e, "Unable to delete {Path}", versions[x].Path);
}
+
+ versions.RemoveAt(x);
}
}
@@ -1371,7 +1377,7 @@ namespace Emby.Server.Implementations
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
var result = await System.Text.Json.JsonSerializer.DeserializeAsync<string>(stream, JsonDefaults.GetOptions(), cancellationToken).ConfigureAwait(false);
var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase);
diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs
index fd302d136..12a9e44e7 100644
--- a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs
+++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Model.Cryptography;
using static MediaBrowser.Common.Cryptography.Constants;
@@ -80,7 +81,7 @@ namespace Emby.Server.Implementations.Cryptography
throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
}
- using var h = HashAlgorithm.Create(hashMethod);
+ using var h = HashAlgorithm.Create(hashMethod) ?? throw new ResourceNotFoundException($"Unknown hash method: {hashMethod}.");
if (salt.Length == 0)
{
return h.ComputeHash(bytes);
diff --git a/Emby.Server.Implementations/Data/SqliteExtensions.cs b/Emby.Server.Implementations/Data/SqliteExtensions.cs
index 70a6df977..1af301ceb 100644
--- a/Emby.Server.Implementations/Data/SqliteExtensions.cs
+++ b/Emby.Server.Implementations/Data/SqliteExtensions.cs
@@ -107,20 +107,6 @@ namespace Emby.Server.Implementations.Data
return null;
}
- public static void Attach(SQLiteDatabaseConnection db, string path, string alias)
- {
- var commandText = string.Format(
- CultureInfo.InvariantCulture,
- "attach @path as {0};",
- alias);
-
- using (var statement = db.PrepareStatement(commandText))
- {
- statement.TryBind("@path", path);
- statement.MoveNext();
- }
- }
-
public static bool IsDBNull(this IReadOnlyList<IResultSetValue> result, int index)
{
return result[index].SQLiteType == SQLiteType.Null;
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index acb75e9b8..638c7a9b4 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -1007,7 +1007,7 @@ namespace Emby.Server.Implementations.Data
return;
}
- var parts = value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ var parts = value.Split('|', StringSplitOptions.RemoveEmptyEntries);
foreach (var part in parts)
{
@@ -1057,7 +1057,7 @@ namespace Emby.Server.Implementations.Data
return;
}
- var parts = value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ var parts = value.Split('|' , StringSplitOptions.RemoveEmptyEntries);
var list = new List<ItemImageInfo>();
foreach (var part in parts)
{
@@ -1096,7 +1096,7 @@ namespace Emby.Server.Implementations.Data
public ItemImageInfo ItemImageInfoFromValueString(string value)
{
- var parts = value.Split(new[] { '*' }, StringSplitOptions.None);
+ var parts = value.Split('*', StringSplitOptions.None);
if (parts.Length < 3)
{
@@ -1532,7 +1532,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
- item.Genres = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ item.Genres = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries);
}
index++;
@@ -1593,7 +1593,7 @@ namespace Emby.Server.Implementations.Data
{
IEnumerable<MetadataField> GetLockedFields(string s)
{
- foreach (var i in s.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
+ foreach (var i in s.Split('|', StringSplitOptions.RemoveEmptyEntries))
{
if (Enum.TryParse(i, true, out MetadataField parsedValue))
{
@@ -1612,7 +1612,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
- item.Studios = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ item.Studios = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries);
}
index++;
@@ -1622,7 +1622,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
- item.Tags = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ item.Tags = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries);
}
index++;
@@ -1636,7 +1636,7 @@ namespace Emby.Server.Implementations.Data
{
IEnumerable<TrailerType> GetTrailerTypes(string s)
{
- foreach (var i in s.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
+ foreach (var i in s.Split('|', StringSplitOptions.RemoveEmptyEntries))
{
if (Enum.TryParse(i, true, out TrailerType parsedValue))
{
@@ -1811,7 +1811,7 @@ namespace Emby.Server.Implementations.Data
{
if (!reader.IsDBNull(index))
{
- item.ProductionLocations = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
+ item.ProductionLocations = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries).ToArray();
}
index++;
@@ -1848,14 +1848,14 @@ namespace Emby.Server.Implementations.Data
{
if (item is IHasArtist hasArtists && !reader.IsDBNull(index))
{
- hasArtists.Artists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ hasArtists.Artists = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries);
}
index++;
if (item is IHasAlbumArtist hasAlbumArtists && !reader.IsDBNull(index))
{
- hasAlbumArtists.AlbumArtists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ hasAlbumArtists.AlbumArtists = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries);
}
index++;
@@ -2403,11 +2403,11 @@ namespace Emby.Server.Implementations.Data
if (string.IsNullOrEmpty(item.OfficialRating))
{
- builder.Append("((OfficialRating is null) * 10)");
+ builder.Append("(OfficialRating is null * 10)");
}
else
{
- builder.Append("((OfficialRating=@ItemOfficialRating) * 10)");
+ builder.Append("(OfficialRating=@ItemOfficialRating * 10)");
}
if (item.ProductionYear.HasValue)
@@ -2416,8 +2416,26 @@ namespace Emby.Server.Implementations.Data
builder.Append("+(Select Case When Abs(COALESCE(ProductionYear, 0) - @ItemProductionYear) < 5 Then 5 Else 0 End )");
}
- //// genres, tags
- builder.Append("+ ((Select count(CleanValue) from ItemValues where ItemId=Guid and CleanValue in (select CleanValue from itemvalues where ItemId=@SimilarItemId)) * 10)");
+ // genres, tags, studios, person, year?
+ builder.Append("+ (Select count(1) * 10 from ItemValues where ItemId=Guid and CleanValue in (select CleanValue from itemvalues where ItemId=@SimilarItemId))");
+
+ if (item is MusicArtist)
+ {
+ // Match albums where the artist is AlbumArtist against other albums.
+ // It is assumed that similar albums => similar artists.
+ builder.Append(
+ @"+ (WITH artistValues AS (
+ SELECT DISTINCT albumValues.CleanValue
+ FROM ItemValues albumValues
+ INNER JOIN ItemValues artistAlbums ON albumValues.ItemId = artistAlbums.ItemId
+ INNER JOIN TypedBaseItems artistItem ON artistAlbums.CleanValue = artistItem.CleanName AND artistAlbums.TYPE = 1 AND artistItem.Guid = @SimilarItemId
+ ), similarArtist AS (
+ SELECT albumValues.ItemId
+ FROM ItemValues albumValues
+ INNER JOIN ItemValues artistAlbums ON albumValues.ItemId = artistAlbums.ItemId
+ INNER JOIN TypedBaseItems artistItem ON artistAlbums.CleanValue = artistItem.CleanName AND artistAlbums.TYPE = 1 AND artistItem.Guid = A.Guid
+ ) SELECT COUNT(DISTINCT(CleanValue)) * 10 FROM ItemValues WHERE ItemId IN (SELECT ItemId FROM similarArtist) AND CleanValue IN (SELECT CleanValue FROM artistValues))");
+ }
builder.Append(") as SimilarityScore");
@@ -5052,7 +5070,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
CheckDisposed();
- var commandText = "select ItemId, Name, Role, PersonType, SortOrder from People";
+ var commandText = "select ItemId, Name, Role, PersonType, SortOrder from People p";
var whereClauses = GetPeopleWhereClauses(query, null);
@@ -5593,7 +5611,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
return counts;
}
- var allTypes = typeString.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
+ var allTypes = typeString.Split('|', StringSplitOptions.RemoveEmptyEntries)
.ToLookup(x => x);
foreach (var type in allTypes)
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index 73502c2c9..f3e3a6397 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -275,7 +275,7 @@ namespace Emby.Server.Implementations.Dto
continue;
}
- var containers = container.Split(new[] { ',' });
+ var containers = container.Split(',');
if (containers.Length < 2)
{
continue;
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index c762aa0b8..d360bb00f 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -32,13 +32,13 @@
<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.DependencyInjection" Version="3.1.9" />
- <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.9" />
- <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.9" />
- <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.9" />
- <PackageReference Include="Mono.Nat" Version="3.0.0" />
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
+ <PackageReference Include="Mono.Nat" Version="3.0.1" />
<PackageReference Include="prometheus-net.DotNetRuntime" Version="3.4.0" />
- <PackageReference Include="ServiceStack.Text.Core" Version="5.9.2" />
+ <PackageReference Include="ServiceStack.Text.Core" Version="5.10.0" />
<PackageReference Include="sharpcompress" Version="0.26.0" />
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.1.0" />
<PackageReference Include="DotNet.Glob" Version="3.1.0" />
@@ -49,10 +49,12 @@
</ItemGroup>
<PropertyGroup>
- <TargetFramework>netstandard2.1</TargetFramework>
+ <TargetFramework>net5.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors Condition=" '$(Configuration)' == 'Release'">true</TreatWarningsAsErrors>
+ <!-- https://github.com/microsoft/ApplicationInsights-dotnet/issues/2047 -->
+ <NoWarn>AD0001</NoWarn>
</PropertyGroup>
<!-- Code Analyzers-->
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
index e733c9092..fdf2e3908 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
@@ -245,7 +245,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
return null;
}
- var parts = authorizationHeader.Split(new[] { ' ' }, 2);
+ var parts = authorizationHeader.Split(' ', 2);
// There should be at least to parts
if (parts.Length != 2)
@@ -269,11 +269,11 @@ namespace Emby.Server.Implementations.HttpServer.Security
foreach (var item in parts)
{
- var param = item.Trim().Split(new[] { '=' }, 2);
+ var param = item.Trim().Split('=', 2);
if (param.Length == 2)
{
- var value = NormalizeValue(param[1].Trim(new[] { '"' }));
+ var value = NormalizeValue(param[1].Trim('"'));
result[param[0]] = value;
}
}
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index f16eda1ec..d83873441 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -6,6 +6,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
+using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Emby.Naming.Audio;
@@ -2485,9 +2486,10 @@ namespace Emby.Server.Implementations.Library
var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd;
+ // TODO nullable - what are we trying to do there with empty episodeInfo?
var episodeInfo = episode.IsFileProtocol
- ? resolver.Resolve(episode.Path, isFolder, null, null, isAbsoluteNaming) ?? new Naming.TV.EpisodeInfo()
- : new Naming.TV.EpisodeInfo();
+ ? resolver.Resolve(episode.Path, isFolder, null, null, isAbsoluteNaming) ?? new Naming.TV.EpisodeInfo(episode.Path)
+ : new Naming.TV.EpisodeInfo(episode.Path);
try
{
@@ -2576,12 +2578,12 @@ namespace Emby.Server.Implementations.Library
if (!episode.IndexNumberEnd.HasValue || forceRefresh)
{
- if (episode.IndexNumberEnd != episodeInfo.EndingEpsiodeNumber)
+ if (episode.IndexNumberEnd != episodeInfo.EndingEpisodeNumber)
{
changed = true;
}
- episode.IndexNumberEnd = episodeInfo.EndingEpsiodeNumber;
+ episode.IndexNumberEnd = episodeInfo.EndingEpisodeNumber;
}
if (!episode.ParentIndexNumber.HasValue || forceRefresh)
@@ -2705,7 +2707,7 @@ namespace Emby.Server.Implementations.Library
var videos = videoListResolver.Resolve(fileSystemChildren);
- var currentVideo = videos.FirstOrDefault(i => string.Equals(owner.Path, i.Files.First().Path, StringComparison.OrdinalIgnoreCase));
+ var currentVideo = videos.FirstOrDefault(i => string.Equals(owner.Path, i.Files[0].Path, StringComparison.OrdinalIgnoreCase));
if (currentVideo != null)
{
@@ -2907,7 +2909,7 @@ namespace Emby.Server.Implementations.Library
return item.GetImageInfo(image.Type, imageIndex);
}
- catch (HttpException ex)
+ catch (HttpRequestException ex)
{
if (ex.StatusCode.HasValue
&& (ex.StatusCode.Value == HttpStatusCode.NotFound || ex.StatusCode.Value == HttpStatusCode.Forbidden))
diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs
index 376a15570..928f5f88e 100644
--- a/Emby.Server.Implementations/Library/MediaSourceManager.cs
+++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs
@@ -849,7 +849,7 @@ namespace Emby.Server.Implementations.Library
throw new ArgumentException("Key can't be empty.", nameof(key));
}
- var keys = key.Split(new[] { LiveStreamIdDelimeter }, 2);
+ var keys = key.Split(LiveStreamIdDelimeter, 2);
var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture), keys[0], StringComparison.OrdinalIgnoreCase));
diff --git a/Emby.Server.Implementations/Library/MediaStreamSelector.cs b/Emby.Server.Implementations/Library/MediaStreamSelector.cs
index 179e0ed98..28fa06239 100644
--- a/Emby.Server.Implementations/Library/MediaStreamSelector.cs
+++ b/Emby.Server.Implementations/Library/MediaStreamSelector.cs
@@ -101,7 +101,7 @@ namespace Emby.Server.Implementations.Library
private static IEnumerable<MediaStream> GetSortedStreams(IEnumerable<MediaStream> streams, MediaStreamType type, string[] languagePreferences)
{
- // Give some preferance to external text subs for better performance
+ // Give some preference to external text subs for better performance
return streams.Where(i => i.Type == type)
.OrderBy(i =>
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
index 70be52411..2c4497c69 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
@@ -201,7 +201,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
continue;
}
- var firstMedia = resolvedItem.Files.First();
+ var firstMedia = resolvedItem.Files[0];
var libraryItem = new T
{
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs
index 44560d1e2..341194f23 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs
@@ -77,11 +77,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
_logger.LogInformation("Copying recording stream to file {0}", targetFile);
// The media source if infinite so we need to handle stopping ourselves
- var durationToken = new CancellationTokenSource(duration);
- cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
+ using var durationToken = new CancellationTokenSource(duration);
+ using var linkedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token);
+ cancellationToken = linkedCancellationToken.Token;
await _streamHelper.CopyUntilCancelled(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
+ await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false),
output,
IODefaults.CopyToBufferSize,
cancellationToken).ConfigureAwait(false);
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index fcc2d1eeb..0dc045ee6 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -1635,7 +1635,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
if (mediaSource.RequiresLooping || !(mediaSource.Container ?? string.Empty).EndsWith("ts", StringComparison.OrdinalIgnoreCase) || (mediaSource.Protocol != MediaProtocol.File && mediaSource.Protocol != MediaProtocol.Http))
{
- return new EncodedRecorder(_logger, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer);
+ return new EncodedRecorder(_logger, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, _config);
}
return new DirectRecorder(_logger, _httpClientFactory, _streamHelper);
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
index 3e5457dbd..e6ee9819e 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
@@ -8,7 +8,9 @@ using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Dto;
@@ -25,6 +27,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
private readonly IServerApplicationPaths _appPaths;
private readonly IJsonSerializer _json;
private readonly TaskCompletionSource<bool> _taskCompletionSource = new TaskCompletionSource<bool>();
+ private readonly IServerConfigurationManager _serverConfigurationManager;
private bool _hasExited;
private Stream _logFileStream;
@@ -35,12 +38,14 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
ILogger logger,
IMediaEncoder mediaEncoder,
IServerApplicationPaths appPaths,
- IJsonSerializer json)
+ IJsonSerializer json,
+ IServerConfigurationManager serverConfigurationManager)
{
_logger = logger;
_mediaEncoder = mediaEncoder;
_appPaths = appPaths;
_json = json;
+ _serverConfigurationManager = serverConfigurationManager;
}
private static bool CopySubtitles => false;
@@ -179,15 +184,17 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
var outputParam = string.Empty;
+ var threads = EncodingHelper.GetNumberOfThreads(null, _serverConfigurationManager.GetEncodingOptions(), null);
var commandLineArgs = string.Format(
CultureInfo.InvariantCulture,
- "-i \"{0}\" {2} -map_metadata -1 -threads 0 {3}{4}{5} -y \"{1}\"",
+ "-i \"{0}\" {2} -map_metadata -1 -threads {6} {3}{4}{5} -y \"{1}\"",
inputTempFile,
targetFile,
videoArgs,
GetAudioArgs(mediaSource),
subtitleArgs,
- outputParam);
+ outputParam,
+ threads);
return inputModifier + " " + commandLineArgs;
}
diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
index 28aabc159..5d17ba1de 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
@@ -15,6 +15,7 @@ using System.Threading.Tasks;
using MediaBrowser.Common;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Model.Cryptography;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.LiveTv;
@@ -33,17 +34,20 @@ namespace Emby.Server.Implementations.LiveTv.Listings
private readonly IHttpClientFactory _httpClientFactory;
private readonly SemaphoreSlim _tokenSemaphore = new SemaphoreSlim(1, 1);
private readonly IApplicationHost _appHost;
+ private readonly ICryptoProvider _cryptoProvider;
public SchedulesDirect(
ILogger<SchedulesDirect> logger,
IJsonSerializer jsonSerializer,
IHttpClientFactory httpClientFactory,
- IApplicationHost appHost)
+ IApplicationHost appHost,
+ ICryptoProvider cryptoProvider)
{
_logger = logger;
_jsonSerializer = jsonSerializer;
_httpClientFactory = httpClientFactory;
_appHost = appHost;
+ _cryptoProvider = cryptoProvider;
}
private string UserAgent => _appHost.ApplicationUserAgent;
@@ -108,7 +112,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
options.Content = new StringContent(requestString, Encoding.UTF8, MediaTypeNames.Application.Json);
options.Headers.TryAddWithoutValidation("token", token);
using var response = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
- await using var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
var dailySchedules = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.Day>>(responseStream).ConfigureAwait(false);
_logger.LogDebug("Found {ScheduleCount} programs on {ChannelID} ScheduleDirect", dailySchedules.Count, channelId);
@@ -119,7 +123,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
programRequestOptions.Content = new StringContent("[\"" + string.Join("\", \"", programsID) + "\"]", Encoding.UTF8, MediaTypeNames.Application.Json);
using var innerResponse = await Send(programRequestOptions, true, info, cancellationToken).ConfigureAwait(false);
- await using var innerResponseStream = await innerResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var innerResponseStream = await innerResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
var programDetails = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.ProgramDetails>>(innerResponseStream).ConfigureAwait(false);
var programDict = programDetails.ToDictionary(p => p.programID, y => y);
@@ -257,7 +261,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
Id = newID,
StartDate = startAt,
EndDate = endAt,
- Name = details.titles[0].title120 ?? "Unkown",
+ Name = details.titles[0].title120 ?? "Unknown",
OfficialRating = null,
CommunityRating = null,
EpisodeTitle = episodeTitle,
@@ -476,9 +480,8 @@ namespace Emby.Server.Implementations.LiveTv.Listings
try
{
using var innerResponse2 = await Send(message, true, info, cancellationToken).ConfigureAwait(false);
- await using var response = await innerResponse2.Content.ReadAsStreamAsync().ConfigureAwait(false);
- return await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.ShowImages>>(
- response).ConfigureAwait(false);
+ await using var response = await innerResponse2.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
+ return await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.ShowImages>>(response).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -505,7 +508,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
try
{
using var httpResponse = await Send(options, false, info, cancellationToken).ConfigureAwait(false);
- await using var response = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var response = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
var root = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.Headends>>(response).ConfigureAwait(false);
@@ -538,6 +541,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
private readonly ConcurrentDictionary<string, NameValuePair> _tokens = new ConcurrentDictionary<string, NameValuePair>();
private DateTime _lastErrorResponse;
+
private async Task<string> GetToken(ListingsProviderInfo info, CancellationToken cancellationToken)
{
var username = info.Username;
@@ -587,7 +591,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
savedToken.Value = DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture);
return result;
}
- catch (HttpException ex)
+ catch (HttpRequestException ex)
{
if (ex.StatusCode.HasValue)
{
@@ -617,7 +621,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
return await _httpClientFactory.CreateClient(NamedClient.Default).SendAsync(options, completionOption, cancellationToken).ConfigureAwait(false);
}
- catch (HttpException ex)
+ catch (HttpRequestException ex)
{
_tokens.Clear();
@@ -642,10 +646,12 @@ namespace Emby.Server.Implementations.LiveTv.Listings
CancellationToken cancellationToken)
{
using var options = new HttpRequestMessage(HttpMethod.Post, ApiUrl + "/token");
- options.Content = new StringContent("{\"username\":\"" + username + "\",\"password\":\"" + password + "\"}", Encoding.UTF8, MediaTypeNames.Application.Json);
+ var hashedPasswordBytes = _cryptoProvider.ComputeHash("SHA1", Encoding.ASCII.GetBytes(password), Array.Empty<byte>());
+ string hashedPassword = Hex.Encode(hashedPasswordBytes);
+ options.Content = new StringContent("{\"username\":\"" + username + "\",\"password\":\"" + hashedPassword + "\"}", Encoding.UTF8, MediaTypeNames.Application.Json);
using var response = await Send(options, false, null, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Token>(stream).ConfigureAwait(false);
if (root.message == "OK")
{
@@ -699,13 +705,13 @@ namespace Emby.Server.Implementations.LiveTv.Listings
try
{
using var httpResponse = await Send(options, false, null, cancellationToken).ConfigureAwait(false);
- await using var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
using var response = httpResponse.Content;
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Lineups>(stream).ConfigureAwait(false);
return root.lineups.Any(i => string.Equals(info.ListingsId, i.lineup, StringComparison.OrdinalIgnoreCase));
}
- catch (HttpException ex)
+ catch (HttpRequestException ex)
{
// Apparently we're supposed to swallow this
if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.BadRequest)
@@ -774,7 +780,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
var list = new List<ChannelInfo>();
using var httpResponse = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
- await using var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Channel>(stream).ConfigureAwait(false);
_logger.LogInformation("Found {ChannelCount} channels on the lineup on ScheduleDirect", root.map.Count);
_logger.LogInformation("Mapping Stations to Channel");
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index 2d6f453bd..76c875737 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -79,7 +79,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
Directory.CreateDirectory(Path.GetDirectoryName(cacheFile));
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(path, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
await using (var fileStream = new FileStream(cacheFile, FileMode.CreateNew))
{
await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 9c7d624ee..8c9bb6ba0 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -1429,7 +1429,7 @@ namespace Emby.Server.Implementations.LiveTv
return result;
}
- public Task AddInfoToProgramDto(IReadOnlyCollection<(BaseItem, BaseItemDto)> tuples, ItemFields[] fields, User user = null)
+ public Task AddInfoToProgramDto(IReadOnlyCollection<(BaseItem, BaseItemDto)> tuples, IReadOnlyList<ItemFields> fields, User user = null)
{
var programTuples = new List<Tuple<BaseItemDto, string, string>>();
var hasChannelImage = fields.Contains(ItemFields.ChannelImage);
@@ -2208,7 +2208,7 @@ namespace Emby.Server.Implementations.LiveTv
/// <returns>Task.</returns>
public Task ResetTuner(string id, CancellationToken cancellationToken)
{
- var parts = id.Split(new[] { '_' }, 2);
+ var parts = id.Split('_', 2);
var service = _services.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture), parts[0], StringComparison.OrdinalIgnoreCase));
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index 2f4c60117..c0a4d1228 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -72,7 +72,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(model.LineupURL, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
var lineup = await JsonSerializer.DeserializeAsync<List<Channels>>(stream, cancellationToken: cancellationToken)
.ConfigureAwait(false) ?? new List<Channels>();
@@ -129,7 +129,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}/discover.json", GetApiUrl(info)), HttpCompletionOption.ResponseHeadersRead, cancellationToken)
.ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
var discoverResponse = await JsonSerializer.DeserializeAsync<DiscoverResponse>(stream, cancellationToken: cancellationToken)
.ConfigureAwait(false);
@@ -143,7 +143,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return discoverResponse;
}
- catch (HttpException ex)
+ catch (HttpRequestException ex)
{
if (!throwAllExceptions && ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
{
@@ -175,7 +175,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}/tuners.html", GetApiUrl(info)), HttpCompletionOption.ResponseHeadersRead, cancellationToken)
.ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
using var sr = new StreamReader(stream, System.Text.Encoding.UTF8);
var tuners = new List<LiveTvTunerInfo>();
while (!sr.EndOfStream)
@@ -663,7 +663,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var modelInfo = await GetModelInfo(info, true, CancellationToken.None).ConfigureAwait(false);
info.DeviceId = modelInfo.DeviceID;
}
- catch (HttpException ex)
+ catch (HttpRequestException ex)
{
if (ex.StatusCode.HasValue && ex.StatusCode.Value == System.Net.HttpStatusCode.NotFound)
{
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
index 0333e723b..78e62ff0a 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
@@ -182,7 +182,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
if (string.IsNullOrEmpty(currentFile))
{
- return (files.Last(), true);
+ return (files[^1], true);
}
var nextIndex = files.FindIndex(i => string.Equals(i, currentFile, StringComparison.OrdinalIgnoreCase)) + 1;
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
index c064e2fe6..1d6c26c13 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
@@ -63,7 +63,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
.SendAsync(requestMessage, cancellationToken)
.ConfigureAwait(false);
response.EnsureSuccessStatusCode();
- return await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ return await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
}
return File.OpenRead(info.Url);
@@ -163,7 +163,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
private string GetChannelNumber(string extInf, Dictionary<string, string> attributes, string mediaUrl)
{
- var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ var nameParts = extInf.Split(',', StringSplitOptions.RemoveEmptyEntries);
var nameInExtInf = nameParts.Length > 1 ? nameParts[^1].AsSpan().Trim() : ReadOnlySpan<char>.Empty;
string numberString = null;
@@ -197,7 +197,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
if (string.IsNullOrWhiteSpace(numberString))
{
// Using this as a fallback now as this leads to Problems with channels like "5 USA"
- // where 5 isnt ment to be the channel number
+ // where 5 isn't ment to be the channel number
// Check for channel number with the format from SatIp
// #EXTINF:0,84. VOX Schweiz
// #EXTINF:0,84.0 - VOX Schweiz
@@ -273,8 +273,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
private static string GetChannelName(string extInf, Dictionary<string, string> attributes)
{
- var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- var nameInExtInf = nameParts.Length > 1 ? nameParts.Last().Trim() : null;
+ var nameParts = extInf.Split(',', StringSplitOptions.RemoveEmptyEntries);
+ var nameInExtInf = nameParts.Length > 1 ? nameParts[^1].Trim() : null;
// Check for channel number with the format from SatIp
// #EXTINF:0,84. VOX Schweiz
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
index 2e1b89509..2de447ad9 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
@@ -135,7 +135,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
Logger.LogInformation("Beginning {0} stream to {1}", GetType().Name, TempFilePath);
using var message = response;
- await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
await using var fileStream = new FileStream(TempFilePath, FileMode.Create, FileAccess.Write, FileShare.Read);
await StreamHelper.CopyToAsync(
stream,
diff --git a/Emby.Server.Implementations/Localization/Core/cs.json b/Emby.Server.Implementations/Localization/Core/cs.json
index fb31b01ff..775267183 100644
--- a/Emby.Server.Implementations/Localization/Core/cs.json
+++ b/Emby.Server.Implementations/Localization/Core/cs.json
@@ -115,5 +115,8 @@
"TasksLibraryCategory": "Knihovna",
"TasksMaintenanceCategory": "Údržba",
"TaskCleanActivityLogDescription": "Smazat záznamy o aktivitě, které jsou starší než zadaná doba.",
- "TaskCleanActivityLog": "Smazat záznam aktivity"
+ "TaskCleanActivityLog": "Smazat záznam aktivity",
+ "Undefined": "Nedefinované",
+ "Forced": "Vynucené",
+ "Default": "Výchozí"
}
diff --git a/Emby.Server.Implementations/Localization/Core/de.json b/Emby.Server.Implementations/Localization/Core/de.json
index c81de8218..6ab22b8a4 100644
--- a/Emby.Server.Implementations/Localization/Core/de.json
+++ b/Emby.Server.Implementations/Localization/Core/de.json
@@ -115,5 +115,8 @@
"TasksLibraryCategory": "Bibliothek",
"TasksMaintenanceCategory": "Wartung",
"TaskCleanActivityLogDescription": "Löscht Aktivitätsprotokolleinträge, die älter als das konfigurierte Alter sind.",
- "TaskCleanActivityLog": "Aktivitätsprotokoll aufräumen"
+ "TaskCleanActivityLog": "Aktivitätsprotokoll aufräumen",
+ "Undefined": "Undefiniert",
+ "Forced": "Erzwungen",
+ "Default": "Standard"
}
diff --git a/Emby.Server.Implementations/Localization/Core/en-GB.json b/Emby.Server.Implementations/Localization/Core/en-GB.json
index 57ff13219..cd64cdde4 100644
--- a/Emby.Server.Implementations/Localization/Core/en-GB.json
+++ b/Emby.Server.Implementations/Localization/Core/en-GB.json
@@ -113,5 +113,7 @@
"TasksChannelsCategory": "Internet Channels",
"TasksApplicationCategory": "Application",
"TasksLibraryCategory": "Library",
- "TasksMaintenanceCategory": "Maintenance"
+ "TasksMaintenanceCategory": "Maintenance",
+ "TaskCleanActivityLogDescription": "Deletes activity log entries older than the configured age.",
+ "TaskCleanActivityLog": "Clean Activity Log"
}
diff --git a/Emby.Server.Implementations/Localization/Core/en-US.json b/Emby.Server.Implementations/Localization/Core/en-US.json
index 6d8b222b4..f8f595faa 100644
--- a/Emby.Server.Implementations/Localization/Core/en-US.json
+++ b/Emby.Server.Implementations/Localization/Core/en-US.json
@@ -9,11 +9,13 @@
"Channels": "Channels",
"ChapterNameValue": "Chapter {0}",
"Collections": "Collections",
+ "Default": "Default",
"DeviceOfflineWithName": "{0} has disconnected",
"DeviceOnlineWithName": "{0} is connected",
"FailedLoginAttemptWithUserName": "Failed login attempt from {0}",
"Favorites": "Favorites",
"Folders": "Folders",
+ "Forced": "Forced",
"Genres": "Genres",
"HeaderAlbumArtists": "Album Artists",
"HeaderContinueWatching": "Continue Watching",
@@ -77,6 +79,7 @@
"Sync": "Sync",
"System": "System",
"TvShows": "TV Shows",
+ "Undefined": "Undefined",
"User": "User",
"UserCreatedWithName": "User {0} has been created",
"UserDeletedWithName": "User {0} has been deleted",
diff --git a/Emby.Server.Implementations/Localization/Core/es-AR.json b/Emby.Server.Implementations/Localization/Core/es-AR.json
index 390074cdd..0d4a14be0 100644
--- a/Emby.Server.Implementations/Localization/Core/es-AR.json
+++ b/Emby.Server.Implementations/Localization/Core/es-AR.json
@@ -113,5 +113,10 @@
"TasksChannelsCategory": "Canales de internet",
"TasksApplicationCategory": "Aplicación",
"TasksLibraryCategory": "Biblioteca",
- "TasksMaintenanceCategory": "Mantenimiento"
+ "TasksMaintenanceCategory": "Mantenimiento",
+ "TaskCleanActivityLogDescription": "Borrar log de actividades anteriores a la fecha establecida.",
+ "TaskCleanActivityLog": "Borrar log de actividades",
+ "Undefined": "Indefinido",
+ "Forced": "Forzado",
+ "Default": "Por Defecto"
}
diff --git a/Emby.Server.Implementations/Localization/Core/es.json b/Emby.Server.Implementations/Localization/Core/es.json
index 60abc08d4..fe674cf36 100644
--- a/Emby.Server.Implementations/Localization/Core/es.json
+++ b/Emby.Server.Implementations/Localization/Core/es.json
@@ -113,5 +113,10 @@
"TaskRefreshChannels": "Actualizar canales",
"TaskRefreshChannelsDescription": "Actualiza la información de los canales de internet.",
"TaskDownloadMissingSubtitles": "Descargar los subtítulos que faltan",
- "TaskDownloadMissingSubtitlesDescription": "Busca en internet los subtítulos que falten en el contenido de tus bibliotecas, basándose en la configuración de los metadatos."
+ "TaskDownloadMissingSubtitlesDescription": "Busca en internet los subtítulos que falten en el contenido de tus bibliotecas, basándose en la configuración de los metadatos.",
+ "TaskCleanActivityLogDescription": "Elimina todos los registros de actividad anteriores a la fecha configurada.",
+ "TaskCleanActivityLog": "Limpiar registro de actividad",
+ "Undefined": "Indefinido",
+ "Forced": "Forzado",
+ "Default": "Predeterminado"
}
diff --git a/Emby.Server.Implementations/Localization/Core/fil.json b/Emby.Server.Implementations/Localization/Core/fil.json
index 1a3e18832..e5ca676a4 100644
--- a/Emby.Server.Implementations/Localization/Core/fil.json
+++ b/Emby.Server.Implementations/Localization/Core/fil.json
@@ -1,7 +1,7 @@
{
"VersionNumber": "Bersyon {0}",
"ValueSpecialEpisodeName": "Espesyal - {0}",
- "ValueHasBeenAddedToLibrary": "Naidagdag na ang {0} sa iyong media library",
+ "ValueHasBeenAddedToLibrary": "Naidagdag na ang {0} sa iyong librerya ng medya",
"UserStoppedPlayingItemWithValues": "Natapos ni {0} ang {1} sa {2}",
"UserStartedPlayingItemWithValues": "Si {0} ay nagplaplay ng {1} sa {2}",
"UserPolicyUpdatedWithName": "Ang user policy ay naiupdate para kay {0}",
@@ -61,8 +61,8 @@
"Latest": "Pinakabago",
"LabelRunningTimeValue": "Oras: {0}",
"LabelIpAddressValue": "Ang IP Address ay {0}",
- "ItemRemovedWithName": "Naitanggal ang {0} sa library",
- "ItemAddedWithName": "Naidagdag ang {0} sa library",
+ "ItemRemovedWithName": "Naitanggal ang {0} sa librerya",
+ "ItemAddedWithName": "Naidagdag ang {0} sa librerya",
"Inherit": "Manahin",
"HeaderRecordingGroups": "Pagtatalang Grupo",
"HeaderNextUp": "Susunod",
@@ -90,12 +90,29 @@
"Application": "Aplikasyon",
"AppDeviceValues": "Aplikasyon: {0}, Aparato: {1}",
"Albums": "Albums",
- "TaskRefreshLibrary": "Suriin ang nasa librerya",
- "TaskRefreshChapterImagesDescription": "Gumawa ng larawan para sa mga pelikula na may kabanata",
+ "TaskRefreshLibrary": "Suriin and Librerya ng Medya",
+ "TaskRefreshChapterImagesDescription": "Gumawa ng larawan para sa mga pelikula na may kabanata.",
"TaskRefreshChapterImages": "Kunin ang mga larawan ng kabanata",
"TaskCleanCacheDescription": "Tanggalin ang mga cache file na hindi na kailangan ng systema.",
"TasksChannelsCategory": "Palabas sa internet",
"TasksLibraryCategory": "Librerya",
"TasksMaintenanceCategory": "Pagpapanatili",
- "HomeVideos": "Sariling pelikula"
+ "HomeVideos": "Sariling pelikula",
+ "TaskRefreshPeopleDescription": "Ini-update ang metadata para sa mga aktor at direktor sa iyong librerya ng medya.",
+ "TaskRefreshPeople": "I-refresh ang Tauhan",
+ "TaskDownloadMissingSubtitlesDescription": "Hinahanap sa internet ang mga nawawalang subtiles base sa metadata configuration.",
+ "TaskDownloadMissingSubtitles": "I-download and nawawalang subtitles",
+ "TaskRefreshChannelsDescription": "Ni-rerefresh ang impormasyon sa internet channels.",
+ "TaskRefreshChannels": "I-refresh ang Channels",
+ "TaskCleanTranscodeDescription": "Binubura ang transcode files na mas matanda ng isang araw.",
+ "TaskUpdatePluginsDescription": "Nag download at install ng updates sa plugins na naka configure para sa automatikong pag update.",
+ "TaskUpdatePlugins": "I-update ang Plugins",
+ "TaskCleanLogsDescription": "Binubura and files ng talaan na mas mantanda ng {0} araw.",
+ "TaskCleanTranscode": "Linisin and Direktoryo ng Transcode",
+ "TaskCleanLogs": "Linisin and Direktoryo ng Talaan",
+ "TaskRefreshLibraryDescription": "Sinusuri ang iyong librerya ng medya para sa bagong files at irefresh ang metadata.",
+ "TaskCleanCache": "Linisin and Direktoryo ng Cache",
+ "TasksApplicationCategory": "Application",
+ "TaskCleanActivityLog": "Linisin ang Tala ng Aktibidad",
+ "TaskCleanActivityLogDescription": "Tanggalin ang mga tala ng aktibidad na mas matanda sa naka configure na edad."
}
diff --git a/Emby.Server.Implementations/Localization/Core/fr.json b/Emby.Server.Implementations/Localization/Core/fr.json
index cc9243f37..3d5d69f36 100644
--- a/Emby.Server.Implementations/Localization/Core/fr.json
+++ b/Emby.Server.Implementations/Localization/Core/fr.json
@@ -115,5 +115,8 @@
"TasksLibraryCategory": "Bibliothèque",
"TasksMaintenanceCategory": "Maintenance",
"TaskCleanActivityLogDescription": "Supprime les entrées du journal d'activité antérieures à l'âge configuré.",
- "TaskCleanActivityLog": "Nettoyer le journal d'activité"
+ "TaskCleanActivityLog": "Nettoyer le journal d'activité",
+ "Undefined": "Non défini",
+ "Forced": "Forcé",
+ "Default": "Par défaut"
}
diff --git a/Emby.Server.Implementations/Localization/Core/he.json b/Emby.Server.Implementations/Localization/Core/he.json
index f906d6e11..981e8a06e 100644
--- a/Emby.Server.Implementations/Localization/Core/he.json
+++ b/Emby.Server.Implementations/Localization/Core/he.json
@@ -113,5 +113,10 @@
"TaskRefreshChannels": "רענן ערוץ",
"TaskCleanTranscodeDescription": "מחק קבצי transcode שנוצרו מלפני יותר מיום.",
"TaskCleanTranscode": "נקה תקיית Transcode",
- "TaskUpdatePluginsDescription": "הורד והתקן עדכונים עבור תוספים שמוגדרים לעדכון אוטומטי."
+ "TaskUpdatePluginsDescription": "הורד והתקן עדכונים עבור תוספים שמוגדרים לעדכון אוטומטי.",
+ "TaskCleanActivityLogDescription": "מחק רשומת פעילות הישנה יותר מהגיל המוגדר.",
+ "TaskCleanActivityLog": "נקה רשומת פעילות",
+ "Undefined": "לא מוגדר",
+ "Forced": "כפוי",
+ "Default": "ברירת מחדל"
}
diff --git a/Emby.Server.Implementations/Localization/Core/hu.json b/Emby.Server.Implementations/Localization/Core/hu.json
index 343d213d4..804dabe57 100644
--- a/Emby.Server.Implementations/Localization/Core/hu.json
+++ b/Emby.Server.Implementations/Localization/Core/hu.json
@@ -113,5 +113,7 @@
"TaskDownloadMissingSubtitles": "Hiányzó feliratok letöltése",
"TaskRefreshChannelsDescription": "Frissíti az internetes csatornák adatait.",
"TaskRefreshChannels": "Csatornák frissítése",
- "TaskCleanTranscodeDescription": "Törli az egy napnál régebbi átkódolási fájlokat."
+ "TaskCleanTranscodeDescription": "Törli az egy napnál régebbi átkódolási fájlokat.",
+ "TaskCleanActivityLogDescription": "A beállítottnál korábbi bejegyzések törlése a tevékenységnaplóból.",
+ "TaskCleanActivityLog": "Tevékenységnapló törlése"
}
diff --git a/Emby.Server.Implementations/Localization/Core/nb.json b/Emby.Server.Implementations/Localization/Core/nb.json
index 245c3cd63..3b016fe62 100644
--- a/Emby.Server.Implementations/Localization/Core/nb.json
+++ b/Emby.Server.Implementations/Localization/Core/nb.json
@@ -113,5 +113,9 @@
"TaskRefreshPeople": "Oppfrisk personer",
"TaskCleanLogsDescription": "Sletter loggfiler som er eldre enn {0} dager gamle.",
"TaskCleanLogs": "Tøm loggmappe",
- "TaskRefreshLibraryDescription": "Skanner mediebibliotekene dine for nye filer og oppdaterer metadata."
+ "TaskRefreshLibraryDescription": "Skanner mediebibliotekene dine for nye filer og oppdaterer metadata.",
+ "TaskCleanActivityLog": "Tøm aktivitetslogg",
+ "Undefined": "Udefinert",
+ "Forced": "Tvungen",
+ "Default": "Standard"
}
diff --git a/Emby.Server.Implementations/Localization/Core/nl.json b/Emby.Server.Implementations/Localization/Core/nl.json
index e102b92b9..e1e88cc9b 100644
--- a/Emby.Server.Implementations/Localization/Core/nl.json
+++ b/Emby.Server.Implementations/Localization/Core/nl.json
@@ -113,5 +113,7 @@
"TasksChannelsCategory": "Internet Kanalen",
"TasksApplicationCategory": "Applicatie",
"TasksLibraryCategory": "Bibliotheek",
- "TasksMaintenanceCategory": "Onderhoud"
+ "TasksMaintenanceCategory": "Onderhoud",
+ "TaskCleanActivityLogDescription": "Verwijder activiteiten logs ouder dan de ingestelde tijd.",
+ "TaskCleanActivityLog": "Leeg activiteiten logboek"
}
diff --git a/Emby.Server.Implementations/Localization/Core/pl.json b/Emby.Server.Implementations/Localization/Core/pl.json
index 003e591b3..e3da96a85 100644
--- a/Emby.Server.Implementations/Localization/Core/pl.json
+++ b/Emby.Server.Implementations/Localization/Core/pl.json
@@ -113,5 +113,10 @@
"TasksChannelsCategory": "Kanały internetowe",
"TasksApplicationCategory": "Aplikacja",
"TasksLibraryCategory": "Biblioteka",
- "TasksMaintenanceCategory": "Konserwacja"
+ "TasksMaintenanceCategory": "Konserwacja",
+ "TaskCleanActivityLogDescription": "Usuwa wpisy dziennika aktywności starsze niż skonfigurowany wiek.",
+ "TaskCleanActivityLog": "Czyść dziennik aktywności",
+ "Undefined": "Nieustalony",
+ "Forced": "Wymuszony",
+ "Default": "Domyślne"
}
diff --git a/Emby.Server.Implementations/Localization/Core/pt-BR.json b/Emby.Server.Implementations/Localization/Core/pt-BR.json
index 5e49ca702..8d25e27f6 100644
--- a/Emby.Server.Implementations/Localization/Core/pt-BR.json
+++ b/Emby.Server.Implementations/Localization/Core/pt-BR.json
@@ -113,5 +113,7 @@
"TasksChannelsCategory": "Canais da Internet",
"TasksApplicationCategory": "Aplicativo",
"TasksLibraryCategory": "Biblioteca",
- "TasksMaintenanceCategory": "Manutenção"
+ "TasksMaintenanceCategory": "Manutenção",
+ "TaskCleanActivityLogDescription": "Apaga o registro de atividades mais antigo que a idade configurada.",
+ "TaskCleanActivityLog": "Limpar Registro de Atividades"
}
diff --git a/Emby.Server.Implementations/Localization/Core/ro.json b/Emby.Server.Implementations/Localization/Core/ro.json
index bc008df3b..5e4022292 100644
--- a/Emby.Server.Implementations/Localization/Core/ro.json
+++ b/Emby.Server.Implementations/Localization/Core/ro.json
@@ -112,5 +112,7 @@
"TasksChannelsCategory": "Canale de pe Internet",
"TasksApplicationCategory": "Aplicație",
"TasksLibraryCategory": "Librărie",
- "TasksMaintenanceCategory": "Mentenanță"
+ "TasksMaintenanceCategory": "Mentenanță",
+ "TaskCleanActivityLogDescription": "Șterge intrările din jurnalul de activitate mai vechi de data configurată.",
+ "TaskCleanActivityLog": "Curăță Jurnalul de Activitate"
}
diff --git a/Emby.Server.Implementations/Localization/Core/sr.json b/Emby.Server.Implementations/Localization/Core/sr.json
index 2b1eccfaf..8da92f309 100644
--- a/Emby.Server.Implementations/Localization/Core/sr.json
+++ b/Emby.Server.Implementations/Localization/Core/sr.json
@@ -112,5 +112,7 @@
"TasksChannelsCategory": "Интернет канали",
"TasksApplicationCategory": "Апликација",
"TasksLibraryCategory": "Библиотека",
- "TasksMaintenanceCategory": "Одржавање"
+ "TasksMaintenanceCategory": "Одржавање",
+ "TaskCleanActivityLogDescription": "Брише историју активности старију од конфигурисаног броја година.",
+ "TaskCleanActivityLog": "Очисти историју активности"
}
diff --git a/Emby.Server.Implementations/Localization/Core/ta.json b/Emby.Server.Implementations/Localization/Core/ta.json
index 8089fc304..5fcdb1f74 100644
--- a/Emby.Server.Implementations/Localization/Core/ta.json
+++ b/Emby.Server.Implementations/Localization/Core/ta.json
@@ -112,5 +112,10 @@
"UserOnlineFromDevice": "{1} இருந்து {0} ஆன்லைன்",
"HomeVideos": "முகப்பு வீடியோக்கள்",
"UserStoppedPlayingItemWithValues": "{0} {2} இல் {1} முடித்துவிட்டது",
- "UserStartedPlayingItemWithValues": "{0} {2}இல் {1} ஐ இயக்குகிறது"
+ "UserStartedPlayingItemWithValues": "{0} {2}இல் {1} ஐ இயக்குகிறது",
+ "TaskCleanActivityLogDescription": "உள்ளமைக்கப்பட்ட வயதை விட பழைய செயல்பாட்டு பதிவு உள்ளீடுகளை நீக்குகிறது.",
+ "TaskCleanActivityLog": "செயல்பாட்டு பதிவை அழி",
+ "Undefined": "வரையறுக்கப்படாத",
+ "Forced": "கட்டாயப்படுத்தப்பட்டது",
+ "Default": "இயல்புநிலை"
}
diff --git a/Emby.Server.Implementations/Localization/Core/vi.json b/Emby.Server.Implementations/Localization/Core/vi.json
index ac74deff8..0549995c8 100644
--- a/Emby.Server.Implementations/Localization/Core/vi.json
+++ b/Emby.Server.Implementations/Localization/Core/vi.json
@@ -112,5 +112,10 @@
"Books": "Sách",
"AuthenticationSucceededWithUserName": "{0} xác thực thành công",
"Application": "Ứng Dụng",
- "AppDeviceValues": "Ứng Dụng: {0}, Thiết Bị: {1}"
+ "AppDeviceValues": "Ứng Dụng: {0}, Thiết Bị: {1}",
+ "TaskCleanActivityLogDescription": "Xóa các mục nhật ký hoạt động cũ hơn độ tuổi đã cài đặt.",
+ "TaskCleanActivityLog": "Xóa Nhật Ký Hoạt Động",
+ "Undefined": "Không Xác Định",
+ "Forced": "Bắt Buộc",
+ "Default": "Mặc Định"
}
diff --git a/Emby.Server.Implementations/Localization/Core/zh-CN.json b/Emby.Server.Implementations/Localization/Core/zh-CN.json
index 3ae0fe5e7..12803456e 100644
--- a/Emby.Server.Implementations/Localization/Core/zh-CN.json
+++ b/Emby.Server.Implementations/Localization/Core/zh-CN.json
@@ -115,5 +115,8 @@
"TasksApplicationCategory": "应用程序",
"TasksMaintenanceCategory": "维护",
"TaskCleanActivityLog": "清理程序日志",
- "TaskCleanActivityLogDescription": "删除早于设置时间的活动日志条目。"
+ "TaskCleanActivityLogDescription": "删除早于设置时间的活动日志条目。",
+ "Undefined": "未定义",
+ "Forced": "强制的",
+ "Default": "默认"
}
diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
index 56f4133a0..3a9e28458 100644
--- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
@@ -653,7 +653,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
try
{
_logger.LogInformation(Name + ": Waiting on Task");
- var exited = Task.WaitAll(new[] { task }, 2000);
+ var exited = task.Wait(2000);
if (exited)
{
diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
index 6f81bf49b..cfbf03ddc 100644
--- a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
@@ -136,7 +136,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
{
var type = scheduledTask.ScheduledTask.GetType();
- _logger.LogInformation("Queueing task {0}", type.Name);
+ _logger.LogInformation("Queuing task {0}", type.Name);
lock (_taskQueue)
{
@@ -176,7 +176,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
{
var type = task.ScheduledTask.GetType();
- _logger.LogInformation("Queueing task {0}", type.Name);
+ _logger.LogInformation("Queuing task {0}", type.Name);
lock (_taskQueue)
{
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs
index 8439f8a99..171e44258 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs
@@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
try
{
previouslyFailedImages = File.ReadAllText(failHistoryPath)
- .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
+ .Split('|', StringSplitOptions.RemoveEmptyEntries)
.ToList();
}
catch (IOException)
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs
index c5af68bce..161fa0580 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Updates;
@@ -101,7 +102,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
throw;
}
}
- catch (HttpException ex)
+ catch (HttpRequestException ex)
{
_logger.LogError(ex, "Error downloading {0}", package.Name);
}
diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs
index b986ffa1c..f9c6a13c6 100644
--- a/Emby.Server.Implementations/Session/WebSocketController.cs
+++ b/Emby.Server.Implementations/Session/WebSocketController.cs
@@ -8,6 +8,7 @@ using System.Linq;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Net;
@@ -55,9 +56,9 @@ namespace Emby.Server.Implementations.Session
connection.Closed += OnConnectionClosed;
}
- private void OnConnectionClosed(object sender, EventArgs e)
+ private void OnConnectionClosed(object? sender, EventArgs e)
{
- var connection = (IWebSocketConnection)sender;
+ var connection = sender as IWebSocketConnection ?? throw new ArgumentException($"{nameof(sender)} is not of type {nameof(IWebSocketConnection)}", nameof(sender));
_logger.LogDebug("Removing websocket from session {Session}", _session.Id);
_sockets.Remove(connection);
connection.Closed -= OnConnectionClosed;
diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs
index 966ed5024..7c4e00311 100644
--- a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs
+++ b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs
@@ -51,7 +51,7 @@ namespace Emby.Server.Implementations.SyncPlay
new Dictionary<Guid, ISyncPlayController>();
/// <summary>
- /// Lock used for accesing any group.
+ /// Lock used for accessing any group.
/// </summary>
private readonly object _groupsLock = new object();
diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs
index fd1f43e62..851e7bd68 100644
--- a/Emby.Server.Implementations/Updates/InstallationManager.cs
+++ b/Emby.Server.Implementations/Updates/InstallationManager.cs
@@ -99,7 +99,7 @@ namespace Emby.Server.Implementations.Updates
{
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
.GetAsync(manifest, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
try
{
@@ -116,11 +116,6 @@ namespace Emby.Server.Implementations.Updates
_logger.LogError(ex, "The URL configured for the plugin repository manifest URL is not valid: {Manifest}", manifest);
return Array.Empty<PackageInfo>();
}
- catch (HttpException ex)
- {
- _logger.LogError(ex, "An error occurred while accessing the plugin manifest: {Manifest}", manifest);
- return Array.Empty<PackageInfo>();
- }
catch (HttpRequestException ex)
{
_logger.LogError(ex, "An error occurred while accessing the plugin manifest: {Manifest}", manifest);
@@ -246,7 +241,8 @@ namespace Emby.Server.Implementations.Updates
_currentInstallations.Add(tuple);
}
- var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token;
+ using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token);
+ var linkedToken = linkedTokenSource.Token;
await _eventManager.PublishAsync(new PluginInstallingEventArgs(package)).ConfigureAwait(false);
@@ -338,7 +334,7 @@ namespace Emby.Server.Implementations.Updates
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
.GetAsync(package.SourceUrl, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
// CA5351: Do Not Use Broken Cryptographic Algorithms
#pragma warning disable CA5351