From 36f3e933a23d802d154c16fd304a82c3fe3f453d Mon Sep 17 00:00:00 2001
From: ConfusedPolarBear <33811686+ConfusedPolarBear@users.noreply.github.com>
Date: Wed, 15 Apr 2020 14:28:42 -0500
Subject: Add quick connect
---
.../QuickConnect/IQuickConnect.cs | 91 ++++++++++++++++++++++
MediaBrowser.Controller/Session/ISessionManager.cs | 2 +
2 files changed, 93 insertions(+)
create mode 100644 MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
(limited to 'MediaBrowser.Controller')
diff --git a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
new file mode 100644
index 0000000000..e4a790ffe7
--- /dev/null
+++ b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using MediaBrowser.Model.QuickConnect;
+using MediaBrowser.Model.Services;
+
+namespace MediaBrowser.Controller.QuickConnect
+{
+ ///
+ /// Quick connect standard interface.
+ ///
+ public interface IQuickConnect
+ {
+ ///
+ /// Gets or sets the length of user facing codes.
+ ///
+ public int CodeLength { get; set; }
+
+ ///
+ /// Gets or sets the string to prefix internal access tokens with.
+ ///
+ public string TokenNamePrefix { get; set; }
+
+ ///
+ /// Gets the current state of quick connect.
+ ///
+ public QuickConnectState State { get; }
+
+ ///
+ /// Gets or sets the time (in minutes) before a pending request will expire.
+ ///
+ public int RequestExpiry { get; set; }
+
+ ///
+ /// Assert that quick connect is currently active and throws an exception if it is not.
+ ///
+ void AssertActive();
+
+ ///
+ /// Changes the status of quick connect.
+ ///
+ /// New state to change to
+ void SetEnabled(QuickConnectState newState);
+
+ ///
+ /// Initiates a new quick connect request.
+ ///
+ /// Friendly device name to display in the request UI.
+ /// A quick connect result with tokens to proceed or a descriptive error message otherwise.
+ QuickConnectResult TryConnect(string friendlyName);
+
+ ///
+ /// Checks the status of an individual request.
+ ///
+ /// Unique secret identifier of the request.
+ /// Quick connect result.
+ QuickConnectResult CheckRequestStatus(string secret);
+
+ ///
+ /// Returns all current quick connect requests as DTOs. Does not include sensitive information.
+ ///
+ /// List of all quick connect results.
+ List GetCurrentRequests();
+
+ ///
+ /// Returns all current quick connect requests (including sensitive information).
+ ///
+ /// List of all quick connect results.
+ List GetCurrentRequestsInternal();
+
+ ///
+ /// Authorizes a quick connect request to connect as the calling user.
+ ///
+ /// HTTP request object.
+ /// Public request lookup value.
+ /// A boolean indicating if the authorization completed successfully.
+ bool AuthorizeRequest(IRequest request, string lookup);
+
+ ///
+ /// Deletes all quick connect access tokens for the provided user.
+ ///
+ /// Guid of the user to delete tokens for.
+ /// A count of the deleted tokens.
+ int DeleteAllDevices(Guid user);
+
+ ///
+ /// Generates a short code to display to the user to uniquely identify this request.
+ ///
+ /// A short, unique alphanumeric string.
+ string GenerateCode();
+ }
+}
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index 771027103b..74ffd5a181 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -246,6 +246,8 @@ namespace MediaBrowser.Controller.Session
/// Task{SessionInfo}.
Task AuthenticateNewSession(AuthenticationRequest request);
+ public Task AuthenticateQuickConnect(AuthenticationRequest request, string token);
+
///
/// Creates the new session.
///
--
cgit v1.2.3
From 387a07c6dd4792ea1e77d333e178f9b4e9c56678 Mon Sep 17 00:00:00 2001
From: ConfusedPolarBear <33811686+ConfusedPolarBear@users.noreply.github.com>
Date: Sun, 19 Apr 2020 01:33:09 -0500
Subject: Add persistent setting configuration and temporary activation
---
.../QuickConnect/ConfigurationExtension.cs | 30 +++++++++
.../QuickConnect/QuickConnectConfiguration.cs | 13 ++++
.../QuickConnect/QuickConnectManager.cs | 72 +++++++++++++++++++---
.../QuickConnect/QuickConnectService.cs | 40 ++++++++++--
.../QuickConnect/IQuickConnect.cs | 8 ++-
5 files changed, 149 insertions(+), 14 deletions(-)
create mode 100644 Emby.Server.Implementations/QuickConnect/ConfigurationExtension.cs
create mode 100644 Emby.Server.Implementations/QuickConnect/QuickConnectConfiguration.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/QuickConnect/ConfigurationExtension.cs b/Emby.Server.Implementations/QuickConnect/ConfigurationExtension.cs
new file mode 100644
index 0000000000..0e35ba80ab
--- /dev/null
+++ b/Emby.Server.Implementations/QuickConnect/ConfigurationExtension.cs
@@ -0,0 +1,30 @@
+#pragma warning disable CS1591
+
+using System.Collections.Generic;
+using MediaBrowser.Common.Configuration;
+
+namespace Emby.Server.Implementations.QuickConnect
+{
+ public static class ConfigurationExtension
+ {
+ public static QuickConnectConfiguration GetQuickConnectConfiguration(this IConfigurationManager manager)
+ {
+ return manager.GetConfiguration("quickconnect");
+ }
+ }
+
+ public class QuickConnectConfigurationFactory : IConfigurationFactory
+ {
+ public IEnumerable GetConfigurations()
+ {
+ return new ConfigurationStore[]
+ {
+ new ConfigurationStore
+ {
+ Key = "quickconnect",
+ ConfigurationType = typeof(QuickConnectConfiguration)
+ }
+ };
+ }
+ }
+}
diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectConfiguration.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectConfiguration.cs
new file mode 100644
index 0000000000..befc463796
--- /dev/null
+++ b/Emby.Server.Implementations/QuickConnect/QuickConnectConfiguration.cs
@@ -0,0 +1,13 @@
+using MediaBrowser.Model.QuickConnect;
+
+namespace Emby.Server.Implementations.QuickConnect
+{
+ public class QuickConnectConfiguration
+ {
+ public QuickConnectConfiguration()
+ {
+ }
+
+ public QuickConnectState State { get; set; }
+ }
+}
diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
index 30418097ca..671ddc2b96 100644
--- a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
+++ b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
@@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.QuickConnect;
@@ -12,6 +14,7 @@ using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.QuickConnect;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
+using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.QuickConnect
@@ -24,6 +27,7 @@ namespace Emby.Server.Implementations.QuickConnect
private readonly RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider();
private Dictionary _currentRequests = new Dictionary();
+ private IServerConfigurationManager _config;
private ILogger _logger;
private IUserManager _userManager;
private ILocalizationManager _localizationManager;
@@ -31,11 +35,13 @@ namespace Emby.Server.Implementations.QuickConnect
private IAuthenticationRepository _authenticationRepository;
private IAuthorizationContext _authContext;
private IServerApplicationHost _appHost;
+ private ITaskManager _taskManager;
///
/// Initializes a new instance of the class.
/// Should only be called at server startup when a singleton is created.
///
+ /// Configuration.
/// Logger.
/// User manager.
/// Localization.
@@ -43,15 +49,19 @@ namespace Emby.Server.Implementations.QuickConnect
/// Application host.
/// Authentication context.
/// Authentication repository.
+ /// Task scheduler.
public QuickConnectManager(
+ IServerConfigurationManager config,
ILoggerFactory loggerFactory,
IUserManager userManager,
ILocalizationManager localization,
IJsonSerializer jsonSerializer,
IServerApplicationHost appHost,
IAuthorizationContext authContext,
- IAuthenticationRepository authenticationRepository)
+ IAuthenticationRepository authenticationRepository,
+ ITaskManager taskManager)
{
+ _config = config;
_logger = loggerFactory.CreateLogger(nameof(QuickConnectManager));
_userManager = userManager;
_localizationManager = localization;
@@ -59,6 +69,16 @@ namespace Emby.Server.Implementations.QuickConnect
_appHost = appHost;
_authContext = authContext;
_authenticationRepository = authenticationRepository;
+ _taskManager = taskManager;
+
+ ReloadConfiguration();
+ }
+
+ private void ReloadConfiguration()
+ {
+ var config = _config.GetQuickConnectConfiguration();
+
+ State = config.State;
}
///
@@ -73,6 +93,10 @@ namespace Emby.Server.Implementations.QuickConnect
///
public int RequestExpiry { get; set; } = 30;
+ private bool TemporaryActivation { get; set; } = false;
+
+ private DateTime DateActivated { get; set; }
+
///
public void AssertActive()
{
@@ -82,17 +106,37 @@ namespace Emby.Server.Implementations.QuickConnect
}
}
+ ///
+ public QuickConnectResult Activate()
+ {
+ // This should not call SetEnabled since that would persist the "temporary" activation to the configuration file
+ State = QuickConnectState.Active;
+ DateActivated = DateTime.Now;
+ TemporaryActivation = true;
+
+ return new QuickConnectResult();
+ }
+
///
public void SetEnabled(QuickConnectState newState)
{
_logger.LogDebug("Changed quick connect state from {0} to {1}", State, newState);
State = newState;
+
+ _config.SaveConfiguration("quickconnect", new QuickConnectConfiguration()
+ {
+ State = State
+ });
+
+ _logger.LogDebug("Configuration saved");
}
///
public QuickConnectResult TryConnect(string friendlyName)
{
+ ExpireRequests(true);
+
if (State != QuickConnectState.Active)
{
_logger.LogDebug("Refusing quick connect initiation request, current state is {0}", State);
@@ -122,13 +166,11 @@ namespace Emby.Server.Implementations.QuickConnect
///
public QuickConnectResult CheckRequestStatus(string secret)
{
- AssertActive();
ExpireRequests();
+ AssertActive();
string lookup = _currentRequests.Where(x => x.Value.Secret == secret).Select(x => x.Value.Lookup).DefaultIfEmpty(string.Empty).First();
- _logger.LogDebug("Transformed private identifier {0} into public lookup {1}", secret, lookup);
-
if (!_currentRequests.ContainsKey(lookup))
{
throw new KeyNotFoundException("Unable to find request with provided identifier");
@@ -146,8 +188,8 @@ namespace Emby.Server.Implementations.QuickConnect
///
public List GetCurrentRequestsInternal()
{
- AssertActive();
ExpireRequests();
+ AssertActive();
return _currentRequests.Values.ToList();
}
@@ -174,12 +216,11 @@ namespace Emby.Server.Implementations.QuickConnect
///
public bool AuthorizeRequest(IRequest request, string lookup)
{
+ ExpireRequests();
AssertActive();
var auth = _authContext.GetAuthorizationInfo(request);
- ExpireRequests();
-
if (!_currentRequests.ContainsKey(lookup))
{
throw new KeyNotFoundException("Unable to find request");
@@ -208,6 +249,8 @@ namespace Emby.Server.Implementations.QuickConnect
UserId = auth.UserId
});
+ _logger.LogInformation("Allowing device {0} to login as user {1} with quick connect code {2}", result.FriendlyName, auth.User.Name, result.Code);
+
return true;
}
@@ -239,8 +282,21 @@ namespace Emby.Server.Implementations.QuickConnect
return string.Join(string.Empty, bytes.Select(x => x.ToString("x2", CultureInfo.InvariantCulture)));
}
- private void ExpireRequests()
+ private void ExpireRequests(bool onlyCheckTime = false)
{
+ // check if quick connect should be deactivated
+ if (TemporaryActivation && DateTime.Now > DateActivated.AddMinutes(10) && State == QuickConnectState.Active)
+ {
+ _logger.LogDebug("Quick connect time expired, deactivating");
+ SetEnabled(QuickConnectState.Available);
+ }
+
+ if (onlyCheckTime)
+ {
+ return;
+ }
+
+ // expire stale connection requests
var delete = new List();
var values = _currentRequests.Values.ToList();
diff --git a/MediaBrowser.Api/QuickConnect/QuickConnectService.cs b/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
index 889a788391..60d6ac4147 100644
--- a/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
+++ b/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
@@ -98,6 +98,11 @@ namespace MediaBrowser.Api.QuickConnect
public object Get(QuickConnectList request)
{
+ if(_quickConnect.State != QuickConnectState.Active)
+ {
+ return Array.Empty();
+ }
+
return _quickConnect.GetCurrentRequests();
}
@@ -124,15 +129,40 @@ namespace MediaBrowser.Api.QuickConnect
public object Post(Activate request)
{
- if (_quickConnect.State == QuickConnectState.Available)
+ string name = _authContext.GetAuthorizationInfo(Request).User.Name;
+
+ if(_quickConnect.State == QuickConnectState.Unavailable)
+ {
+ return new QuickConnectResult()
+ {
+ Error = "Quick connect is not enabled on this server"
+ };
+ }
+
+ else if(_quickConnect.State == QuickConnectState.Available)
{
- _quickConnect.SetEnabled(QuickConnectState.Active);
+ var result = _quickConnect.Activate();
- string name = _authContext.GetAuthorizationInfo(Request).User.Name;
- Logger.LogInformation("{name} enabled quick connect", name);
+ if (string.IsNullOrEmpty(result.Error))
+ {
+ Logger.LogInformation("{name} temporarily activated quick connect", name);
+ }
+
+ return result;
}
- return _quickConnect.State;
+ else if(_quickConnect.State == QuickConnectState.Active)
+ {
+ return new QuickConnectResult()
+ {
+ Error = ""
+ };
+ }
+
+ return new QuickConnectResult()
+ {
+ Error = "Unknown current state"
+ };
}
public object Post(Available request)
diff --git a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
index e4a790ffe7..d44765e112 100644
--- a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
+++ b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
@@ -35,10 +35,16 @@ namespace MediaBrowser.Controller.QuickConnect
///
void AssertActive();
+ ///
+ /// Temporarily activates quick connect for a short amount of time.
+ ///
+ /// A quick connect result object indicating success.
+ QuickConnectResult Activate();
+
///
/// Changes the status of quick connect.
///
- /// New state to change to
+ /// New state to change to.
void SetEnabled(QuickConnectState newState);
///
--
cgit v1.2.3
From 4be476ec5312387f87134915d0fd132b2ad5fa3f Mon Sep 17 00:00:00 2001
From: ConfusedPolarBear <33811686+ConfusedPolarBear@users.noreply.github.com>
Date: Thu, 18 Jun 2020 01:29:47 -0500
Subject: Move all settings into the main server configuration
Decreased the timeout from 30 minutes to 5.
Public lookup values have been replaced with the short code.
---
.../QuickConnect/ConfigurationExtension.cs | 20 -------
.../QuickConnect/QuickConnectConfiguration.cs | 15 -----
.../QuickConnectConfigurationFactory.cs | 27 ---------
.../QuickConnect/QuickConnectManager.cs | 66 ++++++++++------------
.../QuickConnect/IQuickConnect.cs | 8 +--
.../Configuration/ServerConfiguration.cs | 6 ++
.../QuickConnect/QuickConnectResult.cs | 5 --
.../QuickConnect/QuickConnectResultDto.cs | 14 +----
8 files changed, 41 insertions(+), 120 deletions(-)
delete mode 100644 Emby.Server.Implementations/QuickConnect/ConfigurationExtension.cs
delete mode 100644 Emby.Server.Implementations/QuickConnect/QuickConnectConfiguration.cs
delete mode 100644 Emby.Server.Implementations/QuickConnect/QuickConnectConfigurationFactory.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/QuickConnect/ConfigurationExtension.cs b/Emby.Server.Implementations/QuickConnect/ConfigurationExtension.cs
deleted file mode 100644
index 2a19fc36c1..0000000000
--- a/Emby.Server.Implementations/QuickConnect/ConfigurationExtension.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using MediaBrowser.Common.Configuration;
-
-namespace Emby.Server.Implementations.QuickConnect
-{
- ///
- /// Configuration extension to support persistent quick connect configuration.
- ///
- public static class ConfigurationExtension
- {
- ///
- /// Return the current quick connect configuration.
- ///
- /// Configuration manager.
- /// Current quick connect configuration.
- public static QuickConnectConfiguration GetQuickConnectConfiguration(this IConfigurationManager manager)
- {
- return manager.GetConfiguration("quickconnect");
- }
- }
-}
diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectConfiguration.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectConfiguration.cs
deleted file mode 100644
index 2302ddbc3f..0000000000
--- a/Emby.Server.Implementations/QuickConnect/QuickConnectConfiguration.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using MediaBrowser.Model.QuickConnect;
-
-namespace Emby.Server.Implementations.QuickConnect
-{
- ///
- /// Persistent quick connect configuration.
- ///
- public class QuickConnectConfiguration
- {
- ///
- /// Gets or sets persistent quick connect availability state.
- ///
- public QuickConnectState State { get; set; }
- }
-}
diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectConfigurationFactory.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectConfigurationFactory.cs
deleted file mode 100644
index d7bc84c5e2..0000000000
--- a/Emby.Server.Implementations/QuickConnect/QuickConnectConfigurationFactory.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Collections.Generic;
-using MediaBrowser.Common.Configuration;
-
-namespace Emby.Server.Implementations.QuickConnect
-{
- ///
- /// Configuration factory for quick connect.
- ///
- public class QuickConnectConfigurationFactory : IConfigurationFactory
- {
- ///
- /// Returns the current quick connect configuration.
- ///
- /// Current quick connect configuration.
- public IEnumerable GetConfigurations()
- {
- return new[]
- {
- new ConfigurationStore
- {
- Key = "quickconnect",
- ConfigurationType = typeof(QuickConnectConfiguration)
- }
- };
- }
- }
-}
diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
index 7a584c7cd0..8d704f32b7 100644
--- a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
+++ b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
@@ -11,7 +11,9 @@ using MediaBrowser.Controller.QuickConnect;
using MediaBrowser.Controller.Security;
using MediaBrowser.Model.QuickConnect;
using MediaBrowser.Model.Services;
+using MediaBrowser.Common;
using Microsoft.Extensions.Logging;
+using MediaBrowser.Common.Extensions;
namespace Emby.Server.Implementations.QuickConnect
{
@@ -64,9 +66,7 @@ namespace Emby.Server.Implementations.QuickConnect
public QuickConnectState State { get; private set; } = QuickConnectState.Unavailable;
///
- public int RequestExpiry { get; set; } = 30;
-
- private bool TemporaryActivation { get; set; } = false;
+ public int Timeout { get; set; } = 5;
private DateTime DateActivated { get; set; }
@@ -82,10 +82,9 @@ namespace Emby.Server.Implementations.QuickConnect
///
public QuickConnectResult Activate()
{
- // This should not call SetEnabled since that would persist the "temporary" activation to the configuration file
- State = QuickConnectState.Active;
+ SetEnabled(QuickConnectState.Active);
+
DateActivated = DateTime.Now;
- TemporaryActivation = true;
return new QuickConnectResult();
}
@@ -96,12 +95,10 @@ namespace Emby.Server.Implementations.QuickConnect
_logger.LogDebug("Changed quick connect state from {0} to {1}", State, newState);
ExpireRequests(true);
- State = newState;
- _config.SaveConfiguration("quickconnect", new QuickConnectConfiguration()
- {
- State = State
- });
+ State = newState;
+ _config.Configuration.QuickConnectAvailable = newState == QuickConnectState.Available || newState == QuickConnectState.Active;
+ _config.SaveConfiguration();
_logger.LogDebug("Configuration saved");
}
@@ -123,17 +120,16 @@ namespace Emby.Server.Implementations.QuickConnect
_logger.LogDebug("Got new quick connect request from {friendlyName}", friendlyName);
- var lookup = GenerateSecureRandom();
+ var code = GenerateCode();
var result = new QuickConnectResult()
{
- Lookup = lookup,
Secret = GenerateSecureRandom(),
FriendlyName = friendlyName,
DateAdded = DateTime.Now,
- Code = GenerateCode()
+ Code = code
};
- _currentRequests[lookup] = result;
+ _currentRequests[code] = result;
return result;
}
@@ -143,17 +139,16 @@ namespace Emby.Server.Implementations.QuickConnect
ExpireRequests();
AssertActive();
- string lookup = _currentRequests.Where(x => x.Value.Secret == secret).Select(x => x.Value.Lookup).DefaultIfEmpty(string.Empty).First();
+ string code = _currentRequests.Where(x => x.Value.Secret == secret).Select(x => x.Value.Code).DefaultIfEmpty(string.Empty).First();
- if (!_currentRequests.TryGetValue(lookup, out QuickConnectResult result))
+ if (!_currentRequests.TryGetValue(code, out QuickConnectResult result))
{
- throw new KeyNotFoundException("Unable to find request with provided identifier");
+ throw new ResourceNotFoundException("Unable to find request with provided secret");
}
return result;
}
- ///
public List GetCurrentRequests()
{
return GetCurrentRequestsInternal().Select(x => (QuickConnectResultDto)x).ToList();
@@ -186,16 +181,16 @@ namespace Emby.Server.Implementations.QuickConnect
}
///
- public bool AuthorizeRequest(IRequest request, string lookup)
+ public bool AuthorizeRequest(IRequest request, string code)
{
ExpireRequests();
AssertActive();
var auth = _authContext.GetAuthorizationInfo(request);
- if (!_currentRequests.TryGetValue(lookup, out QuickConnectResult result))
+ if (!_currentRequests.TryGetValue(code, out QuickConnectResult result))
{
- throw new KeyNotFoundException("Unable to find request");
+ throw new ResourceNotFoundException("Unable to find request");
}
if (result.Authenticated)
@@ -205,9 +200,9 @@ namespace Emby.Server.Implementations.QuickConnect
result.Authentication = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
- // Advance the time on the request so it expires sooner as the client will pick up the changes in a few seconds
- var added = result.DateAdded ?? DateTime.Now.Subtract(new TimeSpan(0, RequestExpiry, 0));
- result.DateAdded = added.Subtract(new TimeSpan(0, RequestExpiry - 1, 0));
+ // Change the time on the request so it expires one minute into the future. It can't expire immediately as otherwise some clients wouldn't ever see that they have been authenticated.
+ var added = result.DateAdded ?? DateTime.Now.Subtract(new TimeSpan(0, Timeout, 0));
+ result.DateAdded = added.Subtract(new TimeSpan(0, Timeout - 1, 0));
_authenticationRepository.Create(new AuthenticationInfo
{
@@ -271,7 +266,7 @@ namespace Emby.Server.Implementations.QuickConnect
var bytes = new byte[length];
_rng.GetBytes(bytes);
- return string.Join(string.Empty, bytes.Select(x => x.ToString("x2", CultureInfo.InvariantCulture)));
+ return Hex.Encode(bytes);
}
///
@@ -281,12 +276,11 @@ namespace Emby.Server.Implementations.QuickConnect
private void ExpireRequests(bool expireAll = false)
{
// Check if quick connect should be deactivated
- if (TemporaryActivation && DateTime.Now > DateActivated.AddMinutes(10) && State == QuickConnectState.Active && !expireAll)
+ if (State == QuickConnectState.Active && DateTime.Now > DateActivated.AddMinutes(Timeout) && !expireAll)
{
_logger.LogDebug("Quick connect time expired, deactivating");
SetEnabled(QuickConnectState.Available);
expireAll = true;
- TemporaryActivation = false;
}
// Expire stale connection requests
@@ -296,28 +290,28 @@ namespace Emby.Server.Implementations.QuickConnect
for (int i = 0; i < values.Count; i++)
{
var added = values[i].DateAdded ?? DateTime.UnixEpoch;
- if (DateTime.Now > added.AddMinutes(RequestExpiry) || expireAll)
+ if (DateTime.Now > added.AddMinutes(Timeout) || expireAll)
{
- delete.Add(values[i].Lookup);
+ delete.Add(values[i].Code);
}
}
- foreach (var lookup in delete)
+ foreach (var code in delete)
{
- _logger.LogDebug("Removing expired request {lookup}", lookup);
+ _logger.LogDebug("Removing expired request {code}", code);
- if (!_currentRequests.TryRemove(lookup, out _))
+ if (!_currentRequests.TryRemove(code, out _))
{
- _logger.LogWarning("Request {lookup} already expired", lookup);
+ _logger.LogWarning("Request {code} already expired", code);
}
}
}
private void ReloadConfiguration()
{
- var config = _config.GetQuickConnectConfiguration();
+ var available = _config.Configuration.QuickConnectAvailable;
- State = config.State;
+ State = available ? QuickConnectState.Available : QuickConnectState.Unavailable;
}
}
}
diff --git a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
index d44765e112..d31d0e5097 100644
--- a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
+++ b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
@@ -26,9 +26,9 @@ namespace MediaBrowser.Controller.QuickConnect
public QuickConnectState State { get; }
///
- /// Gets or sets the time (in minutes) before a pending request will expire.
+ /// Gets or sets the time (in minutes) before quick connect will automatically deactivate.
///
- public int RequestExpiry { get; set; }
+ public int Timeout { get; set; }
///
/// Assert that quick connect is currently active and throws an exception if it is not.
@@ -77,9 +77,9 @@ namespace MediaBrowser.Controller.QuickConnect
/// Authorizes a quick connect request to connect as the calling user.
///
/// HTTP request object.
- /// Public request lookup value.
+ /// Identifying code for the request..
/// A boolean indicating if the authorization completed successfully.
- bool AuthorizeRequest(IRequest request, string lookup);
+ bool AuthorizeRequest(IRequest request, string code);
///
/// Deletes all quick connect access tokens for the provided user.
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index afbe02dd36..76b2906069 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -76,6 +76,11 @@ namespace MediaBrowser.Model.Configuration
/// true if this instance is port authorized; otherwise, false.
public bool IsPortAuthorized { get; set; }
+ ///
+ /// Gets or sets if quick connect is available for use on this server.
+ ///
+ public bool QuickConnectAvailable { get; set; }
+
public bool AutoRunWebApp { get; set; }
public bool EnableRemoteAccess { get; set; }
@@ -281,6 +286,7 @@ namespace MediaBrowser.Model.Configuration
AutoRunWebApp = true;
EnableRemoteAccess = true;
+ QuickConnectAvailable = false;
EnableUPnP = false;
MinResumePct = 5;
diff --git a/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs b/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs
index 32d7f6aba6..a10d60d57e 100644
--- a/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs
+++ b/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs
@@ -17,11 +17,6 @@ namespace MediaBrowser.Model.QuickConnect
///
public string? Secret { get; set; }
- ///
- /// Gets or sets the public value used to uniquely identify this request. Can only be used to authorize the request.
- ///
- public string? Lookup { get; set; }
-
///
/// Gets or sets the user facing code used so the user can quickly differentiate this request from others.
///
diff --git a/MediaBrowser.Model/QuickConnect/QuickConnectResultDto.cs b/MediaBrowser.Model/QuickConnect/QuickConnectResultDto.cs
index 19acc7cd88..26084caf1e 100644
--- a/MediaBrowser.Model/QuickConnect/QuickConnectResultDto.cs
+++ b/MediaBrowser.Model/QuickConnect/QuickConnectResultDto.cs
@@ -17,25 +17,15 @@ namespace MediaBrowser.Model.QuickConnect
///
public string? Code { get; private set; }
- ///
- /// Gets the public value used to uniquely identify this request. Can only be used to authorize the request.
- ///
- public string? Lookup { get; private set; }
-
///
/// Gets the device friendly name.
///
public string? FriendlyName { get; private set; }
- ///
- /// Gets the DateTime that this request was created.
- ///
- public DateTime? DateAdded { get; private set; }
-
///
/// Cast an internal quick connect result to a DTO by removing all sensitive properties.
///
- /// QuickConnectResult object to cast
+ /// QuickConnectResult object to cast.
public static implicit operator QuickConnectResultDto(QuickConnectResult result)
{
QuickConnectResultDto resultDto = new QuickConnectResultDto
@@ -43,8 +33,6 @@ namespace MediaBrowser.Model.QuickConnect
Authenticated = result.Authenticated,
Code = result.Code,
FriendlyName = result.FriendlyName,
- DateAdded = result.DateAdded,
- Lookup = result.Lookup
};
return resultDto;
--
cgit v1.2.3
From 329980c727cf03587ff5f4011a3af3ef2fa5e4f1 Mon Sep 17 00:00:00 2001
From: ConfusedPolarBear <33811686+ConfusedPolarBear@users.noreply.github.com>
Date: Thu, 18 Jun 2020 01:58:58 -0500
Subject: API cleanup
---
.../QuickConnect/QuickConnectManager.cs | 35 +++--------
.../QuickConnect/QuickConnectService.cs | 67 ++++------------------
.../QuickConnect/IQuickConnect.cs | 23 +++-----
.../QuickConnect/QuickConnectResultDto.cs | 41 -------------
4 files changed, 27 insertions(+), 139 deletions(-)
delete mode 100644 MediaBrowser.Model/QuickConnect/QuickConnectResultDto.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
index 8d704f32b7..263556e9d7 100644
--- a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
+++ b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
@@ -75,18 +75,15 @@ namespace Emby.Server.Implementations.QuickConnect
{
if (State != QuickConnectState.Active)
{
- throw new InvalidOperationException("Quick connect is not active on this server");
+ throw new ArgumentException("Quick connect is not active on this server");
}
}
///
- public QuickConnectResult Activate()
+ public void Activate()
{
- SetEnabled(QuickConnectState.Active);
-
DateActivated = DateTime.Now;
-
- return new QuickConnectResult();
+ SetEnabled(QuickConnectState.Active);
}
///
@@ -149,19 +146,6 @@ namespace Emby.Server.Implementations.QuickConnect
return result;
}
- public List GetCurrentRequests()
- {
- return GetCurrentRequestsInternal().Select(x => (QuickConnectResultDto)x).ToList();
- }
-
- ///
- public List GetCurrentRequestsInternal()
- {
- ExpireRequests();
- AssertActive();
- return _currentRequests.Values.ToList();
- }
-
///
public string GenerateCode()
{
@@ -215,7 +199,7 @@ namespace Emby.Server.Implementations.QuickConnect
UserId = auth.UserId
});
- _logger.LogInformation("Allowing device {0} to login as user {1} with quick connect code {2}", result.FriendlyName, auth.User.Name, result.Code);
+ _logger.LogInformation("Allowing device {0} to login as user {1} with quick connect code {2}", result.FriendlyName, auth.User.Username, result.Code);
return true;
}
@@ -269,11 +253,8 @@ namespace Emby.Server.Implementations.QuickConnect
return Hex.Encode(bytes);
}
- ///
- /// Expire quick connect requests that are over the time limit. If is true, all requests are unconditionally expired.
- ///
- /// If true, all requests will be expired.
- private void ExpireRequests(bool expireAll = false)
+ ///
+ public void ExpireRequests(bool expireAll = false)
{
// Check if quick connect should be deactivated
if (State == QuickConnectState.Active && DateTime.Now > DateActivated.AddMinutes(Timeout) && !expireAll)
@@ -309,9 +290,7 @@ namespace Emby.Server.Implementations.QuickConnect
private void ReloadConfiguration()
{
- var available = _config.Configuration.QuickConnectAvailable;
-
- State = available ? QuickConnectState.Available : QuickConnectState.Unavailable;
+ State = _config.Configuration.QuickConnectAvailable ? QuickConnectState.Available : QuickConnectState.Unavailable;
}
}
}
diff --git a/MediaBrowser.Api/QuickConnect/QuickConnectService.cs b/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
index 60d6ac4147..9047a1e957 100644
--- a/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
+++ b/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
@@ -24,18 +23,12 @@ namespace MediaBrowser.Api.QuickConnect
public string Secret { get; set; }
}
- [Route("/QuickConnect/List", "GET", Summary = "Lists all quick connect requests")]
- [Authenticated]
- public class QuickConnectList : IReturn>
- {
- }
-
[Route("/QuickConnect/Authorize", "POST", Summary = "Authorizes a pending quick connect request")]
[Authenticated]
- public class Authorize : IReturn
+ public class Authorize : IReturn
{
- [ApiMember(Name = "Lookup", Description = "Quick connect public lookup", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string Lookup { get; set; }
+ [ApiMember(Name = "Code", Description = "Quick connect identifying code", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string Code { get; set; }
}
[Route("/QuickConnect/Deauthorize", "POST", Summary = "Deletes all quick connect authorization tokens for the current user")]
@@ -62,8 +55,9 @@ namespace MediaBrowser.Api.QuickConnect
[Route("/QuickConnect/Activate", "POST", Summary = "Temporarily activates quick connect for the time period defined in the server configuration")]
[Authenticated]
- public class Activate : IReturn
+ public class Activate : IReturn
{
+
}
public class QuickConnectService : BaseApiService
@@ -96,18 +90,9 @@ namespace MediaBrowser.Api.QuickConnect
return _quickConnect.CheckRequestStatus(request.Secret);
}
- public object Get(QuickConnectList request)
- {
- if(_quickConnect.State != QuickConnectState.Active)
- {
- return Array.Empty();
- }
-
- return _quickConnect.GetCurrentRequests();
- }
-
public object Get(QuickConnectStatus request)
{
+ _quickConnect.ExpireRequests();
return _quickConnect.State;
}
@@ -120,55 +105,27 @@ namespace MediaBrowser.Api.QuickConnect
public object Post(Authorize request)
{
- bool result = _quickConnect.AuthorizeRequest(Request, request.Lookup);
-
- Logger.LogInformation("Result of authorizing quick connect {0}: {1}", request.Lookup[..10], result);
-
- return result;
+ return _quickConnect.AuthorizeRequest(Request, request.Code);
}
public object Post(Activate request)
{
- string name = _authContext.GetAuthorizationInfo(Request).User.Name;
-
if(_quickConnect.State == QuickConnectState.Unavailable)
{
- return new QuickConnectResult()
- {
- Error = "Quick connect is not enabled on this server"
- };
+ return false;
}
- else if(_quickConnect.State == QuickConnectState.Available)
- {
- var result = _quickConnect.Activate();
-
- if (string.IsNullOrEmpty(result.Error))
- {
- Logger.LogInformation("{name} temporarily activated quick connect", name);
- }
+ string name = _authContext.GetAuthorizationInfo(Request).User.Username;
- return result;
- }
+ Logger.LogInformation("{name} temporarily activated quick connect", name);
+ _quickConnect.Activate();
- else if(_quickConnect.State == QuickConnectState.Active)
- {
- return new QuickConnectResult()
- {
- Error = ""
- };
- }
-
- return new QuickConnectResult()
- {
- Error = "Unknown current state"
- };
+ return true;
}
public object Post(Available request)
{
_quickConnect.SetEnabled(request.Status);
-
return _quickConnect.State;
}
}
diff --git a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
index d31d0e5097..10ec9e6cb5 100644
--- a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
+++ b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
@@ -38,8 +38,7 @@ namespace MediaBrowser.Controller.QuickConnect
///
/// Temporarily activates quick connect for a short amount of time.
///
- /// A quick connect result object indicating success.
- QuickConnectResult Activate();
+ void Activate();
///
/// Changes the status of quick connect.
@@ -61,26 +60,20 @@ namespace MediaBrowser.Controller.QuickConnect
/// Quick connect result.
QuickConnectResult CheckRequestStatus(string secret);
- ///
- /// Returns all current quick connect requests as DTOs. Does not include sensitive information.
- ///
- /// List of all quick connect results.
- List GetCurrentRequests();
-
- ///
- /// Returns all current quick connect requests (including sensitive information).
- ///
- /// List of all quick connect results.
- List GetCurrentRequestsInternal();
-
///
/// Authorizes a quick connect request to connect as the calling user.
///
/// HTTP request object.
- /// Identifying code for the request..
+ /// Identifying code for the request.
/// A boolean indicating if the authorization completed successfully.
bool AuthorizeRequest(IRequest request, string code);
+ ///
+ /// Expire quick connect requests that are over the time limit. If is true, all requests are unconditionally expired.
+ ///
+ /// If true, all requests will be expired.
+ public void ExpireRequests(bool expireAll = false);
+
///
/// Deletes all quick connect access tokens for the provided user.
///
diff --git a/MediaBrowser.Model/QuickConnect/QuickConnectResultDto.cs b/MediaBrowser.Model/QuickConnect/QuickConnectResultDto.cs
deleted file mode 100644
index 26084caf1e..0000000000
--- a/MediaBrowser.Model/QuickConnect/QuickConnectResultDto.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-
-namespace MediaBrowser.Model.QuickConnect
-{
- ///
- /// Stores the non-sensitive results of an incoming quick connect request.
- ///
- public class QuickConnectResultDto
- {
- ///
- /// Gets a value indicating whether this request is authorized.
- ///
- public bool Authenticated { get; private set; }
-
- ///
- /// Gets the user facing code used so the user can quickly differentiate this request from others.
- ///
- public string? Code { get; private set; }
-
- ///
- /// Gets the device friendly name.
- ///
- public string? FriendlyName { get; private set; }
-
- ///
- /// Cast an internal quick connect result to a DTO by removing all sensitive properties.
- ///
- /// QuickConnectResult object to cast.
- public static implicit operator QuickConnectResultDto(QuickConnectResult result)
- {
- QuickConnectResultDto resultDto = new QuickConnectResultDto
- {
- Authenticated = result.Authenticated,
- Code = result.Code,
- FriendlyName = result.FriendlyName,
- };
-
- return resultDto;
- }
- }
-}
--
cgit v1.2.3
From 3c91aa0c3d4af3c3d11b4c732ea14c7e641ba662 Mon Sep 17 00:00:00 2001
From: Matt Montgomery <33811686+ConfusedPolarBear@users.noreply.github.com>
Date: Sun, 26 Jul 2020 23:13:14 -0500
Subject: Code cleanup
---
.../QuickConnect/QuickConnectManager.cs | 25 +++++++++++-----------
.../QuickConnect/QuickConnectService.cs | 2 +-
.../QuickConnect/IQuickConnect.cs | 6 +++---
3 files changed, 16 insertions(+), 17 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
index a69ea2267b..23e94afd72 100644
--- a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
+++ b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
@@ -14,6 +14,7 @@ using MediaBrowser.Model.Services;
using MediaBrowser.Common;
using Microsoft.Extensions.Logging;
using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Authentication;
namespace Emby.Server.Implementations.QuickConnect
{
@@ -83,13 +84,13 @@ namespace Emby.Server.Implementations.QuickConnect
public void Activate()
{
DateActivated = DateTime.Now;
- SetEnabled(QuickConnectState.Active);
+ SetState(QuickConnectState.Active);
}
///
- public void SetEnabled(QuickConnectState newState)
+ public void SetState(QuickConnectState newState)
{
- _logger.LogDebug("Changed quick connect state from {0} to {1}", State, newState);
+ _logger.LogDebug("Changed quick connect state from {State} to {newState}", State, newState);
ExpireRequests(true);
@@ -107,12 +108,8 @@ namespace Emby.Server.Implementations.QuickConnect
if (State != QuickConnectState.Active)
{
- _logger.LogDebug("Refusing quick connect initiation request, current state is {0}", State);
-
- return new QuickConnectResult()
- {
- Error = "Quick connect is not active on this server"
- };
+ _logger.LogDebug("Refusing quick connect initiation request, current state is {State}", State);
+ throw new AuthenticationException("Quick connect is not active on this server");
}
_logger.LogDebug("Got new quick connect request from {friendlyName}", friendlyName);
@@ -200,7 +197,7 @@ namespace Emby.Server.Implementations.QuickConnect
UserId = auth.UserId
});
- _logger.LogInformation("Allowing device {0} to login as user {1} with quick connect code {2}", result.FriendlyName, auth.User.Username, result.Code);
+ _logger.LogInformation("Allowing device {FriendlyName} to login as user {Username} with quick connect code {Code}", result.FriendlyName, auth.User.Username, result.Code);
return true;
}
@@ -216,13 +213,15 @@ namespace Emby.Server.Implementations.QuickConnect
var tokens = raw.Items.Where(x => x.AppName.StartsWith(TokenNamePrefix, StringComparison.CurrentCulture));
+ var removed = 0;
foreach (var token in tokens)
{
_authenticationRepository.Delete(token);
- _logger.LogDebug("Deleted token {0}", token.AccessToken);
+ _logger.LogDebug("Deleted token {AccessToken}", token.AccessToken);
+ removed++;
}
- return tokens.Count();
+ return removed;
}
///
@@ -261,7 +260,7 @@ namespace Emby.Server.Implementations.QuickConnect
if (State == QuickConnectState.Active && DateTime.Now > DateActivated.AddMinutes(Timeout) && !expireAll)
{
_logger.LogDebug("Quick connect time expired, deactivating");
- SetEnabled(QuickConnectState.Available);
+ SetState(QuickConnectState.Available);
expireAll = true;
}
diff --git a/MediaBrowser.Api/QuickConnect/QuickConnectService.cs b/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
index 6298f66e59..7093be9908 100644
--- a/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
+++ b/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
@@ -125,7 +125,7 @@ namespace MediaBrowser.Api.QuickConnect
public object Post(Available request)
{
- _quickConnect.SetEnabled(request.Status);
+ _quickConnect.SetState(request.Status);
return _quickConnect.State;
}
}
diff --git a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
index 10ec9e6cb5..5518e0385d 100644
--- a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
+++ b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
@@ -41,16 +41,16 @@ namespace MediaBrowser.Controller.QuickConnect
void Activate();
///
- /// Changes the status of quick connect.
+ /// Changes the state of quick connect.
///
/// New state to change to.
- void SetEnabled(QuickConnectState newState);
+ void SetState(QuickConnectState newState);
///
/// Initiates a new quick connect request.
///
/// Friendly device name to display in the request UI.
- /// A quick connect result with tokens to proceed or a descriptive error message otherwise.
+ /// A quick connect result with tokens to proceed or throws an exception if not active.
QuickConnectResult TryConnect(string friendlyName);
///
--
cgit v1.2.3
From 31d3b1b83aa356221e8af2f316b58584579207fe Mon Sep 17 00:00:00 2001
From: Matt Montgomery <33811686+ConfusedPolarBear@users.noreply.github.com>
Date: Mon, 27 Jul 2020 15:40:14 -0500
Subject: Cleanup interfaces
---
MediaBrowser.Controller/QuickConnect/IQuickConnect.cs | 10 +++++-----
MediaBrowser.Controller/Session/ISessionManager.cs | 7 ++++++-
2 files changed, 11 insertions(+), 6 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
index 5518e0385d..993637c8aa 100644
--- a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
+++ b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
@@ -13,22 +13,22 @@ namespace MediaBrowser.Controller.QuickConnect
///
/// Gets or sets the length of user facing codes.
///
- public int CodeLength { get; set; }
+ int CodeLength { get; set; }
///
/// Gets or sets the string to prefix internal access tokens with.
///
- public string TokenNamePrefix { get; set; }
+ string TokenNamePrefix { get; set; }
///
/// Gets the current state of quick connect.
///
- public QuickConnectState State { get; }
+ QuickConnectState State { get; }
///
/// Gets or sets the time (in minutes) before quick connect will automatically deactivate.
///
- public int Timeout { get; set; }
+ int Timeout { get; set; }
///
/// Assert that quick connect is currently active and throws an exception if it is not.
@@ -72,7 +72,7 @@ namespace MediaBrowser.Controller.QuickConnect
/// Expire quick connect requests that are over the time limit. If is true, all requests are unconditionally expired.
///
/// If true, all requests will be expired.
- public void ExpireRequests(bool expireAll = false);
+ void ExpireRequests(bool expireAll = false);
///
/// Deletes all quick connect access tokens for the provided user.
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index 23230e41e5..ffa19fb690 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -264,7 +264,12 @@ namespace MediaBrowser.Controller.Session
/// Task{SessionInfo}.
Task AuthenticateNewSession(AuthenticationRequest request);
- public Task AuthenticateQuickConnect(AuthenticationRequest request, string token);
+ ///
+ /// Authenticates a new session with quick connect.
+ ///
+ /// The request.
+ /// Task{SessionInfo}.
+ Task AuthenticateQuickConnect(AuthenticationRequest request, string token);
///
/// Creates the new session.
--
cgit v1.2.3
From a61f6e3308dfc9f84fe2bdfab0194b75c041d2aa Mon Sep 17 00:00:00 2001
From: David
Date: Thu, 13 Aug 2020 15:22:12 +0200
Subject: Fix nuget ci
---
.ci/azure-pipelines-package.yml | 6 +++---
Emby.Naming/Emby.Naming.csproj | 1 +
Jellyfin.Data/Jellyfin.Data.csproj | 8 ++++++++
MediaBrowser.Common/MediaBrowser.Common.csproj | 1 +
.../MediaBrowser.Controller.csproj | 1 +
MediaBrowser.Model/MediaBrowser.Model.csproj | 1 +
bump_version | 23 ++++++++++++++++++++++
7 files changed, 38 insertions(+), 3 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/.ci/azure-pipelines-package.yml b/.ci/azure-pipelines-package.yml
index 003d5baf04..c80ec7b0e0 100644
--- a/.ci/azure-pipelines-package.yml
+++ b/.ci/azure-pipelines-package.yml
@@ -153,11 +153,11 @@ jobs:
vmImage: 'ubuntu-latest'
steps:
- - task: NuGetCommand@2
+ - task: DotNetCoreCLI@2
inputs:
command: 'pack'
- packagesToPack: Jellyfin.Data/Jellyfin.Data.csproj;MediaBrowser.Common/MediaBrowser.Common.csproj;MediaBrowser.Controller/MediaBrowser.Controller.csproj;MediaBrowser.Model/MediaBrowser.Model.csproj;Emby.Naming/Emby.Naming.csproj
- packDestination: '$(Build.ArtifactStagingDirectory)'
+ packagesToPack: 'Jellyfin.Data/Jellyfin.Data.csproj;MediaBrowser.Common/MediaBrowser.Common.csproj;MediaBrowser.Controller/MediaBrowser.Controller.csproj;MediaBrowser.Model/MediaBrowser.Model.csproj;Emby.Naming/Emby.Naming.csproj'
+ versioningScheme: 'off'
- task: NuGetCommand@2
inputs:
diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj
index c017e76c74..410492e671 100644
--- a/Emby.Naming/Emby.Naming.csproj
+++ b/Emby.Naming/Emby.Naming.csproj
@@ -23,6 +23,7 @@
Jellyfin Contributors
Jellyfin.Naming
+ 10.7.0
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
diff --git a/Jellyfin.Data/Jellyfin.Data.csproj b/Jellyfin.Data/Jellyfin.Data.csproj
index 8ce0f3848c..9791983539 100644
--- a/Jellyfin.Data/Jellyfin.Data.csproj
+++ b/Jellyfin.Data/Jellyfin.Data.csproj
@@ -6,6 +6,14 @@
true
+
+ Jellyfin Contributors
+ Jellyfin.Data
+ 10.7.0
+ https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+ https://github.com/jellyfin/jellyfin
+
+
../jellyfin.ruleset
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index 7380f39fda..e7f9a56430 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -8,6 +8,7 @@
Jellyfin Contributors
Jellyfin.Common
+ 10.7.0
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 67f17f7a52..9686b4a726 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -8,6 +8,7 @@
Jellyfin Contributors
Jellyfin.Controller
+ 10.7.0
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 902e29b20b..229a75a462 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -8,6 +8,7 @@
Jellyfin Contributors
Jellyfin.Model
+ 10.7.0
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
diff --git a/bump_version b/bump_version
index 1c943f691d..1db1f44996 100755
--- a/bump_version
+++ b/bump_version
@@ -20,6 +20,12 @@ fi
shared_version_file="./SharedVersion.cs"
build_file="./build.yaml"
+# csproj files for nuget packages
+mediabrowser_common="MediaBrowser.Common/MediaBrowser.Common.csproj"
+jellyfin_data="Jellyfin.Data/Jellyfin.Data.csproj"
+mediabrowser_controller="MediaBrowser.Controller/MediaBrowser.Controller.csproj"
+mediabrowser_model="MediaBrowser.Model/MediaBrowser.Model.csproj"
+emby_naming="Emby.Naming/Emby.Naming.csproj"
new_version="$1"
@@ -45,6 +51,23 @@ echo $old_version
old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' chars
sed -i "s/${old_version_sed}/${new_version}/g" ${build_file}
+# update nuget package version
+for f in ${mediabrowser_common} ${jellyfin_data} ${mediabrowser_controller} ${mediabrowser_model} ${emby_naming}
+do
+ code ${f}
+ echo ${f}
+ # Parse the version from the *.csproj file
+ old_version="$(
+ grep "PackageVersion" ${f} \
+ | awk '{$1=$1};1' \
+ | sed -E 's/([0-9\.]+[-a-z0-9]*)<\/PackageVersion>/\1/'
+ )"
+ echo old nuget version: $old_version
+
+ # Set the nuget version to the specified new_version
+ sed -i "s|${old_version}|${new_version}|g" ${f}
+done
+
if [[ ${new_version} == *"-"* ]]; then
new_version_deb="$( sed 's/-/~/g' <<<"${new_version}" )"
else
--
cgit v1.2.3
From b92fbe4d69975d077737042d13d4fd935bc3e3c7 Mon Sep 17 00:00:00 2001
From: David
Date: Thu, 13 Aug 2020 19:03:24 +0200
Subject: Use VersionPrefix
---
Emby.Naming/Emby.Naming.csproj | 2 +-
Jellyfin.Data/Jellyfin.Data.csproj | 2 +-
MediaBrowser.Common/MediaBrowser.Common.csproj | 2 +-
MediaBrowser.Controller/MediaBrowser.Controller.csproj | 2 +-
MediaBrowser.Model/MediaBrowser.Model.csproj | 2 +-
bump_version | 4 ++--
6 files changed, 7 insertions(+), 7 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj
index 410492e671..14aac1a4ab 100644
--- a/Emby.Naming/Emby.Naming.csproj
+++ b/Emby.Naming/Emby.Naming.csproj
@@ -23,7 +23,7 @@
Jellyfin Contributors
Jellyfin.Naming
- 10.7.0
+ 10.7.0
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
diff --git a/Jellyfin.Data/Jellyfin.Data.csproj b/Jellyfin.Data/Jellyfin.Data.csproj
index 9791983539..cef75f8909 100644
--- a/Jellyfin.Data/Jellyfin.Data.csproj
+++ b/Jellyfin.Data/Jellyfin.Data.csproj
@@ -9,7 +9,7 @@
Jellyfin Contributors
Jellyfin.Data
- 10.7.0
+ 10.7.0
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index e7f9a56430..04100eba45 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -8,7 +8,7 @@
Jellyfin Contributors
Jellyfin.Common
- 10.7.0
+ 10.7.0
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 9686b4a726..6bfe4e403c 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -8,7 +8,7 @@
Jellyfin Contributors
Jellyfin.Controller
- 10.7.0
+ 10.7.0
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 229a75a462..2cb89f77f2 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -8,7 +8,7 @@
Jellyfin Contributors
Jellyfin.Model
- 10.7.0
+ 10.7.0
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
diff --git a/bump_version b/bump_version
index 1db1f44996..226e37eec9 100755
--- a/bump_version
+++ b/bump_version
@@ -58,9 +58,9 @@ do
echo ${f}
# Parse the version from the *.csproj file
old_version="$(
- grep "PackageVersion" ${f} \
+ grep "VersionPrefix" ${f} \
| awk '{$1=$1};1' \
- | sed -E 's/([0-9\.]+[-a-z0-9]*)<\/PackageVersion>/\1/'
+ | sed -E 's/([0-9\.]+[-a-z0-9]*)<\/VersionPrefix>/\1/'
)"
echo old nuget version: $old_version
--
cgit v1.2.3
From e0c6172d23782a84250a345aa73553fc6f624fe5 Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Thu, 13 Aug 2020 16:10:26 -0400
Subject: Add ServiceProvider to IServerApplicationHost
---
MediaBrowser.Controller/IServerApplicationHost.cs | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index abdb0f695d..77da546758 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -16,13 +16,7 @@ namespace MediaBrowser.Controller
{
event EventHandler HasUpdateAvailableChanged;
- ///
- /// Gets the system info.
- ///
- /// SystemInfo.
- Task GetSystemInfo(CancellationToken cancellationToken);
-
- Task GetPublicSystemInfo(CancellationToken cancellationToken);
+ IServiceProvider ServiceProvider { get; }
bool CanLaunchWebBrowser { get; }
@@ -55,6 +49,14 @@ namespace MediaBrowser.Controller
/// The name of the friendly.
string FriendlyName { get; }
+ ///
+ /// Gets the system info.
+ ///
+ /// SystemInfo.
+ Task GetSystemInfo(CancellationToken cancellationToken);
+
+ Task GetPublicSystemInfo(CancellationToken cancellationToken);
+
///
/// Gets all the local IP addresses of this API instance. Each address is validated by sending a 'ping' request
/// to the API that should exist at the address.
--
cgit v1.2.3
From 285af300f50c8380ef04974ab29881cf0e5d600b Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Thu, 13 Aug 2020 20:29:14 -0400
Subject: Create IEventConsumer and IEventManager
---
MediaBrowser.Controller/Events/IEventConsumer.cs | 11 +++++++++++
MediaBrowser.Controller/Events/IEventManager.cs | 20 ++++++++++++++++++++
2 files changed, 31 insertions(+)
create mode 100644 MediaBrowser.Controller/Events/IEventConsumer.cs
create mode 100644 MediaBrowser.Controller/Events/IEventManager.cs
(limited to 'MediaBrowser.Controller')
diff --git a/MediaBrowser.Controller/Events/IEventConsumer.cs b/MediaBrowser.Controller/Events/IEventConsumer.cs
new file mode 100644
index 0000000000..3cefe2f9c8
--- /dev/null
+++ b/MediaBrowser.Controller/Events/IEventConsumer.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.Events
+{
+ public interface IEventConsumer
+ where T : EventArgs
+ {
+ Task OnEvent(T eventArgs);
+ }
+}
diff --git a/MediaBrowser.Controller/Events/IEventManager.cs b/MediaBrowser.Controller/Events/IEventManager.cs
new file mode 100644
index 0000000000..794a8709e5
--- /dev/null
+++ b/MediaBrowser.Controller/Events/IEventManager.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.Events
+{
+ ///
+ /// An interface that handles eventing.
+ ///
+ public interface IEventManager
+ {
+ ///
+ /// Publishes an event.
+ ///
+ /// The event arguments.
+ /// The type of event.
+ /// A task representing the publishing of the event.
+ Task Publish(T eventArgs)
+ where T : EventArgs;
+ }
+}
--
cgit v1.2.3
From 57e2f7248d5ae96063119246efa059d88a856208 Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Thu, 13 Aug 2020 20:30:43 -0400
Subject: Remove unused class and rename file.
---
.../Subtitles/SubtitleDownloadEventArgs.cs | 27 ----------------------
.../Subtitles/SubtitleDownloadFailureEventArgs.cs | 14 +++++++++++
2 files changed, 14 insertions(+), 27 deletions(-)
delete mode 100644 MediaBrowser.Controller/Subtitles/SubtitleDownloadEventArgs.cs
create mode 100644 MediaBrowser.Controller/Subtitles/SubtitleDownloadFailureEventArgs.cs
(limited to 'MediaBrowser.Controller')
diff --git a/MediaBrowser.Controller/Subtitles/SubtitleDownloadEventArgs.cs b/MediaBrowser.Controller/Subtitles/SubtitleDownloadEventArgs.cs
deleted file mode 100644
index 5703aea17c..0000000000
--- a/MediaBrowser.Controller/Subtitles/SubtitleDownloadEventArgs.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using MediaBrowser.Controller.Entities;
-
-namespace MediaBrowser.Controller.Subtitles
-{
- public class SubtitleDownloadEventArgs
- {
- public BaseItem Item { get; set; }
-
- public string Format { get; set; }
-
- public string Language { get; set; }
-
- public bool IsForced { get; set; }
-
- public string Provider { get; set; }
- }
-
- public class SubtitleDownloadFailureEventArgs
- {
- public BaseItem Item { get; set; }
-
- public string Provider { get; set; }
-
- public Exception Exception { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Subtitles/SubtitleDownloadFailureEventArgs.cs b/MediaBrowser.Controller/Subtitles/SubtitleDownloadFailureEventArgs.cs
new file mode 100644
index 0000000000..7687bf5b6d
--- /dev/null
+++ b/MediaBrowser.Controller/Subtitles/SubtitleDownloadFailureEventArgs.cs
@@ -0,0 +1,14 @@
+using System;
+using MediaBrowser.Controller.Entities;
+
+namespace MediaBrowser.Controller.Subtitles
+{
+ public class SubtitleDownloadFailureEventArgs : EventArgs
+ {
+ public BaseItem Item { get; set; }
+
+ public string Provider { get; set; }
+
+ public Exception Exception { get; set; }
+ }
+}
--
cgit v1.2.3
From 3e5fe04427d60261bb87df2e124ce7b2e066b88e Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Thu, 13 Aug 2020 20:31:26 -0400
Subject: Migrate ActivityLogEntryPoint.OnPlaybackStart to IEventConsumer
---
.../Activity/ActivityLogEntryPoint.cs | 53 -----------
.../Consumers/Session/PlaybackStartLogger.cs | 105 +++++++++++++++++++++
.../Library/PlaybackStartEventArgs.cs | 6 ++
3 files changed, 111 insertions(+), 53 deletions(-)
create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs
create mode 100644 MediaBrowser.Controller/Library/PlaybackStartEventArgs.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index 84bec92014..53b3a6293b 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
@@ -83,7 +82,6 @@ namespace Emby.Server.Implementations.Activity
_sessionManager.AuthenticationFailed += OnAuthenticationFailed;
_sessionManager.AuthenticationSucceeded += OnAuthenticationSucceeded;
_sessionManager.SessionEnded += OnSessionEnded;
- _sessionManager.PlaybackStart += OnPlaybackStart;
_sessionManager.PlaybackStopped += OnPlaybackStopped;
_subManager.SubtitleDownloadFailure += OnSubtitleDownloadFailure;
@@ -161,41 +159,6 @@ namespace Emby.Server.Implementations.Activity
.ConfigureAwait(false);
}
- private async void OnPlaybackStart(object sender, PlaybackProgressEventArgs e)
- {
- var item = e.MediaInfo;
-
- if (item == null)
- {
- _logger.LogWarning("PlaybackStart reported with null media info.");
- return;
- }
-
- if (e.Item != null && e.Item.IsThemeMedia)
- {
- // Don't report theme song or local trailer playback
- return;
- }
-
- if (e.Users.Count == 0)
- {
- return;
- }
-
- var user = e.Users.First();
-
- await CreateLogEntry(new ActivityLog(
- string.Format(
- CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("UserStartedPlayingItemWithValues"),
- user.Username,
- GetItemName(item),
- e.DeviceName),
- GetPlaybackNotificationType(item.MediaType),
- user.Id))
- .ConfigureAwait(false);
- }
-
private static string GetItemName(BaseItemDto item)
{
var name = item.Name;
@@ -213,21 +176,6 @@ namespace Emby.Server.Implementations.Activity
return name;
}
- private static string GetPlaybackNotificationType(string mediaType)
- {
- if (string.Equals(mediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase))
- {
- return NotificationType.AudioPlayback.ToString();
- }
-
- if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
- {
- return NotificationType.VideoPlayback.ToString();
- }
-
- return null;
- }
-
private static string GetPlaybackStoppedNotificationType(string mediaType)
{
if (string.Equals(mediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase))
@@ -494,7 +442,6 @@ namespace Emby.Server.Implementations.Activity
_sessionManager.AuthenticationSucceeded -= OnAuthenticationSucceeded;
_sessionManager.SessionEnded -= OnSessionEnded;
- _sessionManager.PlaybackStart -= OnPlaybackStart;
_sessionManager.PlaybackStopped -= OnPlaybackStopped;
_subManager.SubtitleDownloadFailure -= OnSubtitleDownloadFailure;
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs
new file mode 100644
index 0000000000..c48683ea38
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
+using Jellyfin.Data.Entities;
+using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Activity;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Globalization;
+using MediaBrowser.Model.Notifications;
+using Microsoft.Extensions.Logging;
+
+namespace Jellyfin.Server.Implementations.Events.Consumers.Session
+{
+ ///
+ /// Creates an entry in the activity log whenever a user starts playback.
+ ///
+ public class PlaybackStartLogger : IEventConsumer
+ {
+ private readonly ILogger _logger;
+ private readonly ILocalizationManager _localizationManager;
+ private readonly IActivityManager _activityManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The logger.
+ /// The localization manager.
+ /// The activity manager.
+ public PlaybackStartLogger(ILogger logger, ILocalizationManager localizationManager, IActivityManager activityManager)
+ {
+ _logger = logger;
+ _localizationManager = localizationManager;
+ _activityManager = activityManager;
+ }
+
+ ///
+ public async Task OnEvent(PlaybackStartEventArgs eventArgs)
+ {
+ if (eventArgs.MediaInfo == null)
+ {
+ _logger.LogWarning("PlaybackStart reported with null media info.");
+ return;
+ }
+
+ if (eventArgs.Item != null && eventArgs.Item.IsThemeMedia)
+ {
+ // Don't report theme song or local trailer playback
+ return;
+ }
+
+ if (eventArgs.Users.Count == 0)
+ {
+ return;
+ }
+
+ var user = eventArgs.Users.First();
+
+ await _activityManager.CreateAsync(new ActivityLog(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ _localizationManager.GetLocalizedString("UserStartedPlayingItemWithValues"),
+ user.Username,
+ GetItemName(eventArgs.MediaInfo),
+ eventArgs.DeviceName),
+ GetPlaybackNotificationType(eventArgs.MediaInfo.MediaType),
+ user.Id))
+ .ConfigureAwait(false);
+ }
+
+ private static string GetItemName(BaseItemDto item)
+ {
+ var name = item.Name;
+
+ if (!string.IsNullOrEmpty(item.SeriesName))
+ {
+ name = item.SeriesName + " - " + name;
+ }
+
+ if (item.Artists != null && item.Artists.Count > 0)
+ {
+ name = item.Artists[0] + " - " + name;
+ }
+
+ return name;
+ }
+
+ private static string GetPlaybackNotificationType(string mediaType)
+ {
+ if (string.Equals(mediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase))
+ {
+ return NotificationType.AudioPlayback.ToString();
+ }
+
+ if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
+ {
+ return NotificationType.VideoPlayback.ToString();
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Library/PlaybackStartEventArgs.cs b/MediaBrowser.Controller/Library/PlaybackStartEventArgs.cs
new file mode 100644
index 0000000000..3aa9c28954
--- /dev/null
+++ b/MediaBrowser.Controller/Library/PlaybackStartEventArgs.cs
@@ -0,0 +1,6 @@
+namespace MediaBrowser.Controller.Library
+{
+ public class PlaybackStartEventArgs : PlaybackProgressEventArgs
+ {
+ }
+}
--
cgit v1.2.3
From ca1f15af19e26f8f610a7b56cd6b15a6a308a58f Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Thu, 13 Aug 2020 20:48:28 -0400
Subject: Move GenericEventArgs to Jellyfin.Data.Events
---
Emby.Dlna/PlayTo/PlayToController.cs | 2 +-
Emby.Dlna/PlayTo/PlayToManager.cs | 2 +-
Emby.Dlna/Ssdp/DeviceDiscovery.cs | 2 +-
Emby.Notifications/NotificationEntryPoint.cs | 2 +-
.../Activity/ActivityLogEntryPoint.cs | 2 +-
.../Configuration/ServerConfigurationManager.cs | 2 +-
.../Devices/DeviceManager.cs | 2 +-
.../EntryPoints/ExternalPortForwarding.cs | 2 +-
.../EntryPoints/LibraryChangedNotifier.cs | 2 +-
.../EntryPoints/RecordingNotifier.cs | 9 ++++----
.../EntryPoints/ServerEventNotifier.cs | 2 +-
.../HttpServer/HttpListenerHost.cs | 2 +-
.../LiveTv/EmbyTV/EmbyTV.cs | 2 +-
.../LiveTv/EmbyTV/TimerManager.cs | 2 +-
.../LiveTv/LiveTvManager.cs | 2 +-
.../ScheduledTasks/ScheduledTaskWorker.cs | 3 +--
.../ScheduledTasks/TaskManager.cs | 2 +-
.../Session/SessionManager.cs | 2 +-
.../Session/SessionWebSocketListener.cs | 2 +-
.../ActivityLogWebSocketListener.cs | 2 +-
.../ScheduledTasksWebSocketListener.cs | 2 +-
Jellyfin.Data/Events/GenericEventArgs.cs | 26 ++++++++++++++++++++++
.../Activity/ActivityManager.cs | 2 +-
.../Users/DeviceAccessEntryPoint.cs | 2 +-
.../Users/UserManager.cs | 2 +-
MediaBrowser.Controller/Devices/IDeviceManager.cs | 2 +-
MediaBrowser.Controller/Library/IUserManager.cs | 2 +-
MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 2 +-
MediaBrowser.Controller/Net/IHttpServer.cs | 2 +-
.../Providers/IProviderManager.cs | 2 +-
MediaBrowser.Controller/Session/ISessionManager.cs | 2 +-
MediaBrowser.Model/Activity/IActivityManager.cs | 2 +-
MediaBrowser.Model/Dlna/IDeviceDiscovery.cs | 2 +-
MediaBrowser.Model/Events/GenericEventArgs.cs | 26 ----------------------
MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs | 2 +-
MediaBrowser.Model/Tasks/ITaskManager.cs | 2 +-
MediaBrowser.Providers/Manager/ProviderManager.cs | 2 +-
37 files changed, 65 insertions(+), 65 deletions(-)
create mode 100644 Jellyfin.Data/Events/GenericEventArgs.cs
delete mode 100644 MediaBrowser.Model/Events/GenericEventArgs.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs
index 92a93d4349..1f0da8d753 100644
--- a/Emby.Dlna/PlayTo/PlayToController.cs
+++ b/Emby.Dlna/PlayTo/PlayToController.cs
@@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks;
using Emby.Dlna.Didl;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
@@ -18,7 +19,6 @@ using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Session;
using Microsoft.AspNetCore.WebUtilities;
diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs
index 512589e4d7..00edff1a65 100644
--- a/Emby.Dlna/PlayTo/PlayToManager.cs
+++ b/Emby.Dlna/PlayTo/PlayToManager.cs
@@ -6,6 +6,7 @@ using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
@@ -16,7 +17,6 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dlna;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Session;
using Microsoft.Extensions.Logging;
diff --git a/Emby.Dlna/Ssdp/DeviceDiscovery.cs b/Emby.Dlna/Ssdp/DeviceDiscovery.cs
index 7daac96d1d..18ee188fd0 100644
--- a/Emby.Dlna/Ssdp/DeviceDiscovery.cs
+++ b/Emby.Dlna/Ssdp/DeviceDiscovery.cs
@@ -3,9 +3,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Dlna;
-using MediaBrowser.Model.Events;
using Rssdp;
using Rssdp.Infrastructure;
diff --git a/Emby.Notifications/NotificationEntryPoint.cs b/Emby.Notifications/NotificationEntryPoint.cs
index b923fd26ce..ded22d26cc 100644
--- a/Emby.Notifications/NotificationEntryPoint.cs
+++ b/Emby.Notifications/NotificationEntryPoint.cs
@@ -4,6 +4,7 @@ using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
@@ -13,7 +14,6 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Notifications;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Activity;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Notifications;
using Microsoft.Extensions.Logging;
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index 39b6361b7c..75a7916869 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -2,6 +2,7 @@ using System;
using System.Globalization;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Updates;
using MediaBrowser.Controller.Authentication;
@@ -9,7 +10,6 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Activity;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Notifications;
using MediaBrowser.Model.Updates;
diff --git a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
index a15295fca4..f05a30a897 100644
--- a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
+++ b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
@@ -2,11 +2,11 @@ using System;
using System.Globalization;
using System.IO;
using Emby.Server.Implementations.AppBase;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
using Microsoft.Extensions.Logging;
diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs
index cc4b407f5c..f98c694c46 100644
--- a/Emby.Server.Implementations/Devices/DeviceManager.cs
+++ b/Emby.Server.Implementations/Devices/DeviceManager.cs
@@ -7,13 +7,13 @@ using System.IO;
using System.Linq;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Security;
using MediaBrowser.Model.Devices;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
index 9fce49425e..2e8cc76d23 100644
--- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
@@ -7,11 +7,11 @@ using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Dlna;
-using MediaBrowser.Model.Events;
using Microsoft.Extensions.Logging;
using Mono.Nat;
diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
index 1deef7f720..c9d21d9638 100644
--- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
@@ -7,6 +7,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
@@ -15,7 +16,6 @@ using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Events;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.EntryPoints
diff --git a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs
index 6327359106..44d2580d68 100644
--- a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Plugins;
@@ -43,22 +44,22 @@ namespace Emby.Server.Implementations.EntryPoints
return Task.CompletedTask;
}
- private async void OnLiveTvManagerSeriesTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs e)
+ private async void OnLiveTvManagerSeriesTimerCreated(object sender, GenericEventArgs e)
{
await SendMessage("SeriesTimerCreated", e.Argument).ConfigureAwait(false);
}
- private async void OnLiveTvManagerTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs e)
+ private async void OnLiveTvManagerTimerCreated(object sender, GenericEventArgs e)
{
await SendMessage("TimerCreated", e.Argument).ConfigureAwait(false);
}
- private async void OnLiveTvManagerSeriesTimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs e)
+ private async void OnLiveTvManagerSeriesTimerCancelled(object sender, GenericEventArgs e)
{
await SendMessage("SeriesTimerCancelled", e.Argument).ConfigureAwait(false);
}
- private async void OnLiveTvManagerTimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs e)
+ private async void OnLiveTvManagerTimerCancelled(object sender, GenericEventArgs e)
{
await SendMessage("TimerCancelled", e.Argument).ConfigureAwait(false);
}
diff --git a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
index 826d4d8dc3..d023591e19 100644
--- a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
@@ -4,13 +4,13 @@ using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Updates;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Updates;
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index dafdd5b7bf..fe39bb4b29 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -12,13 +12,13 @@ using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.Services;
using Emby.Server.Implementations.SocketSharp;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 80e09f0a34..09c52d95bb 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -13,6 +13,7 @@ using System.Threading.Tasks;
using System.Xml;
using Emby.Server.Implementations.Library;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
@@ -29,7 +30,6 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.MediaInfo;
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs
index 285a59a249..dd479b7d1b 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs
@@ -5,8 +5,8 @@ using System.Collections.Concurrent;
using System.Globalization;
using System.Linq;
using System.Threading;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Serialization;
using Microsoft.Extensions.Logging;
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 1b075d86a8..ef505c78e6 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Emby.Server.Implementations.Library;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Progress;
@@ -24,7 +25,6 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.LiveTv;
diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
index 8a900f42cd..36faae65d2 100644
--- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
@@ -6,11 +6,10 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Progress;
-using MediaBrowser.Model.Events;
-using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
index 81096026bd..fff52ff88a 100644
--- a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
@@ -5,8 +5,8 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Configuration;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs
index 862a7296ca..6e41244639 100644
--- a/Emby.Server.Implementations/Session/SessionManager.cs
+++ b/Emby.Server.Implementations/Session/SessionManager.cs
@@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller;
@@ -24,7 +25,6 @@ using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Devices;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Library;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Session;
diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
index 8bebd37dc8..1da7a64730 100644
--- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
+++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs
@@ -4,9 +4,9 @@ using System.Linq;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
diff --git a/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs b/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs
index 6395b8d62f..849b3b7095 100644
--- a/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs
+++ b/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs
@@ -1,8 +1,8 @@
using System;
using System.Threading.Tasks;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Activity;
-using MediaBrowser.Model.Events;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Api.WebSocketListeners
diff --git a/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs b/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs
index 12f815ff75..8a966c1376 100644
--- a/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs
+++ b/Jellyfin.Api/WebSocketListeners/ScheduledTasksWebSocketListener.cs
@@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
diff --git a/Jellyfin.Data/Events/GenericEventArgs.cs b/Jellyfin.Data/Events/GenericEventArgs.cs
new file mode 100644
index 0000000000..7b9a5111ee
--- /dev/null
+++ b/Jellyfin.Data/Events/GenericEventArgs.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace Jellyfin.Data.Events
+{
+ ///
+ /// Provides a generic EventArgs subclass that can hold any kind of object.
+ ///
+ /// The type of this event.
+ public class GenericEventArgs : EventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The argument.
+ public GenericEventArgs(T arg)
+ {
+ Argument = arg;
+ }
+
+ ///
+ /// Gets the argument.
+ ///
+ /// The argument.
+ public T Argument { get; }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Activity/ActivityManager.cs b/Jellyfin.Server.Implementations/Activity/ActivityManager.cs
index 2deefbe819..09f2611e4e 100644
--- a/Jellyfin.Server.Implementations/Activity/ActivityManager.cs
+++ b/Jellyfin.Server.Implementations/Activity/ActivityManager.cs
@@ -2,8 +2,8 @@ using System;
using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Model.Activity;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Querying;
namespace Jellyfin.Server.Implementations.Activity
diff --git a/Jellyfin.Server.Implementations/Users/DeviceAccessEntryPoint.cs b/Jellyfin.Server.Implementations/Users/DeviceAccessEntryPoint.cs
index 140853e529..1fb89c4a63 100644
--- a/Jellyfin.Server.Implementations/Users/DeviceAccessEntryPoint.cs
+++ b/Jellyfin.Server.Implementations/Users/DeviceAccessEntryPoint.cs
@@ -4,12 +4,12 @@
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session;
-using MediaBrowser.Model.Events;
namespace Jellyfin.Server.Implementations.Users
{
diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs
index 11402ee055..267c1c1033 100644
--- a/Jellyfin.Server.Implementations/Users/UserManager.cs
+++ b/Jellyfin.Server.Implementations/Users/UserManager.cs
@@ -10,6 +10,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Events;
using MediaBrowser.Common;
using MediaBrowser.Common.Cryptography;
using MediaBrowser.Common.Extensions;
@@ -21,7 +22,6 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Cryptography;
using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Users;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
diff --git a/MediaBrowser.Controller/Devices/IDeviceManager.cs b/MediaBrowser.Controller/Devices/IDeviceManager.cs
index 7d279230b5..a038d84d81 100644
--- a/MediaBrowser.Controller/Devices/IDeviceManager.cs
+++ b/MediaBrowser.Controller/Devices/IDeviceManager.cs
@@ -1,7 +1,7 @@
using System;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Model.Devices;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Session;
diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs
index 6685861a9a..c8d8375b38 100644
--- a/MediaBrowser.Controller/Library/IUserManager.cs
+++ b/MediaBrowser.Controller/Library/IUserManager.cs
@@ -2,9 +2,9 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Users;
namespace MediaBrowser.Controller.Library
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
index f619b011bf..d6f629a1b9 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
@@ -3,11 +3,11 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Querying;
diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs
index e6609fae38..b04ebda8ca 100644
--- a/MediaBrowser.Controller/Net/IHttpServer.cs
+++ b/MediaBrowser.Controller/Net/IHttpServer.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
-using MediaBrowser.Model.Events;
+using Jellyfin.Data.Events;
using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs
index 955db0278c..ef744ee3c1 100644
--- a/MediaBrowser.Controller/Providers/IProviderManager.cs
+++ b/MediaBrowser.Controller/Providers/IProviderManager.cs
@@ -4,12 +4,12 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Providers;
namespace MediaBrowser.Controller.Providers
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index e54f210506..d461a9281a 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -2,11 +2,11 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Events;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Security;
using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Session;
using MediaBrowser.Model.SyncPlay;
diff --git a/MediaBrowser.Model/Activity/IActivityManager.cs b/MediaBrowser.Model/Activity/IActivityManager.cs
index 9dab5e77b7..2362f7e927 100644
--- a/MediaBrowser.Model/Activity/IActivityManager.cs
+++ b/MediaBrowser.Model/Activity/IActivityManager.cs
@@ -4,7 +4,7 @@ using System;
using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
-using MediaBrowser.Model.Events;
+using Jellyfin.Data.Events;
using MediaBrowser.Model.Querying;
namespace MediaBrowser.Model.Activity
diff --git a/MediaBrowser.Model/Dlna/IDeviceDiscovery.cs b/MediaBrowser.Model/Dlna/IDeviceDiscovery.cs
index 76c9a4b044..05209e53d0 100644
--- a/MediaBrowser.Model/Dlna/IDeviceDiscovery.cs
+++ b/MediaBrowser.Model/Dlna/IDeviceDiscovery.cs
@@ -1,7 +1,7 @@
#pragma warning disable CS1591
using System;
-using MediaBrowser.Model.Events;
+using Jellyfin.Data.Events;
namespace MediaBrowser.Model.Dlna
{
diff --git a/MediaBrowser.Model/Events/GenericEventArgs.cs b/MediaBrowser.Model/Events/GenericEventArgs.cs
deleted file mode 100644
index 347ea2281e..0000000000
--- a/MediaBrowser.Model/Events/GenericEventArgs.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-
-namespace MediaBrowser.Model.Events
-{
- ///
- /// Provides a generic EventArgs subclass that can hold any kind of object.
- ///
- /// The type of this event.
- public class GenericEventArgs : EventArgs
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The argument.
- public GenericEventArgs(T arg)
- {
- Argument = arg;
- }
-
- ///
- /// Gets the argument.
- ///
- /// The argument.
- public T Argument { get; }
- }
-}
diff --git a/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs b/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs
index b08acba2c6..2f05e08c51 100644
--- a/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs
+++ b/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs
@@ -1,6 +1,6 @@
#nullable disable
using System;
-using MediaBrowser.Model.Events;
+using Jellyfin.Data.Events;
namespace MediaBrowser.Model.Tasks
{
diff --git a/MediaBrowser.Model/Tasks/ITaskManager.cs b/MediaBrowser.Model/Tasks/ITaskManager.cs
index 363773ff74..02b29074e3 100644
--- a/MediaBrowser.Model/Tasks/ITaskManager.cs
+++ b/MediaBrowser.Model/Tasks/ITaskManager.cs
@@ -3,7 +3,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
-using MediaBrowser.Model.Events;
+using Jellyfin.Data.Events;
namespace MediaBrowser.Model.Tasks
{
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index bbd7166e68..9f63c60465 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -9,6 +9,7 @@ using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Events;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Progress;
using MediaBrowser.Controller;
@@ -22,7 +23,6 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Providers;
--
cgit v1.2.3
From b7f21971f43d6d9f956ff0aade31625d3995858a Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Fri, 14 Aug 2020 15:21:17 -0400
Subject: Migrate ActivityLogEntryPoint.OnPluginInstalled to IEventConsumer
---
.../Activity/ActivityLogEntryPoint.cs | 19 --------
.../Consumers/Updates/PluginInstalledLogger.cs | 50 ++++++++++++++++++++++
.../Events/Updates/PluginInstalledEventArgs.cs | 19 ++++++++
3 files changed, 69 insertions(+), 19 deletions(-)
create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstalledLogger.cs
create mode 100644 MediaBrowser.Controller/Events/Updates/PluginInstalledEventArgs.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index 40fc7d8907..600c1d3ea2 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -45,7 +45,6 @@ namespace Emby.Server.Implementations.Activity
///
public Task RunAsync()
{
- _installationManager.PluginInstalled += OnPluginInstalled;
_installationManager.PluginUninstalled += OnPluginUninstalled;
_installationManager.PluginUpdated += OnPluginUpdated;
_installationManager.PackageInstallationFailed += OnPackageInstallationFailed;
@@ -136,23 +135,6 @@ namespace Emby.Server.Implementations.Activity
.ConfigureAwait(false);
}
- private async void OnPluginInstalled(object sender, InstallationInfo e)
- {
- await CreateLogEntry(new ActivityLog(
- string.Format(
- CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("PluginInstalledWithName"),
- e.Name),
- NotificationType.PluginInstalled.ToString(),
- Guid.Empty)
- {
- ShortOverview = string.Format(
- CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("VersionNumber"),
- e.Version)
- }).ConfigureAwait(false);
- }
-
private async void OnPackageInstallationFailed(object sender, InstallationFailedEventArgs e)
{
var installationInfo = e.InstallationInfo;
@@ -179,7 +161,6 @@ namespace Emby.Server.Implementations.Activity
///
public void Dispose()
{
- _installationManager.PluginInstalled -= OnPluginInstalled;
_installationManager.PluginUninstalled -= OnPluginUninstalled;
_installationManager.PluginUpdated -= OnPluginUpdated;
_installationManager.PackageInstallationFailed -= OnPackageInstallationFailed;
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstalledLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstalledLogger.cs
new file mode 100644
index 0000000000..8837172dbe
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstalledLogger.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Globalization;
+using System.Threading.Tasks;
+using Jellyfin.Data.Entities;
+using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Events.Updates;
+using MediaBrowser.Model.Activity;
+using MediaBrowser.Model.Globalization;
+using MediaBrowser.Model.Notifications;
+
+namespace Jellyfin.Server.Implementations.Events.Consumers.Updates
+{
+ ///
+ /// Creates an entry in the activity log when a plugin is installed.
+ ///
+ public class PluginInstalledLogger : IEventConsumer
+ {
+ private readonly ILocalizationManager _localizationManager;
+ private readonly IActivityManager _activityManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The localization manager.
+ /// The activity manager.
+ public PluginInstalledLogger(ILocalizationManager localizationManager, IActivityManager activityManager)
+ {
+ _localizationManager = localizationManager;
+ _activityManager = activityManager;
+ }
+
+ ///
+ public async Task OnEvent(PluginInstalledEventArgs eventArgs)
+ {
+ await _activityManager.CreateAsync(new ActivityLog(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ _localizationManager.GetLocalizedString("PluginInstalledWithName"),
+ eventArgs.Argument.Name),
+ NotificationType.PluginInstalled.ToString(),
+ Guid.Empty)
+ {
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localizationManager.GetLocalizedString("VersionNumber"),
+ eventArgs.Argument.Version)
+ }).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Events/Updates/PluginInstalledEventArgs.cs b/MediaBrowser.Controller/Events/Updates/PluginInstalledEventArgs.cs
new file mode 100644
index 0000000000..dfadc9f61f
--- /dev/null
+++ b/MediaBrowser.Controller/Events/Updates/PluginInstalledEventArgs.cs
@@ -0,0 +1,19 @@
+using Jellyfin.Data.Events;
+using MediaBrowser.Model.Updates;
+
+namespace MediaBrowser.Controller.Events.Updates
+{
+ ///
+ /// An event that occurs when a plugin is installed.
+ ///
+ public class PluginInstalledEventArgs : GenericEventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The installation info.
+ public PluginInstalledEventArgs(InstallationInfo arg) : base(arg)
+ {
+ }
+ }
+}
--
cgit v1.2.3
From 0da7c0568d61e834b8b11693ed79eee2855d4ae6 Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Fri, 14 Aug 2020 15:22:12 -0400
Subject: Migrate ActivityLogEntryPoint.OnPluginUninstalled to IEventConsumer
---
.../Activity/ActivityLogEntryPoint.cs | 15 --------
.../Consumers/Updates/PluginUninstalledLogger.cs | 45 ++++++++++++++++++++++
.../Events/Updates/PluginUninstalledEventArgs.cs | 19 +++++++++
3 files changed, 64 insertions(+), 15 deletions(-)
create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs
create mode 100644 MediaBrowser.Controller/Events/Updates/PluginUninstalledEventArgs.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index 600c1d3ea2..ba0bf9ea2e 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -2,7 +2,6 @@ using System;
using System.Globalization;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
-using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Updates;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
@@ -45,7 +44,6 @@ namespace Emby.Server.Implementations.Activity
///
public Task RunAsync()
{
- _installationManager.PluginUninstalled += OnPluginUninstalled;
_installationManager.PluginUpdated += OnPluginUpdated;
_installationManager.PackageInstallationFailed += OnPackageInstallationFailed;
@@ -123,18 +121,6 @@ namespace Emby.Server.Implementations.Activity
}).ConfigureAwait(false);
}
- private async void OnPluginUninstalled(object sender, IPlugin e)
- {
- await CreateLogEntry(new ActivityLog(
- string.Format(
- CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("PluginUninstalledWithName"),
- e.Name),
- NotificationType.PluginUninstalled.ToString(),
- Guid.Empty))
- .ConfigureAwait(false);
- }
-
private async void OnPackageInstallationFailed(object sender, InstallationFailedEventArgs e)
{
var installationInfo = e.InstallationInfo;
@@ -161,7 +147,6 @@ namespace Emby.Server.Implementations.Activity
///
public void Dispose()
{
- _installationManager.PluginUninstalled -= OnPluginUninstalled;
_installationManager.PluginUpdated -= OnPluginUpdated;
_installationManager.PackageInstallationFailed -= OnPackageInstallationFailed;
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs
new file mode 100644
index 0000000000..91a30069e8
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Globalization;
+using System.Threading.Tasks;
+using Jellyfin.Data.Entities;
+using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Events.Updates;
+using MediaBrowser.Model.Activity;
+using MediaBrowser.Model.Globalization;
+using MediaBrowser.Model.Notifications;
+
+namespace Jellyfin.Server.Implementations.Events.Consumers.Updates
+{
+ ///
+ /// Creates an entry in the activity log when a plugin is uninstalled.
+ ///
+ public class PluginUninstalledLogger : IEventConsumer
+ {
+ private readonly ILocalizationManager _localizationManager;
+ private readonly IActivityManager _activityManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The localization manager.
+ /// The activity manager.
+ public PluginUninstalledLogger(ILocalizationManager localizationManager, IActivityManager activityManager)
+ {
+ _localizationManager = localizationManager;
+ _activityManager = activityManager;
+ }
+
+ ///
+ public async Task OnEvent(PluginUninstalledEventArgs e)
+ {
+ await _activityManager.CreateAsync(new ActivityLog(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ _localizationManager.GetLocalizedString("PluginUninstalledWithName"),
+ e.Argument.Name),
+ NotificationType.PluginUninstalled.ToString(),
+ Guid.Empty))
+ .ConfigureAwait(false);
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Events/Updates/PluginUninstalledEventArgs.cs b/MediaBrowser.Controller/Events/Updates/PluginUninstalledEventArgs.cs
new file mode 100644
index 0000000000..7510b62b88
--- /dev/null
+++ b/MediaBrowser.Controller/Events/Updates/PluginUninstalledEventArgs.cs
@@ -0,0 +1,19 @@
+using Jellyfin.Data.Events;
+using MediaBrowser.Common.Plugins;
+
+namespace MediaBrowser.Controller.Events.Updates
+{
+ ///
+ /// An event that occurs when a plugin is uninstalled.
+ ///
+ public class PluginUninstalledEventArgs : GenericEventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The plugin.
+ public PluginUninstalledEventArgs(IPlugin arg) : base(arg)
+ {
+ }
+ }
+}
--
cgit v1.2.3
From e9244448809cb4251b341832c8fdfecde5f169ab Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Fri, 14 Aug 2020 15:50:17 -0400
Subject: Migrate ActivityLogEntryPoint.OnPluginUpdated to IEventConsumer
---
.../Activity/ActivityLogEntryPoint.cs | 21 ---------
.../Consumers/Updates/PluginUpdatedLogger.cs | 51 ++++++++++++++++++++++
.../Events/Updates/PluginUpdatedEventArgs.cs | 19 ++++++++
3 files changed, 70 insertions(+), 21 deletions(-)
create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUpdatedLogger.cs
create mode 100644 MediaBrowser.Controller/Events/Updates/PluginUpdatedEventArgs.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index ba0bf9ea2e..ee058fd468 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -8,7 +8,6 @@ using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Notifications;
-using MediaBrowser.Model.Updates;
namespace Emby.Server.Implementations.Activity
{
@@ -44,7 +43,6 @@ namespace Emby.Server.Implementations.Activity
///
public Task RunAsync()
{
- _installationManager.PluginUpdated += OnPluginUpdated;
_installationManager.PackageInstallationFailed += OnPackageInstallationFailed;
_sessionManager.SessionStarted += OnSessionStarted;
@@ -103,24 +101,6 @@ namespace Emby.Server.Implementations.Activity
}).ConfigureAwait(false);
}
- private async void OnPluginUpdated(object sender, InstallationInfo e)
- {
- await CreateLogEntry(new ActivityLog(
- string.Format(
- CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("PluginUpdatedWithName"),
- e.Name),
- NotificationType.PluginUpdateInstalled.ToString(),
- Guid.Empty)
- {
- ShortOverview = string.Format(
- CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("VersionNumber"),
- e.Version),
- Overview = e.Changelog
- }).ConfigureAwait(false);
- }
-
private async void OnPackageInstallationFailed(object sender, InstallationFailedEventArgs e)
{
var installationInfo = e.InstallationInfo;
@@ -147,7 +127,6 @@ namespace Emby.Server.Implementations.Activity
///
public void Dispose()
{
- _installationManager.PluginUpdated -= OnPluginUpdated;
_installationManager.PackageInstallationFailed -= OnPackageInstallationFailed;
_sessionManager.SessionStarted -= OnSessionStarted;
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUpdatedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUpdatedLogger.cs
new file mode 100644
index 0000000000..9ce16f774f
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUpdatedLogger.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Globalization;
+using System.Threading.Tasks;
+using Jellyfin.Data.Entities;
+using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Events.Updates;
+using MediaBrowser.Model.Activity;
+using MediaBrowser.Model.Globalization;
+using MediaBrowser.Model.Notifications;
+
+namespace Jellyfin.Server.Implementations.Events.Consumers.Updates
+{
+ ///
+ /// Creates an entry in the activity log when a plugin is updated.
+ ///
+ public class PluginUpdatedLogger : IEventConsumer
+ {
+ private readonly ILocalizationManager _localizationManager;
+ private readonly IActivityManager _activityManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The localization manager.
+ /// The activity manager.
+ public PluginUpdatedLogger(ILocalizationManager localizationManager, IActivityManager activityManager)
+ {
+ _localizationManager = localizationManager;
+ _activityManager = activityManager;
+ }
+
+ ///
+ public async Task OnEvent(PluginUpdatedEventArgs eventArgs)
+ {
+ await _activityManager.CreateAsync(new ActivityLog(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ _localizationManager.GetLocalizedString("PluginUpdatedWithName"),
+ eventArgs.Argument.Name),
+ NotificationType.PluginUpdateInstalled.ToString(),
+ Guid.Empty)
+ {
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localizationManager.GetLocalizedString("VersionNumber"),
+ eventArgs.Argument.Version),
+ Overview = eventArgs.Argument.Changelog
+ }).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Events/Updates/PluginUpdatedEventArgs.cs b/MediaBrowser.Controller/Events/Updates/PluginUpdatedEventArgs.cs
new file mode 100644
index 0000000000..661ca066a8
--- /dev/null
+++ b/MediaBrowser.Controller/Events/Updates/PluginUpdatedEventArgs.cs
@@ -0,0 +1,19 @@
+using Jellyfin.Data.Events;
+using MediaBrowser.Model.Updates;
+
+namespace MediaBrowser.Controller.Events.Updates
+{
+ ///
+ /// An event that occurs when a plugin is updated.
+ ///
+ public class PluginUpdatedEventArgs : GenericEventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The installation info.
+ public PluginUpdatedEventArgs(InstallationInfo arg) : base(arg)
+ {
+ }
+ }
+}
--
cgit v1.2.3
From ca3a8bdb98aeb5d112a4d2a456ebcc445dc5fd12 Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Sat, 15 Aug 2020 02:02:58 -0400
Subject: Migrate ActivityLogEntryPoint.OnSessionStarted to IEventConsumer
---
.../Activity/ActivityLogEntryPoint.cs | 27 -----------
.../Consumers/Session/SessionStartedLogger.cs | 54 ++++++++++++++++++++++
.../Events/Session/SessionStartedEventArgs.cs | 19 ++++++++
3 files changed, 73 insertions(+), 27 deletions(-)
create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/Session/SessionStartedLogger.cs
create mode 100644 MediaBrowser.Controller/Events/Session/SessionStartedEventArgs.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index 00a14fb0bd..d863acd0b4 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -36,7 +36,6 @@ namespace Emby.Server.Implementations.Activity
///
public Task RunAsync()
{
- _sessionManager.SessionStarted += OnSessionStarted;
_sessionManager.SessionEnded += OnSessionEnded;
return Task.CompletedTask;
@@ -67,38 +66,12 @@ namespace Emby.Server.Implementations.Activity
}).ConfigureAwait(false);
}
- private async void OnSessionStarted(object sender, SessionEventArgs e)
- {
- var session = e.SessionInfo;
-
- if (string.IsNullOrEmpty(session.UserName))
- {
- return;
- }
-
- await CreateLogEntry(new ActivityLog(
- string.Format(
- CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("UserOnlineFromDevice"),
- session.UserName,
- session.DeviceName),
- "SessionStarted",
- session.UserId)
- {
- ShortOverview = string.Format(
- CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("LabelIpAddressValue"),
- session.RemoteEndPoint)
- }).ConfigureAwait(false);
- }
-
private async Task CreateLogEntry(ActivityLog entry)
=> await _activityManager.CreateAsync(entry).ConfigureAwait(false);
///
public void Dispose()
{
- _sessionManager.SessionStarted -= OnSessionStarted;
_sessionManager.SessionEnded -= OnSessionEnded;
}
}
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionStartedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionStartedLogger.cs
new file mode 100644
index 0000000000..6a0f29b09f
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionStartedLogger.cs
@@ -0,0 +1,54 @@
+using System.Globalization;
+using System.Threading.Tasks;
+using Jellyfin.Data.Entities;
+using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Events.Session;
+using MediaBrowser.Model.Activity;
+using MediaBrowser.Model.Globalization;
+
+namespace Jellyfin.Server.Implementations.Events.Consumers.Session
+{
+ ///
+ /// Creates an entry in the activity log when a session is started.
+ ///
+ public class SessionStartedLogger : IEventConsumer
+ {
+ private readonly ILocalizationManager _localizationManager;
+ private readonly IActivityManager _activityManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The localization manager.
+ /// The activity manager.
+ public SessionStartedLogger(ILocalizationManager localizationManager, IActivityManager activityManager)
+ {
+ _localizationManager = localizationManager;
+ _activityManager = activityManager;
+ }
+
+ ///
+ public async Task OnEvent(SessionStartedEventArgs eventArgs)
+ {
+ if (string.IsNullOrEmpty(eventArgs.Argument.UserName))
+ {
+ return;
+ }
+
+ await _activityManager.CreateAsync(new ActivityLog(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ _localizationManager.GetLocalizedString("UserOnlineFromDevice"),
+ eventArgs.Argument.UserName,
+ eventArgs.Argument.DeviceName),
+ "SessionStarted",
+ eventArgs.Argument.UserId)
+ {
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localizationManager.GetLocalizedString("LabelIpAddressValue"),
+ eventArgs.Argument.RemoteEndPoint)
+ }).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Events/Session/SessionStartedEventArgs.cs b/MediaBrowser.Controller/Events/Session/SessionStartedEventArgs.cs
new file mode 100644
index 0000000000..aab19cc46a
--- /dev/null
+++ b/MediaBrowser.Controller/Events/Session/SessionStartedEventArgs.cs
@@ -0,0 +1,19 @@
+using Jellyfin.Data.Events;
+using MediaBrowser.Controller.Session;
+
+namespace MediaBrowser.Controller.Events.Session
+{
+ ///
+ /// An event that fires when a session is started.
+ ///
+ public class SessionStartedEventArgs : GenericEventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The session info.
+ public SessionStartedEventArgs(SessionInfo arg) : base(arg)
+ {
+ }
+ }
+}
--
cgit v1.2.3
From 8570cfdba652eb61e2746ea9de6cb9c8bb23eaf5 Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Sat, 15 Aug 2020 02:07:28 -0400
Subject: Migrate ActivityLogEntryPoint.OnSessionEnded to IEventConsumer
---
.../Activity/ActivityLogEntryPoint.cs | 78 ----------------------
.../Consumers/Session/SessionManagerEndedLogger.cs | 54 +++++++++++++++
.../Events/Session/SessionEndedEventArgs.cs | 19 ++++++
3 files changed, 73 insertions(+), 78 deletions(-)
delete mode 100644 Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/Session/SessionManagerEndedLogger.cs
create mode 100644 MediaBrowser.Controller/Events/Session/SessionEndedEventArgs.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
deleted file mode 100644
index d863acd0b4..0000000000
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using System.Globalization;
-using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
-using MediaBrowser.Controller.Plugins;
-using MediaBrowser.Controller.Session;
-using MediaBrowser.Model.Activity;
-using MediaBrowser.Model.Globalization;
-
-namespace Emby.Server.Implementations.Activity
-{
- ///
- /// Entry point for the activity logger.
- ///
- public sealed class ActivityLogEntryPoint : IServerEntryPoint
- {
- private readonly ISessionManager _sessionManager;
- private readonly IActivityManager _activityManager;
- private readonly ILocalizationManager _localization;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The session manager.
- /// The activity manager.
- /// The localization manager.
- public ActivityLogEntryPoint(
- ISessionManager sessionManager,
- IActivityManager activityManager,
- ILocalizationManager localization)
- {
- _sessionManager = sessionManager;
- _activityManager = activityManager;
- _localization = localization;
- }
-
- ///
- public Task RunAsync()
- {
- _sessionManager.SessionEnded += OnSessionEnded;
-
- return Task.CompletedTask;
- }
-
- private async void OnSessionEnded(object sender, SessionEventArgs e)
- {
- var session = e.SessionInfo;
-
- if (string.IsNullOrEmpty(session.UserName))
- {
- return;
- }
-
- await CreateLogEntry(new ActivityLog(
- string.Format(
- CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("UserOfflineFromDevice"),
- session.UserName,
- session.DeviceName),
- "SessionEnded",
- session.UserId)
- {
- ShortOverview = string.Format(
- CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("LabelIpAddressValue"),
- session.RemoteEndPoint),
- }).ConfigureAwait(false);
- }
-
- private async Task CreateLogEntry(ActivityLog entry)
- => await _activityManager.CreateAsync(entry).ConfigureAwait(false);
-
- ///
- public void Dispose()
- {
- _sessionManager.SessionEnded -= OnSessionEnded;
- }
- }
-}
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionManagerEndedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionManagerEndedLogger.cs
new file mode 100644
index 0000000000..1162fe89b7
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionManagerEndedLogger.cs
@@ -0,0 +1,54 @@
+using System.Globalization;
+using System.Threading.Tasks;
+using Jellyfin.Data.Entities;
+using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Events.Session;
+using MediaBrowser.Model.Activity;
+using MediaBrowser.Model.Globalization;
+
+namespace Jellyfin.Server.Implementations.Events.Consumers.Session
+{
+ ///
+ /// Creates an entry in the activity log whenever a session ends.
+ ///
+ public class SessionManagerEndedLogger : IEventConsumer
+ {
+ private readonly ILocalizationManager _localizationManager;
+ private readonly IActivityManager _activityManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The localization manager.
+ /// The activity manager.
+ public SessionManagerEndedLogger(ILocalizationManager localizationManager, IActivityManager activityManager)
+ {
+ _localizationManager = localizationManager;
+ _activityManager = activityManager;
+ }
+
+ ///
+ public async Task OnEvent(SessionEndedEventArgs eventArgs)
+ {
+ if (string.IsNullOrEmpty(eventArgs.Argument.UserName))
+ {
+ return;
+ }
+
+ await _activityManager.CreateAsync(new ActivityLog(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ _localizationManager.GetLocalizedString("UserOfflineFromDevice"),
+ eventArgs.Argument.UserName,
+ eventArgs.Argument.DeviceName),
+ "SessionEnded",
+ eventArgs.Argument.UserId)
+ {
+ ShortOverview = string.Format(
+ CultureInfo.InvariantCulture,
+ _localizationManager.GetLocalizedString("LabelIpAddressValue"),
+ eventArgs.Argument.RemoteEndPoint),
+ }).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Events/Session/SessionEndedEventArgs.cs b/MediaBrowser.Controller/Events/Session/SessionEndedEventArgs.cs
new file mode 100644
index 0000000000..46d7e5a17a
--- /dev/null
+++ b/MediaBrowser.Controller/Events/Session/SessionEndedEventArgs.cs
@@ -0,0 +1,19 @@
+using Jellyfin.Data.Events;
+using MediaBrowser.Controller.Session;
+
+namespace MediaBrowser.Controller.Events.Session
+{
+ ///
+ /// An event that fires when a session is ended.
+ ///
+ public class SessionEndedEventArgs : GenericEventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The session info.
+ public SessionEndedEventArgs(SessionInfo arg) : base(arg)
+ {
+ }
+ }
+}
--
cgit v1.2.3
From 816c80525a64fcac441f44f1d508028070fdc21d Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Sat, 15 Aug 2020 15:55:15 -0400
Subject: Use IEventManager in UserManager
---
.../Users/UserManager.cs | 29 +++++++++-------------
MediaBrowser.Controller/Events/IEventManager.cs | 10 +++++++-
MediaBrowser.Controller/Library/IUserManager.cs | 20 ---------------
3 files changed, 21 insertions(+), 38 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs
index 267c1c1033..3e8edeb442 100644
--- a/Jellyfin.Server.Implementations/Users/UserManager.cs
+++ b/Jellyfin.Server.Implementations/Users/UserManager.cs
@@ -11,12 +11,14 @@ using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Data.Events;
+using Jellyfin.Data.Events.Users;
using MediaBrowser.Common;
using MediaBrowser.Common.Cryptography;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Drawing;
+using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Configuration;
@@ -34,6 +36,7 @@ namespace Jellyfin.Server.Implementations.Users
public class UserManager : IUserManager
{
private readonly JellyfinDbProvider _dbProvider;
+ private readonly IEventManager _eventManager;
private readonly ICryptoProvider _cryptoProvider;
private readonly INetworkManager _networkManager;
private readonly IApplicationHost _appHost;
@@ -49,6 +52,7 @@ namespace Jellyfin.Server.Implementations.Users
/// Initializes a new instance of the class.
///
/// The database provider.
+ /// The event manager.
/// The cryptography provider.
/// The network manager.
/// The application host.
@@ -56,6 +60,7 @@ namespace Jellyfin.Server.Implementations.Users
/// The logger.
public UserManager(
JellyfinDbProvider dbProvider,
+ IEventManager eventManager,
ICryptoProvider cryptoProvider,
INetworkManager networkManager,
IApplicationHost appHost,
@@ -63,6 +68,7 @@ namespace Jellyfin.Server.Implementations.Users
ILogger logger)
{
_dbProvider = dbProvider;
+ _eventManager = eventManager;
_cryptoProvider = cryptoProvider;
_networkManager = networkManager;
_appHost = appHost;
@@ -77,21 +83,9 @@ namespace Jellyfin.Server.Implementations.Users
_defaultPasswordResetProvider = _passwordResetProviders.OfType().First();
}
- ///
- public event EventHandler>? OnUserPasswordChanged;
-
///
public event EventHandler>? OnUserUpdated;
- ///
- public event EventHandler>? OnUserCreated;
-
- ///
- public event EventHandler>? OnUserDeleted;
-
- ///
- public event EventHandler>? OnUserLockedOut;
-
///
public IEnumerable Users
{
@@ -234,7 +228,7 @@ namespace Jellyfin.Server.Implementations.Users
dbContext.Users.Add(newUser);
await dbContext.SaveChangesAsync().ConfigureAwait(false);
- OnUserCreated?.Invoke(this, new GenericEventArgs(newUser));
+ await _eventManager.PublishAsync(new UserCreatedEventArgs(newUser)).ConfigureAwait(false);
return newUser;
}
@@ -293,7 +287,8 @@ namespace Jellyfin.Server.Implementations.Users
dbContext.RemoveRange(user.AccessSchedules);
dbContext.Users.Remove(user);
dbContext.SaveChanges();
- OnUserDeleted?.Invoke(this, new GenericEventArgs(user));
+
+ _eventManager.Publish(new UserDeletedEventArgs(user));
}
///
@@ -319,7 +314,7 @@ namespace Jellyfin.Server.Implementations.Users
await GetAuthenticationProvider(user).ChangePassword(user, newPassword).ConfigureAwait(false);
await UpdateUserAsync(user).ConfigureAwait(false);
- OnUserPasswordChanged?.Invoke(this, new GenericEventArgs(user));
+ await _eventManager.PublishAsync(new UserPasswordChangedEventArgs(user)).ConfigureAwait(false);
}
///
@@ -338,7 +333,7 @@ namespace Jellyfin.Server.Implementations.Users
user.EasyPassword = newPasswordSha1;
UpdateUser(user);
- OnUserPasswordChanged?.Invoke(this, new GenericEventArgs(user));
+ _eventManager.Publish(new UserPasswordChangedEventArgs(user));
}
///
@@ -901,7 +896,7 @@ namespace Jellyfin.Server.Implementations.Users
if (maxInvalidLogins.HasValue && user.InvalidLoginAttemptCount >= maxInvalidLogins)
{
user.SetPermission(PermissionKind.IsDisabled, true);
- OnUserLockedOut?.Invoke(this, new GenericEventArgs(user));
+ await _eventManager.PublishAsync(new UserLockedOutEventArgs(user)).ConfigureAwait(false);
_logger.LogWarning(
"Disabling user {Username} due to {Attempts} unsuccessful login attempts.",
user.Username,
diff --git a/MediaBrowser.Controller/Events/IEventManager.cs b/MediaBrowser.Controller/Events/IEventManager.cs
index 794a8709e5..a1f40b3a6d 100644
--- a/MediaBrowser.Controller/Events/IEventManager.cs
+++ b/MediaBrowser.Controller/Events/IEventManager.cs
@@ -11,10 +11,18 @@ namespace MediaBrowser.Controller.Events
///
/// Publishes an event.
///
+ /// the event arguments.
+ /// The type of event.
+ void Publish(T eventArgs)
+ where T : EventArgs;
+
+ ///
+ /// Publishes an event asynchronously.
+ ///
/// The event arguments.
/// The type of event.
/// A task representing the publishing of the event.
- Task Publish(T eventArgs)
+ Task PublishAsync(T eventArgs)
where T : EventArgs;
}
}
diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs
index c8d8375b38..96a41920ab 100644
--- a/MediaBrowser.Controller/Library/IUserManager.cs
+++ b/MediaBrowser.Controller/Library/IUserManager.cs
@@ -19,26 +19,6 @@ namespace MediaBrowser.Controller.Library
///
event EventHandler> OnUserUpdated;
- ///
- /// Occurs when a user is created.
- ///
- event EventHandler> OnUserCreated;
-
- ///
- /// Occurs when a user is deleted.
- ///
- event EventHandler> OnUserDeleted;
-
- ///
- /// Occurs when a user's password is changed.
- ///
- event EventHandler> OnUserPasswordChanged;
-
- ///
- /// Occurs when a user is locked out.
- ///
- event EventHandler> OnUserLockedOut;
-
///
/// Gets the users.
///
--
cgit v1.2.3
From b7ceb40d6efe083653734e6417b2f5e48b522872 Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Sat, 15 Aug 2020 18:57:46 -0400
Subject: Migrate ServerEventNotifier.OnPackageInstalling to IEventConsumer
---
.../EntryPoints/ServerEventNotifier.cs | 7 -----
.../Consumers/Updates/PluginInstallingNotifier.cs | 31 ++++++++++++++++++++++
.../Events/Updates/PluginInstallingEventArgs.cs | 19 +++++++++++++
3 files changed, 50 insertions(+), 7 deletions(-)
create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallingNotifier.cs
create mode 100644 MediaBrowser.Controller/Events/Updates/PluginInstallingEventArgs.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
index 3d58b91e1d..068872420b 100644
--- a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
@@ -38,7 +38,6 @@ namespace Emby.Server.Implementations.EntryPoints
public Task RunAsync()
{
_installationManager.PluginUninstalled += OnPluginUninstalled;
- _installationManager.PackageInstalling += OnPackageInstalling;
_installationManager.PackageInstallationCancelled += OnPackageInstallationCancelled;
_installationManager.PackageInstallationCompleted += OnPackageInstallationCompleted;
_installationManager.PackageInstallationFailed += OnPackageInstallationFailed;
@@ -46,11 +45,6 @@ namespace Emby.Server.Implementations.EntryPoints
return Task.CompletedTask;
}
- private async void OnPackageInstalling(object sender, InstallationInfo e)
- {
- await SendMessageToAdminSessions("PackageInstalling", e).ConfigureAwait(false);
- }
-
private async void OnPackageInstallationCancelled(object sender, InstallationInfo e)
{
await SendMessageToAdminSessions("PackageInstallationCancelled", e).ConfigureAwait(false);
@@ -103,7 +97,6 @@ namespace Emby.Server.Implementations.EntryPoints
if (dispose)
{
_installationManager.PluginUninstalled -= OnPluginUninstalled;
- _installationManager.PackageInstalling -= OnPackageInstalling;
_installationManager.PackageInstallationCancelled -= OnPackageInstallationCancelled;
_installationManager.PackageInstallationCompleted -= OnPackageInstallationCompleted;
_installationManager.PackageInstallationFailed -= OnPackageInstallationFailed;
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallingNotifier.cs b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallingNotifier.cs
new file mode 100644
index 0000000000..f691d11a7d
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallingNotifier.cs
@@ -0,0 +1,31 @@
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Events.Updates;
+using MediaBrowser.Controller.Session;
+
+namespace Jellyfin.Server.Implementations.Events.Consumers.Updates
+{
+ ///
+ /// Notifies admin users when a plugin is being installed.
+ ///
+ public class PluginInstallingNotifier : IEventConsumer
+ {
+ private readonly ISessionManager _sessionManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The session manager.
+ public PluginInstallingNotifier(ISessionManager sessionManager)
+ {
+ _sessionManager = sessionManager;
+ }
+
+ ///
+ public async Task OnEvent(PluginInstallingEventArgs eventArgs)
+ {
+ await _sessionManager.SendMessageToAdminSessions("PackageInstalling", eventArgs.Argument, CancellationToken.None).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Events/Updates/PluginInstallingEventArgs.cs b/MediaBrowser.Controller/Events/Updates/PluginInstallingEventArgs.cs
new file mode 100644
index 0000000000..045a600272
--- /dev/null
+++ b/MediaBrowser.Controller/Events/Updates/PluginInstallingEventArgs.cs
@@ -0,0 +1,19 @@
+using Jellyfin.Data.Events;
+using MediaBrowser.Model.Updates;
+
+namespace MediaBrowser.Controller.Events.Updates
+{
+ ///
+ /// An event that occurs when a plugin is installing.
+ ///
+ public class PluginInstallingEventArgs : GenericEventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The installation info.
+ public PluginInstallingEventArgs(InstallationInfo arg) : base(arg)
+ {
+ }
+ }
+}
--
cgit v1.2.3
From a40064a146da17a49582f7ef1ad754a497725ccc Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Sat, 15 Aug 2020 23:20:41 -0400
Subject: Migrate ServerEventNotifier.OnPackageInstallationCancelled to
IEventConsumer
---
.../EntryPoints/ServerEventNotifier.cs | 79 ----------------------
.../Updates/PluginInstallationCancelledNotifier.cs | 31 +++++++++
.../PluginInstallationCancelledEventArgs.cs | 19 ++++++
3 files changed, 50 insertions(+), 79 deletions(-)
delete mode 100644 Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
create mode 100644 Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallationCancelledNotifier.cs
create mode 100644 MediaBrowser.Controller/Events/Updates/PluginInstallationCancelledEventArgs.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
deleted file mode 100644
index 1fbb9f3037..0000000000
--- a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Updates;
-using MediaBrowser.Controller.Plugins;
-using MediaBrowser.Controller.Session;
-using MediaBrowser.Model.Updates;
-
-namespace Emby.Server.Implementations.EntryPoints
-{
- ///
- /// Class WebSocketEvents.
- ///
- public class ServerEventNotifier : IServerEntryPoint
- {
- ///
- /// The installation manager.
- ///
- private readonly IInstallationManager _installationManager;
-
- private readonly ISessionManager _sessionManager;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The installation manager.
- /// The session manager.
- public ServerEventNotifier(
- IInstallationManager installationManager,
- ISessionManager sessionManager)
- {
- _installationManager = installationManager;
- _sessionManager = sessionManager;
- }
-
- ///
- public Task RunAsync()
- {
- _installationManager.PackageInstallationCancelled += OnPackageInstallationCancelled;
-
- return Task.CompletedTask;
- }
-
- private async void OnPackageInstallationCancelled(object sender, InstallationInfo e)
- {
- await SendMessageToAdminSessions("PackageInstallationCancelled", e).ConfigureAwait(false);
- }
-
- private async Task SendMessageToAdminSessions(string name, T data)
- {
- try
- {
- await _sessionManager.SendMessageToAdminSessions(name, data, CancellationToken.None).ConfigureAwait(false);
- }
- catch (Exception)
- {
- }
- }
-
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- ///
- /// Releases unmanaged and - optionally - managed resources.
- ///
- /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
- protected virtual void Dispose(bool dispose)
- {
- if (dispose)
- {
- _installationManager.PackageInstallationCancelled -= OnPackageInstallationCancelled;
- }
- }
- }
-}
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallationCancelledNotifier.cs b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallationCancelledNotifier.cs
new file mode 100644
index 0000000000..1c600683a9
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallationCancelledNotifier.cs
@@ -0,0 +1,31 @@
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Events;
+using MediaBrowser.Controller.Events.Updates;
+using MediaBrowser.Controller.Session;
+
+namespace Jellyfin.Server.Implementations.Events.Consumers.Updates
+{
+ ///
+ /// Notifies admin users when a plugin installation is cancelled.
+ ///
+ public class PluginInstallationCancelledNotifier : IEventConsumer
+ {
+ private readonly ISessionManager _sessionManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The session manager.
+ public PluginInstallationCancelledNotifier(ISessionManager sessionManager)
+ {
+ _sessionManager = sessionManager;
+ }
+
+ ///
+ public async Task OnEvent(PluginInstallationCancelledEventArgs eventArgs)
+ {
+ await _sessionManager.SendMessageToAdminSessions("PackageInstallationCancelled", eventArgs.Argument, CancellationToken.None).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Events/Updates/PluginInstallationCancelledEventArgs.cs b/MediaBrowser.Controller/Events/Updates/PluginInstallationCancelledEventArgs.cs
new file mode 100644
index 0000000000..b06046c05a
--- /dev/null
+++ b/MediaBrowser.Controller/Events/Updates/PluginInstallationCancelledEventArgs.cs
@@ -0,0 +1,19 @@
+using Jellyfin.Data.Events;
+using MediaBrowser.Model.Updates;
+
+namespace MediaBrowser.Controller.Events.Updates
+{
+ ///
+ /// An event that occurs when a plugin installation is cancelled.
+ ///
+ public class PluginInstallationCancelledEventArgs : GenericEventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The installation info.
+ public PluginInstallationCancelledEventArgs(InstallationInfo arg) : base(arg)
+ {
+ }
+ }
+}
--
cgit v1.2.3
From 035d29fb357006c29ffb40e0a53c1e999237cdd1 Mon Sep 17 00:00:00 2001
From: Matt Montgomery <33811686+ConfusedPolarBear@users.noreply.github.com>
Date: Thu, 13 Aug 2020 15:35:04 -0500
Subject: Migrate to new API standard
---
.../QuickConnect/QuickConnectManager.cs | 5 +-
Jellyfin.Api/Controllers/QuickConnectController.cs | 160 +++++++++++++++++++++
Jellyfin.Api/Controllers/UserController.cs | 41 ++++++
Jellyfin.Api/Models/UserDtos/QuickConnectDto.cs | 13 ++
.../QuickConnect/QuickConnectService.cs | 132 -----------------
.../QuickConnect/IQuickConnect.cs | 5 +-
MediaBrowser.Controller/Session/ISessionManager.cs | 1 +
7 files changed, 219 insertions(+), 138 deletions(-)
create mode 100644 Jellyfin.Api/Controllers/QuickConnectController.cs
create mode 100644 Jellyfin.Api/Models/UserDtos/QuickConnectDto.cs
delete mode 100644 MediaBrowser.Api/QuickConnect/QuickConnectService.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
index 23e94afd72..949c3b5058 100644
--- a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
+++ b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Concurrent;
-using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
@@ -10,7 +9,7 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.QuickConnect;
using MediaBrowser.Controller.Security;
using MediaBrowser.Model.QuickConnect;
-using MediaBrowser.Model.Services;
+using Microsoft.AspNetCore.Http;
using MediaBrowser.Common;
using Microsoft.Extensions.Logging;
using MediaBrowser.Common.Extensions;
@@ -163,7 +162,7 @@ namespace Emby.Server.Implementations.QuickConnect
}
///
- public bool AuthorizeRequest(IRequest request, string code)
+ public bool AuthorizeRequest(HttpRequest request, string code)
{
ExpireRequests();
AssertActive();
diff --git a/Jellyfin.Api/Controllers/QuickConnectController.cs b/Jellyfin.Api/Controllers/QuickConnectController.cs
new file mode 100644
index 0000000000..d45ea058d2
--- /dev/null
+++ b/Jellyfin.Api/Controllers/QuickConnectController.cs
@@ -0,0 +1,160 @@
+using System.ComponentModel.DataAnnotations;
+using Jellyfin.Api.Constants;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.QuickConnect;
+using MediaBrowser.Model.QuickConnect;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Jellyfin.Api.Controllers
+{
+ ///
+ /// Quick connect controller.
+ ///
+ public class QuickConnectController : BaseJellyfinApiController
+ {
+ private readonly IQuickConnect _quickConnect;
+ private readonly IUserManager _userManager;
+ private readonly IAuthorizationContext _authContext;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Instance of the interface.
+ /// Instance of the interface.
+ /// Instance of the interface.
+ public QuickConnectController(
+ IQuickConnect quickConnect,
+ IUserManager userManager,
+ IAuthorizationContext authContext)
+ {
+ _quickConnect = quickConnect;
+ _userManager = userManager;
+ _authContext = authContext;
+ }
+
+ ///
+ /// Gets the current quick connect state.
+ ///
+ /// Quick connect state returned.
+ /// The current .
+ [HttpGet("Status")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult GetStatus()
+ {
+ _quickConnect.ExpireRequests();
+ return Ok(_quickConnect.State);
+ }
+
+ ///
+ /// Initiate a new quick connect request.
+ ///
+ /// Device friendly name.
+ /// Quick connect request successfully created.
+ /// Quick connect is not active on this server.
+ /// A with a secret and code for future use or an error message.
+ [HttpGet("Initiate")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult Initiate([FromQuery] string? friendlyName)
+ {
+ return Ok(_quickConnect.TryConnect(friendlyName));
+ }
+
+ ///
+ /// Attempts to retrieve authentication information.
+ ///
+ /// Secret previously returned from the Initiate endpoint.
+ /// Quick connect result returned.
+ /// Unknown quick connect secret.
+ /// An updated .
+ [HttpGet("Connect")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ public ActionResult Connect([FromQuery] string? secret)
+ {
+ try
+ {
+ var result = _quickConnect.CheckRequestStatus(secret);
+ return Ok(result);
+ }
+ catch (ResourceNotFoundException)
+ {
+ return NotFound("Unknown secret");
+ }
+ }
+
+ ///
+ /// Temporarily activates quick connect for five minutes.
+ ///
+ /// Quick connect has been temporarily activated.
+ /// Quick connect is unavailable on this server.
+ /// An on success.
+ [HttpPost("Activate")]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public ActionResult Activate()
+ {
+ if (_quickConnect.State == QuickConnectState.Unavailable)
+ {
+ return Forbid("Quick connect is unavailable");
+ }
+
+ _quickConnect.Activate();
+ return NoContent();
+ }
+
+ ///
+ /// Enables or disables quick connect.
+ ///
+ /// New .
+ /// Quick connect state set successfully.
+ /// An on success.
+ [HttpPost("Available")]
+ [Authorize(Policy = Policies.RequiresElevation)]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ public ActionResult Available([FromQuery] QuickConnectState? status)
+ {
+ _quickConnect.SetState(status ?? QuickConnectState.Available);
+ return NoContent();
+ }
+
+ ///
+ /// Authorizes a pending quick connect request.
+ ///
+ /// Quick connect code to authorize.
+ /// Quick connect result authorized successfully.
+ /// Missing quick connect code.
+ /// Boolean indicating if the authorization was successful.
+ [HttpPost("Authorize")]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ public ActionResult Authorize([FromQuery, Required] string? code)
+ {
+ if (code == null)
+ {
+ return BadRequest("Missing code");
+ }
+
+ return Ok(_quickConnect.AuthorizeRequest(Request, code));
+ }
+
+ ///
+ /// Deauthorize all quick connect devices for the current user.
+ ///
+ /// All quick connect devices were deleted.
+ /// The number of devices that were deleted.
+ [HttpPost("Deauthorize")]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult Deauthorize()
+ {
+ var userId = _authContext.GetAuthorizationInfo(Request).UserId;
+ return _quickConnect.DeleteAllDevices(userId);
+ }
+ }
+}
diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs
index 2723125224..131fffb7ac 100644
--- a/Jellyfin.Api/Controllers/UserController.cs
+++ b/Jellyfin.Api/Controllers/UserController.cs
@@ -216,6 +216,47 @@ namespace Jellyfin.Api.Controllers
}
}
+ ///
+ /// Authenticates a user with quick connect.
+ ///
+ /// The request.
+ /// User authenticated.
+ /// Missing token.
+ /// A containing an with information about the new session.
+ [HttpPost("AuthenticateWithQuickConnect")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public async Task> AuthenticateWithQuickConnect([FromBody, Required] QuickConnectDto request)
+ {
+ if (request.Token == null)
+ {
+ return BadRequest("Access token is required.");
+ }
+
+ var auth = _authContext.GetAuthorizationInfo(Request);
+
+ try
+ {
+ var authRequest = new AuthenticationRequest
+ {
+ App = auth.Client,
+ AppVersion = auth.Version,
+ DeviceId = auth.DeviceId,
+ DeviceName = auth.Device,
+ };
+
+ var result = await _sessionManager.AuthenticateQuickConnect(
+ authRequest,
+ request.Token).ConfigureAwait(false);
+
+ return result;
+ }
+ catch (SecurityException e)
+ {
+ // rethrow adding IP address to message
+ throw new SecurityException($"[{HttpContext.Connection.RemoteIpAddress}] {e.Message}", e);
+ }
+ }
+
///
/// Updates a user's password.
///
diff --git a/Jellyfin.Api/Models/UserDtos/QuickConnectDto.cs b/Jellyfin.Api/Models/UserDtos/QuickConnectDto.cs
new file mode 100644
index 0000000000..8f53d5f37f
--- /dev/null
+++ b/Jellyfin.Api/Models/UserDtos/QuickConnectDto.cs
@@ -0,0 +1,13 @@
+namespace Jellyfin.Api.Models.UserDtos
+{
+ ///
+ /// The quick connect request body.
+ ///
+ public class QuickConnectDto
+ {
+ ///
+ /// Gets or sets the quick connect token.
+ ///
+ public string? Token { get; set; }
+ }
+}
diff --git a/MediaBrowser.Api/QuickConnect/QuickConnectService.cs b/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
deleted file mode 100644
index 7093be9908..0000000000
--- a/MediaBrowser.Api/QuickConnect/QuickConnectService.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-using System;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Controller.QuickConnect;
-using MediaBrowser.Model.QuickConnect;
-using MediaBrowser.Model.Services;
-using Microsoft.Extensions.Logging;
-
-namespace MediaBrowser.Api.QuickConnect
-{
- [Route("/QuickConnect/Initiate", "GET", Summary = "Requests a new quick connect code")]
- public class Initiate : IReturn
- {
- [ApiMember(Name = "FriendlyName", Description = "Device friendly name", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string FriendlyName { get; set; }
- }
-
- [Route("/QuickConnect/Connect", "GET", Summary = "Attempts to retrieve authentication information")]
- public class Connect : IReturn
- {
- [ApiMember(Name = "Secret", Description = "Quick connect secret", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string Secret { get; set; }
- }
-
- [Route("/QuickConnect/Authorize", "POST", Summary = "Authorizes a pending quick connect request")]
- [Authenticated]
- public class Authorize : IReturn
- {
- [ApiMember(Name = "Code", Description = "Quick connect identifying code", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string Code { get; set; }
- }
-
- [Route("/QuickConnect/Deauthorize", "POST", Summary = "Deletes all quick connect authorization tokens for the current user")]
- [Authenticated]
- public class Deauthorize : IReturn
- {
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public Guid UserId { get; set; }
- }
-
- [Route("/QuickConnect/Status", "GET", Summary = "Gets the current quick connect state")]
- public class QuickConnectStatus : IReturn
- {
-
- }
-
- [Route("/QuickConnect/Available", "POST", Summary = "Enables or disables quick connect")]
- [Authenticated(Roles = "Admin")]
- public class Available : IReturn
- {
- [ApiMember(Name = "Status", Description = "New quick connect status", IsRequired = false, DataType = "QuickConnectState", ParameterType = "query", Verb = "GET")]
- public QuickConnectState Status { get; set; }
- }
-
- [Route("/QuickConnect/Activate", "POST", Summary = "Temporarily activates quick connect for the time period defined in the server configuration")]
- [Authenticated]
- public class Activate : IReturn
- {
-
- }
-
- public class QuickConnectService : BaseApiService
- {
- private IQuickConnect _quickConnect;
- private IUserManager _userManager;
- private IAuthorizationContext _authContext;
-
- public QuickConnectService(
- ILogger logger,
- IServerConfigurationManager serverConfigurationManager,
- IHttpResultFactory httpResultFactory,
- IUserManager userManager,
- IAuthorizationContext authContext,
- IQuickConnect quickConnect)
- : base(logger, serverConfigurationManager, httpResultFactory)
- {
- _userManager = userManager;
- _quickConnect = quickConnect;
- _authContext = authContext;
- }
-
- public object Get(Initiate request)
- {
- return _quickConnect.TryConnect(request.FriendlyName);
- }
-
- public object Get(Connect request)
- {
- return _quickConnect.CheckRequestStatus(request.Secret);
- }
-
- public object Get(QuickConnectStatus request)
- {
- _quickConnect.ExpireRequests();
- return _quickConnect.State;
- }
-
- public object Post(Deauthorize request)
- {
- AssertCanUpdateUser(_authContext, _userManager, request.UserId, true);
-
- return _quickConnect.DeleteAllDevices(request.UserId);
- }
-
- public object Post(Authorize request)
- {
- return _quickConnect.AuthorizeRequest(Request, request.Code);
- }
-
- public object Post(Activate request)
- {
- if (_quickConnect.State == QuickConnectState.Unavailable)
- {
- return false;
- }
-
- string name = _authContext.GetAuthorizationInfo(Request).User.Username;
-
- Logger.LogInformation("{name} temporarily activated quick connect", name);
- _quickConnect.Activate();
-
- return true;
- }
-
- public object Post(Available request)
- {
- _quickConnect.SetState(request.Status);
- return _quickConnect.State;
- }
- }
-}
diff --git a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
index 993637c8aa..fd7e973f67 100644
--- a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
+++ b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
@@ -1,7 +1,6 @@
using System;
-using System.Collections.Generic;
using MediaBrowser.Model.QuickConnect;
-using MediaBrowser.Model.Services;
+using Microsoft.AspNetCore.Http;
namespace MediaBrowser.Controller.QuickConnect
{
@@ -66,7 +65,7 @@ namespace MediaBrowser.Controller.QuickConnect
/// HTTP request object.
/// Identifying code for the request.
/// A boolean indicating if the authorization completed successfully.
- bool AuthorizeRequest(IRequest request, string code);
+ bool AuthorizeRequest(HttpRequest request, string code);
///
/// Expire quick connect requests that are over the time limit. If is true, all requests are unconditionally expired.
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index ffa19fb690..d44787b885 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -268,6 +268,7 @@ namespace MediaBrowser.Controller.Session
/// Authenticates a new session with quick connect.
///
/// The request.
+ /// Quick connect access token.
/// Task{SessionInfo}.
Task AuthenticateQuickConnect(AuthenticationRequest request, string token);
--
cgit v1.2.3
From 5f1a86324170387f12602d77dad7249faf30548f Mon Sep 17 00:00:00 2001
From: Matt Montgomery <33811686+ConfusedPolarBear@users.noreply.github.com>
Date: Mon, 17 Aug 2020 16:36:45 -0500
Subject: Apply suggestions from code review
---
.../QuickConnect/QuickConnectManager.cs | 38 +++++++++-------------
.../Session/SessionManager.cs | 2 +-
Jellyfin.Api/Controllers/QuickConnectController.cs | 34 +++++++++----------
Jellyfin.Api/Controllers/UserController.cs | 4 +--
.../QuickConnect/IQuickConnect.cs | 12 +++----
.../QuickConnect/QuickConnectResult.cs | 5 ---
6 files changed, 40 insertions(+), 55 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
index 949c3b5058..52e934229a 100644
--- a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
+++ b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
@@ -3,17 +3,16 @@ using System.Collections.Concurrent;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
+using MediaBrowser.Common;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller;
+using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.QuickConnect;
using MediaBrowser.Controller.Security;
using MediaBrowser.Model.QuickConnect;
-using Microsoft.AspNetCore.Http;
-using MediaBrowser.Common;
using Microsoft.Extensions.Logging;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Authentication;
namespace Emby.Server.Implementations.QuickConnect
{
@@ -60,7 +59,7 @@ namespace Emby.Server.Implementations.QuickConnect
public int CodeLength { get; set; } = 6;
///
- public string TokenNamePrefix { get; set; } = "QuickConnect-";
+ public string TokenName { get; set; } = "QuickConnect";
///
public QuickConnectState State { get; private set; } = QuickConnectState.Unavailable;
@@ -82,7 +81,7 @@ namespace Emby.Server.Implementations.QuickConnect
///
public void Activate()
{
- DateActivated = DateTime.Now;
+ DateActivated = DateTime.UtcNow;
SetState(QuickConnectState.Active);
}
@@ -101,7 +100,7 @@ namespace Emby.Server.Implementations.QuickConnect
}
///
- public QuickConnectResult TryConnect(string friendlyName)
+ public QuickConnectResult TryConnect()
{
ExpireRequests();
@@ -111,14 +110,11 @@ namespace Emby.Server.Implementations.QuickConnect
throw new AuthenticationException("Quick connect is not active on this server");
}
- _logger.LogDebug("Got new quick connect request from {friendlyName}", friendlyName);
-
var code = GenerateCode();
var result = new QuickConnectResult()
{
Secret = GenerateSecureRandom(),
- FriendlyName = friendlyName,
- DateAdded = DateTime.Now,
+ DateAdded = DateTime.UtcNow,
Code = code
};
@@ -162,13 +158,11 @@ namespace Emby.Server.Implementations.QuickConnect
}
///
- public bool AuthorizeRequest(HttpRequest request, string code)
+ public bool AuthorizeRequest(Guid userId, string code)
{
ExpireRequests();
AssertActive();
- var auth = _authContext.GetAuthorizationInfo(request);
-
if (!_currentRequests.TryGetValue(code, out QuickConnectResult result))
{
throw new ResourceNotFoundException("Unable to find request");
@@ -182,21 +176,21 @@ namespace Emby.Server.Implementations.QuickConnect
result.Authentication = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
// Change the time on the request so it expires one minute into the future. It can't expire immediately as otherwise some clients wouldn't ever see that they have been authenticated.
- var added = result.DateAdded ?? DateTime.Now.Subtract(new TimeSpan(0, Timeout, 0));
- result.DateAdded = added.Subtract(new TimeSpan(0, Timeout - 1, 0));
+ var added = result.DateAdded ?? DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(Timeout));
+ result.DateAdded = added.Subtract(TimeSpan.FromMinutes(Timeout - 1));
_authenticationRepository.Create(new AuthenticationInfo
{
- AppName = TokenNamePrefix + result.FriendlyName,
+ AppName = TokenName,
AccessToken = result.Authentication,
DateCreated = DateTime.UtcNow,
DeviceId = _appHost.SystemId,
DeviceName = _appHost.FriendlyName,
AppVersion = _appHost.ApplicationVersionString,
- UserId = auth.UserId
+ UserId = userId
});
- _logger.LogInformation("Allowing device {FriendlyName} to login as user {Username} with quick connect code {Code}", result.FriendlyName, auth.User.Username, result.Code);
+ _logger.LogDebug("Authorizing device with code {Code} to login as user {userId}", code, userId);
return true;
}
@@ -210,7 +204,7 @@ namespace Emby.Server.Implementations.QuickConnect
UserId = user
});
- var tokens = raw.Items.Where(x => x.AppName.StartsWith(TokenNamePrefix, StringComparison.CurrentCulture));
+ var tokens = raw.Items.Where(x => x.AppName.StartsWith(TokenName, StringComparison.CurrentCulture));
var removed = 0;
foreach (var token in tokens)
@@ -256,7 +250,7 @@ namespace Emby.Server.Implementations.QuickConnect
public void ExpireRequests(bool expireAll = false)
{
// Check if quick connect should be deactivated
- if (State == QuickConnectState.Active && DateTime.Now > DateActivated.AddMinutes(Timeout) && !expireAll)
+ if (State == QuickConnectState.Active && DateTime.UtcNow > DateActivated.AddMinutes(Timeout) && !expireAll)
{
_logger.LogDebug("Quick connect time expired, deactivating");
SetState(QuickConnectState.Available);
@@ -270,7 +264,7 @@ namespace Emby.Server.Implementations.QuickConnect
for (int i = 0; i < values.Count; i++)
{
var added = values[i].DateAdded ?? DateTime.UnixEpoch;
- if (DateTime.Now > added.AddMinutes(Timeout) || expireAll)
+ if (DateTime.UtcNow > added.AddMinutes(Timeout) || expireAll)
{
code = values[i].Code;
_logger.LogDebug("Removing expired request {code}", code);
diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs
index 8a8223ee7f..fbe8e065c0 100644
--- a/Emby.Server.Implementations/Session/SessionManager.cs
+++ b/Emby.Server.Implementations/Session/SessionManager.cs
@@ -1433,7 +1433,7 @@ namespace Emby.Server.Implementations.Session
Limit = 1
});
- if (result.TotalRecordCount < 1)
+ if (result.TotalRecordCount == 0)
{
throw new SecurityException("Unknown quick connect token");
}
diff --git a/Jellyfin.Api/Controllers/QuickConnectController.cs b/Jellyfin.Api/Controllers/QuickConnectController.cs
index 1625bcffe7..b1ee2ff53b 100644
--- a/Jellyfin.Api/Controllers/QuickConnectController.cs
+++ b/Jellyfin.Api/Controllers/QuickConnectController.cs
@@ -1,8 +1,8 @@
+using System;
using System.ComponentModel.DataAnnotations;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers;
using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.QuickConnect;
using MediaBrowser.Model.QuickConnect;
@@ -18,22 +18,18 @@ namespace Jellyfin.Api.Controllers
public class QuickConnectController : BaseJellyfinApiController
{
private readonly IQuickConnect _quickConnect;
- private readonly IUserManager _userManager;
private readonly IAuthorizationContext _authContext;
///
/// Initializes a new instance of the class.
///
/// Instance of the interface.
- /// Instance of the interface.
/// Instance of the interface.
public QuickConnectController(
IQuickConnect quickConnect,
- IUserManager userManager,
IAuthorizationContext authContext)
{
_quickConnect = quickConnect;
- _userManager = userManager;
_authContext = authContext;
}
@@ -53,15 +49,14 @@ namespace Jellyfin.Api.Controllers
///
/// Initiate a new quick connect request.
///
- /// Device friendly name.
/// Quick connect request successfully created.
/// Quick connect is not active on this server.
/// A with a secret and code for future use or an error message.
[HttpGet("Initiate")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult Initiate([FromQuery] string? friendlyName)
+ public ActionResult Initiate()
{
- return _quickConnect.TryConnect(friendlyName);
+ return _quickConnect.TryConnect();
}
///
@@ -74,12 +69,11 @@ namespace Jellyfin.Api.Controllers
[HttpGet("Connect")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public ActionResult Connect([FromQuery] string? secret)
+ public ActionResult Connect([FromQuery, Required] string secret)
{
try
{
- var result = _quickConnect.CheckRequestStatus(secret);
- return result;
+ return _quickConnect.CheckRequestStatus(secret);
}
catch (ResourceNotFoundException)
{
@@ -117,9 +111,9 @@ namespace Jellyfin.Api.Controllers
[HttpPost("Available")]
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
- public ActionResult Available([FromQuery] QuickConnectState? status)
+ public ActionResult Available([FromQuery] QuickConnectState status = QuickConnectState.Available)
{
- _quickConnect.SetState(status ?? QuickConnectState.Available);
+ _quickConnect.SetState(status);
return NoContent();
}
@@ -127,16 +121,22 @@ namespace Jellyfin.Api.Controllers
/// Authorizes a pending quick connect request.
///
/// Quick connect code to authorize.
+ /// User id.
/// Quick connect result authorized successfully.
- /// Missing quick connect code.
+ /// User is not allowed to authorize quick connect requests.
/// Boolean indicating if the authorization was successful.
[HttpPost("Authorize")]
[Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status400BadRequest)]
- public ActionResult Authorize([FromQuery, Required] string? code)
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public ActionResult Authorize([FromQuery, Required] string code, [FromQuery, Required] Guid userId)
{
- return _quickConnect.AuthorizeRequest(Request, code);
+ if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true))
+ {
+ return Forbid("User is not allowed to authorize quick connect requests.");
+ }
+
+ return _quickConnect.AuthorizeRequest(userId, code);
}
///
diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs
index 355816bd32..d67f82219a 100644
--- a/Jellyfin.Api/Controllers/UserController.cs
+++ b/Jellyfin.Api/Controllers/UserController.cs
@@ -239,11 +239,9 @@ namespace Jellyfin.Api.Controllers
DeviceName = auth.Device,
};
- var result = await _sessionManager.AuthenticateQuickConnect(
+ return await _sessionManager.AuthenticateQuickConnect(
authRequest,
request.Token).ConfigureAwait(false);
-
- return result;
}
catch (SecurityException e)
{
diff --git a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
index fd7e973f67..959a2d7712 100644
--- a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
+++ b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
@@ -1,6 +1,5 @@
using System;
using MediaBrowser.Model.QuickConnect;
-using Microsoft.AspNetCore.Http;
namespace MediaBrowser.Controller.QuickConnect
{
@@ -15,9 +14,9 @@ namespace MediaBrowser.Controller.QuickConnect
int CodeLength { get; set; }
///
- /// Gets or sets the string to prefix internal access tokens with.
+ /// Gets or sets the name of internal access tokens.
///
- string TokenNamePrefix { get; set; }
+ string TokenName { get; set; }
///
/// Gets the current state of quick connect.
@@ -48,9 +47,8 @@ namespace MediaBrowser.Controller.QuickConnect
///
/// Initiates a new quick connect request.
///
- /// Friendly device name to display in the request UI.
/// A quick connect result with tokens to proceed or throws an exception if not active.
- QuickConnectResult TryConnect(string friendlyName);
+ QuickConnectResult TryConnect();
///
/// Checks the status of an individual request.
@@ -62,10 +60,10 @@ namespace MediaBrowser.Controller.QuickConnect
///
/// Authorizes a quick connect request to connect as the calling user.
///
- /// HTTP request object.
+ /// User id.
/// Identifying code for the request.
/// A boolean indicating if the authorization completed successfully.
- bool AuthorizeRequest(HttpRequest request, string code);
+ bool AuthorizeRequest(Guid userId, string code);
///
/// Expire quick connect requests that are over the time limit. If is true, all requests are unconditionally expired.
diff --git a/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs b/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs
index a10d60d57e..0fa40b6a72 100644
--- a/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs
+++ b/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs
@@ -22,11 +22,6 @@ namespace MediaBrowser.Model.QuickConnect
///
public string? Code { get; set; }
- ///
- /// Gets or sets the device friendly name.
- ///
- public string? FriendlyName { get; set; }
-
///
/// Gets or sets the private access token.
///
--
cgit v1.2.3
From 2b400c99ef946ef1e52e3f01cb18bc008a369c59 Mon Sep 17 00:00:00 2001
From: Bond_009
Date: Fri, 7 Aug 2020 19:26:28 +0200
Subject: Fix warnings
---
Emby.Dlna/DlnaManager.cs | 12 +--
Emby.Dlna/PlayTo/Device.cs | 36 ++++---
Emby.Dlna/PlayTo/TransportCommands.cs | 17 ++--
.../Data/SqliteItemRepository.cs | 4 +-
.../LiveTv/EmbyTV/EncodedRecorder.cs | 2 +-
.../LiveTv/Listings/XmlTvListingsProvider.cs | 5 +-
.../LiveTv/LiveTvManager.cs | 106 +++++++++++----------
.../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 16 ++--
Jellyfin.Api/Controllers/ImageController.cs | 2 +-
MediaBrowser.Controller/Entities/Movies/Movie.cs | 4 +-
MediaBrowser.Controller/Entities/TV/Series.cs | 2 +-
MediaBrowser.Controller/Entities/Trailer.cs | 3 +-
MediaBrowser.Controller/Library/Profiler.cs | 17 +++-
MediaBrowser.Controller/LiveTv/LiveTvChannel.cs | 2 +-
MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 2 +-
.../MediaEncoding/EncodingHelper.cs | 8 +-
.../Providers/IProviderManager.cs | 2 +-
.../Encoder/EncodingUtils.cs | 9 +-
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 14 +--
.../Subtitles/SubtitleEncoder.cs | 2 +-
MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs | 2 +-
MediaBrowser.Model/Dlna/DlnaMaps.cs | 8 +-
.../Dlna/MediaFormatProfileResolver.cs | 21 ++--
MediaBrowser.Model/Dlna/StreamInfo.cs | 12 +--
MediaBrowser.Providers/Manager/ImageSaver.cs | 4 +-
.../Manager/ItemImageProvider.cs | 57 +++++------
MediaBrowser.Providers/Manager/MetadataService.cs | 73 +++++++-------
MediaBrowser.Providers/Manager/ProviderManager.cs | 37 +++++--
.../MediaInfo/FFProbeAudioInfo.cs | 15 +--
.../MediaInfo/FFProbeProvider.cs | 21 +---
MediaBrowser.Providers/Music/Extensions.cs | 4 +-
.../Plugins/MusicBrainz/AlbumProvider.cs | 2 +-
.../Plugins/MusicBrainz/ArtistProvider.cs | 4 +-
.../Plugins/Omdb/OmdbImageProvider.cs | 3 +-
.../Plugins/Omdb/OmdbItemProvider.cs | 2 +-
.../Plugins/Omdb/OmdbProvider.cs | 25 +++--
.../Plugins/TheTvdb/TvdbClientManager.cs | 31 ++----
.../Plugins/TheTvdb/TvdbEpisodeImageProvider.cs | 7 +-
.../Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs | 4 +-
.../Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs | 2 +-
.../Plugins/Tmdb/Movies/TmdbSearch.cs | 54 +++++++++--
.../Plugins/Tmdb/TV/TmdbEpisodeProvider.cs | 2 +-
.../Plugins/Tmdb/TV/TmdbEpisodeProviderBase.cs | 4 +-
.../Plugins/Tmdb/TV/TmdbSeasonProvider.cs | 4 +-
.../Plugins/Tmdb/TV/TmdbSeriesProvider.cs | 2 +-
.../Studios/StudiosImageProvider.cs | 3 +-
46 files changed, 366 insertions(+), 302 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs
index 269f7ee43a..ce4be7b514 100644
--- a/Emby.Dlna/DlnaManager.cs
+++ b/Emby.Dlna/DlnaManager.cs
@@ -54,11 +54,15 @@ namespace Emby.Dlna
_appHost = appHost;
}
+ private string UserProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "user");
+
+ private string SystemProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "system");
+
public async Task InitProfilesAsync()
{
try
{
- await ExtractSystemProfilesAsync();
+ await ExtractSystemProfilesAsync().ConfigureAwait(false);
LoadProfiles();
}
catch (Exception ex)
@@ -240,7 +244,7 @@ namespace Emby.Dlna
}
else
{
- var headerString = string.Join(", ", headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
+ var headerString = string.Join(", ", headers.Select(i => string.Format(CultureInfo.InvariantCulture, "{0}={1}", i.Key, i.Value)));
_logger.LogDebug("No matching device profile found. {0}", headerString);
}
@@ -280,10 +284,6 @@ namespace Emby.Dlna
return false;
}
- private string UserProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "user");
-
- private string SystemProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "system");
-
private IEnumerable GetProfiles(string path, DeviceProfileType type)
{
try
diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs
index 72834c69d1..86dd52a1b6 100644
--- a/Emby.Dlna/PlayTo/Device.cs
+++ b/Emby.Dlna/PlayTo/Device.cs
@@ -19,6 +19,8 @@ namespace Emby.Dlna.PlayTo
{
public class Device : IDisposable
{
+ private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
+
private Timer _timer;
public DeviceInfo Properties { get; set; }
@@ -55,16 +57,13 @@ namespace Emby.Dlna.PlayTo
private readonly ILogger _logger;
- private readonly IServerConfigurationManager _config;
-
public Action OnDeviceUnavailable { get; set; }
- public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger, IServerConfigurationManager config)
+ public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger)
{
Properties = deviceProperties;
_httpClient = httpClient;
_logger = logger;
- _config = config;
}
public void Start()
@@ -275,7 +274,7 @@ namespace Emby.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, string.Format("{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME"))
+ await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, string.Format(CultureInfo.InvariantCulture, "{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME"))
.ConfigureAwait(false);
RestartTimer(true);
@@ -285,7 +284,7 @@ namespace Emby.Dlna.PlayTo
{
var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false);
- url = url.Replace("&", "&");
+ url = url.Replace("&", "&", StringComparison.Ordinal);
_logger.LogDebug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", Properties.Name, url, header);
@@ -297,8 +296,8 @@ namespace Emby.Dlna.PlayTo
var dictionary = new Dictionary
{
- {"CurrentURI", url},
- {"CurrentURIMetaData", CreateDidlMeta(metaData)}
+ { "CurrentURI", url },
+ { "CurrentURIMetaData", CreateDidlMeta(metaData) }
};
var service = GetAvTransportService();
@@ -732,10 +731,10 @@ namespace Emby.Dlna.PlayTo
}
var trackUriElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("TrackURI")).FirstOrDefault(i => i != null);
- var trackUri = trackUriElem == null ? null : trackUriElem.Value;
+ var trackUri = trackUriElem?.Value;
var durationElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("TrackDuration")).FirstOrDefault(i => i != null);
- var duration = durationElem == null ? null : durationElem.Value;
+ var duration = durationElem?.Value;
if (!string.IsNullOrWhiteSpace(duration)
&& !string.Equals(duration, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase))
@@ -748,7 +747,7 @@ namespace Emby.Dlna.PlayTo
}
var positionElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("RelTime")).FirstOrDefault(i => i != null);
- var position = positionElem == null ? null : positionElem.Value;
+ var position = positionElem?.Value;
if (!string.IsNullOrWhiteSpace(position) && !string.Equals(position, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase))
{
@@ -819,7 +818,7 @@ namespace Emby.Dlna.PlayTo
// some devices send back invalid xml
try
{
- return XElement.Parse(xml.Replace("&", "&"));
+ return XElement.Parse(xml.Replace("&", "&", StringComparison.Ordinal));
}
catch (XmlException)
{
@@ -848,7 +847,7 @@ namespace Emby.Dlna.PlayTo
ParentId = container.GetAttributeValue(uPnpNamespaces.ParentId),
Title = container.GetValue(uPnpNamespaces.title),
IconUrl = container.GetValue(uPnpNamespaces.Artwork),
- SecondText = "",
+ SecondText = string.Empty,
Url = url,
ProtocolInfo = GetProtocolInfo(container),
MetaData = container.ToString()
@@ -941,12 +940,12 @@ namespace Emby.Dlna.PlayTo
return url;
}
- if (!url.Contains("/"))
+ if (!url.Contains('/', StringComparison.Ordinal))
{
url = "/dmr/" + url;
}
- if (!url.StartsWith("/"))
+ if (!url.StartsWith("/", StringComparison.Ordinal))
{
url = "/" + url;
}
@@ -981,7 +980,7 @@ namespace Emby.Dlna.PlayTo
var deviceProperties = new DeviceInfo()
{
Name = string.Join(" ", friendlyNames),
- BaseUrl = string.Format("http://{0}:{1}", url.Host, url.Port)
+ BaseUrl = string.Format(CultureInfo.InvariantCulture, "http://{0}:{1}", url.Host, url.Port)
};
var model = document.Descendants(uPnpNamespaces.ud.GetName("modelName")).FirstOrDefault();
@@ -1068,10 +1067,9 @@ namespace Emby.Dlna.PlayTo
}
}
- return new Device(deviceProperties, httpClient, logger, config);
+ return new Device(deviceProperties, httpClient, logger);
}
- private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
private static DeviceIcon CreateIcon(XElement element)
{
if (element == null)
@@ -1222,7 +1220,7 @@ namespace Emby.Dlna.PlayTo
public override string ToString()
{
- return string.Format("{0} - {1}", Properties.Name, Properties.BaseUrl);
+ return string.Format(CultureInfo.InvariantCulture, "{0} - {1}", Properties.Name, Properties.BaseUrl);
}
}
}
diff --git a/Emby.Dlna/PlayTo/TransportCommands.cs b/Emby.Dlna/PlayTo/TransportCommands.cs
index c0ce3ab6e9..dc797a6918 100644
--- a/Emby.Dlna/PlayTo/TransportCommands.cs
+++ b/Emby.Dlna/PlayTo/TransportCommands.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using Emby.Dlna.Common;
@@ -11,14 +12,16 @@ namespace Emby.Dlna.PlayTo
{
public class TransportCommands
{
+ private const string CommandBase = "\r\n" + "" + "" + "" + "{2}" + "" + "";
private List _stateVariables = new List();
+ private List _serviceActions = new List();
+
public List StateVariables
{
get => _stateVariables;
set => _stateVariables = value;
}
- private List _serviceActions = new List();
public List ServiceActions
{
get => _serviceActions;
@@ -123,7 +126,7 @@ namespace Emby.Dlna.PlayTo
}
}
- return string.Format(CommandBase, action.Name, xmlNamespace, stateString);
+ return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamespace, stateString);
}
public string BuildPost(ServiceAction action, string xmlNamesapce, object value, string commandParameter = "")
@@ -147,7 +150,7 @@ namespace Emby.Dlna.PlayTo
}
}
- return string.Format(CommandBase, action.Name, xmlNamesapce, stateString);
+ return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamesapce, stateString);
}
public string BuildPost(ServiceAction action, string xmlNamesapce, object value, Dictionary dictionary)
@@ -170,7 +173,7 @@ namespace Emby.Dlna.PlayTo
}
}
- return string.Format(CommandBase, action.Name, xmlNamesapce, stateString);
+ return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamesapce, stateString);
}
private string BuildArgumentXml(Argument argument, string value, string commandParameter = "")
@@ -183,12 +186,10 @@ namespace Emby.Dlna.PlayTo
state.AllowedValues.FirstOrDefault() ??
value;
- return string.Format("<{0} xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"{1}\">{2}{0}>", argument.Name, state.DataType ?? "string", sendValue);
+ return string.Format(CultureInfo.InvariantCulture, "<{0} xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"{1}\">{2}{0}>", argument.Name, state.DataType ?? "string", sendValue);
}
- return string.Format("<{0}>{1}{0}>", argument.Name, value);
+ return string.Format(CultureInfo.InvariantCulture, "<{0}>{1}{0}>", argument.Name, value);
}
-
- private const string CommandBase = "\r\n" + "" + "" + "" + "{2}" + "" + "";
}
}
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index d11e5e62e3..331ffc1349 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -4560,13 +4560,13 @@ namespace Emby.Server.Implementations.Data
if (query.AncestorIds.Length > 1)
{
var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i.ToString("N", CultureInfo.InvariantCulture) + "'"));
- whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause));
+ whereClauses.Add(string.Format(CultureInfo.InvariantCulture, "Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause));
}
if (!string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey))
{
var inClause = "select guid from TypedBaseItems where PresentationUniqueKey=@AncestorWithPresentationUniqueKey";
- whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorId in ({0}))", inClause));
+ whereClauses.Add(string.Format(CultureInfo.InvariantCulture, "Guid in (select itemId from AncestorIds where AncestorId in ({0}))", inClause));
if (statement != null)
{
statement.TryBind("@AncestorWithPresentationUniqueKey", query.AncestorWithPresentationUniqueKey);
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
index d8ec107ecd..612dc5238b 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
@@ -230,7 +230,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
if (filters.Count > 0)
{
- output += string.Format(" -vf \"{0}\"", string.Join(",", filters.ToArray()));
+ output += string.Format(CultureInfo.InvariantCulture, " -vf \"{0}\"", string.Join(",", filters.ToArray()));
}
return output;
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index 0a93c46748..f33d071747 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -237,7 +237,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
&& !programInfo.IsRepeat
&& (programInfo.EpisodeNumber ?? 0) == 0)
{
- programInfo.ShowId = programInfo.ShowId + programInfo.StartDate.Ticks.ToString(CultureInfo.InvariantCulture);
+ programInfo.ShowId += programInfo.StartDate.Ticks.ToString(CultureInfo.InvariantCulture);
}
}
else
@@ -246,7 +246,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
}
// Construct an id from the channel and start date
- programInfo.Id = string.Format("{0}_{1:O}", program.ChannelId, program.StartDate);
+ programInfo.Id = string.Format(CultureInfo.InvariantCulture, "{0}_{1:O}", program.ChannelId, program.StartDate);
if (programInfo.IsMovie)
{
@@ -296,7 +296,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
Name = c.DisplayName,
ImageUrl = c.Icon != null && !string.IsNullOrEmpty(c.Icon.Source) ? c.Icon.Source : null,
Number = string.IsNullOrWhiteSpace(c.Number) ? c.Id : c.Number
-
}).ToList();
}
}
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 1b075d86a8..90cbd85a55 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -41,6 +41,7 @@ namespace Emby.Server.Implementations.LiveTv
///
public class LiveTvManager : ILiveTvManager, IDisposable
{
+ private const int MaxGuideDays = 14;
private const string ExternalServiceTag = "ExternalServiceId";
private const string EtagKey = "ProgramEtag";
@@ -560,7 +561,7 @@ namespace Emby.Server.Implementations.LiveTv
item.Audio = info.Audio;
item.ChannelId = channel.Id;
- item.CommunityRating = item.CommunityRating ?? info.CommunityRating;
+ item.CommunityRating ??= info.CommunityRating;
if ((item.CommunityRating ?? 0).Equals(0))
{
item.CommunityRating = null;
@@ -645,8 +646,8 @@ namespace Emby.Server.Implementations.LiveTv
item.IsSeries = isSeries;
item.Name = info.Name;
- item.OfficialRating = item.OfficialRating ?? info.OfficialRating;
- item.Overview = item.Overview ?? info.Overview;
+ item.OfficialRating ??= info.OfficialRating;
+ item.Overview ??= info.Overview;
item.RunTimeTicks = (info.EndDate - info.StartDate).Ticks;
item.ProviderIds = info.ProviderIds;
@@ -683,19 +684,23 @@ namespace Emby.Server.Implementations.LiveTv
{
if (!string.IsNullOrWhiteSpace(info.ImagePath))
{
- item.SetImage(new ItemImageInfo
- {
- Path = info.ImagePath,
- Type = ImageType.Primary
- }, 0);
+ item.SetImage(
+ new ItemImageInfo
+ {
+ Path = info.ImagePath,
+ Type = ImageType.Primary
+ },
+ 0);
}
else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
{
- item.SetImage(new ItemImageInfo
- {
- Path = info.ImageUrl,
- Type = ImageType.Primary
- }, 0);
+ item.SetImage(
+ new ItemImageInfo
+ {
+ Path = info.ImageUrl,
+ Type = ImageType.Primary
+ },
+ 0);
}
}
@@ -703,11 +708,13 @@ namespace Emby.Server.Implementations.LiveTv
{
if (!string.IsNullOrWhiteSpace(info.ThumbImageUrl))
{
- item.SetImage(new ItemImageInfo
- {
- Path = info.ThumbImageUrl,
- Type = ImageType.Thumb
- }, 0);
+ item.SetImage(
+ new ItemImageInfo
+ {
+ Path = info.ThumbImageUrl,
+ Type = ImageType.Thumb
+ },
+ 0);
}
}
@@ -715,11 +722,13 @@ namespace Emby.Server.Implementations.LiveTv
{
if (!string.IsNullOrWhiteSpace(info.LogoImageUrl))
{
- item.SetImage(new ItemImageInfo
- {
- Path = info.LogoImageUrl,
- Type = ImageType.Logo
- }, 0);
+ item.SetImage(
+ new ItemImageInfo
+ {
+ Path = info.LogoImageUrl,
+ Type = ImageType.Logo
+ },
+ 0);
}
}
@@ -727,11 +736,13 @@ namespace Emby.Server.Implementations.LiveTv
{
if (!string.IsNullOrWhiteSpace(info.BackdropImageUrl))
{
- item.SetImage(new ItemImageInfo
- {
- Path = info.BackdropImageUrl,
- Type = ImageType.Backdrop
- }, 0);
+ item.SetImage(
+ new ItemImageInfo
+ {
+ Path = info.BackdropImageUrl,
+ Type = ImageType.Backdrop
+ },
+ 0);
}
}
@@ -786,7 +797,6 @@ namespace Emby.Server.Implementations.LiveTv
if (query.OrderBy.Count == 0)
{
-
// Unless something else was specified, order by start date to take advantage of a specialized index
query.OrderBy = new[]
{
@@ -824,7 +834,7 @@ namespace Emby.Server.Implementations.LiveTv
if (!string.IsNullOrWhiteSpace(query.SeriesTimerId))
{
- var seriesTimers = await GetSeriesTimersInternal(new SeriesTimerQuery { }, cancellationToken).ConfigureAwait(false);
+ var seriesTimers = await GetSeriesTimersInternal(new SeriesTimerQuery(), cancellationToken).ConfigureAwait(false);
var seriesTimer = seriesTimers.Items.FirstOrDefault(i => string.Equals(_tvDtoService.GetInternalSeriesTimerId(i.Id).ToString("N", CultureInfo.InvariantCulture), query.SeriesTimerId, StringComparison.OrdinalIgnoreCase));
if (seriesTimer != null)
{
@@ -847,13 +857,11 @@ namespace Emby.Server.Implementations.LiveTv
var returnArray = _dtoService.GetBaseItemDtos(queryResult.Items, options, user);
- var result = new QueryResult
+ return new QueryResult
{
Items = returnArray,
TotalRecordCount = queryResult.TotalRecordCount
};
-
- return result;
}
public QueryResult GetRecommendedProgramsInternal(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken)
@@ -1173,7 +1181,6 @@ namespace Emby.Server.Implementations.LiveTv
var existingPrograms = _libraryManager.GetItemList(new InternalItemsQuery
{
-
IncludeItemTypes = new string[] { typeof(LiveTvProgram).Name },
ChannelIds = new Guid[] { currentChannel.Id },
DtoOptions = new DtoOptions(true)
@@ -1298,8 +1305,6 @@ namespace Emby.Server.Implementations.LiveTv
}
}
- private const int MaxGuideDays = 14;
-
private double GetGuideDays()
{
var config = GetConfiguration();
@@ -1712,7 +1717,7 @@ namespace Emby.Server.Implementations.LiveTv
if (timer == null)
{
- throw new ResourceNotFoundException(string.Format("Timer with Id {0} not found", id));
+ throw new ResourceNotFoundException(string.Format(CultureInfo.InvariantCulture, "Timer with Id {0} not found", id));
}
var service = GetService(timer.ServiceName);
@@ -1731,7 +1736,7 @@ namespace Emby.Server.Implementations.LiveTv
if (timer == null)
{
- throw new ResourceNotFoundException(string.Format("SeriesTimer with Id {0} not found", id));
+ throw new ResourceNotFoundException(string.Format(CultureInfo.InvariantCulture, "SeriesTimer with Id {0} not found", id));
}
var service = GetService(timer.ServiceName);
@@ -1743,10 +1748,12 @@ namespace Emby.Server.Implementations.LiveTv
public async Task GetTimer(string id, CancellationToken cancellationToken)
{
- var results = await GetTimers(new TimerQuery
- {
- Id = id
- }, cancellationToken).ConfigureAwait(false);
+ var results = await GetTimers(
+ new TimerQuery
+ {
+ Id = id
+ },
+ cancellationToken).ConfigureAwait(false);
return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase));
}
@@ -1794,10 +1801,7 @@ namespace Emby.Server.Implementations.LiveTv
}
var returnArray = timers
- .Select(i =>
- {
- return i.Item1;
- })
+ .Select(i => i.Item1)
.ToArray();
return new QueryResult
@@ -1968,7 +1972,7 @@ namespace Emby.Server.Implementations.LiveTv
if (service == null)
{
- service = _services.First();
+ service = _services[0];
}
var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false);
@@ -1994,9 +1998,7 @@ namespace Emby.Server.Implementations.LiveTv
{
var info = await GetNewTimerDefaultsInternal(cancellationToken).ConfigureAwait(false);
- var obj = _tvDtoService.GetSeriesTimerInfoDto(info.Item1, info.Item2, null);
-
- return obj;
+ return _tvDtoService.GetSeriesTimerInfoDto(info.Item1, info.Item2, null);
}
public async Task GetNewTimerDefaults(string programId, CancellationToken cancellationToken)
@@ -2125,6 +2127,7 @@ namespace Emby.Server.Implementations.LiveTv
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
private bool _disposed = false;
@@ -2447,8 +2450,7 @@ namespace Emby.Server.Implementations.LiveTv
.SelectMany(i => i.Locations)
.Distinct(StringComparer.OrdinalIgnoreCase)
.Select(i => _libraryManager.FindByPath(i, true))
- .Where(i => i != null)
- .Where(i => i.IsVisibleStandalone(user))
+ .Where(i => i != null && i.IsVisibleStandalone(user))
.SelectMany(i => _libraryManager.GetCollectionFolders(i))
.GroupBy(x => x.Id)
.Select(x => x.First())
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index c61189c0ac..f1e120a649 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -182,12 +182,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
- using (var response = await _httpClient.SendAsync(new HttpRequestOptions()
- {
- Url = string.Format("{0}/tuners.html", GetApiUrl(info)),
- CancellationToken = cancellationToken,
- BufferContent = false
- }, HttpMethod.Get).ConfigureAwait(false))
+ using (var response = await _httpClient.SendAsync(
+ new HttpRequestOptions()
+ {
+ Url = string.Format(CultureInfo.InvariantCulture, "{0}/tuners.html", GetApiUrl(info)),
+ CancellationToken = cancellationToken,
+ BufferContent = false
+ },
+ HttpMethod.Get).ConfigureAwait(false))
using (var stream = response.Content)
using (var sr = new StreamReader(stream, System.Text.Encoding.UTF8))
{
@@ -730,7 +732,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
// Need a way to set the Receive timeout on the socket otherwise this might never timeout?
try
{
- await udpClient.SendToAsync(discBytes, 0, discBytes.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 65001), cancellationToken);
+ await udpClient.SendToAsync(discBytes, 0, discBytes.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 65001), cancellationToken).ConfigureAwait(false);
var receiveBuffer = new byte[8192];
while (!cancellationToken.IsCancellationRequested)
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index 8f5c6beb30..75734f0af0 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -113,7 +113,7 @@ namespace Jellyfin.Api.Controllers
user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType)));
await _providerManager
- .SaveImage(user, memoryStream, mimeType, user.ProfileImage.Path)
+ .SaveImage(memoryStream, mimeType, user.ProfileImage.Path)
.ConfigureAwait(false);
await _userManager.UpdateUserAsync(user).ConfigureAwait(false);
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 53badac4db..5ae396e68b 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -1,5 +1,7 @@
+
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Text.Json.Serialization;
using System.Threading;
@@ -179,7 +181,7 @@ namespace MediaBrowser.Controller.Entities.Movies
list.Add(new ExternalUrl
{
Name = "Trakt",
- Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
+ Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/movies/{0}", imdbId)
});
}
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 45daa8a539..23d9600920 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -496,7 +496,7 @@ namespace MediaBrowser.Controller.Entities.TV
list.Add(new ExternalUrl
{
Name = "Trakt",
- Url = string.Format("https://trakt.tv/shows/{0}", imdbId)
+ Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/shows/{0}", imdbId)
});
}
diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs
index 6b544afc68..83e9ce1e75 100644
--- a/MediaBrowser.Controller/Entities/Trailer.cs
+++ b/MediaBrowser.Controller/Entities/Trailer.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Text.Json.Serialization;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Providers;
@@ -86,7 +87,7 @@ namespace MediaBrowser.Controller.Entities
list.Add(new ExternalUrl
{
Name = "Trakt",
- Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
+ Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/movies/{0}", imdbId)
});
}
diff --git a/MediaBrowser.Controller/Library/Profiler.cs b/MediaBrowser.Controller/Library/Profiler.cs
index 399378a099..5efdc6a481 100644
--- a/MediaBrowser.Controller/Library/Profiler.cs
+++ b/MediaBrowser.Controller/Library/Profiler.cs
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
+using System.Globalization;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Controller.Library
@@ -13,6 +14,7 @@ namespace MediaBrowser.Controller.Library
/// The name.
///
readonly string _name;
+
///
/// The stopwatch.
///
@@ -44,6 +46,7 @@ namespace MediaBrowser.Controller.Library
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
///
@@ -58,13 +61,19 @@ namespace MediaBrowser.Controller.Library
string message;
if (_stopwatch.ElapsedMilliseconds > 300000)
{
- message = string.Format("{0} took {1} minutes.",
- _name, ((float)_stopwatch.ElapsedMilliseconds / 60000).ToString("F"));
+ message = string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} took {1} minutes.",
+ _name,
+ ((float)_stopwatch.ElapsedMilliseconds / 60000).ToString("F", CultureInfo.InvariantCulture));
}
else
{
- message = string.Format("{0} took {1} seconds.",
- _name, ((float)_stopwatch.ElapsedMilliseconds / 1000).ToString("#0.000"));
+ message = string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} took {1} seconds.",
+ _name,
+ ((float)_stopwatch.ElapsedMilliseconds / 1000).ToString("#0.000", CultureInfo.InvariantCulture));
}
_logger.LogInformation(message);
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
index 10af981213..aa7c12dd14 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
@@ -63,7 +63,7 @@ namespace MediaBrowser.Controller.LiveTv
if (double.TryParse(Number, NumberStyles.Any, CultureInfo.InvariantCulture, out number))
{
- return string.Format("{0:00000.0}", number) + "-" + (Name ?? string.Empty);
+ return string.Format(CultureInfo.InvariantCulture, "{0:00000.0}", number) + "-" + (Name ?? string.Empty);
}
}
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
index 472b061e6a..e1de01ff02 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
@@ -261,7 +261,7 @@ namespace MediaBrowser.Controller.LiveTv
list.Add(new ExternalUrl
{
Name = "Trakt",
- Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
+ Url = string.Format(CultureInfo.InvariantCulture, "https://trakt.tv/movies/{0}", imdbId)
});
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 2dd21be3c3..7b09f489e9 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -675,7 +675,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// }
// }
- // fallbackFontParam = string.Format(":force_style='FontName=Droid Sans Fallback':fontsdir='{0}'", _mediaEncoder.EscapeSubtitleFilterPath(_fileSystem.GetDirectoryName(fallbackFontPath)));
+ // fallbackFontParam = string.Format(CultureInfo.InvariantCulture, ":force_style='FontName=Droid Sans Fallback':fontsdir='{0}'", _mediaEncoder.EscapeSubtitleFilterPath(_fileSystem.GetDirectoryName(fallbackFontPath)));
if (state.SubtitleStream.IsExternal)
{
@@ -880,7 +880,7 @@ namespace MediaBrowser.Controller.MediaEncoding
profileScore = Math.Min(profileScore, 2);
// http://www.webmproject.org/docs/encoder-parameters/
- param += string.Format("-speed 16 -quality good -profile:v {0} -slices 8 -crf {1} -qmin {2} -qmax {3}",
+ param += string.Format(CultureInfo.InvariantCulture, "-speed 16 -quality good -profile:v {0} -slices 8 -crf {1} -qmin {2} -qmax {3}",
profileScore.ToString(_usCulture),
crf,
qmin,
@@ -904,7 +904,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var framerate = GetFramerateParam(state);
if (framerate.HasValue)
{
- param += string.Format(" -r {0}", framerate.Value.ToString(_usCulture));
+ param += string.Format(CultureInfo.InvariantCulture, " -r {0}", framerate.Value.ToString(_usCulture));
}
var targetVideoCodec = state.ActualOutputVideoCodec;
@@ -1484,7 +1484,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (time > 0)
{
- return string.Format("-ss {0}", _mediaEncoder.GetTimeParameter(time));
+ return string.Format(CultureInfo.InvariantCulture, "-ss {0}", _mediaEncoder.GetTimeParameter(time));
}
return string.Empty;
diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs
index 8ba01d7730..c77349d010 100644
--- a/MediaBrowser.Controller/Providers/IProviderManager.cs
+++ b/MediaBrowser.Controller/Providers/IProviderManager.cs
@@ -72,7 +72,7 @@ namespace MediaBrowser.Controller.Providers
/// Task.
Task SaveImage(BaseItem item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken);
- Task SaveImage(User user, Stream source, string mimeType, string path);
+ Task SaveImage(Stream source, string mimeType, string path);
///
/// Adds the metadata providers.
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs
index 7c2d9f1fd5..082ae2888d 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs
@@ -1,6 +1,7 @@
#pragma warning disable CS1591
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using MediaBrowser.Model.MediaInfo;
@@ -14,7 +15,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
var url = inputFiles[0];
- return string.Format("\"{0}\"", url);
+ return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", url);
}
return GetConcatInputArgument(inputFiles);
@@ -33,7 +34,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
var files = string.Join("|", inputFiles.Select(NormalizePath));
- return string.Format("concat:\"{0}\"", files);
+ return string.Format(CultureInfo.InvariantCulture, "concat:\"{0}\"", files);
}
// Determine the input path for video files
@@ -49,13 +50,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
if (path.IndexOf("://") != -1)
{
- return string.Format("\"{0}\"", path);
+ return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", path);
}
// Quotes are valid path characters in linux and they need to be escaped here with a leading \
path = NormalizePath(path);
- return string.Format("file:\"{0}\"", path);
+ return string.Format(CultureInfo.InvariantCulture, "file:\"{0}\"", path);
}
///
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 778c0b18c2..b9a6432ad2 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -552,8 +552,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
// Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case.
var thumbnail = enableThumbnail ? ",thumbnail=24" : string.Empty;
- var args = useIFrame ? string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}{4}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, thumbnail) :
- string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg);
+ var args = useIFrame ? string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}{4}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, thumbnail) :
+ string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg);
var probeSizeArgument = EncodingHelper.GetProbeSizeArgument(1);
var analyzeDurationArgument = EncodingHelper.GetAnalyzeDurationArgument(1);
@@ -570,7 +570,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (offset.HasValue)
{
- args = string.Format("-ss {0} ", GetTimeParameter(offset.Value)) + args;
+ args = string.Format(CultureInfo.InvariantCulture, "-ss {0} ", GetTimeParameter(offset.Value)) + args;
}
if (videoStream != null)
@@ -641,7 +641,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (exitCode == -1 || !file.Exists || file.Length == 0)
{
- var msg = string.Format("ffmpeg image extraction failed for {0}", inputPath);
+ var msg = string.Format(CultureInfo.InvariantCulture, "ffmpeg image extraction failed for {0}", inputPath);
_logger.LogError(msg);
@@ -684,13 +684,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
var maxWidthParam = maxWidth.Value.ToString(_usCulture);
- vf += string.Format(",scale=min(iw\\,{0}):trunc(ow/dar/2)*2", maxWidthParam);
+ vf += string.Format(CultureInfo.InvariantCulture, ",scale=min(iw\\,{0}):trunc(ow/dar/2)*2", maxWidthParam);
}
Directory.CreateDirectory(targetDirectory);
var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg");
- var args = string.Format("-i {0} -threads 0 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf);
+ var args = string.Format(CultureInfo.InvariantCulture, "-i {0} -threads 0 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf);
var probeSizeArgument = EncodingHelper.GetProbeSizeArgument(1);
var analyzeDurationArgument = EncodingHelper.GetAnalyzeDurationArgument(1);
@@ -790,7 +790,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (exitCode == -1)
{
- var msg = string.Format("ffmpeg image extraction failed for {0}", inputArgument);
+ var msg = string.Format(CultureInfo.InvariantCulture, "ffmpeg image extraction failed for {0}", inputArgument);
_logger.LogError(msg);
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index 374e35b969..fbe8bd69f7 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -435,7 +435,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
CreateNoWindow = true,
UseShellExecute = false,
FileName = _mediaEncoder.EncoderPath,
- Arguments = string.Format("{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath),
+ Arguments = string.Format(CultureInfo.InvariantCulture, "{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath),
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false
},
diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
index a579f8464d..93e60753ae 100644
--- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
+++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
@@ -157,7 +157,7 @@ namespace MediaBrowser.Model.Dlna
// flagValue = flagValue | DlnaFlags.TimeBasedSeek;
//}
- string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}",
+ string dlnaflags = string.Format(CultureInfo.InvariantCulture, ";DLNA.ORG_FLAGS={0}",
DlnaMaps.FlagsToString(flagValue));
ResponseProfile mediaProfile = _profile.GetVideoMediaProfile(container,
diff --git a/MediaBrowser.Model/Dlna/DlnaMaps.cs b/MediaBrowser.Model/Dlna/DlnaMaps.cs
index 052b4b78b0..95cd0ac276 100644
--- a/MediaBrowser.Model/Dlna/DlnaMaps.cs
+++ b/MediaBrowser.Model/Dlna/DlnaMaps.cs
@@ -1,18 +1,20 @@
#pragma warning disable CS1591
+using System.Globalization;
+
namespace MediaBrowser.Model.Dlna
{
public static class DlnaMaps
{
private static readonly string DefaultStreaming =
- FlagsToString(DlnaFlags.StreamingTransferMode |
+ FlagsToString(DlnaFlags.StreamingTransferMode |
DlnaFlags.BackgroundTransferMode |
DlnaFlags.ConnectionStall |
DlnaFlags.ByteBasedSeek |
DlnaFlags.DlnaV15);
private static readonly string DefaultInteractive =
- FlagsToString(DlnaFlags.InteractiveTransferMode |
+ FlagsToString(DlnaFlags.InteractiveTransferMode |
DlnaFlags.BackgroundTransferMode |
DlnaFlags.ConnectionStall |
DlnaFlags.ByteBasedSeek |
@@ -20,7 +22,7 @@ namespace MediaBrowser.Model.Dlna
public static string FlagsToString(DlnaFlags flags)
{
- return string.Format("{0:X8}{1:D24}", (ulong)flags, 0);
+ return string.Format(CultureInfo.InvariantCulture, "{0:X8}{1:D24}", (ulong)flags, 0);
}
public static string GetOrgOpValue(bool hasKnownRuntime, bool isDirectStream, TranscodeSeekInfo profileTranscodeSeekInfo)
diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
index bdc5f8bb78..3c955989a1 100644
--- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
+++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using MediaBrowser.Model.MediaInfo;
@@ -142,26 +143,26 @@ namespace MediaBrowser.Model.Dlna
{
if (timestampType == TransportStreamTimestamp.None)
{
- return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_HP_{0}D_MPEG1_L2_ISO", resolution)) };
+ return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_HP_{0}D_MPEG1_L2_ISO", resolution)) };
}
- return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_HP_{0}D_MPEG1_L2_T", resolution)) };
+ return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_HP_{0}D_MPEG1_L2_T", resolution)) };
}
if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
{
- return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_MP_{0}D_AAC_MULT5{1}", resolution, suffix)) };
+ return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_MP_{0}D_AAC_MULT5{1}", resolution, suffix)) };
}
if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
{
- return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_MP_{0}D_MPEG1_L3{1}", resolution, suffix)) };
+ return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_MP_{0}D_MPEG1_L3{1}", resolution, suffix)) };
}
if (string.IsNullOrEmpty(audioCodec) ||
string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
{
- return new MediaFormatProfile[] { ValueOf(string.Format("AVC_TS_MP_{0}D_AC3{1}", resolution, suffix)) };
+ return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "AVC_TS_MP_{0}D_AC3{1}", resolution, suffix)) };
}
}
else if (string.Equals(videoCodec, "vc1", StringComparison.OrdinalIgnoreCase))
@@ -180,29 +181,29 @@ namespace MediaBrowser.Model.Dlna
{
suffix = string.Equals(suffix, "_ISO", StringComparison.OrdinalIgnoreCase) ? suffix : "_T";
- return new MediaFormatProfile[] { ValueOf(string.Format("VC1_TS_HD_DTS{0}", suffix)) };
+ return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "VC1_TS_HD_DTS{0}", suffix)) };
}
}
else if (string.Equals(videoCodec, "mpeg4", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase))
{
if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
{
- return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AAC{0}", suffix)) };
+ return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_AAC{0}", suffix)) };
}
if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
{
- return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_MPEG1_L3{0}", suffix)) };
+ return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_MPEG1_L3{0}", suffix)) };
}
if (string.Equals(audioCodec, "mp2", StringComparison.OrdinalIgnoreCase))
{
- return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_MPEG2_L2{0}", suffix)) };
+ return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_MPEG2_L2{0}", suffix)) };
}
if (string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
{
- return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AC3{0}", suffix)) };
+ return new MediaFormatProfile[] { ValueOf(string.Format(CultureInfo.InvariantCulture, "MPEG4_P2_TS_ASP_AC3{0}", suffix)) };
}
}
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 204340c466..94d53ab70e 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -191,7 +191,7 @@ namespace MediaBrowser.Model.Dlna
var encodedValue = pair.Value.Replace(" ", "%20");
- list.Add(string.Format("{0}={1}", pair.Name, encodedValue));
+ list.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Name, encodedValue));
}
string queryString = string.Join("&", list.ToArray());
@@ -214,18 +214,18 @@ namespace MediaBrowser.Model.Dlna
{
if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
{
- return string.Format("{0}/audio/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
+ return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
}
- return string.Format("{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
+ return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
}
if (string.Equals(SubProtocol, "hls", StringComparison.OrdinalIgnoreCase))
{
- return string.Format("{0}/videos/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
+ return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
}
- return string.Format("{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
+ return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
}
private static List BuildParams(StreamInfo item, string accessToken)
@@ -457,7 +457,7 @@ namespace MediaBrowser.Model.Dlna
{
if (MediaSource.Protocol == MediaProtocol.File || !string.Equals(stream.Codec, subtitleProfile.Format, StringComparison.OrdinalIgnoreCase) || !stream.IsExternal)
{
- info.Url = string.Format("{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}",
+ info.Url = string.Format(CultureInfo.InvariantCulture, "{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}",
baseUrl,
ItemId,
MediaSourceId,
diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs
index 26b50784b1..413d297cb5 100644
--- a/MediaBrowser.Providers/Manager/ImageSaver.cs
+++ b/MediaBrowser.Providers/Manager/ImageSaver.cs
@@ -187,7 +187,7 @@ namespace MediaBrowser.Providers.Manager
}
}
- public async Task SaveImage(User user, Stream source, string path)
+ public async Task SaveImage(Stream source, string path)
{
await SaveImageToLocation(source, path, path, CancellationToken.None).ConfigureAwait(false);
}
@@ -355,7 +355,7 @@ namespace MediaBrowser.Providers.Manager
if (string.IsNullOrWhiteSpace(extension))
{
- throw new ArgumentException(string.Format("Unable to determine image file extension from mime type {0}", mimeType));
+ throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Unable to determine image file extension from mime type {0}", mimeType));
}
if (type == ImageType.Thumb && saveLocally)
diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
index a5eb095c46..9227b6d937 100644
--- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs
+++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
@@ -54,7 +54,12 @@ namespace MediaBrowser.Providers.Manager
return hasChanges;
}
- public async Task RefreshImages(BaseItem item, LibraryOptions libraryOptions, List providers, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, CancellationToken cancellationToken)
+ public async Task RefreshImages(
+ BaseItem item,
+ LibraryOptions libraryOptions,
+ List providers,
+ ImageRefreshOptions refreshOptions,
+ CancellationToken cancellationToken)
{
if (refreshOptions.IsReplacingImage(ImageType.Backdrop))
{
@@ -78,19 +83,15 @@ namespace MediaBrowser.Providers.Manager
foreach (var provider in providers)
{
- var remoteProvider = provider as IRemoteImageProvider;
-
- if (remoteProvider != null)
+ if (provider is IRemoteImageProvider remoteProvider)
{
await RefreshFromProvider(item, libraryOptions, remoteProvider, refreshOptions, typeOptions, backdropLimit, screenshotLimit, downloadedImages, result, cancellationToken).ConfigureAwait(false);
continue;
}
- var dynamicImageProvider = provider as IDynamicImageProvider;
-
- if (dynamicImageProvider != null)
+ if (provider is IDynamicImageProvider dynamicImageProvider)
{
- await RefreshFromProvider(item, dynamicImageProvider, refreshOptions, typeOptions, libraryOptions, downloadedImages, result, cancellationToken).ConfigureAwait(false);
+ await RefreshFromProvider(item, dynamicImageProvider, refreshOptions, typeOptions, downloadedImages, result, cancellationToken).ConfigureAwait(false);
}
}
@@ -100,11 +101,11 @@ namespace MediaBrowser.Providers.Manager
///
/// Refreshes from provider.
///
- private async Task RefreshFromProvider(BaseItem item,
+ private async Task RefreshFromProvider(
+ BaseItem item,
IDynamicImageProvider provider,
ImageRefreshOptions refreshOptions,
TypeOptions savedOptions,
- LibraryOptions libraryOptions,
ICollection downloadedImages,
RefreshResult result,
CancellationToken cancellationToken)
@@ -115,7 +116,7 @@ namespace MediaBrowser.Providers.Manager
foreach (var imageType in images)
{
- if (!IsEnabled(savedOptions, imageType, item))
+ if (!IsEnabled(savedOptions, imageType))
{
continue;
}
@@ -133,12 +134,13 @@ namespace MediaBrowser.Providers.Manager
if (response.Protocol == MediaProtocol.Http)
{
_logger.LogDebug("Setting image url into item {0}", item.Id);
- item.SetImage(new ItemImageInfo
- {
- Path = response.Path,
- Type = imageType
-
- }, 0);
+ item.SetImage(
+ new ItemImageInfo
+ {
+ Path = response.Path,
+ Type = imageType
+ },
+ 0);
}
else
{
@@ -157,7 +159,7 @@ namespace MediaBrowser.Providers.Manager
}
downloadedImages.Add(imageType);
- result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate;
+ result.UpdateType |= ItemUpdateType.ImageUpdate;
}
}
}
@@ -279,7 +281,7 @@ namespace MediaBrowser.Providers.Manager
foreach (var imageType in _singularImages)
{
- if (!IsEnabled(savedOptions, imageType, item))
+ if (!IsEnabled(savedOptions, imageType))
{
continue;
}
@@ -299,8 +301,7 @@ namespace MediaBrowser.Providers.Manager
minWidth = savedOptions.GetMinWidth(ImageType.Backdrop);
await DownloadBackdrops(item, libraryOptions, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
- var hasScreenshots = item as IHasScreenshots;
- if (hasScreenshots != null)
+ if (item is IHasScreenshots hasScreenshots)
{
minWidth = savedOptions.GetMinWidth(ImageType.Screenshot);
await DownloadBackdrops(item, libraryOptions, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
@@ -317,7 +318,7 @@ namespace MediaBrowser.Providers.Manager
}
}
- private bool IsEnabled(TypeOptions options, ImageType type, BaseItem item)
+ private bool IsEnabled(TypeOptions options, ImageType type)
{
return options.IsEnabled(type);
}
@@ -452,10 +453,10 @@ namespace MediaBrowser.Providers.Manager
.Where(i => i.Type == type && !(i.Width.HasValue && i.Width.Value < minWidth))
.ToList();
- if (EnableImageStub(item, type, libraryOptions) && eligibleImages.Count > 0)
+ if (EnableImageStub(item, libraryOptions) && eligibleImages.Count > 0)
{
SaveImageStub(item, type, eligibleImages.Select(i => i.Url));
- result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate;
+ result.UpdateType |= ItemUpdateType.ImageUpdate;
return true;
}
@@ -476,7 +477,7 @@ namespace MediaBrowser.Providers.Manager
null,
cancellationToken).ConfigureAwait(false);
- result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate;
+ result.UpdateType |= ItemUpdateType.ImageUpdate;
return true;
}
catch (HttpException ex)
@@ -495,7 +496,7 @@ namespace MediaBrowser.Providers.Manager
return false;
}
- private bool EnableImageStub(BaseItem item, ImageType type, LibraryOptions libraryOptions)
+ private bool EnableImageStub(BaseItem item, LibraryOptions libraryOptions)
{
if (item is LiveTvProgram)
{
@@ -563,10 +564,10 @@ namespace MediaBrowser.Providers.Manager
var url = image.Url;
- if (EnableImageStub(item, imageType, libraryOptions))
+ if (EnableImageStub(item, libraryOptions))
{
SaveImageStub(item, imageType, new[] { url });
- result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate;
+ result.UpdateType |= ItemUpdateType.ImageUpdate;
continue;
}
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index 3b0c7b56ca..dcae300fc1 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -52,7 +52,6 @@ namespace MediaBrowser.Providers.Manager
public async Task RefreshMetadata(BaseItem item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
{
var itemOfType = (TItemType)item;
- var config = ProviderManager.GetMetadataOptions(item);
var updateType = ItemUpdateType.None;
var requiresRefresh = false;
@@ -86,7 +85,7 @@ namespace MediaBrowser.Providers.Manager
// Always validate images and check for new locally stored ones.
if (itemImageProvider.ValidateImages(item, allImageProviders.OfType(), refreshOptions.DirectoryService))
{
- updateType = updateType | ItemUpdateType.ImageUpdate;
+ updateType |= ItemUpdateType.ImageUpdate;
}
}
catch (Exception ex)
@@ -102,7 +101,7 @@ namespace MediaBrowser.Providers.Manager
bool hasRefreshedMetadata = true;
bool hasRefreshedImages = true;
- var isFirstRefresh = item.DateLastRefreshed == default(DateTime);
+ var isFirstRefresh = item.DateLastRefreshed == default;
// Next run metadata providers
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
@@ -114,7 +113,7 @@ namespace MediaBrowser.Providers.Manager
{
if (item.BeforeMetadataRefresh(refreshOptions.ReplaceAllMetadata))
{
- updateType = updateType | ItemUpdateType.MetadataImport;
+ updateType |= ItemUpdateType.MetadataImport;
}
}
@@ -132,7 +131,7 @@ namespace MediaBrowser.Providers.Manager
var result = await RefreshWithProviders(metadataResult, id, refreshOptions, providers, itemImageProvider, cancellationToken).ConfigureAwait(false);
- updateType = updateType | result.UpdateType;
+ updateType |= result.UpdateType;
if (result.Failures > 0)
{
hasRefreshedMetadata = false;
@@ -147,9 +146,9 @@ namespace MediaBrowser.Providers.Manager
if (providers.Count > 0)
{
- var result = await itemImageProvider.RefreshImages(itemOfType, libraryOptions, providers, refreshOptions, config, cancellationToken).ConfigureAwait(false);
+ var result = await itemImageProvider.RefreshImages(itemOfType, libraryOptions, providers, refreshOptions, cancellationToken).ConfigureAwait(false);
- updateType = updateType | result.UpdateType;
+ updateType |= result.UpdateType;
if (result.Failures > 0)
{
hasRefreshedImages = false;
@@ -158,7 +157,7 @@ namespace MediaBrowser.Providers.Manager
}
var beforeSaveResult = BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || requiresRefresh || refreshOptions.ForceSave, updateType);
- updateType = updateType | beforeSaveResult;
+ updateType |= beforeSaveResult;
// Save if changes were made, or it's never been saved before
if (refreshOptions.ForceSave || updateType > ItemUpdateType.None || isFirstRefresh || refreshOptions.ReplaceAllMetadata || requiresRefresh)
@@ -175,7 +174,7 @@ namespace MediaBrowser.Providers.Manager
// If any of these properties are set then make sure the updateType is not None, just to force everything to save
if (refreshOptions.ForceSave || refreshOptions.ReplaceAllMetadata)
{
- updateType = updateType | ItemUpdateType.MetadataDownload;
+ updateType |= ItemUpdateType.MetadataDownload;
}
if (hasRefreshedMetadata && hasRefreshedImages)
@@ -184,11 +183,11 @@ namespace MediaBrowser.Providers.Manager
}
else
{
- item.DateLastRefreshed = default(DateTime);
+ item.DateLastRefreshed = default;
}
// Save to database
- SaveItem(metadataResult, libraryOptions, updateType, cancellationToken);
+ await SaveItemAsync(metadataResult, libraryOptions, updateType, cancellationToken).ConfigureAwait(false);
}
await AfterMetadataRefresh(itemOfType, refreshOptions, cancellationToken).ConfigureAwait(false);
@@ -203,26 +202,26 @@ namespace MediaBrowser.Providers.Manager
lookupInfo.Year = result.ProductionYear;
}
- protected void SaveItem(MetadataResult result, LibraryOptions libraryOptions, ItemUpdateType reason, CancellationToken cancellationToken)
+ protected async Task SaveItemAsync(MetadataResult result, LibraryOptions libraryOptions, ItemUpdateType reason, CancellationToken cancellationToken)
{
if (result.Item.SupportsPeople && result.People != null)
{
var baseItem = result.Item;
LibraryManager.UpdatePeople(baseItem, result.People);
- SavePeopleMetadata(result.People, libraryOptions, cancellationToken);
+ await SavePeopleMetadataAsync(result.People, libraryOptions, cancellationToken).ConfigureAwait(false);
}
result.Item.UpdateToRepository(reason, cancellationToken);
}
- private void SavePeopleMetadata(List people, LibraryOptions libraryOptions, CancellationToken cancellationToken)
+ private async Task SavePeopleMetadataAsync(List people, LibraryOptions libraryOptions, CancellationToken cancellationToken)
{
foreach (var person in people)
{
cancellationToken.ThrowIfCancellationRequested();
- if (person.ProviderIds.Any() || !string.IsNullOrWhiteSpace(person.ImageUrl))
+ if (person.ProviderIds.Count > 0 || !string.IsNullOrWhiteSpace(person.ImageUrl))
{
var updateType = ItemUpdateType.MetadataDownload;
@@ -239,10 +238,10 @@ namespace MediaBrowser.Providers.Manager
if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary))
{
- AddPersonImage(personEntity, libraryOptions, person.ImageUrl, cancellationToken);
+ await AddPersonImageAsync(personEntity, libraryOptions, person.ImageUrl, cancellationToken).ConfigureAwait(false);
saveEntity = true;
- updateType = updateType | ItemUpdateType.ImageUpdate;
+ updateType |= ItemUpdateType.ImageUpdate;
}
if (saveEntity)
@@ -253,26 +252,28 @@ namespace MediaBrowser.Providers.Manager
}
}
- private void AddPersonImage(Person personEntity, LibraryOptions libraryOptions, string imageUrl, CancellationToken cancellationToken)
+ private async Task AddPersonImageAsync(Person personEntity, LibraryOptions libraryOptions, string imageUrl, CancellationToken cancellationToken)
{
- // if (libraryOptions.DownloadImagesInAdvance)
- //{
- // try
- // {
- // await ProviderManager.SaveImage(personEntity, imageUrl, ImageType.Primary, null, cancellationToken).ConfigureAwait(false);
- // return;
- // }
- // catch (Exception ex)
- // {
- // Logger.LogError(ex, "Error in AddPersonImage");
- // }
- //}
-
- personEntity.SetImage(new ItemImageInfo
- {
- Path = imageUrl,
- Type = ImageType.Primary
- }, 0);
+ if (libraryOptions.DownloadImagesInAdvance)
+ {
+ try
+ {
+ await ProviderManager.SaveImage(personEntity, imageUrl, ImageType.Primary, null, cancellationToken).ConfigureAwait(false);
+ return;
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError(ex, "Error in AddPersonImage");
+ }
+ }
+
+ personEntity.SetImage(
+ new ItemImageInfo
+ {
+ Path = imageUrl,
+ Type = ImageType.Primary
+ },
+ 0);
}
protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index e67d1b8c37..d9a84be5cc 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -210,10 +210,10 @@ namespace MediaBrowser.Providers.Manager
}
///
- public Task SaveImage(User user, Stream source, string mimeType, string path)
+ public Task SaveImage(Stream source, string mimeType, string path)
{
return new ImageSaver(_configurationManager, _libraryMonitor, _fileSystem, _logger)
- .SaveImage(user, source, path);
+ .SaveImage(source, path);
}
///
@@ -563,7 +563,7 @@ namespace MediaBrowser.Providers.Manager
var pluginList = summary.Plugins.ToList();
AddMetadataPlugins(pluginList, dummy, libraryOptions, options);
- AddImagePlugins(pluginList, dummy, imageProviders);
+ AddImagePlugins(pluginList, imageProviders);
var subtitleProviders = _subtitleManager.GetSupportedProviders(dummy);
@@ -594,14 +594,14 @@ namespace MediaBrowser.Providers.Manager
var providers = GetMetadataProvidersInternal(item, libraryOptions, options, true, true).ToList();
// Locals
- list.AddRange(providers.Where(i => (i is ILocalMetadataProvider)).Select(i => new MetadataPlugin
+ list.AddRange(providers.Where(i => i is ILocalMetadataProvider).Select(i => new MetadataPlugin
{
Name = i.Name,
Type = MetadataPluginType.LocalMetadataProvider
}));
// Fetchers
- list.AddRange(providers.Where(i => (i is IRemoteMetadataProvider)).Select(i => new MetadataPlugin
+ list.AddRange(providers.Where(i => i is IRemoteMetadataProvider).Select(i => new MetadataPlugin
{
Name = i.Name,
Type = MetadataPluginType.MetadataFetcher
@@ -615,11 +615,10 @@ namespace MediaBrowser.Providers.Manager
}));
}
- private void AddImagePlugins(List list, T item, List imageProviders)
- where T : BaseItem
+ private void AddImagePlugins(List list, List imageProviders)
{
// Locals
- list.AddRange(imageProviders.Where(i => (i is ILocalImageProvider)).Select(i => new MetadataPlugin
+ list.AddRange(imageProviders.Where(i => i is ILocalImageProvider).Select(i => new MetadataPlugin
{
Name = i.Name,
Type = MetadataPluginType.LocalImageProvider
@@ -1166,12 +1165,32 @@ namespace MediaBrowser.Providers.Manager
///
public void Dispose()
{
- _disposed = true;
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Releases unmanaged and optionally managed resources.
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
if (!_disposeCancellationTokenSource.IsCancellationRequested)
{
_disposeCancellationTokenSource.Cancel();
}
+
+ if (disposing)
+ {
+ _disposeCancellationTokenSource.Dispose();
+ }
+
+ _disposed = true;
}
}
}
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
index 69c6fd7222..77f03580ab 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
@@ -2,11 +2,9 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
@@ -17,7 +15,6 @@ using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo;
-using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Providers.MediaInfo
{
@@ -25,19 +22,17 @@ namespace MediaBrowser.Providers.MediaInfo
{
private readonly IMediaEncoder _mediaEncoder;
private readonly IItemRepository _itemRepo;
- private readonly IApplicationPaths _appPaths;
- private readonly IJsonSerializer _json;
private readonly ILibraryManager _libraryManager;
private readonly IMediaSourceManager _mediaSourceManager;
- private readonly CultureInfo _usCulture = new CultureInfo("en-US");
-
- public FFProbeAudioInfo(IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, IItemRepository itemRepo, IApplicationPaths appPaths, IJsonSerializer json, ILibraryManager libraryManager)
+ public FFProbeAudioInfo(
+ IMediaSourceManager mediaSourceManager,
+ IMediaEncoder mediaEncoder,
+ IItemRepository itemRepo,
+ ILibraryManager libraryManager)
{
_mediaEncoder = mediaEncoder;
_itemRepo = itemRepo;
- _appPaths = appPaths;
- _json = json;
_libraryManager = libraryManager;
_mediaSourceManager = mediaSourceManager;
}
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
index 4fabe709be..9926275ae7 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
@@ -40,19 +40,15 @@ namespace MediaBrowser.Providers.MediaInfo
IHasItemChangeMonitor
{
private readonly ILogger _logger;
- private readonly IIsoManager _isoManager;
private readonly IMediaEncoder _mediaEncoder;
private readonly IItemRepository _itemRepo;
private readonly IBlurayExaminer _blurayExaminer;
private readonly ILocalizationManager _localization;
- private readonly IApplicationPaths _appPaths;
- private readonly IJsonSerializer _json;
private readonly IEncodingManager _encodingManager;
private readonly IServerConfigurationManager _config;
private readonly ISubtitleManager _subtitleManager;
private readonly IChapterManager _chapterManager;
private readonly ILibraryManager _libraryManager;
- private readonly IChannelManager _channelManager;
private readonly IMediaSourceManager _mediaSourceManager;
public string Name => "ffprobe";
@@ -126,14 +122,10 @@ namespace MediaBrowser.Providers.MediaInfo
public FFProbeProvider(
ILogger logger,
IMediaSourceManager mediaSourceManager,
- IChannelManager channelManager,
- IIsoManager isoManager,
IMediaEncoder mediaEncoder,
IItemRepository itemRepo,
IBlurayExaminer blurayExaminer,
ILocalizationManager localization,
- IApplicationPaths appPaths,
- IJsonSerializer json,
IEncodingManager encodingManager,
IServerConfigurationManager config,
ISubtitleManager subtitleManager,
@@ -141,19 +133,15 @@ namespace MediaBrowser.Providers.MediaInfo
ILibraryManager libraryManager)
{
_logger = logger;
- _isoManager = isoManager;
_mediaEncoder = mediaEncoder;
_itemRepo = itemRepo;
_blurayExaminer = blurayExaminer;
_localization = localization;
- _appPaths = appPaths;
- _json = json;
_encodingManager = encodingManager;
_config = config;
_subtitleManager = subtitleManager;
_chapterManager = chapterManager;
_libraryManager = libraryManager;
- _channelManager = channelManager;
_mediaSourceManager = mediaSourceManager;
_subtitleResolver = new SubtitleResolver(BaseItem.LocalizationManager);
@@ -211,9 +199,9 @@ namespace MediaBrowser.Providers.MediaInfo
private string NormalizeStrmLine(string line)
{
- return line.Replace("\t", string.Empty)
- .Replace("\r", string.Empty)
- .Replace("\n", string.Empty)
+ return line.Replace("\t", string.Empty, StringComparison.Ordinal)
+ .Replace("\r", string.Empty, StringComparison.Ordinal)
+ .Replace("\n", string.Empty, StringComparison.Ordinal)
.Trim();
}
@@ -242,10 +230,11 @@ namespace MediaBrowser.Providers.MediaInfo
FetchShortcutInfo(item);
}
- var prober = new FFProbeAudioInfo(_mediaSourceManager, _mediaEncoder, _itemRepo, _appPaths, _json, _libraryManager);
+ var prober = new FFProbeAudioInfo(_mediaSourceManager, _mediaEncoder, _itemRepo, _libraryManager);
return prober.Probe(item, options, cancellationToken);
}
+
// Run last
public int Order => 100;
}
diff --git a/MediaBrowser.Providers/Music/Extensions.cs b/MediaBrowser.Providers/Music/Extensions.cs
index b57d352560..dddfd02e4f 100644
--- a/MediaBrowser.Providers/Music/Extensions.cs
+++ b/MediaBrowser.Providers/Music/Extensions.cs
@@ -6,7 +6,7 @@ using MediaBrowser.Model.Entities;
namespace MediaBrowser.Providers.Music
{
- public static class Extensions
+ public static class AlbumInfoExtensions
{
public static string GetAlbumArtist(this AlbumInfo info)
{
@@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Music
return id;
}
- return info.AlbumArtists.FirstOrDefault();
+ return info.AlbumArtists.Count > 0 ? info.AlbumArtists[0] : default;
}
public static string GetReleaseGroupId(this AlbumInfo info)
diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs
index 23acb7fd6a..3550614dd3 100644
--- a/MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs
+++ b/MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs
@@ -276,7 +276,7 @@ namespace MediaBrowser.Providers.Music
private async Task GetReleaseResult(string albumName, string artistId, CancellationToken cancellationToken)
{
- var url = string.Format("/ws/2/release/?query=\"{0}\" AND arid:{1}",
+ var url = string.Format(CultureInfo.InvariantCulture, "/ws/2/release/?query=\"{0}\" AND arid:{1}",
WebUtility.UrlEncode(albumName),
artistId);
diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs
index b829ed3780..781b716406 100644
--- a/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs
+++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs
@@ -46,7 +46,7 @@ namespace MediaBrowser.Providers.Music
// They seem to throw bad request failures on any term with a slash
var nameToSearch = searchInfo.Name.Replace('/', ' ');
- var url = string.Format("/ws/2/artist/?query=\"{0}\"&dismax=true", UrlEncode(nameToSearch));
+ var url = string.Format(CultureInfo.InvariantCulture, "/ws/2/artist/?query=\"{0}\"&dismax=true", UrlEncode(nameToSearch));
using (var response = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false))
await using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
@@ -62,7 +62,7 @@ namespace MediaBrowser.Providers.Music
if (HasDiacritics(searchInfo.Name))
{
// Try again using the search with accent characters url
- url = string.Format("/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
+ url = string.Format(CultureInfo.InvariantCulture, "/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
using var response = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs
index 41e664aace..c18725e0aa 100644
--- a/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Net.Http;
+using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common;
@@ -70,7 +71,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
list.Add(new RemoteImageInfo
{
ProviderName = Name,
- Url = string.Format("https://img.omdbapi.com/?i={0}&apikey=2c9d9507", imdbId)
+ Url = string.Format(CultureInfo.InvariantCulture, "https://img.omdbapi.com/?i={0}&apikey=2c9d9507", imdbId)
});
}
}
diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs
index d2823a08c3..102ad82e17 100644
--- a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs
@@ -127,7 +127,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
}
}
- var url = OmdbProvider.GetOmdbUrl(urlQuery, _appHost, cancellationToken);
+ var url = OmdbProvider.GetOmdbUrl(urlQuery);
using var response = await OmdbProvider.GetOmdbResponse(_httpClientFactory.CreateClient(), url, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs
index 6ad5298deb..c45149c3a7 100644
--- a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs
@@ -256,16 +256,16 @@ namespace MediaBrowser.Providers.Plugins.Omdb
return false;
}
- public static string GetOmdbUrl(string query, IApplicationHost appHost, CancellationToken cancellationToken)
+ public static string GetOmdbUrl(string query)
{
- const string url = "https://www.omdbapi.com?apikey=2c9d9507";
+ const string Url = "https://www.omdbapi.com?apikey=2c9d9507";
if (string.IsNullOrWhiteSpace(query))
{
- return url;
+ return Url;
}
- return url + "&" + query;
+ return Url + "&" + query;
}
private async Task EnsureItemInfo(string imdbId, CancellationToken cancellationToken)
@@ -290,7 +290,11 @@ namespace MediaBrowser.Providers.Plugins.Omdb
}
}
- var url = GetOmdbUrl(string.Format("i={0}&plot=short&tomatoes=true&r=json", imdbParam), _appHost, cancellationToken);
+ var url = GetOmdbUrl(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "i={0}&plot=short&tomatoes=true&r=json",
+ imdbParam));
using var response = await GetOmdbResponse(_httpClientFactory.CreateClient(), url, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
@@ -323,7 +327,12 @@ namespace MediaBrowser.Providers.Plugins.Omdb
}
}
- var url = GetOmdbUrl(string.Format("i={0}&season={1}&detail=full", imdbParam, seasonId), _appHost, cancellationToken);
+ var url = GetOmdbUrl(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "i={0}&season={1}&detail=full",
+ imdbParam,
+ seasonId));
using var response = await GetOmdbResponse(_httpClientFactory.CreateClient(), url, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
@@ -348,7 +357,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var dataPath = Path.Combine(_configurationManager.ApplicationPaths.CachePath, "omdb");
- var filename = string.Format("{0}.json", imdbId);
+ var filename = string.Format(CultureInfo.InvariantCulture, "{0}.json", imdbId);
return Path.Combine(dataPath, filename);
}
@@ -362,7 +371,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var dataPath = Path.Combine(_configurationManager.ApplicationPaths.CachePath, "omdb");
- var filename = string.Format("{0}_season_{1}.json", imdbId, seasonId);
+ var filename = string.Format(CultureInfo.InvariantCulture, "{0}_season_{1}.json", imdbId, seasonId);
return Path.Combine(dataPath, filename);
}
diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs
index cd2f96f14a..f22d484abc 100644
--- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs
+++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -19,7 +20,6 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
{
private const string DefaultLanguage = "en";
- private readonly SemaphoreSlim _cacheWriteLock = new SemaphoreSlim(1, 1);
private readonly IMemoryCache _cache;
private readonly TvDbClient _tvDbClient;
private DateTime _tokenCreatedAt;
@@ -176,7 +176,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
string language,
CancellationToken cancellationToken)
{
- searchInfo.SeriesProviderIds.TryGetValue(MetadataProvider.Tvdb.ToString(),
+ searchInfo.SeriesProviderIds.TryGetValue(nameof(MetadataProvider.Tvdb),
out var seriesTvdbId);
var episodeQuery = new EpisodeQuery();
@@ -203,10 +203,10 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
else if (searchInfo.PremiereDate.HasValue)
{
// tvdb expects yyyy-mm-dd format
- episodeQuery.FirstAired = searchInfo.PremiereDate.Value.ToString("yyyy-MM-dd");
+ episodeQuery.FirstAired = searchInfo.PremiereDate.Value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
}
- return GetEpisodeTvdbId(Convert.ToInt32(seriesTvdbId), episodeQuery, language, cancellationToken);
+ return GetEpisodeTvdbId(Convert.ToInt32(seriesTvdbId, CultureInfo.InvariantCulture), episodeQuery, language, cancellationToken);
}
public async Task GetEpisodeTvdbId(
@@ -218,7 +218,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
var episodePage =
await GetEpisodesPageAsync(Convert.ToInt32(seriesTvdbId), episodeQuery, language, cancellationToken)
.ConfigureAwait(false);
- return episodePage.Data.FirstOrDefault()?.Id.ToString();
+ return episodePage.Data.FirstOrDefault()?.Id.ToString(CultureInfo.InvariantCulture);
}
public Task> GetEpisodesPageAsync(
@@ -276,23 +276,10 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
return cachedValue;
}
- await _cacheWriteLock.WaitAsync().ConfigureAwait(false);
- try
- {
- if (_cache.TryGetValue(key, out cachedValue))
- {
- return cachedValue;
- }
-
- _tvDbClient.AcceptedLanguage = TvdbUtils.NormalizeLanguage(language) ?? DefaultLanguage;
- var result = await resultFactory.Invoke().ConfigureAwait(false);
- _cache.Set(key, result, TimeSpan.FromHours(1));
- return result;
- }
- finally
- {
- _cacheWriteLock.Release();
- }
+ _tvDbClient.AcceptedLanguage = TvdbUtils.NormalizeLanguage(language) ?? DefaultLanguage;
+ var result = await resultFactory.Invoke().ConfigureAwait(false);
+ _cache.Set(key, result, TimeSpan.FromHours(1));
+ return result;
}
private static string GenerateKey(params object[] objects)
diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs
index 4d38d38dca..4e7c0e5a60 100644
--- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbEpisodeImageProvider.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
+using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
@@ -76,7 +77,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
var episodeResult =
await _tvdbClientManager
- .GetEpisodesAsync(Convert.ToInt32(episodeTvdbId), language, cancellationToken)
+ .GetEpisodesAsync(Convert.ToInt32(episodeTvdbId, CultureInfo.InvariantCulture), language, cancellationToken)
.ConfigureAwait(false);
var image = GetImageInfo(episodeResult.Data);
@@ -103,8 +104,8 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
return new RemoteImageInfo
{
- Width = Convert.ToInt32(episode.ThumbWidth),
- Height = Convert.ToInt32(episode.ThumbHeight),
+ Width = Convert.ToInt32(episode.ThumbWidth, CultureInfo.InvariantCulture),
+ Height = Convert.ToInt32(episode.ThumbHeight, CultureInfo.InvariantCulture),
ProviderName = Name,
Url = TvdbUtils.BannerUrl + episode.Filename,
Type = ImageType.Primary
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs
index 4f86a0293a..4da2c042f6 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs
@@ -180,7 +180,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
if (!string.IsNullOrEmpty(language))
{
- url += string.Format("&language={0}", TmdbMovieProvider.NormalizeLanguage(language));
+ url += string.Format(CultureInfo.InvariantCulture, "&language={0}", TmdbMovieProvider.NormalizeLanguage(language));
// Get images in english and with no language
url += "&include_image_language=" + TmdbMovieProvider.GetImageLanguagesParam(language);
@@ -250,7 +250,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets
{
var path = GetDataPath(appPaths, tmdbId);
- var filename = string.Format("all-{0}.json", preferredLanguage ?? string.Empty);
+ var filename = string.Format(CultureInfo.InvariantCulture, "all-{0}.json", preferredLanguage ?? string.Empty);
return Path.Combine(path, filename);
}
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs
index 27ca3759eb..01a887eed5 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/GenericTmdbMovieInfo.cs
@@ -300,7 +300,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{
movie.RemoteTrailers = movieData.Trailers.Youtube.Select(i => new MediaUrl
{
- Url = string.Format("https://www.youtube.com/watch?v={0}", i.Source),
+ Url = string.Format(CultureInfo.InvariantCulture, "https://www.youtube.com/watch?v={0}", i.Source),
Name = i.Name
}).ToArray();
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbSearch.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbSearch.cs
index 48f2a68a63..b7c4a56430 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbSearch.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbSearch.cs
@@ -37,7 +37,8 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
).* # Match rest of string",
RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
- private const string _searchURL = TmdbUtils.BaseTmdbApiUrl + @"3/search/{3}?api_key={1}&query={0}&language={2}";
+ private const string SearchUrl = TmdbUtils.BaseTmdbApiUrl + @"3/search/{3}?api_key={1}&query={0}&language={2}";
+ private const string SearchUrlWithYear = TmdbUtils.BaseTmdbApiUrl + @"3/search/{3}?api_key={1}&query={0}&language={2}&first_air_date_year={4}";
private readonly ILogger _logger;
private readonly IJsonSerializer _json;
@@ -124,7 +125,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
name2 = name2.Trim();
// Search again if the new name is different
- if (!string.Equals(name2, name) && !string.IsNullOrWhiteSpace(name2))
+ if (!string.Equals(name2, name, StringComparison.Ordinal) && !string.IsNullOrWhiteSpace(name2))
{
_logger.LogInformation("TmdbSearch: Finding id for item: {0} ({1})", name2, year);
results = await GetSearchResults(name2, searchType, year, language, tmdbImageUrl, cancellationToken).ConfigureAwait(false);
@@ -164,10 +165,30 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{
if (string.IsNullOrWhiteSpace(name))
{
- throw new ArgumentException("name");
+ throw new ArgumentException("String can't be null or empty.", nameof(name));
}
- var url3 = string.Format(_searchURL, WebUtility.UrlEncode(name), TmdbUtils.ApiKey, language, type);
+ string url3;
+ if (year != null && string.Equals(type, "movie", StringComparison.OrdinalIgnoreCase))
+ {
+ url3 = string.Format(
+ CultureInfo.InvariantCulture,
+ SearchUrl,
+ WebUtility.UrlEncode(name),
+ TmdbUtils.ApiKey,
+ language,
+ type) + "&primary_release_year=" + year;
+ }
+ else
+ {
+ url3 = string.Format(
+ CultureInfo.InvariantCulture,
+ SearchUrl,
+ WebUtility.UrlEncode(name),
+ TmdbUtils.ApiKey,
+ language,
+ type);
+ }
var requestMessage = new HttpRequestMessage(HttpMethod.Get, url3);
foreach (var header in TmdbUtils.AcceptHeaders)
@@ -207,10 +228,31 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
{
if (string.IsNullOrWhiteSpace(name))
{
- throw new ArgumentException("name");
+ throw new ArgumentException("String can't be null or empty.", nameof(name));
}
- var url3 = string.Format(_searchURL, WebUtility.UrlEncode(name), TmdbUtils.ApiKey, language, "tv");
+ string url3;
+ if (year == null)
+ {
+ url3 = string.Format(
+ CultureInfo.InvariantCulture,
+ SearchUrl,
+ WebUtility.UrlEncode(name),
+ TmdbUtils.ApiKey,
+ language,
+ "tv");
+ }
+ else
+ {
+ url3 = string.Format(
+ CultureInfo.InvariantCulture,
+ SearchUrlWithYear,
+ WebUtility.UrlEncode(name),
+ TmdbUtils.ApiKey,
+ language,
+ "tv",
+ year);
+ }
var requestMessage = new HttpRequestMessage(HttpMethod.Get, url3);
foreach (var header in TmdbUtils.AcceptHeaders)
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs
index b4aef4542d..90e3cea932 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs
@@ -131,7 +131,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
{
if (video.Site.Equals("youtube", System.StringComparison.OrdinalIgnoreCase))
{
- var videoUrl = string.Format("http://www.youtube.com/watch?v={0}", video.Key);
+ var videoUrl = string.Format(CultureInfo.InvariantCulture, "http://www.youtube.com/watch?v={0}", video.Key);
item.AddTrailerUrl(videoUrl);
}
}
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProviderBase.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProviderBase.cs
index 154664321f..5705885b46 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProviderBase.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProviderBase.cs
@@ -92,7 +92,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var path = TmdbSeriesProvider.GetSeriesDataPath(_configurationManager.ApplicationPaths, tmdbId);
- var filename = string.Format("season-{0}-episode-{1}-{2}.json",
+ var filename = string.Format(CultureInfo.InvariantCulture, "season-{0}-episode-{1}-{2}.json",
seasonNumber.ToString(CultureInfo.InvariantCulture),
episodeNumber.ToString(CultureInfo.InvariantCulture),
preferredLanguage);
@@ -116,7 +116,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
if (!string.IsNullOrEmpty(language))
{
- url += string.Format("&language={0}", language);
+ url += string.Format(CultureInfo.InvariantCulture, "&language={0}", language);
}
var includeImageLanguageParam = TmdbMovieProvider.GetImageLanguagesParam(language);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs
index 2b9077f557..e59504cc6d 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonProvider.cs
@@ -180,7 +180,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var path = TmdbSeriesProvider.GetSeriesDataPath(_configurationManager.ApplicationPaths, tmdbId);
- var filename = string.Format("season-{0}-{1}.json",
+ var filename = string.Format(CultureInfo.InvariantCulture, "season-{0}-{1}.json",
seasonNumber.ToString(CultureInfo.InvariantCulture),
preferredLanguage);
@@ -203,7 +203,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
if (!string.IsNullOrEmpty(language))
{
- url += string.Format("&language={0}", TmdbMovieProvider.NormalizeLanguage(language));
+ url += string.Format(CultureInfo.InvariantCulture, "&language={0}", TmdbMovieProvider.NormalizeLanguage(language));
}
var includeImageLanguageParam = TmdbMovieProvider.GetImageLanguagesParam(language);
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs
index ac577b125a..0eded32330 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesProvider.cs
@@ -496,7 +496,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV
var path = GetSeriesDataPath(_configurationManager.ApplicationPaths, tmdbId);
- var filename = string.Format("series-{0}.json", preferredLanguage ?? string.Empty);
+ var filename = string.Format(CultureInfo.InvariantCulture, "series-{0}.json", preferredLanguage ?? string.Empty);
return Path.Combine(path, filename);
}
diff --git a/MediaBrowser.Providers/Studios/StudiosImageProvider.cs b/MediaBrowser.Providers/Studios/StudiosImageProvider.cs
index dad155c815..321153c6be 100644
--- a/MediaBrowser.Providers/Studios/StudiosImageProvider.cs
+++ b/MediaBrowser.Providers/Studios/StudiosImageProvider.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
@@ -100,7 +101,7 @@ namespace MediaBrowser.Providers.Studios
private string GetUrl(string image, string filename)
{
- return string.Format("https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/studios/{0}/{1}.jpg", image, filename);
+ return string.Format(CultureInfo.InvariantCulture, "https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/studios/{0}/{1}.jpg", image, filename);
}
private Task EnsureThumbsList(string file, CancellationToken cancellationToken)
--
cgit v1.2.3
From 68edccd9f4e9137b13ad4006c19bb6582341aec6 Mon Sep 17 00:00:00 2001
From: Bond_009
Date: Wed, 19 Aug 2020 18:02:34 +0200
Subject: More warn
---
.../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 3 ++-
MediaBrowser.Controller/Entities/IHasSpecialFeatures.cs | 5 ++++-
MediaBrowser.Controller/Entities/Movies/Movie.cs | 15 ++++++++++-----
MediaBrowser.Controller/Entities/UserViewBuilder.cs | 14 ++++++--------
4 files changed, 22 insertions(+), 15 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index 04b208fdd1..2b5f69d41a 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -37,6 +37,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private readonly INetworkManager _networkManager;
private readonly IStreamHelper _streamHelper;
+ private readonly Dictionary _modelCache = new Dictionary();
+
public HdHomerunHost(
IServerConfigurationManager config,
ILogger logger,
@@ -114,7 +116,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}).Cast().ToList();
}
- private readonly Dictionary _modelCache = new Dictionary();
private async Task GetModelInfo(TunerHostInfo info, bool throwAllExceptions, CancellationToken cancellationToken)
{
var cacheKey = info.Id;
diff --git a/MediaBrowser.Controller/Entities/IHasSpecialFeatures.cs b/MediaBrowser.Controller/Entities/IHasSpecialFeatures.cs
index 688439e6c5..6a350212b1 100644
--- a/MediaBrowser.Controller/Entities/IHasSpecialFeatures.cs
+++ b/MediaBrowser.Controller/Entities/IHasSpecialFeatures.cs
@@ -1,4 +1,7 @@
+#pragma warning disable CS1591
+
using System;
+using System.Collections.Generic;
namespace MediaBrowser.Controller.Entities
{
@@ -8,6 +11,6 @@ namespace MediaBrowser.Controller.Entities
/// Gets or sets the special feature ids.
///
/// The special feature ids.
- Guid[] SpecialFeatureIds { get; set; }
+ IReadOnlyList SpecialFeatureIds { get; set; }
}
}
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 5ae396e68b..8b67aaccc6 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -1,3 +1,4 @@
+#pragma warning disable CS1591
using System;
using System.Collections.Generic;
@@ -19,8 +20,6 @@ namespace MediaBrowser.Controller.Entities.Movies
///
public class Movie : Video, IHasSpecialFeatures, IHasTrailers, IHasLookupInfo, ISupportsBoxSetGrouping
{
- public Guid[] SpecialFeatureIds { get; set; }
-
public Movie()
{
SpecialFeatureIds = Array.Empty();
@@ -29,6 +28,9 @@ namespace MediaBrowser.Controller.Entities.Movies
RemoteTrailerIds = Array.Empty();
}
+ ///
+ public IReadOnlyList SpecialFeatureIds { get; set; }
+
///
public IReadOnlyList LocalTrailerIds { get; set; }
@@ -48,6 +50,9 @@ namespace MediaBrowser.Controller.Entities.Movies
set => TmdbCollectionName = value;
}
+ [JsonIgnore]
+ public override bool StopRefreshIfLocalMetadataFound => false;
+
public override double GetDefaultPrimaryImageAspectRatio()
{
// hack for tv plugins
@@ -107,6 +112,7 @@ namespace MediaBrowser.Controller.Entities.Movies
return itemsChanged;
}
+ ///
public override UnratedItem GetBlockUnratedType()
{
return UnratedItem.Movie;
@@ -135,6 +141,7 @@ namespace MediaBrowser.Controller.Entities.Movies
return info;
}
+ ///
public override bool BeforeMetadataRefresh(bool replaceAllMetdata)
{
var hasChanges = base.BeforeMetadataRefresh(replaceAllMetdata);
@@ -171,6 +178,7 @@ namespace MediaBrowser.Controller.Entities.Movies
return hasChanges;
}
+ ///
public override List GetRelatedUrls()
{
var list = base.GetRelatedUrls();
@@ -187,8 +195,5 @@ namespace MediaBrowser.Controller.Entities.Movies
return list;
}
-
- [JsonIgnore]
- public override bool StopRefreshIfLocalMetadataFound => false;
}
}
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 22bb7fd550..e3f4025bbe 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -672,9 +674,7 @@ namespace MediaBrowser.Controller.Entities
var isPlaceHolder = false;
- var hasPlaceHolder = item as ISupportsPlaceHolders;
-
- if (hasPlaceHolder != null)
+ if (item is ISupportsPlaceHolders hasPlaceHolder)
{
isPlaceHolder = hasPlaceHolder.IsPlaceHolder;
}
@@ -689,13 +689,11 @@ namespace MediaBrowser.Controller.Entities
{
var filterValue = query.HasSpecialFeature.Value;
- var movie = item as IHasSpecialFeatures;
-
- if (movie != null)
+ if (item is IHasSpecialFeatures movie)
{
var ok = filterValue
- ? movie.SpecialFeatureIds.Length > 0
- : movie.SpecialFeatureIds.Length == 0;
+ ? movie.SpecialFeatureIds.Count > 0
+ : movie.SpecialFeatureIds.Count == 0;
if (!ok)
{
--
cgit v1.2.3
From ab2147751f9079bc104da068909a485fc9402a64 Mon Sep 17 00:00:00 2001
From: Bond_009
Date: Thu, 20 Aug 2020 12:16:24 +0200
Subject: Make MediaBrowser.MediaEncoding warnings free
---
Emby.Dlna/Main/DlnaEntryPoint.cs | 4 +-
Emby.Dlna/PlayTo/uBaseObject.cs | 2 +-
Emby.Dlna/PlayTo/uPnpNamespaces.cs | 2 +-
.../Data/SqliteItemRepository.cs | 7 +-
Emby.Server.Implementations/IO/LibraryMonitor.cs | 27 +---
.../IO/LibraryMonitorStartup.cs | 35 +++++
.../Library/LibraryManager.cs | 2 +-
.../LiveTv/EmbyTV/EntryPoint.cs | 2 +-
.../LiveTv/Listings/SchedulesDirect.cs | 2 +-
.../ScheduledTasks/ScheduledTaskWorker.cs | 148 +++++++++++----------
.../ScheduledTasks/TaskManager.cs | 1 +
.../ScheduledTasks/Tasks/DeleteLogFileTask.cs | 64 ++++-----
.../Services/ServicePath.cs | 8 +-
.../Entities/UserViewBuilder.cs | 1 -
.../Attachments/AttachmentExtractor.cs | 4 +-
.../Encoder/EncodingUtils.cs | 5 +-
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 4 +-
.../MediaBrowser.MediaEncoding.csproj | 2 +-
.../Probing/ProbeResultNormalizer.cs | 9 +-
MediaBrowser.MediaEncoding/Subtitles/AssParser.cs | 8 +-
MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs | 95 ++++++-------
.../Subtitles/SubtitleEncoder.cs | 17 +--
22 files changed, 236 insertions(+), 213 deletions(-)
create mode 100644 Emby.Server.Implementations/IO/LibraryMonitorStartup.cs
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs
index a21d4cc11d..191763de4f 100644
--- a/Emby.Dlna/Main/DlnaEntryPoint.cs
+++ b/Emby.Dlna/Main/DlnaEntryPoint.cs
@@ -30,7 +30,7 @@ using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
namespace Emby.Dlna.Main
{
- public class DlnaEntryPoint : IServerEntryPoint, IRunBeforeStartup
+ public sealed class DlnaEntryPoint : IServerEntryPoint, IRunBeforeStartup
{
private readonly IServerConfigurationManager _config;
private readonly ILogger _logger;
@@ -60,7 +60,7 @@ namespace Emby.Dlna.Main
public IMediaReceiverRegistrar MediaReceiverRegistrar { get; private set; }
- public static DlnaEntryPoint Current;
+ public static DlnaEntryPoint Current { get; private set; };
public DlnaEntryPoint(
IServerConfigurationManager config,
diff --git a/Emby.Dlna/PlayTo/uBaseObject.cs b/Emby.Dlna/PlayTo/uBaseObject.cs
index 05c19299f1..f2dc31f6dd 100644
--- a/Emby.Dlna/PlayTo/uBaseObject.cs
+++ b/Emby.Dlna/PlayTo/uBaseObject.cs
@@ -31,7 +31,7 @@ namespace Emby.Dlna.PlayTo
throw new ArgumentNullException(nameof(obj));
}
- return string.Equals(Id, obj.Id);
+ return string.Equals(Id, obj.Id, StringComparison.Ordinal);
}
public string MediaType
diff --git a/Emby.Dlna/PlayTo/uPnpNamespaces.cs b/Emby.Dlna/PlayTo/uPnpNamespaces.cs
index dc65cdf43c..6ea7dc9cf7 100644
--- a/Emby.Dlna/PlayTo/uPnpNamespaces.cs
+++ b/Emby.Dlna/PlayTo/uPnpNamespaces.cs
@@ -4,7 +4,7 @@ using System.Xml.Linq;
namespace Emby.Dlna.PlayTo
{
- public class uPnpNamespaces
+ public static class uPnpNamespaces
{
public static XNamespace dc = "http://purl.org/dc/elements/1.1/";
public static XNamespace ns = "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/";
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 331ffc1349..5bf740cfcc 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -4308,7 +4308,7 @@ namespace Emby.Server.Implementations.Data
whereClauses.Add("ProductionYear=@Years");
if (statement != null)
{
- statement.TryBind("@Years", query.Years[0].ToString());
+ statement.TryBind("@Years", query.Years[0].ToString(CultureInfo.InvariantCulture));
}
}
else if (query.Years.Length > 1)
@@ -5170,7 +5170,10 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
insertText.Append(',');
}
- insertText.AppendFormat("(@ItemId, @AncestorId{0}, @AncestorIdText{0})", i.ToString(CultureInfo.InvariantCulture));
+ insertText.AppendFormat(
+ CultureInfo.InvariantCulture,
+ "(@ItemId, @AncestorId{0}, @AncestorIdText{0})",
+ i.ToString(CultureInfo.InvariantCulture));
}
using (var statement = PrepareStatement(db, insertText.ToString()))
diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs
index a32b03aaa9..9290dfcd0e 100644
--- a/Emby.Server.Implementations/IO/LibraryMonitor.cs
+++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs
@@ -6,12 +6,11 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using Emby.Server.Implementations.Library;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.IO;
-using Emby.Server.Implementations.Library;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.IO
@@ -38,6 +37,8 @@ namespace Emby.Server.Implementations.IO
///
private readonly ConcurrentDictionary _tempIgnoredPaths = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase);
+ private bool _disposed = false;
+
///
/// Add the path to our temporary ignore list. Use when writing to a path within our listening scope.
///
@@ -492,8 +493,6 @@ namespace Emby.Server.Implementations.IO
}
}
- private bool _disposed = false;
-
///
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///
@@ -522,24 +521,4 @@ namespace Emby.Server.Implementations.IO
_disposed = true;
}
}
-
- public class LibraryMonitorStartup : IServerEntryPoint
- {
- private readonly ILibraryMonitor _monitor;
-
- public LibraryMonitorStartup(ILibraryMonitor monitor)
- {
- _monitor = monitor;
- }
-
- public Task RunAsync()
- {
- _monitor.Start();
- return Task.CompletedTask;
- }
-
- public void Dispose()
- {
- }
- }
}
diff --git a/Emby.Server.Implementations/IO/LibraryMonitorStartup.cs b/Emby.Server.Implementations/IO/LibraryMonitorStartup.cs
new file mode 100644
index 0000000000..c51cf05459
--- /dev/null
+++ b/Emby.Server.Implementations/IO/LibraryMonitorStartup.cs
@@ -0,0 +1,35 @@
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Plugins;
+
+namespace Emby.Server.Implementations.IO
+{
+ ///
+ /// which is responsible for starting the library monitor.
+ ///
+ public sealed class LibraryMonitorStartup : IServerEntryPoint
+ {
+ private readonly ILibraryMonitor _monitor;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The library monitor.
+ public LibraryMonitorStartup(ILibraryMonitor monitor)
+ {
+ _monitor = monitor;
+ }
+
+ ///
+ public Task RunAsync()
+ {
+ _monitor.Start();
+ return Task.CompletedTask;
+ }
+
+ ///
+ public void Dispose()
+ {
+ }
+ }
+}
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 7b770d9400..7ed8f0bbfb 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -729,7 +729,7 @@ namespace Emby.Server.Implementations.Library
Directory.CreateDirectory(rootFolderPath);
var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ??
- ((Folder) ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath)))
+ ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath)))
.DeepCopy();
// In case program data folder was moved
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs
index 69a9cb78aa..a2ec2df375 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs
@@ -5,7 +5,7 @@ using MediaBrowser.Controller.Plugins;
namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
- public class EntryPoint : IServerEntryPoint
+ public sealed class EntryPoint : IServerEntryPoint
{
///
public Task RunAsync()
diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
index 77a7069eb8..c4d5cc58aa 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
@@ -929,7 +929,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
private static string NormalizeName(string value)
{
- return value.Replace(" ", string.Empty).Replace("-", string.Empty);
+ return value.Replace(" ", string.Empty, StringComparison.Ordinal).Replace("-", string.Empty, StringComparison.Ordinal);
}
public class ScheduleDirect
diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
index 8a900f42cd..1ef083d048 100644
--- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
@@ -10,7 +10,6 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Progress;
using MediaBrowser.Model.Events;
-using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
@@ -22,37 +21,53 @@ namespace Emby.Server.Implementations.ScheduledTasks
///
public class ScheduledTaskWorker : IScheduledTaskWorker
{
- public event EventHandler> TaskProgress;
-
- ///
- /// Gets the scheduled task.
- ///
- /// The scheduled task.
- public IScheduledTask ScheduledTask { get; private set; }
-
///
/// Gets or sets the json serializer.
///
/// The json serializer.
- private IJsonSerializer JsonSerializer { get; set; }
+ private readonly IJsonSerializer _jsonSerializer;
///
/// Gets or sets the application paths.
///
/// The application paths.
- private IApplicationPaths ApplicationPaths { get; set; }
+ private readonly IApplicationPaths _applicationPaths;
///
- /// Gets the logger.
+ /// Gets or sets the logger.
///
/// The logger.
- private ILogger Logger { get; set; }
+ private readonly ILogger _logger;
///
- /// Gets the task manager.
+ /// Gets or sets the task manager.
///
/// The task manager.
- private ITaskManager TaskManager { get; set; }
+ private readonly ITaskManager _taskManager;
+
+ ///
+ /// The _last execution result sync lock.
+ ///
+ private readonly object _lastExecutionResultSyncLock = new object();
+
+ private bool _readFromFile = false;
+
+ ///
+ /// The _last execution result.
+ ///
+ private TaskResult _lastExecutionResult;
+
+ private Task _currentTask;
+
+ ///
+ /// The _triggers.
+ ///
+ private Tuple[] _triggers;
+
+ ///
+ /// The _id.
+ ///
+ private string _id;
///
/// Initializes a new instance of the class.
@@ -71,7 +86,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
/// or
/// jsonSerializer
/// or
- /// logger
+ /// logger.
///
public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger)
{
@@ -101,23 +116,22 @@ namespace Emby.Server.Implementations.ScheduledTasks
}
ScheduledTask = scheduledTask;
- ApplicationPaths = applicationPaths;
- TaskManager = taskManager;
- JsonSerializer = jsonSerializer;
- Logger = logger;
+ _applicationPaths = applicationPaths;
+ _taskManager = taskManager;
+ _jsonSerializer = jsonSerializer;
+ _logger = logger;
InitTriggerEvents();
}
- private bool _readFromFile = false;
- ///
- /// The _last execution result.
- ///
- private TaskResult _lastExecutionResult;
+ public event EventHandler> TaskProgress;
+
///
- /// The _last execution result sync lock.
+ /// Gets the scheduled task.
///
- private readonly object _lastExecutionResultSyncLock = new object();
+ /// The scheduled task.
+ public IScheduledTask ScheduledTask { get; private set; }
+
///
/// Gets the last execution result.
///
@@ -136,11 +150,11 @@ namespace Emby.Server.Implementations.ScheduledTasks
{
try
{
- _lastExecutionResult = JsonSerializer.DeserializeFromFile(path);
+ _lastExecutionResult = _jsonSerializer.DeserializeFromFile(path);
}
catch (Exception ex)
{
- Logger.LogError(ex, "Error deserializing {File}", path);
+ _logger.LogError(ex, "Error deserializing {File}", path);
}
}
@@ -160,7 +174,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
lock (_lastExecutionResultSyncLock)
{
- JsonSerializer.SerializeToFile(value, path);
+ _jsonSerializer.SerializeToFile(value, path);
}
}
}
@@ -184,7 +198,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
public string Category => ScheduledTask.Category;
///
- /// Gets the current cancellation token.
+ /// Gets or sets the current cancellation token.
///
/// The current cancellation token source.
private CancellationTokenSource CurrentCancellationTokenSource { get; set; }
@@ -221,12 +235,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
public double? CurrentProgress { get; private set; }
///
- /// The _triggers.
- ///
- private Tuple[] _triggers;
-
- ///
- /// Gets the triggers that define when the task will run.
+ /// Gets or sets the triggers that define when the task will run.
///
/// The triggers.
private Tuple[] InternalTriggers
@@ -255,7 +264,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
/// Gets the triggers that define when the task will run.
///
/// The triggers.
- /// value
+ /// value is null.
public TaskTriggerInfo[] Triggers
{
get
@@ -280,11 +289,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
}
}
- ///
- /// The _id.
- ///
- private string _id;
-
///
/// Gets the unique id.
///
@@ -325,9 +329,9 @@ namespace Emby.Server.Implementations.ScheduledTasks
trigger.Stop();
- trigger.Triggered -= trigger_Triggered;
- trigger.Triggered += trigger_Triggered;
- trigger.Start(LastExecutionResult, Logger, Name, isApplicationStartup);
+ trigger.Triggered -= OnTriggerTriggered;
+ trigger.Triggered += OnTriggerTriggered;
+ trigger.Start(LastExecutionResult, _logger, Name, isApplicationStartup);
}
}
@@ -336,7 +340,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
///
/// The source of the event.
/// The instance containing the event data.
- async void trigger_Triggered(object sender, EventArgs e)
+ private async void OnTriggerTriggered(object sender, EventArgs e)
{
var trigger = (ITaskTrigger)sender;
@@ -347,19 +351,17 @@ namespace Emby.Server.Implementations.ScheduledTasks
return;
}
- Logger.LogInformation("{0} fired for task: {1}", trigger.GetType().Name, Name);
+ _logger.LogInformation("{0} fired for task: {1}", trigger.GetType().Name, Name);
trigger.Stop();
- TaskManager.QueueScheduledTask(ScheduledTask, trigger.TaskOptions);
+ _taskManager.QueueScheduledTask(ScheduledTask, trigger.TaskOptions);
await Task.Delay(1000).ConfigureAwait(false);
- trigger.Start(LastExecutionResult, Logger, Name, false);
+ trigger.Start(LastExecutionResult, _logger, Name, false);
}
- private Task _currentTask;
-
///
/// Executes the task.
///
@@ -395,9 +397,9 @@ namespace Emby.Server.Implementations.ScheduledTasks
CurrentCancellationTokenSource = new CancellationTokenSource();
- Logger.LogInformation("Executing {0}", Name);
+ _logger.LogInformation("Executing {0}", Name);
- ((TaskManager)TaskManager).OnTaskExecuting(this);
+ ((TaskManager)_taskManager).OnTaskExecuting(this);
progress.ProgressChanged += OnProgressChanged;
@@ -423,7 +425,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
}
catch (Exception ex)
{
- Logger.LogError(ex, "Error");
+ _logger.LogError(ex, "Error");
failureException = ex;
@@ -476,7 +478,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
{
if (State == TaskState.Running)
{
- Logger.LogInformation("Attempting to cancel Scheduled Task {0}", Name);
+ _logger.LogInformation("Attempting to cancel Scheduled Task {0}", Name);
CurrentCancellationTokenSource.Cancel();
}
}
@@ -487,7 +489,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
/// System.String.
private string GetScheduledTasksConfigurationDirectory()
{
- return Path.Combine(ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
+ return Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
}
///
@@ -496,7 +498,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
/// System.String.
private string GetScheduledTasksDataDirectory()
{
- return Path.Combine(ApplicationPaths.DataPath, "ScheduledTasks");
+ return Path.Combine(_applicationPaths.DataPath, "ScheduledTasks");
}
///
@@ -535,7 +537,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
TaskTriggerInfo[] list = null;
if (File.Exists(path))
{
- list = JsonSerializer.DeserializeFromFile(path);
+ list = _jsonSerializer.DeserializeFromFile(path);
}
// Return defaults if file doesn't exist.
@@ -571,7 +573,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
Directory.CreateDirectory(Path.GetDirectoryName(path));
- JsonSerializer.SerializeToFile(triggers, path);
+ _jsonSerializer.SerializeToFile(triggers, path);
}
///
@@ -585,7 +587,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
{
var elapsedTime = endTime - startTime;
- Logger.LogInformation("{0} {1} after {2} minute(s) and {3} seconds", Name, status, Math.Truncate(elapsedTime.TotalMinutes), elapsedTime.Seconds);
+ _logger.LogInformation("{0} {1} after {2} minute(s) and {3} seconds", Name, status, Math.Truncate(elapsedTime.TotalMinutes), elapsedTime.Seconds);
var result = new TaskResult
{
@@ -606,7 +608,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
LastExecutionResult = result;
- ((TaskManager)TaskManager).OnTaskCompleted(this, result);
+ ((TaskManager)_taskManager).OnTaskCompleted(this, result);
}
///
@@ -615,6 +617,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
///
@@ -635,12 +638,12 @@ namespace Emby.Server.Implementations.ScheduledTasks
{
try
{
- Logger.LogInformation(Name + ": Cancelling");
+ _logger.LogInformation(Name + ": Cancelling");
token.Cancel();
}
catch (Exception ex)
{
- Logger.LogError(ex, "Error calling CancellationToken.Cancel();");
+ _logger.LogError(ex, "Error calling CancellationToken.Cancel();");
}
}
@@ -649,21 +652,21 @@ namespace Emby.Server.Implementations.ScheduledTasks
{
try
{
- Logger.LogInformation(Name + ": Waiting on Task");
+ _logger.LogInformation(Name + ": Waiting on Task");
var exited = Task.WaitAll(new[] { task }, 2000);
if (exited)
{
- Logger.LogInformation(Name + ": Task exited");
+ _logger.LogInformation(Name + ": Task exited");
}
else
{
- Logger.LogInformation(Name + ": Timed out waiting for task to stop");
+ _logger.LogInformation(Name + ": Timed out waiting for task to stop");
}
}
catch (Exception ex)
{
- Logger.LogError(ex, "Error calling Task.WaitAll();");
+ _logger.LogError(ex, "Error calling Task.WaitAll();");
}
}
@@ -671,12 +674,12 @@ namespace Emby.Server.Implementations.ScheduledTasks
{
try
{
- Logger.LogDebug(Name + ": Disposing CancellationToken");
+ _logger.LogDebug(Name + ": Disposing CancellationToken");
token.Dispose();
}
catch (Exception ex)
{
- Logger.LogError(ex, "Error calling CancellationToken.Dispose();");
+ _logger.LogError(ex, "Error calling CancellationToken.Dispose();");
}
}
@@ -692,8 +695,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
///
/// The info.
/// BaseTaskTrigger.
- ///
- /// Invalid trigger type: + info.Type
+ /// Invalid trigger type: + info.Type.
private ITaskTrigger GetTrigger(TaskTriggerInfo info)
{
var options = new TaskOptions
@@ -765,7 +767,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
foreach (var triggerInfo in InternalTriggers)
{
var trigger = triggerInfo.Item2;
- trigger.Triggered -= trigger_Triggered;
+ trigger.Triggered -= OnTriggerTriggered;
trigger.Stop();
}
}
diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
index 81096026bd..6d2b4ffc8d 100644
--- a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs
@@ -207,6 +207,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
///
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
index 402b39a263..54e18eaea0 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
@@ -1,12 +1,13 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
+using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Tasks;
-using MediaBrowser.Model.Globalization;
namespace Emby.Server.Implementations.ScheduledTasks.Tasks
{
@@ -15,12 +16,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
///
public class DeleteLogFileTask : IScheduledTask, IConfigurableScheduledTask
{
- ///
- /// Gets or sets the configuration manager.
- ///
- /// The configuration manager.
- private IConfigurationManager ConfigurationManager { get; set; }
-
+ private readonly IConfigurationManager _configurationManager;
private readonly IFileSystem _fileSystem;
private readonly ILocalizationManager _localization;
@@ -32,18 +28,43 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
/// The localization manager.
public DeleteLogFileTask(IConfigurationManager configurationManager, IFileSystem fileSystem, ILocalizationManager localization)
{
- ConfigurationManager = configurationManager;
+ _configurationManager = configurationManager;
_fileSystem = fileSystem;
_localization = localization;
}
+ ///
+ public string Name => _localization.GetLocalizedString("TaskCleanLogs");
+
+ ///
+ public string Description => string.Format(
+ CultureInfo.InvariantCulture,
+ _localization.GetLocalizedString("TaskCleanLogsDescription"),
+ _configurationManager.CommonConfiguration.LogFileRetentionDays);
+
+ ///
+ public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory");
+
+ ///
+ public string Key => "CleanLogFiles";
+
+ ///
+ public bool IsHidden => false;
+
+ ///
+ public bool IsEnabled => true;
+
+ ///
+ public bool IsLogged => true;
+
///
/// Creates the triggers that define when the task will run.
///
/// IEnumerable{BaseTaskTrigger}.
public IEnumerable GetDefaultTriggers()
{
- return new[] {
+ return new[]
+ {
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
};
}
@@ -57,10 +78,10 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
public Task Execute(CancellationToken cancellationToken, IProgress progress)
{
// Delete log files more than n days old
- var minDateModified = DateTime.UtcNow.AddDays(-ConfigurationManager.CommonConfiguration.LogFileRetentionDays);
+ var minDateModified = DateTime.UtcNow.AddDays(-_configurationManager.CommonConfiguration.LogFileRetentionDays);
// Only delete the .txt log files, the *.log files created by serilog get managed by itself
- var filesToDelete = _fileSystem.GetFiles(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath, new[] { ".txt" }, true, true)
+ var filesToDelete = _fileSystem.GetFiles(_configurationManager.CommonApplicationPaths.LogDirectoryPath, new[] { ".txt" }, true, true)
.Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
.ToList();
@@ -83,26 +104,5 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
return Task.CompletedTask;
}
-
- ///
- public string Name => _localization.GetLocalizedString("TaskCleanLogs");
-
- ///
- public string Description => string.Format(_localization.GetLocalizedString("TaskCleanLogsDescription"), ConfigurationManager.CommonConfiguration.LogFileRetentionDays);
-
- ///
- public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory");
-
- ///
- public string Key => "CleanLogFiles";
-
- ///
- public bool IsHidden => false;
-
- ///
- public bool IsEnabled => true;
-
- ///
- public bool IsLogged => true;
}
}
diff --git a/Emby.Server.Implementations/Services/ServicePath.cs b/Emby.Server.Implementations/Services/ServicePath.cs
index 442b2ab1c5..0d4728b43c 100644
--- a/Emby.Server.Implementations/Services/ServicePath.cs
+++ b/Emby.Server.Implementations/Services/ServicePath.cs
@@ -80,8 +80,8 @@ namespace Emby.Server.Implementations.Services
public static List GetFirstMatchWildCardHashKeys(string[] pathPartsForMatching)
{
- const string hashPrefix = WildCard + PathSeperator;
- return GetPotentialMatchesWithPrefix(hashPrefix, pathPartsForMatching);
+ const string HashPrefix = WildCard + PathSeperator;
+ return GetPotentialMatchesWithPrefix(HashPrefix, pathPartsForMatching);
}
private static List GetPotentialMatchesWithPrefix(string hashPrefix, string[] pathPartsForMatching)
@@ -92,7 +92,7 @@ namespace Emby.Server.Implementations.Services
{
list.Add(hashPrefix + part);
- if (part.IndexOf(ComponentSeperator) == -1)
+ if (part.IndexOf(ComponentSeperator, StringComparison.Ordinal) == -1)
{
continue;
}
@@ -130,7 +130,7 @@ namespace Emby.Server.Implementations.Services
}
if (component.IndexOf(VariablePrefix, StringComparison.OrdinalIgnoreCase) != -1
- && component.IndexOf(ComponentSeperator) != -1)
+ && component.IndexOf(ComponentSeperator, StringComparison.Ordinal) != -1)
{
hasSeparators.Add(true);
componentsList.AddRange(component.Split(ComponentSeperator));
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index e3f4025bbe..b384b27d1a 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -10,7 +10,6 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.TV;
-using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using Microsoft.Extensions.Logging;
diff --git a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs
index a8ebe6bc54..21b5d0c5be 100644
--- a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs
+++ b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs
@@ -240,11 +240,11 @@ namespace MediaBrowser.MediaEncoding.Attachments
if (protocol == MediaProtocol.File)
{
var date = _fileSystem.GetLastWriteTimeUtc(mediaPath);
- filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture) + "_" + date.Ticks.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D");
+ filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture) + "_" + date.Ticks.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D", CultureInfo.InvariantCulture);
}
else
{
- filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D");
+ filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D", CultureInfo.InvariantCulture);
}
var prefix = filename.Substring(0, 1);
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs
index 082ae2888d..63310fdf6b 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs
@@ -1,5 +1,6 @@
#pragma warning disable CS1591
+using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@@ -48,7 +49,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// System.String.
private static string GetFileInputArgument(string path)
{
- if (path.IndexOf("://") != -1)
+ if (path.IndexOf("://", StringComparison.Ordinal) != -1)
{
return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", path);
}
@@ -67,7 +68,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
private static string NormalizePath(string path)
{
// Quotes are valid path characters in linux and they need to be escaped here with a leading \
- return path.Replace("\"", "\\\"");
+ return path.Replace("\"", "\\\"", StringComparison.Ordinal);
}
}
}
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index b9a6432ad2..7449e4a624 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -377,7 +377,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
var args = extractChapters
? "{0} -i {1} -threads 0 -v warning -print_format json -show_streams -show_chapters -show_format"
: "{0} -i {1} -threads 0 -v warning -print_format json -show_streams -show_format";
- args = string.Format(args, probeSizeArgument, inputPath).Trim();
+ args = string.Format(CultureInfo.InvariantCulture, args, probeSizeArgument, inputPath).Trim();
var process = new Process
{
@@ -856,7 +856,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
// https://ffmpeg.org/ffmpeg-filters.html#Notes-on-filtergraph-escaping
// We need to double escape
- return path.Replace('\\', '/').Replace(":", "\\:").Replace("'", "'\\\\\\''");
+ return path.Replace('\\', '/').Replace(":", "\\:", StringComparison.Ordinal).Replace("'", "'\\\\\\''", StringComparison.Ordinal);
}
///
diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
index 017f917e27..814edd7323 100644
--- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
+++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
@@ -34,7 +34,7 @@
-
+
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index 19e3bd8e60..40a3b43e1c 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -42,7 +42,8 @@ namespace MediaBrowser.MediaEncoding.Probing
var info = new MediaInfo
{
Path = path,
- Protocol = protocol
+ Protocol = protocol,
+ VideoType = videoType
};
FFProbeHelpers.NormalizeFFProbeResult(data);
@@ -1133,7 +1134,7 @@ namespace MediaBrowser.MediaEncoding.Probing
{
// Only use the comma as a delimeter if there are no slashes or pipes.
// We want to be careful not to split names that have commas in them
- var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i) != -1) ?
+ var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i, StringComparison.Ordinal) != -1) ?
_nameDelimiters :
new[] { ',' };
@@ -1377,8 +1378,8 @@ namespace MediaBrowser.MediaEncoding.Probing
if (subtitle.Contains('/', StringComparison.Ordinal)) // It contains a episode number and season number
{
string[] numbers = subtitle.Split(' ');
- video.IndexNumber = int.Parse(numbers[0].Replace(".", string.Empty, StringComparison.Ordinal).Split('/')[0]);
- int totalEpisodesInSeason = int.Parse(numbers[0].Replace(".", string.Empty, StringComparison.Ordinal).Split('/')[1]);
+ video.IndexNumber = int.Parse(numbers[0].Replace(".", string.Empty, StringComparison.Ordinal).Split('/')[0], CultureInfo.InvariantCulture);
+ int totalEpisodesInSeason = int.Parse(numbers[0].Replace(".", string.Empty, StringComparison.Ordinal).Split('/')[1], CultureInfo.InvariantCulture);
description = string.Join(" ", numbers, 1, numbers.Length - 1).Trim(); // Skip the first, concatenate the rest, clean up spaces and save it
}
diff --git a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
index 308b62886c..86b87fddd8 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
@@ -86,9 +86,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
private void RemoteNativeFormatting(SubtitleTrackEvent p)
{
- int indexOfBegin = p.Text.IndexOf('{');
+ int indexOfBegin = p.Text.IndexOf('{', StringComparison.Ordinal);
string pre = string.Empty;
- while (indexOfBegin >= 0 && p.Text.IndexOf('}') > indexOfBegin)
+ while (indexOfBegin >= 0 && p.Text.IndexOf('}', StringComparison.Ordinal) > indexOfBegin)
{
string s = p.Text.Substring(indexOfBegin);
if (s.StartsWith("{\\an1}", StringComparison.Ordinal) ||
@@ -116,10 +116,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles
pre = s.Substring(0, 5) + "}";
}
- int indexOfEnd = p.Text.IndexOf('}');
+ int indexOfEnd = p.Text.IndexOf('}', StringComparison.Ordinal);
p.Text = p.Text.Remove(indexOfBegin, (indexOfEnd - indexOfBegin) + 1);
- indexOfBegin = p.Text.IndexOf('{');
+ indexOfBegin = p.Text.IndexOf('{', StringComparison.Ordinal);
}
p.Text = pre + p.Text;
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
index 6b7a81e6eb..a5d6417473 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
@@ -50,14 +51,14 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
eventsStarted = true;
}
- else if (!string.IsNullOrEmpty(line) && line.Trim().StartsWith(";"))
+ else if (!string.IsNullOrEmpty(line) && line.Trim().StartsWith(";", StringComparison.Ordinal))
{
// skip comment lines
}
else if (eventsStarted && line.Trim().Length > 0)
{
string s = line.Trim().ToLowerInvariant();
- if (s.StartsWith("format:"))
+ if (s.StartsWith("format:", StringComparison.Ordinal))
{
if (line.Length > 10)
{
@@ -103,7 +104,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
string[] splittedLine;
- if (s.StartsWith("dialogue:"))
+ if (s.StartsWith("dialogue:", StringComparison.Ordinal))
{
splittedLine = line.Substring(10).Split(',');
}
@@ -181,10 +182,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles
string[] timeCode = time.Split(':', '.');
return new TimeSpan(
0,
- int.Parse(timeCode[0]),
- int.Parse(timeCode[1]),
- int.Parse(timeCode[2]),
- int.Parse(timeCode[3]) * 10).Ticks;
+ int.Parse(timeCode[0], CultureInfo.InvariantCulture),
+ int.Parse(timeCode[1], CultureInfo.InvariantCulture),
+ int.Parse(timeCode[2], CultureInfo.InvariantCulture),
+ int.Parse(timeCode[3], CultureInfo.InvariantCulture) * 10).Ticks;
}
private static string GetFormattedText(string text)
@@ -193,11 +194,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles
for (int i = 0; i < 10; i++) // just look ten times...
{
- if (text.Contains(@"{\fn"))
+ if (text.Contains(@"{\fn", StringComparison.Ordinal))
{
- int start = text.IndexOf(@"{\fn");
+ int start = text.IndexOf(@"{\fn", StringComparison.Ordinal);
int end = text.IndexOf('}', start);
- if (end > 0 && !text.Substring(start).StartsWith("{\\fn}"))
+ if (end > 0 && !text.Substring(start).StartsWith("{\\fn}", StringComparison.Ordinal))
{
string fontName = text.Substring(start + 4, end - (start + 4));
string extraTags = string.Empty;
@@ -212,7 +213,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
text = text.Insert(start, "");
}
- int indexOfEndTag = text.IndexOf("{\\fn}", start);
+ int indexOfEndTag = text.IndexOf("{\\fn}", start, StringComparison.Ordinal);
if (indexOfEndTag > 0)
{
text = text.Remove(indexOfEndTag, "{\\fn}".Length).Insert(indexOfEndTag, "");
@@ -224,11 +225,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
}
- if (text.Contains(@"{\fs"))
+ if (text.Contains(@"{\fs", StringComparison.Ordinal))
{
- int start = text.IndexOf(@"{\fs");
+ int start = text.IndexOf(@"{\fs", StringComparison.Ordinal);
int end = text.IndexOf('}', start);
- if (end > 0 && !text.Substring(start).StartsWith("{\\fs}"))
+ if (end > 0 && !text.Substring(start).StartsWith("{\\fs}", StringComparison.Ordinal))
{
string fontSize = text.Substring(start + 4, end - (start + 4));
string extraTags = string.Empty;
@@ -245,7 +246,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
text = text.Insert(start, "");
}
- int indexOfEndTag = text.IndexOf("{\\fs}", start);
+ int indexOfEndTag = text.IndexOf("{\\fs}", start, StringComparison.Ordinal);
if (indexOfEndTag > 0)
{
text = text.Remove(indexOfEndTag, "{\\fs}".Length).Insert(indexOfEndTag, "");
@@ -258,17 +259,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
}
- if (text.Contains(@"{\c"))
+ if (text.Contains(@"{\c", StringComparison.Ordinal))
{
- int start = text.IndexOf(@"{\c");
+ int start = text.IndexOf(@"{\c", StringComparison.Ordinal);
int end = text.IndexOf('}', start);
- if (end > 0 && !text.Substring(start).StartsWith("{\\c}"))
+ if (end > 0 && !text.Substring(start).StartsWith("{\\c}", StringComparison.Ordinal))
{
string color = text.Substring(start + 4, end - (start + 4));
string extraTags = string.Empty;
CheckAndAddSubTags(ref color, ref extraTags, out bool italic);
- color = color.Replace("&", string.Empty).TrimStart('H');
+ color = color.Replace("&", string.Empty, StringComparison.Ordinal).TrimStart('H');
color = color.PadLeft(6, '0');
// switch to rrggbb from bbggrr
@@ -285,7 +286,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
text = text.Insert(start, "");
}
- int indexOfEndTag = text.IndexOf("{\\c}", start);
+ int indexOfEndTag = text.IndexOf("{\\c}", start, StringComparison.Ordinal);
if (indexOfEndTag > 0)
{
text = text.Remove(indexOfEndTag, "{\\c}".Length).Insert(indexOfEndTag, "");
@@ -297,17 +298,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
}
- if (text.Contains(@"{\1c")) // "1" specifices primary color
+ if (text.Contains(@"{\1c", StringComparison.Ordinal)) // "1" specifices primary color
{
- int start = text.IndexOf(@"{\1c");
+ int start = text.IndexOf(@"{\1c", StringComparison.Ordinal);
int end = text.IndexOf('}', start);
- if (end > 0 && !text.Substring(start).StartsWith("{\\1c}"))
+ if (end > 0 && !text.Substring(start).StartsWith("{\\1c}", StringComparison.Ordinal))
{
string color = text.Substring(start + 5, end - (start + 5));
string extraTags = string.Empty;
CheckAndAddSubTags(ref color, ref extraTags, out bool italic);
- color = color.Replace("&", string.Empty).TrimStart('H');
+ color = color.Replace("&", string.Empty, StringComparison.Ordinal).TrimStart('H');
color = color.PadLeft(6, '0');
// switch to rrggbb from bbggrr
@@ -329,25 +330,25 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
}
- text = text.Replace(@"{\i1}", "");
- text = text.Replace(@"{\i0}", "");
- text = text.Replace(@"{\i}", "");
+ text = text.Replace(@"{\i1}", "", StringComparison.Ordinal);
+ text = text.Replace(@"{\i0}", "", StringComparison.Ordinal);
+ text = text.Replace(@"{\i}", "", StringComparison.Ordinal);
if (CountTagInText(text, "") > CountTagInText(text, ""))
{
text += "";
}
- text = text.Replace(@"{\u1}", "");
- text = text.Replace(@"{\u0}", "");
- text = text.Replace(@"{\u}", "");
+ text = text.Replace(@"{\u1}", "", StringComparison.Ordinal);
+ text = text.Replace(@"{\u0}", "", StringComparison.Ordinal);
+ text = text.Replace(@"{\u}", "", StringComparison.Ordinal);
if (CountTagInText(text, "") > CountTagInText(text, ""))
{
text += "";
}
- text = text.Replace(@"{\b1}", "");
- text = text.Replace(@"{\b0}", "");
- text = text.Replace(@"{\b}", "");
+ text = text.Replace(@"{\b1}", "", StringComparison.Ordinal);
+ text = text.Replace(@"{\b0}", "", StringComparison.Ordinal);
+ text = text.Replace(@"{\b}", "", StringComparison.Ordinal);
if (CountTagInText(text, "") > CountTagInText(text, ""))
{
text += "";
@@ -362,7 +363,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
private static int CountTagInText(string text, string tag)
{
int count = 0;
- int index = text.IndexOf(tag);
+ int index = text.IndexOf(tag, StringComparison.Ordinal);
while (index >= 0)
{
count++;
@@ -371,7 +372,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
return count;
}
- index = text.IndexOf(tag, index + 1);
+ index = text.IndexOf(tag, index + 1, StringComparison.Ordinal);
}
return count;
@@ -380,7 +381,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
private static void CheckAndAddSubTags(ref string tagName, ref string extraTags, out bool italic)
{
italic = false;
- int indexOfSPlit = tagName.IndexOf(@"\");
+ int indexOfSPlit = tagName.IndexOf('\\', StringComparison.Ordinal);
if (indexOfSPlit > 0)
{
string rest = tagName.Substring(indexOfSPlit).TrimStart('\\');
@@ -388,9 +389,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
for (int i = 0; i < 10; i++)
{
- if (rest.StartsWith("fs") && rest.Length > 2)
+ if (rest.StartsWith("fs", StringComparison.Ordinal) && rest.Length > 2)
{
- indexOfSPlit = rest.IndexOf(@"\");
+ indexOfSPlit = rest.IndexOf('\\', StringComparison.Ordinal);
string fontSize = rest;
if (indexOfSPlit > 0)
{
@@ -404,9 +405,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
extraTags += " size=\"" + fontSize.Substring(2) + "\"";
}
- else if (rest.StartsWith("fn") && rest.Length > 2)
+ else if (rest.StartsWith("fn", StringComparison.Ordinal) && rest.Length > 2)
{
- indexOfSPlit = rest.IndexOf(@"\");
+ indexOfSPlit = rest.IndexOf('\\', StringComparison.Ordinal);
string fontName = rest;
if (indexOfSPlit > 0)
{
@@ -420,9 +421,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
extraTags += " face=\"" + fontName.Substring(2) + "\"";
}
- else if (rest.StartsWith("c") && rest.Length > 2)
+ else if (rest.StartsWith("c", StringComparison.Ordinal) && rest.Length > 2)
{
- indexOfSPlit = rest.IndexOf(@"\");
+ indexOfSPlit = rest.IndexOf('\\', StringComparison.Ordinal);
string fontColor = rest;
if (indexOfSPlit > 0)
{
@@ -435,7 +436,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
string color = fontColor.Substring(2);
- color = color.Replace("&", string.Empty).TrimStart('H');
+ color = color.Replace("&", string.Empty, StringComparison.Ordinal).TrimStart('H');
color = color.PadLeft(6, '0');
// switch to rrggbb from bbggrr
color = "#" + color.Remove(color.Length - 6) + color.Substring(color.Length - 2, 2) + color.Substring(color.Length - 4, 2) + color.Substring(color.Length - 6, 2);
@@ -443,9 +444,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
extraTags += " color=\"" + color + "\"";
}
- else if (rest.StartsWith("i1") && rest.Length > 1)
+ else if (rest.StartsWith("i1", StringComparison.Ordinal) && rest.Length > 1)
{
- indexOfSPlit = rest.IndexOf(@"\");
+ indexOfSPlit = rest.IndexOf('\\', StringComparison.Ordinal);
italic = true;
if (indexOfSPlit > 0)
{
@@ -456,9 +457,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
rest = string.Empty;
}
}
- else if (rest.Length > 0 && rest.Contains("\\"))
+ else if (rest.Length > 0 && rest.Contains('\\', StringComparison.Ordinal))
{
- indexOfSPlit = rest.IndexOf(@"\");
+ indexOfSPlit = rest.IndexOf('\\', StringComparison.Ordinal);
rest = rest.Substring(indexOfSPlit).TrimStart('\\');
}
}
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index fbe8bd69f7..6ac5ac2ff1 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -415,7 +415,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
// FFmpeg automatically convert character encoding when it is UTF-16
// If we specify character encoding, it rejects with "do not specify a character encoding" and "Unable to recode subtitle event"
- if ((inputPath.EndsWith(".smi") || inputPath.EndsWith(".sami")) &&
+ if ((inputPath.EndsWith(".smi", StringComparison.Ordinal) || inputPath.EndsWith(".sami", StringComparison.Ordinal)) &&
(encodingParam.Equals("UTF-16BE", StringComparison.OrdinalIgnoreCase) ||
encodingParam.Equals("UTF-16LE", StringComparison.OrdinalIgnoreCase)))
{
@@ -506,7 +506,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
string.Format(CultureInfo.InvariantCulture, "ffmpeg subtitle conversion failed for {0}", inputPath));
}
- await SetAssFont(outputPath).ConfigureAwait(false);
+ await SetAssFont(outputPath, cancellationToken).ConfigureAwait(false);
_logger.LogInformation("ffmpeg subtitle conversion succeeded for {Path}", inputPath);
}
@@ -668,7 +668,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
if (string.Equals(outputCodec, "ass", StringComparison.OrdinalIgnoreCase))
{
- await SetAssFont(outputPath).ConfigureAwait(false);
+ await SetAssFont(outputPath, cancellationToken).ConfigureAwait(false);
}
}
@@ -676,8 +676,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
/// Sets the ass font.
///
/// The file.
+ /// The token to monitor for cancellation requests. The default value is System.Threading.CancellationToken.None.
/// Task.
- private async Task SetAssFont(string file)
+ private async Task SetAssFont(string file, CancellationToken cancellationToken = default)
{
_logger.LogInformation("Setting ass font within {File}", file);
@@ -692,14 +693,14 @@ namespace MediaBrowser.MediaEncoding.Subtitles
text = await reader.ReadToEndAsync().ConfigureAwait(false);
}
- var newText = text.Replace(",Arial,", ",Arial Unicode MS,");
+ var newText = text.Replace(",Arial,", ",Arial Unicode MS,", StringComparison.Ordinal);
- if (!string.Equals(text, newText))
+ if (!string.Equals(text, newText, StringComparison.Ordinal))
{
using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
using (var writer = new StreamWriter(fileStream, encoding))
{
- writer.Write(newText);
+ await writer.WriteAsync(newText.AsMemory(), cancellationToken).ConfigureAwait(false);
}
}
}
@@ -736,7 +737,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName;
// UTF16 is automatically converted to UTF8 by FFmpeg, do not specify a character encoding
- if ((path.EndsWith(".ass") || path.EndsWith(".ssa") || path.EndsWith(".srt"))
+ if ((path.EndsWith(".ass", StringComparison.Ordinal) || path.EndsWith(".ssa", StringComparison.Ordinal) || path.EndsWith(".srt", StringComparison.Ordinal))
&& (string.Equals(charset, "utf-16le", StringComparison.OrdinalIgnoreCase)
|| string.Equals(charset, "utf-16be", StringComparison.OrdinalIgnoreCase)))
{
--
cgit v1.2.3
From 119f64f5e7b09aeb4ff8f59237093906c1e08f5f Mon Sep 17 00:00:00 2001
From: Bond_009
Date: Fri, 21 Aug 2020 22:01:19 +0200
Subject: Make some methods async
---
.../Channels/ChannelManager.cs | 21 ++++++---
.../Collections/CollectionManager.cs | 51 +++++++++-------------
.../Library/LibraryManager.cs | 39 +++++++----------
.../LiveTv/LiveTvManager.cs | 16 ++++---
.../Playlists/PlaylistManager.cs | 16 +++----
Jellyfin.Api/Controllers/CollectionController.cs | 15 ++++---
Jellyfin.Api/Controllers/ImageController.cs | 14 +++---
Jellyfin.Api/Controllers/ItemUpdateController.cs | 7 +--
Jellyfin.Api/Controllers/PlaylistsController.cs | 12 ++---
Jellyfin.Api/Controllers/RemoteImageController.cs | 2 +-
Jellyfin.Api/Controllers/VideosController.cs | 14 +++---
.../Collections/ICollectionManager.cs | 12 ++---
MediaBrowser.Controller/Entities/BaseItem.cs | 20 ++++-----
MediaBrowser.Controller/Entities/Folder.cs | 4 +-
MediaBrowser.Controller/Entities/Video.cs | 7 +--
MediaBrowser.Controller/Library/ILibraryManager.cs | 41 +++++++++++++----
.../Playlists/IPlaylistManager.cs | 6 +--
.../Encoder/EncoderValidator.cs | 5 ++-
MediaBrowser.Providers/Manager/MetadataService.cs | 4 +-
MediaBrowser.Providers/TV/DummySeasonProvider.cs | 4 +-
20 files changed, 165 insertions(+), 145 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs
index d8ab1f1a14..26fc1bee44 100644
--- a/Emby.Server.Implementations/Channels/ChannelManager.cs
+++ b/Emby.Server.Implementations/Channels/ChannelManager.cs
@@ -746,12 +746,21 @@ namespace Emby.Server.Implementations.Channels
// null if came from cache
if (itemsResult != null)
{
- var internalItems = itemsResult.Items
- .Select(i => GetChannelItemEntity(i, channelProvider, channel.Id, parentItem, cancellationToken))
- .ToArray();
+ var items = itemsResult.Items;
+ var itemsLen = items.Count;
+ var internalItems = new Guid[itemsLen];
+ for (int i = 0; i < itemsLen; i++)
+ {
+ internalItems[i] = (await GetChannelItemEntityAsync(
+ items[i],
+ channelProvider,
+ channel.Id,
+ parentItem,
+ cancellationToken).ConfigureAwait(false)).Id;
+ }
var existingIds = _libraryManager.GetItemIds(query);
- var deadIds = existingIds.Except(internalItems.Select(i => i.Id))
+ var deadIds = existingIds.Except(internalItems)
.ToArray();
foreach (var deadId in deadIds)
@@ -963,7 +972,7 @@ namespace Emby.Server.Implementations.Channels
return item;
}
- private BaseItem GetChannelItemEntity(ChannelItemInfo info, IChannel channelProvider, Guid internalChannelId, BaseItem parentFolder, CancellationToken cancellationToken)
+ private async Task GetChannelItemEntityAsync(ChannelItemInfo info, IChannel channelProvider, Guid internalChannelId, BaseItem parentFolder, CancellationToken cancellationToken)
{
var parentFolderId = parentFolder.Id;
@@ -1165,7 +1174,7 @@ namespace Emby.Server.Implementations.Channels
}
else if (forceUpdate)
{
- item.UpdateToRepository(ItemUpdateType.None, cancellationToken);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.None, cancellationToken).ConfigureAwait(false);
}
if ((isNew || forceUpdate) && info.Type == ChannelItemType.Media)
diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs
index ac2edc1e2e..3011a37e31 100644
--- a/Emby.Server.Implementations/Collections/CollectionManager.cs
+++ b/Emby.Server.Implementations/Collections/CollectionManager.cs
@@ -132,7 +132,7 @@ namespace Emby.Server.Implementations.Collections
}
///
- public BoxSet CreateCollection(CollectionCreationOptions options)
+ public async Task CreateCollectionAsync(CollectionCreationOptions options)
{
var name = options.Name;
@@ -141,7 +141,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).GetAwaiter().GetResult();
+ var parentFolder = await GetCollectionsFolder(true).ConfigureAwait(false);
if (parentFolder == null)
{
@@ -169,12 +169,16 @@ namespace Emby.Server.Implementations.Collections
if (options.ItemIdList.Length > 0)
{
- AddToCollection(collection.Id, options.ItemIdList, false, new MetadataRefreshOptions(new DirectoryService(_fileSystem))
- {
- // The initial adding of items is going to create a local metadata file
- // This will cause internet metadata to be skipped as a result
- MetadataRefreshMode = MetadataRefreshMode.FullRefresh
- });
+ await AddToCollectionAsync(
+ collection.Id,
+ options.ItemIdList.Select(x => new Guid(x)),
+ false,
+ new MetadataRefreshOptions(new DirectoryService(_fileSystem))
+ {
+ // The initial adding of items is going to create a local metadata file
+ // This will cause internet metadata to be skipped as a result
+ MetadataRefreshMode = MetadataRefreshMode.FullRefresh
+ }).ConfigureAwait(false);
}
else
{
@@ -197,18 +201,10 @@ namespace Emby.Server.Implementations.Collections
}
///
- public void AddToCollection(Guid collectionId, IEnumerable ids)
- {
- AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
- }
+ public Task AddToCollectionAsync(Guid collectionId, IEnumerable ids)
+ => AddToCollectionAsync(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
- ///
- public void AddToCollection(Guid collectionId, IEnumerable ids)
- {
- AddToCollection(collectionId, ids.Select(i => i.ToString("N", CultureInfo.InvariantCulture)), true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
- }
-
- private void AddToCollection(Guid collectionId, IEnumerable ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
+ private async Task AddToCollectionAsync(Guid collectionId, IEnumerable ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
{
var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
if (collection == null)
@@ -224,15 +220,14 @@ namespace Emby.Server.Implementations.Collections
foreach (var id in ids)
{
- var guidId = new Guid(id);
- var item = _libraryManager.GetItemById(guidId);
+ var item = _libraryManager.GetItemById(id);
if (item == null)
{
throw new ArgumentException("No item exists with the supplied Id");
}
- if (!currentLinkedChildrenIds.Contains(guidId))
+ if (!currentLinkedChildrenIds.Contains(id))
{
itemList.Add(item);
@@ -249,7 +244,7 @@ namespace Emby.Server.Implementations.Collections
collection.UpdateRatingToItems(linkedChildrenList);
- collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await collection.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
refreshOptions.ForceSave = true;
_providerManager.QueueRefresh(collection.Id, refreshOptions, RefreshPriority.High);
@@ -266,13 +261,7 @@ namespace Emby.Server.Implementations.Collections
}
///
- public void RemoveFromCollection(Guid collectionId, IEnumerable itemIds)
- {
- RemoveFromCollection(collectionId, itemIds.Select(i => new Guid(i)));
- }
-
- ///
- public void RemoveFromCollection(Guid collectionId, IEnumerable itemIds)
+ public async Task RemoveFromCollectionAsync(Guid collectionId, IEnumerable itemIds)
{
var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
@@ -309,7 +298,7 @@ namespace Emby.Server.Implementations.Collections
collection.LinkedChildren = collection.LinkedChildren.Except(list).ToArray();
}
- collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await collection.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
_providerManager.QueueRefresh(
collection.Id,
new MetadataRefreshOptions(new DirectoryService(_fileSystem))
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 7ed8f0bbfb..375f09f5bb 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -771,7 +771,7 @@ namespace Emby.Server.Implementations.Library
if (folder.ParentId != rootFolder.Id)
{
folder.ParentId = rootFolder.Id;
- folder.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None);
+ folder.UpdateToRepositoryAsync(ItemUpdateType.MetadataImport, CancellationToken.None).GetAwaiter().GetResult();
}
rootFolder.AddVirtualChild(folder);
@@ -1868,7 +1868,8 @@ namespace Emby.Server.Implementations.Library
return image.Path != null && !image.IsLocalFile;
}
- public void UpdateImages(BaseItem item, bool forceUpdate = false)
+ ///
+ public async Task UpdateImagesAsync(BaseItem item, bool forceUpdate = false)
{
if (item == null)
{
@@ -1891,7 +1892,7 @@ namespace Emby.Server.Implementations.Library
try
{
var index = item.GetImageIndex(img);
- image = ConvertImageToLocal(item, img, index).ConfigureAwait(false).GetAwaiter().GetResult();
+ image = await ConvertImageToLocal(item, img, index).ConfigureAwait(false);
}
catch (ArgumentException)
{
@@ -1913,7 +1914,7 @@ namespace Emby.Server.Implementations.Library
}
catch (Exception ex)
{
- _logger.LogError(ex, "Cannnot get image dimensions for {0}", image.Path);
+ _logger.LogError(ex, "Cannot get image dimensions for {0}", image.Path);
image.Width = 0;
image.Height = 0;
continue;
@@ -1943,10 +1944,8 @@ namespace Emby.Server.Implementations.Library
RegisterItem(item);
}
- ///
- /// Updates the item.
- ///
- public void UpdateItems(IReadOnlyList items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken)
+ ///
+ public async Task UpdateItemsAsync(IReadOnlyList items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken)
{
foreach (var item in items)
{
@@ -1957,7 +1956,7 @@ namespace Emby.Server.Implementations.Library
item.DateLastSaved = DateTime.UtcNow;
- UpdateImages(item, updateReason >= ItemUpdateType.ImageUpdate);
+ await UpdateImagesAsync(item, updateReason >= ItemUpdateType.ImageUpdate).ConfigureAwait(false);
}
_itemRepository.SaveItems(items, cancellationToken);
@@ -1991,17 +1990,9 @@ namespace Emby.Server.Implementations.Library
}
}
- ///
- /// Updates the item.
- ///
- /// The item.
- /// The parent item.
- /// The update reason.
- /// The cancellation token.
- public void UpdateItem(BaseItem item, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken)
- {
- UpdateItems(new[] { item }, parent, updateReason, cancellationToken);
- }
+ ///
+ public Task UpdateItemAsync(BaseItem item, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken)
+ => UpdateItemsAsync(new[] { item }, parent, updateReason, cancellationToken);
///
/// Reports the item removed.
@@ -2233,7 +2224,7 @@ namespace Emby.Server.Implementations.Library
if (refresh)
{
- item.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None);
+ item.UpdateToRepositoryAsync(ItemUpdateType.MetadataImport, CancellationToken.None).GetAwaiter().GetResult();
ProviderManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal);
}
@@ -2420,7 +2411,7 @@ namespace Emby.Server.Implementations.Library
if (!string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase))
{
item.ViewType = viewType;
- item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).GetAwaiter().GetResult();
}
var refresh = isNew || DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval;
@@ -2902,7 +2893,7 @@ namespace Emby.Server.Implementations.Library
await ProviderManager.SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false);
- item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
return item.GetImageInfo(image.Type, imageIndex);
}
@@ -2920,7 +2911,7 @@ namespace Emby.Server.Implementations.Library
// Remove this image to prevent it from retrying over and over
item.RemoveImage(image);
- item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
throw new InvalidOperationException();
}
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 90cbd85a55..5ed6baeb9b 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -422,7 +422,7 @@ namespace Emby.Server.Implementations.LiveTv
}
}
- private LiveTvChannel GetChannel(ChannelInfo channelInfo, string serviceName, BaseItem parentFolder, CancellationToken cancellationToken)
+ private async Task GetChannelAsync(ChannelInfo channelInfo, string serviceName, BaseItem parentFolder, CancellationToken cancellationToken)
{
var parentFolderId = parentFolder.Id;
var isNew = false;
@@ -512,7 +512,7 @@ namespace Emby.Server.Implementations.LiveTv
}
else if (forceUpdate)
{
- _libraryManager.UpdateItem(item, parentFolder, ItemUpdateType.MetadataImport, cancellationToken);
+ await _libraryManager.UpdateItemAsync(item, parentFolder, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
}
return item;
@@ -1129,7 +1129,7 @@ namespace Emby.Server.Implementations.LiveTv
try
{
- var item = GetChannel(channelInfo.Item2, channelInfo.Item1, parentFolder, cancellationToken);
+ var item = await GetChannelAsync(channelInfo.Item2, channelInfo.Item1, parentFolder, cancellationToken).ConfigureAwait(false);
list.Add(item);
}
@@ -1146,7 +1146,7 @@ namespace Emby.Server.Implementations.LiveTv
double percent = numComplete;
percent /= allChannelsList.Count;
- progress.Report(5 * percent + 10);
+ progress.Report((5 * percent) + 10);
}
progress.Report(15);
@@ -1221,7 +1221,11 @@ namespace Emby.Server.Implementations.LiveTv
if (updatedPrograms.Count > 0)
{
- _libraryManager.UpdateItems(updatedPrograms, currentChannel, ItemUpdateType.MetadataImport, cancellationToken);
+ await _libraryManager.UpdateItemsAsync(
+ updatedPrograms,
+ currentChannel,
+ ItemUpdateType.MetadataImport,
+ cancellationToken).ConfigureAwait(false);
}
currentChannel.IsMovie = isMovie;
@@ -1234,7 +1238,7 @@ namespace Emby.Server.Implementations.LiveTv
currentChannel.AddTag("Kids");
}
- currentChannel.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken);
+ await currentChannel.UpdateToRepositoryAsync(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
await currentChannel.RefreshMetadata(
new MetadataRefreshOptions(new DirectoryService(_fileSystem))
{
diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs
index 38ceadedbb..d35223b0a6 100644
--- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs
+++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs
@@ -184,17 +184,17 @@ namespace Emby.Server.Implementations.Playlists
return Playlist.GetPlaylistItems(playlistMediaType, items, user, options);
}
- public void AddToPlaylist(string playlistId, ICollection itemIds, Guid userId)
+ public Task AddToPlaylistAsync(string playlistId, ICollection itemIds, Guid userId)
{
var user = userId.Equals(Guid.Empty) ? null : _userManager.GetUserById(userId);
- AddToPlaylistInternal(playlistId, itemIds, user, new DtoOptions(false)
+ return AddToPlaylistInternal(playlistId, itemIds, user, new DtoOptions(false)
{
EnableImages = true
});
}
- private void AddToPlaylistInternal(string playlistId, ICollection newItemIds, User user, DtoOptions options)
+ private async Task AddToPlaylistInternal(string playlistId, ICollection newItemIds, User user, DtoOptions options)
{
// Retrieve the existing playlist
var playlist = _libraryManager.GetItemById(playlistId) as Playlist
@@ -238,7 +238,7 @@ namespace Emby.Server.Implementations.Playlists
// Update the playlist in the repository
playlist.LinkedChildren = newLinkedChildren;
- playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await playlist.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
// Update the playlist on disk
if (playlist.IsFile)
@@ -256,7 +256,7 @@ namespace Emby.Server.Implementations.Playlists
RefreshPriority.High);
}
- public void RemoveFromPlaylist(string playlistId, IEnumerable entryIds)
+ public async Task RemoveFromPlaylistAsync(string playlistId, IEnumerable entryIds)
{
if (!(_libraryManager.GetItemById(playlistId) is Playlist playlist))
{
@@ -273,7 +273,7 @@ namespace Emby.Server.Implementations.Playlists
.Select(i => i.Item1)
.ToArray();
- playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await playlist.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
if (playlist.IsFile)
{
@@ -289,7 +289,7 @@ namespace Emby.Server.Implementations.Playlists
RefreshPriority.High);
}
- public void MoveItem(string playlistId, string entryId, int newIndex)
+ public async Task MoveItemAsync(string playlistId, string entryId, int newIndex)
{
if (!(_libraryManager.GetItemById(playlistId) is Playlist playlist))
{
@@ -322,7 +322,7 @@ namespace Emby.Server.Implementations.Playlists
playlist.LinkedChildren = newList.ToArray();
- playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await playlist.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
if (playlist.IsFile)
{
diff --git a/Jellyfin.Api/Controllers/CollectionController.cs b/Jellyfin.Api/Controllers/CollectionController.cs
index 53821a1885..c5910d6e81 100644
--- a/Jellyfin.Api/Controllers/CollectionController.cs
+++ b/Jellyfin.Api/Controllers/CollectionController.cs
@@ -1,5 +1,6 @@
using System;
using System.ComponentModel.DataAnnotations;
+using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
@@ -51,7 +52,7 @@ namespace Jellyfin.Api.Controllers
/// A with information about the new collection.
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult CreateCollection(
+ public async Task> CreateCollection(
[FromQuery] string? name,
[FromQuery] string? ids,
[FromQuery] Guid? parentId,
@@ -59,14 +60,14 @@ namespace Jellyfin.Api.Controllers
{
var userId = _authContext.GetAuthorizationInfo(Request).UserId;
- var item = _collectionManager.CreateCollection(new CollectionCreationOptions
+ var item = await _collectionManager.CreateCollectionAsync(new CollectionCreationOptions
{
IsLocked = isLocked,
Name = name,
ParentId = parentId,
ItemIdList = RequestHelpers.Split(ids, ',', true),
UserIds = new[] { userId }
- });
+ }).ConfigureAwait(false);
var dtoOptions = new DtoOptions().AddClientFields(Request);
@@ -87,9 +88,9 @@ namespace Jellyfin.Api.Controllers
/// A indicating success.
[HttpPost("{collectionId}/Items")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
- public ActionResult AddToCollection([FromRoute] Guid collectionId, [FromQuery, Required] string? itemIds)
+ public async Task AddToCollection([FromRoute] Guid collectionId, [FromQuery, Required] string? itemIds)
{
- _collectionManager.AddToCollection(collectionId, RequestHelpers.Split(itemIds, ',', true));
+ await _collectionManager.AddToCollectionAsync(collectionId, RequestHelpers.GetGuids(itemIds)).ConfigureAwait(true);
return NoContent();
}
@@ -102,9 +103,9 @@ namespace Jellyfin.Api.Controllers
/// A indicating success.
[HttpDelete("{collectionId}/Items")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
- public ActionResult RemoveFromCollection([FromRoute] Guid collectionId, [FromQuery, Required] string? itemIds)
+ public async Task RemoveFromCollection([FromRoute] Guid collectionId, [FromQuery, Required] string? itemIds)
{
- _collectionManager.RemoveFromCollection(collectionId, RequestHelpers.Split(itemIds, ',', true));
+ await _collectionManager.RemoveFromCollectionAsync(collectionId, RequestHelpers.GetGuids(itemIds)).ConfigureAwait(false);
return NoContent();
}
}
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index 75734f0af0..ca9c2fa460 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -174,7 +174,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public ActionResult DeleteItemImage(
+ public async Task DeleteItemImage(
[FromRoute] Guid itemId,
[FromRoute] ImageType imageType,
[FromRoute] int? imageIndex = null)
@@ -185,7 +185,7 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- item.DeleteImage(imageType, imageIndex ?? 0);
+ await item.DeleteImageAsync(imageType, imageIndex ?? 0).ConfigureAwait(false);
return NoContent();
}
@@ -218,7 +218,7 @@ namespace Jellyfin.Api.Controllers
// Handle image/png; charset=utf-8
var mimeType = Request.ContentType.Split(';').FirstOrDefault();
await _providerManager.SaveImage(item, Request.Body, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
- item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
return NoContent();
}
@@ -237,7 +237,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public ActionResult UpdateItemImageIndex(
+ public async Task UpdateItemImageIndex(
[FromRoute] Guid itemId,
[FromRoute] ImageType imageType,
[FromRoute] int imageIndex,
@@ -249,7 +249,7 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- item.SwapImages(imageType, imageIndex, newIndex);
+ await item.SwapImagesAsync(imageType, imageIndex, newIndex).ConfigureAwait(false);
return NoContent();
}
@@ -264,7 +264,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public ActionResult> GetItemImageInfos([FromRoute] Guid itemId)
+ public async Task>> GetItemImageInfos([FromRoute] Guid itemId)
{
var item = _libraryManager.GetItemById(itemId);
if (item == null)
@@ -281,7 +281,7 @@ namespace Jellyfin.Api.Controllers
return list;
}
- _libraryManager.UpdateImages(item); // this makes sure dimensions and hashes are correct
+ await _libraryManager.UpdateImagesAsync(item).ConfigureAwait(false); // this makes sure dimensions and hashes are correct
foreach (var image in itemImages)
{
diff --git a/Jellyfin.Api/Controllers/ItemUpdateController.cs b/Jellyfin.Api/Controllers/ItemUpdateController.cs
index 4b40c6ada9..ec52f49964 100644
--- a/Jellyfin.Api/Controllers/ItemUpdateController.cs
+++ b/Jellyfin.Api/Controllers/ItemUpdateController.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading;
+using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
@@ -67,7 +68,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("Items/{itemId}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public ActionResult UpdateItem([FromRoute] Guid itemId, [FromBody, Required] BaseItemDto request)
+ public async Task UpdateItem([FromRoute] Guid itemId, [FromBody, Required] BaseItemDto request)
{
var item = _libraryManager.GetItemById(itemId);
if (item == null)
@@ -101,7 +102,7 @@ namespace Jellyfin.Api.Controllers
item.OnMetadataChanged();
- item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
if (isLockedChanged && item.IsFolder)
{
@@ -110,7 +111,7 @@ namespace Jellyfin.Api.Controllers
foreach (var child in folder.GetRecursiveChildren())
{
child.IsLocked = newLockData;
- child.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await child.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
}
}
diff --git a/Jellyfin.Api/Controllers/PlaylistsController.cs b/Jellyfin.Api/Controllers/PlaylistsController.cs
index 12c87d7c36..d69228c33d 100644
--- a/Jellyfin.Api/Controllers/PlaylistsController.cs
+++ b/Jellyfin.Api/Controllers/PlaylistsController.cs
@@ -83,12 +83,12 @@ namespace Jellyfin.Api.Controllers
/// An on success.
[HttpPost("{playlistId}/Items")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
- public ActionResult AddToPlaylist(
+ public async Task AddToPlaylist(
[FromRoute] string? playlistId,
[FromQuery] string? ids,
[FromQuery] Guid? userId)
{
- _playlistManager.AddToPlaylist(playlistId, RequestHelpers.GetGuids(ids), userId ?? Guid.Empty);
+ await _playlistManager.AddToPlaylistAsync(playlistId, RequestHelpers.GetGuids(ids), userId ?? Guid.Empty).ConfigureAwait(false);
return NoContent();
}
@@ -102,12 +102,12 @@ namespace Jellyfin.Api.Controllers
/// An on success.
[HttpPost("{playlistId}/Items/{itemId}/Move/{newIndex}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
- public ActionResult MoveItem(
+ public async Task MoveItem(
[FromRoute] string? playlistId,
[FromRoute] string? itemId,
[FromRoute] int newIndex)
{
- _playlistManager.MoveItem(playlistId, itemId, newIndex);
+ await _playlistManager.MoveItemAsync(playlistId, itemId, newIndex).ConfigureAwait(false);
return NoContent();
}
@@ -120,9 +120,9 @@ namespace Jellyfin.Api.Controllers
/// An on success.
[HttpDelete("{playlistId}/Items")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
- public ActionResult RemoveFromPlaylist([FromRoute] string? playlistId, [FromQuery] string? entryIds)
+ public async Task RemoveFromPlaylist([FromRoute] string? playlistId, [FromQuery] string? entryIds)
{
- _playlistManager.RemoveFromPlaylist(playlistId, RequestHelpers.Split(entryIds, ',', true));
+ await _playlistManager.RemoveFromPlaylistAsync(playlistId, RequestHelpers.Split(entryIds, ',', true)).ConfigureAwait(false);
return NoContent();
}
diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs
index a203c50b96..30a4f73fc0 100644
--- a/Jellyfin.Api/Controllers/RemoteImageController.cs
+++ b/Jellyfin.Api/Controllers/RemoteImageController.cs
@@ -221,7 +221,7 @@ namespace Jellyfin.Api.Controllers
await _providerManager.SaveImage(item, imageUrl, type, null, CancellationToken.None)
.ConfigureAwait(false);
- item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
return NoContent();
}
diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs
index 14d3f24607..f42810c945 100644
--- a/Jellyfin.Api/Controllers/VideosController.cs
+++ b/Jellyfin.Api/Controllers/VideosController.cs
@@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public ActionResult DeleteAlternateSources([FromRoute] Guid itemId)
+ public async Task DeleteAlternateSources([FromRoute] Guid itemId)
{
var video = (Video)_libraryManager.GetItemById(itemId);
@@ -180,12 +180,12 @@ namespace Jellyfin.Api.Controllers
link.SetPrimaryVersionId(null);
link.LinkedAlternateVersions = Array.Empty();
- link.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await link.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
}
video.LinkedAlternateVersions = Array.Empty();
video.SetPrimaryVersionId(null);
- video.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await video.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
return NoContent();
}
@@ -201,7 +201,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
- public ActionResult MergeVersions([FromQuery, Required] string? itemIds)
+ public async Task MergeVersions([FromQuery, Required] string? itemIds)
{
var items = RequestHelpers.Split(itemIds, ',', true)
.Select(i => _libraryManager.GetItemById(i))
@@ -239,7 +239,7 @@ namespace Jellyfin.Api.Controllers
{
item.SetPrimaryVersionId(primaryVersion.Id.ToString("N", CultureInfo.InvariantCulture));
- item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
list.Add(new LinkedChild
{
@@ -258,12 +258,12 @@ namespace Jellyfin.Api.Controllers
if (item.LinkedAlternateVersions.Length > 0)
{
item.LinkedAlternateVersions = Array.Empty();
- item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
}
}
primaryVersion.LinkedAlternateVersions = list.ToArray();
- primaryVersion.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ await primaryVersion.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
return NoContent();
}
diff --git a/MediaBrowser.Controller/Collections/ICollectionManager.cs b/MediaBrowser.Controller/Collections/ICollectionManager.cs
index 701423c0f3..3861ae634a 100644
--- a/MediaBrowser.Controller/Collections/ICollectionManager.cs
+++ b/MediaBrowser.Controller/Collections/ICollectionManager.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
@@ -27,24 +28,23 @@ namespace MediaBrowser.Controller.Collections
/// Creates the collection.
///
/// The options.
- BoxSet CreateCollection(CollectionCreationOptions options);
+ Task CreateCollectionAsync(CollectionCreationOptions options);
///
/// Adds to collection.
///
/// The collection identifier.
/// The item ids.
- void AddToCollection(Guid collectionId, IEnumerable itemIds);
+ /// representing the asynchronous operation.
+ Task AddToCollectionAsync(Guid collectionId, IEnumerable itemIds);
///
/// Removes from collection.
///
/// The collection identifier.
/// The item ids.
- void RemoveFromCollection(Guid collectionId, IEnumerable itemIds);
-
- void AddToCollection(Guid collectionId, IEnumerable itemIds);
- void RemoveFromCollection(Guid collectionId, IEnumerable itemIds);
+ /// A representing the asynchronous operation.
+ Task RemoveFromCollectionAsync(Guid collectionId, IEnumerable itemIds);
///
/// Collapses the items within box sets.
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index f34309c400..9e595ddc3e 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -1390,7 +1390,7 @@ namespace MediaBrowser.Controller.Entities
new List();
var ownedItemsChanged = await RefreshedOwnedItems(options, files, cancellationToken).ConfigureAwait(false);
- LibraryManager.UpdateImages(this); // ensure all image properties in DB are fresh
+ await LibraryManager.UpdateImagesAsync(this).ConfigureAwait(false); // ensure all image properties in DB are fresh
if (ownedItemsChanged)
{
@@ -2279,7 +2279,7 @@ namespace MediaBrowser.Controller.Entities
///
/// The type.
/// The index.
- public void DeleteImage(ImageType type, int index)
+ public async Task DeleteImageAsync(ImageType type, int index)
{
var info = GetImageInfo(type, index);
@@ -2297,7 +2297,7 @@ namespace MediaBrowser.Controller.Entities
FileSystem.DeleteFile(info.Path);
}
- UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
+ await UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
}
public void RemoveImage(ItemImageInfo image)
@@ -2310,10 +2310,8 @@ namespace MediaBrowser.Controller.Entities
ImageInfos = ImageInfos.Except(deletedImages).ToArray();
}
- public virtual void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
- {
- LibraryManager.UpdateItem(this, GetParent(), updateReason, cancellationToken);
- }
+ public virtual Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
+ => LibraryManager.UpdateItemAsync(this, GetParent(), updateReason, cancellationToken);
///
/// Validates that images within the item are still on the filesystem.
@@ -2558,7 +2556,7 @@ namespace MediaBrowser.Controller.Entities
return type == ImageType.Backdrop || type == ImageType.Screenshot || type == ImageType.Chapter;
}
- public void SwapImages(ImageType type, int index1, int index2)
+ public Task SwapImagesAsync(ImageType type, int index1, int index2)
{
if (!AllowsMultipleImages(type))
{
@@ -2571,13 +2569,13 @@ namespace MediaBrowser.Controller.Entities
if (info1 == null || info2 == null)
{
// Nothing to do
- return;
+ return Task.CompletedTask;
}
if (!info1.IsLocalFile || !info2.IsLocalFile)
{
// TODO: Not supported yet
- return;
+ return Task.CompletedTask;
}
var path1 = info1.Path;
@@ -2594,7 +2592,7 @@ namespace MediaBrowser.Controller.Entities
info2.Width = 0;
info2.Height = 0;
- UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
+ return UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None);
}
public virtual bool IsPlayed(User user)
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 6441340f97..11542c1cad 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -350,12 +350,12 @@ namespace MediaBrowser.Controller.Entities
if (currentChild.UpdateFromResolvedItem(child) > ItemUpdateType.None)
{
- currentChild.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken);
+ await currentChild.UpdateToRepositoryAsync(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
}
else
{
// metadata is up-to-date; make sure DB has correct images dimensions and hash
- LibraryManager.UpdateImages(currentChild);
+ await LibraryManager.UpdateImagesAsync(currentChild).ConfigureAwait(false);
}
continue;
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index b7d7e8e1a3..eeff78e103 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -495,9 +495,10 @@ namespace MediaBrowser.Controller.Entities
}
}
- public override void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
+ ///
+ public override async Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
{
- base.UpdateToRepository(updateReason, cancellationToken);
+ await base.UpdateToRepositoryAsync(updateReason, cancellationToken).ConfigureAwait(false);
var localAlternates = GetLocalAlternateVersionIds()
.Select(i => LibraryManager.GetItemById(i))
@@ -514,7 +515,7 @@ namespace MediaBrowser.Controller.Entities
item.Genres = Genres;
item.ProviderIds = ProviderIds;
- item.UpdateToRepository(ItemUpdateType.MetadataDownload, cancellationToken);
+ await item.UpdateToRepositoryAsync(ItemUpdateType.MetadataDownload, cancellationToken).ConfigureAwait(false);
}
}
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 9abcf2b626..d53b1fc8da 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -72,6 +72,7 @@ namespace MediaBrowser.Controller.Library
/// The name.
/// Task{Artist}.
MusicArtist GetArtist(string name);
+
MusicArtist GetArtist(string name, DtoOptions options);
///
/// Gets a Studio.
@@ -124,7 +125,7 @@ namespace MediaBrowser.Controller.Library
///
void QueueLibraryScan();
- void UpdateImages(BaseItem item, bool forceUpdate = false);
+ Task UpdateImagesAsync(BaseItem item, bool forceUpdate = false);
///
/// Gets the default view.
@@ -179,6 +180,7 @@ namespace MediaBrowser.Controller.Library
/// The sort order.
/// IEnumerable{BaseItem}.
IEnumerable Sort(IEnumerable items, User user, IEnumerable sortBy, SortOrder sortOrder);
+
IEnumerable Sort(IEnumerable items, User user, IEnumerable> orderBy);
///
@@ -200,9 +202,16 @@ namespace MediaBrowser.Controller.Library
///
/// Updates the item.
///
- void UpdateItems(IReadOnlyList items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken);
+ Task UpdateItemsAsync(IReadOnlyList items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken);
- void UpdateItem(BaseItem item, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken);
+ ///
+ /// Updates the item.
+ ///
+ /// The item.
+ /// The parent item.
+ /// The update reason.
+ /// The cancellation token.
+ Task UpdateItemAsync(BaseItem item, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken);
///
/// Retrieves the item.
@@ -317,7 +326,8 @@ namespace MediaBrowser.Controller.Library
/// The name.
/// Type of the view.
/// Name of the sort.
- UserView GetNamedView(string name,
+ UserView GetNamedView(
+ string name,
string viewType,
string sortName);
@@ -329,7 +339,8 @@ namespace MediaBrowser.Controller.Library
/// Type of the view.
/// Name of the sort.
/// The unique identifier.
- UserView GetNamedView(string name,
+ UserView GetNamedView(
+ string name,
Guid parentId,
string viewType,
string sortName,
@@ -341,7 +352,8 @@ namespace MediaBrowser.Controller.Library
/// The parent.
/// Type of the view.
/// Name of the sort.
- UserView GetShadowView(BaseItem parent,
+ UserView GetShadowView(
+ BaseItem parent,
string viewType,
string sortName);
@@ -393,7 +405,9 @@ namespace MediaBrowser.Controller.Library
/// The file system children.
/// The directory service.
/// IEnumerable<Trailer>.
- IEnumerable
public class PlaybackProgressEventArgs : EventArgs
{
+ public PlaybackProgressEventArgs()
+ {
+ Users = new List();
+ }
+
public List Users { get; set; }
public long? PlaybackPositionTicks { get; set; }
@@ -35,10 +42,5 @@ namespace MediaBrowser.Controller.Library
public string PlaySessionId { get; set; }
public SessionInfo Session { get; set; }
-
- public PlaybackProgressEventArgs()
- {
- Users = new List();
- }
}
}
diff --git a/MediaBrowser.Controller/Library/PlaybackStopEventArgs.cs b/MediaBrowser.Controller/Library/PlaybackStopEventArgs.cs
index 12add25732..f0d77ba2d4 100644
--- a/MediaBrowser.Controller/Library/PlaybackStopEventArgs.cs
+++ b/MediaBrowser.Controller/Library/PlaybackStopEventArgs.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Library
{
public class PlaybackStopEventArgs : PlaybackProgressEventArgs
diff --git a/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs b/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs
index fa01927843..cd91097535 100644
--- a/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs
+++ b/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
diff --git a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs
index 67d0df4fdc..d7afd21184 100644
--- a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using MediaBrowser.Model.LiveTv;
namespace MediaBrowser.Controller.LiveTv
diff --git a/MediaBrowser.Controller/LiveTv/IListingsProvider.cs b/MediaBrowser.Controller/LiveTv/IListingsProvider.cs
index 2ea0a748e1..038ff2eaeb 100644
--- a/MediaBrowser.Controller/LiveTv/IListingsProvider.cs
+++ b/MediaBrowser.Controller/LiveTv/IListingsProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading;
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
index f619b011bf..0794422153 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading;
@@ -105,6 +107,7 @@ namespace MediaBrowser.Controller.LiveTv
///
/// The identifier.
/// The media source identifier.
+ /// The current live streams.
/// The cancellation token.
/// Task{StreamResponseInfo}.
Task> GetChannelStream(string id, string mediaSourceId, List currentLiveStreams, CancellationToken cancellationToken);
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
index b71a766485..3ca1d165ef 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading;
diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
index 3679e4f78f..ff92bf856c 100644
--- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs
+++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@@ -14,28 +16,37 @@ namespace MediaBrowser.Controller.LiveTv
///
/// The name.
string Name { get; }
+
///
/// Gets the type.
///
/// The type.
string Type { get; }
+
+ bool IsSupported { get; }
+
///
/// Gets the channels.
///
/// Task<IEnumerable<ChannelInfo>>.
Task> GetChannels(bool enableCache, CancellationToken cancellationToken);
+
///
/// Gets the tuner infos.
///
/// The cancellation token.
/// Task<List<LiveTvTunerInfo>>.
Task> GetTunerInfos(CancellationToken cancellationToken);
+
///
/// Gets the channel stream.
///
/// The channel identifier.
/// The stream identifier.
+ /// The current live streams.
+ /// The cancellation token to cancel operation.
Task GetChannelStream(string channelId, string streamId, List currentLiveStreams, CancellationToken cancellationToken);
+
///
/// Gets the channel stream media sources.
///
@@ -45,10 +56,7 @@ namespace MediaBrowser.Controller.LiveTv
Task> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken);
Task> DiscoverDevices(int discoveryDurationMs, CancellationToken cancellationToken);
- bool IsSupported
- {
- get;
- }
+
}
public interface IConfigurableTunerHost
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
index aa7c12dd14..ec933caf34 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvConflictException.cs b/MediaBrowser.Controller/LiveTv/LiveTvConflictException.cs
index 0e09d1aeba..881c42c738 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvConflictException.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvConflictException.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
namespace MediaBrowser.Controller.LiveTv
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
index e1de01ff02..43af495dd6 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs
index 67b2f0eb1c..02178297b1 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using MediaBrowser.Model.LiveTv;
@@ -5,6 +7,12 @@ namespace MediaBrowser.Controller.LiveTv
{
public class LiveTvServiceStatusInfo
{
+ public LiveTvServiceStatusInfo()
+ {
+ Tuners = new List();
+ IsVisible = true;
+ }
+
///
/// Gets or sets the status.
///
@@ -39,11 +47,5 @@ namespace MediaBrowser.Controller.LiveTv
///
/// true if this instance is visible; otherwise, false.
public bool IsVisible { get; set; }
-
- public LiveTvServiceStatusInfo()
- {
- Tuners = new List();
- IsVisible = true;
- }
}
}
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs
index 2857f73f6d..739978e7ce 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using MediaBrowser.Model.LiveTv;
@@ -5,6 +7,11 @@ namespace MediaBrowser.Controller.LiveTv
{
public class LiveTvTunerInfo
{
+ public LiveTvTunerInfo()
+ {
+ Clients = new List();
+ }
+
///
/// Gets or sets the type of the source.
///
@@ -64,10 +71,5 @@ namespace MediaBrowser.Controller.LiveTv
///
/// true if this instance can reset; otherwise, false.
public bool CanReset { get; set; }
-
- public LiveTvTunerInfo()
- {
- Clients = new List();
- }
}
}
diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
index d06a15323a..bdcffd5cae 100644
--- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using MediaBrowser.Model.LiveTv;
diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
index b9e0218ab2..303882b7ef 100644
--- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using MediaBrowser.Model.LiveTv;
diff --git a/MediaBrowser.Controller/LiveTv/RecordingStatusChangedEventArgs.cs b/MediaBrowser.Controller/LiveTv/RecordingStatusChangedEventArgs.cs
index 99460a6862..847c0ea8c0 100644
--- a/MediaBrowser.Controller/LiveTv/RecordingStatusChangedEventArgs.cs
+++ b/MediaBrowser.Controller/LiveTv/RecordingStatusChangedEventArgs.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using MediaBrowser.Model.LiveTv;
diff --git a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs
index 6e7acaae39..1343ecd982 100644
--- a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using MediaBrowser.Model.LiveTv;
diff --git a/MediaBrowser.Controller/LiveTv/TimerInfo.cs b/MediaBrowser.Controller/LiveTv/TimerInfo.cs
index df98bb6af8..bcef4666d2 100644
--- a/MediaBrowser.Controller/LiveTv/TimerInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/TimerInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs b/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs
index df3f55c26c..2759b314f5 100644
--- a/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs
+++ b/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.LiveTv
{
public class TunerChannelMapping
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 67f17f7a52..9692cf921d 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -30,6 +30,7 @@
netstandard2.1
false
true
+ true
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 7b09f489e9..550916f823 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
index b971b7c4bf..68bc502a0f 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
index 8f6fcb9ab1..4cbb63e46c 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/MediaBrowser.Controller/MediaEncoding/IAttachmentExtractor.cs b/MediaBrowser.Controller/MediaEncoding/IAttachmentExtractor.cs
index 7c7e84de64..fbc8275341 100644
--- a/MediaBrowser.Controller/MediaEncoding/IAttachmentExtractor.cs
+++ b/MediaBrowser.Controller/MediaEncoding/IAttachmentExtractor.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.IO;
using System.Threading;
using System.Threading.Tasks;
diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
index f60e702393..17d6dc5d27 100644
--- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
+++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading;
diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs
index 174e74f348..6ebf7f159b 100644
--- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs
+++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -12,7 +14,8 @@ namespace MediaBrowser.Controller.MediaEncoding
/// Gets the subtitles.
///
/// Task{Stream}.
- Task GetSubtitles(BaseItem item,
+ Task GetSubtitles(
+ BaseItem item,
string mediaSourceId,
int subtitleStreamIndex,
string outputFormat,
@@ -25,6 +28,7 @@ namespace MediaBrowser.Controller.MediaEncoding
/// Gets the subtitle language encoding parameter.
///
/// The path.
+ /// The language.
/// The protocol.
/// The cancellation token.
/// System.String.
diff --git a/MediaBrowser.Controller/MediaEncoding/ImageEncodingOptions.cs b/MediaBrowser.Controller/MediaEncoding/ImageEncodingOptions.cs
index 361dd79dcc..e7b4c8c15c 100644
--- a/MediaBrowser.Controller/MediaEncoding/ImageEncodingOptions.cs
+++ b/MediaBrowser.Controller/MediaEncoding/ImageEncodingOptions.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.MediaEncoding
{
public class ImageEncodingOptions
diff --git a/MediaBrowser.Controller/MediaEncoding/JobLogger.cs b/MediaBrowser.Controller/MediaEncoding/JobLogger.cs
index c9f64c7075..ac520c5c44 100644
--- a/MediaBrowser.Controller/MediaEncoding/JobLogger.cs
+++ b/MediaBrowser.Controller/MediaEncoding/JobLogger.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Globalization;
using System.IO;
diff --git a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs
index 6c9bbb043e..ce53c23ad2 100644
--- a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs
+++ b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs
index 39a47792ae..59729de49c 100644
--- a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs
+++ b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
diff --git a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs
index 87a7f7e10b..1366fd42e8 100644
--- a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs
+++ b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
@@ -53,7 +55,7 @@ namespace MediaBrowser.Controller.Net
}
public bool IgnoreLegacyAuth { get; set; }
-
+
public bool AllowLocalOnly { get; set; }
}
@@ -68,7 +70,7 @@ namespace MediaBrowser.Controller.Net
bool AllowLocalOnly { get; }
string[] GetRoles();
-
+
bool IgnoreLegacyAuth { get; }
}
}
diff --git a/MediaBrowser.Controller/Net/AuthorizationInfo.cs b/MediaBrowser.Controller/Net/AuthorizationInfo.cs
index 4361e253b6..735c46ef86 100644
--- a/MediaBrowser.Controller/Net/AuthorizationInfo.cs
+++ b/MediaBrowser.Controller/Net/AuthorizationInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using Jellyfin.Data.Entities;
diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
index a54f6d57b5..916dea58be 100644
--- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
+++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/MediaBrowser.Controller/Net/IHttpResultFactory.cs b/MediaBrowser.Controller/Net/IHttpResultFactory.cs
index 609bd5f596..8293a87142 100644
--- a/MediaBrowser.Controller/Net/IHttpResultFactory.cs
+++ b/MediaBrowser.Controller/Net/IHttpResultFactory.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
@@ -21,7 +23,9 @@ namespace MediaBrowser.Controller.Net
object GetResult(string content, string contentType, IDictionary responseHeaders = null);
object GetResult(IRequest requestContext, byte[] content, string contentType, IDictionary responseHeaders = null);
+
object GetResult(IRequest requestContext, Stream content, string contentType, IDictionary responseHeaders = null);
+
object GetResult(IRequest requestContext, string content, string contentType, IDictionary responseHeaders = null);
object GetRedirectResult(string url);
diff --git a/MediaBrowser.Controller/Net/ISessionContext.cs b/MediaBrowser.Controller/Net/ISessionContext.cs
index 421ac3fe24..5da748f41d 100644
--- a/MediaBrowser.Controller/Net/ISessionContext.cs
+++ b/MediaBrowser.Controller/Net/ISessionContext.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Services;
@@ -7,9 +9,11 @@ namespace MediaBrowser.Controller.Net
public interface ISessionContext
{
SessionInfo GetSession(object requestContext);
+
User GetUser(object requestContext);
SessionInfo GetSession(IRequest requestContext);
+
User GetUser(IRequest requestContext);
}
}
diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs
index 3ef8e5f6d4..e87f3bca68 100644
--- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs
+++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
#nullable enable
using System;
diff --git a/MediaBrowser.Controller/Net/SecurityException.cs b/MediaBrowser.Controller/Net/SecurityException.cs
index f0d0b45a0a..c6347133a8 100644
--- a/MediaBrowser.Controller/Net/SecurityException.cs
+++ b/MediaBrowser.Controller/Net/SecurityException.cs
@@ -1,3 +1,5 @@
+#nullable enable
+
using System;
namespace MediaBrowser.Controller.Net
diff --git a/MediaBrowser.Controller/Net/StaticResultOptions.cs b/MediaBrowser.Controller/Net/StaticResultOptions.cs
index 85772e0368..c1e9bc8453 100644
--- a/MediaBrowser.Controller/Net/StaticResultOptions.cs
+++ b/MediaBrowser.Controller/Net/StaticResultOptions.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/MediaBrowser.Controller/Notifications/INotificationManager.cs b/MediaBrowser.Controller/Notifications/INotificationManager.cs
index 44defbe0b2..08d9bc12a2 100644
--- a/MediaBrowser.Controller/Notifications/INotificationManager.cs
+++ b/MediaBrowser.Controller/Notifications/INotificationManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
diff --git a/MediaBrowser.Controller/Notifications/INotificationService.cs b/MediaBrowser.Controller/Notifications/INotificationService.cs
index ab5eb13cd4..fa947220ad 100644
--- a/MediaBrowser.Controller/Notifications/INotificationService.cs
+++ b/MediaBrowser.Controller/Notifications/INotificationService.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
diff --git a/MediaBrowser.Controller/Notifications/INotificationTypeFactory.cs b/MediaBrowser.Controller/Notifications/INotificationTypeFactory.cs
index 9f1d2841d7..52a3e120b5 100644
--- a/MediaBrowser.Controller/Notifications/INotificationTypeFactory.cs
+++ b/MediaBrowser.Controller/Notifications/INotificationTypeFactory.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using MediaBrowser.Model.Notifications;
diff --git a/MediaBrowser.Controller/Notifications/UserNotification.cs b/MediaBrowser.Controller/Notifications/UserNotification.cs
index a1029589b8..d768abfe73 100644
--- a/MediaBrowser.Controller/Notifications/UserNotification.cs
+++ b/MediaBrowser.Controller/Notifications/UserNotification.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using Jellyfin.Data.Entities;
using MediaBrowser.Model.Notifications;
diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs
index 0ae1b8bbfa..ebc37bd1f3 100644
--- a/MediaBrowser.Controller/Persistence/IItemRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading;
@@ -156,15 +158,23 @@ namespace MediaBrowser.Controller.Persistence
int GetCount(InternalItemsQuery query);
QueryResult<(BaseItem, ItemCounts)> GetGenres(InternalItemsQuery query);
+
QueryResult<(BaseItem, ItemCounts)> GetMusicGenres(InternalItemsQuery query);
+
QueryResult<(BaseItem, ItemCounts)> GetStudios(InternalItemsQuery query);
+
QueryResult<(BaseItem, ItemCounts)> GetArtists(InternalItemsQuery query);
+
QueryResult<(BaseItem, ItemCounts)> GetAlbumArtists(InternalItemsQuery query);
+
QueryResult<(BaseItem, ItemCounts)> GetAllArtists(InternalItemsQuery query);
List GetMusicGenreNames();
+
List GetStudioNames();
+
List GetGenreNames();
+
List GetAllArtistNames();
}
}
diff --git a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
index ba7c9fd509..81ba513cef 100644
--- a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
@@ -24,9 +24,15 @@ namespace MediaBrowser.Controller.Persistence
///
/// The user id.
/// The key.
- /// Task{UserItemData}.
+ /// The user data.
UserItemData GetUserData(long userId, string key);
+ ///
+ /// Gets the user data.
+ ///
+ /// The user id.
+ /// The keys.
+ /// The user data.
UserItemData GetUserData(long userId, List keys);
///
diff --git a/MediaBrowser.Controller/Persistence/MediaAttachmentQuery.cs b/MediaBrowser.Controller/Persistence/MediaAttachmentQuery.cs
index e3b2d46650..e07e96f73e 100644
--- a/MediaBrowser.Controller/Persistence/MediaAttachmentQuery.cs
+++ b/MediaBrowser.Controller/Persistence/MediaAttachmentQuery.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
namespace MediaBrowser.Controller.Persistence
diff --git a/MediaBrowser.Controller/Persistence/MediaStreamQuery.cs b/MediaBrowser.Controller/Persistence/MediaStreamQuery.cs
index 7dc563b3ad..f9295c8fd3 100644
--- a/MediaBrowser.Controller/Persistence/MediaStreamQuery.cs
+++ b/MediaBrowser.Controller/Persistence/MediaStreamQuery.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using MediaBrowser.Model.Entities;
diff --git a/MediaBrowser.Controller/Playlists/IPlaylistManager.cs b/MediaBrowser.Controller/Playlists/IPlaylistManager.cs
index a3e7d4a677..fbf2c52131 100644
--- a/MediaBrowser.Controller/Playlists/IPlaylistManager.cs
+++ b/MediaBrowser.Controller/Playlists/IPlaylistManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index 0fd63770f4..216dd27098 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/MediaBrowser.Controller/Plugins/ILocalizablePlugin.cs b/MediaBrowser.Controller/Plugins/ILocalizablePlugin.cs
index 5deb165f62..bf15fe0407 100644
--- a/MediaBrowser.Controller/Plugins/ILocalizablePlugin.cs
+++ b/MediaBrowser.Controller/Plugins/ILocalizablePlugin.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.IO;
using System.Reflection;
diff --git a/MediaBrowser.Controller/Plugins/IPluginConfigurationPage.cs b/MediaBrowser.Controller/Plugins/IPluginConfigurationPage.cs
index 077f5ab63e..93eab42cc7 100644
--- a/MediaBrowser.Controller/Plugins/IPluginConfigurationPage.cs
+++ b/MediaBrowser.Controller/Plugins/IPluginConfigurationPage.cs
@@ -42,6 +42,7 @@ namespace MediaBrowser.Controller.Plugins
/// The plugin configuration.
///
PluginConfiguration,
+
///
/// The none.
///
diff --git a/MediaBrowser.Controller/Providers/AlbumInfo.cs b/MediaBrowser.Controller/Providers/AlbumInfo.cs
index dbda4843f9..276bcf1252 100644
--- a/MediaBrowser.Controller/Providers/AlbumInfo.cs
+++ b/MediaBrowser.Controller/Providers/AlbumInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
diff --git a/MediaBrowser.Controller/Providers/ArtistInfo.cs b/MediaBrowser.Controller/Providers/ArtistInfo.cs
index 08bf3982b1..adf885baa6 100644
--- a/MediaBrowser.Controller/Providers/ArtistInfo.cs
+++ b/MediaBrowser.Controller/Providers/ArtistInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
namespace MediaBrowser.Controller.Providers
diff --git a/MediaBrowser.Controller/Providers/BookInfo.cs b/MediaBrowser.Controller/Providers/BookInfo.cs
index 03a6737c5f..cce0a25fcb 100644
--- a/MediaBrowser.Controller/Providers/BookInfo.cs
+++ b/MediaBrowser.Controller/Providers/BookInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Providers
{
public class BookInfo : ItemLookupInfo
diff --git a/MediaBrowser.Controller/Providers/BoxSetInfo.cs b/MediaBrowser.Controller/Providers/BoxSetInfo.cs
index d23f2b9bf3..f43ea67178 100644
--- a/MediaBrowser.Controller/Providers/BoxSetInfo.cs
+++ b/MediaBrowser.Controller/Providers/BoxSetInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Providers
{
public class BoxSetInfo : ItemLookupInfo
diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs
index b7640c2050..f77455485a 100644
--- a/MediaBrowser.Controller/Providers/DirectoryService.cs
+++ b/MediaBrowser.Controller/Providers/DirectoryService.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/MediaBrowser.Controller/Providers/DynamicImageResponse.cs b/MediaBrowser.Controller/Providers/DynamicImageResponse.cs
index 7c1371702e..006174be8c 100644
--- a/MediaBrowser.Controller/Providers/DynamicImageResponse.cs
+++ b/MediaBrowser.Controller/Providers/DynamicImageResponse.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.IO;
using MediaBrowser.Model.Drawing;
diff --git a/MediaBrowser.Controller/Providers/EpisodeInfo.cs b/MediaBrowser.Controller/Providers/EpisodeInfo.cs
index 55c41ff82c..a4c8dab7ea 100644
--- a/MediaBrowser.Controller/Providers/EpisodeInfo.cs
+++ b/MediaBrowser.Controller/Providers/EpisodeInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
diff --git a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs
index 6b4c9feb51..32a9cbef2e 100644
--- a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
diff --git a/MediaBrowser.Controller/Providers/IDirectoryService.cs b/MediaBrowser.Controller/Providers/IDirectoryService.cs
index 949a17740b..f06481c7a9 100644
--- a/MediaBrowser.Controller/Providers/IDirectoryService.cs
+++ b/MediaBrowser.Controller/Providers/IDirectoryService.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using MediaBrowser.Model.IO;
diff --git a/MediaBrowser.Controller/Providers/IDynamicImageProvider.cs b/MediaBrowser.Controller/Providers/IDynamicImageProvider.cs
index dec327d665..ab66462fa6 100644
--- a/MediaBrowser.Controller/Providers/IDynamicImageProvider.cs
+++ b/MediaBrowser.Controller/Providers/IDynamicImageProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
diff --git a/MediaBrowser.Controller/Providers/IHasItemChangeMonitor.cs b/MediaBrowser.Controller/Providers/IHasItemChangeMonitor.cs
index 68acb39105..a0e20e312e 100644
--- a/MediaBrowser.Controller/Providers/IHasItemChangeMonitor.cs
+++ b/MediaBrowser.Controller/Providers/IHasItemChangeMonitor.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Providers
diff --git a/MediaBrowser.Controller/Providers/IHasLookupInfo.cs b/MediaBrowser.Controller/Providers/IHasLookupInfo.cs
index 4c0c384423..42cb523713 100644
--- a/MediaBrowser.Controller/Providers/IHasLookupInfo.cs
+++ b/MediaBrowser.Controller/Providers/IHasLookupInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Providers
{
public interface IHasLookupInfo
diff --git a/MediaBrowser.Controller/Providers/IHasOrder.cs b/MediaBrowser.Controller/Providers/IHasOrder.cs
index a3db612256..9fde0e6958 100644
--- a/MediaBrowser.Controller/Providers/IHasOrder.cs
+++ b/MediaBrowser.Controller/Providers/IHasOrder.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Providers
{
public interface IHasOrder
diff --git a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs
index 463c81376d..c129eddb3a 100644
--- a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs
+++ b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
diff --git a/MediaBrowser.Controller/Providers/ILocalMetadataProvider.cs b/MediaBrowser.Controller/Providers/ILocalMetadataProvider.cs
index 44fb1b394f..e771c881df 100644
--- a/MediaBrowser.Controller/Providers/ILocalMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/ILocalMetadataProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
diff --git a/MediaBrowser.Controller/Providers/IMetadataProvider.cs b/MediaBrowser.Controller/Providers/IMetadataProvider.cs
index 62b16dadd7..1a87e0625d 100644
--- a/MediaBrowser.Controller/Providers/IMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/IMetadataProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Providers
diff --git a/MediaBrowser.Controller/Providers/IMetadataService.cs b/MediaBrowser.Controller/Providers/IMetadataService.cs
index 21204e6d31..5f3d4274ef 100644
--- a/MediaBrowser.Controller/Providers/IMetadataService.cs
+++ b/MediaBrowser.Controller/Providers/IMetadataService.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Threading;
using System.Threading.Tasks;
diff --git a/MediaBrowser.Controller/Providers/IPreRefreshProvider.cs b/MediaBrowser.Controller/Providers/IPreRefreshProvider.cs
index 28da27ae77..6d98af33e4 100644
--- a/MediaBrowser.Controller/Providers/IPreRefreshProvider.cs
+++ b/MediaBrowser.Controller/Providers/IPreRefreshProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Providers
{
public interface IPreRefreshProvider : ICustomMetadataProvider
diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs
index c77349d010..e470d77b60 100644
--- a/MediaBrowser.Controller/Providers/IProviderManager.cs
+++ b/MediaBrowser.Controller/Providers/IProviderManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs b/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs
index c143b15cdb..f146decb60 100644
--- a/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
diff --git a/MediaBrowser.Controller/Providers/IRemoteSearchProvider.cs b/MediaBrowser.Controller/Providers/IRemoteSearchProvider.cs
index 17ad9e4a3a..9592baa7c1 100644
--- a/MediaBrowser.Controller/Providers/IRemoteSearchProvider.cs
+++ b/MediaBrowser.Controller/Providers/IRemoteSearchProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
diff --git a/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs b/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs
index 3f8c409f5c..9fc379f045 100644
--- a/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs
+++ b/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Linq;
using MediaBrowser.Model.Entities;
diff --git a/MediaBrowser.Controller/Providers/ItemInfo.cs b/MediaBrowser.Controller/Providers/ItemInfo.cs
index d61153dfa6..b50def043f 100644
--- a/MediaBrowser.Controller/Providers/ItemInfo.cs
+++ b/MediaBrowser.Controller/Providers/ItemInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
diff --git a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs
index 4707b0c7fc..49974c2a37 100644
--- a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs
+++ b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using MediaBrowser.Model.Entities;
diff --git a/MediaBrowser.Controller/Providers/LocalImageInfo.cs b/MediaBrowser.Controller/Providers/LocalImageInfo.cs
index 1842810255..41801862fd 100644
--- a/MediaBrowser.Controller/Providers/LocalImageInfo.cs
+++ b/MediaBrowser.Controller/Providers/LocalImageInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
diff --git a/MediaBrowser.Controller/Providers/MetadataRefreshMode.cs b/MediaBrowser.Controller/Providers/MetadataRefreshMode.cs
index 6d49b55104..920e3da5b0 100644
--- a/MediaBrowser.Controller/Providers/MetadataRefreshMode.cs
+++ b/MediaBrowser.Controller/Providers/MetadataRefreshMode.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Providers
{
public enum MetadataRefreshMode
diff --git a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs
index 0a473b80ca..b92b837012 100644
--- a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs
+++ b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Linq;
using MediaBrowser.Controller.Entities;
diff --git a/MediaBrowser.Controller/Providers/MetadataResult.cs b/MediaBrowser.Controller/Providers/MetadataResult.cs
index 270ea24449..1c695cafa0 100644
--- a/MediaBrowser.Controller/Providers/MetadataResult.cs
+++ b/MediaBrowser.Controller/Providers/MetadataResult.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
diff --git a/MediaBrowser.Controller/Providers/MovieInfo.cs b/MediaBrowser.Controller/Providers/MovieInfo.cs
index 5b2c3ed03b..20e6b697ad 100644
--- a/MediaBrowser.Controller/Providers/MovieInfo.cs
+++ b/MediaBrowser.Controller/Providers/MovieInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Providers
{
public class MovieInfo : ItemLookupInfo
diff --git a/MediaBrowser.Controller/Providers/MusicVideoInfo.cs b/MediaBrowser.Controller/Providers/MusicVideoInfo.cs
index 9835351fc8..0b927f6eb0 100644
--- a/MediaBrowser.Controller/Providers/MusicVideoInfo.cs
+++ b/MediaBrowser.Controller/Providers/MusicVideoInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
namespace MediaBrowser.Controller.Providers
diff --git a/MediaBrowser.Controller/Providers/PersonLookupInfo.cs b/MediaBrowser.Controller/Providers/PersonLookupInfo.cs
index a6218c039a..11cb71f902 100644
--- a/MediaBrowser.Controller/Providers/PersonLookupInfo.cs
+++ b/MediaBrowser.Controller/Providers/PersonLookupInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Providers
{
public class PersonLookupInfo : ItemLookupInfo
diff --git a/MediaBrowser.Controller/Providers/RemoteSearchQuery.cs b/MediaBrowser.Controller/Providers/RemoteSearchQuery.cs
index a2ac6c9ae0..9653bc1c4a 100644
--- a/MediaBrowser.Controller/Providers/RemoteSearchQuery.cs
+++ b/MediaBrowser.Controller/Providers/RemoteSearchQuery.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
namespace MediaBrowser.Controller.Providers
diff --git a/MediaBrowser.Controller/Providers/SeasonInfo.cs b/MediaBrowser.Controller/Providers/SeasonInfo.cs
index dd2ef9ad73..2a4c1f03c7 100644
--- a/MediaBrowser.Controller/Providers/SeasonInfo.cs
+++ b/MediaBrowser.Controller/Providers/SeasonInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
diff --git a/MediaBrowser.Controller/Providers/SeriesInfo.cs b/MediaBrowser.Controller/Providers/SeriesInfo.cs
index 6c206e0314..976fa175ad 100644
--- a/MediaBrowser.Controller/Providers/SeriesInfo.cs
+++ b/MediaBrowser.Controller/Providers/SeriesInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Providers
{
public class SeriesInfo : ItemLookupInfo
diff --git a/MediaBrowser.Controller/Providers/SongInfo.cs b/MediaBrowser.Controller/Providers/SongInfo.cs
index 50615b0bd3..58f76dca91 100644
--- a/MediaBrowser.Controller/Providers/SongInfo.cs
+++ b/MediaBrowser.Controller/Providers/SongInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
diff --git a/MediaBrowser.Controller/Providers/TrailerInfo.cs b/MediaBrowser.Controller/Providers/TrailerInfo.cs
index 13f07562d4..630850f9db 100644
--- a/MediaBrowser.Controller/Providers/TrailerInfo.cs
+++ b/MediaBrowser.Controller/Providers/TrailerInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace MediaBrowser.Controller.Providers
{
public class TrailerInfo : ItemLookupInfo
diff --git a/MediaBrowser.Controller/Resolvers/IItemResolver.cs b/MediaBrowser.Controller/Resolvers/IItemResolver.cs
index a73937b3e3..b99c468435 100644
--- a/MediaBrowser.Controller/Resolvers/IItemResolver.cs
+++ b/MediaBrowser.Controller/Resolvers/IItemResolver.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
diff --git a/MediaBrowser.Controller/Resolvers/ResolverPriority.cs b/MediaBrowser.Controller/Resolvers/ResolverPriority.cs
index 1911e5c1dd..ac73a5ea89 100644
--- a/MediaBrowser.Controller/Resolvers/ResolverPriority.cs
+++ b/MediaBrowser.Controller/Resolvers/ResolverPriority.cs
@@ -9,15 +9,22 @@ namespace MediaBrowser.Controller.Resolvers
/// The first.
///
First = 1,
+
///
/// The second.
///
Second = 2,
+
///
/// The third.
///
Third = 3,
+
+ ///
+ /// The Fourth.
+ ///
Fourth = 4,
+
///
/// The last.
///
diff --git a/MediaBrowser.Controller/Security/AuthenticationInfo.cs b/MediaBrowser.Controller/Security/AuthenticationInfo.cs
index 1d0b959b73..efac9273ec 100644
--- a/MediaBrowser.Controller/Security/AuthenticationInfo.cs
+++ b/MediaBrowser.Controller/Security/AuthenticationInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
namespace MediaBrowser.Controller.Security
diff --git a/MediaBrowser.Controller/Security/AuthenticationInfoQuery.cs b/MediaBrowser.Controller/Security/AuthenticationInfoQuery.cs
index 2bd17eb263..c5f3da0b1b 100644
--- a/MediaBrowser.Controller/Security/AuthenticationInfoQuery.cs
+++ b/MediaBrowser.Controller/Security/AuthenticationInfoQuery.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
namespace MediaBrowser.Controller.Security
diff --git a/MediaBrowser.Controller/Security/IAuthenticationRepository.cs b/MediaBrowser.Controller/Security/IAuthenticationRepository.cs
index 6a9625613d..883b74165c 100644
--- a/MediaBrowser.Controller/Security/IAuthenticationRepository.cs
+++ b/MediaBrowser.Controller/Security/IAuthenticationRepository.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using MediaBrowser.Model.Devices;
using MediaBrowser.Model.Querying;
@@ -29,6 +31,7 @@ namespace MediaBrowser.Controller.Security
void Delete(AuthenticationInfo info);
DeviceOptions GetDeviceOptions(string deviceId);
+
void UpdateDeviceOptions(string deviceId, DeviceOptions options);
}
}
diff --git a/MediaBrowser.Controller/Session/AuthenticationRequest.cs b/MediaBrowser.Controller/Session/AuthenticationRequest.cs
index 685ca3bddc..cc321fd22e 100644
--- a/MediaBrowser.Controller/Session/AuthenticationRequest.cs
+++ b/MediaBrowser.Controller/Session/AuthenticationRequest.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
namespace MediaBrowser.Controller.Session
diff --git a/MediaBrowser.Controller/Session/ISessionController.cs b/MediaBrowser.Controller/Session/ISessionController.cs
index 04450085bf..22d6e2a04e 100644
--- a/MediaBrowser.Controller/Session/ISessionController.cs
+++ b/MediaBrowser.Controller/Session/ISessionController.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Threading;
using System.Threading.Tasks;
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index e54f210506..1a1e200fac 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading;
diff --git a/MediaBrowser.Controller/Session/SessionEventArgs.cs b/MediaBrowser.Controller/Session/SessionEventArgs.cs
index 08baaf6476..097e32eaec 100644
--- a/MediaBrowser.Controller/Session/SessionEventArgs.cs
+++ b/MediaBrowser.Controller/Session/SessionEventArgs.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
namespace MediaBrowser.Controller.Session
diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs
index 4b088998cd..054fd33d9d 100644
--- a/MediaBrowser.Controller/Session/SessionInfo.cs
+++ b/MediaBrowser.Controller/Session/SessionInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Linq;
using System.Text.Json.Serialization;
diff --git a/MediaBrowser.Controller/Sorting/AlphanumComparator.cs b/MediaBrowser.Controller/Sorting/AlphanumComparator.cs
index de7f72d1c2..70cb9eebe0 100644
--- a/MediaBrowser.Controller/Sorting/AlphanumComparator.cs
+++ b/MediaBrowser.Controller/Sorting/AlphanumComparator.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
#nullable enable
using System;
@@ -127,7 +129,7 @@ namespace MediaBrowser.Controller.Sorting
}
///
- public int Compare(string x, string y)
+ public int Compare(string? x, string? y)
{
return CompareValues(x, y);
}
diff --git a/MediaBrowser.Controller/Sorting/SortExtensions.cs b/MediaBrowser.Controller/Sorting/SortExtensions.cs
index 2a68f46789..88467814cd 100644
--- a/MediaBrowser.Controller/Sorting/SortExtensions.cs
+++ b/MediaBrowser.Controller/Sorting/SortExtensions.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -7,6 +9,7 @@ namespace MediaBrowser.Controller.Sorting
public static class SortExtensions
{
private static readonly AlphanumComparator _comparer = new AlphanumComparator();
+
public static IEnumerable OrderByString(this IEnumerable list, Func getName)
{
return list.OrderBy(getName, _comparer);
diff --git a/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs b/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs
index 39538aacd7..f43d523a63 100644
--- a/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs
+++ b/MediaBrowser.Controller/Subtitles/ISubtitleManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Threading;
diff --git a/MediaBrowser.Controller/Subtitles/ISubtitleProvider.cs b/MediaBrowser.Controller/Subtitles/ISubtitleProvider.cs
index 8ffd7c5305..a633262de9 100644
--- a/MediaBrowser.Controller/Subtitles/ISubtitleProvider.cs
+++ b/MediaBrowser.Controller/Subtitles/ISubtitleProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
diff --git a/MediaBrowser.Controller/Subtitles/SubtitleDownloadEventArgs.cs b/MediaBrowser.Controller/Subtitles/SubtitleDownloadEventArgs.cs
index 5703aea17c..b1d74517ea 100644
--- a/MediaBrowser.Controller/Subtitles/SubtitleDownloadEventArgs.cs
+++ b/MediaBrowser.Controller/Subtitles/SubtitleDownloadEventArgs.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using MediaBrowser.Controller.Entities;
diff --git a/MediaBrowser.Controller/Subtitles/SubtitleResponse.cs b/MediaBrowser.Controller/Subtitles/SubtitleResponse.cs
index ad6025927c..a86b057783 100644
--- a/MediaBrowser.Controller/Subtitles/SubtitleResponse.cs
+++ b/MediaBrowser.Controller/Subtitles/SubtitleResponse.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.IO;
namespace MediaBrowser.Controller.Subtitles
diff --git a/MediaBrowser.Controller/Subtitles/SubtitleSearchRequest.cs b/MediaBrowser.Controller/Subtitles/SubtitleSearchRequest.cs
index a202723b99..7d3c20e8f1 100644
--- a/MediaBrowser.Controller/Subtitles/SubtitleSearchRequest.cs
+++ b/MediaBrowser.Controller/Subtitles/SubtitleSearchRequest.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using MediaBrowser.Controller.Providers;
diff --git a/MediaBrowser.Controller/Sync/IHasDynamicAccess.cs b/MediaBrowser.Controller/Sync/IHasDynamicAccess.cs
index d6bac23bec..e7395b136d 100644
--- a/MediaBrowser.Controller/Sync/IHasDynamicAccess.cs
+++ b/MediaBrowser.Controller/Sync/IHasDynamicAccess.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Sync;
diff --git a/MediaBrowser.Controller/Sync/IServerSyncProvider.cs b/MediaBrowser.Controller/Sync/IServerSyncProvider.cs
index 8b2d5d7797..c97fd70442 100644
--- a/MediaBrowser.Controller/Sync/IServerSyncProvider.cs
+++ b/MediaBrowser.Controller/Sync/IServerSyncProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.IO;
using System.Threading;
diff --git a/MediaBrowser.Controller/Sync/ISyncProvider.cs b/MediaBrowser.Controller/Sync/ISyncProvider.cs
index 56f6f37299..950cc73e85 100644
--- a/MediaBrowser.Controller/Sync/ISyncProvider.cs
+++ b/MediaBrowser.Controller/Sync/ISyncProvider.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using MediaBrowser.Model.Sync;
diff --git a/MediaBrowser.Controller/Sync/SyncedFileInfo.cs b/MediaBrowser.Controller/Sync/SyncedFileInfo.cs
index 687a46d78f..a626738fb2 100644
--- a/MediaBrowser.Controller/Sync/SyncedFileInfo.cs
+++ b/MediaBrowser.Controller/Sync/SyncedFileInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using MediaBrowser.Model.MediaInfo;
@@ -5,6 +7,11 @@ namespace MediaBrowser.Controller.Sync
{
public class SyncedFileInfo
{
+ public SyncedFileInfo()
+ {
+ RequiredHttpHeaders = new Dictionary();
+ }
+
///
/// Gets or sets the path.
///
@@ -12,25 +19,23 @@ namespace MediaBrowser.Controller.Sync
public string Path { get; set; }
public string[] PathParts { get; set; }
+
///
/// Gets or sets the protocol.
///
/// The protocol.
public MediaProtocol Protocol { get; set; }
+
///
/// Gets or sets the required HTTP headers.
///
/// The required HTTP headers.
public Dictionary RequiredHttpHeaders { get; set; }
+
///
/// Gets or sets the identifier.
///
/// The identifier.
public string Id { get; set; }
-
- public SyncedFileInfo()
- {
- RequiredHttpHeaders = new Dictionary();
- }
}
}
diff --git a/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs b/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs
index 45c5438061..60d17fe367 100644
--- a/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs
+++ b/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs
@@ -64,4 +64,4 @@ namespace MediaBrowser.Controller.SyncPlay
/// The group info for the clients.
GroupInfoView GetInfo();
}
-}
\ No newline at end of file
+}
diff --git a/MediaBrowser.Controller/TV/ITVSeriesManager.cs b/MediaBrowser.Controller/TV/ITVSeriesManager.cs
index 09a0f6fea9..291dea04ef 100644
--- a/MediaBrowser.Controller/TV/ITVSeriesManager.cs
+++ b/MediaBrowser.Controller/TV/ITVSeriesManager.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Querying;
--
cgit v1.2.3
From 5ec1a979b2bb501edb8836c0170cd10e5dd2d292 Mon Sep 17 00:00:00 2001
From: Bond_009
Date: Sat, 22 Aug 2020 21:57:28 +0200
Subject: Remove extra newline
---
MediaBrowser.Controller/Authentication/AuthenticationResult.cs | 1 -
1 file changed, 1 deletion(-)
(limited to 'MediaBrowser.Controller')
diff --git a/MediaBrowser.Controller/Authentication/AuthenticationResult.cs b/MediaBrowser.Controller/Authentication/AuthenticationResult.cs
index bdebd76ab3..4249a9a667 100644
--- a/MediaBrowser.Controller/Authentication/AuthenticationResult.cs
+++ b/MediaBrowser.Controller/Authentication/AuthenticationResult.cs
@@ -1,6 +1,5 @@
#pragma warning disable CS1591
-
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
--
cgit v1.2.3
From c4d8275fc1ad29823788043750e2f3f8e8b8244e Mon Sep 17 00:00:00 2001
From: Bond_009
Date: Sun, 23 Aug 2020 00:26:32 +0200
Subject: Fix duplicate
---
MediaBrowser.Controller/Entities/Folder.cs | 2 --
1 file changed, 2 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 7687cf12b6..11542c1cad 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -1,7 +1,5 @@
#pragma warning disable CS1591
-#pragma warning disable CS1591
-
using System;
using System.Collections.Generic;
using System.Globalization;
--
cgit v1.2.3
From 71c33d09c4a71ac9fcd390237986dee969109510 Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Mon, 24 Aug 2020 20:34:33 -0400
Subject: Document IEventConsumer
---
MediaBrowser.Controller/Events/IEventConsumer.cs | 9 +++++++++
1 file changed, 9 insertions(+)
(limited to 'MediaBrowser.Controller')
diff --git a/MediaBrowser.Controller/Events/IEventConsumer.cs b/MediaBrowser.Controller/Events/IEventConsumer.cs
index 3cefe2f9c8..5c4ab5d8dd 100644
--- a/MediaBrowser.Controller/Events/IEventConsumer.cs
+++ b/MediaBrowser.Controller/Events/IEventConsumer.cs
@@ -3,9 +3,18 @@ using System.Threading.Tasks;
namespace MediaBrowser.Controller.Events
{
+ ///
+ /// An interface representing a type that consumes events of type T.
+ ///
+ /// The type of events this consumes.
public interface IEventConsumer
where T : EventArgs
{
+ ///
+ /// A method that is called when an event of type T is fired.
+ ///
+ /// The event.
+ /// A task representing the consumption of the event.
Task OnEvent(T eventArgs);
}
}
--
cgit v1.2.3
From 2eb9a3670bc63c06c464c487eb3d7b59de310dfe Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Mon, 24 Aug 2020 20:34:42 -0400
Subject: Document PlaybackStartEventArgs
---
MediaBrowser.Controller/Library/PlaybackStartEventArgs.cs | 3 +++
1 file changed, 3 insertions(+)
(limited to 'MediaBrowser.Controller')
diff --git a/MediaBrowser.Controller/Library/PlaybackStartEventArgs.cs b/MediaBrowser.Controller/Library/PlaybackStartEventArgs.cs
index 3aa9c28954..ac372bceba 100644
--- a/MediaBrowser.Controller/Library/PlaybackStartEventArgs.cs
+++ b/MediaBrowser.Controller/Library/PlaybackStartEventArgs.cs
@@ -1,5 +1,8 @@
namespace MediaBrowser.Controller.Library
{
+ ///
+ /// An event that occurs when playback is started.
+ ///
public class PlaybackStartEventArgs : PlaybackProgressEventArgs
{
}
--
cgit v1.2.3
From b5bbbb9cefb7b360e12b44522d6494bfb4c0f848 Mon Sep 17 00:00:00 2001
From: Patrick Barron
Date: Mon, 24 Aug 2020 20:34:53 -0400
Subject: Document SubtitleDownloadFailureEventArgs
---
.../Subtitles/SubtitleDownloadFailureEventArgs.cs | 12 ++++++++++++
1 file changed, 12 insertions(+)
(limited to 'MediaBrowser.Controller')
diff --git a/MediaBrowser.Controller/Subtitles/SubtitleDownloadFailureEventArgs.cs b/MediaBrowser.Controller/Subtitles/SubtitleDownloadFailureEventArgs.cs
index 7687bf5b6d..ce8141219a 100644
--- a/MediaBrowser.Controller/Subtitles/SubtitleDownloadFailureEventArgs.cs
+++ b/MediaBrowser.Controller/Subtitles/SubtitleDownloadFailureEventArgs.cs
@@ -3,12 +3,24 @@ using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Subtitles
{
+ ///
+ /// An event that occurs when subtitle downloading fails.
+ ///
public class SubtitleDownloadFailureEventArgs : EventArgs
{
+ ///
+ /// Gets or sets the item.
+ ///
public BaseItem Item { get; set; }
+ ///
+ /// Gets or sets the provider.
+ ///
public string Provider { get; set; }
+ ///
+ /// Gets or sets the exception.
+ ///
public Exception Exception { get; set; }
}
}
--
cgit v1.2.3
From 670c41ee8900da32f0936a9a1f45d73e0508432b Mon Sep 17 00:00:00 2001
From: crobibero
Date: Tue, 25 Aug 2020 21:33:19 -0600
Subject: Properly pack project license
---
Emby.Naming/Emby.Naming.csproj | 12 +-
Jellyfin.Data/Jellyfin.Data.csproj | 12 +-
LICENSE | 339 ---------------------
LICENSE.txt | 339 +++++++++++++++++++++
MediaBrowser.Common/MediaBrowser.Common.csproj | 12 +-
.../MediaBrowser.Controller.csproj | 12 +-
MediaBrowser.Model/MediaBrowser.Model.csproj | 12 +-
7 files changed, 394 insertions(+), 344 deletions(-)
delete mode 100644 LICENSE
create mode 100644 LICENSE.txt
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj
index 14aac1a4ab..8108957577 100644
--- a/Emby.Naming/Emby.Naming.csproj
+++ b/Emby.Naming/Emby.Naming.csproj
@@ -24,10 +24,20 @@
Jellyfin Contributors
Jellyfin.Naming
10.7.0
- https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
+
+ LICENSE.txt
+
+
+
+
+ LICENSE.txt
+ true
+
+
+
diff --git a/Jellyfin.Data/Jellyfin.Data.csproj b/Jellyfin.Data/Jellyfin.Data.csproj
index 64a1dc57ac..0b4bbb562d 100644
--- a/Jellyfin.Data/Jellyfin.Data.csproj
+++ b/Jellyfin.Data/Jellyfin.Data.csproj
@@ -11,10 +11,20 @@
Jellyfin Contributors
Jellyfin.Data
10.7.0
- https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
+
+ LICENSE.txt
+
+
+
+
+ LICENSE.txt
+ true
+
+
+
../jellyfin.ruleset
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 4522ba0659..0000000000
--- a/LICENSE
+++ /dev/null
@@ -1,339 +0,0 @@
-GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- {{description}}
- Copyright (C) {{year}} {{fullname}}
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- {signature of Ty Coon}, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000000..4522ba0659
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,339 @@
+GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ {{description}}
+ Copyright (C) {{year}} {{fullname}}
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ {signature of Ty Coon}, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index 04100eba45..3716b66a07 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -9,10 +9,20 @@
Jellyfin Contributors
Jellyfin.Common
10.7.0
- https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
+
+ LICENSE.txt
+
+
+
+
+ LICENSE.txt
+ true
+
+
+
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index c155c66687..1763d240b7 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -9,10 +9,20 @@
Jellyfin Contributors
Jellyfin.Controller
10.7.0
- https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
+
+ LICENSE.txt
+
+
+
+
+ LICENSE.txt
+ true
+
+
+
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 2cb89f77f2..f40b90d895 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -9,10 +9,20 @@
Jellyfin Contributors
Jellyfin.Model
10.7.0
- https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://github.com/jellyfin/jellyfin
+
+ LICENSE.txt
+
+
+
+
+ LICENSE.txt
+ true
+
+
+
netstandard2.0;netstandard2.1
false
--
cgit v1.2.3
From 5f60da29c737cae4ee298f9fbeae971740f8a5ba Mon Sep 17 00:00:00 2001
From: crobibero
Date: Wed, 26 Aug 2020 07:36:57 -0600
Subject: switch to spdx
---
Emby.Naming/Emby.Naming.csproj | 12 +-----------
Jellyfin.Data/Jellyfin.Data.csproj | 12 +-----------
MediaBrowser.Common/MediaBrowser.Common.csproj | 12 +-----------
MediaBrowser.Controller/MediaBrowser.Controller.csproj | 12 +-----------
MediaBrowser.Model/MediaBrowser.Model.csproj | 12 +-----------
5 files changed, 5 insertions(+), 55 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj
index 8108957577..cad5001e1c 100644
--- a/Emby.Naming/Emby.Naming.csproj
+++ b/Emby.Naming/Emby.Naming.csproj
@@ -25,19 +25,9 @@
Jellyfin.Naming
10.7.0
https://github.com/jellyfin/jellyfin
+ GPL-3.0-or-later
-
- LICENSE.txt
-
-
-
-
- LICENSE.txt
- true
-
-
-
diff --git a/Jellyfin.Data/Jellyfin.Data.csproj b/Jellyfin.Data/Jellyfin.Data.csproj
index 0b4bbb562d..18b5bb5221 100644
--- a/Jellyfin.Data/Jellyfin.Data.csproj
+++ b/Jellyfin.Data/Jellyfin.Data.csproj
@@ -12,19 +12,9 @@
Jellyfin.Data
10.7.0
https://github.com/jellyfin/jellyfin
+ GPL-3.0-or-later
-
- LICENSE.txt
-
-
-
-
- LICENSE.txt
- true
-
-
-
../jellyfin.ruleset
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index 3716b66a07..e8ec753495 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -10,19 +10,9 @@
Jellyfin.Common
10.7.0
https://github.com/jellyfin/jellyfin
+ GPL-3.0-or-later
-
- LICENSE.txt
-
-
-
-
- LICENSE.txt
- true
-
-
-
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 1763d240b7..9c86dba245 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -10,19 +10,9 @@
Jellyfin.Controller
10.7.0
https://github.com/jellyfin/jellyfin
+ GPL-3.0-or-later
-
- LICENSE.txt
-
-
-
-
- LICENSE.txt
- true
-
-
-
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index f40b90d895..81cecf2c77 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -10,19 +10,9 @@
Jellyfin.Model
10.7.0
https://github.com/jellyfin/jellyfin
+ GPL-3.0-or-later
-
- LICENSE.txt
-
-
-
-
- LICENSE.txt
- true
-
-
-
netstandard2.0;netstandard2.1
false
--
cgit v1.2.3
From b02650ec2f812500e99c03a80425d548fc5cfc0c Mon Sep 17 00:00:00 2001
From: crobibero
Date: Wed, 26 Aug 2020 07:39:01 -0600
Subject: use proper spdx
---
Emby.Naming/Emby.Naming.csproj | 2 +-
Jellyfin.Data/Jellyfin.Data.csproj | 2 +-
MediaBrowser.Common/MediaBrowser.Common.csproj | 2 +-
MediaBrowser.Controller/MediaBrowser.Controller.csproj | 2 +-
MediaBrowser.Model/MediaBrowser.Model.csproj | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
(limited to 'MediaBrowser.Controller')
diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj
index cad5001e1c..5e2c6e3e36 100644
--- a/Emby.Naming/Emby.Naming.csproj
+++ b/Emby.Naming/Emby.Naming.csproj
@@ -25,7 +25,7 @@
Jellyfin.Naming
10.7.0
https://github.com/jellyfin/jellyfin
- GPL-3.0-or-later
+ GPL-3.0-only
diff --git a/Jellyfin.Data/Jellyfin.Data.csproj b/Jellyfin.Data/Jellyfin.Data.csproj
index 18b5bb5221..e8065419d7 100644
--- a/Jellyfin.Data/Jellyfin.Data.csproj
+++ b/Jellyfin.Data/Jellyfin.Data.csproj
@@ -12,7 +12,7 @@
Jellyfin.Data
10.7.0
https://github.com/jellyfin/jellyfin
- GPL-3.0-or-later
+ GPL-3.0-only
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index e8ec753495..deb674e456 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -10,7 +10,7 @@
Jellyfin.Common
10.7.0
https://github.com/jellyfin/jellyfin
- GPL-3.0-or-later
+ GPL-3.0-only
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 9c86dba245..df92eda38a 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -10,7 +10,7 @@
Jellyfin.Controller
10.7.0
https://github.com/jellyfin/jellyfin
- GPL-3.0-or-later
+ GPL-3.0-only
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 81cecf2c77..b0f99cef2a 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -10,7 +10,7 @@
Jellyfin.Model
10.7.0
https://github.com/jellyfin/jellyfin
- GPL-3.0-or-later
+ GPL-3.0-only
--
cgit v1.2.3