aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs19
-rw-r--r--Emby.Server.Implementations/Activity/ActivityManager.cs2
-rw-r--r--Emby.Server.Implementations/Activity/ActivityRepository.cs2
-rw-r--r--Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs38
-rw-r--r--Emby.Server.Implementations/AppBase/ConfigurationHelper.cs4
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs178
-rw-r--r--Emby.Server.Implementations/Archiving/ZipClient.cs8
-rw-r--r--Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs2
-rw-r--r--Emby.Server.Implementations/Browser/BrowserLauncher.cs3
-rw-r--r--Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs8
-rw-r--r--Emby.Server.Implementations/Channels/ChannelImageProvider.cs2
-rw-r--r--Emby.Server.Implementations/Channels/ChannelManager.cs16
-rw-r--r--Emby.Server.Implementations/Channels/ChannelPostScanTask.cs2
-rw-r--r--Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs2
-rw-r--r--Emby.Server.Implementations/Collections/CollectionImageProvider.cs3
-rw-r--r--Emby.Server.Implementations/Collections/CollectionManager.cs4
-rw-r--r--Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs61
-rw-r--r--Emby.Server.Implementations/ConfigurationOptions.cs7
-rw-r--r--Emby.Server.Implementations/Cryptography/CryptographyProvider.cs23
-rw-r--r--Emby.Server.Implementations/Data/BaseSqliteRepository.cs6
-rw-r--r--Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs2
-rw-r--r--Emby.Server.Implementations/Data/ManagedConnection.cs2
-rw-r--r--Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs2
-rw-r--r--Emby.Server.Implementations/Data/SqliteExtensions.cs2
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs28
-rw-r--r--Emby.Server.Implementations/Data/SqliteUserDataRepository.cs2
-rw-r--r--Emby.Server.Implementations/Data/SqliteUserRepository.cs2
-rw-r--r--Emby.Server.Implementations/Data/TypeMapper.cs11
-rw-r--r--Emby.Server.Implementations/Devices/DeviceId.cs2
-rw-r--r--Emby.Server.Implementations/Devices/DeviceManager.cs3
-rw-r--r--Emby.Server.Implementations/Diagnostics/CommonProcess.cs2
-rw-r--r--Emby.Server.Implementations/Diagnostics/ProcessFactory.cs2
-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/EntryPoints/AutomaticRestartEntryPoint.cs2
-rw-r--r--Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs3
-rw-r--r--Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs17
-rw-r--r--Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs2
-rw-r--r--Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs37
-rw-r--r--Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs109
-rw-r--r--Emby.Server.Implementations/EntryPoints/StartupWizard.cs21
-rw-r--r--Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs35
-rw-r--r--Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs2
-rw-r--r--Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs3
-rw-r--r--Emby.Server.Implementations/HttpServer/FileWriter.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpListenerHost.cs5
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpResultFactory.cs10
-rw-r--r--Emby.Server.Implementations/HttpServer/IHttpListener.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs6
-rw-r--r--Emby.Server.Implementations/HttpServer/ResponseFilter.cs12
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/AuthService.cs19
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/SessionContext.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/StreamWriter.cs57
-rw-r--r--Emby.Server.Implementations/HttpServer/WebSocketConnection.cs110
-rw-r--r--Emby.Server.Implementations/IO/ExtendedFileSystemInfo.cs2
-rw-r--r--Emby.Server.Implementations/IO/FileRefresher.cs2
-rw-r--r--Emby.Server.Implementations/IO/LibraryMonitor.cs10
-rw-r--r--Emby.Server.Implementations/IO/ManagedFileSystem.cs2
-rw-r--r--Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs2
-rw-r--r--Emby.Server.Implementations/IO/StreamHelper.cs2
-rw-r--r--Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs2
-rw-r--r--Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs4
-rw-r--r--Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs15
-rw-r--r--Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs13
-rw-r--r--Emby.Server.Implementations/Library/ExclusiveLiveStream.cs2
-rw-r--r--Emby.Server.Implementations/Library/InvalidAuthProvider.cs11
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs6
-rw-r--r--Emby.Server.Implementations/Library/LiveStreamHelper.cs2
-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/MusicManager.cs5
-rw-r--r--Emby.Server.Implementations/Library/PathExtensions.cs4
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs4
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs35
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs15
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs4
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs15
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/FolderResolver.cs4
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/ItemResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs5
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs10
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs10
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs3
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs7
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs10
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/SearchEngine.cs8
-rw-r--r--Emby.Server.Implementations/Library/UserDataManager.cs18
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs78
-rw-r--r--Emby.Server.Implementations/Library/UserViewManager.cs24
-rw-r--r--Emby.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs6
-rw-r--r--Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs9
-rw-r--r--Emby.Server.Implementations/Library/Validators/GenresPostScanTask.cs8
-rw-r--r--Emby.Server.Implementations/Library/Validators/GenresValidator.cs15
-rw-r--r--Emby.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs7
-rw-r--r--Emby.Server.Implementations/Library/Validators/MusicGenresValidator.cs15
-rw-r--r--Emby.Server.Implementations/Library/Validators/PeopleValidator.cs1
-rw-r--r--Emby.Server.Implementations/Library/Validators/StudiosPostScanTask.cs8
-rw-r--r--Emby.Server.Implementations/Library/Validators/StudiosValidator.cs16
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs10
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs10
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs4
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs31
-rw-r--r--Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs4
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs13
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs5
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs12
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs4
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs5
-rw-r--r--Emby.Server.Implementations/Localization/Core/af.json96
-rw-r--r--Emby.Server.Implementations/Localization/Core/bg-BG.json38
-rw-r--r--Emby.Server.Implementations/Localization/Core/ca.json74
-rw-r--r--Emby.Server.Implementations/Localization/Core/de.json8
-rw-r--r--Emby.Server.Implementations/Localization/Core/el.json2
-rw-r--r--Emby.Server.Implementations/Localization/Core/he.json60
-rw-r--r--Emby.Server.Implementations/Localization/Core/id.json32
-rw-r--r--Emby.Server.Implementations/Localization/Core/is.json78
-rw-r--r--Emby.Server.Implementations/Localization/Core/it.json14
-rw-r--r--Emby.Server.Implementations/Localization/Core/ko.json8
-rw-r--r--Emby.Server.Implementations/Localization/Core/nb.json2
-rw-r--r--Emby.Server.Implementations/Localization/Core/nl.json6
-rw-r--r--Emby.Server.Implementations/Localization/Core/pt-BR.json24
-rw-r--r--Emby.Server.Implementations/Localization/Core/ru.json6
-rw-r--r--Emby.Server.Implementations/Localization/Core/sk.json40
-rw-r--r--Emby.Server.Implementations/Localization/Core/sv.json16
-rw-r--r--Emby.Server.Implementations/Localization/Core/tr.json110
-rw-r--r--Emby.Server.Implementations/Localization/Core/zh-HK.json2
-rw-r--r--Emby.Server.Implementations/Localization/Core/zh-TW.json2
-rw-r--r--Emby.Server.Implementations/Localization/LocalizationManager.cs2
-rw-r--r--Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs4
-rw-r--r--Emby.Server.Implementations/Networking/NetworkManager.cs148
-rw-r--r--Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs1
-rw-r--r--Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs5
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs9
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/TaskManager.cs32
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodeFileTask.cs35
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs4
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs5
-rw-r--r--Emby.Server.Implementations/ServerApplicationPaths.cs51
-rw-r--r--Emby.Server.Implementations/Services/ServicePath.cs16
-rw-r--r--Emby.Server.Implementations/Services/SwaggerService.cs4
-rw-r--r--Emby.Server.Implementations/Session/HttpSessionController.cs2
-rw-r--r--Emby.Server.Implementations/Session/SessionManager.cs88
-rw-r--r--Emby.Server.Implementations/Session/SessionWebSocketListener.cs4
-rw-r--r--Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs2
-rw-r--r--Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs6
-rw-r--r--Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs48
-rw-r--r--Emby.Server.Implementations/Sorting/NameComparer.cs4
-rw-r--r--Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs4
-rw-r--r--Emby.Server.Implementations/Sorting/StudioComparer.cs5
-rw-r--r--Emby.Server.Implementations/Updates/InstallationManager.cs21
-rw-r--r--Emby.Server.Implementations/UserViews/DynamicImageProvider.cs5
-rw-r--r--Emby.Server.Implementations/WebSockets/WebSocketManager.cs10
156 files changed, 1456 insertions, 1132 deletions
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index 1514402d6..b622a3167 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -39,6 +41,19 @@ namespace Emby.Server.Implementations.Activity
private readonly IServerApplicationHost _appHost;
private readonly IDeviceManager _deviceManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ActivityLogEntryPoint"/> class.
+ /// </summary>
+ /// <param name="logger"></param>
+ /// <param name="sessionManager"></param>
+ /// <param name="deviceManager"></param>
+ /// <param name="taskManager"></param>
+ /// <param name="activityManager"></param>
+ /// <param name="localization"></param>
+ /// <param name="installationManager"></param>
+ /// <param name="subManager"></param>
+ /// <param name="userManager"></param>
+ /// <param name="appHost"></param>
public ActivityLogEntryPoint(
ILogger<ActivityLogEntryPoint> logger,
ISessionManager sessionManager,
@@ -616,8 +631,8 @@ namespace Emby.Server.Implementations.Activity
/// <summary>
/// Constructs a string description of a time-span value.
/// </summary>
- /// <param name="value">The value of this item</param>
- /// <param name="description">The name of this item (singular form)</param>
+ /// <param name="value">The value of this item.</param>
+ /// <param name="description">The name of this item (singular form).</param>
private static string CreateValueString(int value, string description)
{
return string.Format(
diff --git a/Emby.Server.Implementations/Activity/ActivityManager.cs b/Emby.Server.Implementations/Activity/ActivityManager.cs
index 0c513ea12..a30e93912 100644
--- a/Emby.Server.Implementations/Activity/ActivityManager.cs
+++ b/Emby.Server.Implementations/Activity/ActivityManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Linq;
using MediaBrowser.Controller.Library;
diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs
index ffaeaa541..7be72319e 100644
--- a/Emby.Server.Implementations/Activity/ActivityRepository.cs
+++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
index 7ec5252d0..080cfbbd1 100644
--- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
+++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
@@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
-using System.Threading;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Extensions;
@@ -16,7 +15,7 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.AppBase
{
/// <summary>
- /// Class BaseConfigurationManager
+ /// Class BaseConfigurationManager.
/// </summary>
public abstract class BaseConfigurationManager : IConfigurationManager
{
@@ -48,7 +47,7 @@ namespace Emby.Server.Implementations.AppBase
/// <param name="applicationPaths">The application paths.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="xmlSerializer">The XML serializer.</param>
- /// <param name="fileSystem">The file system</param>
+ /// <param name="fileSystem">The file system.</param>
protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILoggerFactory loggerFactory, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
{
CommonApplicationPaths = applicationPaths;
@@ -85,6 +84,7 @@ namespace Emby.Server.Implementations.AppBase
/// </summary>
/// <value>The logger.</value>
protected ILogger Logger { get; private set; }
+
/// <summary>
/// Gets the XML serializer.
/// </summary>
@@ -92,13 +92,13 @@ namespace Emby.Server.Implementations.AppBase
protected IXmlSerializer XmlSerializer { get; private set; }
/// <summary>
- /// Gets or sets the application paths.
+ /// Gets the application paths.
/// </summary>
/// <value>The application paths.</value>
public IApplicationPaths CommonApplicationPaths { get; private set; }
/// <summary>
- /// Gets the system configuration.
+ /// Gets or sets the system configuration.
/// </summary>
/// <value>The configuration.</value>
public BaseApplicationConfiguration CommonConfiguration
@@ -124,6 +124,7 @@ namespace Emby.Server.Implementations.AppBase
return _configuration;
}
}
+
protected set
{
_configuration = value;
@@ -132,6 +133,10 @@ namespace Emby.Server.Implementations.AppBase
}
}
+ /// <summary>
+ /// Adds parts.
+ /// </summary>
+ /// <param name="factories">The configuration factories.</param>
public virtual void AddParts(IEnumerable<IConfigurationFactory> factories)
{
_configurationFactories = factories.ToArray();
@@ -173,7 +178,7 @@ namespace Emby.Server.Implementations.AppBase
/// Replaces the configuration.
/// </summary>
/// <param name="newConfiguration">The new configuration.</param>
- /// <exception cref="ArgumentNullException">newConfiguration</exception>
+ /// <exception cref="ArgumentNullException"><c>newConfiguration</c> is <c>null</c>.</exception>
public virtual void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration)
{
if (newConfiguration == null)
@@ -216,7 +221,7 @@ namespace Emby.Server.Implementations.AppBase
cachePath = CommonConfiguration.CachePath;
}
- Logger.LogInformation("Setting cache path to " + cachePath);
+ Logger.LogInformation("Setting cache path: {Path}", cachePath);
((BaseApplicationPaths)CommonApplicationPaths).CachePath = cachePath;
}
@@ -224,7 +229,7 @@ namespace Emby.Server.Implementations.AppBase
/// Replaces the cache path.
/// </summary>
/// <param name="newConfig">The new configuration.</param>
- /// <exception cref="DirectoryNotFoundException"></exception>
+ /// <exception cref="DirectoryNotFoundException">The new cache path doesn't exist.</exception>
private void ValidateCachePath(BaseApplicationConfiguration newConfig)
{
var newPath = newConfig.CachePath;
@@ -235,7 +240,7 @@ namespace Emby.Server.Implementations.AppBase
// Validate
if (!Directory.Exists(newPath))
{
- throw new FileNotFoundException(
+ throw new DirectoryNotFoundException(
string.Format(
CultureInfo.InvariantCulture,
"{0} does not exist.",
@@ -246,6 +251,10 @@ namespace Emby.Server.Implementations.AppBase
}
}
+ /// <summary>
+ /// Ensures that we have write access to the path.
+ /// </summary>
+ /// <param name="path">The path.</param>
protected void EnsureWriteAccess(string path)
{
var file = Path.Combine(path, Guid.NewGuid().ToString());
@@ -258,6 +267,7 @@ namespace Emby.Server.Implementations.AppBase
return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLowerInvariant() + ".xml");
}
+ /// <inheritdoc />
public object GetConfiguration(string key)
{
return _configurations.GetOrAdd(key, k =>
@@ -304,6 +314,7 @@ namespace Emby.Server.Implementations.AppBase
}
}
+ /// <inheritdoc />
public void SaveConfiguration(string key, object configuration)
{
var configurationStore = GetConfigurationStore(key);
@@ -314,8 +325,7 @@ namespace Emby.Server.Implementations.AppBase
throw new ArgumentException("Expected configuration type is " + configurationType.Name);
}
- var validatingStore = configurationStore as IValidatingConfiguration;
- if (validatingStore != null)
+ if (configurationStore is IValidatingConfiguration validatingStore)
{
var currentConfiguration = GetConfiguration(key);
@@ -341,6 +351,11 @@ namespace Emby.Server.Implementations.AppBase
OnNamedConfigurationUpdated(key, configuration);
}
+ /// <summary>
+ /// Event handler for when a named configuration has been updated.
+ /// </summary>
+ /// <param name="key">The key of the configuration.</param>
+ /// <param name="configuration">The old configuration.</param>
protected virtual void OnNamedConfigurationUpdated(string key, object configuration)
{
NamedConfigurationUpdated?.Invoke(this, new ConfigurationUpdateEventArgs
@@ -350,6 +365,7 @@ namespace Emby.Server.Implementations.AppBase
});
}
+ /// <inheritdoc />
public Type GetConfigurationType(string key)
{
return GetConfigurationStore(key)
diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs
index 90b97061f..854d7b4cb 100644
--- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs
+++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs
@@ -6,13 +6,13 @@ using MediaBrowser.Model.Serialization;
namespace Emby.Server.Implementations.AppBase
{
/// <summary>
- /// Class ConfigurationHelper
+ /// Class ConfigurationHelper.
/// </summary>
public static class ConfigurationHelper
{
/// <summary>
/// Reads an xml configuration file from the file system
- /// It will immediately re-serialize and save if new serialization data is available due to property changes
+ /// It will immediately re-serialize and save if new serialization data is available due to property changes.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="path">The path.</param>
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index fef461b9a..aed0c14a2 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -88,7 +88,6 @@ using MediaBrowser.Model.Cryptography;
using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
@@ -110,9 +109,8 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
-using ServiceStack;
+using Microsoft.OpenApi.Models;
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
namespace Emby.Server.Implementations
@@ -232,7 +230,25 @@ namespace Emby.Server.Implementations
}
}
- protected IServiceProvider _serviceProvider;
+ /// <summary>
+ /// Gets or sets the service provider.
+ /// </summary>
+ public IServiceProvider ServiceProvider { get; set; }
+
+ /// <summary>
+ /// Gets the http port for the webhost.
+ /// </summary>
+ public int HttpPort { get; private set; }
+
+ /// <summary>
+ /// Gets the https port for the webhost.
+ /// </summary>
+ public int HttpsPort { get; private set; }
+
+ /// <summary>
+ /// Gets the content root for the webhost.
+ /// </summary>
+ public string ContentRoot { get; private set; }
/// <summary>
/// Gets the server configuration manager.
@@ -321,7 +337,7 @@ namespace Emby.Server.Implementations
private readonly IConfiguration _configuration;
/// <summary>
- /// Gets or sets the installation manager.
+ /// Gets the installation manager.
/// </summary>
/// <value>The installation manager.</value>
protected IInstallationManager InstallationManager { get; private set; }
@@ -456,20 +472,20 @@ namespace Emby.Server.Implementations
public string Name => ApplicationProductName;
/// <summary>
- /// Creates an instance of type and resolves all constructor dependencies
+ /// Creates an instance of type and resolves all constructor dependencies.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>System.Object.</returns>
public object CreateInstance(Type type)
- => ActivatorUtilities.CreateInstance(_serviceProvider, type);
+ => ActivatorUtilities.CreateInstance(ServiceProvider, type);
/// <summary>
- /// Creates an instance of type and resolves all constructor dependencies
+ /// Creates an instance of type and resolves all constructor dependencies.
/// </summary>
/// /// <typeparam name="T">The type.</typeparam>
/// <returns>T.</returns>
public T CreateInstance<T>()
- => ActivatorUtilities.CreateInstance<T>(_serviceProvider);
+ => ActivatorUtilities.CreateInstance<T>(ServiceProvider);
/// <summary>
/// Creates the instance safe.
@@ -481,7 +497,7 @@ namespace Emby.Server.Implementations
try
{
Logger.LogDebug("Creating instance of {Type}", type);
- return ActivatorUtilities.CreateInstance(_serviceProvider, type);
+ return ActivatorUtilities.CreateInstance(ServiceProvider, type);
}
catch (Exception ex)
{
@@ -495,12 +511,12 @@ namespace Emby.Server.Implementations
/// </summary>
/// <typeparam name="T">The type</typeparam>
/// <returns>``0.</returns>
- public T Resolve<T>() => _serviceProvider.GetService<T>();
+ public T Resolve<T>() => ServiceProvider.GetService<T>();
/// <summary>
/// Gets the export types.
/// </summary>
- /// <typeparam name="T">The type</typeparam>
+ /// <typeparam name="T">The type.</typeparam>
/// <returns>IEnumerable{Type}.</returns>
public IEnumerable<Type> GetExportTypes<T>()
{
@@ -512,11 +528,12 @@ namespace Emby.Server.Implementations
/// <inheritdoc />
public IReadOnlyCollection<T> GetExports<T>(bool manageLifetime = true)
{
+ // Convert to list so this isn't executed for each iteration
var parts = GetExportTypes<T>()
.Select(CreateInstanceSafe)
.Where(i => i != null)
.Cast<T>()
- .ToList(); // Convert to list so this isn't executed for each iteration
+ .ToList();
if (manageLifetime)
{
@@ -611,77 +628,14 @@ namespace Emby.Server.Implementations
await RegisterResources(serviceCollection).ConfigureAwait(false);
- FindParts();
-
- string contentRoot = ServerConfigurationManager.Configuration.DashboardSourcePath;
- if (string.IsNullOrEmpty(contentRoot))
- {
- contentRoot = ServerConfigurationManager.ApplicationPaths.WebPath;
- }
-
- var host = new WebHostBuilder()
- .UseKestrel(options =>
- {
- var addresses = ServerConfigurationManager
- .Configuration
- .LocalNetworkAddresses
- .Select(NormalizeConfiguredLocalAddress)
- .Where(i => i != null)
- .ToList();
- if (addresses.Any())
- {
- foreach (var address in addresses)
- {
- Logger.LogInformation("Kestrel listening on {ipaddr}", address);
- options.Listen(address, HttpPort);
-
- if (EnableHttps && Certificate != null)
- {
- options.Listen(address, HttpsPort, listenOptions => listenOptions.UseHttps(Certificate));
- }
- }
- }
- else
- {
- Logger.LogInformation("Kestrel listening on all interfaces");
- options.ListenAnyIP(HttpPort);
-
- if (EnableHttps && Certificate != null)
- {
- options.ListenAnyIP(HttpsPort, listenOptions => listenOptions.UseHttps(Certificate));
- }
- }
- })
- .UseContentRoot(contentRoot)
- .ConfigureServices(services =>
- {
- services.AddResponseCompression();
- services.AddHttpContextAccessor();
- })
- .Configure(app =>
- {
- app.UseWebSockets();
-
- app.UseResponseCompression();
-
- // TODO app.UseMiddleware<WebSocketMiddleware>();
- app.Use(ExecuteWebsocketHandlerAsync);
- app.Use(ExecuteHttpHandlerAsync);
- })
- .Build();
-
- try
+ ContentRoot = ServerConfigurationManager.Configuration.DashboardSourcePath;
+ if (string.IsNullOrEmpty(ContentRoot))
{
- await host.StartAsync().ConfigureAwait(false);
- }
- catch
- {
- Logger.LogError("Kestrel failed to start! This is most likely due to an invalid address or port bind - correct your bind configuration in system.xml and try again.");
- throw;
+ ContentRoot = ServerConfigurationManager.ApplicationPaths.WebPath;
}
}
- private async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func<Task> next)
+ public async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func<Task> next)
{
if (!context.WebSockets.IsWebSocketRequest)
{
@@ -692,7 +646,7 @@ namespace Emby.Server.Implementations
await HttpServer.ProcessWebSocketRequest(context).ConfigureAwait(false);
}
- private async Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> next)
+ public async Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> next)
{
if (context.WebSockets.IsWebSocketRequest)
{
@@ -753,7 +707,8 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton(typeof(IStreamHelper), typeof(StreamHelper));
- serviceCollection.AddSingleton(typeof(ICryptoProvider), typeof(CryptographyProvider));
+ var cryptoProvider = new CryptographyProvider();
+ serviceCollection.AddSingleton<ICryptoProvider>(cryptoProvider);
SocketFactory = new SocketFactory();
serviceCollection.AddSingleton(SocketFactory);
@@ -792,7 +747,17 @@ namespace Emby.Server.Implementations
_userRepository = GetUserRepository();
- UserManager = new UserManager(LoggerFactory.CreateLogger<UserManager>(), _userRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, this, JsonSerializer, FileSystemManager);
+ UserManager = new UserManager(
+ LoggerFactory.CreateLogger<UserManager>(),
+ _userRepository,
+ XmlSerializer,
+ NetworkManager,
+ () => ImageProcessor,
+ () => DtoService,
+ this,
+ JsonSerializer,
+ FileSystemManager,
+ cryptoProvider);
serviceCollection.AddSingleton(UserManager);
@@ -876,16 +841,14 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton(ChapterManager);
MediaEncoder = new MediaBrowser.MediaEncoding.Encoder.MediaEncoder(
- LoggerFactory,
- JsonSerializer,
- StartupOptions.FFmpegPath,
+ LoggerFactory.CreateLogger<MediaBrowser.MediaEncoding.Encoder.MediaEncoder>(),
ServerConfigurationManager,
FileSystemManager,
- () => SubtitleEncoder,
- () => MediaSourceManager,
ProcessFactory,
- 5000,
- LocalizationManager);
+ LocalizationManager,
+ () => SubtitleEncoder,
+ _configuration,
+ StartupOptions.FFmpegPath);
serviceCollection.AddSingleton(MediaEncoder);
EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager);
@@ -899,13 +862,22 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<IAuthorizationContext>(authContext);
serviceCollection.AddSingleton<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
- AuthService = new AuthService(authContext, ServerConfigurationManager, SessionManager, NetworkManager);
+ AuthService = new AuthService(LoggerFactory.CreateLogger<AuthService>(), authContext, ServerConfigurationManager, SessionManager, NetworkManager);
serviceCollection.AddSingleton(AuthService);
- SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(LibraryManager, LoggerFactory, ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, ProcessFactory);
+ SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(
+ LibraryManager,
+ LoggerFactory.CreateLogger<MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder>(),
+ ApplicationPaths,
+ FileSystemManager,
+ MediaEncoder,
+ HttpClient,
+ MediaSourceManager,
+ ProcessFactory);
serviceCollection.AddSingleton(SubtitleEncoder);
serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager));
+ serviceCollection.AddSingleton<EncodingHelper>();
_displayPreferencesRepository.Initialize();
@@ -918,8 +890,6 @@ namespace Emby.Server.Implementations
((UserDataManager)UserDataManager).Repository = userDataRepo;
ItemRepository.Initialize(userDataRepo, UserManager);
((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
-
- _serviceProvider = serviceCollection.BuildServiceProvider();
}
public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths)
@@ -1010,7 +980,7 @@ namespace Emby.Server.Implementations
}
/// <summary>
- /// Dirty hacks
+ /// Dirty hacks.
/// </summary>
private void SetStaticProperties()
{
@@ -1076,9 +1046,9 @@ namespace Emby.Server.Implementations
/// <summary>
/// Finds the parts.
/// </summary>
- protected void FindParts()
+ public void FindParts()
{
- InstallationManager = _serviceProvider.GetService<IInstallationManager>();
+ InstallationManager = ServiceProvider.GetService<IInstallationManager>();
InstallationManager.PluginInstalled += PluginInstalled;
if (!ServerConfigurationManager.Configuration.IsPortAuthorized)
@@ -1207,7 +1177,7 @@ namespace Emby.Server.Implementations
private CertificateInfo CertificateInfo { get; set; }
- protected X509Certificate2 Certificate { get; private set; }
+ public X509Certificate2 Certificate { get; private set; }
private IEnumerable<string> GetUrlPrefixes()
{
@@ -1418,11 +1388,12 @@ namespace Emby.Server.Implementations
/// <summary>
/// Gets the system status.
/// </summary>
- /// <param name="cancellationToken">The cancellation token</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>SystemInfo.</returns>
public async Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken)
{
var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
+ var transcodingTempPath = ConfigurationManager.GetTranscodePath();
return new SystemInfo
{
@@ -1446,7 +1417,7 @@ namespace Emby.Server.Implementations
CanSelfRestart = CanSelfRestart,
CanLaunchWebBrowser = CanLaunchWebBrowser,
HasUpdateAvailable = HasUpdateAvailable,
- TranscodingTempPath = ApplicationPaths.TranscodingTempPath,
+ TranscodingTempPath = transcodingTempPath,
ServerName = FriendlyName,
LocalAddress = localAddress,
SupportsLibraryMonitor = true,
@@ -1591,7 +1562,7 @@ namespace Emby.Server.Implementations
return resultList;
}
- private IPAddress NormalizeConfiguredLocalAddress(string address)
+ public IPAddress NormalizeConfiguredLocalAddress(string address)
{
var index = address.Trim('/').IndexOf('/');
@@ -1667,10 +1638,6 @@ namespace Emby.Server.Implementations
? Environment.MachineName
: ServerConfigurationManager.Configuration.ServerName;
- public int HttpPort { get; private set; }
-
- public int HttpsPort { get; private set; }
-
/// <summary>
/// Shuts down.
/// </summary>
@@ -1847,6 +1814,7 @@ namespace Emby.Server.Implementations
internal class CertificateInfo
{
public string Path { get; set; }
+
public string Password { get; set; }
}
}
diff --git a/Emby.Server.Implementations/Archiving/ZipClient.cs b/Emby.Server.Implementations/Archiving/ZipClient.cs
index 6b0fd2dc6..4a6e5cfd7 100644
--- a/Emby.Server.Implementations/Archiving/ZipClient.cs
+++ b/Emby.Server.Implementations/Archiving/ZipClient.cs
@@ -10,15 +10,10 @@ using SharpCompress.Readers.Zip;
namespace Emby.Server.Implementations.Archiving
{
/// <summary>
- /// Class DotNetZipClient
+ /// Class DotNetZipClient.
/// </summary>
public class ZipClient : IZipClient
{
- public ZipClient()
- {
-
- }
-
/// <summary>
/// Extracts all.
/// </summary>
@@ -144,7 +139,6 @@ namespace Emby.Server.Implementations.Archiving
}
}
-
/// <summary>
/// Extracts all from tar.
/// </summary>
diff --git a/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs b/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs
index b27f84848..93000ae12 100644
--- a/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs
+++ b/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.Branding;
diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs
index 718129ef0..f5da0d018 100644
--- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs
+++ b/Emby.Server.Implementations/Browser/BrowserLauncher.cs
@@ -4,7 +4,7 @@ using MediaBrowser.Controller;
namespace Emby.Server.Implementations.Browser
{
/// <summary>
- /// Class BrowserLauncher
+ /// Class BrowserLauncher.
/// </summary>
public static class BrowserLauncher
{
@@ -32,6 +32,7 @@ namespace Emby.Server.Implementations.Browser
/// <summary>
/// Opens the URL.
/// </summary>
+ /// <param name="appHost">The application host instance.</param>
/// <param name="url">The URL.</param>
private static void OpenUrl(IServerApplicationHost appHost, string url)
{
diff --git a/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs b/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs
index c10f00f9b..6016fed07 100644
--- a/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs
+++ b/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading;
@@ -13,11 +15,16 @@ namespace Emby.Server.Implementations.Channels
{
private readonly ChannelManager _channelManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ChannelDynamicMediaSourceProvider"/> class.
+ /// </summary>
+ /// <param name="channelManager">The channel manager.</param>
public ChannelDynamicMediaSourceProvider(IChannelManager channelManager)
{
_channelManager = (ChannelManager)channelManager;
}
+ /// <inheritdoc />
public Task<IEnumerable<MediaSourceInfo>> GetMediaSources(BaseItem item, CancellationToken cancellationToken)
{
if (item.SourceType == SourceType.Channel)
@@ -28,6 +35,7 @@ namespace Emby.Server.Implementations.Channels
return Task.FromResult<IEnumerable<MediaSourceInfo>>(new List<MediaSourceInfo>());
}
+ /// <inheritdoc />
public Task<ILiveStream> OpenMediaSource(string openToken, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
{
throw new NotImplementedException();
diff --git a/Emby.Server.Implementations/Channels/ChannelImageProvider.cs b/Emby.Server.Implementations/Channels/ChannelImageProvider.cs
index bafa68818..62aeb9bcb 100644
--- a/Emby.Server.Implementations/Channels/ChannelImageProvider.cs
+++ b/Emby.Server.Implementations/Channels/ChannelImageProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using System.Linq;
using System.Threading;
diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs
index 22681fb49..6e1baddfe 100644
--- a/Emby.Server.Implementations/Channels/ChannelManager.cs
+++ b/Emby.Server.Implementations/Channels/ChannelManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -473,7 +475,7 @@ namespace Emby.Server.Implementations.Channels
await item.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem))
{
ForceSave = !isNew && forceUpdate
- }, cancellationToken);
+ }, cancellationToken).ConfigureAwait(false);
return item;
}
@@ -510,7 +512,7 @@ namespace Emby.Server.Implementations.Channels
return _libraryManager.GetItemIds(new InternalItemsQuery
{
IncludeItemTypes = new[] { typeof(Channel).Name },
- OrderBy = new ValueTuple<string, SortOrder>[] { new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) }
+ OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }
}).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
}
@@ -618,16 +620,16 @@ namespace Emby.Server.Implementations.Channels
{
query.OrderBy = new[]
{
- new ValueTuple<string, SortOrder>(ItemSortBy.PremiereDate, SortOrder.Descending),
- new ValueTuple<string, SortOrder>(ItemSortBy.ProductionYear, SortOrder.Descending),
- new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending)
+ (ItemSortBy.PremiereDate, SortOrder.Descending),
+ (ItemSortBy.ProductionYear, SortOrder.Descending),
+ (ItemSortBy.DateCreated, SortOrder.Descending)
};
}
else
{
query.OrderBy = new[]
{
- new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending)
+ (ItemSortBy.DateCreated, SortOrder.Descending)
};
}
@@ -636,7 +638,7 @@ namespace Emby.Server.Implementations.Channels
private async Task RefreshLatestChannelItems(IChannel channel, CancellationToken cancellationToken)
{
- var internalChannel = await GetChannel(channel, cancellationToken);
+ var internalChannel = await GetChannel(channel, cancellationToken).ConfigureAwait(false);
var query = new InternalItemsQuery();
query.Parent = internalChannel;
diff --git a/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs b/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs
index 3c7cbb115..2712fc8c5 100644
--- a/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs
+++ b/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Linq;
using System.Threading;
diff --git a/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs b/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs
index 303a8ac7b..5774c0415 100644
--- a/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs
+++ b/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading;
diff --git a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs
index 0244c4a68..1fa556ec9 100644
--- a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs
+++ b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -76,7 +78,6 @@ namespace Emby.Server.Implementations.Collections
.Where(i => i != null)
.GroupBy(x => x.Id)
.Select(x => x.First())
- .OrderBy(i => Guid.NewGuid())
.ToList();
}
diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs
index 6d414be73..2b8a5bdc5 100644
--- a/Emby.Server.Implementations/Collections/CollectionManager.cs
+++ b/Emby.Server.Implementations/Collections/CollectionManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -121,7 +123,7 @@ namespace Emby.Server.Implementations.Collections
// This could cause it to get re-resolved as a plain folder
var folderName = _fileSystem.GetValidFilename(name) + " [boxset]";
- var parentFolder = GetCollectionsFolder(true).Result;
+ var parentFolder = GetCollectionsFolder(true).GetAwaiter().GetResult();
if (parentFolder == null)
{
diff --git a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
index c7f92b80b..3d8d15d19 100644
--- a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
+++ b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using Emby.Server.Implementations.AppBase;
using MediaBrowser.Common.Configuration;
@@ -14,11 +15,10 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Configuration
{
/// <summary>
- /// Class ServerConfigurationManager
+ /// Class ServerConfigurationManager.
/// </summary>
public class ServerConfigurationManager : BaseConfigurationManager, IServerConfigurationManager
{
-
/// <summary>
/// Initializes a new instance of the <see cref="ServerConfigurationManager" /> class.
/// </summary>
@@ -32,6 +32,9 @@ namespace Emby.Server.Implementations.Configuration
UpdateMetadataPath();
}
+ /// <summary>
+ /// Configuration updating event.
+ /// </summary>
public event EventHandler<GenericEventArgs<ServerConfiguration>> ConfigurationUpdating;
/// <summary>
@@ -62,13 +65,6 @@ namespace Emby.Server.Implementations.Configuration
base.OnConfigurationUpdated();
}
- public override void AddParts(IEnumerable<IConfigurationFactory> factories)
- {
- base.AddParts(factories);
-
- UpdateTranscodePath();
- }
-
/// <summary>
/// Updates the metadata path.
/// </summary>
@@ -85,28 +81,6 @@ namespace Emby.Server.Implementations.Configuration
}
/// <summary>
- /// Updates the transcoding temporary path.
- /// </summary>
- private void UpdateTranscodePath()
- {
- var encodingConfig = this.GetConfiguration<EncodingOptions>("encoding");
-
- ((ServerApplicationPaths)ApplicationPaths).TranscodingTempPath = string.IsNullOrEmpty(encodingConfig.TranscodingTempPath) ?
- null :
- Path.Combine(encodingConfig.TranscodingTempPath, "transcodes");
- }
-
- protected override void OnNamedConfigurationUpdated(string key, object configuration)
- {
- base.OnNamedConfigurationUpdated(key, configuration);
-
- if (string.Equals(key, "encoding", StringComparison.OrdinalIgnoreCase))
- {
- UpdateTranscodePath();
- }
- }
-
- /// <summary>
/// Replaces the configuration.
/// </summary>
/// <param name="newConfiguration">The new configuration.</param>
@@ -123,12 +97,11 @@ namespace Emby.Server.Implementations.Configuration
base.ReplaceConfiguration(newConfiguration);
}
-
/// <summary>
/// Validates the SSL certificate.
/// </summary>
/// <param name="newConfig">The new configuration.</param>
- /// <exception cref="DirectoryNotFoundException"></exception>
+ /// <exception cref="FileNotFoundException">The certificate path doesn't exist.</exception>
private void ValidateSslCertificate(BaseApplicationConfiguration newConfig)
{
var serverConfig = (ServerConfiguration)newConfig;
@@ -136,12 +109,16 @@ namespace Emby.Server.Implementations.Configuration
var newPath = serverConfig.CertificatePath;
if (!string.IsNullOrWhiteSpace(newPath)
- && !string.Equals(Configuration.CertificatePath ?? string.Empty, newPath))
+ && !string.Equals(Configuration.CertificatePath, newPath, StringComparison.Ordinal))
{
// Validate
if (!File.Exists(newPath))
{
- throw new FileNotFoundException(string.Format("Certificate file '{0}' does not exist.", newPath));
+ throw new FileNotFoundException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Certificate file '{0}' does not exist.",
+ newPath));
}
}
}
@@ -150,24 +127,32 @@ namespace Emby.Server.Implementations.Configuration
/// Validates the metadata path.
/// </summary>
/// <param name="newConfig">The new configuration.</param>
- /// <exception cref="DirectoryNotFoundException"></exception>
+ /// <exception cref="DirectoryNotFoundException">The new config path doesn't exist.</exception>
private void ValidateMetadataPath(ServerConfiguration newConfig)
{
var newPath = newConfig.MetadataPath;
if (!string.IsNullOrWhiteSpace(newPath)
- && !string.Equals(Configuration.MetadataPath ?? string.Empty, newPath))
+ && !string.Equals(Configuration.MetadataPath, newPath, StringComparison.Ordinal))
{
// Validate
if (!Directory.Exists(newPath))
{
- throw new FileNotFoundException(string.Format("{0} does not exist.", newPath));
+ throw new DirectoryNotFoundException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} does not exist.",
+ newPath));
}
EnsureWriteAccess(newPath);
}
}
+ /// <summary>
+ /// Sets all configuration values to their optimal values.
+ /// </summary>
+ /// <returns>If the configuration changed.</returns>
public bool SetOptimalValues()
{
var config = Configuration;
diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs
index 62408ee70..2ea7ff6e9 100644
--- a/Emby.Server.Implementations/ConfigurationOptions.cs
+++ b/Emby.Server.Implementations/ConfigurationOptions.cs
@@ -1,13 +1,16 @@
using System.Collections.Generic;
+using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
namespace Emby.Server.Implementations
{
public static class ConfigurationOptions
{
- public static readonly Dictionary<string, string> Configuration = new Dictionary<string, string>
+ public static Dictionary<string, string> Configuration => new Dictionary<string, string>
{
{ "HttpListenerHost:DefaultRedirectPath", "web/index.html" },
- { "MusicBrainz:BaseUrl", "https://www.musicbrainz.org" }
+ { "MusicBrainz:BaseUrl", "https://www.musicbrainz.org" },
+ { FfmpegProbeSizeKey, "1G" },
+ { FfmpegAnalyzeDurationKey, "200M" }
};
}
}
diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs
index 23b77e268..776074b72 100644
--- a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs
+++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs
@@ -6,6 +6,9 @@ using static MediaBrowser.Common.Cryptography.Constants;
namespace Emby.Server.Implementations.Cryptography
{
+ /// <summary>
+ /// Class providing abstractions over cryptographic functions.
+ /// </summary>
public class CryptographyProvider : ICryptoProvider, IDisposable
{
private static readonly HashSet<string> _supportedHashMethods = new HashSet<string>()
@@ -30,6 +33,9 @@ namespace Emby.Server.Implementations.Cryptography
private bool _disposed = false;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CryptographyProvider"/> class.
+ /// </summary>
public CryptographyProvider()
{
// FIXME: When we get DotNet Standard 2.1 we need to revisit how we do the crypto
@@ -39,8 +45,10 @@ namespace Emby.Server.Implementations.Cryptography
_randomNumberGenerator = RandomNumberGenerator.Create();
}
+ /// <inheritdoc />
public string DefaultHashMethod => "PBKDF2";
+ /// <inheritdoc />
public IEnumerable<string> GetSupportedHashMethods()
=> _supportedHashMethods;
@@ -59,12 +67,7 @@ namespace Emby.Server.Implementations.Cryptography
throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}");
}
- public byte[] ComputeHash(string hashMethod, byte[] bytes)
- => ComputeHash(hashMethod, bytes, Array.Empty<byte>());
-
- public byte[] ComputeHashWithDefaultMethod(byte[] bytes)
- => ComputeHash(DefaultHashMethod, bytes);
-
+ /// <inheritdoc />
public byte[] ComputeHash(string hashMethod, byte[] bytes, byte[] salt)
{
if (hashMethod == DefaultHashMethod)
@@ -90,15 +93,17 @@ namespace Emby.Server.Implementations.Cryptography
}
throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
-
}
+ /// <inheritdoc />
public byte[] ComputeHashWithDefaultMethod(byte[] bytes, byte[] salt)
=> PBKDF2(DefaultHashMethod, bytes, salt, DefaultIterations);
+ /// <inheritdoc />
public byte[] GenerateSalt()
=> GenerateSalt(DefaultSaltLength);
+ /// <inheritdoc />
public byte[] GenerateSalt(int length)
{
byte[] salt = new byte[length];
@@ -113,6 +118,10 @@ namespace Emby.Server.Implementations.Cryptography
GC.SuppressFinalize(this);
}
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources.
+ /// </summary>
+ /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
diff --git a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
index 4e392f6c9..0654132f4 100644
--- a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
+++ b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -11,6 +13,10 @@ namespace Emby.Server.Implementations.Data
{
private bool _disposed = false;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BaseSqliteRepository"/> class.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
protected BaseSqliteRepository(ILogger logger)
{
Logger = logger;
diff --git a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
index f7743a3c2..2a8f2d6b3 100644
--- a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
+++ b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Threading;
using System.Threading.Tasks;
diff --git a/Emby.Server.Implementations/Data/ManagedConnection.cs b/Emby.Server.Implementations/Data/ManagedConnection.cs
index 4c3424410..5c094ddd2 100644
--- a/Emby.Server.Implementations/Data/ManagedConnection.cs
+++ b/Emby.Server.Implementations/Data/ManagedConnection.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading;
diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
index 2f6c1288d..d474f1c6b 100644
--- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Emby.Server.Implementations/Data/SqliteExtensions.cs b/Emby.Server.Implementations/Data/SqliteExtensions.cs
index c76ae0cac..c87793072 100644
--- a/Emby.Server.Implementations/Data/SqliteExtensions.cs
+++ b/Emby.Server.Implementations/Data/SqliteExtensions.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 65f8a915f..69cfcb67b 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -7,6 +7,7 @@ using System.Text;
using System.Text.Json;
using System.Threading;
using Emby.Server.Implementations.Playlists;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Json;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Channels;
@@ -1177,7 +1178,7 @@ namespace Emby.Server.Implementations.Data
{
if (id == Guid.Empty)
{
- throw new ArgumentException(nameof(id), "Guid can't be empty");
+ throw new ArgumentException("Guid can't be empty", nameof(id));
}
CheckDisposed();
@@ -2831,8 +2832,8 @@ namespace Emby.Server.Implementations.Data
BindSimilarParams(query, statement);
BindSearchParams(query, statement);
- // Running this again will bind the params
- GetWhereClauses(query, statement);
+ // Running this again will bind the params
+ GetWhereClauses(query, statement);
var hasEpisodeAttributes = HasEpisodeAttributes(query);
var hasServiceName = HasServiceName(query);
@@ -2881,14 +2882,14 @@ namespace Emby.Server.Implementations.Data
private string GetOrderByText(InternalItemsQuery query)
{
+ var orderBy = query.OrderBy;
if (string.IsNullOrEmpty(query.SearchTerm))
{
- int oldLen = query.OrderBy.Length;
-
- if (query.SimilarTo != null && oldLen == 0)
+ int oldLen = orderBy.Count;
+ if (oldLen == 0 && query.SimilarTo != null)
{
var arr = new (string, SortOrder)[oldLen + 2];
- query.OrderBy.CopyTo(arr, 0);
+ orderBy.CopyTo(arr, 0);
arr[oldLen] = ("SimilarityScore", SortOrder.Descending);
arr[oldLen + 1] = (ItemSortBy.Random, SortOrder.Ascending);
query.OrderBy = arr;
@@ -2896,16 +2897,15 @@ namespace Emby.Server.Implementations.Data
}
else
{
- query.OrderBy = new []
+ query.OrderBy = new[]
{
("SearchScore", SortOrder.Descending),
(ItemSortBy.SortName, SortOrder.Ascending)
};
}
- var orderBy = query.OrderBy;
- if (orderBy.Length == 0)
+ if (orderBy.Count == 0)
{
return string.Empty;
}
@@ -2913,14 +2913,8 @@ namespace Emby.Server.Implementations.Data
return " ORDER BY " + string.Join(",", orderBy.Select(i =>
{
var columnMap = MapOrderByField(i.Item1, query);
- var columnAscending = i.Item2 == SortOrder.Ascending;
- const bool enableOrderInversion = false;
- if (columnMap.Item2 && enableOrderInversion)
- {
- columnAscending = !columnAscending;
- }
- var sortOrder = columnAscending ? "ASC" : "DESC";
+ var sortOrder = i.Item2 == SortOrder.Ascending ? "ASC" : "DESC";
return columnMap.Item1 + " " + sortOrder;
}));
diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
index 26ac17bdc..22955850a 100644
--- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs
index 26798993b..a042320c9 100644
--- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteUserRepository.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/Emby.Server.Implementations/Data/TypeMapper.cs b/Emby.Server.Implementations/Data/TypeMapper.cs
index 0e67affbf..7044b1d19 100644
--- a/Emby.Server.Implementations/Data/TypeMapper.cs
+++ b/Emby.Server.Implementations/Data/TypeMapper.cs
@@ -5,25 +5,22 @@ using System.Linq;
namespace Emby.Server.Implementations.Data
{
/// <summary>
- /// Class TypeMapper
+ /// Class TypeMapper.
/// </summary>
public class TypeMapper
{
/// <summary>
- /// This holds all the types in the running assemblies so that we can de-serialize properly when we don't have strong types
+ /// This holds all the types in the running assemblies
+ /// so that we can de-serialize properly when we don't have strong types.
/// </summary>
private readonly ConcurrentDictionary<string, Type> _typeMap = new ConcurrentDictionary<string, Type>();
- public TypeMapper()
- {
- }
-
/// <summary>
/// Gets the type.
/// </summary>
/// <param name="typeName">Name of the type.</param>
/// <returns>Type.</returns>
- /// <exception cref="ArgumentNullException"></exception>
+ /// <exception cref="ArgumentNullException"><c>typeName</c> is null.</exception>
public Type GetType(string typeName)
{
if (string.IsNullOrEmpty(typeName))
diff --git a/Emby.Server.Implementations/Devices/DeviceId.cs b/Emby.Server.Implementations/Devices/DeviceId.cs
index 7344dc72f..f0d43e665 100644
--- a/Emby.Server.Implementations/Devices/DeviceId.cs
+++ b/Emby.Server.Implementations/Devices/DeviceId.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Globalization;
using System.IO;
diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs
index d1704b373..2393f1f45 100644
--- a/Emby.Server.Implementations/Devices/DeviceManager.cs
+++ b/Emby.Server.Implementations/Devices/DeviceManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -130,7 +132,6 @@ namespace Emby.Server.Implementations.Devices
var session = _authRepo.Get(new AuthenticationInfoQuery
{
DeviceId = id
-
}).Items.FirstOrDefault();
var device = session == null ? null : ToDeviceInfo(session);
diff --git a/Emby.Server.Implementations/Diagnostics/CommonProcess.cs b/Emby.Server.Implementations/Diagnostics/CommonProcess.cs
index 175a8f3ce..bfa49ac5f 100644
--- a/Emby.Server.Implementations/Diagnostics/CommonProcess.cs
+++ b/Emby.Server.Implementations/Diagnostics/CommonProcess.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Diagnostics;
using System.IO;
diff --git a/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs b/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs
index 14aadaaae..02ad3c1a8 100644
--- a/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs
+++ b/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using MediaBrowser.Model.Diagnostics;
namespace Emby.Server.Implementations.Diagnostics
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index 6c0e32e05..3d622b3fc 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 45607dc09..115e07d57 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -1,8 +1,9 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Emby.Naming\Emby.Naming.csproj" />
<ProjectReference Include="..\Emby.Notifications\Emby.Notifications.csproj" />
+ <ProjectReference Include="..\Jellyfin.Api\Jellyfin.Api.csproj" />
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
@@ -14,12 +15,12 @@
<ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj" />
<ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj" />
<ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj" />
- <ProjectReference Include="..\Emby.XmlTv\Emby.XmlTv\Emby.XmlTv.csproj" />
<ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="IPNetwork2" Version="2.4.0.126" />
+ <PackageReference Include="Jellyfin.XmlTv" Version="10.4.3" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
@@ -28,13 +29,14 @@
<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="3.0.0" />
- <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
- <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.0.0" />
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.1" />
+ <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.0.1" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.0.1" />
<PackageReference Include="Mono.Nat" Version="2.0.0" />
- <PackageReference Include="ServiceStack.Text.Core" Version="5.6.0" />
+ <PackageReference Include="ServiceStack.Text.Core" Version="5.7.0" />
<PackageReference Include="sharpcompress" Version="0.24.0" />
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.0.1" />
+ <PackageReference Include="System.Interactive.Async" Version="4.0.0" />
</ItemGroup>
<ItemGroup>
@@ -49,7 +51,7 @@
<!-- Code analysers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
- <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.4" />
+ <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.7" />
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
diff --git a/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs
index 19ea09359..d69b0909d 100644
--- a/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs
+++ b/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Linq;
using System.Threading;
diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
index 08041eb59..e290c62e1 100644
--- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Net;
@@ -70,7 +72,6 @@ namespace Emby.Server.Implementations.EntryPoints
if (!string.Equals(_lastConfigIdentifier, GetConfigIdentifier(), StringComparison.OrdinalIgnoreCase))
{
Stop();
-
Start();
}
}
diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
index 9c0db2cf5..5f938e59a 100644
--- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -21,7 +23,7 @@ namespace Emby.Server.Implementations.EntryPoints
public class LibraryChangedNotifier : IServerEntryPoint
{
/// <summary>
- /// The _library manager
+ /// The library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
@@ -30,7 +32,7 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly ILogger _logger;
/// <summary>
- /// The _library changed sync lock
+ /// The library changed sync lock.
/// </summary>
private readonly object _libraryChangedSyncLock = new object();
@@ -48,7 +50,7 @@ namespace Emby.Server.Implementations.EntryPoints
private Timer LibraryUpdateTimer { get; set; }
/// <summary>
- /// The library update duration
+ /// The library update duration.
/// </summary>
private const int LibraryUpdateDuration = 30000;
@@ -188,8 +190,11 @@ namespace Emby.Server.Implementations.EntryPoints
{
if (LibraryUpdateTimer == null)
{
- LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration,
- Timeout.Infinite);
+ LibraryUpdateTimer = new Timer(
+ LibraryUpdateTimerCallback,
+ null,
+ LibraryUpdateDuration,
+ Timeout.Infinite);
}
else
{
@@ -452,7 +457,7 @@ namespace Emby.Server.Implementations.EntryPoints
return new[] { item };
}
- return new T[] { };
+ return Array.Empty<T>();
}
/// <summary>
diff --git a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs
index 0186da9e1..dbb3503c4 100644
--- a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Linq;
using System.Threading;
diff --git a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs
index 3a7516dca..f00996b5f 100644
--- a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs
+++ b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Library;
@@ -12,42 +11,51 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.EntryPoints
{
/// <summary>
- /// Class RefreshUsersMetadata
+ /// Class RefreshUsersMetadata.
/// </summary>
public class RefreshUsersMetadata : IScheduledTask, IConfigurableScheduledTask
{
private readonly ILogger _logger;
+
/// <summary>
- /// The _user manager
+ /// The user manager.
/// </summary>
private readonly IUserManager _userManager;
private IFileSystem _fileSystem;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class.
+ /// </summary>
+ public RefreshUsersMetadata(ILogger logger, IUserManager userManager, IFileSystem fileSystem)
+ {
+ _logger = logger;
+ _userManager = userManager;
+ _fileSystem = fileSystem;
+ }
+
+ /// <inheritdoc />
public string Name => "Refresh Users";
+ /// <inheritdoc />
public string Key => "RefreshUsers";
+ /// <inheritdoc />
public string Description => "Refresh user infos";
+ /// <inheritdoc />
public string Category => "Library";
+ /// <inheritdoc />
public bool IsHidden => true;
+ /// <inheritdoc />
public bool IsEnabled => true;
+ /// <inheritdoc />
public bool IsLogged => true;
- /// <summary>
- /// Initializes a new instance of the <see cref="RefreshUsersMetadata" /> class.
- /// </summary>
- public RefreshUsersMetadata(ILogger logger, IUserManager userManager, IFileSystem fileSystem)
- {
- _logger = logger;
- _userManager = userManager;
- _fileSystem = fileSystem;
- }
-
+ /// <inheritdoc />
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
{
foreach (var user in _userManager.Users)
@@ -58,9 +66,10 @@ namespace Emby.Server.Implementations.EntryPoints
}
}
+ /// <inheritdoc />
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
- return new List<TaskTriggerInfo>
+ return new[]
{
new TaskTriggerInfo
{
diff --git a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
index 141e72958..e1dbb663b 100644
--- a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
@@ -16,33 +16,46 @@ using MediaBrowser.Model.Tasks;
namespace Emby.Server.Implementations.EntryPoints
{
/// <summary>
- /// Class WebSocketEvents
+ /// Class WebSocketEvents.
/// </summary>
public class ServerEventNotifier : IServerEntryPoint
{
/// <summary>
- /// The _user manager
+ /// The user manager.
/// </summary>
private readonly IUserManager _userManager;
/// <summary>
- /// The _installation manager
+ /// The installation manager.
/// </summary>
private readonly IInstallationManager _installationManager;
/// <summary>
- /// The _kernel
+ /// The kernel.
/// </summary>
private readonly IServerApplicationHost _appHost;
/// <summary>
- /// The _task manager
+ /// The task manager.
/// </summary>
private readonly ITaskManager _taskManager;
private readonly ISessionManager _sessionManager;
- public ServerEventNotifier(IServerApplicationHost appHost, IUserManager userManager, IInstallationManager installationManager, ITaskManager taskManager, ISessionManager sessionManager)
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ServerEventNotifier"/> class.
+ /// </summary>
+ /// <param name="appHost">The application host.</param>
+ /// <param name="userManager">The user manager.</param>
+ /// <param name="installationManager">The installation manager.</param>
+ /// <param name="taskManager">The task manager.</param>
+ /// <param name="sessionManager">The session manager.</param>
+ public ServerEventNotifier(
+ IServerApplicationHost appHost,
+ IUserManager userManager,
+ IInstallationManager installationManager,
+ ITaskManager taskManager,
+ ISessionManager sessionManager)
{
_userManager = userManager;
_installationManager = installationManager;
@@ -51,47 +64,48 @@ namespace Emby.Server.Implementations.EntryPoints
_sessionManager = sessionManager;
}
+ /// <inheritdoc />
public Task RunAsync()
{
- _userManager.UserDeleted += userManager_UserDeleted;
- _userManager.UserUpdated += userManager_UserUpdated;
- _userManager.UserPolicyUpdated += _userManager_UserPolicyUpdated;
- _userManager.UserConfigurationUpdated += _userManager_UserConfigurationUpdated;
+ _userManager.UserDeleted += OnUserDeleted;
+ _userManager.UserUpdated += OnUserUpdated;
+ _userManager.UserPolicyUpdated += OnUserPolicyUpdated;
+ _userManager.UserConfigurationUpdated += OnUserConfigurationUpdated;
- _appHost.HasPendingRestartChanged += kernel_HasPendingRestartChanged;
+ _appHost.HasPendingRestartChanged += OnHasPendingRestartChanged;
- _installationManager.PluginUninstalled += InstallationManager_PluginUninstalled;
- _installationManager.PackageInstalling += _installationManager_PackageInstalling;
- _installationManager.PackageInstallationCancelled += _installationManager_PackageInstallationCancelled;
- _installationManager.PackageInstallationCompleted += _installationManager_PackageInstallationCompleted;
- _installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed;
+ _installationManager.PluginUninstalled += OnPluginUninstalled;
+ _installationManager.PackageInstalling += OnPackageInstalling;
+ _installationManager.PackageInstallationCancelled += OnPackageInstallationCancelled;
+ _installationManager.PackageInstallationCompleted += OnPackageInstallationCompleted;
+ _installationManager.PackageInstallationFailed += OnPackageInstallationFailed;
- _taskManager.TaskCompleted += _taskManager_TaskCompleted;
+ _taskManager.TaskCompleted += OnTaskCompleted;
return Task.CompletedTask;
}
- void _installationManager_PackageInstalling(object sender, InstallationEventArgs e)
+ private void OnPackageInstalling(object sender, InstallationEventArgs e)
{
SendMessageToAdminSessions("PackageInstalling", e.InstallationInfo);
}
- void _installationManager_PackageInstallationCancelled(object sender, InstallationEventArgs e)
+ private void OnPackageInstallationCancelled(object sender, InstallationEventArgs e)
{
SendMessageToAdminSessions("PackageInstallationCancelled", e.InstallationInfo);
}
- void _installationManager_PackageInstallationCompleted(object sender, InstallationEventArgs e)
+ private void OnPackageInstallationCompleted(object sender, InstallationEventArgs e)
{
SendMessageToAdminSessions("PackageInstallationCompleted", e.InstallationInfo);
}
- void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e)
+ private void OnPackageInstallationFailed(object sender, InstallationFailedEventArgs e)
{
SendMessageToAdminSessions("PackageInstallationFailed", e.InstallationInfo);
}
- void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e)
+ private void OnTaskCompleted(object sender, TaskCompletionEventArgs e)
{
SendMessageToAdminSessions("ScheduledTaskEnded", e.Result);
}
@@ -101,7 +115,7 @@ namespace Emby.Server.Implementations.EntryPoints
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
- void InstallationManager_PluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
+ private void OnPluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
{
SendMessageToAdminSessions("PluginUninstalled", e.Argument.GetPluginInfo());
}
@@ -111,7 +125,7 @@ namespace Emby.Server.Implementations.EntryPoints
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
- void kernel_HasPendingRestartChanged(object sender, EventArgs e)
+ private void OnHasPendingRestartChanged(object sender, EventArgs e)
{
_sessionManager.SendRestartRequiredNotification(CancellationToken.None);
}
@@ -121,7 +135,7 @@ namespace Emby.Server.Implementations.EntryPoints
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
- void userManager_UserUpdated(object sender, GenericEventArgs<User> e)
+ private void OnUserUpdated(object sender, GenericEventArgs<User> e)
{
var dto = _userManager.GetUserDto(e.Argument);
@@ -133,19 +147,19 @@ namespace Emby.Server.Implementations.EntryPoints
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
- void userManager_UserDeleted(object sender, GenericEventArgs<User> e)
+ private void OnUserDeleted(object sender, GenericEventArgs<User> e)
{
SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N", CultureInfo.InvariantCulture));
}
- void _userManager_UserPolicyUpdated(object sender, GenericEventArgs<User> e)
+ private void OnUserPolicyUpdated(object sender, GenericEventArgs<User> e)
{
var dto = _userManager.GetUserDto(e.Argument);
SendMessageToUserSession(e.Argument, "UserPolicyUpdated", dto);
}
- void _userManager_UserConfigurationUpdated(object sender, GenericEventArgs<User> e)
+ private void OnUserConfigurationUpdated(object sender, GenericEventArgs<User> e)
{
var dto = _userManager.GetUserDto(e.Argument);
@@ -156,7 +170,7 @@ namespace Emby.Server.Implementations.EntryPoints
{
try
{
- await _sessionManager.SendMessageToAdminSessions(name, data, CancellationToken.None);
+ await _sessionManager.SendMessageToAdminSessions(name, data, CancellationToken.None).ConfigureAwait(false);
}
catch (Exception)
{
@@ -168,7 +182,11 @@ namespace Emby.Server.Implementations.EntryPoints
{
try
{
- await _sessionManager.SendMessageToUserSessions(new List<Guid> { user.Id }, name, data, CancellationToken.None);
+ await _sessionManager.SendMessageToUserSessions(
+ new List<Guid> { user.Id },
+ name,
+ data,
+ CancellationToken.None).ConfigureAwait(false);
}
catch (Exception)
{
@@ -176,12 +194,11 @@ namespace Emby.Server.Implementations.EntryPoints
}
}
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
+ /// <inheritdoc />
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
/// <summary>
@@ -192,18 +209,20 @@ namespace Emby.Server.Implementations.EntryPoints
{
if (dispose)
{
- _userManager.UserDeleted -= userManager_UserDeleted;
- _userManager.UserUpdated -= userManager_UserUpdated;
- _userManager.UserPolicyUpdated -= _userManager_UserPolicyUpdated;
- _userManager.UserConfigurationUpdated -= _userManager_UserConfigurationUpdated;
-
- _installationManager.PluginUninstalled -= InstallationManager_PluginUninstalled;
- _installationManager.PackageInstalling -= _installationManager_PackageInstalling;
- _installationManager.PackageInstallationCancelled -= _installationManager_PackageInstallationCancelled;
- _installationManager.PackageInstallationCompleted -= _installationManager_PackageInstallationCompleted;
- _installationManager.PackageInstallationFailed -= _installationManager_PackageInstallationFailed;
-
- _appHost.HasPendingRestartChanged -= kernel_HasPendingRestartChanged;
+ _userManager.UserDeleted -= OnUserDeleted;
+ _userManager.UserUpdated -= OnUserUpdated;
+ _userManager.UserPolicyUpdated -= OnUserPolicyUpdated;
+ _userManager.UserConfigurationUpdated -= OnUserConfigurationUpdated;
+
+ _installationManager.PluginUninstalled -= OnPluginUninstalled;
+ _installationManager.PackageInstalling -= OnPackageInstalling;
+ _installationManager.PackageInstallationCancelled -= OnPackageInstallationCancelled;
+ _installationManager.PackageInstallationCompleted -= OnPackageInstallationCompleted;
+ _installationManager.PackageInstallationFailed -= OnPackageInstallationFailed;
+
+ _appHost.HasPendingRestartChanged -= OnHasPendingRestartChanged;
+
+ _taskManager.TaskCompleted -= OnTaskCompleted;
}
}
}
diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
index 8be6db87d..161788c63 100644
--- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
+++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
@@ -8,21 +8,28 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.EntryPoints
{
/// <summary>
- /// Class StartupWizard
+ /// Class StartupWizard.
/// </summary>
public class StartupWizard : IServerEntryPoint
{
/// <summary>
- /// The _app host
+ /// The app host.
/// </summary>
private readonly IServerApplicationHost _appHost;
+
/// <summary>
- /// The _user manager
+ /// The user manager.
/// </summary>
private readonly ILogger _logger;
private IServerConfigurationManager _config;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="StartupWizard"/> class.
+ /// </summary>
+ /// <param name="appHost">The application host.</param>
+ /// <param name="logger">The logger.</param>
+ /// <param name="config">The configuration manager.</param>
public StartupWizard(IServerApplicationHost appHost, ILogger logger, IServerConfigurationManager config)
{
_appHost = appHost;
@@ -30,9 +37,7 @@ namespace Emby.Server.Implementations.EntryPoints
_config = config;
}
- /// <summary>
- /// Runs this instance.
- /// </summary>
+ /// <inheritdoc />
public Task RunAsync()
{
if (!_appHost.CanLaunchWebBrowser)
@@ -57,9 +62,7 @@ namespace Emby.Server.Implementations.EntryPoints
return Task.CompletedTask;
}
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
+ /// <inheritdoc />
public void Dispose()
{
}
diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
index 5b90dc1fb..9ee219854 100644
--- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
+++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
@@ -10,30 +10,36 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.EntryPoints
{
/// <summary>
- /// Class UdpServerEntryPoint
+ /// Class UdpServerEntryPoint.
/// </summary>
public class UdpServerEntryPoint : IServerEntryPoint
{
/// <summary>
- /// Gets or sets the UDP server.
+ /// The port of the UDP server.
/// </summary>
- /// <value>The UDP server.</value>
- private UdpServer UdpServer { get; set; }
+ public const int PortNumber = 7359;
/// <summary>
- /// The _logger
+ /// The logger.
/// </summary>
private readonly ILogger _logger;
private readonly ISocketFactory _socketFactory;
private readonly IServerApplicationHost _appHost;
private readonly IJsonSerializer _json;
- public const int PortNumber = 7359;
+ /// <summary>
+ /// The UDP server.
+ /// </summary>
+ private UdpServer _udpServer;
/// <summary>
/// Initializes a new instance of the <see cref="UdpServerEntryPoint" /> class.
/// </summary>
- public UdpServerEntryPoint(ILogger logger, IServerApplicationHost appHost, IJsonSerializer json, ISocketFactory socketFactory)
+ public UdpServerEntryPoint(
+ ILogger logger,
+ IServerApplicationHost appHost,
+ IJsonSerializer json,
+ ISocketFactory socketFactory)
{
_logger = logger;
_appHost = appHost;
@@ -41,9 +47,7 @@ namespace Emby.Server.Implementations.EntryPoints
_socketFactory = socketFactory;
}
- /// <summary>
- /// Runs this instance.
- /// </summary>
+ /// <inheritdoc />
public Task RunAsync()
{
var udpServer = new UdpServer(_logger, _appHost, _json, _socketFactory);
@@ -52,7 +56,7 @@ namespace Emby.Server.Implementations.EntryPoints
{
udpServer.Start(PortNumber);
- UdpServer = udpServer;
+ _udpServer = udpServer;
}
catch (Exception ex)
{
@@ -62,12 +66,11 @@ namespace Emby.Server.Implementations.EntryPoints
return Task.CompletedTask;
}
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
+ /// <inheritdoc />
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
/// <summary>
@@ -78,9 +81,9 @@ namespace Emby.Server.Implementations.EntryPoints
{
if (dispose)
{
- if (UdpServer != null)
+ if (_udpServer != null)
{
- UdpServer.Dispose();
+ _udpServer.Dispose();
}
}
}
diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
index bae3422ff..e431da148 100644
--- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs
index 0e6083773..50233ea48 100644
--- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs
@@ -282,6 +282,7 @@ namespace Emby.Server.Implementations.HttpClientManager
};
}
+ /// <inheritdoc />
public Task<HttpResponseInfo> Post(HttpRequestOptions options)
=> SendAsync(options, HttpMethod.Post);
@@ -325,7 +326,7 @@ namespace Emby.Server.Implementations.HttpClientManager
if (options.LogErrorResponseBody)
{
- var msg = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ string msg = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
_logger.LogError("HTTP request failed with message: {Message}", msg);
}
diff --git a/Emby.Server.Implementations/HttpServer/FileWriter.cs b/Emby.Server.Implementations/HttpServer/FileWriter.cs
index 2c7e81361..c1c8c3eb3 100644
--- a/Emby.Server.Implementations/HttpServer/FileWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/FileWriter.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index dc1a56e27..2aefc9fe5 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -18,7 +20,6 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
@@ -164,7 +165,7 @@ namespace Emby.Server.Implementations.HttpServer
{
OnReceive = ProcessWebSocketMessageReceived,
Url = e.Url,
- QueryString = e.QueryString ?? new QueryCollection()
+ QueryString = e.QueryString
};
connection.Closed += OnConnectionClosed;
diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
index 0b2924a3b..a62b4e7af 100644
--- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -5,12 +7,10 @@ using System.IO;
using System.IO.Compression;
using System.Net;
using System.Runtime.Serialization;
-using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Emby.Server.Implementations.Services;
-using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
@@ -24,12 +24,12 @@ using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
namespace Emby.Server.Implementations.HttpServer
{
/// <summary>
- /// Class HttpResultFactory
+ /// Class HttpResultFactory.
/// </summary>
public class HttpResultFactory : IHttpResultFactory
{
/// <summary>
- /// The _logger
+ /// The logger.
/// </summary>
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
@@ -460,7 +460,7 @@ namespace Emby.Server.Implementations.HttpServer
if (string.IsNullOrEmpty(path))
{
- throw new ArgumentNullException(nameof(path));
+ throw new ArgumentException("Path can't be empty.", nameof(options));
}
if (fileShare != FileShareMode.Read && fileShare != FileShareMode.ReadWrite)
diff --git a/Emby.Server.Implementations/HttpServer/IHttpListener.cs b/Emby.Server.Implementations/HttpServer/IHttpListener.cs
index 005656d2c..501593725 100644
--- a/Emby.Server.Implementations/HttpServer/IHttpListener.cs
+++ b/Emby.Server.Implementations/HttpServer/IHttpListener.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Threading;
using System.Threading.Tasks;
diff --git a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
index e27f794ba..8b9028f6b 100644
--- a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -48,12 +50,14 @@ namespace Emby.Server.Implementations.HttpServer
public IDictionary<string, string> Headers => _options;
/// <summary>
- /// Initializes a new instance of the <see cref="StreamWriter" /> class.
+ /// Initializes a new instance of the <see cref="RangeRequestWriter" /> class.
/// </summary>
/// <param name="rangeHeader">The range header.</param>
+ /// <param name="contentLength">The content length.</param>
/// <param name="source">The source.</param>
/// <param name="contentType">Type of the content.</param>
/// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
+ /// <param name="logger">The logger instance.</param>
public RangeRequestWriter(string rangeHeader, long contentLength, Stream source, string contentType, bool isHeadRequest, ILogger logger)
{
if (string.IsNullOrEmpty(contentType))
diff --git a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
index 3e731366e..5e0466629 100644
--- a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
+++ b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs
@@ -8,11 +8,17 @@ using Microsoft.Net.Http.Headers;
namespace Emby.Server.Implementations.HttpServer
{
+ /// <summary>
+ /// Class ResponseFilter.
+ /// </summary>
public class ResponseFilter
{
- private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US"));
private readonly ILogger _logger;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ResponseFilter"/> class.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
public ResponseFilter(ILogger logger)
{
_logger = logger;
@@ -37,7 +43,7 @@ namespace Emby.Server.Implementations.HttpServer
if (!string.IsNullOrEmpty(exception.Message))
{
- var error = exception.Message.Replace(Environment.NewLine, " ");
+ var error = exception.Message.Replace(Environment.NewLine, " ", StringComparison.Ordinal);
error = RemoveControlCharacters(error);
res.Headers.Add("X-Application-Error-Code", error);
@@ -55,7 +61,7 @@ namespace Emby.Server.Implementations.HttpServer
if (hasHeaders.Headers.TryGetValue(HeaderNames.ContentLength, out string contentLength)
&& !string.IsNullOrEmpty(contentLength))
{
- var length = long.Parse(contentLength, _usCulture);
+ var length = long.Parse(contentLength, CultureInfo.InvariantCulture);
if (length > 0)
{
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
index 93a61fe67..58421aaf1 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
@@ -1,5 +1,8 @@
+#pragma warning disable CS1591
+
using System;
using System.Linq;
+using Emby.Server.Implementations.SocketSharp;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
@@ -7,22 +10,27 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Services;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.HttpServer.Security
{
public class AuthService : IAuthService
{
+ private readonly ILogger<AuthService> _logger;
private readonly IAuthorizationContext _authorizationContext;
private readonly ISessionManager _sessionManager;
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
public AuthService(
+ ILogger<AuthService> logger,
IAuthorizationContext authorizationContext,
IServerConfigurationManager config,
ISessionManager sessionManager,
INetworkManager networkManager)
{
+ _logger = logger;
_authorizationContext = authorizationContext;
_config = config;
_sessionManager = sessionManager;
@@ -34,7 +42,14 @@ namespace Emby.Server.Implementations.HttpServer.Security
ValidateUser(request, authAttribtues);
}
- private void ValidateUser(IRequest request, IAuthenticationAttributes authAttribtues)
+ public User Authenticate(HttpRequest request, IAuthenticationAttributes authAttributes)
+ {
+ var req = new WebSocketSharpRequest(request, null, request.Path, _logger);
+ var user = ValidateUser(req, authAttributes);
+ return user;
+ }
+
+ private User ValidateUser(IRequest request, IAuthenticationAttributes authAttribtues)
{
// This code is executed before the service
var auth = _authorizationContext.GetAuthorizationInfo(request);
@@ -81,6 +96,8 @@ namespace Emby.Server.Implementations.HttpServer.Security
request.RemoteIp,
user);
}
+
+ return user;
}
private void ValidateUserAccess(
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
index 457448604..129faeaab 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
index 81e11d312..166952c64 100644
--- a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
diff --git a/Emby.Server.Implementations/HttpServer/StreamWriter.cs b/Emby.Server.Implementations/HttpServer/StreamWriter.cs
index 194d04441..5afc51dbc 100644
--- a/Emby.Server.Implementations/HttpServer/StreamWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/StreamWriter.cs
@@ -10,37 +10,20 @@ using Microsoft.Net.Http.Headers;
namespace Emby.Server.Implementations.HttpServer
{
/// <summary>
- /// Class StreamWriter
+ /// Class StreamWriter.
/// </summary>
public class StreamWriter : IAsyncStreamWriter, IHasHeaders
{
/// <summary>
- /// Gets or sets the source stream.
- /// </summary>
- /// <value>The source stream.</value>
- private Stream SourceStream { get; set; }
-
- private byte[] SourceBytes { get; set; }
-
- /// <summary>
- /// The _options
+ /// The options.
/// </summary>
private readonly IDictionary<string, string> _options = new Dictionary<string, string>();
- /// <summary>
- /// Gets the options.
- /// </summary>
- /// <value>The options.</value>
- public IDictionary<string, string> Headers => _options;
-
- public Action OnComplete { get; set; }
- public Action OnError { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="StreamWriter" /> class.
/// </summary>
/// <param name="source">The source.</param>
/// <param name="contentType">Type of the content.</param>
- /// <param name="logger">The logger.</param>
public StreamWriter(Stream source, string contentType)
{
if (string.IsNullOrEmpty(contentType))
@@ -65,6 +48,7 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
/// <param name="source">The source.</param>
/// <param name="contentType">Type of the content.</param>
+ /// <param name="contentLength">The content length.</param>
public StreamWriter(byte[] source, string contentType, int contentLength)
{
if (string.IsNullOrEmpty(contentType))
@@ -78,6 +62,31 @@ namespace Emby.Server.Implementations.HttpServer
Headers[HeaderNames.ContentType] = contentType;
}
+ /// <summary>
+ /// Gets or sets the source stream.
+ /// </summary>
+ /// <value>The source stream.</value>
+ private Stream SourceStream { get; set; }
+
+ private byte[] SourceBytes { get; set; }
+
+ /// <summary>
+ /// Gets the options.
+ /// </summary>
+ /// <value>The options.</value>
+ public IDictionary<string, string> Headers => _options;
+
+ /// <summary>
+ /// Fires when complete.
+ /// </summary>
+ public Action OnComplete { get; set; }
+
+ /// <summary>
+ /// Fires when an error occours.
+ /// </summary>
+ public Action OnError { get; set; }
+
+ /// <inheritdoc />
public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)
{
try
@@ -98,19 +107,13 @@ namespace Emby.Server.Implementations.HttpServer
}
catch
{
- if (OnError != null)
- {
- OnError();
- }
+ OnError?.Invoke();
throw;
}
finally
{
- if (OnComplete != null)
- {
- OnComplete();
- }
+ OnComplete?.Invoke();
}
}
}
diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
index 54a16040f..2292d86a4 100644
--- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
+++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
@@ -7,7 +7,6 @@ using Emby.Server.Implementations.Net;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using UtfUnknown;
@@ -15,60 +14,24 @@ using UtfUnknown;
namespace Emby.Server.Implementations.HttpServer
{
/// <summary>
- /// Class WebSocketConnection
+ /// Class WebSocketConnection.
/// </summary>
public class WebSocketConnection : IWebSocketConnection
{
- public event EventHandler<EventArgs> Closed;
-
- /// <summary>
- /// The _socket
- /// </summary>
- private readonly IWebSocket _socket;
-
/// <summary>
- /// The _remote end point
- /// </summary>
- public string RemoteEndPoint { get; private set; }
-
- /// <summary>
- /// The logger
+ /// The logger.
/// </summary>
private readonly ILogger _logger;
/// <summary>
- /// The _json serializer
+ /// The json serializer.
/// </summary>
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
- /// Gets or sets the receive action.
- /// </summary>
- /// <value>The receive action.</value>
- public Func<WebSocketMessageInfo, Task> OnReceive { get; set; }
-
- /// <summary>
- /// Gets the last activity date.
- /// </summary>
- /// <value>The last activity date.</value>
- public DateTime LastActivityDate { get; private set; }
-
- /// <summary>
- /// Gets the id.
+ /// The socket.
/// </summary>
- /// <value>The id.</value>
- public Guid Id { get; private set; }
-
- /// <summary>
- /// Gets or sets the URL.
- /// </summary>
- /// <value>The URL.</value>
- public string Url { get; set; }
- /// <summary>
- /// Gets or sets the query string.
- /// </summary>
- /// <value>The query string.</value>
- public IQueryCollection QueryString { get; set; }
+ private readonly IWebSocket _socket;
/// <summary>
/// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
@@ -84,14 +47,17 @@ namespace Emby.Server.Implementations.HttpServer
{
throw new ArgumentNullException(nameof(socket));
}
+
if (string.IsNullOrEmpty(remoteEndPoint))
{
throw new ArgumentNullException(nameof(remoteEndPoint));
}
+
if (jsonSerializer == null)
{
throw new ArgumentNullException(nameof(jsonSerializer));
}
+
if (logger == null)
{
throw new ArgumentNullException(nameof(logger));
@@ -105,10 +71,54 @@ namespace Emby.Server.Implementations.HttpServer
RemoteEndPoint = remoteEndPoint;
_logger = logger;
- socket.Closed += socket_Closed;
+ socket.Closed += OnSocketClosed;
}
- void socket_Closed(object sender, EventArgs e)
+ /// <inheritdoc />
+ public event EventHandler<EventArgs> Closed;
+
+ /// <summary>
+ /// Gets or sets the remote end point.
+ /// </summary>
+ public string RemoteEndPoint { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the receive action.
+ /// </summary>
+ /// <value>The receive action.</value>
+ public Func<WebSocketMessageInfo, Task> OnReceive { get; set; }
+
+ /// <summary>
+ /// Gets the last activity date.
+ /// </summary>
+ /// <value>The last activity date.</value>
+ public DateTime LastActivityDate { get; private set; }
+
+ /// <summary>
+ /// Gets the id.
+ /// </summary>
+ /// <value>The id.</value>
+ public Guid Id { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the URL.
+ /// </summary>
+ /// <value>The URL.</value>
+ public string Url { get; set; }
+
+ /// <summary>
+ /// Gets or sets the query string.
+ /// </summary>
+ /// <value>The query string.</value>
+ public IQueryCollection QueryString { get; set; }
+
+ /// <summary>
+ /// Gets the state.
+ /// </summary>
+ /// <value>The state.</value>
+ public WebSocketState State => _socket.State;
+
+ void OnSocketClosed(object sender, EventArgs e)
{
Closed?.Invoke(this, EventArgs.Empty);
}
@@ -210,6 +220,7 @@ namespace Emby.Server.Implementations.HttpServer
return _socket.SendAsync(buffer, true, cancellationToken);
}
+ /// <inheritdoc />
public Task SendAsync(string text, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(text))
@@ -222,18 +233,11 @@ namespace Emby.Server.Implementations.HttpServer
return _socket.SendAsync(text, true, cancellationToken);
}
- /// <summary>
- /// Gets the state.
- /// </summary>
- /// <value>The state.</value>
- public WebSocketState State => _socket.State;
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
+ /// <inheritdoc />
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
/// <summary>
diff --git a/Emby.Server.Implementations/IO/ExtendedFileSystemInfo.cs b/Emby.Server.Implementations/IO/ExtendedFileSystemInfo.cs
index 48b34a3a0..3150f3367 100644
--- a/Emby.Server.Implementations/IO/ExtendedFileSystemInfo.cs
+++ b/Emby.Server.Implementations/IO/ExtendedFileSystemInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace Emby.Server.Implementations.IO
{
public class ExtendedFileSystemInfo
diff --git a/Emby.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs
index 40e8ed5dc..4b5b11f01 100644
--- a/Emby.Server.Implementations/IO/FileRefresher.cs
+++ b/Emby.Server.Implementations/IO/FileRefresher.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs
index aeb541c54..b1fb8cc63 100644
--- a/Emby.Server.Implementations/IO/LibraryMonitor.cs
+++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -16,22 +18,22 @@ namespace Emby.Server.Implementations.IO
public class LibraryMonitor : ILibraryMonitor
{
/// <summary>
- /// The file system watchers
+ /// The file system watchers.
/// </summary>
private readonly ConcurrentDictionary<string, FileSystemWatcher> _fileSystemWatchers = new ConcurrentDictionary<string, FileSystemWatcher>(StringComparer.OrdinalIgnoreCase);
/// <summary>
- /// The affected paths
+ /// The affected paths.
/// </summary>
private readonly List<FileRefresher> _activeRefreshers = new List<FileRefresher>();
/// <summary>
- /// A dynamic list of paths that should be ignored. Added to during our own file sytem modifications.
+ /// A dynamic list of paths that should be ignored. Added to during our own file system modifications.
/// </summary>
private readonly ConcurrentDictionary<string, string> _tempIgnoredPaths = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
/// <summary>
- /// Any file name ending in any of these will be ignored by the watchers
+ /// Any file name ending in any of these will be ignored by the watchers.
/// </summary>
private static readonly HashSet<string> _alwaysIgnoreFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs
index ae8371a32..442fbabd1 100644
--- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs
+++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs b/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs
index 5e5e91bb3..e6696b8c4 100644
--- a/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs
+++ b/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.IO;
using MediaBrowser.Model.IO;
diff --git a/Emby.Server.Implementations/IO/StreamHelper.cs b/Emby.Server.Implementations/IO/StreamHelper.cs
index 7c8c079e3..40b397edc 100644
--- a/Emby.Server.Implementations/IO/StreamHelper.cs
+++ b/Emby.Server.Implementations/IO/StreamHelper.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Buffers;
using System.IO;
diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs
index 6afcf567a..fd50f156a 100644
--- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs
+++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
index 8bdb38784..bc1398332 100644
--- a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
+++ b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
@@ -42,6 +42,10 @@ namespace Emby.Server.Implementations.Library
".grab",
};
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CoreResolutionIgnoreRule"/> class.
+ /// </summary>
+ /// <param name="libraryManager">The library manager.</param>
public CoreResolutionIgnoreRule(ILibraryManager libraryManager)
{
_libraryManager = libraryManager;
diff --git a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
index 85110c21c..94f60ea62 100644
--- a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
+++ b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
@@ -10,10 +10,17 @@ using MediaBrowser.Model.Cryptography;
namespace Emby.Server.Implementations.Library
{
+ /// <summary>
+ /// The default authentication provider.
+ /// </summary>
public class DefaultAuthenticationProvider : IAuthenticationProvider, IRequiresResolvedUser
{
private readonly ICryptoProvider _cryptographyProvider;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultAuthenticationProvider"/> class.
+ /// </summary>
+ /// <param name="cryptographyProvider">The cryptography provider.</param>
public DefaultAuthenticationProvider(ICryptoProvider cryptographyProvider)
{
_cryptographyProvider = cryptographyProvider;
@@ -38,12 +45,13 @@ namespace Emby.Server.Implementations.Library
// This is the version that we need to use for local users. Because reasons.
public Task<ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser)
{
- bool success = false;
if (resolvedUser == null)
{
throw new ArgumentNullException(nameof(resolvedUser));
}
+ bool success = false;
+
// As long as jellyfin supports passwordless users, we need this little block here to accommodate
if (!HasPassword(resolvedUser) && string.IsNullOrEmpty(password))
{
@@ -59,7 +67,10 @@ namespace Emby.Server.Implementations.Library
if (_cryptographyProvider.GetSupportedHashMethods().Contains(readyHash.Id)
|| _cryptographyProvider.DefaultHashMethod == readyHash.Id)
{
- byte[] calculatedHash = _cryptographyProvider.ComputeHash(readyHash.Id, passwordbytes, readyHash.Salt);
+ byte[] calculatedHash = _cryptographyProvider.ComputeHash(
+ readyHash.Id,
+ passwordbytes,
+ readyHash.Salt);
if (calculatedHash.SequenceEqual(readyHash.Hash))
{
diff --git a/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs b/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs
index fa6bbcf91..6c6fbd86f 100644
--- a/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs
+++ b/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs
@@ -12,6 +12,9 @@ using MediaBrowser.Model.Users;
namespace Emby.Server.Implementations.Library
{
+ /// <summary>
+ /// The default password reset provider.
+ /// </summary>
public class DefaultPasswordResetProvider : IPasswordResetProvider
{
private const string BaseResetFileName = "passwordreset";
@@ -22,6 +25,12 @@ namespace Emby.Server.Implementations.Library
private readonly string _passwordResetFileBase;
private readonly string _passwordResetFileBaseDir;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultPasswordResetProvider"/> class.
+ /// </summary>
+ /// <param name="configurationManager">The configuration manager.</param>
+ /// <param name="jsonSerializer">The JSON serializer.</param>
+ /// <param name="userManager">The user manager.</param>
public DefaultPasswordResetProvider(
IServerConfigurationManager configurationManager,
IJsonSerializer jsonSerializer,
@@ -56,8 +65,8 @@ namespace Emby.Server.Implementations.Library
File.Delete(resetfile);
}
else if (string.Equals(
- spr.Pin.Replace("-", string.Empty),
- pin.Replace("-", string.Empty),
+ spr.Pin.Replace("-", string.Empty, StringComparison.Ordinal),
+ pin.Replace("-", string.Empty, StringComparison.Ordinal),
StringComparison.InvariantCultureIgnoreCase))
{
var resetUser = _userManager.GetUserByName(spr.UserName);
diff --git a/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs b/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs
index a3c879f12..9a7186898 100644
--- a/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs
+++ b/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Globalization;
using System.Threading;
diff --git a/Emby.Server.Implementations/Library/InvalidAuthProvider.cs b/Emby.Server.Implementations/Library/InvalidAuthProvider.cs
index 7913df5e4..dc61aacd7 100644
--- a/Emby.Server.Implementations/Library/InvalidAuthProvider.cs
+++ b/Emby.Server.Implementations/Library/InvalidAuthProvider.cs
@@ -4,37 +4,48 @@ using MediaBrowser.Controller.Entities;
namespace Emby.Server.Implementations.Library
{
+ /// <summary>
+ /// An invalid authentication provider.
+ /// </summary>
public class InvalidAuthProvider : IAuthenticationProvider
{
+ /// <inheritdoc />
public string Name => "InvalidOrMissingAuthenticationProvider";
+ /// <inheritdoc />
public bool IsEnabled => true;
+ /// <inheritdoc />
public Task<ProviderAuthenticationResult> Authenticate(string username, string password)
{
throw new AuthenticationException("User Account cannot login with this provider. The Normal provider for this user cannot be found");
}
+ /// <inheritdoc />
public bool HasPassword(User user)
{
return true;
}
+ /// <inheritdoc />
public Task ChangePassword(User user, string newPassword)
{
return Task.CompletedTask;
}
+ /// <inheritdoc />
public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash)
{
// Nothing here
}
+ /// <inheritdoc />
public string GetPasswordHash(User user)
{
return string.Empty;
}
+ /// <inheritdoc />
public string GetEasyPasswordHash(User user)
{
return string.Empty;
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 528636ecd..6942088fe 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -829,7 +831,7 @@ namespace Emby.Server.Implementations.Library
{
Path = path,
IsFolder = isFolder,
- OrderBy = new[] { ItemSortBy.DateCreated }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
+ OrderBy = new[] { (ItemSortBy.DateCreated, SortOrder.Descending) },
Limit = 1,
DtoOptions = new DtoOptions(true)
};
@@ -1257,7 +1259,7 @@ namespace Emby.Server.Implementations.Library
public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
{
- if (query.Recursive && !query.ParentId.Equals(Guid.Empty))
+ if (query.Recursive && query.ParentId != Guid.Empty)
{
var parent = GetItemById(query.ParentId);
if (parent != null)
diff --git a/Emby.Server.Implementations/Library/LiveStreamHelper.cs b/Emby.Server.Implementations/Library/LiveStreamHelper.cs
index 33e6f2434..ed7d8aa40 100644
--- a/Emby.Server.Implementations/Library/LiveStreamHelper.cs
+++ b/Emby.Server.Implementations/Library/LiveStreamHelper.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs
index 7a26e0c37..22193c997 100644
--- a/Emby.Server.Implementations/Library/MediaSourceManager.cs
+++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/Emby.Server.Implementations/Library/MediaStreamSelector.cs b/Emby.Server.Implementations/Library/MediaStreamSelector.cs
index 0a6c8845d..6b9f4d052 100644
--- a/Emby.Server.Implementations/Library/MediaStreamSelector.cs
+++ b/Emby.Server.Implementations/Library/MediaStreamSelector.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/Emby.Server.Implementations/Library/MusicManager.cs b/Emby.Server.Implementations/Library/MusicManager.cs
index 10602fea7..1ec578371 100644
--- a/Emby.Server.Implementations/Library/MusicManager.cs
+++ b/Emby.Server.Implementations/Library/MusicManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -89,10 +91,9 @@ namespace Emby.Server.Implementations.Library
Limit = 200,
- OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) },
+ OrderBy = new[] { (ItemSortBy.Random, SortOrder.Ascending) },
DtoOptions = dtoOptions
-
});
}
diff --git a/Emby.Server.Implementations/Library/PathExtensions.cs b/Emby.Server.Implementations/Library/PathExtensions.cs
index d3a81f622..4fdf73b77 100644
--- a/Emby.Server.Implementations/Library/PathExtensions.cs
+++ b/Emby.Server.Implementations/Library/PathExtensions.cs
@@ -3,6 +3,9 @@ using System.Text.RegularExpressions;
namespace Emby.Server.Implementations.Library
{
+ /// <summary>
+ /// Class providing extension methods for working with paths.
+ /// </summary>
public static class PathExtensions
{
/// <summary>
@@ -32,6 +35,7 @@ namespace Emby.Server.Implementations.Library
int end = str.IndexOf(']', start);
return str.Substring(start, end - start);
}
+
// for imdbid we also accept pattern matching
if (string.Equals(attrib, "imdbid", StringComparison.OrdinalIgnoreCase))
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
index e39192d28..9d4bd9e59 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
@@ -13,7 +15,7 @@ using MediaBrowser.Model.IO;
namespace Emby.Server.Implementations.Library.Resolvers.Audio
{
/// <summary>
- /// Class AudioResolver
+ /// Class AudioResolver.
/// </summary>
public class AudioResolver : ItemResolver<MediaBrowser.Controller.Entities.Audio.Audio>, IMultiItemResolver
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index 3ce1da81a..4a2d210d5 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
@@ -13,7 +13,7 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Resolvers.Audio
{
/// <summary>
- /// Class MusicAlbumResolver
+ /// Class MusicAlbumResolver.
/// </summary>
public class MusicAlbumResolver : ItemResolver<MusicAlbum>
{
@@ -21,6 +21,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
private readonly IFileSystem _fileSystem;
private readonly ILibraryManager _libraryManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MusicAlbumResolver"/> class.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ /// <param name="fileSystem">The file system.</param>
+ /// <param name="libraryManager">The library manager.</param>
public MusicAlbumResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager)
{
_logger = logger;
@@ -50,16 +56,25 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
return null;
}
- if (!args.IsDirectory) return null;
+ if (!args.IsDirectory)
+ {
+ return null;
+ }
// Avoid mis-identifying top folders
- if (args.HasParent<MusicAlbum>()) return null;
- if (args.Parent.IsRoot) return null;
+ if (args.HasParent<MusicAlbum>())
+ {
+ return null;
+ }
+
+ if (args.Parent.IsRoot)
+ {
+ return null;
+ }
return IsMusicAlbum(args) ? new MusicAlbum() : null;
}
-
/// <summary>
/// Determine if the supplied file data points to a music album
/// </summary>
@@ -78,8 +93,11 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
// Args points to an album if parent is an Artist folder or it directly contains music
if (args.IsDirectory)
{
- //if (args.Parent is MusicArtist) return true; //saves us from testing children twice
- if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService, _logger, _fileSystem, args.GetLibraryOptions(), _libraryManager)) return true;
+ // if (args.Parent is MusicArtist) return true; //saves us from testing children twice
+ if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService, _logger, _fileSystem, args.GetLibraryOptions(), _libraryManager))
+ {
+ return true;
+ }
}
return false;
@@ -88,7 +106,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
/// <summary>
/// Determine if the supplied list contains what we should consider music
/// </summary>
- private bool ContainsMusic(IEnumerable<FileSystemMetadata> list,
+ private bool ContainsMusic(
+ IEnumerable<FileSystemMetadata> list,
bool allowSubfolders,
IDirectoryService directoryService,
ILogger logger,
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
index 74e9b8304..ee7e84929 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
@@ -11,7 +11,7 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Resolvers.Audio
{
/// <summary>
- /// Class MusicArtistResolver
+ /// Class MusicArtistResolver.
/// </summary>
public class MusicArtistResolver : ItemResolver<MusicArtist>
{
@@ -20,6 +20,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
private readonly ILibraryManager _libraryManager;
private readonly IServerConfigurationManager _config;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MusicArtistResolver"/> class.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ /// <param name="fileSystem">The file system.</param>
+ /// <param name="libraryManager">The library manager.</param>
+ /// <param name="config">The configuration manager.</param>
public MusicArtistResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager, IServerConfigurationManager config)
{
_logger = logger;
@@ -41,7 +48,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
/// <returns>MusicArtist.</returns>
protected override MusicArtist Resolve(ItemResolveArgs args)
{
- if (!args.IsDirectory) return null;
+ if (!args.IsDirectory)
+ {
+ return null;
+ }
// Don't allow nested artists
if (args.HasParent<MusicArtist>() || args.HasParent<MusicAlbum>())
@@ -79,6 +89,5 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
// If we contain an album assume we are an artist folder
return args.FileSystemChildren.Where(i => i.IsDirectory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService, args.GetLibraryOptions())) ? new MusicArtist() : null;
}
-
}
}
diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
index 541b13cbe..c4bb861b8 100644
--- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.IO;
using System.Linq;
@@ -10,7 +12,7 @@ using MediaBrowser.Model.Entities;
namespace Emby.Server.Implementations.Library.Resolvers
{
/// <summary>
- /// Resolves a Path into a Video or Video subclass
+ /// Resolves a Path into a Video or Video subclass.
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class BaseVideoResolver<T> : MediaBrowser.Controller.Resolvers.ItemResolver<T>
diff --git a/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs
index f22554ee5..0b93ebeb8 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.IO;
using System.Linq;
@@ -7,18 +9,10 @@ using MediaBrowser.Model.Entities;
namespace Emby.Server.Implementations.Library.Resolvers.Books
{
- /// <summary>
- ///
- /// </summary>
public class BookResolver : MediaBrowser.Controller.Resolvers.ItemResolver<Book>
{
private readonly string[] _validExtensions = { ".pdf", ".epub", ".mobi", ".cbr", ".cbz", ".azw3" };
- /// <summary>
- ///
- /// </summary>
- /// <param name="args"></param>
- /// <returns></returns>
protected override Book Resolve(ItemResolveArgs args)
{
var collectionType = args.GetCollectionType();
@@ -47,11 +41,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books
return null;
}
- /// <summary>
- ///
- /// </summary>
- /// <param name="args"></param>
- /// <returns></returns>
private Book GetBook(ItemResolveArgs args)
{
var bookFiles = args.FileSystemChildren.Where(f =>
diff --git a/Emby.Server.Implementations/Library/Resolvers/FolderResolver.cs b/Emby.Server.Implementations/Library/Resolvers/FolderResolver.cs
index e48b6c967..7dbce7a6e 100644
--- a/Emby.Server.Implementations/Library/Resolvers/FolderResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/FolderResolver.cs
@@ -5,7 +5,7 @@ using MediaBrowser.Controller.Resolvers;
namespace Emby.Server.Implementations.Library.Resolvers
{
/// <summary>
- /// Class FolderResolver
+ /// Class FolderResolver.
/// </summary>
public class FolderResolver : FolderResolver<Folder>
{
@@ -32,7 +32,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
}
/// <summary>
- /// Class FolderResolver
+ /// Class FolderResolver.
/// </summary>
/// <typeparam name="TItemType">The type of the T item type.</typeparam>
public abstract class FolderResolver<TItemType> : ItemResolver<TItemType>
diff --git a/Emby.Server.Implementations/Library/Resolvers/ItemResolver.cs b/Emby.Server.Implementations/Library/Resolvers/ItemResolver.cs
index a6db40714..32ccc7fdd 100644
--- a/Emby.Server.Implementations/Library/Resolvers/ItemResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/ItemResolver.cs
@@ -5,7 +5,7 @@ using MediaBrowser.Controller.Resolvers;
namespace Emby.Server.Implementations.Library.Resolvers
{
/// <summary>
- /// Class ItemResolver
+ /// Class ItemResolver.
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class ItemResolver<T> : IItemResolver
diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs
index 922bd4bbb..e4bc4a469 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs
@@ -4,12 +4,11 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Library.Resolvers.Movies
{
/// <summary>
- /// Class BoxSetResolver
+ /// Class BoxSetResolver.
/// </summary>
public class BoxSetResolver : FolderResolver<BoxSet>
{
@@ -63,7 +62,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
/// <param name="item">The item.</param>
private static void SetProviderIdFromPath(BaseItem item)
{
- //we need to only look at the name of this actual item (not parents)
+ // we need to only look at the name of this actual item (not parents)
var justName = Path.GetFileName(item.Path);
var id = justName.GetAttributeValue("tmdbid");
diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 1b63b00a3..6c7690055 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -17,7 +17,7 @@ using MediaBrowser.Model.IO;
namespace Emby.Server.Implementations.Library.Resolvers.Movies
{
/// <summary>
- /// Class MovieResolver
+ /// Class MovieResolver.
/// </summary>
public class MovieResolver : BaseVideoResolver<Video>, IMultiItemResolver
{
@@ -27,6 +27,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
/// <value>The priority.</value>
public override ResolverPriority Priority => ResolverPriority.Third;
+ /// <inheritdoc />
public MultiItemResolverResult ResolveMultiple(
Folder parent,
List<FileSystemMetadata> files,
@@ -522,7 +523,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
CollectionType.MusicVideos,
CollectionType.Movies,
CollectionType.Photos
- };
+ };
private bool IsInvalid(Folder parent, string collectionType)
{
@@ -544,6 +545,11 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
private IImageProcessor _imageProcessor;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MovieResolver"/> class.
+ /// </summary>
+ /// <param name="libraryManager">The library manager.</param>
+ /// <param name="imageProcessor">The image processor.</param>
public MovieResolver(ILibraryManager libraryManager, IImageProcessor imageProcessor)
: base(libraryManager)
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs
index 82779f8d3..4536b0aaa 100644
--- a/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs
@@ -7,11 +7,19 @@ using MediaBrowser.Model.Entities;
namespace Emby.Server.Implementations.Library.Resolvers
{
+ /// <summary>
+ /// Class PhotoAlbumResolver.
+ /// </summary>
public class PhotoAlbumResolver : FolderResolver<PhotoAlbum>
{
private readonly IImageProcessor _imageProcessor;
private ILibraryManager _libraryManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PhotoAlbumResolver"/> class.
+ /// </summary>
+ /// <param name="imageProcessor">The image processor.</param>
+ /// <param name="libraryManager">The library manager.</param>
public PhotoAlbumResolver(IImageProcessor imageProcessor, ILibraryManager libraryManager)
{
_imageProcessor = imageProcessor;
@@ -74,9 +82,11 @@ namespace Emby.Server.Implementations.Library.Resolvers
}
}
}
+
return false;
}
+ /// <inheritdoc />
public override ResolverPriority Priority => ResolverPriority.Second;
}
}
diff --git a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs
index 8171c010b..a71ae8250 100644
--- a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs
index c295894d3..a68562fc2 100644
--- a/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs
@@ -1,10 +1,11 @@
+#pragma warning disable CS1591
+
using System;
using System.IO;
using System.Linq;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Playlists;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Library.Resolvers
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs
index 7e4b38b4c..1030ed39d 100644
--- a/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.IO;
using System.Linq;
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
index a6d18c9b5..7f477a0f0 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
@@ -7,7 +7,7 @@ using MediaBrowser.Model.Entities;
namespace Emby.Server.Implementations.Library.Resolvers.TV
{
/// <summary>
- /// Class EpisodeResolver
+ /// Class EpisodeResolver.
/// </summary>
public class EpisodeResolver : BaseVideoResolver<Episode>
{
@@ -26,6 +26,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
}
var season = parent as Season;
+
// Just in case the user decided to nest episodes.
// Not officially supported but in some cases we can handle it.
if (season == null)
@@ -73,6 +74,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
return null;
}
+ /// <summary>
+ /// Initializes a new instance of the <see cref="EpisodeResolver"/> class.
+ /// </summary>
+ /// <param name="libraryManager">The library manager.</param>
public EpisodeResolver(ILibraryManager libraryManager)
: base(libraryManager)
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 1f873d7c6..7cc9eabc8 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
@@ -14,7 +16,7 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Resolvers.TV
{
/// <summary>
- /// Class SeriesResolver
+ /// Class SeriesResolver.
/// </summary>
public class SeriesResolver : FolderResolver<Series>
{
@@ -22,6 +24,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
private readonly ILogger _logger;
private readonly ILibraryManager _libraryManager;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SeriesResolver"/> class.
+ /// </summary>
+ /// <param name="fileSystem">The file system.</param>
+ /// <param name="logger">The logger.</param>
+ /// <param name="libraryManager">The library manager.</param>
public SeriesResolver(IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager)
{
_fileSystem = fileSystem;
diff --git a/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs
index 68d5d8b2d..62268fce9 100644
--- a/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs
index 9c7f7dfcb..11d6c737a 100644
--- a/Emby.Server.Implementations/Library/SearchEngine.cs
+++ b/Emby.Server.Implementations/Library/SearchEngine.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -13,8 +15,6 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library
{
- /// <summary>
- /// </summary>
public class SearchEngine : ISearchEngine
{
private readonly ILibraryManager _libraryManager;
@@ -83,7 +83,7 @@ namespace Emby.Server.Implementations.Library
if (string.IsNullOrEmpty(searchTerm))
{
- throw new ArgumentNullException(nameof(searchTerm));
+ throw new ArgumentNullException("SearchTerm can't be empty.", nameof(searchTerm));
}
searchTerm = searchTerm.Trim().RemoveDiacritics();
@@ -162,7 +162,7 @@ namespace Emby.Server.Implementations.Library
Limit = query.Limit,
IncludeItemsByName = string.IsNullOrEmpty(query.ParentId),
ParentId = string.IsNullOrEmpty(query.ParentId) ? Guid.Empty : new Guid(query.ParentId),
- OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) },
+ OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
Recursive = true,
IsKids = query.IsKids,
diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs
index 36adc0b9c..071681b08 100644
--- a/Emby.Server.Implementations/Library/UserDataManager.cs
+++ b/Emby.Server.Implementations/Library/UserDataManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -15,7 +17,7 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library
{
/// <summary>
- /// Class UserDataManager
+ /// Class UserDataManager.
/// </summary>
public class UserDataManager : IUserDataManager
{
@@ -55,6 +57,7 @@ namespace Emby.Server.Implementations.Library
{
throw new ArgumentNullException(nameof(userData));
}
+
if (item == null)
{
throw new ArgumentNullException(nameof(item));
@@ -160,11 +163,6 @@ namespace Emby.Server.Implementations.Library
return GetUserData(user, item.Id, item.GetUserDataKeys());
}
- public UserItemData GetUserData(string userId, BaseItem item)
- {
- return GetUserData(new Guid(userId), item);
- }
-
public UserItemData GetUserData(Guid userId, BaseItem item)
{
return GetUserData(userId, item.Id, item.GetUserDataKeys());
@@ -228,24 +226,21 @@ namespace Emby.Server.Implementations.Library
{
var pctIn = decimal.Divide(positionTicks, runtimeTicks) * 100;
- // Don't track in very beginning
if (pctIn < _config.Configuration.MinResumePct)
{
+ // ignore progress during the beginning
positionTicks = 0;
}
-
- // If we're at the end, assume completed
else if (pctIn > _config.Configuration.MaxResumePct || positionTicks >= runtimeTicks)
{
+ // mark as completed close to the end
positionTicks = 0;
data.Played = playedToCompletion = true;
}
-
else
{
// Enforce MinResumeDuration
var durationSeconds = TimeSpan.FromTicks(runtimeTicks).TotalSeconds;
-
if (durationSeconds < _config.Configuration.MinResumeDurationSeconds)
{
positionTicks = 0;
@@ -265,6 +260,7 @@ namespace Emby.Server.Implementations.Library
positionTicks = 0;
data.Played = false;
}
+
if (!item.SupportsPositionTicksResume)
{
positionTicks = 0;
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index 60d16c8a0..85bfa154a 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -8,7 +10,6 @@ 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;
@@ -25,6 +26,7 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Cryptography;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Events;
@@ -36,19 +38,19 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library
{
/// <summary>
- /// Class UserManager
+ /// Class UserManager.
/// </summary>
public class UserManager : IUserManager
{
/// <summary>
- /// The _logger
+ /// The logger.
/// </summary>
private readonly ILogger _logger;
private readonly object _policySyncLock = new object();
/// <summary>
- /// Gets the active user repository
+ /// Gets the active user repository.
/// </summary>
/// <value>The user repository.</value>
private readonly IUserRepository _userRepository;
@@ -60,6 +62,7 @@ namespace Emby.Server.Implementations.Library
private readonly Func<IDtoService> _dtoServiceFactory;
private readonly IServerApplicationHost _appHost;
private readonly IFileSystem _fileSystem;
+ private readonly ICryptoProvider _cryptoProvider;
private ConcurrentDictionary<Guid, User> _users;
@@ -80,7 +83,8 @@ namespace Emby.Server.Implementations.Library
Func<IDtoService> dtoServiceFactory,
IServerApplicationHost appHost,
IJsonSerializer jsonSerializer,
- IFileSystem fileSystem)
+ IFileSystem fileSystem,
+ ICryptoProvider cryptoProvider)
{
_logger = logger;
_userRepository = userRepository;
@@ -91,6 +95,7 @@ namespace Emby.Server.Implementations.Library
_appHost = appHost;
_jsonSerializer = jsonSerializer;
_fileSystem = fileSystem;
+ _cryptoProvider = cryptoProvider;
_users = null;
}
@@ -179,12 +184,7 @@ namespace Emby.Server.Implementations.Library
_defaultPasswordResetProvider = passwordResetProviders.OfType<DefaultPasswordResetProvider>().First();
}
- /// <summary>
- /// Gets a User by Id.
- /// </summary>
- /// <param name="id">The id.</param>
- /// <returns>User.</returns>
- /// <exception cref="ArgumentException"></exception>
+ /// <inheritdoc />
public User GetUserById(Guid id)
{
if (id == Guid.Empty)
@@ -196,14 +196,6 @@ namespace Emby.Server.Implementations.Library
return user;
}
- /// <summary>
- /// Gets the user by identifier.
- /// </summary>
- /// <param name="id">The identifier.</param>
- /// <returns>User.</returns>
- public User GetUserById(string id)
- => GetUserById(new Guid(id));
-
public User GetUserByName(string name)
{
if (string.IsNullOrWhiteSpace(name))
@@ -364,6 +356,8 @@ namespace Emby.Server.Implementations.Library
return success ? user : null;
}
+#nullable enable
+
private static string GetAuthenticationProviderId(IAuthenticationProvider provider)
{
return provider.GetType().FullName;
@@ -384,7 +378,7 @@ namespace Emby.Server.Implementations.Library
return GetPasswordResetProviders(user)[0];
}
- private IAuthenticationProvider[] GetAuthenticationProviders(User user)
+ private IAuthenticationProvider[] GetAuthenticationProviders(User? user)
{
var authenticationProviderId = user?.Policy.AuthenticationProviderId;
@@ -405,7 +399,7 @@ namespace Emby.Server.Implementations.Library
return providers;
}
- private IPasswordResetProvider[] GetPasswordResetProviders(User user)
+ private IPasswordResetProvider[] GetPasswordResetProviders(User? user)
{
var passwordResetProviderId = user?.Policy.PasswordResetProviderId;
@@ -424,11 +418,14 @@ namespace Emby.Server.Implementations.Library
return providers;
}
- private async Task<(string username, bool success)> AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser)
+ private async Task<(string username, bool success)> AuthenticateWithProvider(
+ IAuthenticationProvider provider,
+ string username,
+ string password,
+ User? resolvedUser)
{
try
{
-
var authenticationResult = provider is IRequiresResolvedUser requiresResolvedUser
? await requiresResolvedUser.Authenticate(username, password, resolvedUser).ConfigureAwait(false)
: await provider.Authenticate(username, password).ConfigureAwait(false);
@@ -449,15 +446,15 @@ namespace Emby.Server.Implementations.Library
}
}
- private async Task<(IAuthenticationProvider authenticationProvider, string username, bool success)> AuthenticateLocalUser(
+ private async Task<(IAuthenticationProvider? authenticationProvider, string username, bool success)> AuthenticateLocalUser(
string username,
string password,
string hashedPassword,
- User user,
+ User? user,
string remoteEndPoint)
{
bool success = false;
- IAuthenticationProvider authenticationProvider = null;
+ IAuthenticationProvider? authenticationProvider = null;
foreach (var provider in GetAuthenticationProviders(user))
{
@@ -475,24 +472,21 @@ namespace Emby.Server.Implementations.Library
if (!success
&& _networkManager.IsInLocalNetwork(remoteEndPoint)
- && user.Configuration.EnableLocalPassword)
+ && user.Configuration.EnableLocalPassword
+ && !string.IsNullOrEmpty(user.EasyPassword))
{
- success = string.Equals(
- GetLocalPasswordHash(user),
- _defaultAuthenticationProvider.GetHashedString(user, password),
- StringComparison.OrdinalIgnoreCase);
+ // Check easy password
+ var passwordHash = PasswordHash.Parse(user.EasyPassword);
+ var hash = _cryptoProvider.ComputeHash(
+ passwordHash.Id,
+ Encoding.UTF8.GetBytes(password),
+ passwordHash.Salt);
+ success = passwordHash.Hash.SequenceEqual(hash);
}
return (authenticationProvider, username, success);
}
- private string GetLocalPasswordHash(User user)
- {
- return string.IsNullOrEmpty(user.EasyPassword)
- ? null
- : Hex.Encode(PasswordHash.Parse(user.EasyPassword).Hash);
- }
-
private void ResetInvalidLoginAttemptCount(User user)
{
user.Policy.InvalidLoginAttemptCount = 0;
@@ -538,6 +532,8 @@ namespace Emby.Server.Implementations.Library
defaultName = "MyJellyfinUser";
}
+ _logger.LogWarning("No users, creating one with username {UserName}", defaultName);
+
var name = MakeValidUsername(defaultName);
var user = InstantiateNewUser(name);
@@ -555,6 +551,8 @@ namespace Emby.Server.Implementations.Library
_users[user.Id] = user;
}
+#nullable restore
+
public UserDto GetUserDto(User user, string remoteEndPoint = null)
{
if (user == null)
@@ -601,7 +599,7 @@ namespace Emby.Server.Implementations.Library
catch (Exception ex)
{
// Have to use a catch-all unfortunately because some .net image methods throw plain Exceptions
- _logger.LogError(ex, "Error generating PrimaryImageAspectRatio for {user}", user.Name);
+ _logger.LogError(ex, "Error generating PrimaryImageAspectRatio for {User}", user.Name);
}
}
@@ -625,7 +623,7 @@ namespace Emby.Server.Implementations.Library
}
catch (Exception ex)
{
- _logger.LogError(ex, "Error getting {imageType} image info for {imagePath}", image.Type, image.Path);
+ _logger.LogError(ex, "Error getting {ImageType} image info for {ImagePath}", image.Type, image.Path);
return null;
}
}
diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs
index 88e2a8fa6..322819b05 100644
--- a/Emby.Server.Implementations/Library/UserViewManager.cs
+++ b/Emby.Server.Implementations/Library/UserViewManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -42,6 +44,11 @@ namespace Emby.Server.Implementations.Library
{
var user = _userManager.GetUserById(query.UserId);
+ if (user == null)
+ {
+ throw new ArgumentException("User Id specified in the query does not exist.", nameof(query));
+ }
+
var folders = _libraryManager.GetUserRootFolder()
.GetChildren(user, true)
.OfType<Folder>()
@@ -54,7 +61,7 @@ namespace Emby.Server.Implementations.Library
foreach (var folder in folders)
{
var collectionFolder = folder as ICollectionFolder;
- var folderViewType = collectionFolder == null ? null : collectionFolder.CollectionType;
+ var folderViewType = collectionFolder?.CollectionType;
if (UserView.IsUserSpecific(folder))
{
@@ -130,16 +137,11 @@ namespace Emby.Server.Implementations.Library
{
var index = orders.IndexOf(i.Id.ToString("N", CultureInfo.InvariantCulture));
- if (index == -1)
+ if (index == -1
+ && i is UserView view
+ && view.DisplayParentId != Guid.Empty)
{
- var view = i as UserView;
- if (view != null)
- {
- if (!view.DisplayParentId.Equals(Guid.Empty))
- {
- index = orders.IndexOf(view.DisplayParentId.ToString("N", CultureInfo.InvariantCulture));
- }
- }
+ index = orders.IndexOf(view.DisplayParentId.ToString("N", CultureInfo.InvariantCulture));
}
return index == -1 ? int.MaxValue : index;
@@ -340,7 +342,7 @@ namespace Emby.Server.Implementations.Library
var query = new InternalItemsQuery(user)
{
IncludeItemTypes = includeItemTypes,
- OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) },
+ OrderBy = new[] { (ItemSortBy.DateCreated, SortOrder.Descending) },
IsFolder = includeItemTypes.Length == 0 ? false : (bool?)null,
ExcludeItemTypes = excludeItemTypes,
IsVirtualItem = false,
diff --git a/Emby.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs b/Emby.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs
index 27261d449..61a07d0d6 100644
--- a/Emby.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs
+++ b/Emby.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs
@@ -8,12 +8,12 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Validators
{
/// <summary>
- /// Class ArtistsPostScanTask
+ /// Class ArtistsPostScanTask.
/// </summary>
public class ArtistsPostScanTask : ILibraryPostScanTask
{
/// <summary>
- /// The _library manager
+ /// The _library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
private readonly ILogger _logger;
@@ -23,6 +23,8 @@ namespace Emby.Server.Implementations.Library.Validators
/// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
/// </summary>
/// <param name="libraryManager">The library manager.</param>
+ /// <param name="logger">The logger.</param>
+ /// <param name="itemRepo">The item repository.</param>
public ArtistsPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
{
_libraryManager = libraryManager;
diff --git a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs
index b584cc649..1497f4a3a 100644
--- a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs
@@ -12,26 +12,27 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Validators
{
/// <summary>
- /// Class ArtistsValidator
+ /// Class ArtistsValidator.
/// </summary>
public class ArtistsValidator
{
/// <summary>
- /// The _library manager
+ /// The library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
/// <summary>
- /// The _logger
+ /// The logger.
/// </summary>
private readonly ILogger _logger;
private readonly IItemRepository _itemRepo;
/// <summary>
- /// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
+ /// Initializes a new instance of the <see cref="ArtistsValidator" /> class.
/// </summary>
/// <param name="libraryManager">The library manager.</param>
/// <param name="logger">The logger.</param>
+ /// <param name="itemRepo">The item repository.</param>
public ArtistsValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
{
_libraryManager = libraryManager;
diff --git a/Emby.Server.Implementations/Library/Validators/GenresPostScanTask.cs b/Emby.Server.Implementations/Library/Validators/GenresPostScanTask.cs
index 056807300..06d1dd89d 100644
--- a/Emby.Server.Implementations/Library/Validators/GenresPostScanTask.cs
+++ b/Emby.Server.Implementations/Library/Validators/GenresPostScanTask.cs
@@ -7,20 +7,24 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Validators
{
+ /// <summary>
+ /// Class GenresPostScanTask.
+ /// </summary>
public class GenresPostScanTask : ILibraryPostScanTask
{
/// <summary>
- /// The _library manager
+ /// The _library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
private readonly ILogger _logger;
private readonly IItemRepository _itemRepo;
/// <summary>
- /// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
+ /// Initializes a new instance of the <see cref="GenresPostScanTask" /> class.
/// </summary>
/// <param name="libraryManager">The library manager.</param>
/// <param name="logger">The logger.</param>
+ /// <param name="itemRepo">The item repository.</param>
public GenresPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
{
_libraryManager = libraryManager;
diff --git a/Emby.Server.Implementations/Library/Validators/GenresValidator.cs b/Emby.Server.Implementations/Library/Validators/GenresValidator.cs
index f8459c61f..b0cd5f87a 100644
--- a/Emby.Server.Implementations/Library/Validators/GenresValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/GenresValidator.cs
@@ -7,19 +7,28 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Validators
{
- class GenresValidator
+ /// <summary>
+ /// Class GenresValidator.
+ /// </summary>
+ public class GenresValidator
{
/// <summary>
- /// The _library manager
+ /// The library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
private readonly IItemRepository _itemRepo;
/// <summary>
- /// The _logger
+ /// The logger.
/// </summary>
private readonly ILogger _logger;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="GenresValidator"/> class.
+ /// </summary>
+ /// <param name="libraryManager">The library manager.</param>
+ /// <param name="logger">The logger.</param>
+ /// <param name="itemRepo">The item repository.</param>
public GenresValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
{
_libraryManager = libraryManager;
diff --git a/Emby.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs b/Emby.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs
index d7ab92d30..58549e9d7 100644
--- a/Emby.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs
+++ b/Emby.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs
@@ -8,22 +8,23 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Validators
{
/// <summary>
- /// Class MusicGenresPostScanTask
+ /// Class MusicGenresPostScanTask.
/// </summary>
public class MusicGenresPostScanTask : ILibraryPostScanTask
{
/// <summary>
- /// The _library manager
+ /// The library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
private readonly ILogger _logger;
private readonly IItemRepository _itemRepo;
/// <summary>
- /// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
+ /// Initializes a new instance of the <see cref="MusicGenresPostScanTask" /> class.
/// </summary>
/// <param name="libraryManager">The library manager.</param>
/// <param name="logger">The logger.</param>
+ /// <param name="itemRepo">The item repository.</param>
public MusicGenresPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
{
_libraryManager = libraryManager;
diff --git a/Emby.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/Emby.Server.Implementations/Library/Validators/MusicGenresValidator.cs
index 710e5d043..5ee4ca72e 100644
--- a/Emby.Server.Implementations/Library/Validators/MusicGenresValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/MusicGenresValidator.cs
@@ -7,19 +7,28 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Validators
{
- class MusicGenresValidator
+ /// <summary>
+ /// Class MusicGenresValidator.
+ /// </summary>
+ public class MusicGenresValidator
{
/// <summary>
- /// The _library manager
+ /// The library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
/// <summary>
- /// The _logger
+ /// The logger.
/// </summary>
private readonly ILogger _logger;
private readonly IItemRepository _itemRepo;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MusicGenresValidator" /> class.
+ /// </summary>
+ /// <param name="libraryManager">The library manager.</param>
+ /// <param name="logger">The logger.</param>
+ /// <param name="itemRepo">The item repository.</param>
public MusicGenresValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
{
_libraryManager = libraryManager;
diff --git a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
index 137a010ec..8275c873a 100644
--- a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
@@ -32,6 +32,7 @@ namespace Emby.Server.Implementations.Library.Validators
/// </summary>
/// <param name="libraryManager">The library manager.</param>
/// <param name="logger">The logger.</param>
+ /// <param name="fileSystem">The file system.</param>
public PeopleValidator(ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem)
{
_libraryManager = libraryManager;
diff --git a/Emby.Server.Implementations/Library/Validators/StudiosPostScanTask.cs b/Emby.Server.Implementations/Library/Validators/StudiosPostScanTask.cs
index 4aa5c7e72..00899c336 100644
--- a/Emby.Server.Implementations/Library/Validators/StudiosPostScanTask.cs
+++ b/Emby.Server.Implementations/Library/Validators/StudiosPostScanTask.cs
@@ -8,12 +8,12 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Validators
{
/// <summary>
- /// Class MusicGenresPostScanTask
+ /// Class MusicGenresPostScanTask.
/// </summary>
public class StudiosPostScanTask : ILibraryPostScanTask
{
/// <summary>
- /// The _library manager
+ /// The _library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
@@ -21,9 +21,11 @@ namespace Emby.Server.Implementations.Library.Validators
private readonly IItemRepository _itemRepo;
/// <summary>
- /// Initializes a new instance of the <see cref="ArtistsPostScanTask" /> class.
+ /// Initializes a new instance of the <see cref="StudiosPostScanTask" /> class.
/// </summary>
/// <param name="libraryManager">The library manager.</param>
+ /// <param name="logger">The logger.</param>
+ /// <param name="itemRepo">The item repository.</param>
public StudiosPostScanTask(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
{
_libraryManager = libraryManager;
diff --git a/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs b/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs
index 93ded9e7b..15e7a0dbb 100644
--- a/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs
@@ -9,19 +9,29 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Library.Validators
{
- class StudiosValidator
+ /// <summary>
+ /// Class StudiosValidator.
+ /// </summary>
+ public class StudiosValidator
{
/// <summary>
- /// The _library manager
+ /// The library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
private readonly IItemRepository _itemRepo;
+
/// <summary>
- /// The _logger
+ /// The logger.
/// </summary>
private readonly ILogger _logger;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="StudiosValidator" /> class.
+ /// </summary>
+ /// <param name="libraryManager">The library manager.</param>
+ /// <param name="logger">The logger.</param>
+ /// <param name="itemRepo">The item repository.</param>
public StudiosValidator(ILibraryManager libraryManager, ILogger logger, IItemRepository itemRepo)
{
_libraryManager = libraryManager;
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 687a178a6..3b6bfce6a 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -237,7 +237,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
if (requiresRefresh)
{
- await _libraryManager.ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None);
+ await _libraryManager.ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None).ConfigureAwait(false);
}
}
@@ -1582,15 +1582,15 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return;
}
- var episodesToDelete = (librarySeries.GetItemList(new InternalItemsQuery
+ var episodesToDelete = librarySeries.GetItemList(new InternalItemsQuery
{
- OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) },
+ OrderBy = new[] { (ItemSortBy.DateCreated, SortOrder.Descending) },
IsVirtualItem = false,
IsFolder = false,
Recursive = true,
DtoOptions = new DtoOptions(true)
- }))
+ })
.Where(i => i.IsFileProtocol && File.Exists(i.Path))
.Skip(seriesTimer.KeepUpTo - 1)
.ToList();
@@ -2260,7 +2260,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
},
MinStartDate = startDateUtc.AddMinutes(-3),
MaxStartDate = startDateUtc.AddMinutes(3),
- OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) }
+ OrderBy = new[] { (ItemSortBy.StartDate, SortOrder.Ascending) }
};
if (!string.IsNullOrWhiteSpace(channelId))
diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
index 9a4c91d0b..838ac97d7 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
@@ -501,7 +501,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
public async Task<List<NameIdPair>> GetHeadends(ListingsProviderInfo info, string country, string location, CancellationToken cancellationToken)
{
- var token = await GetToken(info, cancellationToken);
+ var token = await GetToken(info, cancellationToken).ConfigureAwait(false);
var lineups = new List<NameIdPair>();
@@ -713,7 +713,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
private async Task AddLineupToAccount(ListingsProviderInfo info, CancellationToken cancellationToken)
{
- var token = await GetToken(info, cancellationToken);
+ var token = await GetToken(info, cancellationToken).ConfigureAwait(false);
if (string.IsNullOrEmpty(token))
{
@@ -738,7 +738,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
httpOptions.RequestHeaders["token"] = token;
- using (await _httpClient.SendAsync(httpOptions, "PUT"))
+ using (await _httpClient.SendAsync(httpOptions, "PUT").ConfigureAwait(false))
{
}
}
@@ -750,7 +750,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
throw new ArgumentException("Listings Id required");
}
- var token = await GetToken(info, cancellationToken);
+ var token = await GetToken(info, cancellationToken).ConfigureAwait(false);
if (string.IsNullOrEmpty(token))
{
@@ -833,7 +833,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
throw new Exception("ListingsId required");
}
- var token = await GetToken(info, cancellationToken);
+ var token = await GetToken(info, cancellationToken).ConfigureAwait(false);
if (string.IsNullOrEmpty(token))
{
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index 88693f22a..1f38de2d8 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -7,8 +7,8 @@ using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
-using Emby.XmlTv.Classes;
-using Emby.XmlTv.Entities;
+using Jellyfin.XmlTv;
+using Jellyfin.XmlTv.Entities;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index d4bd598e3..ee7db1413 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -209,16 +209,16 @@ namespace Emby.Server.Implementations.LiveTv
var orderBy = internalQuery.OrderBy.ToList();
- orderBy.AddRange(query.SortBy.Select(i => new ValueTuple<string, SortOrder>(i, query.SortOrder ?? SortOrder.Ascending)));
+ orderBy.AddRange(query.SortBy.Select(i => (i, query.SortOrder ?? SortOrder.Ascending)));
if (query.EnableFavoriteSorting)
{
- orderBy.Insert(0, new ValueTuple<string, SortOrder>(ItemSortBy.IsFavoriteOrLiked, SortOrder.Descending));
+ orderBy.Insert(0, (ItemSortBy.IsFavoriteOrLiked, SortOrder.Descending));
}
if (!internalQuery.OrderBy.Any(i => string.Equals(i.Item1, ItemSortBy.SortName, StringComparison.OrdinalIgnoreCase)))
{
- orderBy.Add(new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending));
+ orderBy.Add((ItemSortBy.SortName, SortOrder.Ascending));
}
internalQuery.OrderBy = orderBy.ToArray();
@@ -304,9 +304,12 @@ namespace Emby.Server.Implementations.LiveTv
}
private ILiveTvService GetService(string name)
- {
- return _services.FirstOrDefault(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));
- }
+ => Array.Find(_services, x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase))
+ ?? throw new KeyNotFoundException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "No service with the name '{0}' can be found.",
+ name));
private static void Normalize(MediaSourceInfo mediaSource, ILiveTvService service, bool isVideo)
{
@@ -772,22 +775,22 @@ namespace Emby.Server.Implementations.LiveTv
var topFolder = GetInternalLiveTvFolder(cancellationToken);
- if (query.OrderBy.Length == 0)
+ if (query.OrderBy.Count == 0)
{
if (query.IsAiring ?? false)
{
// Unless something else was specified, order by start date to take advantage of a specialized index
- query.OrderBy = new ValueTuple<string, SortOrder>[]
+ query.OrderBy = new[]
{
- new ValueTuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending)
+ (ItemSortBy.StartDate, SortOrder.Ascending)
};
}
else
{
// Unless something else was specified, order by start date to take advantage of a specialized index
- query.OrderBy = new ValueTuple<string, SortOrder>[]
+ query.OrderBy = new[]
{
- new ValueTuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending)
+ (ItemSortBy.StartDate, SortOrder.Ascending)
};
}
}
@@ -871,7 +874,7 @@ namespace Emby.Server.Implementations.LiveTv
IsSports = query.IsSports,
IsKids = query.IsKids,
EnableTotalRecordCount = query.EnableTotalRecordCount,
- OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) },
+ OrderBy = new[] { (ItemSortBy.StartDate, SortOrder.Ascending) },
TopParentIds = new[] { topFolder.Id },
DtoOptions = options,
GenreIds = query.GenreIds
@@ -1396,7 +1399,7 @@ namespace Emby.Server.Implementations.LiveTv
IsVirtualItem = false,
Limit = limit,
StartIndex = query.StartIndex,
- OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) },
+ OrderBy = new[] { (ItemSortBy.DateCreated, SortOrder.Descending) },
EnableTotalRecordCount = query.EnableTotalRecordCount,
IncludeItemTypes = includeItemTypes.ToArray(),
ExcludeItemTypes = excludeItemTypes.ToArray(),
@@ -1894,7 +1897,7 @@ namespace Emby.Server.Implementations.LiveTv
MaxStartDate = now,
MinEndDate = now,
Limit = channelIds.Length,
- OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) },
+ OrderBy = new[] { (ItemSortBy.StartDate, SortOrder.Ascending) },
TopParentIds = new[] { GetInternalLiveTvFolder(CancellationToken.None).Id },
DtoOptions = options
diff --git a/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs b/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs
index 542951de4..1056a33b9 100644
--- a/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs
+++ b/Emby.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs
@@ -38,8 +38,8 @@ namespace Emby.Server.Implementations.LiveTv
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
- return new[] {
-
+ return new[]
+ {
// Every so often
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
};
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index da98f3e58..06f27fa3e 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -185,7 +185,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
Url = string.Format("{0}/tuners.html", GetApiUrl(info)),
CancellationToken = cancellationToken,
BufferContent = false
- }, HttpMethod.Get))
+ }, HttpMethod.Get).ConfigureAwait(false))
using (var stream = response.Content)
using (var sr = new StreamReader(stream, System.Text.Encoding.UTF8))
{
@@ -259,7 +259,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
for (int i = 0; i < model.TunerCount; ++i)
{
var name = string.Format("Tuner {0}", i + 1);
- var currentChannel = "none"; /// @todo Get current channel and map back to Station Id
+ var currentChannel = "none"; // @todo Get current channel and map back to Station Id
var isAvailable = await manager.CheckTunerAvailability(ipInfo, i, cancellationToken).ConfigureAwait(false);
var status = isAvailable ? LiveTvTunerStatus.Available : LiveTvTunerStatus.LiveTv;
tuners.Add(new LiveTvTunerInfo
@@ -298,7 +298,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
public async Task<List<LiveTvTunerInfo>> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken)
{
// TODO Need faster way to determine UDP vs HTTP
- var channels = await GetChannels(info, true, cancellationToken);
+ var channels = await GetChannels(info, true, cancellationToken).ConfigureAwait(false);
var hdHomerunChannelInfo = channels.FirstOrDefault() as HdHomerunChannelInfo;
@@ -582,11 +582,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
modelInfo.TunerCount,
FileSystem,
Logger,
- Config.ApplicationPaths,
+ Config,
_appHost,
_networkManager,
_streamHelper);
-
}
var enableHttpStream = true;
@@ -611,7 +610,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
FileSystem,
_httpClient,
Logger,
- Config.ApplicationPaths,
+ Config,
_appHost,
_streamHelper);
}
@@ -624,7 +623,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
modelInfo.TunerCount,
FileSystem,
Logger,
- Config.ApplicationPaths,
+ Config,
_appHost,
_networkManager,
_streamHelper);
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
index eafa86d54..649becbd3 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
@@ -6,6 +6,7 @@ using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
@@ -33,11 +34,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
int numTuners,
IFileSystem fileSystem,
ILogger logger,
- IServerApplicationPaths appPaths,
+ IConfigurationManager configurationManager,
IServerApplicationHost appHost,
INetworkManager networkManager,
IStreamHelper streamHelper)
- : base(mediaSource, tunerHostInfo, fileSystem, logger, appPaths, streamHelper)
+ : base(mediaSource, tunerHostInfo, fileSystem, logger, configurationManager, streamHelper)
{
_appHost = appHost;
_networkManager = networkManager;
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
index d12c96392..1d55e7992 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
@@ -5,8 +5,8 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Controller;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.LiveTv;
@@ -16,8 +16,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
public class LiveStream : ILiveStream
{
+ private readonly IConfigurationManager _configurationManager;
+
protected readonly IFileSystem FileSystem;
- protected readonly IServerApplicationPaths AppPaths;
+
protected readonly IStreamHelper StreamHelper;
protected string TempFilePath;
@@ -29,7 +31,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
TunerHostInfo tuner,
IFileSystem fileSystem,
ILogger logger,
- IServerApplicationPaths appPaths,
+ IConfigurationManager configurationManager,
IStreamHelper streamHelper)
{
OriginalMediaSource = mediaSource;
@@ -44,7 +46,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
TunerHostId = tuner.Id;
}
- AppPaths = appPaths;
+ _configurationManager = configurationManager;
StreamHelper = streamHelper;
ConsumerCount = 1;
@@ -68,7 +70,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
protected void SetTempFilePath(string extension)
{
- TempFilePath = Path.Combine(AppPaths.GetTranscodingTempPath(), UniqueId + "." + extension);
+ TempFilePath = Path.Combine(_configurationManager.GetTranscodePath(), UniqueId + "." + extension);
}
public virtual Task Open(CancellationToken openCancellationToken)
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index a02a9ade4..df054f1eb 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -114,11 +114,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
if (!_disallowedSharedStreamExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
{
- return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _streamHelper);
+ return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config, _appHost, _streamHelper);
}
}
- return new LiveStream(mediaSource, info, FileSystem, Logger, Config.ApplicationPaths, _streamHelper);
+ return new LiveStream(mediaSource, info, FileSystem, Logger, Config, _streamHelper);
}
public async Task Validate(TunerHostInfo info)
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
index c6e894560..758495362 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Library;
@@ -26,10 +27,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
IFileSystem fileSystem,
IHttpClient httpClient,
ILogger logger,
- IServerApplicationPaths appPaths,
+ IConfigurationManager configurationManager,
IServerApplicationHost appHost,
IStreamHelper streamHelper)
- : base(mediaSource, tunerHostInfo, fileSystem, logger, appPaths, streamHelper)
+ : base(mediaSource, tunerHostInfo, fileSystem, logger, configurationManager, streamHelper)
{
_httpClient = httpClient;
_appHost = appHost;
diff --git a/Emby.Server.Implementations/Localization/Core/af.json b/Emby.Server.Implementations/Localization/Core/af.json
new file mode 100644
index 000000000..dcec26801
--- /dev/null
+++ b/Emby.Server.Implementations/Localization/Core/af.json
@@ -0,0 +1,96 @@
+{
+ "Artists": "Kunstenare",
+ "Channels": "Kanale",
+ "Folders": "Fouers",
+ "Favorites": "Gunstelinge",
+ "HeaderFavoriteShows": "Gunsteling Vertonings",
+ "ValueSpecialEpisodeName": "Spesiaal - {0}",
+ "HeaderAlbumArtists": "Album Kunstenaars",
+ "Books": "Boeke",
+ "HeaderNextUp": "Volgende",
+ "Movies": "Rolprente",
+ "Shows": "Program",
+ "HeaderContinueWatching": "Hou Aan Kyk",
+ "HeaderFavoriteEpisodes": "Gunsteling Episodes",
+ "Photos": "Fotos",
+ "Playlists": "Speellysse",
+ "HeaderFavoriteArtists": "Gunsteling Kunstenaars",
+ "HeaderFavoriteAlbums": "Gunsteling Albums",
+ "Sync": "Sinkroniseer",
+ "HeaderFavoriteSongs": "Gunsteling Liedjies",
+ "Songs": "Liedjies",
+ "DeviceOnlineWithName": "{0} is verbind",
+ "DeviceOfflineWithName": "{0} het afgesluit",
+ "Collections": "Versamelings",
+ "Inherit": "Ontvang",
+ "HeaderLiveTV": "Live TV",
+ "Application": "Program",
+ "AppDeviceValues": "App: {0}, Toestel: {1}",
+ "VersionNumber": "Weergawe {0}",
+ "ValueHasBeenAddedToLibrary": "{0} is by jou media biblioteek bygevoeg",
+ "UserStoppedPlayingItemWithValues": "{0} het klaar {1} op {2} gespeel",
+ "UserStartedPlayingItemWithValues": "{0} is besig om {1} op {2} te speel",
+ "UserPolicyUpdatedWithName": "Gebruiker beleid is verander vir {0}",
+ "UserPasswordChangedWithName": "Gebruiker {0} se wagwoord is verander",
+ "UserOnlineFromDevice": "{0} is aanlyn van {1}",
+ "UserOfflineFromDevice": "{0} is ontkoppel van {1}",
+ "UserLockedOutWithName": "Gebruiker {0} is uitgesluit",
+ "UserDownloadingItemWithValues": "{0} is besig om {1} af te laai",
+ "UserDeletedWithName": "Gebruiker {0} is verwyder",
+ "UserCreatedWithName": "Gebruiker {0} is geskep",
+ "User": "Gebruiker",
+ "TvShows": "TV Programme",
+ "System": "Stelsel",
+ "SubtitlesDownloadedForItem": "Ondertitels afgelaai vir {0}",
+ "SubtitleDownloadFailureFromForItem": "Ondertitels het misluk om af te laai van {0} vir {1}",
+ "StartupEmbyServerIsLoading": "Jellyfin Bediener is besig om te laai. Probeer weer in 'n kort tyd.",
+ "ServerNameNeedsToBeRestarted": "{0} moet herbegin word",
+ "ScheduledTaskStartedWithName": "{0} het begin",
+ "ScheduledTaskFailedWithName": "{0} het misluk",
+ "ProviderValue": "Voorsiener: {0}",
+ "PluginUpdatedWithName": "{0} was opgedateer",
+ "PluginUninstalledWithName": "{0} was verwyder",
+ "PluginInstalledWithName": "{0} is geïnstalleer",
+ "Plugin": "Inprop module",
+ "NotificationOptionVideoPlaybackStopped": "Video terugspeel het gestop",
+ "NotificationOptionVideoPlayback": "Video terugspeel het begin",
+ "NotificationOptionUserLockedOut": "Gebruiker uitgeslyt",
+ "NotificationOptionTaskFailed": "Geskeduleerde taak het misluk",
+ "NotificationOptionServerRestartRequired": "Bediener herbegin nodig",
+ "NotificationOptionPluginUpdateInstalled": "Nuwe inprop module geïnstalleer",
+ "NotificationOptionPluginUninstalled": "Inprop module verwyder",
+ "NotificationOptionPluginInstalled": "Inprop module geïnstalleer",
+ "NotificationOptionPluginError": "Inprop module het misluk",
+ "NotificationOptionNewLibraryContent": "Nuwe inhoud bygevoeg",
+ "NotificationOptionInstallationFailed": "Installering het misluk",
+ "NotificationOptionCameraImageUploaded": "Kamera foto is opgelaai",
+ "NotificationOptionAudioPlaybackStopped": "Oudio terugspeel het gestop",
+ "NotificationOptionAudioPlayback": "Oudio terugspeel het begin",
+ "NotificationOptionApplicationUpdateInstalled": "Nuwe program weergawe geïnstalleer",
+ "NotificationOptionApplicationUpdateAvailable": "Nuwe program weergawe beskikbaar",
+ "NewVersionIsAvailable": "'n Nuwe Jellyfin Bedienaar weergawe kan afgelaai word.",
+ "NameSeasonUnknown": "Seisoen Onbekend",
+ "NameSeasonNumber": "Seisoen {0}",
+ "NameInstallFailed": "{0} installering het misluk",
+ "MusicVideos": "Musiek videos",
+ "Music": "Musiek",
+ "MixedContent": "Gemengde inhoud",
+ "MessageServerConfigurationUpdated": "Bediener konfigurasie is opgedateer",
+ "MessageNamedServerConfigurationUpdatedWithValue": "Bediener konfigurasie seksie {0} is opgedateer",
+ "MessageApplicationUpdatedTo": "Jellyfin Bediener is opgedateer na {0}",
+ "MessageApplicationUpdated": "Jellyfin Bediener is opgedateer",
+ "Latest": "Nuutste",
+ "LabelRunningTimeValue": "Lopende tyd: {0}",
+ "LabelIpAddressValue": "IP adres: {0}",
+ "ItemRemovedWithName": "{0} is uit versameling verwyder",
+ "ItemAddedWithName": "{0} is in die versameling",
+ "HomeVideos": "Tuis opnames",
+ "HeaderRecordingGroups": "Groep Opnames",
+ "HeaderCameraUploads": "Kamera Oplaai",
+ "Genres": "Genres",
+ "FailedLoginAttemptWithUserName": "Mislukte aansluiting van {0}",
+ "ChapterNameValue": "Hoofstuk",
+ "CameraImageUploadedFrom": "'n Nuwe kamera photo opgelaai van {0}",
+ "AuthenticationSucceededWithUserName": "{0} suksesvol geverifieer",
+ "Albums": "Albums"
+}
diff --git a/Emby.Server.Implementations/Localization/Core/bg-BG.json b/Emby.Server.Implementations/Localization/Core/bg-BG.json
index a71dc9346..46c10d912 100644
--- a/Emby.Server.Implementations/Localization/Core/bg-BG.json
+++ b/Emby.Server.Implementations/Localization/Core/bg-BG.json
@@ -1,22 +1,22 @@
{
"Albums": "Албуми",
- "AppDeviceValues": "Програма: {0}, Устройство: {1}",
+ "AppDeviceValues": "Програма: {0}, устройство: {1}",
"Application": "Програма",
"Artists": "Изпълнители",
"AuthenticationSucceededWithUserName": "{0} се удостовери успешно",
"Books": "Книги",
- "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
+ "CameraImageUploadedFrom": "Нова снимка от камера беше качена от {0}",
"Channels": "Канали",
"ChapterNameValue": "Глава {0}",
"Collections": "Колекции",
"DeviceOfflineWithName": "{0} се разкачи",
"DeviceOnlineWithName": "{0} е свързан",
- "FailedLoginAttemptWithUserName": "Failed login attempt from {0}",
+ "FailedLoginAttemptWithUserName": "Неуспешен опит за влизане от {0}",
"Favorites": "Любими",
"Folders": "Папки",
"Genres": "Жанрове",
"HeaderAlbumArtists": "Изпълнители на албуми",
- "HeaderCameraUploads": "Camera Uploads",
+ "HeaderCameraUploads": "",
"HeaderContinueWatching": "Продължаване на гледането",
"HeaderFavoriteAlbums": "Любими албуми",
"HeaderFavoriteArtists": "Любими изпълнители",
@@ -25,26 +25,26 @@
"HeaderFavoriteSongs": "Любими песни",
"HeaderLiveTV": "Телевизия на живо",
"HeaderNextUp": "Следва",
- "HeaderRecordingGroups": "Recording Groups",
+ "HeaderRecordingGroups": "",
"HomeVideos": "Домашни клипове",
"Inherit": "Наследяване",
"ItemAddedWithName": "{0} е добавено към библиотеката",
"ItemRemovedWithName": "{0} е премахнато от библиотеката",
"LabelIpAddressValue": "ИП адрес: {0}",
- "LabelRunningTimeValue": "Running time: {0}",
+ "LabelRunningTimeValue": "",
"Latest": "Последни",
"MessageApplicationUpdated": "Сървърът е обновен",
- "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}",
- "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated",
- "MessageServerConfigurationUpdated": "Server configuration has been updated",
+ "MessageApplicationUpdatedTo": "",
+ "MessageNamedServerConfigurationUpdatedWithValue": "",
+ "MessageServerConfigurationUpdated": "",
"MixedContent": "Смесено съдържание",
"Movies": "Филми",
"Music": "Музика",
"MusicVideos": "Музикални клипове",
- "NameInstallFailed": "{0} installation failed",
+ "NameInstallFailed": "",
"NameSeasonNumber": "Сезон {0}",
- "NameSeasonUnknown": "Season Unknown",
- "NewVersionIsAvailable": "A new version of Jellyfin Server is available for download.",
+ "NameSeasonUnknown": "Неразпознат сезон",
+ "NewVersionIsAvailable": "",
"NotificationOptionApplicationUpdateAvailable": "Налично е обновление на програмата",
"NotificationOptionApplicationUpdateInstalled": "Обновлението на програмата е инсталирано",
"NotificationOptionAudioPlayback": "Възпроизвеждането на звук започна",
@@ -58,7 +58,7 @@
"NotificationOptionPluginUpdateInstalled": "Обновлението на приставката е инсталирано",
"NotificationOptionServerRestartRequired": "Нужно е повторно пускане на сървъра",
"NotificationOptionTaskFailed": "Грешка в планирана задача",
- "NotificationOptionUserLockedOut": "User locked out",
+ "NotificationOptionUserLockedOut": "",
"NotificationOptionVideoPlayback": "Възпроизвеждането на видео започна",
"NotificationOptionVideoPlaybackStopped": "Възпроизвеждането на видео е спряно",
"Photos": "Снимки",
@@ -70,12 +70,12 @@
"ProviderValue": "Доставчик: {0}",
"ScheduledTaskFailedWithName": "{0} се провали",
"ScheduledTaskStartedWithName": "{0} започна",
- "ServerNameNeedsToBeRestarted": "{0} needs to be restarted",
+ "ServerNameNeedsToBeRestarted": "",
"Shows": "Сериали",
"Songs": "Песни",
"StartupEmbyServerIsLoading": "Сървърът зарежда. Моля, опитайте отново след малко.",
"SubtitleDownloadFailureForItem": "Неуспешно изтегляне на субтитри за {0}",
- "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
+ "SubtitleDownloadFailureFromForItem": "",
"SubtitlesDownloadedForItem": "Изтеглени са субтитри за {0}",
"Sync": "Синхронизиране",
"System": "Система",
@@ -83,15 +83,15 @@
"User": "Потребител",
"UserCreatedWithName": "Потребителят {0} е създаден",
"UserDeletedWithName": "Потребителят {0} е изтрит",
- "UserDownloadingItemWithValues": "{0} is downloading {1}",
- "UserLockedOutWithName": "User {0} has been locked out",
+ "UserDownloadingItemWithValues": "",
+ "UserLockedOutWithName": "",
"UserOfflineFromDevice": "{0} се разкачи от {1}",
"UserOnlineFromDevice": "{0} е на линия от {1}",
"UserPasswordChangedWithName": "Паролата на потребителя {0} е променена",
- "UserPolicyUpdatedWithName": "User policy has been updated for {0}",
+ "UserPolicyUpdatedWithName": "",
"UserStartedPlayingItemWithValues": "{0} пусна {1}",
"UserStoppedPlayingItemWithValues": "{0} спря {1}",
- "ValueHasBeenAddedToLibrary": "{0} has been added to your media library",
+ "ValueHasBeenAddedToLibrary": "",
"ValueSpecialEpisodeName": "Специални - {0}",
"VersionNumber": "Версия {0}"
}
diff --git a/Emby.Server.Implementations/Localization/Core/ca.json b/Emby.Server.Implementations/Localization/Core/ca.json
index 74406a064..9961b0984 100644
--- a/Emby.Server.Implementations/Localization/Core/ca.json
+++ b/Emby.Server.Implementations/Localization/Core/ca.json
@@ -1,11 +1,11 @@
{
"Albums": "Àlbums",
- "AppDeviceValues": "App: {0}, Dispositiu: {1}",
- "Application": "Application",
+ "AppDeviceValues": "Aplicació: {0}, Dispositiu: {1}",
+ "Application": "Aplicació",
"Artists": "Artistes",
"AuthenticationSucceededWithUserName": "{0} s'ha autenticat correctament",
"Books": "Llibres",
- "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
+ "CameraImageUploadedFrom": "Una nova imatge de càmera ha sigut pujada des de {0}",
"Channels": "Canals",
"ChapterNameValue": "Episodi {0}",
"Collections": "Col·leccions",
@@ -15,8 +15,8 @@
"Favorites": "Preferits",
"Folders": "Directoris",
"Genres": "Gèneres",
- "HeaderAlbumArtists": "Album Artists",
- "HeaderCameraUploads": "Camera Uploads",
+ "HeaderAlbumArtists": "Artistes dels Àlbums",
+ "HeaderCameraUploads": "Pujades de Càmera",
"HeaderContinueWatching": "Continua Veient",
"HeaderFavoriteAlbums": "Àlbums Preferits",
"HeaderFavoriteArtists": "Artistes Preferits",
@@ -27,71 +27,71 @@
"HeaderNextUp": "A continuació",
"HeaderRecordingGroups": "Grups d'Enregistrament",
"HomeVideos": "Vídeos domèstics",
- "Inherit": "Heretat",
- "ItemAddedWithName": "{0} afegit a la biblioteca",
- "ItemRemovedWithName": "{0} eliminat de la biblioteca",
+ "Inherit": "Hereta",
+ "ItemAddedWithName": "{0} ha estat afegit a la biblioteca",
+ "ItemRemovedWithName": "{0} ha estat eliminat de la biblioteca",
"LabelIpAddressValue": "Adreça IP: {0}",
- "LabelRunningTimeValue": "Temps en marxa: {0}",
+ "LabelRunningTimeValue": "Temps en funcionament: {0}",
"Latest": "Darreres",
- "MessageApplicationUpdated": "El Servidor d'Jellyfin ha estat actualitzat",
- "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}",
- "MessageNamedServerConfigurationUpdatedWithValue": "La secció de configuració {0} ha estat actualitzada",
+ "MessageApplicationUpdated": "El Servidor de Jellyfin ha estat actualitzat",
+ "MessageApplicationUpdatedTo": "El Servidor de Jellyfin ha estat actualitzat a {0}",
+ "MessageNamedServerConfigurationUpdatedWithValue": "La secció {0} de la configuració del servidor ha estat actualitzada",
"MessageServerConfigurationUpdated": "S'ha actualitzat la configuració del servidor",
"MixedContent": "Contingut mesclat",
"Movies": "Pel·lícules",
"Music": "Música",
"MusicVideos": "Vídeos musicals",
- "NameInstallFailed": "{0} installation failed",
+ "NameInstallFailed": "Instalació de {0} fallida",
"NameSeasonNumber": "Temporada {0}",
- "NameSeasonUnknown": "Season Unknown",
- "NewVersionIsAvailable": "A new version of Jellyfin Server is available for download.",
+ "NameSeasonUnknown": "Temporada Desconeguda",
+ "NewVersionIsAvailable": "Una nova versió del Servidor Jellyfin està disponible per descarregar.",
"NotificationOptionApplicationUpdateAvailable": "Actualització d'aplicació disponible",
"NotificationOptionApplicationUpdateInstalled": "Actualització d'aplicació instal·lada",
- "NotificationOptionAudioPlayback": "Audio playback started",
- "NotificationOptionAudioPlaybackStopped": "Audio playback stopped",
- "NotificationOptionCameraImageUploaded": "Camera image uploaded",
- "NotificationOptionInstallationFailed": "Installation failure",
- "NotificationOptionNewLibraryContent": "New content added",
- "NotificationOptionPluginError": "Un component ha fallat",
- "NotificationOptionPluginInstalled": "Complement instal·lat",
- "NotificationOptionPluginUninstalled": "Complement desinstal·lat",
- "NotificationOptionPluginUpdateInstalled": "Actualització de complement instal·lada",
- "NotificationOptionServerRestartRequired": "Server restart required",
- "NotificationOptionTaskFailed": "Scheduled task failure",
- "NotificationOptionUserLockedOut": "User locked out",
- "NotificationOptionVideoPlayback": "Video playback started",
- "NotificationOptionVideoPlaybackStopped": "Video playback stopped",
+ "NotificationOptionAudioPlayback": "Reproducció d'audio iniciada",
+ "NotificationOptionAudioPlaybackStopped": "Reproducció d'audio aturada",
+ "NotificationOptionCameraImageUploaded": "Imatge de càmera pujada",
+ "NotificationOptionInstallationFailed": "Instalació fallida",
+ "NotificationOptionNewLibraryContent": "Nou contingut afegit",
+ "NotificationOptionPluginError": "Un connector ha fallat",
+ "NotificationOptionPluginInstalled": "Connector instal·lat",
+ "NotificationOptionPluginUninstalled": "Connector desinstal·lat",
+ "NotificationOptionPluginUpdateInstalled": "Actualització de connector instal·lada",
+ "NotificationOptionServerRestartRequired": "Reinici del servidor requerit",
+ "NotificationOptionTaskFailed": "Tasca programada fallida",
+ "NotificationOptionUserLockedOut": "Usuari tancat",
+ "NotificationOptionVideoPlayback": "Reproducció de video iniciada",
+ "NotificationOptionVideoPlaybackStopped": "Reproducció de video aturada",
"Photos": "Fotos",
"Playlists": "Llistes de reproducció",
- "Plugin": "Plugin",
+ "Plugin": "Connector",
"PluginInstalledWithName": "{0} ha estat instal·lat",
"PluginUninstalledWithName": "{0} ha estat desinstal·lat",
"PluginUpdatedWithName": "{0} ha estat actualitzat",
"ProviderValue": "Proveïdor: {0}",
"ScheduledTaskFailedWithName": "{0} ha fallat",
"ScheduledTaskStartedWithName": "{0} iniciat",
- "ServerNameNeedsToBeRestarted": "{0} needs to be restarted",
- "Shows": "Espectacles",
+ "ServerNameNeedsToBeRestarted": "{0} necessita ser reiniciat",
+ "Shows": "Programes",
"Songs": "Cançons",
"StartupEmbyServerIsLoading": "El Servidor d'Jellyfin est&agrave; carregant. Si et plau, prova de nou en breus.",
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
- "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
+ "SubtitleDownloadFailureFromForItem": "Els subtítols no s'han pogut baixar de {0} per {1}",
"SubtitlesDownloadedForItem": "Subtítols descarregats per a {0}",
- "Sync": "Sync",
+ "Sync": "Sincronitzar",
"System": "System",
"TvShows": "Espectacles de TV",
"User": "User",
"UserCreatedWithName": "S'ha creat l'usuari {0}",
"UserDeletedWithName": "L'usuari {0} ha estat eliminat",
"UserDownloadingItemWithValues": "{0} està descarregant {1}",
- "UserLockedOutWithName": "User {0} has been locked out",
+ "UserLockedOutWithName": "L'usuari {0} ha sigut tancat",
"UserOfflineFromDevice": "{0} s'ha desconnectat de {1}",
"UserOnlineFromDevice": "{0} està connectat des de {1}",
"UserPasswordChangedWithName": "La contrasenya ha estat canviada per a l'usuari {0}",
- "UserPolicyUpdatedWithName": "User policy has been updated for {0}",
+ "UserPolicyUpdatedWithName": "La política d'usuari s'ha actualitzat per {0}",
"UserStartedPlayingItemWithValues": "{0} ha començat a reproduir {1}",
"UserStoppedPlayingItemWithValues": "{0} ha parat de reproduir {1}",
- "ValueHasBeenAddedToLibrary": "{0} has been added to your media library",
+ "ValueHasBeenAddedToLibrary": "{0} ha sigut afegit a la teva llibreria",
"ValueSpecialEpisodeName": "Especial - {0}",
"VersionNumber": "Versió {0}"
}
diff --git a/Emby.Server.Implementations/Localization/Core/de.json b/Emby.Server.Implementations/Localization/Core/de.json
index 0db201769..019736c47 100644
--- a/Emby.Server.Implementations/Localization/Core/de.json
+++ b/Emby.Server.Implementations/Localization/Core/de.json
@@ -3,14 +3,14 @@
"AppDeviceValues": "App: {0}, Gerät: {1}",
"Application": "Anwendung",
"Artists": "Interpreten",
- "AuthenticationSucceededWithUserName": "{0} hat sich angemeldet",
+ "AuthenticationSucceededWithUserName": "{0} hat sich erfolgreich angemeldet",
"Books": "Bücher",
"CameraImageUploadedFrom": "Ein neues Foto wurde hochgeladen von {0}",
"Channels": "Kanäle",
"ChapterNameValue": "Kapitel {0}",
"Collections": "Sammlungen",
"DeviceOfflineWithName": "{0} wurde getrennt",
- "DeviceOnlineWithName": "{0} hat sich verbunden",
+ "DeviceOnlineWithName": "{0} ist verbunden",
"FailedLoginAttemptWithUserName": "Fehlgeschlagener Anmeldeversuch von {0}",
"Favorites": "Favoriten",
"Folders": "Verzeichnisse",
@@ -23,7 +23,7 @@
"HeaderFavoriteEpisodes": "Lieblingsepisoden",
"HeaderFavoriteShows": "Lieblingsserien",
"HeaderFavoriteSongs": "Lieblingslieder",
- "HeaderLiveTV": "Live-TV",
+ "HeaderLiveTV": "Live TV",
"HeaderNextUp": "Als Nächstes",
"HeaderRecordingGroups": "Aufnahme-Gruppen",
"HomeVideos": "Heimvideos",
@@ -35,7 +35,7 @@
"Latest": "Neueste",
"MessageApplicationUpdated": "Jellyfin-Server wurde aktualisiert",
"MessageApplicationUpdatedTo": "Jellyfin-Server wurde auf Version {0} aktualisiert",
- "MessageNamedServerConfigurationUpdatedWithValue": "Der Server Einstellungsbereich {0} wurde aktualisiert",
+ "MessageNamedServerConfigurationUpdatedWithValue": "Der Server-Einstellungsbereich {0} wurde aktualisiert",
"MessageServerConfigurationUpdated": "Servereinstellungen wurden aktualisiert",
"MixedContent": "Gemischte Inhalte",
"Movies": "Filme",
diff --git a/Emby.Server.Implementations/Localization/Core/el.json b/Emby.Server.Implementations/Localization/Core/el.json
index 3589a4893..580b42330 100644
--- a/Emby.Server.Implementations/Localization/Core/el.json
+++ b/Emby.Server.Implementations/Localization/Core/el.json
@@ -3,7 +3,7 @@
"AppDeviceValues": "Εφαρμογή: {0}, Συσκευή: {1}",
"Application": "Εφαρμογή",
"Artists": "Καλλιτέχνες",
- "AuthenticationSucceededWithUserName": "Ο χρήστης {0} επαληθεύτηκε με επιτυχία",
+ "AuthenticationSucceededWithUserName": "Ο χρήστης {0} επαληθεύτηκε επιτυχώς",
"Books": "Βιβλία",
"CameraImageUploadedFrom": "Μια νέα εικόνα κάμερας έχει αποσταλεί από {0}",
"Channels": "Κανάλια",
diff --git a/Emby.Server.Implementations/Localization/Core/he.json b/Emby.Server.Implementations/Localization/Core/he.json
index 0ed998c4b..b08c8966e 100644
--- a/Emby.Server.Implementations/Localization/Core/he.json
+++ b/Emby.Server.Implementations/Localization/Core/he.json
@@ -1,41 +1,41 @@
{
"Albums": "אלבומים",
- "AppDeviceValues": "App: {0}, Device: {1}",
+ "AppDeviceValues": "יישום: {0}, מכשיר: {1}",
"Application": "אפליקציה",
"Artists": "אמנים",
- "AuthenticationSucceededWithUserName": "{0} successfully authenticated",
+ "AuthenticationSucceededWithUserName": "{0} זוהה בהצלחה",
"Books": "ספרים",
- "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
- "Channels": "Channels",
- "ChapterNameValue": "Chapter {0}",
- "Collections": "Collections",
- "DeviceOfflineWithName": "{0} has disconnected",
- "DeviceOnlineWithName": "{0} is connected",
- "FailedLoginAttemptWithUserName": "Failed login attempt from {0}",
- "Favorites": "Favorites",
- "Folders": "Folders",
+ "CameraImageUploadedFrom": "תמונה חדשה הועלתה מ{0}",
+ "Channels": "ערוצים",
+ "ChapterNameValue": "פרק {0}",
+ "Collections": "קולקציות",
+ "DeviceOfflineWithName": "{0} התנתק",
+ "DeviceOnlineWithName": "{0} מחובר",
+ "FailedLoginAttemptWithUserName": "ניסיון כניסה שגוי מ{0}",
+ "Favorites": "אהובים",
+ "Folders": "תיקיות",
"Genres": "ז'אנרים",
- "HeaderAlbumArtists": "Album Artists",
- "HeaderCameraUploads": "Camera Uploads",
- "HeaderContinueWatching": "המשך בצפייה",
- "HeaderFavoriteAlbums": "Favorite Albums",
- "HeaderFavoriteArtists": "Favorite Artists",
- "HeaderFavoriteEpisodes": "Favorite Episodes",
- "HeaderFavoriteShows": "Favorite Shows",
- "HeaderFavoriteSongs": "Favorite Songs",
- "HeaderLiveTV": "Live TV",
- "HeaderNextUp": "Next Up",
+ "HeaderAlbumArtists": "אמני האלבום",
+ "HeaderCameraUploads": "העלאות ממצלמה",
+ "HeaderContinueWatching": "המשך לצפות",
+ "HeaderFavoriteAlbums": "אלבומים שאהבתי",
+ "HeaderFavoriteArtists": "אמנים שאהבתי",
+ "HeaderFavoriteEpisodes": "פרקים אהובים",
+ "HeaderFavoriteShows": "תוכניות אהובות",
+ "HeaderFavoriteSongs": "שירים שאהבתי",
+ "HeaderLiveTV": "טלוויזיה בשידור חי",
+ "HeaderNextUp": "הבא",
"HeaderRecordingGroups": "קבוצות הקלטה",
- "HomeVideos": "Home videos",
- "Inherit": "Inherit",
+ "HomeVideos": "סרטונים בייתים",
+ "Inherit": "הורש",
"ItemAddedWithName": "{0} was added to the library",
- "ItemRemovedWithName": "{0} was removed from the library",
- "LabelIpAddressValue": "Ip address: {0}",
- "LabelRunningTimeValue": "Running time: {0}",
+ "ItemRemovedWithName": "{0} נמחק מהספרייה",
+ "LabelIpAddressValue": "Ip כתובת: {0}",
+ "LabelRunningTimeValue": "משך צפייה: {0}",
"Latest": "אחרון",
- "MessageApplicationUpdated": "Jellyfin Server has been updated",
- "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}",
- "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated",
+ "MessageApplicationUpdated": "שרת הJellyfin עודכן",
+ "MessageApplicationUpdatedTo": "שרת הJellyfin עודכן לגרסא {0}",
+ "MessageNamedServerConfigurationUpdatedWithValue": "הגדרת השרת {0} שונתה",
"MessageServerConfigurationUpdated": "Server configuration has been updated",
"MixedContent": "תוכן מעורב",
"Movies": "סרטים",
@@ -50,7 +50,7 @@
"NotificationOptionAudioPlayback": "Audio playback started",
"NotificationOptionAudioPlaybackStopped": "Audio playback stopped",
"NotificationOptionCameraImageUploaded": "Camera image uploaded",
- "NotificationOptionInstallationFailed": "Installation failure",
+ "NotificationOptionInstallationFailed": "התקנה נכשלה",
"NotificationOptionNewLibraryContent": "New content added",
"NotificationOptionPluginError": "Plugin failure",
"NotificationOptionPluginInstalled": "Plugin installed",
diff --git a/Emby.Server.Implementations/Localization/Core/id.json b/Emby.Server.Implementations/Localization/Core/id.json
new file mode 100644
index 000000000..8d17ad38e
--- /dev/null
+++ b/Emby.Server.Implementations/Localization/Core/id.json
@@ -0,0 +1,32 @@
+{
+ "Albums": "Album",
+ "AuthenticationSucceededWithUserName": "{0} berhasil diautentikasi",
+ "AppDeviceValues": "Aplikasi: {0}, Alat: {1}",
+ "LabelRunningTimeValue": "Waktu berjalan: {0}",
+ "MessageApplicationUpdatedTo": "Jellyfin Server sudah diperbarui ke {0}",
+ "MessageApplicationUpdated": "Jellyfin Server sudah diperbarui",
+ "Latest": "Terbaru",
+ "LabelIpAddressValue": "IP address: {0}",
+ "ItemRemovedWithName": "{0} sudah dikeluarkan dari perpustakaan",
+ "ItemAddedWithName": "{0} sudah dimasukkan ke dalam perpustakaan",
+ "Inherit": "Warisan",
+ "HomeVideos": "Video Rumah",
+ "HeaderRecordingGroups": "Grup Rekaman",
+ "HeaderNextUp": "Selanjutnya",
+ "HeaderLiveTV": "TV Live",
+ "HeaderFavoriteSongs": "Lagu Favorit",
+ "HeaderFavoriteShows": "Tayangan Favorit",
+ "HeaderFavoriteEpisodes": "Episode Favorit",
+ "HeaderFavoriteArtists": "Artis Favorit",
+ "HeaderFavoriteAlbums": "Album Favorit",
+ "HeaderContinueWatching": "Masih Melihat",
+ "HeaderCameraUploads": "Uplod Kamera",
+ "HeaderAlbumArtists": "Album Artis",
+ "Genres": "Genre",
+ "Folders": "Folder",
+ "Favorites": "Favorit",
+ "Collections": "Koleksi",
+ "Books": "Buku",
+ "Artists": "Artis",
+ "Application": "Aplikasi"
+}
diff --git a/Emby.Server.Implementations/Localization/Core/is.json b/Emby.Server.Implementations/Localization/Core/is.json
new file mode 100644
index 000000000..c3b5211b8
--- /dev/null
+++ b/Emby.Server.Implementations/Localization/Core/is.json
@@ -0,0 +1,78 @@
+{
+ "LabelIpAddressValue": "IP tala: {0}",
+ "ItemRemovedWithName": "{0} var fjarlægt úr safninu",
+ "ItemAddedWithName": "{0} var bætt í safnið",
+ "Inherit": "Erfa",
+ "HomeVideos": "Myndbönd að heiman",
+ "HeaderRecordingGroups": "Upptökuhópar",
+ "HeaderNextUp": "Næst á dagskrá",
+ "HeaderLiveTV": "Sjónvarp í beinni útsendingu",
+ "HeaderFavoriteSongs": "Uppáhalds Lög",
+ "HeaderFavoriteShows": "Uppáhalds Sjónvarpsþættir",
+ "HeaderFavoriteEpisodes": "Uppáhalds Þættir",
+ "HeaderFavoriteArtists": "Uppáhalds Listamenn",
+ "HeaderFavoriteAlbums": "Uppáhalds Plötur",
+ "HeaderContinueWatching": "Halda áfram að horfa",
+ "HeaderCameraUploads": "Myndavéla upphal",
+ "HeaderAlbumArtists": "Höfundur plötu",
+ "Genres": "Tegundir",
+ "Folders": "Möppur",
+ "Favorites": "Uppáhalds",
+ "FailedLoginAttemptWithUserName": "{0} reyndi að auðkenna sig",
+ "DeviceOnlineWithName": "{0} hefur tengst",
+ "DeviceOfflineWithName": "{0} hefur aftengst",
+ "Collections": "Söfn",
+ "ChapterNameValue": "Kafli {0}",
+ "Channels": "Stöðvar",
+ "CameraImageUploadedFrom": "Ný ljósmynd frá myndavél hefur verið hlaðið upp frá {0}",
+ "Books": "Bækur",
+ "AuthenticationSucceededWithUserName": "{0} náði að auðkennast",
+ "Artists": "Listamaður",
+ "Application": "Forrit",
+ "AppDeviceValues": "Snjallforrit: {0}, Tæki: {1}",
+ "Albums": "Plötur",
+ "Plugin": "Viðbót",
+ "Photos": "Myndir",
+ "NotificationOptionVideoPlaybackStopped": "Myndbandafspilun stöðvuð",
+ "NotificationOptionVideoPlayback": "Myndbandafspilun hafin",
+ "NotificationOptionUserLockedOut": "Notandi læstur úti",
+ "NotificationOptionServerRestartRequired": "Endurræsing miðlara nauðsynileg",
+ "NotificationOptionPluginUpdateInstalled": "Viðbótar uppfærsla uppsett",
+ "NotificationOptionPluginUninstalled": "Viðbót fjarlægð",
+ "NotificationOptionPluginInstalled": "Viðbót settur upp",
+ "NotificationOptionPluginError": "Bilun í viðbót",
+ "NotificationOptionInstallationFailed": "Uppsetning tókst ekki",
+ "NotificationOptionCameraImageUploaded": "Myndavélarmynd hlaðið upp",
+ "NotificationOptionAudioPlaybackStopped": "Hljóðafspilun stöðvuð",
+ "NotificationOptionAudioPlayback": "Hljóðafspilun hafin",
+ "NotificationOptionApplicationUpdateInstalled": "Uppfærsla uppsett",
+ "NotificationOptionApplicationUpdateAvailable": "Uppfærsla í boði",
+ "NameSeasonUnknown": "Sería óþekkt",
+ "NameSeasonNumber": "Sería {0}",
+ "MixedContent": "Blandað efni",
+ "MessageServerConfigurationUpdated": "Stillingar miðlarans hefur verið uppfærð",
+ "MessageApplicationUpdatedTo": "Jellyfin Server hefur verið uppfærður í {0}",
+ "MessageApplicationUpdated": "Jellyfin Server hefur verið uppfærður",
+ "Latest": "Nýjasta",
+ "LabelRunningTimeValue": "Keyrslutími kerfis: {0}",
+ "User": "Notandi",
+ "System": "Kerfi",
+ "NotificationOptionNewLibraryContent": "Nýju efni bætt við",
+ "NewVersionIsAvailable": "Ný útgáfa af Jellyfin Server er fáanleg til niðurhals.",
+ "NameInstallFailed": "{0} uppsetning mistókst",
+ "MusicVideos": "Tónlistarmyndbönd",
+ "Music": "Tónlist",
+ "Movies": "Kvikmyndir",
+ "UserDeletedWithName": "Notanda {0} hefur verið eytt",
+ "UserCreatedWithName": "Notandi {0} hefur verið stofnaður",
+ "TvShows": "Þættir",
+ "Sync": "Samstilla",
+ "Songs": "Lög",
+ "ServerNameNeedsToBeRestarted": "{0} þarf að endurræsa",
+ "ScheduledTaskStartedWithName": "{0} hafin",
+ "ScheduledTaskFailedWithName": "{0} mistókst",
+ "PluginUpdatedWithName": "{0} var uppfært",
+ "PluginUninstalledWithName": "{0} var fjarlægt",
+ "PluginInstalledWithName": "{0} var sett upp",
+ "NotificationOptionTaskFailed": "Tímasett verkefni mistókst"
+}
diff --git a/Emby.Server.Implementations/Localization/Core/it.json b/Emby.Server.Implementations/Localization/Core/it.json
index 357883cd3..8f91effb9 100644
--- a/Emby.Server.Implementations/Localization/Core/it.json
+++ b/Emby.Server.Implementations/Localization/Core/it.json
@@ -9,13 +9,13 @@
"Channels": "Canali",
"ChapterNameValue": "Capitolo {0}",
"Collections": "Collezioni",
- "DeviceOfflineWithName": "{0} è stato disconnesso",
+ "DeviceOfflineWithName": "{0} ha disconnesso",
"DeviceOnlineWithName": "{0} è connesso",
"FailedLoginAttemptWithUserName": "Tentativo di accesso fallito da {0}",
"Favorites": "Preferiti",
"Folders": "Cartelle",
"Genres": "Generi",
- "HeaderAlbumArtists": "Artisti Album",
+ "HeaderAlbumArtists": "Artisti dell' Album",
"HeaderCameraUploads": "Caricamenti Fotocamera",
"HeaderContinueWatching": "Continua a guardare",
"HeaderFavoriteAlbums": "Album preferiti",
@@ -32,7 +32,7 @@
"ItemRemovedWithName": "{0} è stato rimosso dalla libreria",
"LabelIpAddressValue": "Indirizzo IP: {0}",
"LabelRunningTimeValue": "Durata: {0}",
- "Latest": "Più recenti",
+ "Latest": "Novità",
"MessageApplicationUpdated": "Il Server Jellyfin è stato aggiornato",
"MessageApplicationUpdatedTo": "Jellyfin Server è stato aggiornato a {0}",
"MessageNamedServerConfigurationUpdatedWithValue": "La sezione {0} della configurazione server è stata aggiornata",
@@ -43,7 +43,7 @@
"MusicVideos": "Video musicali",
"NameInstallFailed": "{0} installazione fallita",
"NameSeasonNumber": "Stagione {0}",
- "NameSeasonUnknown": "Stagione sconosciuto",
+ "NameSeasonUnknown": "Stagione sconosciuta",
"NewVersionIsAvailable": "Una nuova versione di Jellyfin Server è disponibile per il download.",
"NotificationOptionApplicationUpdateAvailable": "Aggiornamento dell'applicazione disponibile",
"NotificationOptionApplicationUpdateInstalled": "Aggiornamento dell'applicazione installato",
@@ -88,9 +88,9 @@
"UserOfflineFromDevice": "{0} è stato disconnesso da {1}",
"UserOnlineFromDevice": "{0} è online da {1}",
"UserPasswordChangedWithName": "La password è stata cambiata per l'utente {0}",
- "UserPolicyUpdatedWithName": "La politica dell'utente è stata aggiornata per {0}",
- "UserStartedPlayingItemWithValues": "{0} ha avviato la riproduzione di {1}",
- "UserStoppedPlayingItemWithValues": "{0} ha interrotto la riproduzione di {1}",
+ "UserPolicyUpdatedWithName": "La policy dell'utente è stata aggiornata per {0}",
+ "UserStartedPlayingItemWithValues": "{0} ha avviato la riproduzione di {1} su {2}",
+ "UserStoppedPlayingItemWithValues": "{0} ha interrotto la riproduzione di {1} su {2}",
"ValueHasBeenAddedToLibrary": "{0} è stato aggiunto alla tua libreria multimediale",
"ValueSpecialEpisodeName": "Speciale - {0}",
"VersionNumber": "Versione {0}"
diff --git a/Emby.Server.Implementations/Localization/Core/ko.json b/Emby.Server.Implementations/Localization/Core/ko.json
index 3d2350c07..0320a0a1b 100644
--- a/Emby.Server.Implementations/Localization/Core/ko.json
+++ b/Emby.Server.Implementations/Localization/Core/ko.json
@@ -5,13 +5,13 @@
"Artists": "아티스트",
"AuthenticationSucceededWithUserName": "{0}이 성공적으로 인증됨",
"Books": "도서",
- "CameraImageUploadedFrom": "{0}에서 새로운 카메라 이미지가 업로드되었습니다",
+ "CameraImageUploadedFrom": "{0}에서 새로운 카메라 이미지가 업로드됨",
"Channels": "채널",
"ChapterNameValue": "챕터 {0}",
"Collections": "컬렉션",
- "DeviceOfflineWithName": "{0} 연결 끊김",
- "DeviceOnlineWithName": "{0} 연결됨",
- "FailedLoginAttemptWithUserName": "{0} 로그인 실패",
+ "DeviceOfflineWithName": "{0}의 연결 끊김",
+ "DeviceOnlineWithName": "{0}이 연결됨",
+ "FailedLoginAttemptWithUserName": "{0}에서 로그인 실패",
"Favorites": "즐겨찾기",
"Folders": "폴더",
"Genres": "장르",
diff --git a/Emby.Server.Implementations/Localization/Core/nb.json b/Emby.Server.Implementations/Localization/Core/nb.json
index 1237fb70a..48216f71c 100644
--- a/Emby.Server.Implementations/Localization/Core/nb.json
+++ b/Emby.Server.Implementations/Localization/Core/nb.json
@@ -45,7 +45,7 @@
"NameSeasonNumber": "Sesong {0}",
"NameSeasonUnknown": "Sesong ukjent",
"NewVersionIsAvailable": "En ny versjon av Jellyfin-serveren er tilgjengelig for nedlastning.",
- "NotificationOptionApplicationUpdateAvailable": "Applikasjon oppdatering tilgjengelig",
+ "NotificationOptionApplicationUpdateAvailable": "Programvareoppdatering er tilgjengelig",
"NotificationOptionApplicationUpdateInstalled": "Applikasjonsoppdatering installert",
"NotificationOptionAudioPlayback": "Lyd tilbakespilling startet",
"NotificationOptionAudioPlaybackStopped": "Lyd avspilling stoppet",
diff --git a/Emby.Server.Implementations/Localization/Core/nl.json b/Emby.Server.Implementations/Localization/Core/nl.json
index 637e514ed..4423b7f98 100644
--- a/Emby.Server.Implementations/Localization/Core/nl.json
+++ b/Emby.Server.Implementations/Localization/Core/nl.json
@@ -5,10 +5,10 @@
"Artists": "Artiesten",
"AuthenticationSucceededWithUserName": "{0} is succesvol geverifieerd",
"Books": "Boeken",
- "CameraImageUploadedFrom": "Er is een nieuwe foto toegevoegd via {0}",
+ "CameraImageUploadedFrom": "Er is een nieuwe foto toegevoegd van {0}",
"Channels": "Kanalen",
"ChapterNameValue": "Hoofdstuk {0}",
- "Collections": "Collecties",
+ "Collections": "Verzamelingen",
"DeviceOfflineWithName": "{0} heeft de verbinding verbroken",
"DeviceOnlineWithName": "{0} is verbonden",
"FailedLoginAttemptWithUserName": "Mislukte aanmeld poging van {0}",
@@ -58,7 +58,7 @@
"NotificationOptionPluginUpdateInstalled": "Plug-in-update geïnstalleerd",
"NotificationOptionServerRestartRequired": "Server herstart nodig",
"NotificationOptionTaskFailed": "Geplande taak mislukt",
- "NotificationOptionUserLockedOut": "Gebruikersaccount vergrendeld",
+ "NotificationOptionUserLockedOut": "Gebruiker is vergrendeld",
"NotificationOptionVideoPlayback": "Video gestart",
"NotificationOptionVideoPlaybackStopped": "Video gestopt",
"Photos": "Foto's",
diff --git a/Emby.Server.Implementations/Localization/Core/pt-BR.json b/Emby.Server.Implementations/Localization/Core/pt-BR.json
index faa8499b8..41a389e3b 100644
--- a/Emby.Server.Implementations/Localization/Core/pt-BR.json
+++ b/Emby.Server.Implementations/Localization/Core/pt-BR.json
@@ -1,7 +1,7 @@
{
"Albums": "Álbuns",
"AppDeviceValues": "App: {0}, Dispositivo: {1}",
- "Application": "Inscrição",
+ "Application": "Aplicativo",
"Artists": "Artistas",
"AuthenticationSucceededWithUserName": "{0} autenticado com sucesso",
"Books": "Livros",
@@ -10,7 +10,7 @@
"ChapterNameValue": "Capítulo {0}",
"Collections": "Coletâneas",
"DeviceOfflineWithName": "{0} se desconectou",
- "DeviceOnlineWithName": "{0} está conectado",
+ "DeviceOnlineWithName": "{0} se conectou",
"FailedLoginAttemptWithUserName": "Falha na tentativa de login de {0}",
"Favorites": "Favoritos",
"Folders": "Pastas",
@@ -24,7 +24,7 @@
"HeaderFavoriteShows": "Séries Favoritas",
"HeaderFavoriteSongs": "Músicas Favoritas",
"HeaderLiveTV": "TV ao Vivo",
- "HeaderNextUp": "Próximos",
+ "HeaderNextUp": "A Seguir",
"HeaderRecordingGroups": "Grupos de Gravação",
"HomeVideos": "Vídeos caseiros",
"Inherit": "Herdar",
@@ -40,16 +40,16 @@
"MixedContent": "Conteúdo misto",
"Movies": "Filmes",
"Music": "Música",
- "MusicVideos": "Clipes",
+ "MusicVideos": "Videoclipes",
"NameInstallFailed": "A instalação de {0} falhou",
"NameSeasonNumber": "Temporada {0}",
"NameSeasonUnknown": "Temporada Desconhecida",
"NewVersionIsAvailable": "Uma nova versão do Servidor Jellyfin está disponível para download.",
- "NotificationOptionApplicationUpdateAvailable": "Atualização de aplicativo disponível",
- "NotificationOptionApplicationUpdateInstalled": "Atualização de aplicativo instalada",
+ "NotificationOptionApplicationUpdateAvailable": "Atualização do aplicativo disponível",
+ "NotificationOptionApplicationUpdateInstalled": "Atualização do aplicativo instalada",
"NotificationOptionAudioPlayback": "Reprodução de áudio iniciada",
"NotificationOptionAudioPlaybackStopped": "Reprodução de áudio parada",
- "NotificationOptionCameraImageUploaded": "Imagem de câmera enviada",
+ "NotificationOptionCameraImageUploaded": "Imagem da câmera enviada",
"NotificationOptionInstallationFailed": "Falha na instalação",
"NotificationOptionNewLibraryContent": "Novo conteúdo adicionado",
"NotificationOptionPluginError": "Falha de plugin",
@@ -73,7 +73,7 @@
"ServerNameNeedsToBeRestarted": "O servidor {0} precisa ser reiniciado",
"Shows": "Séries",
"Songs": "Músicas",
- "StartupEmbyServerIsLoading": "O Servidor Jellyfin está carregando. Por favor tente novamente em breve.",
+ "StartupEmbyServerIsLoading": "O Servidor Jellyfin está carregando. Por favor, tente novamente mais tarde.",
"SubtitleDownloadFailureForItem": "Download de legendas falhou para {0}",
"SubtitleDownloadFailureFromForItem": "Houve um problema ao baixar as legendas de {0} para {1}",
"SubtitlesDownloadedForItem": "Legendas baixadas para {0}",
@@ -86,12 +86,12 @@
"UserDownloadingItemWithValues": "{0} está baixando {1}",
"UserLockedOutWithName": "Usuário {0} foi bloqueado",
"UserOfflineFromDevice": "{0} se desconectou de {1}",
- "UserOnlineFromDevice": "{0} está ativo em {1}",
+ "UserOnlineFromDevice": "{0} está online em {1}",
"UserPasswordChangedWithName": "A senha foi alterada para o usuário {0}",
"UserPolicyUpdatedWithName": "A política de usuário foi atualizada para {0}",
- "UserStartedPlayingItemWithValues": "{0} iniciou a reprodução de {1}",
- "UserStoppedPlayingItemWithValues": "{0} parou de reproduzir {1}",
- "ValueHasBeenAddedToLibrary": "{0} foi adicionado a sua biblioteca",
+ "UserStartedPlayingItemWithValues": "{0} está reproduzindo {1} em {2}",
+ "UserStoppedPlayingItemWithValues": "{0} parou de reproduzir {1} em {2}",
+ "ValueHasBeenAddedToLibrary": "{0} foi adicionado à sua biblioteca de mídia",
"ValueSpecialEpisodeName": "Especial - {0}",
"VersionNumber": "Versão {0}"
}
diff --git a/Emby.Server.Implementations/Localization/Core/ru.json b/Emby.Server.Implementations/Localization/Core/ru.json
index 0ad4b37aa..7cf957a94 100644
--- a/Emby.Server.Implementations/Localization/Core/ru.json
+++ b/Emby.Server.Implementations/Localization/Core/ru.json
@@ -1,11 +1,11 @@
{
"Albums": "Альбомы",
- "AppDeviceValues": "Прил.: {0}, Устр.: {1}",
+ "AppDeviceValues": "Приложение.: {0}, Устройство.: {1}",
"Application": "Приложение",
"Artists": "Исполнители",
"AuthenticationSucceededWithUserName": "{0} - авторизация успешна",
- "Books": "Литература",
- "CameraImageUploadedFrom": "Новое фото было выложено с камеры {0}",
+ "Books": "Книги",
+ "CameraImageUploadedFrom": "Новое фото загружено с камеры {0}",
"Channels": "Каналы",
"ChapterNameValue": "Сцена {0}",
"Collections": "Коллекции",
diff --git a/Emby.Server.Implementations/Localization/Core/sk.json b/Emby.Server.Implementations/Localization/Core/sk.json
index 6eade7942..9bac305a2 100644
--- a/Emby.Server.Implementations/Localization/Core/sk.json
+++ b/Emby.Server.Implementations/Localization/Core/sk.json
@@ -1,28 +1,28 @@
{
"Albums": "Albumy",
- "AppDeviceValues": "Apka: {0}, Zariadenie: {1}",
+ "AppDeviceValues": "Aplikácia: {0}, Zariadenie: {1}",
"Application": "Aplikácia",
"Artists": "Umelci",
"AuthenticationSucceededWithUserName": "{0} úspešne overený",
"Books": "Knihy",
- "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
+ "CameraImageUploadedFrom": "Z {0} bola nahraná nová fotografia",
"Channels": "Kanály",
"ChapterNameValue": "Kapitola {0}",
- "Collections": "Zbierky",
+ "Collections": "Kolekcie",
"DeviceOfflineWithName": "{0} sa odpojil",
"DeviceOnlineWithName": "{0} je pripojený",
"FailedLoginAttemptWithUserName": "Neúspešný pokus o prihlásenie z {0}",
"Favorites": "Obľúbené",
"Folders": "Priečinky",
"Genres": "Žánre",
- "HeaderAlbumArtists": "Album Artists",
+ "HeaderAlbumArtists": "Albumy umelcov",
"HeaderCameraUploads": "Nahrané fotografie",
- "HeaderContinueWatching": "Pokračujte v pozeraní",
+ "HeaderContinueWatching": "Pokračovať v pozeraní",
"HeaderFavoriteAlbums": "Obľúbené albumy",
"HeaderFavoriteArtists": "Obľúbení umelci",
"HeaderFavoriteEpisodes": "Obľúbené epizódy",
"HeaderFavoriteShows": "Obľúbené seriály",
- "HeaderFavoriteSongs": "Obľúbené pesničky",
+ "HeaderFavoriteSongs": "Obľúbené piesne",
"HeaderLiveTV": "Živá TV",
"HeaderNextUp": "Nasleduje",
"HeaderRecordingGroups": "Skupiny nahrávok",
@@ -34,7 +34,7 @@
"LabelRunningTimeValue": "Dĺžka: {0}",
"Latest": "Najnovšie",
"MessageApplicationUpdated": "Jellyfin Server bol aktualizovaný",
- "MessageApplicationUpdatedTo": "Jellyfin Server bol aktualizový na {0}",
+ "MessageApplicationUpdatedTo": "Jellyfin Server bol aktualizový na verziu {0}",
"MessageNamedServerConfigurationUpdatedWithValue": "Sekcia {0} konfigurácie servera bola aktualizovaná",
"MessageServerConfigurationUpdated": "Konfigurácia servera bola aktualizovaná",
"MixedContent": "Zmiešaný obsah",
@@ -42,23 +42,23 @@
"Music": "Hudba",
"MusicVideos": "Hudobné videá",
"NameInstallFailed": "Inštalácia {0} zlyhala",
- "NameSeasonNumber": "Sezóna {0}",
- "NameSeasonUnknown": "Neznáma sezóna",
- "NewVersionIsAvailable": "Nová verzia Jellyfin Server je dostupná na stiahnutie.",
- "NotificationOptionApplicationUpdateAvailable": "Je dostupná aktualizácia aplikácie",
+ "NameSeasonNumber": "Séria {0}",
+ "NameSeasonUnknown": "Neznáma séria",
+ "NewVersionIsAvailable": "Nová verzia Jellyfin Serveru je dostupná na stiahnutie.",
+ "NotificationOptionApplicationUpdateAvailable": "Aktualizácia aplikácie je dostupná",
"NotificationOptionApplicationUpdateInstalled": "Aktualizácia aplikácie nainštalovaná",
- "NotificationOptionAudioPlayback": "Spustené prehrávanie audia",
- "NotificationOptionAudioPlaybackStopped": "Zastavené prehrávanie audia",
- "NotificationOptionCameraImageUploaded": "Nahraný obrázok z fotoaparátu",
+ "NotificationOptionAudioPlayback": "Prehrávanie audia bolo spustené",
+ "NotificationOptionAudioPlaybackStopped": "Prehrávanie audia bolo zastavené",
+ "NotificationOptionCameraImageUploaded": "Obrázok z fotoaparátu bol nahraný",
"NotificationOptionInstallationFailed": "Chyba inštalácie",
- "NotificationOptionNewLibraryContent": "Pridaný nový obsah",
+ "NotificationOptionNewLibraryContent": "Nový obsah bol pridaný",
"NotificationOptionPluginError": "Chyba rozšírenia",
"NotificationOptionPluginInstalled": "Rozšírenie nainštalované",
"NotificationOptionPluginUninstalled": "Rozšírenie odinštalované",
"NotificationOptionPluginUpdateInstalled": "Aktualizácia rozšírenia nainštalovaná",
"NotificationOptionServerRestartRequired": "Vyžaduje sa reštart servera",
"NotificationOptionTaskFailed": "Naplánovaná úloha zlyhala",
- "NotificationOptionUserLockedOut": "User locked out",
+ "NotificationOptionUserLockedOut": "Používateľ je uzamknutý",
"NotificationOptionVideoPlayback": "Spustené prehrávanie videa",
"NotificationOptionVideoPlaybackStopped": "Zastavené prehrávanie videa",
"Photos": "Fotky",
@@ -69,9 +69,9 @@
"PluginUpdatedWithName": "{0} bol aktualizovaný",
"ProviderValue": "Poskytovateľ: {0}",
"ScheduledTaskFailedWithName": "{0} zlyhalo",
- "ScheduledTaskStartedWithName": "{0} started",
+ "ScheduledTaskStartedWithName": "{0} zahájených",
"ServerNameNeedsToBeRestarted": "{0} vyžaduje reštart",
- "Shows": "Series",
+ "Shows": "Seriály",
"Songs": "Skladby",
"StartupEmbyServerIsLoading": "Jellyfin Server sa spúšťa. Skúste to prosím o chvíľu znova.",
"SubtitleDownloadFailureForItem": "Sťahovanie titulkov pre {0} zlyhalo",
@@ -84,11 +84,11 @@
"UserCreatedWithName": "Používateľ {0} bol vytvorený",
"UserDeletedWithName": "Používateľ {0} bol vymazaný",
"UserDownloadingItemWithValues": "{0} sťahuje {1}",
- "UserLockedOutWithName": "User {0} has been locked out",
+ "UserLockedOutWithName": "Používateľ {0} bol vymknutý",
"UserOfflineFromDevice": "{0} sa odpojil od {1}",
"UserOnlineFromDevice": "{0} je online z {1}",
"UserPasswordChangedWithName": "Heslo používateľa {0} zmenené",
- "UserPolicyUpdatedWithName": "User policy has been updated for {0}",
+ "UserPolicyUpdatedWithName": "Používateľské zásady pre {0} boli aktualizované",
"UserStartedPlayingItemWithValues": "{0} spustil prehrávanie {1}",
"UserStoppedPlayingItemWithValues": "{0} zastavil prehrávanie {1}",
"ValueHasBeenAddedToLibrary": "{0} bolo pridané do vašej knižnice médií",
diff --git a/Emby.Server.Implementations/Localization/Core/sv.json b/Emby.Server.Implementations/Localization/Core/sv.json
index fb2761a7d..744b0e2d3 100644
--- a/Emby.Server.Implementations/Localization/Core/sv.json
+++ b/Emby.Server.Implementations/Localization/Core/sv.json
@@ -5,7 +5,7 @@
"Artists": "Artister",
"AuthenticationSucceededWithUserName": "{0} har autentiserats",
"Books": "Böcker",
- "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
+ "CameraImageUploadedFrom": "En ny kamerabild har laddats upp från {0}",
"Channels": "Kanaler",
"ChapterNameValue": "Kapitel {0}",
"Collections": "Samlingar",
@@ -16,7 +16,7 @@
"Folders": "Mappar",
"Genres": "Genrer",
"HeaderAlbumArtists": "Albumartister",
- "HeaderCameraUploads": "Camera Uploads",
+ "HeaderCameraUploads": "Kamera Uppladdningar",
"HeaderContinueWatching": "Fortsätt kolla på",
"HeaderFavoriteAlbums": "Favoritalbum",
"HeaderFavoriteArtists": "Favoritartister",
@@ -34,17 +34,17 @@
"LabelRunningTimeValue": "Speltid: {0}",
"Latest": "Senaste",
"MessageApplicationUpdated": "Jellyfin Server har uppdaterats",
- "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}",
+ "MessageApplicationUpdatedTo": "Jellyfin Server har uppgraderats till {0}",
"MessageNamedServerConfigurationUpdatedWithValue": "Serverinställningarna {0} har uppdaterats",
"MessageServerConfigurationUpdated": "Server konfigurationen har uppdaterats",
"MixedContent": "Blandat innehåll",
"Movies": "Filmer",
"Music": "Musik",
"MusicVideos": "Musikvideos",
- "NameInstallFailed": "{0} installation failed",
+ "NameInstallFailed": "{0} installationen misslyckades",
"NameSeasonNumber": "Säsong {0}",
"NameSeasonUnknown": "Okänd säsong",
- "NewVersionIsAvailable": "A new version of Jellyfin Server is available for download.",
+ "NewVersionIsAvailable": "En ny version av Jellyfin Server är klar för nedladdning.",
"NotificationOptionApplicationUpdateAvailable": "Ny programversion tillgänglig",
"NotificationOptionApplicationUpdateInstalled": "Programuppdatering installerad",
"NotificationOptionAudioPlayback": "Ljuduppspelning har påbörjats",
@@ -70,12 +70,12 @@
"ProviderValue": "Källa: {0}",
"ScheduledTaskFailedWithName": "{0} misslyckades",
"ScheduledTaskStartedWithName": "{0} startad",
- "ServerNameNeedsToBeRestarted": "{0} needs to be restarted",
+ "ServerNameNeedsToBeRestarted": "{0} behöver startas om",
"Shows": "Serier",
"Songs": "Låtar",
"StartupEmbyServerIsLoading": "Jellyfin server arbetar. Pröva igen inom kort.",
"SubtitleDownloadFailureForItem": "Nerladdning av undertexter för {0} misslyckades",
- "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
+ "SubtitleDownloadFailureFromForItem": "Undertexter misslyckades att ladda ner {0} för {1}",
"SubtitlesDownloadedForItem": "Undertexter har laddats ner till {0}",
"Sync": "Synk",
"System": "System",
@@ -91,7 +91,7 @@
"UserPolicyUpdatedWithName": "Användarpolicyn har uppdaterats för {0}",
"UserStartedPlayingItemWithValues": "{0} har börjat spela upp {1}",
"UserStoppedPlayingItemWithValues": "{0} har avslutat uppspelningen av {1}",
- "ValueHasBeenAddedToLibrary": "{0} has been added to your media library",
+ "ValueHasBeenAddedToLibrary": "{0} har blivit tillagd till ditt mediabibliotek",
"ValueSpecialEpisodeName": "Specialavsnitt - {0}",
"VersionNumber": "Version {0}"
}
diff --git a/Emby.Server.Implementations/Localization/Core/tr.json b/Emby.Server.Implementations/Localization/Core/tr.json
index 3b5ce29c7..eb1c2623f 100644
--- a/Emby.Server.Implementations/Localization/Core/tr.json
+++ b/Emby.Server.Implementations/Localization/Core/tr.json
@@ -25,73 +25,73 @@
"HeaderFavoriteSongs": "Favori Şarkılar",
"HeaderLiveTV": "Canlı TV",
"HeaderNextUp": "Sonraki hafta",
- "HeaderRecordingGroups": "Recording Groups",
- "HomeVideos": "Home videos",
- "Inherit": "Inherit",
- "ItemAddedWithName": "{0} was added to the library",
- "ItemRemovedWithName": "{0} was removed from the library",
- "LabelIpAddressValue": "Ip adresi: {0}",
+ "HeaderRecordingGroups": "Kayıt Grupları",
+ "HomeVideos": "Ev videoları",
+ "Inherit": "Devral",
+ "ItemAddedWithName": "{0} kütüphaneye eklendi",
+ "ItemRemovedWithName": "{0} kütüphaneden silindi",
+ "LabelIpAddressValue": "IP adresi: {0}",
"LabelRunningTimeValue": "Çalışma süresi: {0}",
- "Latest": "Latest",
+ "Latest": "En son",
"MessageApplicationUpdated": "Jellyfin Sunucusu güncellendi",
- "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}",
- "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated",
- "MessageServerConfigurationUpdated": "Server configuration has been updated",
- "MixedContent": "Mixed content",
+ "MessageApplicationUpdatedTo": "Jellyfin Sunucusu {0} olarak güncellendi",
+ "MessageNamedServerConfigurationUpdatedWithValue": "Sunucu ayarları kısım {0} güncellendi",
+ "MessageServerConfigurationUpdated": "Sunucu ayarları güncellendi",
+ "MixedContent": "Karışık içerik",
"Movies": "Filmler",
"Music": "Müzik",
"MusicVideos": "Müzik videoları",
- "NameInstallFailed": "{0} kurulum başarısız",
+ "NameInstallFailed": "{0} kurulumu başarısız",
"NameSeasonNumber": "Sezon {0}",
"NameSeasonUnknown": "Bilinmeyen Sezon",
"NewVersionIsAvailable": "Jellyfin Sunucusunun yeni bir versiyonu indirmek için hazır.",
- "NotificationOptionApplicationUpdateAvailable": "Application update available",
- "NotificationOptionApplicationUpdateInstalled": "Application update installed",
- "NotificationOptionAudioPlayback": "Audio playback started",
- "NotificationOptionAudioPlaybackStopped": "Audio playback stopped",
- "NotificationOptionCameraImageUploaded": "Camera image uploaded",
- "NotificationOptionInstallationFailed": "Yükleme hatası",
- "NotificationOptionNewLibraryContent": "New content added",
- "NotificationOptionPluginError": "Plugin failure",
- "NotificationOptionPluginInstalled": "Plugin installed",
- "NotificationOptionPluginUninstalled": "Plugin uninstalled",
- "NotificationOptionPluginUpdateInstalled": "Plugin update installed",
- "NotificationOptionServerRestartRequired": "Server restart required",
- "NotificationOptionTaskFailed": "Scheduled task failure",
- "NotificationOptionUserLockedOut": "User locked out",
- "NotificationOptionVideoPlayback": "Video playback started",
- "NotificationOptionVideoPlaybackStopped": "Video playback stopped",
+ "NotificationOptionApplicationUpdateAvailable": "Uygulama güncellemesi mevcut",
+ "NotificationOptionApplicationUpdateInstalled": "Uygulama güncellemesi yüklendi",
+ "NotificationOptionAudioPlayback": "Ses çalma başladı",
+ "NotificationOptionAudioPlaybackStopped": "Ses çalma durduruldu",
+ "NotificationOptionCameraImageUploaded": "Kamera fotoğrafı yüklendi",
+ "NotificationOptionInstallationFailed": "Yükleme başarısız oldu",
+ "NotificationOptionNewLibraryContent": "Yeni içerik eklendi",
+ "NotificationOptionPluginError": "Eklenti hatası",
+ "NotificationOptionPluginInstalled": "Eklenti yüklendi",
+ "NotificationOptionPluginUninstalled": "Eklenti kaldırıldı",
+ "NotificationOptionPluginUpdateInstalled": "Eklenti güncellemesi yüklendi",
+ "NotificationOptionServerRestartRequired": "Sunucu yeniden başlatma gerekli",
+ "NotificationOptionTaskFailed": "Zamanlanmış görev hatası",
+ "NotificationOptionUserLockedOut": "Kullanıcı kitlendi",
+ "NotificationOptionVideoPlayback": "Video oynatma başladı",
+ "NotificationOptionVideoPlaybackStopped": "Video oynatma durduruldu",
"Photos": "Fotoğraflar",
"Playlists": "Çalma listeleri",
- "Plugin": "Plugin",
- "PluginInstalledWithName": "{0} was installed",
- "PluginUninstalledWithName": "{0} was uninstalled",
- "PluginUpdatedWithName": "{0} was updated",
- "ProviderValue": "Provider: {0}",
- "ScheduledTaskFailedWithName": "{0} failed",
- "ScheduledTaskStartedWithName": "{0} started",
- "ServerNameNeedsToBeRestarted": "{0} needs to be restarted",
+ "Plugin": "Eklenti",
+ "PluginInstalledWithName": "{0} yüklendi",
+ "PluginUninstalledWithName": "{0} kaldırıldı",
+ "PluginUpdatedWithName": "{0} güncellendi",
+ "ProviderValue": "Sağlayıcı: {0}",
+ "ScheduledTaskFailedWithName": "{0} başarısız oldu",
+ "ScheduledTaskStartedWithName": "{0} başladı",
+ "ServerNameNeedsToBeRestarted": "{0} yeniden başlatılması gerekiyor",
"Shows": "Diziler",
"Songs": "Şarkılar",
- "StartupEmbyServerIsLoading": "Jellyfin Server is loading. Please try again shortly.",
+ "StartupEmbyServerIsLoading": "Jellyfin Sunucusu yükleniyor. Lütfen kısa süre sonra tekrar deneyin.",
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
- "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}",
- "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}",
+ "SubtitleDownloadFailureFromForItem": "{1} için alt yazılar {0} 'dan indirilemedi",
+ "SubtitlesDownloadedForItem": "{0} için altyazılar indirildi",
"Sync": "Eşitle",
- "System": "System",
- "TvShows": "TV Shows",
- "User": "User",
- "UserCreatedWithName": "User {0} has been created",
- "UserDeletedWithName": "User {0} has been deleted",
- "UserDownloadingItemWithValues": "{0} is downloading {1}",
- "UserLockedOutWithName": "User {0} has been locked out",
- "UserOfflineFromDevice": "{0} has disconnected from {1}",
- "UserOnlineFromDevice": "{0} is online from {1}",
- "UserPasswordChangedWithName": "Password has been changed for user {0}",
- "UserPolicyUpdatedWithName": "User policy has been updated for {0}",
- "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": "Özel -{0}",
- "VersionNumber": "Version {0}"
+ "System": "Sistem",
+ "TvShows": "Diziler",
+ "User": "Kullanıcı",
+ "UserCreatedWithName": "{0} kullanıcısı oluşturuldu",
+ "UserDeletedWithName": "Kullanıcı {0} silindi",
+ "UserDownloadingItemWithValues": "{0} indiriliyor {1}",
+ "UserLockedOutWithName": "Kullanıcı {0} kitlendi",
+ "UserOfflineFromDevice": "{0}, {1} ile bağlantısı kesildi",
+ "UserOnlineFromDevice": "{0}, {1} çevrimiçi",
+ "UserPasswordChangedWithName": "{0} kullanıcısı için şifre değiştirildi",
+ "UserPolicyUpdatedWithName": "Kullanıcı politikası {0} için güncellendi",
+ "UserStartedPlayingItemWithValues": "{0}, {2} cihazında {1} izliyor",
+ "UserStoppedPlayingItemWithValues": "{0}, {2} cihazında {1} izlemeyi bitirdi",
+ "ValueHasBeenAddedToLibrary": "Medya kitaplığınıza {0} eklendi",
+ "ValueSpecialEpisodeName": "Özel - {0}",
+ "VersionNumber": "Versiyon {0}"
}
diff --git a/Emby.Server.Implementations/Localization/Core/zh-HK.json b/Emby.Server.Implementations/Localization/Core/zh-HK.json
index 387fc2b92..33fcb2d37 100644
--- a/Emby.Server.Implementations/Localization/Core/zh-HK.json
+++ b/Emby.Server.Implementations/Localization/Core/zh-HK.json
@@ -2,7 +2,7 @@
"Albums": "Albums",
"AppDeviceValues": "App: {0}, Device: {1}",
"Application": "Application",
- "Artists": "Artists",
+ "Artists": "藝人",
"AuthenticationSucceededWithUserName": "{0} successfully authenticated",
"Books": "Books",
"CameraImageUploadedFrom": "A new camera image has been uploaded from {0}",
diff --git a/Emby.Server.Implementations/Localization/Core/zh-TW.json b/Emby.Server.Implementations/Localization/Core/zh-TW.json
index 293fc28a8..33bdbfb98 100644
--- a/Emby.Server.Implementations/Localization/Core/zh-TW.json
+++ b/Emby.Server.Implementations/Localization/Core/zh-TW.json
@@ -1,6 +1,6 @@
{
"Albums": "專輯",
- "AppDeviceValues": "應用: {0}, 裝置: {1}",
+ "AppDeviceValues": "軟體: {0}, 裝置: {1}",
"Application": "應用程式",
"Artists": "演出者",
"AuthenticationSucceededWithUserName": "{0} 成功授權",
diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs
index 13cdc50ca..bda43e832 100644
--- a/Emby.Server.Implementations/Localization/LocalizationManager.cs
+++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs
@@ -5,11 +5,9 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
-using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Serialization;
using Microsoft.Extensions.Logging;
diff --git a/Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs b/Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs
index 268bf4042..fda32da5e 100644
--- a/Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs
+++ b/Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs
@@ -27,12 +27,12 @@ namespace Emby.Server.Implementations.Middleware
var webSocketContext = await httpContext.WebSockets.AcceptWebSocketAsync(null).ConfigureAwait(false);
if (webSocketContext != null)
{
- await _webSocketManager.OnWebSocketConnected(webSocketContext);
+ await _webSocketManager.OnWebSocketConnected(webSocketContext).ConfigureAwait(false);
}
}
else
{
- await _next.Invoke(httpContext);
+ await _next.Invoke(httpContext).ConfigureAwait(false);
}
}
}
diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs
index d948dad68..1d8d3cf39 100644
--- a/Emby.Server.Implementations/Networking/NetworkManager.cs
+++ b/Emby.Server.Implementations/Networking/NetworkManager.cs
@@ -7,8 +7,6 @@ using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading.Tasks;
using MediaBrowser.Common.Net;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Net;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Networking
@@ -55,10 +53,7 @@ namespace Emby.Server.Implementations.Networking
_macAddresses = null;
}
- if (NetworkChanged != null)
- {
- NetworkChanged(this, EventArgs.Empty);
- }
+ NetworkChanged?.Invoke(this, EventArgs.Empty);
}
public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true)
@@ -261,10 +256,10 @@ namespace Emby.Server.Implementations.Networking
return true;
}
- if (normalizedSubnet.IndexOf('/') != -1)
+ if (normalizedSubnet.Contains('/', StringComparison.Ordinal))
{
- var ipnetwork = IPNetwork.Parse(normalizedSubnet);
- if (ipnetwork.Contains(address))
+ var ipNetwork = IPNetwork.Parse(normalizedSubnet);
+ if (ipNetwork.Contains(address))
{
return true;
}
@@ -453,119 +448,11 @@ namespace Emby.Server.Implementations.Networking
.Select(x => x.GetPhysicalAddress())
.Where(x => x != null && x != PhysicalAddress.None);
- /// <summary>
- /// Parses the specified endpointstring.
- /// </summary>
- /// <param name="endpointstring">The endpointstring.</param>
- /// <returns>IPEndPoint.</returns>
- public IPEndPoint Parse(string endpointstring)
- {
- return Parse(endpointstring, -1).Result;
- }
-
- /// <summary>
- /// Parses the specified endpointstring.
- /// </summary>
- /// <param name="endpointstring">The endpointstring.</param>
- /// <param name="defaultport">The defaultport.</param>
- /// <returns>IPEndPoint.</returns>
- /// <exception cref="ArgumentException">Endpoint descriptor may not be empty.</exception>
- /// <exception cref="FormatException"></exception>
- private static async Task<IPEndPoint> Parse(string endpointstring, int defaultport)
- {
- if (string.IsNullOrEmpty(endpointstring)
- || endpointstring.Trim().Length == 0)
- {
- throw new ArgumentException("Endpoint descriptor may not be empty.");
- }
-
- if (defaultport != -1 &&
- (defaultport < IPEndPoint.MinPort
- || defaultport > IPEndPoint.MaxPort))
- {
- throw new ArgumentException(string.Format("Invalid default port '{0}'", defaultport));
- }
-
- string[] values = endpointstring.Split(new char[] { ':' });
- IPAddress ipaddy;
- int port = -1;
-
- //check if we have an IPv6 or ports
- if (values.Length <= 2) // ipv4 or hostname
- {
- port = values.Length == 1 ? defaultport : GetPort(values[1]);
-
- //try to use the address as IPv4, otherwise get hostname
- if (!IPAddress.TryParse(values[0], out ipaddy))
- ipaddy = await GetIPfromHost(values[0]).ConfigureAwait(false);
- }
- else if (values.Length > 2) //ipv6
- {
- //could [a:b:c]:d
- if (values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]"))
- {
- string ipaddressstring = string.Join(":", values.Take(values.Length - 1).ToArray());
- ipaddy = IPAddress.Parse(ipaddressstring);
- port = GetPort(values[values.Length - 1]);
- }
- else //[a:b:c] or a:b:c
- {
- ipaddy = IPAddress.Parse(endpointstring);
- port = defaultport;
- }
- }
- else
- {
- throw new FormatException(string.Format("Invalid endpoint ipaddress '{0}'", endpointstring));
- }
-
- if (port == -1)
- throw new ArgumentException(string.Format("No port specified: '{0}'", endpointstring));
-
- return new IPEndPoint(ipaddy, port);
- }
-
- protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
- /// <summary>
- /// Gets the port.
- /// </summary>
- /// <param name="p">The p.</param>
- /// <returns>System.Int32.</returns>
- /// <exception cref="FormatException"></exception>
- private static int GetPort(string p)
- {
- if (!int.TryParse(p, out var port)
- || port < IPEndPoint.MinPort
- || port > IPEndPoint.MaxPort)
- {
- throw new FormatException(string.Format("Invalid end point port '{0}'", p));
- }
-
- return port;
- }
-
- /// <summary>
- /// Gets the I pfrom host.
- /// </summary>
- /// <param name="p">The p.</param>
- /// <returns>IPAddress.</returns>
- /// <exception cref="ArgumentException"></exception>
- private static async Task<IPAddress> GetIPfromHost(string p)
- {
- var hosts = await Dns.GetHostAddressesAsync(p).ConfigureAwait(false);
-
- if (hosts == null || hosts.Length == 0)
- throw new ArgumentException(string.Format("Host not found: {0}", p));
-
- return hosts[0];
- }
-
public bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask)
{
- IPAddress network1 = GetNetworkAddress(address1, subnetMask);
- IPAddress network2 = GetNetworkAddress(address2, subnetMask);
- return network1.Equals(network2);
+ IPAddress network1 = GetNetworkAddress(address1, subnetMask);
+ IPAddress network2 = GetNetworkAddress(address2, subnetMask);
+ return network1.Equals(network2);
}
private IPAddress GetNetworkAddress(IPAddress address, IPAddress subnetMask)
@@ -581,7 +468,7 @@ namespace Emby.Server.Implementations.Networking
byte[] broadcastAddress = new byte[ipAdressBytes.Length];
for (int i = 0; i < broadcastAddress.Length; i++)
{
- broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i]));
+ broadcastAddress[i] = (byte)(ipAdressBytes[i] & subnetMaskBytes[i]);
}
return new IPAddress(broadcastAddress);
@@ -621,24 +508,5 @@ namespace Emby.Server.Implementations.Networking
return null;
}
-
- /// <summary>
- /// Gets the network shares.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>IEnumerable{NetworkShare}.</returns>
- public virtual IEnumerable<NetworkShare> GetNetworkShares(string path)
- {
- return new List<NetworkShare>();
- }
-
- /// <summary>
- /// Gets available devices within the domain
- /// </summary>
- /// <returns>PC's in the Domain</returns>
- public virtual IEnumerable<FileSystemEntryInfo> GetNetworkDevices()
- {
- return new List<FileSystemEntryInfo>();
- }
}
}
diff --git a/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
index de51a37ab..cd9f7946e 100644
--- a/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
+++ b/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
@@ -48,4 +48,3 @@ namespace Emby.Server.Implementations.Playlists
}
}
}
-
diff --git a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs
index cad66a80f..2dfe59088 100644
--- a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs
+++ b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs
@@ -62,7 +62,6 @@ namespace Emby.Server.Implementations.Playlists
return null;
})
.Where(i => i != null)
- .OrderBy(i => Guid.NewGuid())
.GroupBy(x => x.Id)
.Select(x => x.First())
.ToList();
@@ -84,7 +83,7 @@ namespace Emby.Server.Implementations.Playlists
{
Genres = new[] { item.Name },
IncludeItemTypes = new[] { typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Audio).Name },
- OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) },
+ OrderBy = new[] { (ItemSortBy.Random, SortOrder.Ascending) },
Limit = 4,
Recursive = true,
ImageTypes = new[] { ImageType.Primary },
@@ -108,7 +107,7 @@ namespace Emby.Server.Implementations.Playlists
{
Genres = new[] { item.Name },
IncludeItemTypes = new[] { typeof(Series).Name, typeof(Movie).Name },
- OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) },
+ OrderBy = new[] { (ItemSortBy.Random, SortOrder.Ascending) },
Limit = 4,
Recursive = true,
ImageTypes = new[] { ImageType.Primary },
diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
index 83226b07f..5b188d962 100644
--- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
@@ -23,7 +23,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
public event EventHandler<GenericEventArgs<double>> TaskProgress;
/// <summary>
- /// Gets or sets the scheduled task.
+ /// Gets the scheduled task.
/// </summary>
/// <value>The scheduled task.</value>
public IScheduledTask ScheduledTask { get; private set; }
@@ -215,11 +215,12 @@ namespace Emby.Server.Implementations.ScheduledTasks
public double? CurrentProgress { get; private set; }
/// <summary>
- /// The _triggers
+ /// The _triggers.
/// </summary>
private Tuple<TaskTriggerInfo, ITaskTrigger>[] _triggers;
+
/// <summary>
- /// Gets the triggers that define when the task will run
+ /// Gets the triggers that define when the task will run.
/// </summary>
/// <value>The triggers.</value>
private Tuple<TaskTriggerInfo, ITaskTrigger>[] InternalTriggers
@@ -245,7 +246,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
}
/// <summary>
- /// Gets the triggers that define when the task will run
+ /// Gets the triggers that define when the task will run.
/// </summary>
/// <value>The triggers.</value>
/// <exception cref="ArgumentNullException">value</exception>
diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
index 595c3037d..ecf58dbc0 100644
--- a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
@@ -36,19 +36,19 @@ namespace Emby.Server.Implementations.ScheduledTasks
/// Gets or sets the json serializer.
/// </summary>
/// <value>The json serializer.</value>
- private IJsonSerializer JsonSerializer { get; set; }
+ private readonly IJsonSerializer _jsonSerializer;
/// <summary>
/// Gets or sets the application paths.
/// </summary>
/// <value>The application paths.</value>
- private IApplicationPaths ApplicationPaths { get; set; }
+ private readonly IApplicationPaths _applicationPaths;
/// <summary>
/// Gets the logger.
/// </summary>
/// <value>The logger.</value>
- private ILogger Logger { get; set; }
+ private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
/// <summary>
@@ -57,19 +57,19 @@ namespace Emby.Server.Implementations.ScheduledTasks
/// <param name="applicationPaths">The application paths.</param>
/// <param name="jsonSerializer">The json serializer.</param>
/// <param name="loggerFactory">The logger factory.</param>
- /// <exception cref="System.ArgumentException">kernel</exception>
+ /// <param name="fileSystem">The filesystem manager.</param>
public TaskManager(
IApplicationPaths applicationPaths,
IJsonSerializer jsonSerializer,
ILoggerFactory loggerFactory,
IFileSystem fileSystem)
{
- ApplicationPaths = applicationPaths;
- JsonSerializer = jsonSerializer;
- Logger = loggerFactory.CreateLogger(nameof(TaskManager));
+ _applicationPaths = applicationPaths;
+ _jsonSerializer = jsonSerializer;
+ _logger = loggerFactory.CreateLogger(nameof(TaskManager));
_fileSystem = fileSystem;
- ScheduledTasks = new IScheduledTaskWorker[] { };
+ ScheduledTasks = Array.Empty<IScheduledTaskWorker>();
}
/// <summary>
@@ -78,7 +78,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
/// <typeparam name="T"></typeparam>
/// <param name="options">Task options.</param>
public void CancelIfRunningAndQueue<T>(TaskOptions options)
- where T : IScheduledTask
+ where T : IScheduledTask
{
var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T));
((ScheduledTaskWorker)task).CancelIfRunning();
@@ -115,7 +115,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
if (scheduledTask == null)
{
- Logger.LogError("Unable to find scheduled task of type {0} in QueueScheduledTask.", typeof(T).Name);
+ _logger.LogError("Unable to find scheduled task of type {0} in QueueScheduledTask.", typeof(T).Name);
}
else
{
@@ -147,13 +147,13 @@ namespace Emby.Server.Implementations.ScheduledTasks
if (scheduledTask == null)
{
- Logger.LogError("Unable to find scheduled task of type {0} in Execute.", typeof(T).Name);
+ _logger.LogError("Unable to find scheduled task of type {0} in Execute.", typeof(T).Name);
}
else
{
var type = scheduledTask.ScheduledTask.GetType();
- Logger.LogInformation("Queueing task {0}", type.Name);
+ _logger.LogInformation("Queueing task {0}", type.Name);
lock (_taskQueue)
{
@@ -176,7 +176,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
if (scheduledTask == null)
{
- Logger.LogError("Unable to find scheduled task of type {0} in QueueScheduledTask.", task.GetType().Name);
+ _logger.LogError("Unable to find scheduled task of type {0} in QueueScheduledTask.", task.GetType().Name);
}
else
{
@@ -193,7 +193,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
{
var type = task.ScheduledTask.GetType();
- Logger.LogInformation("Queueing task {0}", type.Name);
+ _logger.LogInformation("Queueing task {0}", type.Name);
lock (_taskQueue)
{
@@ -213,7 +213,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
/// <param name="tasks">The tasks.</param>
public void AddTasks(IEnumerable<IScheduledTask> tasks)
{
- var list = tasks.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger, _fileSystem));
+ var list = tasks.Select(t => new ScheduledTaskWorker(t, _applicationPaths, this, _jsonSerializer, _logger, _fileSystem));
ScheduledTasks = ScheduledTasks.Concat(list).ToArray();
}
@@ -281,7 +281,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
/// </summary>
private void ExecuteQueuedTasks()
{
- Logger.LogInformation("ExecuteQueuedTasks");
+ _logger.LogInformation("ExecuteQueuedTasks");
// Execute queued tasks
lock (_taskQueue)
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodeFileTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodeFileTask.cs
index c343a7d48..f197734d4 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodeFileTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteTranscodeFileTask.cs
@@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
@@ -15,34 +16,28 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
/// </summary>
public class DeleteTranscodeFileTask : IScheduledTask, IConfigurableScheduledTask
{
- /// <summary>
- /// Gets or sets the application paths.
- /// </summary>
- /// <value>The application paths.</value>
- private ServerApplicationPaths ApplicationPaths { get; set; }
-
private readonly ILogger _logger;
-
+ private readonly IConfigurationManager _configurationManager;
private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="DeleteTranscodeFileTask" /> class.
/// </summary>
- public DeleteTranscodeFileTask(ServerApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
+ public DeleteTranscodeFileTask(ILogger logger, IFileSystem fileSystem, IConfigurationManager configurationManager)
{
- ApplicationPaths = appPaths;
_logger = logger;
_fileSystem = fileSystem;
+ _configurationManager = configurationManager;
}
/// <summary>
- /// Creates the triggers that define when the task will run
+ /// Creates the triggers that define when the task will run.
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers() => new List<TaskTriggerInfo>();
/// <summary>
- /// Returns the task to be executed
+ /// Returns the task to be executed.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
@@ -52,21 +47,13 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
var minDateModified = DateTime.UtcNow.AddDays(-1);
progress.Report(50);
- try
- {
- DeleteTempFilesFromDirectory(cancellationToken, ApplicationPaths.TranscodingTempPath, minDateModified, progress);
- }
- catch (DirectoryNotFoundException)
- {
- // No biggie here. Nothing to delete
- }
+ DeleteTempFilesFromDirectory(cancellationToken, _configurationManager.GetTranscodePath(), minDateModified, progress);
return Task.CompletedTask;
}
-
/// <summary>
- /// Deletes the transcoded temp files from directory with a last write time less than a given date
+ /// Deletes the transcoded temp files from directory with a last write time less than a given date.
/// </summary>
/// <param name="cancellationToken">The task cancellation token.</param>
/// <param name="directory">The directory.</param>
@@ -138,13 +125,13 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
}
}
- public string Name => "Transcoding temp cleanup";
+ public string Name => "Transcode file cleanup";
- public string Description => "Deletes transcoding temp files older than 24 hours.";
+ public string Description => "Deletes transcode files more than 24 hours old.";
public string Category => "Maintenance";
- public string Key => "DeleteTranscodingTempFiles";
+ public string Key => "DeleteTranscodeFiles";
public bool IsHidden => false;
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs
index fe8deae59..909fffb1f 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs
@@ -52,7 +52,9 @@ namespace Emby.Server.Implementations.ScheduledTasks
{
progress.Report(0);
- var packagesToInstall = (await _installationManager.GetAvailablePluginUpdates(cancellationToken).ConfigureAwait(false)).ToList();
+ var packagesToInstall = await _installationManager.GetAvailablePluginUpdates(cancellationToken)
+ .ToListAsync(cancellationToken)
+ .ConfigureAwait(false);
progress.Report(10);
diff --git a/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs
index ec9466c4a..ea278de0d 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs
@@ -1,5 +1,4 @@
using System;
-using System.Globalization;
using System.Threading;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
@@ -7,12 +6,12 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.ScheduledTasks
{
/// <summary>
- /// Represents a task trigger that fires everyday
+ /// Represents a task trigger that fires everyday.
/// </summary>
public class DailyTrigger : ITaskTrigger
{
/// <summary>
- /// Get the time of day to trigger the task to run
+ /// Get the time of day to trigger the task to run.
/// </summary>
/// <value>The time of day.</value>
public TimeSpan TimeOfDay { get; set; }
diff --git a/Emby.Server.Implementations/ServerApplicationPaths.cs b/Emby.Server.Implementations/ServerApplicationPaths.cs
index 46195cc74..2f57c97a1 100644
--- a/Emby.Server.Implementations/ServerApplicationPaths.cs
+++ b/Emby.Server.Implementations/ServerApplicationPaths.cs
@@ -1,4 +1,3 @@
-using System;
using System.IO;
using Emby.Server.Implementations.AppBase;
using MediaBrowser.Controller;
@@ -10,8 +9,6 @@ namespace Emby.Server.Implementations
/// </summary>
public class ServerApplicationPaths : BaseApplicationPaths, IServerApplicationPaths
{
- private string _defaultTranscodingTempPath;
- private string _transcodingTempPath;
private string _internalMetadataPath;
/// <summary>
@@ -23,7 +20,8 @@ namespace Emby.Server.Implementations
string configurationDirectoryPath,
string cacheDirectoryPath,
string webDirectoryPath)
- : base(programDataPath,
+ : base(
+ programDataPath,
logDirectoryPath,
configurationDirectoryPath,
cacheDirectoryPath,
@@ -31,8 +29,6 @@ namespace Emby.Server.Implementations
{
}
- public string ApplicationResourcesPath { get; } = AppContext.BaseDirectory;
-
/// <summary>
/// Gets the path to the base root media directory.
/// </summary>
@@ -46,17 +42,12 @@ namespace Emby.Server.Implementations
public string DefaultUserViewsPath => Path.Combine(RootFolderPath, "default");
/// <summary>
- /// Gets the path to localization data.
- /// </summary>
- /// <value>The localization path.</value>
- public string LocalizationPath => Path.Combine(ProgramDataPath, "localization");
-
- /// <summary>
/// Gets the path to the People directory.
/// </summary>
/// <value>The people path.</value>
public string PeoplePath => Path.Combine(InternalMetadataPath, "People");
+ /// <inheritdoc />
public string ArtistsPath => Path.Combine(InternalMetadataPath, "artists");
/// <summary>
@@ -107,46 +98,14 @@ namespace Emby.Server.Implementations
/// <value>The user configuration directory path.</value>
public string UserConfigurationDirectoryPath => Path.Combine(ConfigurationDirectoryPath, "users");
- public string DefaultTranscodingTempPath => _defaultTranscodingTempPath ?? (_defaultTranscodingTempPath = Path.Combine(ProgramDataPath, "transcoding-temp"));
-
- public string TranscodingTempPath
- {
- get => _transcodingTempPath ?? (_transcodingTempPath = DefaultTranscodingTempPath);
- set => _transcodingTempPath = value;
- }
-
- public string GetTranscodingTempPath()
- {
- var path = TranscodingTempPath;
-
- if (!string.Equals(path, DefaultTranscodingTempPath, StringComparison.OrdinalIgnoreCase))
- {
- try
- {
- Directory.CreateDirectory(path);
-
- var testPath = Path.Combine(path, Guid.NewGuid().ToString());
- Directory.CreateDirectory(testPath);
- Directory.Delete(testPath);
-
- return path;
- }
- catch
- {
- }
- }
-
- path = DefaultTranscodingTempPath;
- Directory.CreateDirectory(path);
- return path;
- }
-
+ /// <inheritdoc />
public string InternalMetadataPath
{
get => _internalMetadataPath ?? (_internalMetadataPath = Path.Combine(DataPath, "metadata"));
set => _internalMetadataPath = value;
}
+ /// <inheritdoc />
public string VirtualInternalMetadataPath { get; } = "%MetadataPath%";
}
}
diff --git a/Emby.Server.Implementations/Services/ServicePath.cs b/Emby.Server.Implementations/Services/ServicePath.cs
index 0b67669b9..27c4dcba0 100644
--- a/Emby.Server.Implementations/Services/ServicePath.cs
+++ b/Emby.Server.Implementations/Services/ServicePath.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -45,8 +46,8 @@ namespace Emby.Server.Implementations.Services
public int PathComponentsCount { get; set; }
/// <summary>
- /// The total number of segments after subparts have been exploded ('.')
- /// e.g. /path/to/here.ext == 4
+ /// Gets or sets the total number of segments after subparts have been exploded ('.')
+ /// e.g. /path/to/here.ext == 4.
/// </summary>
public int TotalComponentsCount { get; set; }
@@ -279,7 +280,7 @@ namespace Emby.Server.Implementations.Services
}
/// <summary>
- /// Provide for quick lookups based on hashes that can be determined from a request url
+ /// Provide for quick lookups based on hashes that can be determined from a request url.
/// </summary>
public string FirstMatchHashKey { get; private set; }
@@ -436,9 +437,12 @@ namespace Emby.Server.Implementations.Services
&& requestComponents.Length >= this.TotalComponentsCount - this.wildcardCount;
if (!isValidWildCardPath)
- throw new ArgumentException(string.Format(
- "Path Mismatch: Request Path '{0}' has invalid number of components compared to: '{1}'",
- pathInfo, this.restPath));
+ throw new ArgumentException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Path Mismatch: Request Path '{0}' has invalid number of components compared to: '{1}'",
+ pathInfo,
+ this.restPath));
}
var requestKeyValuesMap = new Dictionary<string, string>();
diff --git a/Emby.Server.Implementations/Services/SwaggerService.cs b/Emby.Server.Implementations/Services/SwaggerService.cs
index d22386436..c30f32af9 100644
--- a/Emby.Server.Implementations/Services/SwaggerService.cs
+++ b/Emby.Server.Implementations/Services/SwaggerService.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Controller.Net;
@@ -175,7 +175,7 @@ namespace Emby.Server.Implementations.Services
private SwaggerTag[] GetTags()
{
- return new SwaggerTag[] { };
+ return Array.Empty<SwaggerTag>();
}
private Dictionary<string, SwaggerDefinition> GetDefinitions()
diff --git a/Emby.Server.Implementations/Session/HttpSessionController.cs b/Emby.Server.Implementations/Session/HttpSessionController.cs
index 1104a7a85..dfb81816c 100644
--- a/Emby.Server.Implementations/Session/HttpSessionController.cs
+++ b/Emby.Server.Implementations/Session/HttpSessionController.cs
@@ -105,7 +105,7 @@ namespace Emby.Server.Implementations.Session
return SendMessage(command.Command.ToString(), messageId, args, cancellationToken);
}
- private string[] _supportedMessages = new string[] { };
+ private string[] _supportedMessages = Array.Empty<string>();
public Task SendMessage<T>(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken)
{
if (!IsSessionActive)
diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs
index 61329160a..b1d513dd4 100644
--- a/Emby.Server.Implementations/Session/SessionManager.cs
+++ b/Emby.Server.Implementations/Session/SessionManager.cs
@@ -667,12 +667,9 @@ namespace Emby.Server.Implementations.Session
data.PlayCount++;
data.LastPlayedDate = DateTime.UtcNow;
- if (item.SupportsPlayedStatus)
+ if (item.SupportsPlayedStatus && !item.SupportsPositionTicksResume)
{
- if (!(item is Video))
- {
- data.Played = true;
- }
+ data.Played = true;
}
else
{
@@ -769,7 +766,6 @@ namespace Emby.Server.Implementations.Session
{
_userDataManager.SaveUserData(user, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None);
}
-
}
private static bool UpdatePlaybackSettings(User user, PlaybackProgressInfo info, UserItemData data)
@@ -1061,7 +1057,7 @@ namespace Emby.Server.Implementations.Session
var session = GetSessionToRemoteControl(sessionId);
- var user = !session.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(session.UserId) : null;
+ var user = session.UserId == Guid.Empty ? null : _userManager.GetUserById(session.UserId);
List<BaseItem> items;
@@ -1086,7 +1082,7 @@ namespace Emby.Server.Implementations.Session
if (command.PlayCommand == PlayCommand.PlayShuffle)
{
- items = items.OrderBy(i => Guid.NewGuid()).ToList();
+ items.Shuffle();
command.PlayCommand = PlayCommand.PlayNow;
}
@@ -1100,28 +1096,27 @@ namespace Emby.Server.Implementations.Session
}
}
- if (user != null && command.ItemIds.Length == 1 && user.Configuration.EnableNextEpisodeAutoPlay)
+ if (user != null
+ && command.ItemIds.Length == 1
+ && user.Configuration.EnableNextEpisodeAutoPlay
+ && _libraryManager.GetItemById(command.ItemIds[0]) is Episode episode)
{
- var episode = _libraryManager.GetItemById(command.ItemIds[0]) as Episode;
- if (episode != null)
+ var series = episode.Series;
+ if (series != null)
{
- var series = episode.Series;
- if (series != null)
+ var episodes = series.GetEpisodes(
+ user,
+ new DtoOptions(false)
+ {
+ EnableImages = false
+ })
+ .Where(i => !i.IsVirtualItem)
+ .SkipWhile(i => i.Id != episode.Id)
+ .ToList();
+
+ if (episodes.Count > 0)
{
- var episodes = series.GetEpisodes(
- user,
- new DtoOptions(false)
- {
- EnableImages = false
- })
- .Where(i => !i.IsVirtualItem)
- .SkipWhile(i => i.Id != episode.Id)
- .ToList();
-
- if (episodes.Count > 0)
- {
- command.ItemIds = episodes.Select(i => i.Id).ToArray();
- }
+ command.ItemIds = episodes.Select(i => i.Id).ToArray();
}
}
}
@@ -1146,7 +1141,7 @@ namespace Emby.Server.Implementations.Session
if (item == null)
{
_logger.LogError("A non-existant item Id {0} was passed into TranslateItemForPlayback", id);
- return new List<BaseItem>();
+ return Array.Empty<BaseItem>();
}
if (item is IItemByName byName)
@@ -1164,7 +1159,7 @@ namespace Emby.Server.Implementations.Session
}
},
IsVirtualItem = false,
- OrderBy = new ValueTuple<string, SortOrder>[] { new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) }
+ OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }
});
}
@@ -1185,12 +1180,11 @@ namespace Emby.Server.Implementations.Session
}
},
IsVirtualItem = false,
- OrderBy = new ValueTuple<string, SortOrder>[] { new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) }
-
+ OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }
});
}
- return new List<BaseItem> { item };
+ return new[] { item };
}
private IEnumerable<BaseItem> TranslateItemForInstantMix(Guid id, User user)
@@ -1388,27 +1382,27 @@ namespace Emby.Server.Implementations.Session
if (user != null)
{
// TODO: Move this to userManager?
- if (!string.IsNullOrEmpty(request.DeviceId))
+ if (!string.IsNullOrEmpty(request.DeviceId)
+ && !_deviceManager.CanAccessDevice(user, request.DeviceId))
{
- if (!_deviceManager.CanAccessDevice(user, request.DeviceId))
- {
- throw new SecurityException("User is not allowed access from this device.");
- }
+ throw new SecurityException("User is not allowed access from this device.");
}
}
- if (enforcePassword)
+ if (user == null)
{
- var result = await _userManager.AuthenticateUser(request.Username, request.Password, request.PasswordSha1, request.RemoteEndPoint, true).ConfigureAwait(false);
-
- if (result == null)
- {
- AuthenticationFailed?.Invoke(this, new GenericEventArgs<AuthenticationRequest>(request));
-
- throw new SecurityException("Invalid user or password entered.");
- }
+ AuthenticationFailed?.Invoke(this, new GenericEventArgs<AuthenticationRequest>(request));
+ throw new SecurityException("Invalid user or password entered.");
+ }
- user = result;
+ if (enforcePassword)
+ {
+ user = await _userManager.AuthenticateUser(
+ request.Username,
+ request.Password,
+ request.PasswordSha1,
+ request.RemoteEndPoint,
+ true).ConfigureAwait(false);
}
var token = GetAuthorizationToken(user, request.DeviceId, request.App, request.AppVersion, request.DeviceName);
diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
index 63ec75762..930f2d35d 100644
--- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
+++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
@@ -4,7 +4,6 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
@@ -67,7 +66,7 @@ namespace Emby.Server.Implementations.Session
{
if (queryString == null)
{
- throw new ArgumentNullException(nameof(queryString));
+ return null;
}
var token = queryString["api_key"];
@@ -75,6 +74,7 @@ namespace Emby.Server.Implementations.Session
{
return null;
}
+
var deviceId = queryString["deviceId"];
return _sessionManager.GetSessionByAuthenticationToken(token, deviceId, remoteEndpoint);
}
diff --git a/Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs b/Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs
index 62b16ed8c..67521d6c6 100644
--- a/Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs
+++ b/Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs
@@ -33,7 +33,7 @@ namespace Emby.Server.Implementations.SocketSharp
}
/// <summary>
- /// Gets or sets the state.
+ /// Gets the state.
/// </summary>
/// <value>The state.</value>
public WebSocketState State => _webSocket.State;
diff --git a/Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs b/Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs
index e93bff124..ba5ba1904 100644
--- a/Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs
+++ b/Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs
@@ -81,8 +81,10 @@ namespace Emby.Server.Implementations.SocketSharp
if (webSocketContext.State == WebSocketState.Open)
{
- await webSocketContext.CloseAsync(result.CloseStatus ?? WebSocketCloseStatus.NormalClosure,
- result.CloseStatusDescription, _disposeCancellationToken);
+ await webSocketContext.CloseAsync(
+ result.CloseStatus ?? WebSocketCloseStatus.NormalClosure,
+ result.CloseStatusDescription,
+ _disposeCancellationToken).ConfigureAwait(false);
}
socket.Dispose();
diff --git a/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs b/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs
index 332ce3903..1781df8b5 100644
--- a/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs
+++ b/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
-using System.Linq;
+using System.Net.Mime;
using MediaBrowser.Common.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
@@ -13,11 +13,11 @@ using IHttpRequest = MediaBrowser.Model.Services.IHttpRequest;
namespace Emby.Server.Implementations.SocketSharp
{
- public partial class WebSocketSharpRequest : IHttpRequest
+ public class WebSocketSharpRequest : IHttpRequest
{
- public const string FormUrlEncoded = "application/x-www-form-urlencoded";
- public const string MultiPartFormData = "multipart/form-data";
- public const string Soap11 = "text/xml; charset=utf-8";
+ private const string FormUrlEncoded = "application/x-www-form-urlencoded";
+ private const string MultiPartFormData = "multipart/form-data";
+ private const string Soap11 = "text/xml; charset=utf-8";
private string _remoteIp;
private Dictionary<string, object> _items;
@@ -78,7 +78,7 @@ namespace Emby.Server.Implementations.SocketSharp
get =>
_responseContentType
?? (_responseContentType = GetResponseContentType(Request));
- set => this._responseContentType = value;
+ set => _responseContentType = value;
}
public string PathInfo => Request.Path.Value;
@@ -91,7 +91,6 @@ namespace Emby.Server.Implementations.SocketSharp
public bool IsLocal => Request.HttpContext.Connection.LocalIpAddress.Equals(Request.HttpContext.Connection.RemoteIpAddress);
-
public string HttpMethod => Request.Method;
public string Verb => HttpMethod;
@@ -124,24 +123,29 @@ namespace Emby.Server.Implementations.SocketSharp
return specifiedContentType;
}
- const string serverDefaultContentType = "application/json";
+ const string ServerDefaultContentType = MediaTypeNames.Application.Json;
var acceptContentTypes = httpReq.Headers.GetCommaSeparatedValues(HeaderNames.Accept);
string defaultContentType = null;
if (HasAnyOfContentTypes(httpReq, FormUrlEncoded, MultiPartFormData))
{
- defaultContentType = serverDefaultContentType;
+ defaultContentType = ServerDefaultContentType;
}
var acceptsAnything = false;
var hasDefaultContentType = defaultContentType != null;
if (acceptContentTypes != null)
{
- foreach (var acceptsType in acceptContentTypes)
+ foreach (ReadOnlySpan<char> acceptsType in acceptContentTypes)
{
- // TODO: @bond move to Span when Span.Split lands
- // https://github.com/dotnet/corefx/issues/26528
- var contentType = acceptsType?.Split(';')[0].Trim();
+ ReadOnlySpan<char> contentType = acceptsType;
+ var index = contentType.IndexOf(';');
+ if (index != -1)
+ {
+ contentType = contentType.Slice(0, index);
+ }
+
+ contentType = contentType.Trim();
acceptsAnything = contentType.Equals("*/*", StringComparison.OrdinalIgnoreCase);
if (acceptsAnything)
@@ -158,7 +162,7 @@ namespace Emby.Server.Implementations.SocketSharp
}
else
{
- return serverDefaultContentType;
+ return ServerDefaultContentType;
}
}
}
@@ -169,7 +173,7 @@ namespace Emby.Server.Implementations.SocketSharp
}
// We could also send a '406 Not Acceptable', but this is allowed also
- return serverDefaultContentType;
+ return ServerDefaultContentType;
}
public static bool HasAnyOfContentTypes(HttpRequest request, params string[] contentTypes)
@@ -197,12 +201,12 @@ namespace Emby.Server.Implementations.SocketSharp
private static string GetQueryStringContentType(HttpRequest httpReq)
{
- ReadOnlySpan<char> format = httpReq.Query["format"].ToString().AsSpan();
+ ReadOnlySpan<char> format = httpReq.Query["format"].ToString();
if (format == null)
{
- const int formatMaxLength = 4;
- ReadOnlySpan<char> pi = httpReq.Path.ToString().AsSpan();
- if (pi == null || pi.Length <= formatMaxLength)
+ const int FormatMaxLength = 4;
+ ReadOnlySpan<char> pi = httpReq.Path.ToString();
+ if (pi == null || pi.Length <= FormatMaxLength)
{
return null;
}
@@ -213,18 +217,18 @@ namespace Emby.Server.Implementations.SocketSharp
}
format = LeftPart(pi, '/');
- if (format.Length > formatMaxLength)
+ if (format.Length > FormatMaxLength)
{
return null;
}
}
format = LeftPart(format, '.');
- if (format.Contains("json".AsSpan(), StringComparison.OrdinalIgnoreCase))
+ if (format.Contains("json", StringComparison.OrdinalIgnoreCase))
{
return "application/json";
}
- else if (format.Contains("xml".AsSpan(), StringComparison.OrdinalIgnoreCase))
+ else if (format.Contains("xml", StringComparison.OrdinalIgnoreCase))
{
return "application/xml";
}
diff --git a/Emby.Server.Implementations/Sorting/NameComparer.cs b/Emby.Server.Implementations/Sorting/NameComparer.cs
index 10fa4359a..4eb1549f5 100644
--- a/Emby.Server.Implementations/Sorting/NameComparer.cs
+++ b/Emby.Server.Implementations/Sorting/NameComparer.cs
@@ -19,10 +19,14 @@ namespace Emby.Server.Implementations.Sorting
public int Compare(BaseItem x, BaseItem y)
{
if (x == null)
+ {
throw new ArgumentNullException(nameof(x));
+ }
if (y == null)
+ {
throw new ArgumentNullException(nameof(y));
+ }
return string.Compare(x.Name, y.Name, StringComparison.CurrentCultureIgnoreCase);
}
diff --git a/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs b/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs
index e8fa8edc8..7afbd9ff7 100644
--- a/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs
+++ b/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs
@@ -24,10 +24,14 @@ namespace Emby.Server.Implementations.Sorting
public int Compare(BaseItem x, BaseItem y)
{
if (x == null)
+ {
throw new ArgumentNullException(nameof(x));
+ }
if (y == null)
+ {
throw new ArgumentNullException(nameof(y));
+ }
var levelX = string.IsNullOrEmpty(x.OfficialRating) ? 0 : _localization.GetRatingLevel(x.OfficialRating) ?? 0;
var levelY = string.IsNullOrEmpty(y.OfficialRating) ? 0 : _localization.GetRatingLevel(y.OfficialRating) ?? 0;
diff --git a/Emby.Server.Implementations/Sorting/StudioComparer.cs b/Emby.Server.Implementations/Sorting/StudioComparer.cs
index 617ed55d5..c9ac765c1 100644
--- a/Emby.Server.Implementations/Sorting/StudioComparer.cs
+++ b/Emby.Server.Implementations/Sorting/StudioComparer.cs
@@ -17,10 +17,15 @@ namespace Emby.Server.Implementations.Sorting
public int Compare(BaseItem x, BaseItem y)
{
if (x == null)
+ {
throw new ArgumentNullException(nameof(x));
+ }
if (y == null)
+ {
throw new ArgumentNullException(nameof(y));
+ }
+
return AlphanumComparator.CompareValues(x.Studios.FirstOrDefault() ?? string.Empty, y.Studios.FirstOrDefault() ?? string.Empty);
}
diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs
index 1c5402268..2705e0628 100644
--- a/Emby.Server.Implementations/Updates/InstallationManager.cs
+++ b/Emby.Server.Implementations/Updates/InstallationManager.cs
@@ -141,8 +141,7 @@ namespace Emby.Server.Implementations.Updates
if (guid != Guid.Empty)
{
- var strGuid = guid.ToString("N", CultureInfo.InvariantCulture);
- availablePackages = availablePackages.Where(x => x.guid.Equals(strGuid, StringComparison.OrdinalIgnoreCase));
+ availablePackages = availablePackages.Where(x => Guid.Parse(x.guid) == guid);
}
return availablePackages;
@@ -180,7 +179,7 @@ namespace Emby.Server.Implementations.Updates
// Package not found.
if (package == null)
{
- return null;
+ return Enumerable.Empty<PackageVersionInfo>();
}
return GetCompatibleVersions(
@@ -190,19 +189,23 @@ namespace Emby.Server.Implementations.Updates
}
/// <inheritdoc />
- public async Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(CancellationToken cancellationToken = default)
+ public async IAsyncEnumerable<PackageVersionInfo> GetAvailablePluginUpdates(CancellationToken cancellationToken = default)
{
var catalog = await GetAvailablePackages(cancellationToken).ConfigureAwait(false);
var systemUpdateLevel = _applicationHost.SystemUpdateLevel;
// Figure out what needs to be installed
- return _applicationHost.Plugins.Select(x =>
+ foreach (var plugin in _applicationHost.Plugins)
{
- var compatibleversions = GetCompatibleVersions(catalog, x.Name, x.Id, x.Version, systemUpdateLevel);
- return compatibleversions.FirstOrDefault(y => y.Version > x.Version);
- }).Where(x => x != null)
- .Where(x => !CompletedInstallations.Any(y => string.Equals(y.AssemblyGuid, x.guid, StringComparison.OrdinalIgnoreCase)));
+ var compatibleversions = GetCompatibleVersions(catalog, plugin.Name, plugin.Id, plugin.Version, systemUpdateLevel);
+ var version = compatibleversions.FirstOrDefault(y => y.Version > plugin.Version);
+ if (version != null
+ && !CompletedInstallations.Any(x => string.Equals(x.AssemblyGuid, version.guid, StringComparison.OrdinalIgnoreCase)))
+ {
+ yield return version;
+ }
+ }
}
/// <inheritdoc />
diff --git a/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs b/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs
index f48520443..78ac95f85 100644
--- a/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs
+++ b/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs
@@ -86,20 +86,17 @@ namespace Emby.Server.Implementations.UserViews
{
return items
.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb))
- .OrderBy(i => Guid.NewGuid())
.ToList();
}
return items
.Where(i => i.HasImage(ImageType.Primary))
- .OrderBy(i => Guid.NewGuid())
.ToList();
}
protected override bool Supports(BaseItem item)
{
- var view = item as UserView;
- if (view != null)
+ if (item is UserView view)
{
return IsUsingCollectionStrip(view);
}
diff --git a/Emby.Server.Implementations/WebSockets/WebSocketManager.cs b/Emby.Server.Implementations/WebSockets/WebSocketManager.cs
index 04c73ecea..efd97e4ff 100644
--- a/Emby.Server.Implementations/WebSockets/WebSocketManager.cs
+++ b/Emby.Server.Implementations/WebSockets/WebSocketManager.cs
@@ -39,12 +39,12 @@ namespace Emby.Server.Implementations.WebSockets
do
{
var buffer = WebSocket.CreateServerBuffer(BufferSize);
- result = await webSocket.ReceiveAsync(buffer, cancellationToken);
+ result = await webSocket.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false);
message.AddRange(buffer.Array.Take(result.Count));
if (result.EndOfMessage)
{
- await ProcessMessage(message.ToArray(), taskCompletionSource);
+ await ProcessMessage(message.ToArray(), taskCompletionSource).ConfigureAwait(false);
message.Clear();
}
} while (!taskCompletionSource.Task.IsCompleted &&
@@ -53,8 +53,10 @@ namespace Emby.Server.Implementations.WebSockets
if (webSocket.State == WebSocketState.Open)
{
- await webSocket.CloseAsync(result.CloseStatus ?? WebSocketCloseStatus.NormalClosure,
- result.CloseStatusDescription, cancellationToken);
+ await webSocket.CloseAsync(
+ result.CloseStatus ?? WebSocketCloseStatus.NormalClosure,
+ result.CloseStatusDescription,
+ cancellationToken).ConfigureAwait(false);
}
}