From f055995a1f59e3395e99e8fc9b470d1dfed2914b Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 17 Apr 2020 14:21:15 +0200 Subject: Use System.Buffers in RangeRequestWriter --- .../HttpServer/RangeRequestWriter.cs | 181 ++++++++++----------- 1 file changed, 84 insertions(+), 97 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs index 8b9028f6bc..980c2cd3a8 100644 --- a/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/Emby.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -1,6 +1,7 @@ #pragma warning disable CS1591 using System; +using System.Buffers; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -8,46 +9,17 @@ using System.Net; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Services; -using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; namespace Emby.Server.Implementations.HttpServer { public class RangeRequestWriter : IAsyncStreamWriter, IHttpResult { - /// - /// Gets or sets the source stream. - /// - /// The source stream. - private Stream SourceStream { get; set; } - private string RangeHeader { get; set; } - private bool IsHeadRequest { get; set; } - - private long RangeStart { get; set; } - private long RangeEnd { get; set; } - private long RangeLength { get; set; } - private long TotalContentLength { get; set; } - - public Action OnComplete { get; set; } - private readonly ILogger _logger; - private const int BufferSize = 81920; - /// - /// The _options - /// private readonly Dictionary _options = new Dictionary(); - /// - /// The us culture - /// - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - /// - /// Additional HTTP Headers - /// - /// The headers. - public IDictionary Headers => _options; + private List> _requestedRanges; /// /// Initializes a new instance of the class. @@ -57,8 +29,7 @@ namespace Emby.Server.Implementations.HttpServer /// The source. /// Type of the content. /// if set to true [is head request]. - /// The logger instance. - public RangeRequestWriter(string rangeHeader, long contentLength, Stream source, string contentType, bool isHeadRequest, ILogger logger) + public RangeRequestWriter(string rangeHeader, long contentLength, Stream source, string contentType, bool isHeadRequest) { if (string.IsNullOrEmpty(contentType)) { @@ -68,7 +39,6 @@ namespace Emby.Server.Implementations.HttpServer RangeHeader = rangeHeader; SourceStream = source; IsHeadRequest = isHeadRequest; - this._logger = logger; ContentType = contentType; Headers[HeaderNames.ContentType] = contentType; @@ -79,40 +49,26 @@ namespace Emby.Server.Implementations.HttpServer } /// - /// Sets the range values. + /// Gets or sets the source stream. /// - private void SetRangeValues(long contentLength) - { - var requestedRange = RequestedRanges[0]; - - TotalContentLength = contentLength; - - // If the requested range is "0-", we can optimize by just doing a stream copy - if (!requestedRange.Value.HasValue) - { - RangeEnd = TotalContentLength - 1; - } - else - { - RangeEnd = requestedRange.Value.Value; - } - - RangeStart = requestedRange.Key; - RangeLength = 1 + RangeEnd - RangeStart; + /// The source stream. + private Stream SourceStream { get; set; } + private string RangeHeader { get; set; } + private bool IsHeadRequest { get; set; } - Headers[HeaderNames.ContentLength] = RangeLength.ToString(CultureInfo.InvariantCulture); - Headers[HeaderNames.ContentRange] = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}"; + private long RangeStart { get; set; } + private long RangeEnd { get; set; } + private long RangeLength { get; set; } + private long TotalContentLength { get; set; } - if (RangeStart > 0 && SourceStream.CanSeek) - { - SourceStream.Position = RangeStart; - } - } + public Action OnComplete { get; set; } /// - /// The _requested ranges + /// Additional HTTP Headers /// - private List> _requestedRanges; + /// The headers. + public IDictionary Headers => _options; + /// /// Gets the requested ranges. /// @@ -137,11 +93,12 @@ namespace Emby.Server.Implementations.HttpServer if (!string.IsNullOrEmpty(vals[0])) { - start = long.Parse(vals[0], UsCulture); + start = long.Parse(vals[0], CultureInfo.InvariantCulture); } + if (!string.IsNullOrEmpty(vals[1])) { - end = long.Parse(vals[1], UsCulture); + end = long.Parse(vals[1], CultureInfo.InvariantCulture); } _requestedRanges.Add(new KeyValuePair(start, end)); @@ -152,6 +109,51 @@ namespace Emby.Server.Implementations.HttpServer } } + public string ContentType { get; set; } + + public IRequest RequestContext { get; set; } + + public object Response { get; set; } + + public int Status { get; set; } + + public HttpStatusCode StatusCode + { + get => (HttpStatusCode)Status; + set => Status = (int)value; + } + + /// + /// Sets the range values. + /// + private void SetRangeValues(long contentLength) + { + var requestedRange = RequestedRanges[0]; + + TotalContentLength = contentLength; + + // If the requested range is "0-", we can optimize by just doing a stream copy + if (!requestedRange.Value.HasValue) + { + RangeEnd = TotalContentLength - 1; + } + else + { + RangeEnd = requestedRange.Value.Value; + } + + RangeStart = requestedRange.Key; + RangeLength = 1 + RangeEnd - RangeStart; + + Headers[HeaderNames.ContentLength] = RangeLength.ToString(CultureInfo.InvariantCulture); + Headers[HeaderNames.ContentRange] = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}"; + + if (RangeStart > 0 && SourceStream.CanSeek) + { + SourceStream.Position = RangeStart; + } + } + public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken) { try @@ -167,59 +169,44 @@ namespace Emby.Server.Implementations.HttpServer // If the requested range is "0-", we can optimize by just doing a stream copy if (RangeEnd >= TotalContentLength - 1) { - await source.CopyToAsync(responseStream, BufferSize).ConfigureAwait(false); + await source.CopyToAsync(responseStream, BufferSize, cancellationToken).ConfigureAwait(false); } else { - await CopyToInternalAsync(source, responseStream, RangeLength).ConfigureAwait(false); + await CopyToInternalAsync(source, responseStream, RangeLength, cancellationToken).ConfigureAwait(false); } } } finally { - if (OnComplete != null) - { - OnComplete(); - } + OnComplete?.Invoke(); } } - private static async Task CopyToInternalAsync(Stream source, Stream destination, long copyLength) + private static async Task CopyToInternalAsync(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken) { - var array = new byte[BufferSize]; - int bytesRead; - while ((bytesRead = await source.ReadAsync(array, 0, array.Length).ConfigureAwait(false)) != 0) + var array = ArrayPool.Shared.Rent(BufferSize); + try { - if (bytesRead == 0) + int bytesRead; + while ((bytesRead = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0) { - break; - } + var bytesToCopy = Math.Min(bytesRead, copyLength); - var bytesToCopy = Math.Min(bytesRead, copyLength); + await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToCopy), cancellationToken).ConfigureAwait(false); - await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToCopy)).ConfigureAwait(false); + copyLength -= bytesToCopy; - copyLength -= bytesToCopy; - - if (copyLength <= 0) - { - break; + if (copyLength <= 0) + { + break; + } } } - } - - public string ContentType { get; set; } - - public IRequest RequestContext { get; set; } - - public object Response { get; set; } - - public int Status { get; set; } - - public HttpStatusCode StatusCode - { - get => (HttpStatusCode)Status; - set => Status = (int)value; + finally + { + ArrayPool.Shared.Return(array); + } } } } -- cgit v1.2.3 From 6b959f40ac208094da0a1d41d8c8a42df9a87876 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 17 Apr 2020 20:01:25 +0200 Subject: Fix build --- Emby.Server.Implementations/HttpServer/HttpResultFactory.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs index b42662420b..0d0396bc7b 100644 --- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -565,13 +565,12 @@ namespace Emby.Server.Implementations.HttpServer } catch (NotSupportedException) { - } } if (!string.IsNullOrWhiteSpace(rangeHeader) && totalContentLength.HasValue) { - var hasHeaders = new RangeRequestWriter(rangeHeader, totalContentLength.Value, stream, contentType, isHeadRequest, _logger) + var hasHeaders = new RangeRequestWriter(rangeHeader, totalContentLength.Value, stream, contentType, isHeadRequest) { OnComplete = options.OnComplete }; @@ -608,8 +607,11 @@ namespace Emby.Server.Implementations.HttpServer /// /// Adds the caching responseHeaders. /// - private void AddCachingHeaders(IDictionary responseHeaders, TimeSpan? cacheDuration, - bool noCache, DateTime? lastModifiedDate) + private void AddCachingHeaders( + IDictionary responseHeaders, + TimeSpan? cacheDuration, + bool noCache, + DateTime? lastModifiedDate) { if (noCache) { -- cgit v1.2.3 From 2aaecb8e148aef6cda67797fa4227a8ebcf7e5bb Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 28 Apr 2020 21:45:46 +0100 Subject: Whilst fixing issues with SSDP on devices with multiple interfaces, i came across a design issue in the current code - namely interfaces without a gateway were ignored. Fixing this required the removal of the code that attempted to detect virtual interfaces. Not wanting to remove functionality, but not able to keep the code in place, I implemented a work around solution (see 4 below). Whilst in the area, I also fixed a few minor bugs i encountered (1, 5, 6 below) and stopped SSDP messages from going out on non-LAN interfaces (3) All these changes are related. Changes 1 IsInPrivateAddressSpace - improved subnet code checking 2 interfaces with no gateway were being excluded from SSDP blasts 3 filtered SSDP blasts from not LAN addresses as defined on the network page. 4 removed #986 mod - as this was part of the issue of #2986. Interfaces can be excluded from the LAN by putting the LAN address in brackets. eg. [10.1.1.1] will exclude an interface with ip address 10.1.1.1 from SSDP 5 fixed a problem where an invalid LAN address causing the SSDP to crash 6 corrected local link filter (FilterIPAddress) to filter on 169.254. addresses --- Emby.Dlna/Main/DlnaEntryPoint.cs | 6 + Emby.Server.Implementations/ApplicationHost.cs | 2 +- .../Networking/NetworkManager.cs | 149 ++++++++++++--------- MediaBrowser.Common/Net/INetworkManager.cs | 4 +- RSSDP/SsdpCommunicationsServer.cs | 4 +- RSSDP/SsdpDeviceLocator.cs | 2 +- 6 files changed, 97 insertions(+), 70 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index c5d60b2a05..7213504831 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -266,6 +266,12 @@ namespace Emby.Dlna.Main continue; } + // Limit to LAN addresses only + if (!_networkManager.IsAddressInSubnets(address, true, true)) + { + continue; + } + var fullService = "urn:schemas-upnp-org:device:MediaServer:1"; _logger.LogInformation("Registering publisher for {0} on {1}", fullService, address); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 33aec1a06b..97fc2c0048 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1274,7 +1274,7 @@ namespace Emby.Server.Implementations if (addresses.Count == 0) { - addresses.AddRange(_networkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces)); + addresses.AddRange(_networkManager.GetLocalIpAddresses()); } var resultList = new List(); diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index b3e88b6675..465530888e 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -56,13 +56,13 @@ namespace Emby.Server.Implementations.Networking NetworkChanged?.Invoke(this, EventArgs.Empty); } - public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true) + public IPAddress[] GetLocalIpAddresses() { lock (_localIpAddressSyncLock) { if (_localIpAddresses == null) { - var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).ToArray(); + var addresses = GetLocalIpAddressesInternal().ToArray(); _localIpAddresses = addresses; } @@ -71,35 +71,37 @@ namespace Emby.Server.Implementations.Networking } } - private List GetLocalIpAddressesInternal(bool ignoreVirtualInterface) + private List GetLocalIpAddressesInternal() { - var list = GetIPsDefault(ignoreVirtualInterface).ToList(); + var list = GetIPsDefault().ToList(); if (list.Count == 0) { list = GetLocalIpAddressesFallback().GetAwaiter().GetResult().ToList(); } - var listClone = list.ToList(); + var listClone = new List(); - return list - .OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1) - .ThenBy(i => listClone.IndexOf(i)) - .Where(FilterIpAddress) - .GroupBy(i => i.ToString()) - .Select(x => x.First()) - .ToList(); - } + var subnets = LocalSubnetsFn(); - private static bool FilterIpAddress(IPAddress address) - { - if (address.IsIPv6LinkLocal - || address.ToString().StartsWith("169.", StringComparison.OrdinalIgnoreCase)) + foreach (var i in list) { - return false; + if (i.IsIPv6LinkLocal || i.ToString().StartsWith("169.254.", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + if (Array.IndexOf(subnets, "[" + i.ToString() + "]") == -1) + { + listClone.Add(i); + } } - return true; + return listClone + .OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1) + // .ThenBy(i => listClone.IndexOf(i)) + .GroupBy(i => i.ToString()) + .Select(x => x.First()) + .ToList(); } public bool IsInPrivateAddressSpace(string endpoint) @@ -107,6 +109,7 @@ namespace Emby.Server.Implementations.Networking return IsInPrivateAddressSpace(endpoint, true); } + // checks if the address in endpoint is an RFC1918, RFC1122, or RFC3927 address private bool IsInPrivateAddressSpace(string endpoint, bool checkSubnets) { if (string.Equals(endpoint, "::1", StringComparison.OrdinalIgnoreCase)) @@ -128,23 +131,28 @@ namespace Emby.Server.Implementations.Networking } // Private address space: - // http://en.wikipedia.org/wiki/Private_network - if (endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase)) + if (endpoint.ToLower() == "localhost") { - return Is172AddressPrivate(endpoint); + return true; } - if (endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) || - endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) || - endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase)) + try { - return true; - } + byte[] octet = IPAddress.Parse(endpoint).GetAddressBytes(); - if (checkSubnets && endpoint.StartsWith("192.168", StringComparison.OrdinalIgnoreCase)) + if ((octet[0] == 10) || + (octet[0] == 172 && (octet[1] >= 16 && octet[1] <= 31)) || // RFC1918 + (octet[0] == 192 && octet[1] == 168) || // RFC1918 + (octet[0] == 127) || // RFC1122 + (octet[0] == 169 && octet[1] == 254)) // RFC3927 + { + return false; + } + } + catch { - return true; + // return false; } if (checkSubnets && IsInPrivateAddressSpaceAndLocalSubnet(endpoint)) @@ -177,6 +185,7 @@ namespace Emby.Server.Implementations.Networking return false; } + // Gives a list of possible subnets from the system whose interface ip starts with endpointFirstPart private List GetSubnets(string endpointFirstPart) { lock (_subnetLookupLock) @@ -222,19 +231,6 @@ namespace Emby.Server.Implementations.Networking } } - private static bool Is172AddressPrivate(string endpoint) - { - for (var i = 16; i <= 31; i++) - { - if (endpoint.StartsWith("172." + i.ToString(CultureInfo.InvariantCulture) + ".", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - } - - return false; - } - public bool IsInLocalNetwork(string endpoint) { return IsInLocalNetworkInternal(endpoint, true); @@ -245,23 +241,57 @@ namespace Emby.Server.Implementations.Networking return IsAddressInSubnets(IPAddress.Parse(addressString), addressString, subnets); } + // returns true if address is in the LAN list in the config file + // always returns false if address has been excluded from the LAN if excludeInterfaces is true + // and excludes RFC addresses if excludeRFC is true + public bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC) + { + byte[] octet = address.GetAddressBytes(); + + if ((octet[0] == 127) || // RFC1122 + (octet[0] == 169 && octet[1] == 254)) // RFC3927 + { + // don't use on loopback or 169 interfaces + return false; + } + + string addressString = address.ToString(); + string excludeAddress = "[" + addressString + "]"; + var subnets = LocalSubnetsFn(); + + // Exclude any addresses if they appear in the LAN list in [ ] + if (Array.IndexOf(subnets, excludeAddress) != -1) + { + return false; + } + return IsAddressInSubnets(address, addressString, subnets); + } + + // Checks to see if address/addressString (same but different type) falls within subnets[] private static bool IsAddressInSubnets(IPAddress address, string addressString, string[] subnets) { foreach (var subnet in subnets) { var normalizedSubnet = subnet.Trim(); - + // is the subnet a host address and does it match the address being passes? if (string.Equals(normalizedSubnet, addressString, StringComparison.OrdinalIgnoreCase)) { return true; } - + // parse CIDR subnets and see if address falls within it. if (normalizedSubnet.Contains('/', StringComparison.Ordinal)) { - var ipNetwork = IPNetwork.Parse(normalizedSubnet); - if (ipNetwork.Contains(address)) + try { - return true; + var ipNetwork = IPNetwork.Parse(normalizedSubnet); + if (ipNetwork.Contains(address)) + { + return true; + } + } + catch + { + // Ignoring - invalid subnet passed encountered. } } } @@ -359,8 +389,8 @@ namespace Emby.Server.Implementations.Networking { return Dns.GetHostAddressesAsync(hostName); } - - private IEnumerable GetIPsDefault(bool ignoreVirtualInterface) + + private IEnumerable GetIPsDefault() { IEnumerable interfaces; @@ -380,15 +410,7 @@ namespace Emby.Server.Implementations.Networking { var ipProperties = network.GetIPProperties(); - // Try to exclude virtual adapters - // http://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms - var addr = ipProperties.GatewayAddresses.FirstOrDefault(); - if (addr == null - || (ignoreVirtualInterface - && (addr.Address.Equals(IPAddress.Any) || addr.Address.Equals(IPAddress.IPv6Any)))) - { - return Enumerable.Empty(); - } + // Exclude any addresses if they appear in the LAN list in [ ] return ipProperties.UnicastAddresses .Select(i => i.Address) @@ -494,15 +516,12 @@ namespace Emby.Server.Implementations.Networking foreach (NetworkInterface ni in interfaces) { - if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null) + foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) { - foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) + if (ip.Address.Equals(address) && ip.IPv4Mask != null) { - if (ip.Address.Equals(address) && ip.IPv4Mask != null) - { - return ip.IPv4Mask; - } - } + return ip.IPv4Mask; + } } } diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 3ba75abd85..b7ec1d122c 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -41,10 +41,12 @@ namespace MediaBrowser.Common.Net /// true if [is in local network] [the specified endpoint]; otherwise, false. bool IsInLocalNetwork(string endpoint); - IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface); + IPAddress[] GetLocalIpAddresses(); bool IsAddressInSubnets(string addressString, string[] subnets); + bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC); + bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask); IPAddress GetLocalIpSubnetMask(IPAddress address); diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 18097ef241..47da520056 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -370,13 +370,13 @@ namespace Rssdp.Infrastructure if (_enableMultiSocketBinding) { - foreach (var address in _networkManager.GetLocalIpAddresses(_config.Configuration.IgnoreVirtualInterfaces)) + foreach (var address in _networkManager.GetLocalIpAddresses()) { if (address.AddressFamily == AddressFamily.InterNetworkV6) { // Not support IPv6 right now continue; - } + } try { diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs index 59a2710d58..b62c50e28d 100644 --- a/RSSDP/SsdpDeviceLocator.cs +++ b/RSSDP/SsdpDeviceLocator.cs @@ -357,7 +357,7 @@ namespace Rssdp.Infrastructure private void ProcessSearchResponseMessage(HttpResponseMessage message, IPAddress localIpAddress) { if (!message.IsSuccessStatusCode) return; - + var location = GetFirstHeaderUriValue("Location", message); if (location != null) { -- cgit v1.2.3 From a3140f83c6461164658303d1bb7c1d992cfd9802 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 28 Apr 2020 21:51:49 +0100 Subject: Revert "Whilst fixing issues with SSDP on devices with multiple interfaces, i came across a design issue in the current code - namely interfaces without a gateway were ignored." This reverts commit 2aaecb8e148aef6cda67797fa4227a8ebcf7e5bb. --- Emby.Dlna/Main/DlnaEntryPoint.cs | 6 - Emby.Server.Implementations/ApplicationHost.cs | 2 +- .../Networking/NetworkManager.cs | 149 +++++++++------------ MediaBrowser.Common/Net/INetworkManager.cs | 4 +- RSSDP/SsdpCommunicationsServer.cs | 4 +- RSSDP/SsdpDeviceLocator.cs | 2 +- 6 files changed, 70 insertions(+), 97 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 7213504831..c5d60b2a05 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -266,12 +266,6 @@ namespace Emby.Dlna.Main continue; } - // Limit to LAN addresses only - if (!_networkManager.IsAddressInSubnets(address, true, true)) - { - continue; - } - var fullService = "urn:schemas-upnp-org:device:MediaServer:1"; _logger.LogInformation("Registering publisher for {0} on {1}", fullService, address); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 97fc2c0048..33aec1a06b 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1274,7 +1274,7 @@ namespace Emby.Server.Implementations if (addresses.Count == 0) { - addresses.AddRange(_networkManager.GetLocalIpAddresses()); + addresses.AddRange(_networkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces)); } var resultList = new List(); diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 465530888e..b3e88b6675 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -56,13 +56,13 @@ namespace Emby.Server.Implementations.Networking NetworkChanged?.Invoke(this, EventArgs.Empty); } - public IPAddress[] GetLocalIpAddresses() + public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true) { lock (_localIpAddressSyncLock) { if (_localIpAddresses == null) { - var addresses = GetLocalIpAddressesInternal().ToArray(); + var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).ToArray(); _localIpAddresses = addresses; } @@ -71,45 +71,42 @@ namespace Emby.Server.Implementations.Networking } } - private List GetLocalIpAddressesInternal() + private List GetLocalIpAddressesInternal(bool ignoreVirtualInterface) { - var list = GetIPsDefault().ToList(); + var list = GetIPsDefault(ignoreVirtualInterface).ToList(); if (list.Count == 0) { list = GetLocalIpAddressesFallback().GetAwaiter().GetResult().ToList(); } - var listClone = new List(); + var listClone = list.ToList(); - var subnets = LocalSubnetsFn(); - - foreach (var i in list) - { - if (i.IsIPv6LinkLocal || i.ToString().StartsWith("169.254.", StringComparison.OrdinalIgnoreCase)) - { - continue; - } - if (Array.IndexOf(subnets, "[" + i.ToString() + "]") == -1) - { - listClone.Add(i); - } - } - - return listClone + return list .OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1) - // .ThenBy(i => listClone.IndexOf(i)) + .ThenBy(i => listClone.IndexOf(i)) + .Where(FilterIpAddress) .GroupBy(i => i.ToString()) .Select(x => x.First()) .ToList(); } + private static bool FilterIpAddress(IPAddress address) + { + if (address.IsIPv6LinkLocal + || address.ToString().StartsWith("169.", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + return true; + } + public bool IsInPrivateAddressSpace(string endpoint) { return IsInPrivateAddressSpace(endpoint, true); } - // checks if the address in endpoint is an RFC1918, RFC1122, or RFC3927 address private bool IsInPrivateAddressSpace(string endpoint, bool checkSubnets) { if (string.Equals(endpoint, "::1", StringComparison.OrdinalIgnoreCase)) @@ -131,28 +128,23 @@ namespace Emby.Server.Implementations.Networking } // Private address space: + // http://en.wikipedia.org/wiki/Private_network - if (endpoint.ToLower() == "localhost") + if (endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase)) { - return true; + return Is172AddressPrivate(endpoint); } - try + if (endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) || + endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) || + endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase)) { - byte[] octet = IPAddress.Parse(endpoint).GetAddressBytes(); - - if ((octet[0] == 10) || - (octet[0] == 172 && (octet[1] >= 16 && octet[1] <= 31)) || // RFC1918 - (octet[0] == 192 && octet[1] == 168) || // RFC1918 - (octet[0] == 127) || // RFC1122 - (octet[0] == 169 && octet[1] == 254)) // RFC3927 - { - return false; - } + return true; } - catch + + if (checkSubnets && endpoint.StartsWith("192.168", StringComparison.OrdinalIgnoreCase)) { - // return false; + return true; } if (checkSubnets && IsInPrivateAddressSpaceAndLocalSubnet(endpoint)) @@ -185,7 +177,6 @@ namespace Emby.Server.Implementations.Networking return false; } - // Gives a list of possible subnets from the system whose interface ip starts with endpointFirstPart private List GetSubnets(string endpointFirstPart) { lock (_subnetLookupLock) @@ -231,6 +222,19 @@ namespace Emby.Server.Implementations.Networking } } + private static bool Is172AddressPrivate(string endpoint) + { + for (var i = 16; i <= 31; i++) + { + if (endpoint.StartsWith("172." + i.ToString(CultureInfo.InvariantCulture) + ".", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } + public bool IsInLocalNetwork(string endpoint) { return IsInLocalNetworkInternal(endpoint, true); @@ -241,57 +245,23 @@ namespace Emby.Server.Implementations.Networking return IsAddressInSubnets(IPAddress.Parse(addressString), addressString, subnets); } - // returns true if address is in the LAN list in the config file - // always returns false if address has been excluded from the LAN if excludeInterfaces is true - // and excludes RFC addresses if excludeRFC is true - public bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC) - { - byte[] octet = address.GetAddressBytes(); - - if ((octet[0] == 127) || // RFC1122 - (octet[0] == 169 && octet[1] == 254)) // RFC3927 - { - // don't use on loopback or 169 interfaces - return false; - } - - string addressString = address.ToString(); - string excludeAddress = "[" + addressString + "]"; - var subnets = LocalSubnetsFn(); - - // Exclude any addresses if they appear in the LAN list in [ ] - if (Array.IndexOf(subnets, excludeAddress) != -1) - { - return false; - } - return IsAddressInSubnets(address, addressString, subnets); - } - - // Checks to see if address/addressString (same but different type) falls within subnets[] private static bool IsAddressInSubnets(IPAddress address, string addressString, string[] subnets) { foreach (var subnet in subnets) { var normalizedSubnet = subnet.Trim(); - // is the subnet a host address and does it match the address being passes? + if (string.Equals(normalizedSubnet, addressString, StringComparison.OrdinalIgnoreCase)) { return true; } - // parse CIDR subnets and see if address falls within it. + if (normalizedSubnet.Contains('/', StringComparison.Ordinal)) { - try - { - var ipNetwork = IPNetwork.Parse(normalizedSubnet); - if (ipNetwork.Contains(address)) - { - return true; - } - } - catch + var ipNetwork = IPNetwork.Parse(normalizedSubnet); + if (ipNetwork.Contains(address)) { - // Ignoring - invalid subnet passed encountered. + return true; } } } @@ -389,8 +359,8 @@ namespace Emby.Server.Implementations.Networking { return Dns.GetHostAddressesAsync(hostName); } - - private IEnumerable GetIPsDefault() + + private IEnumerable GetIPsDefault(bool ignoreVirtualInterface) { IEnumerable interfaces; @@ -410,7 +380,15 @@ namespace Emby.Server.Implementations.Networking { var ipProperties = network.GetIPProperties(); - // Exclude any addresses if they appear in the LAN list in [ ] + // Try to exclude virtual adapters + // http://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms + var addr = ipProperties.GatewayAddresses.FirstOrDefault(); + if (addr == null + || (ignoreVirtualInterface + && (addr.Address.Equals(IPAddress.Any) || addr.Address.Equals(IPAddress.IPv6Any)))) + { + return Enumerable.Empty(); + } return ipProperties.UnicastAddresses .Select(i => i.Address) @@ -516,12 +494,15 @@ namespace Emby.Server.Implementations.Networking foreach (NetworkInterface ni in interfaces) { - foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) + if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null) { - if (ip.Address.Equals(address) && ip.IPv4Mask != null) + foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) { - return ip.IPv4Mask; - } + if (ip.Address.Equals(address) && ip.IPv4Mask != null) + { + return ip.IPv4Mask; + } + } } } diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index b7ec1d122c..3ba75abd85 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -41,12 +41,10 @@ namespace MediaBrowser.Common.Net /// true if [is in local network] [the specified endpoint]; otherwise, false. bool IsInLocalNetwork(string endpoint); - IPAddress[] GetLocalIpAddresses(); + IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface); bool IsAddressInSubnets(string addressString, string[] subnets); - bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC); - bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask); IPAddress GetLocalIpSubnetMask(IPAddress address); diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 47da520056..18097ef241 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -370,13 +370,13 @@ namespace Rssdp.Infrastructure if (_enableMultiSocketBinding) { - foreach (var address in _networkManager.GetLocalIpAddresses()) + foreach (var address in _networkManager.GetLocalIpAddresses(_config.Configuration.IgnoreVirtualInterfaces)) { if (address.AddressFamily == AddressFamily.InterNetworkV6) { // Not support IPv6 right now continue; - } + } try { diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs index b62c50e28d..59a2710d58 100644 --- a/RSSDP/SsdpDeviceLocator.cs +++ b/RSSDP/SsdpDeviceLocator.cs @@ -357,7 +357,7 @@ namespace Rssdp.Infrastructure private void ProcessSearchResponseMessage(HttpResponseMessage message, IPAddress localIpAddress) { if (!message.IsSuccessStatusCode) return; - + var location = GetFirstHeaderUriValue("Location", message); if (location != null) { -- cgit v1.2.3 From ebd589aa86abb7bdbc9ab981cb8f4c908f790ac1 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 28 Apr 2020 21:57:39 +0100 Subject: Whilst fixing issues with SSDP on devices with multiple interfaces, i came across a design issue in the current code - namely interfaces without a gateway were ignored. Fixing this required the removal of the code that attempted to detect virtual interfaces. Not wanting to remove functionality, but not able to keep the code in place, I implemented a work around solution (see 4 below). Whilst in the area, I also fixed a few minor bugs i encountered (1, 5, 6 below) and stopped SSDP messages from going out on non-LAN interfaces (3) All these changes are related. Changes 1 IsInPrivateAddressSpace - improved subnet code checking 2 interfaces with no gateway were being excluded from SSDP blasts 3 filtered SSDP blasts from not LAN addresses as defined on the network page. 4 removed #986 mod - as this was part of the issue of #2986. Interfaces can be excluded from the LAN by putting the LAN address in brackets. eg. [10.1.1.1] will exclude an interface with ip address 10.1.1.1 from SSDP 5 fixed a problem where an invalid LAN address causing the SSDP to crash 6 corrected local link filter (FilterIPAddress) to filter on 169.254. addresses --- Emby.Dlna/Main/DlnaEntryPoint.cs | 8 +- Emby.Server.Implementations/ApplicationHost.cs | 2 +- .../Networking/NetworkManager.cs | 150 ++++++++++++--------- MediaBrowser.Common/Net/INetworkManager.cs | 4 +- RSSDP/SsdpCommunicationsServer.cs | 11 +- RSSDP/SsdpDeviceLocator.cs | 2 +- 6 files changed, 101 insertions(+), 76 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index c5d60b2a05..e6806c87bb 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -180,7 +180,7 @@ namespace Emby.Dlna.Main var enableMultiSocketBinding = OperatingSystem.Id == OperatingSystemId.Windows || OperatingSystem.Id == OperatingSystemId.Linux; - _communicationsServer = new SsdpCommunicationsServer(_config, _socketFactory, _networkManager, _logger, enableMultiSocketBinding) + _communicationsServer = new SsdpCommunicationsServer(_socketFactory, _networkManager, _logger, enableMultiSocketBinding) { IsShared = true }; @@ -266,6 +266,12 @@ namespace Emby.Dlna.Main continue; } + // Limit to LAN addresses only + if (!_networkManager.IsAddressInSubnets(address, true, true)) + { + continue; + } + var fullService = "urn:schemas-upnp-org:device:MediaServer:1"; _logger.LogInformation("Registering publisher for {0} on {1}", fullService, address); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 33aec1a06b..97fc2c0048 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1274,7 +1274,7 @@ namespace Emby.Server.Implementations if (addresses.Count == 0) { - addresses.AddRange(_networkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces)); + addresses.AddRange(_networkManager.GetLocalIpAddresses()); } var resultList = new List(); diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index b3e88b6675..5979d1eae7 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Net; using System.Net.NetworkInformation; @@ -56,13 +55,13 @@ namespace Emby.Server.Implementations.Networking NetworkChanged?.Invoke(this, EventArgs.Empty); } - public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true) + public IPAddress[] GetLocalIpAddresses() { lock (_localIpAddressSyncLock) { if (_localIpAddresses == null) { - var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).ToArray(); + var addresses = GetLocalIpAddressesInternal().ToArray(); _localIpAddresses = addresses; } @@ -71,35 +70,37 @@ namespace Emby.Server.Implementations.Networking } } - private List GetLocalIpAddressesInternal(bool ignoreVirtualInterface) + private List GetLocalIpAddressesInternal() { - var list = GetIPsDefault(ignoreVirtualInterface).ToList(); + var list = GetIPsDefault().ToList(); if (list.Count == 0) { list = GetLocalIpAddressesFallback().GetAwaiter().GetResult().ToList(); } - var listClone = list.ToList(); + var listClone = new List(); - return list - .OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1) - .ThenBy(i => listClone.IndexOf(i)) - .Where(FilterIpAddress) - .GroupBy(i => i.ToString()) - .Select(x => x.First()) - .ToList(); - } + var subnets = LocalSubnetsFn(); - private static bool FilterIpAddress(IPAddress address) - { - if (address.IsIPv6LinkLocal - || address.ToString().StartsWith("169.", StringComparison.OrdinalIgnoreCase)) + foreach (var i in list) { - return false; + if (i.IsIPv6LinkLocal || i.ToString().StartsWith("169.254.", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + if (Array.IndexOf(subnets, "[" + i.ToString() + "]") == -1) + { + listClone.Add(i); + } } - return true; + return listClone + .OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1) + // .ThenBy(i => listClone.IndexOf(i)) + .GroupBy(i => i.ToString()) + .Select(x => x.First()) + .ToList(); } public bool IsInPrivateAddressSpace(string endpoint) @@ -107,6 +108,7 @@ namespace Emby.Server.Implementations.Networking return IsInPrivateAddressSpace(endpoint, true); } + // checks if the address in endpoint is an RFC1918, RFC1122, or RFC3927 address private bool IsInPrivateAddressSpace(string endpoint, bool checkSubnets) { if (string.Equals(endpoint, "::1", StringComparison.OrdinalIgnoreCase)) @@ -128,23 +130,28 @@ namespace Emby.Server.Implementations.Networking } // Private address space: - // http://en.wikipedia.org/wiki/Private_network - if (endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase)) + if (endpoint.ToLower() == "localhost") { - return Is172AddressPrivate(endpoint); + return true; } - if (endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) || - endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) || - endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase)) + try { - return true; - } + byte[] octet = IPAddress.Parse(endpoint).GetAddressBytes(); - if (checkSubnets && endpoint.StartsWith("192.168", StringComparison.OrdinalIgnoreCase)) + if ((octet[0] == 10) || + (octet[0] == 172 && (octet[1] >= 16 && octet[1] <= 31)) || // RFC1918 + (octet[0] == 192 && octet[1] == 168) || // RFC1918 + (octet[0] == 127) || // RFC1122 + (octet[0] == 169 && octet[1] == 254)) // RFC3927 + { + return false; + } + } + catch { - return true; + } if (checkSubnets && IsInPrivateAddressSpaceAndLocalSubnet(endpoint)) @@ -177,6 +184,7 @@ namespace Emby.Server.Implementations.Networking return false; } + // Gives a list of possible subnets from the system whose interface ip starts with endpointFirstPart private List GetSubnets(string endpointFirstPart) { lock (_subnetLookupLock) @@ -222,19 +230,6 @@ namespace Emby.Server.Implementations.Networking } } - private static bool Is172AddressPrivate(string endpoint) - { - for (var i = 16; i <= 31; i++) - { - if (endpoint.StartsWith("172." + i.ToString(CultureInfo.InvariantCulture) + ".", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - } - - return false; - } - public bool IsInLocalNetwork(string endpoint) { return IsInLocalNetworkInternal(endpoint, true); @@ -245,23 +240,57 @@ namespace Emby.Server.Implementations.Networking return IsAddressInSubnets(IPAddress.Parse(addressString), addressString, subnets); } + // returns true if address is in the LAN list in the config file + // always returns false if address has been excluded from the LAN if excludeInterfaces is true + // and excludes RFC addresses if excludeRFC is true + public bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC) + { + byte[] octet = address.GetAddressBytes(); + + if ((octet[0] == 127) || // RFC1122 + (octet[0] == 169 && octet[1] == 254)) // RFC3927 + { + // don't use on loopback or 169 interfaces + return false; + } + + string addressString = address.ToString(); + string excludeAddress = "[" + addressString + "]"; + var subnets = LocalSubnetsFn(); + + // Exclude any addresses if they appear in the LAN list in [ ] + if (Array.IndexOf(subnets, excludeAddress) != -1) + { + return false; + } + return IsAddressInSubnets(address, addressString, subnets); + } + + // Checks to see if address/addressString (same but different type) falls within subnets[] private static bool IsAddressInSubnets(IPAddress address, string addressString, string[] subnets) { foreach (var subnet in subnets) { var normalizedSubnet = subnet.Trim(); - + // is the subnet a host address and does it match the address being passes? if (string.Equals(normalizedSubnet, addressString, StringComparison.OrdinalIgnoreCase)) { return true; } - + // parse CIDR subnets and see if address falls within it. if (normalizedSubnet.Contains('/', StringComparison.Ordinal)) { - var ipNetwork = IPNetwork.Parse(normalizedSubnet); - if (ipNetwork.Contains(address)) + try { - return true; + var ipNetwork = IPNetwork.Parse(normalizedSubnet); + if (ipNetwork.Contains(address)) + { + return true; + } + } + catch + { + // Ignoring - invalid subnet passed encountered. } } } @@ -359,8 +388,8 @@ namespace Emby.Server.Implementations.Networking { return Dns.GetHostAddressesAsync(hostName); } - - private IEnumerable GetIPsDefault(bool ignoreVirtualInterface) + + private IEnumerable GetIPsDefault() { IEnumerable interfaces; @@ -380,15 +409,7 @@ namespace Emby.Server.Implementations.Networking { var ipProperties = network.GetIPProperties(); - // Try to exclude virtual adapters - // http://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms - var addr = ipProperties.GatewayAddresses.FirstOrDefault(); - if (addr == null - || (ignoreVirtualInterface - && (addr.Address.Equals(IPAddress.Any) || addr.Address.Equals(IPAddress.IPv6Any)))) - { - return Enumerable.Empty(); - } + // Exclude any addresses if they appear in the LAN list in [ ] return ipProperties.UnicastAddresses .Select(i => i.Address) @@ -494,15 +515,12 @@ namespace Emby.Server.Implementations.Networking foreach (NetworkInterface ni in interfaces) { - if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null) + foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) { - foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) + if (ip.Address.Equals(address) && ip.IPv4Mask != null) { - if (ip.Address.Equals(address) && ip.IPv4Mask != null) - { - return ip.IPv4Mask; - } - } + return ip.IPv4Mask; + } } } diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 3ba75abd85..b7ec1d122c 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -41,10 +41,12 @@ namespace MediaBrowser.Common.Net /// true if [is in local network] [the specified endpoint]; otherwise, false. bool IsInLocalNetwork(string endpoint); - IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface); + IPAddress[] GetLocalIpAddresses(); bool IsAddressInSubnets(string addressString, string[] subnets); + bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC); + bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask); IPAddress GetLocalIpSubnetMask(IPAddress address); diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 18097ef241..a16e4c73f9 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -46,8 +46,7 @@ namespace Rssdp.Infrastructure private HttpResponseParser _ResponseParser; private readonly ILogger _logger; private ISocketFactory _SocketFactory; - private readonly INetworkManager _networkManager; - private readonly IServerConfigurationManager _config; + private readonly INetworkManager _networkManager; private int _LocalPort; private int _MulticastTtl; @@ -77,11 +76,11 @@ namespace Rssdp.Infrastructure /// Minimum constructor. /// /// The argument is null. - public SsdpCommunicationsServer(IServerConfigurationManager config, ISocketFactory socketFactory, + public SsdpCommunicationsServer(ISocketFactory socketFactory, INetworkManager networkManager, ILogger logger, bool enableMultiSocketBinding) : this(socketFactory, 0, SsdpConstants.SsdpDefaultMulticastTimeToLive, networkManager, logger, enableMultiSocketBinding) { - _config = config; + } /// @@ -370,13 +369,13 @@ namespace Rssdp.Infrastructure if (_enableMultiSocketBinding) { - foreach (var address in _networkManager.GetLocalIpAddresses(_config.Configuration.IgnoreVirtualInterfaces)) + foreach (var address in _networkManager.GetLocalIpAddresses()) { if (address.AddressFamily == AddressFamily.InterNetworkV6) { // Not support IPv6 right now continue; - } + } try { diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs index 59a2710d58..b62c50e28d 100644 --- a/RSSDP/SsdpDeviceLocator.cs +++ b/RSSDP/SsdpDeviceLocator.cs @@ -357,7 +357,7 @@ namespace Rssdp.Infrastructure private void ProcessSearchResponseMessage(HttpResponseMessage message, IPAddress localIpAddress) { if (!message.IsSuccessStatusCode) return; - + var location = GetFirstHeaderUriValue("Location", message); if (location != null) { -- cgit v1.2.3 From 3a5333228fc28c511c7a2d44ea0bc036c0474ccf Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sun, 17 May 2020 20:44:44 +0100 Subject: Update Emby.Server.Implementations/Networking/NetworkManager.cs Co-authored-by: Patrick Barron <18354464+barronpm@users.noreply.github.com> --- Emby.Server.Implementations/Networking/NetworkManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index b14b845418..f2cbdbaa59 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -200,7 +200,7 @@ namespace Emby.Server.Implementations.Networking } /// - /// Checks if the give address false within the ranges givin in [subnets]. The addresses in subnets can be hosts or subnets in the CIDR format. + /// Checks if the give address falls within the ranges given in [subnets]. The addresses in subnets can be hosts or subnets in the CIDR format. /// /// IPAddress version of the address. /// The address to check. -- cgit v1.2.3 From 36312c92f56671484caaeaf89e28f7737723e97d Mon Sep 17 00:00:00 2001 From: Ken Brazier Date: Sun, 31 May 2020 16:40:02 -0600 Subject: 2354 open soft-links to read size --- Emby.Server.Implementations/IO/ManagedFileSystem.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 7461ec4f1d..8b75e8c708 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -245,6 +245,16 @@ namespace Emby.Server.Implementations.IO if (info is FileInfo fileInfo) { result.Length = fileInfo.Length; + + // Issue #2354 get the size of files behind symbolic links + if(fileInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)) + { + using (Stream thisFileStream = File.OpenRead(fileInfo.ToString())) + { + result.Length = thisFileStream.Length; + } + } + result.DirectoryName = fileInfo.DirectoryName; } -- cgit v1.2.3 From 455e46444510bae9aeac544e9cd28735a40ce856 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 1 Jun 2020 09:57:17 +0100 Subject: Update Emby.Server.Implementations/Networking/NetworkManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Networking/NetworkManager.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index f2cbdbaa59..35041569d0 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -114,11 +114,9 @@ namespace Emby.Server.Implementations.Networking public int GetRandomUnusedUdpPort() { var localEndPoint = new IPEndPoint(IPAddress.Any, 0); - var udpClient = new UdpClient(localEndPoint); - using (udpClient) + using (var udpClient = new UdpClient(localEndPoint)) { - var port = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - return port; + return ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; } } -- cgit v1.2.3 From fbd02a493b3284f50a70380db866be02f5226c4e Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 1 Jun 2020 09:57:48 +0100 Subject: Update Emby.Server.Implementations/Networking/NetworkManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Networking/NetworkManager.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 35041569d0..4b0c315c09 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -123,12 +123,7 @@ namespace Emby.Server.Implementations.Networking /// public List GetMacAddresses() { - if (_macAddresses == null) - { - _macAddresses = GetMacAddressesInternal().ToList(); - } - - return _macAddresses; + return _macAddresses ??= GetMacAddressesInternal().ToList(); } /// -- cgit v1.2.3 From adb789a802438f756492326b0c036bc77d70cea1 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 1 Jun 2020 09:58:16 +0100 Subject: Update Emby.Server.Implementations/Networking/NetworkManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Networking/NetworkManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 4b0c315c09..6552cd8ecc 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -251,7 +251,7 @@ namespace Emby.Server.Implementations.Networking => NetworkInterface.GetAllNetworkInterfaces() .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback) .Select(x => x.GetPhysicalAddress()) - .Where(x => x != null && x != PhysicalAddress.None); + .Where(x => !x.Equals(PhysicalAddress.None)); private void OnNetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) { -- cgit v1.2.3 From 1d86084653c1f437da04edd82a627ed02480375b Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 1 Jun 2020 10:14:38 +0100 Subject: Update Emby.Server.Implementations/Networking/NetworkManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Networking/NetworkManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 6552cd8ecc..caa3d964a3 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -296,7 +296,7 @@ namespace Emby.Server.Implementations.Networking continue; } - if (Array.IndexOf(subnets, "[" + i.ToString() + "]") == -1) + if (Array.IndexOf(subnets, $"[{i}]") == -1) { listClone.Add(i); } -- cgit v1.2.3 From b7f4b8e2b5a61e3784b3e5dc68c1123bddbff264 Mon Sep 17 00:00:00 2001 From: dkanada Date: Thu, 4 Jun 2020 23:57:57 +0900 Subject: initial implementation for custom plugin repositories --- .../ConfigurationOptions.cs | 1 - Emby.Server.Implementations/IStartupOptions.cs | 5 --- .../Updates/InstallationManager.cs | 39 ++++++++++++---------- Jellyfin.Server/StartupOptions.cs | 9 ----- MediaBrowser.Api/Devices/DeviceService.cs | 1 - MediaBrowser.Api/PackageService.cs | 25 ++++++++++++++ .../Updates/IInstallationManager.cs | 8 +++++ .../Configuration/ServerConfiguration.cs | 18 ++++++++++ MediaBrowser.Model/Updates/RepositoryInfo.cs | 34 +++++++++++++++++++ 9 files changed, 106 insertions(+), 34 deletions(-) create mode 100644 MediaBrowser.Model/Updates/RepositoryInfo.cs (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs index dea9b6682a..ff7ee085f8 100644 --- a/Emby.Server.Implementations/ConfigurationOptions.cs +++ b/Emby.Server.Implementations/ConfigurationOptions.cs @@ -17,7 +17,6 @@ namespace Emby.Server.Implementations { { HostWebClientKey, bool.TrueString }, { HttpListenerHost.DefaultRedirectKey, "web/index.html" }, - { InstallationManager.PluginManifestUrlKey, "https://repo.jellyfin.org/releases/plugin/manifest-stable.json" }, { FfmpegProbeSizeKey, "1G" }, { FfmpegAnalyzeDurationKey, "200M" }, { PlaylistsAllowDuplicatesKey, bool.TrueString } diff --git a/Emby.Server.Implementations/IStartupOptions.cs b/Emby.Server.Implementations/IStartupOptions.cs index 0b9f805389..e7e72c686b 100644 --- a/Emby.Server.Implementations/IStartupOptions.cs +++ b/Emby.Server.Implementations/IStartupOptions.cs @@ -36,11 +36,6 @@ namespace Emby.Server.Implementations /// string RestartArgs { get; } - /// - /// Gets the value of the --plugin-manifest-url command line option. - /// - string PluginManifestUrl { get; } - /// /// Gets the value of the --published-server-url command line option. /// diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 178f32c313..bdd7c31d69 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -31,11 +31,6 @@ namespace Emby.Server.Implementations.Updates /// public class InstallationManager : IInstallationManager { - /// - /// The key for a setting that specifies a URL for the plugin repository JSON manifest. - /// - public const string PluginManifestUrlKey = "InstallationManager:PluginManifestUrl"; - /// /// The logger. /// @@ -122,16 +117,14 @@ namespace Emby.Server.Implementations.Updates public IEnumerable CompletedInstallations => _completedInstallationsInternal; /// - public async Task> GetAvailablePackages(CancellationToken cancellationToken = default) + public async Task> GetPackages(string manifest, CancellationToken cancellationToken = default) { - var manifestUrl = _appConfig.GetValue(PluginManifestUrlKey); - try { using (var response = await _httpClient.SendAsync( new HttpRequestOptions { - Url = manifestUrl, + Url = manifest, CancellationToken = cancellationToken, CacheMode = CacheMode.Unconditional, CacheLength = TimeSpan.FromMinutes(3) @@ -145,25 +138,35 @@ namespace Emby.Server.Implementations.Updates } catch (SerializationException ex) { - const string LogTemplate = - "Failed to deserialize the plugin manifest retrieved from {PluginManifestUrl}. If you " + - "have specified a custom plugin repository manifest URL with --plugin-manifest-url or " + - PluginManifestUrlKey + ", please ensure that it is correct."; - _logger.LogError(ex, LogTemplate, manifestUrl); + _logger.LogError(ex, "Failed to deserialize the plugin manifest retrieved from {Manifest}", manifest); throw; } } } catch (UriFormatException ex) { - const string LogTemplate = - "The URL configured for the plugin repository manifest URL is not valid: {PluginManifestUrl}. " + - "Please check the URL configured by --plugin-manifest-url or " + PluginManifestUrlKey; - _logger.LogError(ex, LogTemplate, manifestUrl); + _logger.LogError(ex, "The URL configured for the plugin repository manifest URL is not valid: {Manifest}", manifest); throw; } } + /// + public async Task> GetAvailablePackages(CancellationToken cancellationToken = default) + { + var result = new List(); + foreach (RepositoryInfo repository in _config.Configuration.PluginRepositories) + { + if (!repository.Enabled) + { + continue; + } + + result.AddRange(await GetPackages(repository.Url, cancellationToken).ConfigureAwait(true)); + } + + return result.ToList().AsReadOnly(); + } + /// public IEnumerable FilterPackages( IEnumerable availablePackages, diff --git a/Jellyfin.Server/StartupOptions.cs b/Jellyfin.Server/StartupOptions.cs index cc250b06e2..a26114e778 100644 --- a/Jellyfin.Server/StartupOptions.cs +++ b/Jellyfin.Server/StartupOptions.cs @@ -79,10 +79,6 @@ namespace Jellyfin.Server [Option("restartargs", Required = false, HelpText = "Arguments for restart script.")] public string? RestartArgs { get; set; } - /// - [Option("plugin-manifest-url", Required = false, HelpText = "A custom URL for the plugin repository JSON manifest")] - public string? PluginManifestUrl { get; set; } - /// [Option("published-server-url", Required = false, HelpText = "Jellyfin Server URL to publish via auto discover process")] public Uri? PublishedServerUrl { get; set; } @@ -95,11 +91,6 @@ namespace Jellyfin.Server { var config = new Dictionary(); - if (PluginManifestUrl != null) - { - config.Add(InstallationManager.PluginManifestUrlKey, PluginManifestUrl); - } - if (NoWebClient) { config.Add(ConfigurationExtensions.HostWebClientKey, bool.FalseString); diff --git a/MediaBrowser.Api/Devices/DeviceService.cs b/MediaBrowser.Api/Devices/DeviceService.cs index dd3f3e738a..18860983ec 100644 --- a/MediaBrowser.Api/Devices/DeviceService.cs +++ b/MediaBrowser.Api/Devices/DeviceService.cs @@ -92,7 +92,6 @@ namespace MediaBrowser.Api.Devices var sessions = _authRepo.Get(new AuthenticationInfoQuery { DeviceId = request.Id - }).Items; foreach (var session in sessions) diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs index 444354a992..31ca05759d 100644 --- a/MediaBrowser.Api/PackageService.cs +++ b/MediaBrowser.Api/PackageService.cs @@ -13,6 +13,18 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Api { + [Route("/Repositories", "GET", Summary = "Gets all package repositories")] + [Authenticated] + public class GetRepositories : IReturnVoid + { + } + + [Route("/Repositories", "POST", Summary = "Sets the enabled and existing package repositories")] + [Authenticated] + public class SetRepositories : List, IReturnVoid + { + } + /// /// Class GetPackage /// @@ -94,6 +106,7 @@ namespace MediaBrowser.Api public class PackageService : BaseApiService { private readonly IInstallationManager _installationManager; + private readonly IServerConfigurationManager _serverConfigurationManager; public PackageService( ILogger logger, @@ -103,6 +116,18 @@ namespace MediaBrowser.Api : base(logger, serverConfigurationManager, httpResultFactory) { _installationManager = installationManager; + _serverConfigurationManager = serverConfigurationManager; + } + + public object Get(GetRepositories request) + { + var result = _serverConfigurationManager.Configuration.PluginRepositories; + return ToOptimizedResult(result); + } + + public void Post(SetRepositories request) + { + _serverConfigurationManager.Configuration.PluginRepositories = request; } /// diff --git a/MediaBrowser.Common/Updates/IInstallationManager.cs b/MediaBrowser.Common/Updates/IInstallationManager.cs index 965ffe0ec2..a5025aee96 100644 --- a/MediaBrowser.Common/Updates/IInstallationManager.cs +++ b/MediaBrowser.Common/Updates/IInstallationManager.cs @@ -40,6 +40,14 @@ namespace MediaBrowser.Common.Updates /// IEnumerable CompletedInstallations { get; } + /// + /// Parses a plugin manifest at the supplied URL. + /// + /// The URL to query. + /// The cancellation token. + /// Task{IReadOnlyList{PackageInfo}}. + Task> GetPackages(string manifest, CancellationToken cancellationToken = default); + /// /// Gets all available packages. /// diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 60b1e6eae6..b8ec1c7108 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -2,7 +2,9 @@ #pragma warning disable CS1591 using System; +using System.Collections.Generic; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Updates; namespace MediaBrowser.Model.Configuration { @@ -229,6 +231,8 @@ namespace MediaBrowser.Model.Configuration public string[] CodecsUsed { get; set; } + public List PluginRepositories { get; set; } + public bool IgnoreVirtualInterfaces { get; set; } public bool EnableExternalContentInSuggestions { get; set; } @@ -241,11 +245,13 @@ namespace MediaBrowser.Model.Configuration public bool EnableNewOmdbSupport { get; set; } public string[] RemoteIPFilter { get; set; } + public bool IsRemoteIPFilterBlacklist { get; set; } public int ImageExtractionTimeoutMs { get; set; } public PathSubstitution[] PathSubstitutions { get; set; } + public bool EnableSimpleArtistDetection { get; set; } public string[] UninstalledPlugins { get; set; } @@ -298,6 +304,17 @@ namespace MediaBrowser.Model.Configuration SortRemoveCharacters = new[] { ",", "&", "-", "{", "}", "'" }; SortRemoveWords = new[] { "the", "a", "an" }; + PluginRepositories = new List + { + new RepositoryInfo + { + Name = "Jellyfin Stable", + Url = "https://repo.jellyfin.org/releases/plugin/manifest-stable.json", + Id = Guid.Parse("3721cd80-b10f-4b26-aecd-74c0f0defe97"), + Enabled = true + } + }; + BaseUrl = string.Empty; UICulture = "en-US"; @@ -355,6 +372,7 @@ namespace MediaBrowser.Model.Configuration public class PathSubstitution { public string From { get; set; } + public string To { get; set; } } } diff --git a/MediaBrowser.Model/Updates/RepositoryInfo.cs b/MediaBrowser.Model/Updates/RepositoryInfo.cs new file mode 100644 index 0000000000..c07abc8093 --- /dev/null +++ b/MediaBrowser.Model/Updates/RepositoryInfo.cs @@ -0,0 +1,34 @@ +using System; + +namespace MediaBrowser.Model.Updates +{ + /// + /// Class RepositoryInfo. + /// + public class RepositoryInfo + { + /// + /// Gets or sets the name. + /// + /// The name. + public string Name { get; set; } + + /// + /// Gets or sets the URL. + /// + /// The URL. + public string Url { get; set; } + + /// + /// Gets or sets the ID. + /// + /// The ID. + public Guid Id { get; set; } + + /// + /// Gets or sets the enabled status of the repository. + /// + /// The enabled status. + public bool Enabled { get; set; } + } +} -- cgit v1.2.3 From 8ac2f1bb8be29bf9d2285958cb233692765bfe32 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 6 Jun 2020 22:02:30 +0900 Subject: simplify the custom repository feature for now --- Emby.Server.Implementations/Updates/InstallationManager.cs | 5 ----- Jellyfin.Server/Migrations/Routines/AddDefaultPluginRepository.cs | 3 +-- MediaBrowser.Model/Updates/RepositoryInfo.cs | 6 ------ 3 files changed, 1 insertion(+), 13 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index bdd7c31d69..6c02b8fdce 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -156,11 +156,6 @@ namespace Emby.Server.Implementations.Updates var result = new List(); foreach (RepositoryInfo repository in _config.Configuration.PluginRepositories) { - if (!repository.Enabled) - { - continue; - } - result.AddRange(await GetPackages(repository.Url, cancellationToken).ConfigureAwait(true)); } diff --git a/Jellyfin.Server/Migrations/Routines/AddDefaultPluginRepository.cs b/Jellyfin.Server/Migrations/Routines/AddDefaultPluginRepository.cs index b6004adef6..1461c7c576 100644 --- a/Jellyfin.Server/Migrations/Routines/AddDefaultPluginRepository.cs +++ b/Jellyfin.Server/Migrations/Routines/AddDefaultPluginRepository.cs @@ -14,8 +14,7 @@ namespace Jellyfin.Server.Migrations.Routines private readonly RepositoryInfo _defaultRepositoryInfo = new RepositoryInfo { Name = "Jellyfin Stable", - Url = "https://repo.jellyfin.org/releases/plugin/manifest-stable.json", - Enabled = true + Url = "https://repo.jellyfin.org/releases/plugin/manifest-stable.json" }; /// diff --git a/MediaBrowser.Model/Updates/RepositoryInfo.cs b/MediaBrowser.Model/Updates/RepositoryInfo.cs index b0dc3593ad..a6414fa7b7 100644 --- a/MediaBrowser.Model/Updates/RepositoryInfo.cs +++ b/MediaBrowser.Model/Updates/RepositoryInfo.cs @@ -18,11 +18,5 @@ namespace MediaBrowser.Model.Updates /// /// The URL. public string Url { get; set; } - - /// - /// Gets or sets the enabled status of the repository. - /// - /// The enabled status. - public bool Enabled { get; set; } } } -- cgit v1.2.3 From 7161a30af7e1ac1eacc00add5487d036ab7cb9dc Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 7 Jun 2020 02:08:05 +0900 Subject: improve error handling when a single repository has issues Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Updates/InstallationManager.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 6c02b8fdce..b910943405 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -139,14 +139,19 @@ namespace Emby.Server.Implementations.Updates catch (SerializationException ex) { _logger.LogError(ex, "Failed to deserialize the plugin manifest retrieved from {Manifest}", manifest); - throw; + return Enumerable.Empty(); } } } catch (UriFormatException ex) { _logger.LogError(ex, "The URL configured for the plugin repository manifest URL is not valid: {Manifest}", manifest); - throw; + return Enumerable.Empty(); + } + catch (HttpException ex) + { + _logger.LogError(ex, "An error occurred while accessing the plugin manifest: {Manifest}", manifest); + return Enumerable.Empty(); } } @@ -159,7 +164,7 @@ namespace Emby.Server.Implementations.Updates result.AddRange(await GetPackages(repository.Url, cancellationToken).ConfigureAwait(true)); } - return result.ToList().AsReadOnly(); + return result.AsReadOnly(); } /// -- cgit v1.2.3 From 91f60c2139f2a7fe8a18455db36d0cdb9a5bf4eb Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 7 Jun 2020 21:23:11 +0900 Subject: add missing line from using block --- Emby.Server.Implementations/Updates/InstallationManager.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index b910943405..5a1612273e 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -19,6 +19,7 @@ using MediaBrowser.Common.Updates; using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Events; using MediaBrowser.Model.IO; +using MediaBrowser.Model.Net; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Updates; using Microsoft.Extensions.Configuration; -- cgit v1.2.3 From 02f6ced07ac306c2cc2857684890cebc4f84c1e9 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 19 Jun 2020 22:07:25 +0100 Subject: Merged --- Emby.Server.Implementations/Networking/NetworkManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index caa3d964a3..82f5d39770 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -15,7 +15,7 @@ namespace Emby.Server.Implementations.Networking /// public class NetworkManager : INetworkManager { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly object _localIpAddressSyncLock = new object(); private readonly object _subnetLookupLock = new object(); private readonly Dictionary> _subnetLookup = new Dictionary>(StringComparer.Ordinal); -- cgit v1.2.3 From 46006a1aff5759e9843813a9d31dc79672af71d5 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 19 Jun 2020 22:32:07 +0100 Subject: Re-ordered code for the match --- .../Networking/NetworkManager.cs | 431 +++++++++++---------- 1 file changed, 217 insertions(+), 214 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 82f5d39770..967263a200 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -16,10 +16,13 @@ namespace Emby.Server.Implementations.Networking public class NetworkManager : INetworkManager { private readonly ILogger _logger; + + private IPAddress[] _localIpAddresses; private readonly object _localIpAddressSyncLock = new object(); + private readonly object _subnetLookupLock = new object(); private readonly Dictionary> _subnetLookup = new Dictionary>(StringComparer.Ordinal); - private IPAddress[] _localIpAddresses; + private List _macAddresses; /// @@ -40,219 +43,6 @@ namespace Emby.Server.Implementations.Networking /// public Func LocalSubnetsFn { get; set; } - /// - public IPAddress[] GetLocalIpAddresses() - { - lock (_localIpAddressSyncLock) - { - if (_localIpAddresses == null) - { - var addresses = GetLocalIpAddressesInternal().ToArray(); - - _localIpAddresses = addresses; - } - - return _localIpAddresses; - } - } - - /// - public bool IsInPrivateAddressSpace(string endpoint) - { - return IsInPrivateAddressSpace(endpoint, true); - } - - /// - public bool IsInLocalNetwork(string endpoint) - { - return IsInLocalNetworkInternal(endpoint, true); - } - - /// - public bool IsAddressInSubnets(string addressString, string[] subnets) - { - return IsAddressInSubnets(IPAddress.Parse(addressString), addressString, subnets); - } - - /// - public bool IsInPrivateAddressSpaceAndLocalSubnet(string endpoint) - { - if (endpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase)) - { - var endpointFirstPart = endpoint.Split('.')[0]; - - var subnets = GetSubnets(endpointFirstPart); - - foreach (var subnet_Match in subnets) - { - // logger.LogDebug("subnet_Match:" + subnet_Match); - - if (endpoint.StartsWith(subnet_Match + ".", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - } - } - - return false; - } - - /// - /// Gets a random port number that is currently available. - /// - /// System.Int32. - public int GetRandomUnusedTcpPort() - { - var listener = new TcpListener(IPAddress.Any, 0); - listener.Start(); - var port = ((IPEndPoint)listener.LocalEndpoint).Port; - listener.Stop(); - return port; - } - - /// - public int GetRandomUnusedUdpPort() - { - var localEndPoint = new IPEndPoint(IPAddress.Any, 0); - using (var udpClient = new UdpClient(localEndPoint)) - { - return ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; - } - } - - /// - public List GetMacAddresses() - { - return _macAddresses ??= GetMacAddressesInternal().ToList(); - } - - /// - public bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask) - { - IPAddress network1 = GetNetworkAddress(address1, subnetMask); - IPAddress network2 = GetNetworkAddress(address2, subnetMask); - return network1.Equals(network2); - } - - /// - public bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC) - { - byte[] octet = address.GetAddressBytes(); - - if ((octet[0] == 127) || // RFC1122 - (octet[0] == 169 && octet[1] == 254)) // RFC3927 - { - // don't use on loopback or 169 interfaces - return false; - } - - string addressString = address.ToString(); - string excludeAddress = "[" + addressString + "]"; - var subnets = LocalSubnetsFn(); - - // Exclude any addresses if they appear in the LAN list in [ ] - if (Array.IndexOf(subnets, excludeAddress) != -1) - { - return false; - } - - return IsAddressInSubnets(address, addressString, subnets); - } - - /// - public IPAddress GetLocalIpSubnetMask(IPAddress address) - { - NetworkInterface[] interfaces; - - try - { - var validStatuses = new[] { OperationalStatus.Up, OperationalStatus.Unknown }; - - interfaces = NetworkInterface.GetAllNetworkInterfaces() - .Where(i => validStatuses.Contains(i.OperationalStatus)) - .ToArray(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error in GetAllNetworkInterfaces"); - return null; - } - - foreach (NetworkInterface ni in interfaces) - { - foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) - { - if (ip.Address.Equals(address) && ip.IPv4Mask != null) - { - return ip.IPv4Mask; - } - } - } - - return null; - } - - /// - /// Checks if the give address falls within the ranges given in [subnets]. The addresses in subnets can be hosts or subnets in the CIDR format. - /// - /// IPAddress version of the address. - /// The address to check. - /// If true, check against addresses in the LAN settings which have [] arroud and return true if it matches the address give in address. - /// falseif the address isn't in the subnets, true otherwise. - private static bool IsAddressInSubnets(IPAddress address, string addressString, string[] subnets) - { - foreach (var subnet in subnets) - { - var normalizedSubnet = subnet.Trim(); - // Is the subnet a host address and does it match the address being passes? - if (string.Equals(normalizedSubnet, addressString, StringComparison.OrdinalIgnoreCase)) - { - return true; - } - - // Parse CIDR subnets and see if address falls within it. - if (normalizedSubnet.Contains('/', StringComparison.Ordinal)) - { - try - { - var ipNetwork = IPNetwork.Parse(normalizedSubnet); - if (ipNetwork.Contains(address)) - { - return true; - } - } - catch - { - // Ignoring - invalid subnet passed encountered. - } - } - } - - return false; - } - - private static Task GetIpAddresses(string hostName) - { - return Dns.GetHostAddressesAsync(hostName); - } - - private static async Task> GetLocalIpAddressesFallback() - { - var host = await Dns.GetHostEntryAsync(Dns.GetHostName()).ConfigureAwait(false); - - // Reverse them because the last one is usually the correct one - // It's not fool-proof so ultimately the consumer will have to examine them and decide - return host.AddressList - .Where(i => i.AddressFamily == AddressFamily.InterNetwork || i.AddressFamily == AddressFamily.InterNetworkV6) - .Reverse(); - } - - private static IEnumerable GetMacAddressesInternal() - => NetworkInterface.GetAllNetworkInterfaces() - .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback) - .Select(x => x.GetPhysicalAddress()) - .Where(x => !x.Equals(PhysicalAddress.None)); - private void OnNetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) { _logger.LogDebug("NetworkAvailabilityChanged"); @@ -276,6 +66,22 @@ namespace Emby.Server.Implementations.Networking NetworkChanged?.Invoke(this, EventArgs.Empty); } + /// + public IPAddress[] GetLocalIpAddresses() + { + lock (_localIpAddressSyncLock) + { + if (_localIpAddresses == null) + { + var addresses = GetLocalIpAddressesInternal().ToArray(); + + _localIpAddresses = addresses; + } + + return _localIpAddresses; + } + } + private List GetLocalIpAddressesInternal() { var list = GetIPsDefault().ToList(); @@ -310,6 +116,12 @@ namespace Emby.Server.Implementations.Networking .ToList(); } + /// + public bool IsInPrivateAddressSpace(string endpoint) + { + return IsInPrivateAddressSpace(endpoint, true); + } + // Checks if the address in endpoint is an RFC1918, RFC1122, or RFC3927 address private bool IsInPrivateAddressSpace(string endpoint, bool checkSubnets) { @@ -357,6 +169,29 @@ namespace Emby.Server.Implementations.Networking return false; } + /// + public bool IsInPrivateAddressSpaceAndLocalSubnet(string endpoint) + { + if (endpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase)) + { + var endpointFirstPart = endpoint.Split('.')[0]; + + var subnets = GetSubnets(endpointFirstPart); + + foreach (var subnet_Match in subnets) + { + // logger.LogDebug("subnet_Match:" + subnet_Match); + + if (endpoint.StartsWith(subnet_Match + ".", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + } + + return false; + } + // Gives a list of possible subnets from the system whose interface ip starts with endpointFirstPart private List GetSubnets(string endpointFirstPart) { @@ -403,6 +238,82 @@ namespace Emby.Server.Implementations.Networking } } + /// + public bool IsInLocalNetwork(string endpoint) + { + return IsInLocalNetworkInternal(endpoint, true); + } + + /// + public bool IsAddressInSubnets(string addressString, string[] subnets) + { + return IsAddressInSubnets(IPAddress.Parse(addressString), addressString, subnets); + } + + /// + public bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC) + { + byte[] octet = address.GetAddressBytes(); + + if ((octet[0] == 127) || // RFC1122 + (octet[0] == 169 && octet[1] == 254)) // RFC3927 + { + // don't use on loopback or 169 interfaces + return false; + } + + string addressString = address.ToString(); + string excludeAddress = "[" + addressString + "]"; + var subnets = LocalSubnetsFn(); + + // Exclude any addresses if they appear in the LAN list in [ ] + if (Array.IndexOf(subnets, excludeAddress) != -1) + { + return false; + } + + return IsAddressInSubnets(address, addressString, subnets); + } + + /// + /// Checks if the give address falls within the ranges given in [subnets]. The addresses in subnets can be hosts or subnets in the CIDR format. + /// + /// IPAddress version of the address. + /// The address to check. + /// If true, check against addresses in the LAN settings which have [] arroud and return true if it matches the address give in address. + /// falseif the address isn't in the subnets, true otherwise. + private static bool IsAddressInSubnets(IPAddress address, string addressString, string[] subnets) + { + foreach (var subnet in subnets) + { + var normalizedSubnet = subnet.Trim(); + // Is the subnet a host address and does it match the address being passes? + if (string.Equals(normalizedSubnet, addressString, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + // Parse CIDR subnets and see if address falls within it. + if (normalizedSubnet.Contains('/', StringComparison.Ordinal)) + { + try + { + var ipNetwork = IPNetwork.Parse(normalizedSubnet); + if (ipNetwork.Contains(address)) + { + return true; + } + } + catch + { + // Ignoring - invalid subnet passed encountered. + } + } + } + + return false; + } + private bool IsInLocalNetworkInternal(string endpoint, bool resolveHost) { if (string.IsNullOrEmpty(endpoint)) @@ -489,6 +400,11 @@ namespace Emby.Server.Implementations.Networking return false; } + private static Task GetIpAddresses(string hostName) + { + return Dns.GetHostAddressesAsync(hostName); + } + private IEnumerable GetIPsDefault() { IEnumerable interfaces; @@ -518,6 +434,60 @@ namespace Emby.Server.Implementations.Networking .Select(x => x.First()); } + private static async Task> GetLocalIpAddressesFallback() + { + var host = await Dns.GetHostEntryAsync(Dns.GetHostName()).ConfigureAwait(false); + + // Reverse them because the last one is usually the correct one + // It's not fool-proof so ultimately the consumer will have to examine them and decide + return host.AddressList + .Where(i => i.AddressFamily == AddressFamily.InterNetwork || i.AddressFamily == AddressFamily.InterNetworkV6) + .Reverse(); + } + + /// + /// Gets a random port number that is currently available. + /// + /// System.Int32. + public int GetRandomUnusedTcpPort() + { + var listener = new TcpListener(IPAddress.Any, 0); + listener.Start(); + var port = ((IPEndPoint)listener.LocalEndpoint).Port; + listener.Stop(); + return port; + } + + /// + public int GetRandomUnusedUdpPort() + { + var localEndPoint = new IPEndPoint(IPAddress.Any, 0); + using (var udpClient = new UdpClient(localEndPoint)) + { + return ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; + } + } + + /// + public List GetMacAddresses() + { + return _macAddresses ??= GetMacAddressesInternal().ToList(); + } + + private static IEnumerable GetMacAddressesInternal() + => NetworkInterface.GetAllNetworkInterfaces() + .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback) + .Select(x => x.GetPhysicalAddress()) + .Where(x => !x.Equals(PhysicalAddress.None)); + + /// + public bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask) + { + IPAddress network1 = GetNetworkAddress(address1, subnetMask); + IPAddress network2 = GetNetworkAddress(address2, subnetMask); + return network1.Equals(network2); + } + private IPAddress GetNetworkAddress(IPAddress address, IPAddress subnetMask) { byte[] ipAdressBytes = address.GetAddressBytes(); @@ -536,5 +506,38 @@ namespace Emby.Server.Implementations.Networking return new IPAddress(broadcastAddress); } + + /// + public IPAddress GetLocalIpSubnetMask(IPAddress address) + { + NetworkInterface[] interfaces; + + try + { + var validStatuses = new[] { OperationalStatus.Up, OperationalStatus.Unknown }; + + interfaces = NetworkInterface.GetAllNetworkInterfaces() + .Where(i => validStatuses.Contains(i.OperationalStatus)) + .ToArray(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error in GetAllNetworkInterfaces"); + return null; + } + + foreach (NetworkInterface ni in interfaces) + { + foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) + { + if (ip.Address.Equals(address) && ip.IPv4Mask != null) + { + return ip.IPv4Mask; + } + } + } + + return null; + } } } -- cgit v1.2.3 From afe09612e82a49c4021fbc2ceddf1816db9f959d Mon Sep 17 00:00:00 2001 From: telans Date: Fri, 19 Jun 2020 21:57:37 +1200 Subject: fix SA1119 --- .../HttpServer/HttpResultFactory.cs | 2 +- Emby.Server.Implementations/HttpServer/ResponseFilter.cs | 4 ++-- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 2 +- .../Security/AuthenticationRepository.cs | 4 ++-- Emby.Server.Implementations/Services/ServicePath.cs | 4 ++-- Jellyfin.Data/Entities/Artwork.cs | 6 +++--- Jellyfin.Data/Entities/BookMetadata.cs | 2 +- Jellyfin.Data/Entities/Chapter.cs | 10 +++++----- Jellyfin.Data/Entities/Collection.cs | 4 ++-- Jellyfin.Data/Entities/CollectionItem.cs | 2 +- Jellyfin.Data/Entities/Company.cs | 2 +- Jellyfin.Data/Entities/CompanyMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/Episode.cs | 2 +- Jellyfin.Data/Entities/EpisodeMetadata.cs | 6 +++--- Jellyfin.Data/Entities/Genre.cs | 4 ++-- Jellyfin.Data/Entities/Library.cs | 4 ++-- Jellyfin.Data/Entities/LibraryItem.cs | 6 +++--- Jellyfin.Data/Entities/LibraryRoot.cs | 6 +++--- Jellyfin.Data/Entities/MediaFile.cs | 6 +++--- Jellyfin.Data/Entities/MediaFileStream.cs | 4 ++-- Jellyfin.Data/Entities/Metadata.cs | 16 ++++++++-------- Jellyfin.Data/Entities/MetadataProvider.cs | 4 ++-- Jellyfin.Data/Entities/MetadataProviderId.cs | 4 ++-- Jellyfin.Data/Entities/MovieMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/MusicAlbumMetadata.cs | 6 +++--- Jellyfin.Data/Entities/Person.cs | 12 ++++++------ Jellyfin.Data/Entities/PersonRole.cs | 6 +++--- Jellyfin.Data/Entities/Rating.cs | 6 +++--- Jellyfin.Data/Entities/RatingSource.cs | 8 ++++---- Jellyfin.Data/Entities/Release.cs | 4 ++-- Jellyfin.Data/Entities/Season.cs | 2 +- Jellyfin.Data/Entities/SeasonMetadata.cs | 2 +- Jellyfin.Data/Entities/Series.cs | 6 +++--- Jellyfin.Data/Entities/SeriesMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/Track.cs | 2 +- MediaBrowser.Controller/Entities/CollectionFolder.cs | 2 +- MediaBrowser.Controller/Entities/Folder.cs | 4 ++-- MediaBrowser.Controller/Library/ItemResolveArgs.cs | 2 +- MediaBrowser.Providers/Manager/MetadataService.cs | 2 +- 39 files changed, 96 insertions(+), 96 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs index ad31b3e1ea..7b7da703be 100644 --- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -426,7 +426,7 @@ namespace Emby.Server.Implementations.HttpServer /// private object GetCachedResult(IRequest requestContext, IDictionary responseHeaders, StaticResultOptions options) { - bool noCache = (requestContext.Headers[HeaderNames.CacheControl].ToString()).IndexOf("no-cache", StringComparison.OrdinalIgnoreCase) != -1; + bool noCache = requestContext.Headers[HeaderNames.CacheControl].ToString().IndexOf("no-cache", StringComparison.OrdinalIgnoreCase) != -1; AddCachingHeaders(responseHeaders, options.CacheDuration, noCache, options.DateLastModified); if (!noCache) diff --git a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs index 3ab5dbc160..a8cd2ac8f2 100644 --- a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs +++ b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs @@ -41,11 +41,11 @@ namespace Emby.Server.Implementations.HttpServer res.Headers.Add(key, value); } // Try to prevent compatibility view - res.Headers["Access-Control-Allow-Headers"] = ("Accept, Accept-Language, Authorization, Cache-Control, " + + res.Headers["Access-Control-Allow-Headers"] = "Accept, Accept-Language, Authorization, Cache-Control, " + "Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, " + "Content-Type, Cookie, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, " + "Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, " + - "X-Emby-Authorization"); + "X-Emby-Authorization"; if (dto is Exception exception) { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index dff113a2a7..db9d240281 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -691,7 +691,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { var model = ModelNumber ?? string.Empty; - if ((model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1)) + if (model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1) { return true; } diff --git a/Emby.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Implementations/Security/AuthenticationRepository.cs index 9c1be9a1ab..4dfadc7032 100644 --- a/Emby.Server.Implementations/Security/AuthenticationRepository.cs +++ b/Emby.Server.Implementations/Security/AuthenticationRepository.cs @@ -98,7 +98,7 @@ namespace Emby.Server.Implementations.Security statement.TryBind("@AppName", info.AppName); statement.TryBind("@AppVersion", info.AppVersion); statement.TryBind("@DeviceName", info.DeviceName); - statement.TryBind("@UserId", (info.UserId.Equals(Guid.Empty) ? null : info.UserId.ToString("N", CultureInfo.InvariantCulture))); + statement.TryBind("@UserId", info.UserId.Equals(Guid.Empty) ? null : info.UserId.ToString("N", CultureInfo.InvariantCulture)); statement.TryBind("@UserName", info.UserName); statement.TryBind("@IsActive", true); statement.TryBind("@DateCreated", info.DateCreated.ToDateTimeParamValue()); @@ -131,7 +131,7 @@ namespace Emby.Server.Implementations.Security statement.TryBind("@AppName", info.AppName); statement.TryBind("@AppVersion", info.AppVersion); statement.TryBind("@DeviceName", info.DeviceName); - statement.TryBind("@UserId", (info.UserId.Equals(Guid.Empty) ? null : info.UserId.ToString("N", CultureInfo.InvariantCulture))); + statement.TryBind("@UserId", info.UserId.Equals(Guid.Empty) ? null : info.UserId.ToString("N", CultureInfo.InvariantCulture)); statement.TryBind("@UserName", info.UserName); statement.TryBind("@DateCreated", info.DateCreated.ToDateTimeParamValue()); statement.TryBind("@DateLastActivity", info.DateLastActivity.ToDateTimeParamValue()); diff --git a/Emby.Server.Implementations/Services/ServicePath.cs b/Emby.Server.Implementations/Services/ServicePath.cs index 3b7ffaf2cd..14ae126a33 100644 --- a/Emby.Server.Implementations/Services/ServicePath.cs +++ b/Emby.Server.Implementations/Services/ServicePath.cs @@ -302,9 +302,9 @@ namespace Emby.Server.Implementations.Services } // Routes with least wildcard matches get the highest score - var score = Math.Max((100 - wildcardMatchCount), 1) * 1000 + var score = Math.Max(100 - wildcardMatchCount, 1) * 1000 // Routes with less variable (and more literal) matches - + Math.Max((10 - VariableArgsCount), 1) * 100; + + Math.Max(10 - VariableArgsCount, 1) * 100; // Exact verb match is better than ANY if (Verbs.Length == 1 && string.Equals(httpMethod, Verbs[0], StringComparison.OrdinalIgnoreCase)) diff --git a/Jellyfin.Data/Entities/Artwork.cs b/Jellyfin.Data/Entities/Artwork.cs index 852d742a58..df071e477b 100644 --- a/Jellyfin.Data/Entities/Artwork.cs +++ b/Jellyfin.Data/Entities/Artwork.cs @@ -87,7 +87,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -126,7 +126,7 @@ namespace Jellyfin.Data.Entities { string value = _Path; GetPath(ref value); - return (_Path = value); + return _Path = value; } set @@ -163,7 +163,7 @@ namespace Jellyfin.Data.Entities { Enums.ArtKind value = _Kind; GetKind(ref value); - return (_Kind = value); + return _Kind = value; } set diff --git a/Jellyfin.Data/Entities/BookMetadata.cs b/Jellyfin.Data/Entities/BookMetadata.cs index 47578dc46b..914eda0642 100644 --- a/Jellyfin.Data/Entities/BookMetadata.cs +++ b/Jellyfin.Data/Entities/BookMetadata.cs @@ -82,7 +82,7 @@ namespace Jellyfin.Data.Entities { long? value = _ISBN; GetISBN(ref value); - return (_ISBN = value); + return _ISBN = value; } set diff --git a/Jellyfin.Data/Entities/Chapter.cs b/Jellyfin.Data/Entities/Chapter.cs index d5b2b39ce7..77685add6e 100644 --- a/Jellyfin.Data/Entities/Chapter.cs +++ b/Jellyfin.Data/Entities/Chapter.cs @@ -84,7 +84,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -122,7 +122,7 @@ namespace Jellyfin.Data.Entities { string value = _Name; GetName(ref value); - return (_Name = value); + return _Name = value; } set @@ -163,7 +163,7 @@ namespace Jellyfin.Data.Entities { string value = _Language; GetLanguage(ref value); - return (_Language = value); + return _Language = value; } set @@ -200,7 +200,7 @@ namespace Jellyfin.Data.Entities { long value = _TimeStart; GetTimeStart(ref value); - return (_TimeStart = value); + return _TimeStart = value; } set @@ -233,7 +233,7 @@ namespace Jellyfin.Data.Entities { long? value = _TimeEnd; GetTimeEnd(ref value); - return (_TimeEnd = value); + return _TimeEnd = value; } set diff --git a/Jellyfin.Data/Entities/Collection.cs b/Jellyfin.Data/Entities/Collection.cs index d2f441d030..01836d8937 100644 --- a/Jellyfin.Data/Entities/Collection.cs +++ b/Jellyfin.Data/Entities/Collection.cs @@ -47,7 +47,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -85,7 +85,7 @@ namespace Jellyfin.Data.Entities { string value = _Name; GetName(ref value); - return (_Name = value); + return _Name = value; } set diff --git a/Jellyfin.Data/Entities/CollectionItem.cs b/Jellyfin.Data/Entities/CollectionItem.cs index 7cfdbbe167..08b0e99f41 100644 --- a/Jellyfin.Data/Entities/CollectionItem.cs +++ b/Jellyfin.Data/Entities/CollectionItem.cs @@ -91,7 +91,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set diff --git a/Jellyfin.Data/Entities/Company.cs b/Jellyfin.Data/Entities/Company.cs index 908e41f3de..2ac7bcfe5f 100644 --- a/Jellyfin.Data/Entities/Company.cs +++ b/Jellyfin.Data/Entities/Company.cs @@ -99,7 +99,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set diff --git a/Jellyfin.Data/Entities/CompanyMetadata.cs b/Jellyfin.Data/Entities/CompanyMetadata.cs index 240cccbff5..695c7f0965 100644 --- a/Jellyfin.Data/Entities/CompanyMetadata.cs +++ b/Jellyfin.Data/Entities/CompanyMetadata.cs @@ -83,7 +83,7 @@ namespace Jellyfin.Data.Entities { string value = _Description; GetDescription(ref value); - return (_Description = value); + return _Description = value; } set @@ -121,7 +121,7 @@ namespace Jellyfin.Data.Entities { string value = _Headquarters; GetHeadquarters(ref value); - return (_Headquarters = value); + return _Headquarters = value; } set @@ -159,7 +159,7 @@ namespace Jellyfin.Data.Entities { string value = _Country; GetCountry(ref value); - return (_Country = value); + return _Country = value; } set @@ -197,7 +197,7 @@ namespace Jellyfin.Data.Entities { string value = _Homepage; GetHomepage(ref value); - return (_Homepage = value); + return _Homepage = value; } set diff --git a/Jellyfin.Data/Entities/Episode.cs b/Jellyfin.Data/Entities/Episode.cs index 405c815cd0..69106ab79d 100644 --- a/Jellyfin.Data/Entities/Episode.cs +++ b/Jellyfin.Data/Entities/Episode.cs @@ -84,7 +84,7 @@ namespace Jellyfin.Data.Entities { int? value = _EpisodeNumber; GetEpisodeNumber(ref value); - return (_EpisodeNumber = value); + return _EpisodeNumber = value; } set diff --git a/Jellyfin.Data/Entities/EpisodeMetadata.cs b/Jellyfin.Data/Entities/EpisodeMetadata.cs index 4999842aa2..da5ea43ccd 100644 --- a/Jellyfin.Data/Entities/EpisodeMetadata.cs +++ b/Jellyfin.Data/Entities/EpisodeMetadata.cs @@ -83,7 +83,7 @@ namespace Jellyfin.Data.Entities { string value = _Outline; GetOutline(ref value); - return (_Outline = value); + return _Outline = value; } set @@ -121,7 +121,7 @@ namespace Jellyfin.Data.Entities { string value = _Plot; GetPlot(ref value); - return (_Plot = value); + return _Plot = value; } set @@ -159,7 +159,7 @@ namespace Jellyfin.Data.Entities { string value = _Tagline; GetTagline(ref value); - return (_Tagline = value); + return _Tagline = value; } set diff --git a/Jellyfin.Data/Entities/Genre.cs b/Jellyfin.Data/Entities/Genre.cs index 0f6f681a44..9b2264921c 100644 --- a/Jellyfin.Data/Entities/Genre.cs +++ b/Jellyfin.Data/Entities/Genre.cs @@ -80,7 +80,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -119,7 +119,7 @@ namespace Jellyfin.Data.Entities { string value = _Name; GetName(ref value); - return (_Name = value); + return _Name = value; } set diff --git a/Jellyfin.Data/Entities/Library.cs b/Jellyfin.Data/Entities/Library.cs index a091ece03f..ff94b93f04 100644 --- a/Jellyfin.Data/Entities/Library.cs +++ b/Jellyfin.Data/Entities/Library.cs @@ -75,7 +75,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -114,7 +114,7 @@ namespace Jellyfin.Data.Entities { string value = _Name; GetName(ref value); - return (_Name = value); + return _Name = value; } set diff --git a/Jellyfin.Data/Entities/LibraryItem.cs b/Jellyfin.Data/Entities/LibraryItem.cs index d29d6250e5..f41753560c 100644 --- a/Jellyfin.Data/Entities/LibraryItem.cs +++ b/Jellyfin.Data/Entities/LibraryItem.cs @@ -57,7 +57,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -95,7 +95,7 @@ namespace Jellyfin.Data.Entities { Guid value = _UrlId; GetUrlId(ref value); - return (_UrlId = value); + return _UrlId = value; } set @@ -132,7 +132,7 @@ namespace Jellyfin.Data.Entities { DateTime value = _DateAdded; GetDateAdded(ref value); - return (_DateAdded = value); + return _DateAdded = value; } internal set diff --git a/Jellyfin.Data/Entities/LibraryRoot.cs b/Jellyfin.Data/Entities/LibraryRoot.cs index d9a4f62e50..16fbc92f6e 100644 --- a/Jellyfin.Data/Entities/LibraryRoot.cs +++ b/Jellyfin.Data/Entities/LibraryRoot.cs @@ -75,7 +75,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -115,7 +115,7 @@ namespace Jellyfin.Data.Entities { string value = _Path; GetPath(ref value); - return (_Path = value); + return _Path = value; } set @@ -154,7 +154,7 @@ namespace Jellyfin.Data.Entities { string value = _NetworkPath; GetNetworkPath(ref value); - return (_NetworkPath = value); + return _NetworkPath = value; } set diff --git a/Jellyfin.Data/Entities/MediaFile.cs b/Jellyfin.Data/Entities/MediaFile.cs index 6e6602bfae..8201eed526 100644 --- a/Jellyfin.Data/Entities/MediaFile.cs +++ b/Jellyfin.Data/Entities/MediaFile.cs @@ -88,7 +88,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -128,7 +128,7 @@ namespace Jellyfin.Data.Entities { string value = _Path; GetPath(ref value); - return (_Path = value); + return _Path = value; } set @@ -165,7 +165,7 @@ namespace Jellyfin.Data.Entities { Enums.MediaFileKind value = _Kind; GetKind(ref value); - return (_Kind = value); + return _Kind = value; } set diff --git a/Jellyfin.Data/Entities/MediaFileStream.cs b/Jellyfin.Data/Entities/MediaFileStream.cs index 823988d6c9..c018c0cbf9 100644 --- a/Jellyfin.Data/Entities/MediaFileStream.cs +++ b/Jellyfin.Data/Entities/MediaFileStream.cs @@ -79,7 +79,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -116,7 +116,7 @@ namespace Jellyfin.Data.Entities { int value = _StreamNumber; GetStreamNumber(ref value); - return (_StreamNumber = value); + return _StreamNumber = value; } set diff --git a/Jellyfin.Data/Entities/Metadata.cs b/Jellyfin.Data/Entities/Metadata.cs index a6ca61709a..146c70a10d 100644 --- a/Jellyfin.Data/Entities/Metadata.cs +++ b/Jellyfin.Data/Entities/Metadata.cs @@ -74,7 +74,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -114,7 +114,7 @@ namespace Jellyfin.Data.Entities { string value = _Title; GetTitle(ref value); - return (_Title = value); + return _Title = value; } set @@ -152,7 +152,7 @@ namespace Jellyfin.Data.Entities { string value = _OriginalTitle; GetOriginalTitle(ref value); - return (_OriginalTitle = value); + return _OriginalTitle = value; } set @@ -190,7 +190,7 @@ namespace Jellyfin.Data.Entities { string value = _SortTitle; GetSortTitle(ref value); - return (_SortTitle = value); + return _SortTitle = value; } set @@ -231,7 +231,7 @@ namespace Jellyfin.Data.Entities { string value = _Language; GetLanguage(ref value); - return (_Language = value); + return _Language = value; } set @@ -264,7 +264,7 @@ namespace Jellyfin.Data.Entities { DateTimeOffset? value = _ReleaseDate; GetReleaseDate(ref value); - return (_ReleaseDate = value); + return _ReleaseDate = value; } set @@ -301,7 +301,7 @@ namespace Jellyfin.Data.Entities { DateTime value = _DateAdded; GetDateAdded(ref value); - return (_DateAdded = value); + return _DateAdded = value; } internal set @@ -338,7 +338,7 @@ namespace Jellyfin.Data.Entities { DateTime value = _DateModified; GetDateModified(ref value); - return (_DateModified = value); + return _DateModified = value; } internal set diff --git a/Jellyfin.Data/Entities/MetadataProvider.cs b/Jellyfin.Data/Entities/MetadataProvider.cs index 8c6c4000a0..ae22ccfeb1 100644 --- a/Jellyfin.Data/Entities/MetadataProvider.cs +++ b/Jellyfin.Data/Entities/MetadataProvider.cs @@ -75,7 +75,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -114,7 +114,7 @@ namespace Jellyfin.Data.Entities { string value = _Name; GetName(ref value); - return (_Name = value); + return _Name = value; } set diff --git a/Jellyfin.Data/Entities/MetadataProviderId.cs b/Jellyfin.Data/Entities/MetadataProviderId.cs index 67ffc4f0cd..30683ced3b 100644 --- a/Jellyfin.Data/Entities/MetadataProviderId.cs +++ b/Jellyfin.Data/Entities/MetadataProviderId.cs @@ -101,7 +101,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -140,7 +140,7 @@ namespace Jellyfin.Data.Entities { string value = _ProviderId; GetProviderId(ref value); - return (_ProviderId = value); + return _ProviderId = value; } set diff --git a/Jellyfin.Data/Entities/MovieMetadata.cs b/Jellyfin.Data/Entities/MovieMetadata.cs index cb722c015f..48584dd13c 100644 --- a/Jellyfin.Data/Entities/MovieMetadata.cs +++ b/Jellyfin.Data/Entities/MovieMetadata.cs @@ -88,7 +88,7 @@ namespace Jellyfin.Data.Entities { string value = _Outline; GetOutline(ref value); - return (_Outline = value); + return _Outline = value; } set @@ -126,7 +126,7 @@ namespace Jellyfin.Data.Entities { string value = _Plot; GetPlot(ref value); - return (_Plot = value); + return _Plot = value; } set @@ -164,7 +164,7 @@ namespace Jellyfin.Data.Entities { string value = _Tagline; GetTagline(ref value); - return (_Tagline = value); + return _Tagline = value; } set @@ -202,7 +202,7 @@ namespace Jellyfin.Data.Entities { string value = _Country; GetCountry(ref value); - return (_Country = value); + return _Country = value; } set diff --git a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs b/Jellyfin.Data/Entities/MusicAlbumMetadata.cs index 4b9f9cb626..5847101ca3 100644 --- a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs +++ b/Jellyfin.Data/Entities/MusicAlbumMetadata.cs @@ -88,7 +88,7 @@ namespace Jellyfin.Data.Entities { string value = _Barcode; GetBarcode(ref value); - return (_Barcode = value); + return _Barcode = value; } set @@ -126,7 +126,7 @@ namespace Jellyfin.Data.Entities { string value = _LabelNumber; GetLabelNumber(ref value); - return (_LabelNumber = value); + return _LabelNumber = value; } set @@ -164,7 +164,7 @@ namespace Jellyfin.Data.Entities { string value = _Country; GetCountry(ref value); - return (_Country = value); + return _Country = value; } set diff --git a/Jellyfin.Data/Entities/Person.cs b/Jellyfin.Data/Entities/Person.cs index e9b91a19e8..206fe77097 100644 --- a/Jellyfin.Data/Entities/Person.cs +++ b/Jellyfin.Data/Entities/Person.cs @@ -83,7 +83,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -120,7 +120,7 @@ namespace Jellyfin.Data.Entities { Guid value = _UrlId; GetUrlId(ref value); - return (_UrlId = value); + return _UrlId = value; } set @@ -159,7 +159,7 @@ namespace Jellyfin.Data.Entities { string value = _Name; GetName(ref value); - return (_Name = value); + return _Name = value; } set @@ -197,7 +197,7 @@ namespace Jellyfin.Data.Entities { string value = _SourceId; GetSourceId(ref value); - return (_SourceId = value); + return _SourceId = value; } set @@ -234,7 +234,7 @@ namespace Jellyfin.Data.Entities { DateTime value = _DateAdded; GetDateAdded(ref value); - return (_DateAdded = value); + return _DateAdded = value; } internal set @@ -271,7 +271,7 @@ namespace Jellyfin.Data.Entities { DateTime value = _DateModified; GetDateModified(ref value); - return (_DateModified = value); + return _DateModified = value; } internal set diff --git a/Jellyfin.Data/Entities/PersonRole.cs b/Jellyfin.Data/Entities/PersonRole.cs index 2f14044ac2..928eb74aee 100644 --- a/Jellyfin.Data/Entities/PersonRole.cs +++ b/Jellyfin.Data/Entities/PersonRole.cs @@ -89,7 +89,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -127,7 +127,7 @@ namespace Jellyfin.Data.Entities { string value = _Role; GetRole(ref value); - return (_Role = value); + return _Role = value; } set @@ -164,7 +164,7 @@ namespace Jellyfin.Data.Entities { Enums.PersonRoleType value = _Type; GetType(ref value); - return (_Type = value); + return _Type = value; } set diff --git a/Jellyfin.Data/Entities/Rating.cs b/Jellyfin.Data/Entities/Rating.cs index 2c27dbd496..e00d5297db 100644 --- a/Jellyfin.Data/Entities/Rating.cs +++ b/Jellyfin.Data/Entities/Rating.cs @@ -79,7 +79,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -116,7 +116,7 @@ namespace Jellyfin.Data.Entities { double value = _Value; GetValue(ref value); - return (_Value = value); + return _Value = value; } set @@ -149,7 +149,7 @@ namespace Jellyfin.Data.Entities { int? value = _Votes; GetVotes(ref value); - return (_Votes = value); + return _Votes = value; } set diff --git a/Jellyfin.Data/Entities/RatingSource.cs b/Jellyfin.Data/Entities/RatingSource.cs index 2a4bed7ecc..941f53e52a 100644 --- a/Jellyfin.Data/Entities/RatingSource.cs +++ b/Jellyfin.Data/Entities/RatingSource.cs @@ -86,7 +86,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -124,7 +124,7 @@ namespace Jellyfin.Data.Entities { string value = _Name; GetName(ref value); - return (_Name = value); + return _Name = value; } set @@ -161,7 +161,7 @@ namespace Jellyfin.Data.Entities { double value = _MaximumValue; GetMaximumValue(ref value); - return (_MaximumValue = value); + return _MaximumValue = value; } set @@ -198,7 +198,7 @@ namespace Jellyfin.Data.Entities { double value = _MinimumValue; GetMinimumValue(ref value); - return (_MinimumValue = value); + return _MinimumValue = value; } set diff --git a/Jellyfin.Data/Entities/Release.cs b/Jellyfin.Data/Entities/Release.cs index 098a78ca04..e08c04545c 100644 --- a/Jellyfin.Data/Entities/Release.cs +++ b/Jellyfin.Data/Entities/Release.cs @@ -111,7 +111,7 @@ namespace Jellyfin.Data.Entities { int value = _Id; GetId(ref value); - return (_Id = value); + return _Id = value; } protected set @@ -150,7 +150,7 @@ namespace Jellyfin.Data.Entities { string value = _Name; GetName(ref value); - return (_Name = value); + return _Name = value; } set diff --git a/Jellyfin.Data/Entities/Season.cs b/Jellyfin.Data/Entities/Season.cs index 03b3805cfb..d71f4b522b 100644 --- a/Jellyfin.Data/Entities/Season.cs +++ b/Jellyfin.Data/Entities/Season.cs @@ -84,7 +84,7 @@ namespace Jellyfin.Data.Entities { int? value = _SeasonNumber; GetSeasonNumber(ref value); - return (_SeasonNumber = value); + return _SeasonNumber = value; } set diff --git a/Jellyfin.Data/Entities/SeasonMetadata.cs b/Jellyfin.Data/Entities/SeasonMetadata.cs index 35ff6e89ab..8659383385 100644 --- a/Jellyfin.Data/Entities/SeasonMetadata.cs +++ b/Jellyfin.Data/Entities/SeasonMetadata.cs @@ -84,7 +84,7 @@ namespace Jellyfin.Data.Entities { string value = _Outline; GetOutline(ref value); - return (_Outline = value); + return _Outline = value; } set diff --git a/Jellyfin.Data/Entities/Series.cs b/Jellyfin.Data/Entities/Series.cs index 69b1854ab3..bede14acfb 100644 --- a/Jellyfin.Data/Entities/Series.cs +++ b/Jellyfin.Data/Entities/Series.cs @@ -65,7 +65,7 @@ namespace Jellyfin.Data.Entities { DayOfWeek? value = _AirsDayOfWeek; GetAirsDayOfWeek(ref value); - return (_AirsDayOfWeek = value); + return _AirsDayOfWeek = value; } set @@ -101,7 +101,7 @@ namespace Jellyfin.Data.Entities { DateTimeOffset? value = _AirsTime; GetAirsTime(ref value); - return (_AirsTime = value); + return _AirsTime = value; } set @@ -134,7 +134,7 @@ namespace Jellyfin.Data.Entities { DateTimeOffset? value = _FirstAired; GetFirstAired(ref value); - return (_FirstAired = value); + return _FirstAired = value; } set diff --git a/Jellyfin.Data/Entities/SeriesMetadata.cs b/Jellyfin.Data/Entities/SeriesMetadata.cs index e72de07fd4..bb7426754c 100644 --- a/Jellyfin.Data/Entities/SeriesMetadata.cs +++ b/Jellyfin.Data/Entities/SeriesMetadata.cs @@ -88,7 +88,7 @@ namespace Jellyfin.Data.Entities { string value = _Outline; GetOutline(ref value); - return (_Outline = value); + return _Outline = value; } set @@ -126,7 +126,7 @@ namespace Jellyfin.Data.Entities { string value = _Plot; GetPlot(ref value); - return (_Plot = value); + return _Plot = value; } set @@ -164,7 +164,7 @@ namespace Jellyfin.Data.Entities { string value = _Tagline; GetTagline(ref value); - return (_Tagline = value); + return _Tagline = value; } set @@ -202,7 +202,7 @@ namespace Jellyfin.Data.Entities { string value = _Country; GetCountry(ref value); - return (_Country = value); + return _Country = value; } set diff --git a/Jellyfin.Data/Entities/Track.cs b/Jellyfin.Data/Entities/Track.cs index 59a9eb4af2..e13a53d382 100644 --- a/Jellyfin.Data/Entities/Track.cs +++ b/Jellyfin.Data/Entities/Track.cs @@ -84,7 +84,7 @@ namespace Jellyfin.Data.Entities { int? value = _TrackNumber; GetTrackNumber(ref value); - return (_TrackNumber = value); + return _TrackNumber = value; } set diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 5c02bd2b54..5c6a9d2a28 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -225,7 +225,7 @@ namespace MediaBrowser.Controller.Entities return null; } - return (totalProgresses / foldersWithProgress); + return totalProgresses / foldersWithProgress; } protected override bool RefreshLinkedChildren(IEnumerable fileSystemChildren) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index d4fa8f9b30..6441340f97 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -480,7 +480,7 @@ namespace MediaBrowser.Controller.Entities innerProgress.RegisterAction(p => { double innerPercent = currentInnerPercent; - innerPercent += p / (count); + innerPercent += p / count; progress.Report(innerPercent); }); @@ -556,7 +556,7 @@ namespace MediaBrowser.Controller.Entities innerProgress.RegisterAction(p => { double innerPercent = currentInnerPercent; - innerPercent += p / (count); + innerPercent += p / count; progress.Report(innerPercent); }); diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index 92473eaa18..1516bb1e9b 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -42,7 +42,7 @@ namespace MediaBrowser.Controller.Library public LibraryOptions GetLibraryOptions() { - return LibraryOptions ?? (LibraryOptions = (Parent == null ? new LibraryOptions() : BaseItem.LibraryManager.GetLibraryOptions(Parent))); + return LibraryOptions ?? (LibraryOptions = Parent == null ? new LibraryOptions() : BaseItem.LibraryManager.GetLibraryOptions(Parent)); } /// diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index a3920d26f3..6f03d33aec 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -391,7 +391,7 @@ namespace MediaBrowser.Providers.Manager { if (!child.IsFolder) { - ticks += (child.RunTimeTicks ?? 0); + ticks += child.RunTimeTicks ?? 0; } } -- cgit v1.2.3 From 8de6452967d229624c81e06d992b1cb0cb6715b1 Mon Sep 17 00:00:00 2001 From: telans Date: Fri, 19 Jun 2020 22:21:49 +1200 Subject: fix some documentation periods --- Emby.Server.Implementations/Data/SqliteItemRepository.cs | 2 +- Emby.Server.Implementations/Library/LibraryManager.cs | 4 ++-- .../Library/Resolvers/TV/SeasonResolver.cs | 4 ++-- Emby.Server.Implementations/ScheduledTasks/TaskManager.cs | 2 +- Jellyfin.Data/Entities/BookMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/Chapter.cs | 4 ++-- Jellyfin.Data/Entities/CompanyMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/CustomItemMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/EpisodeMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/Group.cs | 2 +- Jellyfin.Data/Entities/LibraryRoot.cs | 4 ++-- Jellyfin.Data/Entities/MediaFile.cs | 4 ++-- Jellyfin.Data/Entities/Metadata.cs | 4 ++-- Jellyfin.Data/Entities/MovieMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/MusicAlbumMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/PhotoMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/SeasonMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/SeriesMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/TrackMetadata.cs | 8 ++++---- MediaBrowser.Controller/Drawing/IImageProcessor.cs | 6 +++--- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- MediaBrowser.Controller/Net/AuthenticatedAttribute.cs | 6 +++--- MediaBrowser.Controller/Net/SecurityException.cs | 2 +- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 2 +- MediaBrowser.Model/Services/QueryParamCollection.cs | 4 ++-- MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs | 2 +- 26 files changed, 67 insertions(+), 67 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index da37a8c866..6e5389ad4f 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -6308,7 +6308,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type /// Gets the attachment. /// /// The reader. - /// MediaAttachment + /// MediaAttachment. private MediaAttachment GetMediaAttachment(IReadOnlyList reader) { var item = new MediaAttachment diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 893af4cae2..edb58e9102 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -136,7 +136,7 @@ namespace Emby.Server.Implementations.Library /// /// Initializes a new instance of the class. /// - /// The application host + /// The application host. /// The logger. /// The task manager. /// The user manager. @@ -1793,7 +1793,7 @@ namespace Emby.Server.Implementations.Library /// Creates the items. /// /// The items. - /// The parent item + /// The parent item. /// The cancellation token. public void CreateItems(IEnumerable items, BaseItem parent, CancellationToken cancellationToken) { diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs index c43a0ec6b2..c8e41001ab 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs @@ -23,8 +23,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV /// /// The config. /// The library manager. - /// The localization - /// The logger + /// The localization. + /// The logger. public SeasonResolver( IServerConfigurationManager config, ILibraryManager libraryManager, diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs index 0ad4253e4b..3fe15ec687 100644 --- a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs +++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs @@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.ScheduledTasks /// Queues the scheduled task. /// /// - /// Task options + /// Task options. public void QueueScheduledTask(TaskOptions options) where T : IScheduledTask { diff --git a/Jellyfin.Data/Entities/BookMetadata.cs b/Jellyfin.Data/Entities/BookMetadata.cs index 914eda0642..dc71463719 100644 --- a/Jellyfin.Data/Entities/BookMetadata.cs +++ b/Jellyfin.Data/Entities/BookMetadata.cs @@ -29,8 +29,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public BookMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Book _book0) { @@ -51,8 +51,8 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public static BookMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Book _book0) { diff --git a/Jellyfin.Data/Entities/Chapter.cs b/Jellyfin.Data/Entities/Chapter.cs index 77685add6e..960853e151 100644 --- a/Jellyfin.Data/Entities/Chapter.cs +++ b/Jellyfin.Data/Entities/Chapter.cs @@ -27,7 +27,7 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// ISO-639-3 3-character language codes + /// ISO-639-3 3-character language codes. /// /// public Chapter(string language, long timestart, Release _release0) @@ -47,7 +47,7 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// ISO-639-3 3-character language codes + /// ISO-639-3 3-character language codes. /// /// public static Chapter Create(string language, long timestart, Release _release0) diff --git a/Jellyfin.Data/Entities/CompanyMetadata.cs b/Jellyfin.Data/Entities/CompanyMetadata.cs index 695c7f0965..12f2133104 100644 --- a/Jellyfin.Data/Entities/CompanyMetadata.cs +++ b/Jellyfin.Data/Entities/CompanyMetadata.cs @@ -26,8 +26,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public CompanyMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Company _company0) { @@ -47,8 +47,8 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public static CompanyMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Company _company0) { diff --git a/Jellyfin.Data/Entities/CustomItemMetadata.cs b/Jellyfin.Data/Entities/CustomItemMetadata.cs index b81408aa68..dd66c8f832 100644 --- a/Jellyfin.Data/Entities/CustomItemMetadata.cs +++ b/Jellyfin.Data/Entities/CustomItemMetadata.cs @@ -25,8 +25,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public CustomItemMetadata(string title, string language, DateTime dateadded, DateTime datemodified, CustomItem _customitem0) { @@ -46,8 +46,8 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public static CustomItemMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, CustomItem _customitem0) { diff --git a/Jellyfin.Data/Entities/EpisodeMetadata.cs b/Jellyfin.Data/Entities/EpisodeMetadata.cs index da5ea43ccd..b17e4aa19f 100644 --- a/Jellyfin.Data/Entities/EpisodeMetadata.cs +++ b/Jellyfin.Data/Entities/EpisodeMetadata.cs @@ -26,8 +26,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public EpisodeMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Episode _episode0) { @@ -47,8 +47,8 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public static EpisodeMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Episode _episode0) { diff --git a/Jellyfin.Data/Entities/Group.cs b/Jellyfin.Data/Entities/Group.cs index 5cbb126f9d..47833378e8 100644 --- a/Jellyfin.Data/Entities/Group.cs +++ b/Jellyfin.Data/Entities/Group.cs @@ -99,7 +99,7 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The name of this group + /// The name of this group. public static Group Create(string name) { return new Group(name); diff --git a/Jellyfin.Data/Entities/LibraryRoot.cs b/Jellyfin.Data/Entities/LibraryRoot.cs index 16fbc92f6e..a6f3e49c9d 100644 --- a/Jellyfin.Data/Entities/LibraryRoot.cs +++ b/Jellyfin.Data/Entities/LibraryRoot.cs @@ -27,7 +27,7 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// Absolute Path + /// Absolute Path. public LibraryRoot(string path) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); @@ -40,7 +40,7 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// Absolute Path + /// Absolute Path. public static LibraryRoot Create(string path) { return new LibraryRoot(path); diff --git a/Jellyfin.Data/Entities/MediaFile.cs b/Jellyfin.Data/Entities/MediaFile.cs index 8201eed526..5d9448d41e 100644 --- a/Jellyfin.Data/Entities/MediaFile.cs +++ b/Jellyfin.Data/Entities/MediaFile.cs @@ -30,7 +30,7 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// Relative to the LibraryRoot + /// Relative to the LibraryRoot. /// /// public MediaFile(string path, Enums.MediaFileKind kind, Release _release0) @@ -51,7 +51,7 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// Relative to the LibraryRoot + /// Relative to the LibraryRoot. /// /// public static MediaFile Create(string path, Enums.MediaFileKind kind, Release _release0) diff --git a/Jellyfin.Data/Entities/Metadata.cs b/Jellyfin.Data/Entities/Metadata.cs index 146c70a10d..8446c30b2f 100644 --- a/Jellyfin.Data/Entities/Metadata.cs +++ b/Jellyfin.Data/Entities/Metadata.cs @@ -26,8 +26,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. protected Metadata(string title, string language, DateTime dateadded, DateTime datemodified) { if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); diff --git a/Jellyfin.Data/Entities/MovieMetadata.cs b/Jellyfin.Data/Entities/MovieMetadata.cs index 48584dd13c..4fda88e8e2 100644 --- a/Jellyfin.Data/Entities/MovieMetadata.cs +++ b/Jellyfin.Data/Entities/MovieMetadata.cs @@ -30,8 +30,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public MovieMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Movie _movie0) { @@ -52,8 +52,8 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public static MovieMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Movie _movie0) { diff --git a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs b/Jellyfin.Data/Entities/MusicAlbumMetadata.cs index 5847101ca3..a5056adc01 100644 --- a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs +++ b/Jellyfin.Data/Entities/MusicAlbumMetadata.cs @@ -30,8 +30,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public MusicAlbumMetadata(string title, string language, DateTime dateadded, DateTime datemodified, MusicAlbum _musicalbum0) { @@ -52,8 +52,8 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public static MusicAlbumMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, MusicAlbum _musicalbum0) { diff --git a/Jellyfin.Data/Entities/PhotoMetadata.cs b/Jellyfin.Data/Entities/PhotoMetadata.cs index 5a9cf5b66a..4a0b07ff83 100644 --- a/Jellyfin.Data/Entities/PhotoMetadata.cs +++ b/Jellyfin.Data/Entities/PhotoMetadata.cs @@ -26,8 +26,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public PhotoMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Photo _photo0) { @@ -47,8 +47,8 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public static PhotoMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Photo _photo0) { diff --git a/Jellyfin.Data/Entities/SeasonMetadata.cs b/Jellyfin.Data/Entities/SeasonMetadata.cs index 8659383385..8c72d99528 100644 --- a/Jellyfin.Data/Entities/SeasonMetadata.cs +++ b/Jellyfin.Data/Entities/SeasonMetadata.cs @@ -27,8 +27,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public SeasonMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Season _season0) { @@ -48,8 +48,8 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public static SeasonMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Season _season0) { diff --git a/Jellyfin.Data/Entities/SeriesMetadata.cs b/Jellyfin.Data/Entities/SeriesMetadata.cs index bb7426754c..2c04ef12fd 100644 --- a/Jellyfin.Data/Entities/SeriesMetadata.cs +++ b/Jellyfin.Data/Entities/SeriesMetadata.cs @@ -30,8 +30,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public SeriesMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Series _series0) { @@ -52,8 +52,8 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public static SeriesMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Series _series0) { diff --git a/Jellyfin.Data/Entities/TrackMetadata.cs b/Jellyfin.Data/Entities/TrackMetadata.cs index 05bb953f8e..55f4a38e01 100644 --- a/Jellyfin.Data/Entities/TrackMetadata.cs +++ b/Jellyfin.Data/Entities/TrackMetadata.cs @@ -26,8 +26,8 @@ namespace Jellyfin.Data.Entities /// /// Public constructor with required data. /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public TrackMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Track _track0) { @@ -47,8 +47,8 @@ namespace Jellyfin.Data.Entities /// /// Static create function (for use in LINQ queries, etc.) /// - /// The title or name of the object - /// ISO-639-3 3-character language codes + /// The title or name of the object. + /// ISO-639-3 3-character language codes. /// public static TrackMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Track _track0) { diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs index 488692c036..69d7991652 100644 --- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -30,7 +30,7 @@ namespace MediaBrowser.Controller.Drawing /// Gets the dimensions of the image. /// /// Path to the image file. - /// ImageDimensions + /// ImageDimensions. ImageDimensions GetImageDimensions(string path); /// @@ -38,14 +38,14 @@ namespace MediaBrowser.Controller.Drawing /// /// The base item. /// The information. - /// ImageDimensions + /// ImageDimensions. ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info); /// /// Gets the blurhash of the image. /// /// Path to the image file. - /// BlurHash + /// BlurHash. string GetImageBlurHash(string path); /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index d76409afc8..7b833c36b0 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1371,7 +1371,7 @@ namespace MediaBrowser.Controller.Entities /// /// The options. /// The cancellation token. - /// true if a provider reports we changed + /// true if a provider reports we changed. public async Task RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken) { TriggerOnRefreshStart(); diff --git a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs index ba3c715b88..ad786f97bc 100644 --- a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs +++ b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs @@ -31,9 +31,9 @@ namespace MediaBrowser.Controller.Net /// /// The request filter is executed before the service. /// - /// The http request wrapper - /// The http response wrapper - /// The request DTO + /// The http request wrapper. + /// The http response wrapper. + /// The request DTO. public void RequestFilter(IRequest request, HttpResponse response, object requestDto) { AuthService.Authenticate(request, this); diff --git a/MediaBrowser.Controller/Net/SecurityException.cs b/MediaBrowser.Controller/Net/SecurityException.cs index a5b94ea5e3..f0d0b45a0a 100644 --- a/MediaBrowser.Controller/Net/SecurityException.cs +++ b/MediaBrowser.Controller/Net/SecurityException.cs @@ -27,7 +27,7 @@ namespace MediaBrowser.Controller.Net /// /// Initializes a new instance of the class. /// - /// The message that describes the error + /// The message that describes the error. /// The exception that is the cause of the current exception, or a null reference if no inner exception is specified. public SecurityException(string message, Exception innerException) : base(message, innerException) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 1183e9fb2e..9397a347f3 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -166,7 +166,7 @@ namespace MediaBrowser.MediaEncoding.Encoder /// Validates the supplied FQPN to ensure it is a ffmpeg utility. /// If checks pass, global variable FFmpegPath and EncoderLocation are updated. /// - /// FQPN to test + /// FQPN to test. /// Location (External, Custom, System) of tool /// private bool ValidatePath(string path, FFmpegLocation location) diff --git a/MediaBrowser.Model/Services/QueryParamCollection.cs b/MediaBrowser.Model/Services/QueryParamCollection.cs index d07ff15482..bdb0cabdf2 100644 --- a/MediaBrowser.Model/Services/QueryParamCollection.cs +++ b/MediaBrowser.Model/Services/QueryParamCollection.cs @@ -124,8 +124,8 @@ namespace MediaBrowser.Model.Services /// Gets or sets a query parameter value by name. A query may contain multiple values of the same name /// (i.e. "x=1&x=2"), in which case the value is an array, which works for both getting and setting. /// - /// The query parameter name - /// The query parameter value or array of values + /// The query parameter name. + /// The query parameter value or array of values. public string this[string name] { get => Get(name); diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs index 3c0922f39b..1961e8bff9 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs @@ -312,7 +312,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies /// The id. /// if set to true [is TMDB identifier]. /// The language. - /// The cancellation token + /// The cancellation token. /// Task{CompleteMovieData}. internal async Task FetchMainResult(string id, bool isTmdbId, string language, CancellationToken cancellationToken) { -- cgit v1.2.3 From 98db8f72e01b608e6c384ecf5b107fc2d105b652 Mon Sep 17 00:00:00 2001 From: telans Date: Sat, 20 Jun 2020 20:35:29 +1200 Subject: fix SA1503 for one line if statements --- DvdLib/Ifo/Dvd.cs | 16 +++- DvdLib/Ifo/DvdTime.cs | 10 ++- DvdLib/Ifo/ProgramChain.cs | 11 ++- DvdLib/Ifo/Title.cs | 5 +- Emby.Dlna/PlayTo/PlayToManager.cs | 10 ++- .../Data/SqliteItemRepository.cs | 95 ++++++++++++++++++---- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 9 +- Emby.Server.Implementations/Net/UdpSocket.cs | 10 ++- .../Playlists/PlaylistManager.cs | 12 ++- .../Services/ServiceController.cs | 5 +- .../Services/ServiceExec.cs | 5 +- .../Services/ServicePath.cs | 5 +- Jellyfin.Data/Entities/Artwork.cs | 19 ++++- Jellyfin.Data/Entities/BookMetadata.cs | 18 +++- Jellyfin.Data/Entities/Chapter.cs | 12 ++- Jellyfin.Data/Entities/CollectionItem.cs | 19 ++++- Jellyfin.Data/Entities/Company.cs | 30 +++++-- Jellyfin.Data/Entities/CompanyMetadata.cs | 19 ++++- Jellyfin.Data/Entities/CustomItemMetadata.cs | 19 ++++- Jellyfin.Data/Entities/Episode.cs | 6 +- Jellyfin.Data/Entities/EpisodeMetadata.cs | 19 ++++- Jellyfin.Data/Entities/Genre.cs | 13 ++- Jellyfin.Data/Entities/Library.cs | 7 +- Jellyfin.Data/Entities/LibraryRoot.cs | 7 +- Jellyfin.Data/Entities/MediaFile.cs | 12 ++- Jellyfin.Data/Entities/MediaFileStream.cs | 7 +- Jellyfin.Data/Entities/Metadata.cs | 12 ++- Jellyfin.Data/Entities/MetadataProvider.cs | 7 +- Jellyfin.Data/Entities/MetadataProviderId.cs | 31 +++++-- Jellyfin.Data/Entities/MovieMetadata.cs | 18 +++- Jellyfin.Data/Entities/MusicAlbumMetadata.cs | 18 +++- Jellyfin.Data/Entities/Person.cs | 6 +- Jellyfin.Data/Entities/PersonRole.cs | 6 +- Jellyfin.Data/Entities/PhotoMetadata.cs | 19 ++++- Jellyfin.Data/Entities/ProviderMapping.cs | 19 ++++- Jellyfin.Data/Entities/Rating.cs | 7 +- Jellyfin.Data/Entities/RatingSource.cs | 7 +- Jellyfin.Data/Entities/Release.cs | 42 ++++++++-- Jellyfin.Data/Entities/Season.cs | 6 +- Jellyfin.Data/Entities/SeasonMetadata.cs | 19 ++++- Jellyfin.Data/Entities/SeriesMetadata.cs | 18 +++- Jellyfin.Data/Entities/Track.cs | 6 +- Jellyfin.Data/Entities/TrackMetadata.cs | 19 ++++- MediaBrowser.Controller/Entities/BaseItem.cs | 5 +- MediaBrowser.Controller/Library/ItemResolveArgs.cs | 6 +- .../Probing/ProbeResultNormalizer.cs | 30 +++++-- MediaBrowser.Model/Dlna/StreamBuilder.cs | 5 +- MediaBrowser.Model/Entities/MediaStream.cs | 5 +- MediaBrowser.Model/Services/RouteAttribute.cs | 18 +++- .../Manager/ItemImageProvider.cs | 5 +- .../Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs | 5 +- .../Plugins/Tmdb/Movies/TmdbMovieProvider.cs | 5 +- RSSDP/DeviceAvailableEventArgs.cs | 5 +- RSSDP/DeviceEventArgs.cs | 5 +- RSSDP/DeviceUnavailableEventArgs.cs | 5 +- RSSDP/DisposableManagedObjectBase.cs | 5 +- RSSDP/HttpParserBase.cs | 27 ++++-- RSSDP/HttpRequestParser.cs | 16 +++- RSSDP/HttpResponseParser.cs | 16 +++- RSSDP/IEnumerableExtensions.cs | 11 ++- RSSDP/SsdpCommunicationsServer.cs | 21 ++++- RSSDP/SsdpDevice.cs | 22 ++++- RSSDP/SsdpDeviceLocator.cs | 84 +++++++++++++++---- RSSDP/SsdpDevicePublisher.cs | 75 ++++++++++++++--- 64 files changed, 843 insertions(+), 193 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/DvdLib/Ifo/Dvd.cs b/DvdLib/Ifo/Dvd.cs index ca20baa73f..361319625c 100644 --- a/DvdLib/Ifo/Dvd.cs +++ b/DvdLib/Ifo/Dvd.cs @@ -117,12 +117,19 @@ namespace DvdLib.Ifo uint chapNum = 1; vtsFs.Seek(baseAddr + offsets[titleNum], SeekOrigin.Begin); var t = Titles.FirstOrDefault(vtst => vtst.IsVTSTitle(vtsNum, titleNum + 1)); - if (t == null) continue; + if (t == null) + { + continue; + } do { t.Chapters.Add(new Chapter(vtsRead.ReadUInt16(), vtsRead.ReadUInt16(), chapNum)); - if (titleNum + 1 < numTitles && vtsFs.Position == (baseAddr + offsets[titleNum + 1])) break; + if (titleNum + 1 < numTitles && vtsFs.Position == (baseAddr + offsets[titleNum + 1])) + { + break; + } + chapNum++; } while (vtsFs.Position < (baseAddr + endaddr)); @@ -147,7 +154,10 @@ namespace DvdLib.Ifo uint vtsPgcOffset = vtsRead.ReadUInt32(); var t = Titles.FirstOrDefault(vtst => vtst.IsVTSTitle(vtsNum, titleNum)); - if (t != null) t.AddPgc(vtsRead, startByte + vtsPgcOffset, entryPgc, pgcNum); + if (t != null) + { + t.AddPgc(vtsRead, startByte + vtsPgcOffset, entryPgc, pgcNum); + } } } } diff --git a/DvdLib/Ifo/DvdTime.cs b/DvdLib/Ifo/DvdTime.cs index 978af90c2e..d231406106 100644 --- a/DvdLib/Ifo/DvdTime.cs +++ b/DvdLib/Ifo/DvdTime.cs @@ -15,8 +15,14 @@ namespace DvdLib.Ifo Second = GetBCDValue(data[2]); Frames = GetBCDValue((byte)(data[3] & 0x3F)); - if ((data[3] & 0x80) != 0) FrameRate = 30; - else if ((data[3] & 0x40) != 0) FrameRate = 25; + if ((data[3] & 0x80) != 0) + { + FrameRate = 30; + } + else if ((data[3] & 0x40) != 0) + { + FrameRate = 25; + } } private static byte GetBCDValue(byte data) diff --git a/DvdLib/Ifo/ProgramChain.cs b/DvdLib/Ifo/ProgramChain.cs index 8048f4bbd6..83c0051b90 100644 --- a/DvdLib/Ifo/ProgramChain.cs +++ b/DvdLib/Ifo/ProgramChain.cs @@ -75,8 +75,15 @@ namespace DvdLib.Ifo StillTime = br.ReadByte(); byte pbMode = br.ReadByte(); - if (pbMode == 0) PlaybackMode = ProgramPlaybackMode.Sequential; - else PlaybackMode = ((pbMode & 0x80) == 0) ? ProgramPlaybackMode.Random : ProgramPlaybackMode.Shuffle; + if (pbMode == 0) + { + PlaybackMode = ProgramPlaybackMode.Sequential; + } + else + { + PlaybackMode = ((pbMode & 0x80) == 0) ? ProgramPlaybackMode.Random : ProgramPlaybackMode.Shuffle; + } + ProgramCount = (uint)(pbMode & 0x7F); Palette = br.ReadBytes(64); diff --git a/DvdLib/Ifo/Title.cs b/DvdLib/Ifo/Title.cs index 4af3af754a..29a0b95c72 100644 --- a/DvdLib/Ifo/Title.cs +++ b/DvdLib/Ifo/Title.cs @@ -59,7 +59,10 @@ namespace DvdLib.Ifo var pgc = new ProgramChain(pgcNum); pgc.ParseHeader(br); ProgramChains.Add(pgc); - if (entryPgc) EntryProgramChain = pgc; + if (entryPgc) + { + EntryProgramChain = pgc; + } br.BaseStream.Seek(curPos, SeekOrigin.Begin); } diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index 240c8a7d98..512589e4d7 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -78,9 +78,15 @@ namespace Emby.Dlna.PlayTo var info = e.Argument; - if (!info.Headers.TryGetValue("USN", out string usn)) usn = string.Empty; + if (!info.Headers.TryGetValue("USN", out string usn)) + { + usn = string.Empty; + } - if (!info.Headers.TryGetValue("NT", out string nt)) nt = string.Empty; + if (!info.Headers.TryGetValue("NT", out string nt)) + { + nt = string.Empty; + } string location = info.Location.ToString(); diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 6e5389ad4f..a6390b1ef2 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -2775,22 +2775,85 @@ namespace Emby.Server.Implementations.Data private string FixUnicodeChars(string buffer) { - if (buffer.IndexOf('\u2013') > -1) buffer = buffer.Replace('\u2013', '-'); // en dash - if (buffer.IndexOf('\u2014') > -1) buffer = buffer.Replace('\u2014', '-'); // em dash - if (buffer.IndexOf('\u2015') > -1) buffer = buffer.Replace('\u2015', '-'); // horizontal bar - if (buffer.IndexOf('\u2017') > -1) buffer = buffer.Replace('\u2017', '_'); // double low line - if (buffer.IndexOf('\u2018') > -1) buffer = buffer.Replace('\u2018', '\''); // left single quotation mark - if (buffer.IndexOf('\u2019') > -1) buffer = buffer.Replace('\u2019', '\''); // right single quotation mark - if (buffer.IndexOf('\u201a') > -1) buffer = buffer.Replace('\u201a', ','); // single low-9 quotation mark - if (buffer.IndexOf('\u201b') > -1) buffer = buffer.Replace('\u201b', '\''); // single high-reversed-9 quotation mark - if (buffer.IndexOf('\u201c') > -1) buffer = buffer.Replace('\u201c', '\"'); // left double quotation mark - if (buffer.IndexOf('\u201d') > -1) buffer = buffer.Replace('\u201d', '\"'); // right double quotation mark - if (buffer.IndexOf('\u201e') > -1) buffer = buffer.Replace('\u201e', '\"'); // double low-9 quotation mark - if (buffer.IndexOf('\u2026') > -1) buffer = buffer.Replace("\u2026", "..."); // horizontal ellipsis - if (buffer.IndexOf('\u2032') > -1) buffer = buffer.Replace('\u2032', '\''); // prime - if (buffer.IndexOf('\u2033') > -1) buffer = buffer.Replace('\u2033', '\"'); // double prime - if (buffer.IndexOf('\u0060') > -1) buffer = buffer.Replace('\u0060', '\''); // grave accent - if (buffer.IndexOf('\u00B4') > -1) buffer = buffer.Replace('\u00B4', '\''); // acute accent + if (buffer.IndexOf('\u2013') > -1) + { + buffer = buffer.Replace('\u2013', '-'); // en dash + } + + if (buffer.IndexOf('\u2014') > -1) + { + buffer = buffer.Replace('\u2014', '-'); // em dash + } + + if (buffer.IndexOf('\u2015') > -1) + { + buffer = buffer.Replace('\u2015', '-'); // horizontal bar + } + + if (buffer.IndexOf('\u2017') > -1) + { + buffer = buffer.Replace('\u2017', '_'); // double low line + } + + if (buffer.IndexOf('\u2018') > -1) + { + buffer = buffer.Replace('\u2018', '\''); // left single quotation mark + } + + if (buffer.IndexOf('\u2019') > -1) + { + buffer = buffer.Replace('\u2019', '\''); // right single quotation mark + } + + if (buffer.IndexOf('\u201a') > -1) + { + buffer = buffer.Replace('\u201a', ','); // single low-9 quotation mark + } + + if (buffer.IndexOf('\u201b') > -1) + { + buffer = buffer.Replace('\u201b', '\''); // single high-reversed-9 quotation mark + } + + if (buffer.IndexOf('\u201c') > -1) + { + buffer = buffer.Replace('\u201c', '\"'); // left double quotation mark + } + + if (buffer.IndexOf('\u201d') > -1) + { + buffer = buffer.Replace('\u201d', '\"'); // right double quotation mark + } + + if (buffer.IndexOf('\u201e') > -1) + { + buffer = buffer.Replace('\u201e', '\"'); // double low-9 quotation mark + } + + if (buffer.IndexOf('\u2026') > -1) + { + buffer = buffer.Replace("\u2026", "..."); // horizontal ellipsis + } + + if (buffer.IndexOf('\u2032') > -1) + { + buffer = buffer.Replace('\u2032', '\''); // prime + } + + if (buffer.IndexOf('\u2033') > -1) + { + buffer = buffer.Replace('\u2033', '\"'); // double prime + } + + if (buffer.IndexOf('\u0060') > -1) + { + buffer = buffer.Replace('\u0060', '\''); // grave accent + } + + if (buffer.IndexOf('\u00B4') > -1) + { + buffer = buffer.Replace('\u00B4', '\''); // acute accent + } return buffer; } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index db9d240281..2e2488e6ec 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -201,7 +201,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun var index = line.IndexOf("Channel", StringComparison.OrdinalIgnoreCase); var name = line.Substring(0, index - 1); var currentChannel = line.Substring(index + 7); - if (currentChannel != "none") { status = LiveTvTunerStatus.LiveTv; } else { status = LiveTvTunerStatus.Available; } + if (currentChannel != "none") + { + status = LiveTvTunerStatus.LiveTv; + } + else + { + status = LiveTvTunerStatus.Available; + } tuners.Add(new LiveTvTunerInfo { diff --git a/Emby.Server.Implementations/Net/UdpSocket.cs b/Emby.Server.Implementations/Net/UdpSocket.cs index 848f82d855..b51c034460 100644 --- a/Emby.Server.Implementations/Net/UdpSocket.cs +++ b/Emby.Server.Implementations/Net/UdpSocket.cs @@ -37,7 +37,10 @@ namespace Emby.Server.Implementations.Net public UdpSocket(Socket socket, int localPort, IPAddress ip) { - if (socket == null) throw new ArgumentNullException(nameof(socket)); + if (socket == null) + { + throw new ArgumentNullException(nameof(socket)); + } _socket = socket; _localPort = localPort; @@ -103,7 +106,10 @@ namespace Emby.Server.Implementations.Net public UdpSocket(Socket socket, IPEndPoint endPoint) { - if (socket == null) throw new ArgumentNullException(nameof(socket)); + if (socket == null) + { + throw new ArgumentNullException(nameof(socket)); + } _socket = socket; _socket.Connect(endPoint); diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs index ac816ccd93..5dd1af4b87 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -539,13 +539,21 @@ namespace Emby.Server.Implementations.Playlists private static string UnEscape(string content) { - if (content == null) return content; + if (content == null) + { + return content; + } + return content.Replace("&", "&").Replace("'", "'").Replace(""", "\"").Replace(">", ">").Replace("<", "<"); } private static string Escape(string content) { - if (content == null) return null; + if (content == null) + { + return null; + } + return content.Replace("&", "&").Replace("'", "'").Replace("\"", """).Replace(">", ">").Replace("<", "<"); } diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs index b84e471401..857df591a1 100644 --- a/Emby.Server.Implementations/Services/ServiceController.cs +++ b/Emby.Server.Implementations/Services/ServiceController.cs @@ -144,7 +144,10 @@ namespace Emby.Server.Implementations.Services var yieldedWildcardMatches = RestPath.GetFirstMatchWildCardHashKeys(matchUsingPathParts); foreach (var potentialHashMatch in yieldedWildcardMatches) { - if (!this.RestPathMap.TryGetValue(potentialHashMatch, out firstMatches)) continue; + if (!this.RestPathMap.TryGetValue(potentialHashMatch, out firstMatches)) + { + continue; + } var bestScore = -1; RestPath bestMatch = null; diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs index 606f2a2405..18d7ab46e7 100644 --- a/Emby.Server.Implementations/Services/ServiceExec.cs +++ b/Emby.Server.Implementations/Services/ServiceExec.cs @@ -63,7 +63,10 @@ namespace Emby.Server.Implementations.Services { foreach (var actionCtx in actions) { - if (execMap.ContainsKey(actionCtx.Id)) continue; + if (execMap.ContainsKey(actionCtx.Id)) + { + continue; + } execMap[actionCtx.Id] = actionCtx; } diff --git a/Emby.Server.Implementations/Services/ServicePath.cs b/Emby.Server.Implementations/Services/ServicePath.cs index 14ae126a33..eb07441893 100644 --- a/Emby.Server.Implementations/Services/ServicePath.cs +++ b/Emby.Server.Implementations/Services/ServicePath.cs @@ -124,7 +124,10 @@ namespace Emby.Server.Implementations.Services var hasSeparators = new List(); foreach (var component in this.restPath.Split(PathSeperatorChar)) { - if (string.IsNullOrEmpty(component)) continue; + if (string.IsNullOrEmpty(component)) + { + continue; + } if (component.IndexOf(VariablePrefix, StringComparison.OrdinalIgnoreCase) != -1 && component.IndexOf(ComponentSeperator) != -1) diff --git a/Jellyfin.Data/Entities/Artwork.cs b/Jellyfin.Data/Entities/Artwork.cs index df071e477b..6ed32eac33 100644 --- a/Jellyfin.Data/Entities/Artwork.cs +++ b/Jellyfin.Data/Entities/Artwork.cs @@ -32,17 +32,28 @@ namespace Jellyfin.Data.Entities /// public Artwork(string path, Enums.ArtKind kind, Metadata _metadata0, PersonRole _personrole1) { - if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException(nameof(path)); + } + this.Path = path; this.Kind = kind; - if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); + if (_metadata0 == null) + { + throw new ArgumentNullException(nameof(_metadata0)); + } + _metadata0.Artwork.Add(this); - if (_personrole1 == null) throw new ArgumentNullException(nameof(_personrole1)); - _personrole1.Artwork = this; + if (_personrole1 == null) + { + throw new ArgumentNullException(nameof(_personrole1)); + } + _personrole1.Artwork = this; Init(); } diff --git a/Jellyfin.Data/Entities/BookMetadata.cs b/Jellyfin.Data/Entities/BookMetadata.cs index dc71463719..df43090d3d 100644 --- a/Jellyfin.Data/Entities/BookMetadata.cs +++ b/Jellyfin.Data/Entities/BookMetadata.cs @@ -34,13 +34,25 @@ namespace Jellyfin.Data.Entities /// public BookMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Book _book0) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; - if (_book0 == null) throw new ArgumentNullException(nameof(_book0)); + if (_book0 == null) + { + throw new ArgumentNullException(nameof(_book0)); + } + _book0.BookMetadata.Add(this); this.Publishers = new HashSet(); diff --git a/Jellyfin.Data/Entities/Chapter.cs b/Jellyfin.Data/Entities/Chapter.cs index 960853e151..4575cdb4d7 100644 --- a/Jellyfin.Data/Entities/Chapter.cs +++ b/Jellyfin.Data/Entities/Chapter.cs @@ -32,12 +32,20 @@ namespace Jellyfin.Data.Entities /// public Chapter(string language, long timestart, Release _release0) { - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; this.TimeStart = timestart; - if (_release0 == null) throw new ArgumentNullException(nameof(_release0)); + if (_release0 == null) + { + throw new ArgumentNullException(nameof(_release0)); + } + _release0.Chapters.Add(this); diff --git a/Jellyfin.Data/Entities/CollectionItem.cs b/Jellyfin.Data/Entities/CollectionItem.cs index 08b0e99f41..d879806ee6 100644 --- a/Jellyfin.Data/Entities/CollectionItem.cs +++ b/Jellyfin.Data/Entities/CollectionItem.cs @@ -38,15 +38,26 @@ namespace Jellyfin.Data.Entities // NOTE: This class has one-to-one associations with CollectionItem. // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - if (_collection0 == null) throw new ArgumentNullException(nameof(_collection0)); + if (_collection0 == null) + { + throw new ArgumentNullException(nameof(_collection0)); + } + _collection0.CollectionItem.Add(this); - if (_collectionitem1 == null) throw new ArgumentNullException(nameof(_collectionitem1)); + if (_collectionitem1 == null) + { + throw new ArgumentNullException(nameof(_collectionitem1)); + } + _collectionitem1.Next = this; - if (_collectionitem2 == null) throw new ArgumentNullException(nameof(_collectionitem2)); - _collectionitem2.Previous = this; + if (_collectionitem2 == null) + { + throw new ArgumentNullException(nameof(_collectionitem2)); + } + _collectionitem2.Previous = this; Init(); } diff --git a/Jellyfin.Data/Entities/Company.cs b/Jellyfin.Data/Entities/Company.cs index 2ac7bcfe5f..e905a17daf 100644 --- a/Jellyfin.Data/Entities/Company.cs +++ b/Jellyfin.Data/Entities/Company.cs @@ -37,19 +37,39 @@ namespace Jellyfin.Data.Entities /// public Company(MovieMetadata _moviemetadata0, SeriesMetadata _seriesmetadata1, MusicAlbumMetadata _musicalbummetadata2, BookMetadata _bookmetadata3, Company _company4) { - if (_moviemetadata0 == null) throw new ArgumentNullException(nameof(_moviemetadata0)); + if (_moviemetadata0 == null) + { + throw new ArgumentNullException(nameof(_moviemetadata0)); + } + _moviemetadata0.Studios.Add(this); - if (_seriesmetadata1 == null) throw new ArgumentNullException(nameof(_seriesmetadata1)); + if (_seriesmetadata1 == null) + { + throw new ArgumentNullException(nameof(_seriesmetadata1)); + } + _seriesmetadata1.Networks.Add(this); - if (_musicalbummetadata2 == null) throw new ArgumentNullException(nameof(_musicalbummetadata2)); + if (_musicalbummetadata2 == null) + { + throw new ArgumentNullException(nameof(_musicalbummetadata2)); + } + _musicalbummetadata2.Labels.Add(this); - if (_bookmetadata3 == null) throw new ArgumentNullException(nameof(_bookmetadata3)); + if (_bookmetadata3 == null) + { + throw new ArgumentNullException(nameof(_bookmetadata3)); + } + _bookmetadata3.Publishers.Add(this); - if (_company4 == null) throw new ArgumentNullException(nameof(_company4)); + if (_company4 == null) + { + throw new ArgumentNullException(nameof(_company4)); + } + _company4.Parent = this; this.CompanyMetadata = new HashSet(); diff --git a/Jellyfin.Data/Entities/CompanyMetadata.cs b/Jellyfin.Data/Entities/CompanyMetadata.cs index 12f2133104..e75349cf2a 100644 --- a/Jellyfin.Data/Entities/CompanyMetadata.cs +++ b/Jellyfin.Data/Entities/CompanyMetadata.cs @@ -31,15 +31,26 @@ namespace Jellyfin.Data.Entities /// public CompanyMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Company _company0) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; - if (_company0 == null) throw new ArgumentNullException(nameof(_company0)); - _company0.CompanyMetadata.Add(this); + if (_company0 == null) + { + throw new ArgumentNullException(nameof(_company0)); + } + _company0.CompanyMetadata.Add(this); Init(); } diff --git a/Jellyfin.Data/Entities/CustomItemMetadata.cs b/Jellyfin.Data/Entities/CustomItemMetadata.cs index dd66c8f832..965ed731f9 100644 --- a/Jellyfin.Data/Entities/CustomItemMetadata.cs +++ b/Jellyfin.Data/Entities/CustomItemMetadata.cs @@ -30,15 +30,26 @@ namespace Jellyfin.Data.Entities /// public CustomItemMetadata(string title, string language, DateTime dateadded, DateTime datemodified, CustomItem _customitem0) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; - if (_customitem0 == null) throw new ArgumentNullException(nameof(_customitem0)); - _customitem0.CustomItemMetadata.Add(this); + if (_customitem0 == null) + { + throw new ArgumentNullException(nameof(_customitem0)); + } + _customitem0.CustomItemMetadata.Add(this); Init(); } diff --git a/Jellyfin.Data/Entities/Episode.cs b/Jellyfin.Data/Entities/Episode.cs index 69106ab79d..57fbf894bf 100644 --- a/Jellyfin.Data/Entities/Episode.cs +++ b/Jellyfin.Data/Entities/Episode.cs @@ -42,7 +42,11 @@ namespace Jellyfin.Data.Entities this.UrlId = urlid; - if (_season0 == null) throw new ArgumentNullException(nameof(_season0)); + if (_season0 == null) + { + throw new ArgumentNullException(nameof(_season0)); + } + _season0.Episodes.Add(this); this.Releases = new HashSet(); diff --git a/Jellyfin.Data/Entities/EpisodeMetadata.cs b/Jellyfin.Data/Entities/EpisodeMetadata.cs index b17e4aa19f..9a21fd50f0 100644 --- a/Jellyfin.Data/Entities/EpisodeMetadata.cs +++ b/Jellyfin.Data/Entities/EpisodeMetadata.cs @@ -31,15 +31,26 @@ namespace Jellyfin.Data.Entities /// public EpisodeMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Episode _episode0) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; - if (_episode0 == null) throw new ArgumentNullException(nameof(_episode0)); - _episode0.EpisodeMetadata.Add(this); + if (_episode0 == null) + { + throw new ArgumentNullException(nameof(_episode0)); + } + _episode0.EpisodeMetadata.Add(this); Init(); } diff --git a/Jellyfin.Data/Entities/Genre.cs b/Jellyfin.Data/Entities/Genre.cs index 9b2264921c..24e6815d80 100644 --- a/Jellyfin.Data/Entities/Genre.cs +++ b/Jellyfin.Data/Entities/Genre.cs @@ -31,12 +31,19 @@ namespace Jellyfin.Data.Entities /// public Genre(string name, Metadata _metadata0) { - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(nameof(name)); + } + this.Name = name; - if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); - _metadata0.Genres.Add(this); + if (_metadata0 == null) + { + throw new ArgumentNullException(nameof(_metadata0)); + } + _metadata0.Genres.Add(this); Init(); } diff --git a/Jellyfin.Data/Entities/Library.cs b/Jellyfin.Data/Entities/Library.cs index ff94b93f04..d935e43b14 100644 --- a/Jellyfin.Data/Entities/Library.cs +++ b/Jellyfin.Data/Entities/Library.cs @@ -30,9 +30,12 @@ namespace Jellyfin.Data.Entities /// public Library(string name) { - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); - this.Name = name; + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(nameof(name)); + } + this.Name = name; Init(); } diff --git a/Jellyfin.Data/Entities/LibraryRoot.cs b/Jellyfin.Data/Entities/LibraryRoot.cs index a6f3e49c9d..9695ed638d 100644 --- a/Jellyfin.Data/Entities/LibraryRoot.cs +++ b/Jellyfin.Data/Entities/LibraryRoot.cs @@ -30,9 +30,12 @@ namespace Jellyfin.Data.Entities /// Absolute Path. public LibraryRoot(string path) { - if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); - this.Path = path; + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException(nameof(path)); + } + this.Path = path; Init(); } diff --git a/Jellyfin.Data/Entities/MediaFile.cs b/Jellyfin.Data/Entities/MediaFile.cs index 5d9448d41e..7382cda95b 100644 --- a/Jellyfin.Data/Entities/MediaFile.cs +++ b/Jellyfin.Data/Entities/MediaFile.cs @@ -35,12 +35,20 @@ namespace Jellyfin.Data.Entities /// public MediaFile(string path, Enums.MediaFileKind kind, Release _release0) { - if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException(nameof(path)); + } + this.Path = path; this.Kind = kind; - if (_release0 == null) throw new ArgumentNullException(nameof(_release0)); + if (_release0 == null) + { + throw new ArgumentNullException(nameof(_release0)); + } + _release0.MediaFiles.Add(this); this.MediaFileStreams = new HashSet(); diff --git a/Jellyfin.Data/Entities/MediaFileStream.cs b/Jellyfin.Data/Entities/MediaFileStream.cs index c018c0cbf9..977fd54e19 100644 --- a/Jellyfin.Data/Entities/MediaFileStream.cs +++ b/Jellyfin.Data/Entities/MediaFileStream.cs @@ -33,9 +33,12 @@ namespace Jellyfin.Data.Entities { this.StreamNumber = streamnumber; - if (_mediafile0 == null) throw new ArgumentNullException(nameof(_mediafile0)); - _mediafile0.MediaFileStreams.Add(this); + if (_mediafile0 == null) + { + throw new ArgumentNullException(nameof(_mediafile0)); + } + _mediafile0.MediaFileStreams.Add(this); Init(); } diff --git a/Jellyfin.Data/Entities/Metadata.cs b/Jellyfin.Data/Entities/Metadata.cs index 8446c30b2f..a4ac6dc540 100644 --- a/Jellyfin.Data/Entities/Metadata.cs +++ b/Jellyfin.Data/Entities/Metadata.cs @@ -30,10 +30,18 @@ namespace Jellyfin.Data.Entities /// ISO-639-3 3-character language codes. protected Metadata(string title, string language, DateTime dateadded, DateTime datemodified) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; this.PersonRoles = new HashSet(); diff --git a/Jellyfin.Data/Entities/MetadataProvider.cs b/Jellyfin.Data/Entities/MetadataProvider.cs index ae22ccfeb1..e93ea97d62 100644 --- a/Jellyfin.Data/Entities/MetadataProvider.cs +++ b/Jellyfin.Data/Entities/MetadataProvider.cs @@ -30,9 +30,12 @@ namespace Jellyfin.Data.Entities /// public MetadataProvider(string name) { - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); - this.Name = name; + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(nameof(name)); + } + this.Name = name; Init(); } diff --git a/Jellyfin.Data/Entities/MetadataProviderId.cs b/Jellyfin.Data/Entities/MetadataProviderId.cs index 30683ced3b..68f139436a 100644 --- a/Jellyfin.Data/Entities/MetadataProviderId.cs +++ b/Jellyfin.Data/Entities/MetadataProviderId.cs @@ -40,21 +40,40 @@ namespace Jellyfin.Data.Entities // NOTE: This class has one-to-one associations with MetadataProviderId. // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - if (string.IsNullOrEmpty(providerid)) throw new ArgumentNullException(nameof(providerid)); + if (string.IsNullOrEmpty(providerid)) + { + throw new ArgumentNullException(nameof(providerid)); + } + this.ProviderId = providerid; - if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); + if (_metadata0 == null) + { + throw new ArgumentNullException(nameof(_metadata0)); + } + _metadata0.Sources.Add(this); - if (_person1 == null) throw new ArgumentNullException(nameof(_person1)); + if (_person1 == null) + { + throw new ArgumentNullException(nameof(_person1)); + } + _person1.Sources.Add(this); - if (_personrole2 == null) throw new ArgumentNullException(nameof(_personrole2)); + if (_personrole2 == null) + { + throw new ArgumentNullException(nameof(_personrole2)); + } + _personrole2.Sources.Add(this); - if (_ratingsource3 == null) throw new ArgumentNullException(nameof(_ratingsource3)); - _ratingsource3.Source = this; + if (_ratingsource3 == null) + { + throw new ArgumentNullException(nameof(_ratingsource3)); + } + _ratingsource3.Source = this; Init(); } diff --git a/Jellyfin.Data/Entities/MovieMetadata.cs b/Jellyfin.Data/Entities/MovieMetadata.cs index 4fda88e8e2..cbcb78e374 100644 --- a/Jellyfin.Data/Entities/MovieMetadata.cs +++ b/Jellyfin.Data/Entities/MovieMetadata.cs @@ -35,13 +35,25 @@ namespace Jellyfin.Data.Entities /// public MovieMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Movie _movie0) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; - if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0)); + if (_movie0 == null) + { + throw new ArgumentNullException(nameof(_movie0)); + } + _movie0.MovieMetadata.Add(this); this.Studios = new HashSet(); diff --git a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs b/Jellyfin.Data/Entities/MusicAlbumMetadata.cs index a5056adc01..bfcbebbe8a 100644 --- a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs +++ b/Jellyfin.Data/Entities/MusicAlbumMetadata.cs @@ -35,13 +35,25 @@ namespace Jellyfin.Data.Entities /// public MusicAlbumMetadata(string title, string language, DateTime dateadded, DateTime datemodified, MusicAlbum _musicalbum0) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; - if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0)); + if (_musicalbum0 == null) + { + throw new ArgumentNullException(nameof(_musicalbum0)); + } + _musicalbum0.MusicAlbumMetadata.Add(this); this.Labels = new HashSet(); diff --git a/Jellyfin.Data/Entities/Person.cs b/Jellyfin.Data/Entities/Person.cs index 206fe77097..b6d91ea869 100644 --- a/Jellyfin.Data/Entities/Person.cs +++ b/Jellyfin.Data/Entities/Person.cs @@ -36,7 +36,11 @@ namespace Jellyfin.Data.Entities { this.UrlId = urlid; - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(nameof(name)); + } + this.Name = name; this.Sources = new HashSet(); diff --git a/Jellyfin.Data/Entities/PersonRole.cs b/Jellyfin.Data/Entities/PersonRole.cs index 928eb74aee..2dd5f116fc 100644 --- a/Jellyfin.Data/Entities/PersonRole.cs +++ b/Jellyfin.Data/Entities/PersonRole.cs @@ -42,7 +42,11 @@ namespace Jellyfin.Data.Entities this.Type = type; - if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); + if (_metadata0 == null) + { + throw new ArgumentNullException(nameof(_metadata0)); + } + _metadata0.PersonRoles.Add(this); this.Sources = new HashSet(); diff --git a/Jellyfin.Data/Entities/PhotoMetadata.cs b/Jellyfin.Data/Entities/PhotoMetadata.cs index 4a0b07ff83..b5aec7229e 100644 --- a/Jellyfin.Data/Entities/PhotoMetadata.cs +++ b/Jellyfin.Data/Entities/PhotoMetadata.cs @@ -31,15 +31,26 @@ namespace Jellyfin.Data.Entities /// public PhotoMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Photo _photo0) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; - if (_photo0 == null) throw new ArgumentNullException(nameof(_photo0)); - _photo0.PhotoMetadata.Add(this); + if (_photo0 == null) + { + throw new ArgumentNullException(nameof(_photo0)); + } + _photo0.PhotoMetadata.Add(this); Init(); } diff --git a/Jellyfin.Data/Entities/ProviderMapping.cs b/Jellyfin.Data/Entities/ProviderMapping.cs index 4125eabcd6..c53e3bf408 100644 --- a/Jellyfin.Data/Entities/ProviderMapping.cs +++ b/Jellyfin.Data/Entities/ProviderMapping.cs @@ -34,15 +34,26 @@ namespace Jellyfin.Data.Entities /// public ProviderMapping(string providername, string providersecrets, string providerdata, User _user0, Group _group1) { - if (string.IsNullOrEmpty(providername)) throw new ArgumentNullException(nameof(providername)); + if (string.IsNullOrEmpty(providername)) + { + throw new ArgumentNullException(nameof(providername)); + } + this.ProviderName = providername; - if (string.IsNullOrEmpty(providersecrets)) throw new ArgumentNullException(nameof(providersecrets)); + if (string.IsNullOrEmpty(providersecrets)) + { + throw new ArgumentNullException(nameof(providersecrets)); + } + this.ProviderSecrets = providersecrets; - if (string.IsNullOrEmpty(providerdata)) throw new ArgumentNullException(nameof(providerdata)); - this.ProviderData = providerdata; + if (string.IsNullOrEmpty(providerdata)) + { + throw new ArgumentNullException(nameof(providerdata)); + } + this.ProviderData = providerdata; Init(); } diff --git a/Jellyfin.Data/Entities/Rating.cs b/Jellyfin.Data/Entities/Rating.cs index e00d5297db..49a0d502d2 100644 --- a/Jellyfin.Data/Entities/Rating.cs +++ b/Jellyfin.Data/Entities/Rating.cs @@ -33,9 +33,12 @@ namespace Jellyfin.Data.Entities { this.Value = value; - if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); - _metadata0.Ratings.Add(this); + if (_metadata0 == null) + { + throw new ArgumentNullException(nameof(_metadata0)); + } + _metadata0.Ratings.Add(this); Init(); } diff --git a/Jellyfin.Data/Entities/RatingSource.cs b/Jellyfin.Data/Entities/RatingSource.cs index 941f53e52a..b62d8b4443 100644 --- a/Jellyfin.Data/Entities/RatingSource.cs +++ b/Jellyfin.Data/Entities/RatingSource.cs @@ -39,9 +39,12 @@ namespace Jellyfin.Data.Entities this.MinimumValue = minimumvalue; - if (_rating0 == null) throw new ArgumentNullException(nameof(_rating0)); - _rating0.RatingType = this; + if (_rating0 == null) + { + throw new ArgumentNullException(nameof(_rating0)); + } + _rating0.RatingType = this; Init(); } diff --git a/Jellyfin.Data/Entities/Release.cs b/Jellyfin.Data/Entities/Release.cs index e08c04545c..1e9faa5a1d 100644 --- a/Jellyfin.Data/Entities/Release.cs +++ b/Jellyfin.Data/Entities/Release.cs @@ -40,25 +40,53 @@ namespace Jellyfin.Data.Entities /// public Release(string name, Movie _movie0, Episode _episode1, Track _track2, CustomItem _customitem3, Book _book4, Photo _photo5) { - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(nameof(name)); + } + this.Name = name; - if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0)); + if (_movie0 == null) + { + throw new ArgumentNullException(nameof(_movie0)); + } + _movie0.Releases.Add(this); - if (_episode1 == null) throw new ArgumentNullException(nameof(_episode1)); + if (_episode1 == null) + { + throw new ArgumentNullException(nameof(_episode1)); + } + _episode1.Releases.Add(this); - if (_track2 == null) throw new ArgumentNullException(nameof(_track2)); + if (_track2 == null) + { + throw new ArgumentNullException(nameof(_track2)); + } + _track2.Releases.Add(this); - if (_customitem3 == null) throw new ArgumentNullException(nameof(_customitem3)); + if (_customitem3 == null) + { + throw new ArgumentNullException(nameof(_customitem3)); + } + _customitem3.Releases.Add(this); - if (_book4 == null) throw new ArgumentNullException(nameof(_book4)); + if (_book4 == null) + { + throw new ArgumentNullException(nameof(_book4)); + } + _book4.Releases.Add(this); - if (_photo5 == null) throw new ArgumentNullException(nameof(_photo5)); + if (_photo5 == null) + { + throw new ArgumentNullException(nameof(_photo5)); + } + _photo5.Releases.Add(this); this.MediaFiles = new HashSet(); diff --git a/Jellyfin.Data/Entities/Season.cs b/Jellyfin.Data/Entities/Season.cs index d71f4b522b..4b1e785758 100644 --- a/Jellyfin.Data/Entities/Season.cs +++ b/Jellyfin.Data/Entities/Season.cs @@ -42,7 +42,11 @@ namespace Jellyfin.Data.Entities this.UrlId = urlid; - if (_series0 == null) throw new ArgumentNullException(nameof(_series0)); + if (_series0 == null) + { + throw new ArgumentNullException(nameof(_series0)); + } + _series0.Seasons.Add(this); this.SeasonMetadata = new HashSet(); diff --git a/Jellyfin.Data/Entities/SeasonMetadata.cs b/Jellyfin.Data/Entities/SeasonMetadata.cs index 8c72d99528..10d19875e6 100644 --- a/Jellyfin.Data/Entities/SeasonMetadata.cs +++ b/Jellyfin.Data/Entities/SeasonMetadata.cs @@ -32,15 +32,26 @@ namespace Jellyfin.Data.Entities /// public SeasonMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Season _season0) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; - if (_season0 == null) throw new ArgumentNullException(nameof(_season0)); - _season0.SeasonMetadata.Add(this); + if (_season0 == null) + { + throw new ArgumentNullException(nameof(_season0)); + } + _season0.SeasonMetadata.Add(this); Init(); } diff --git a/Jellyfin.Data/Entities/SeriesMetadata.cs b/Jellyfin.Data/Entities/SeriesMetadata.cs index 2c04ef12fd..16eb59315e 100644 --- a/Jellyfin.Data/Entities/SeriesMetadata.cs +++ b/Jellyfin.Data/Entities/SeriesMetadata.cs @@ -35,13 +35,25 @@ namespace Jellyfin.Data.Entities /// public SeriesMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Series _series0) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; - if (_series0 == null) throw new ArgumentNullException(nameof(_series0)); + if (_series0 == null) + { + throw new ArgumentNullException(nameof(_series0)); + } + _series0.SeriesMetadata.Add(this); this.Networks = new HashSet(); diff --git a/Jellyfin.Data/Entities/Track.cs b/Jellyfin.Data/Entities/Track.cs index e13a53d382..b7d7b5873b 100644 --- a/Jellyfin.Data/Entities/Track.cs +++ b/Jellyfin.Data/Entities/Track.cs @@ -42,7 +42,11 @@ namespace Jellyfin.Data.Entities this.UrlId = urlid; - if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0)); + if (_musicalbum0 == null) + { + throw new ArgumentNullException(nameof(_musicalbum0)); + } + _musicalbum0.Tracks.Add(this); this.Releases = new HashSet(); diff --git a/Jellyfin.Data/Entities/TrackMetadata.cs b/Jellyfin.Data/Entities/TrackMetadata.cs index 55f4a38e01..23e1219aaf 100644 --- a/Jellyfin.Data/Entities/TrackMetadata.cs +++ b/Jellyfin.Data/Entities/TrackMetadata.cs @@ -31,15 +31,26 @@ namespace Jellyfin.Data.Entities /// public TrackMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Track _track0) { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + if (string.IsNullOrEmpty(title)) + { + throw new ArgumentNullException(nameof(title)); + } + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + if (string.IsNullOrEmpty(language)) + { + throw new ArgumentNullException(nameof(language)); + } + this.Language = language; - if (_track0 == null) throw new ArgumentNullException(nameof(_track0)); - _track0.TrackMetadata.Add(this); + if (_track0 == null) + { + throw new ArgumentNullException(nameof(_track0)); + } + _track0.TrackMetadata.Add(this); Init(); } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 7b833c36b0..2ad1c717cf 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -690,7 +690,10 @@ namespace MediaBrowser.Controller.Entities /// System.String. protected virtual string CreateSortName() { - if (Name == null) return null; // some items may not have name filled in properly + if (Name == null) + { + return null; // some items may not have name filled in properly + } if (!EnableAlphaNumericSorting) { diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index 731c6d6674..2e5dcc4c53 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -252,7 +252,11 @@ namespace MediaBrowser.Controller.Library { if (args != null) { - if (args.Path == null && Path == null) return true; + if (args.Path == null && Path == null) + { + return true; + } + return args.Path != null && BaseItem.FileSystem.AreEqual(args.Path, Path); } diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index ba807ab85b..190abaa058 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -1065,23 +1065,43 @@ namespace MediaBrowser.MediaEncoding.Probing // These support mulitple values, but for now we only store the first. var mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id")); - if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMARTISTID")); + if (mb == null) + { + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMARTISTID")); + } + audio.SetProviderId(MetadataProvider.MusicBrainzAlbumArtist, mb); mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id")); - if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ARTISTID")); + if (mb == null) + { + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ARTISTID")); + } + audio.SetProviderId(MetadataProvider.MusicBrainzArtist, mb); mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id")); - if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMID")); + if (mb == null) + { + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMID")); + } + audio.SetProviderId(MetadataProvider.MusicBrainzAlbum, mb); mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id")); - if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASEGROUPID")); + if (mb == null) + { + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASEGROUPID")); + } + audio.SetProviderId(MetadataProvider.MusicBrainzReleaseGroup, mb); mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Track Id")); - if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASETRACKID")); + if (mb == null) + { + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASETRACKID")); + } + audio.SetProviderId(MetadataProvider.MusicBrainzTrack, mb); } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 06bd244763..cfe862f5a9 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -384,7 +384,10 @@ namespace MediaBrowser.Model.Dlna audioCodecProfiles.Add(i); } - if (audioCodecProfiles.Count >= 1) break; + if (audioCodecProfiles.Count >= 1) + { + break; + } } var audioTranscodingConditions = new List(); diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index d8ee79d0d0..7a488005ea 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -421,7 +421,10 @@ namespace MediaBrowser.Model.Entities { get { - if (Type != MediaStreamType.Subtitle) return false; + if (Type != MediaStreamType.Subtitle) + { + return false; + } if (string.IsNullOrEmpty(Codec) && !IsExternal) { diff --git a/MediaBrowser.Model/Services/RouteAttribute.cs b/MediaBrowser.Model/Services/RouteAttribute.cs index 162576aa7e..f8bf511124 100644 --- a/MediaBrowser.Model/Services/RouteAttribute.cs +++ b/MediaBrowser.Model/Services/RouteAttribute.cs @@ -128,9 +128,21 @@ namespace MediaBrowser.Model.Services public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != this.GetType()) + { + return false; + } + return Equals((RouteAttribute)obj); } diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index cf55466023..82ed65ebb6 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -113,7 +113,10 @@ namespace MediaBrowser.Providers.Manager foreach (var imageType in images) { - if (!IsEnabled(savedOptions, imageType, item)) continue; + if (!IsEnabled(savedOptions, imageType, item)) + { + continue; + } if (!HasImage(item, imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType))) { diff --git a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs index 15f0a9004b..71799efa46 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs @@ -159,7 +159,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets { var mainResult = await FetchMainResult(tmdbId, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); - if (mainResult == null) return; + if (mainResult == null) + { + return; + } var dataFilePath = GetDataFilePath(_config.ApplicationPaths, tmdbId, preferredMetadataLanguage); diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs index 1961e8bff9..1c4cf1da13 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs @@ -194,7 +194,10 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies { var mainResult = await FetchMainResult(id, true, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false); - if (mainResult == null) return; + if (mainResult == null) + { + return; + } var dataFilePath = GetDataFilePath(id, preferredMetadataLanguage); diff --git a/RSSDP/DeviceAvailableEventArgs.cs b/RSSDP/DeviceAvailableEventArgs.cs index 9c57471ca0..b7d22a7df5 100644 --- a/RSSDP/DeviceAvailableEventArgs.cs +++ b/RSSDP/DeviceAvailableEventArgs.cs @@ -22,7 +22,10 @@ namespace Rssdp /// Thrown if the parameter is null. public DeviceAvailableEventArgs(DiscoveredSsdpDevice discoveredDevice, bool isNewlyDiscovered) { - if (discoveredDevice == null) throw new ArgumentNullException(nameof(discoveredDevice)); + if (discoveredDevice == null) + { + throw new ArgumentNullException(nameof(discoveredDevice)); + } _DiscoveredDevice = discoveredDevice; _IsNewlyDiscovered = isNewlyDiscovered; diff --git a/RSSDP/DeviceEventArgs.cs b/RSSDP/DeviceEventArgs.cs index b124527ca9..2455ccbfad 100644 --- a/RSSDP/DeviceEventArgs.cs +++ b/RSSDP/DeviceEventArgs.cs @@ -16,7 +16,10 @@ namespace Rssdp /// Thrown if the argument is null. public DeviceEventArgs(SsdpDevice device) { - if (device == null) throw new ArgumentNullException(nameof(device)); + if (device == null) + { + throw new ArgumentNullException(nameof(device)); + } _Device = device; } diff --git a/RSSDP/DeviceUnavailableEventArgs.cs b/RSSDP/DeviceUnavailableEventArgs.cs index cee59268dc..94248f39f2 100644 --- a/RSSDP/DeviceUnavailableEventArgs.cs +++ b/RSSDP/DeviceUnavailableEventArgs.cs @@ -19,7 +19,10 @@ namespace Rssdp /// Thrown if the parameter is null. public DeviceUnavailableEventArgs(DiscoveredSsdpDevice discoveredDevice, bool expired) { - if (discoveredDevice == null) throw new ArgumentNullException(nameof(discoveredDevice)); + if (discoveredDevice == null) + { + throw new ArgumentNullException(nameof(discoveredDevice)); + } _DiscoveredDevice = discoveredDevice; _Expired = expired; diff --git a/RSSDP/DisposableManagedObjectBase.cs b/RSSDP/DisposableManagedObjectBase.cs index befa4ccffb..628572b17a 100644 --- a/RSSDP/DisposableManagedObjectBase.cs +++ b/RSSDP/DisposableManagedObjectBase.cs @@ -23,7 +23,10 @@ namespace Rssdp.Infrastructure /// protected virtual void ThrowIfDisposed() { - if (this.IsDisposed) throw new ObjectDisposedException(this.GetType().FullName); + if (this.IsDisposed) + { + throw new ObjectDisposedException(this.GetType().FullName); + } } /// diff --git a/RSSDP/HttpParserBase.cs b/RSSDP/HttpParserBase.cs index ff97b6db84..058bfbf555 100644 --- a/RSSDP/HttpParserBase.cs +++ b/RSSDP/HttpParserBase.cs @@ -31,9 +31,20 @@ namespace Rssdp.Infrastructure [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Honestly, it's fine. MemoryStream doesn't mind.")] protected virtual void Parse(T message, System.Net.Http.Headers.HttpHeaders headers, string data) { - if (data == null) throw new ArgumentNullException(nameof(data)); - if (data.Length == 0) throw new ArgumentException("data cannot be an empty string.", nameof(data)); - if (!LineTerminators.Any(data.Contains)) throw new ArgumentException("data is not a valid request, it does not contain any CRLF/LF terminators.", nameof(data)); + if (data == null) + { + throw new ArgumentNullException(nameof(data)); + } + + if (data.Length == 0) + { + throw new ArgumentException("data cannot be an empty string.", nameof(data)); + } + + if (!LineTerminators.Any(data.Contains)) + { + throw new ArgumentException("data is not a valid request, it does not contain any CRLF/LF terminators.", nameof(data)); + } using (var retVal = new ByteArrayContent(Array.Empty())) { @@ -66,10 +77,16 @@ namespace Rssdp.Infrastructure /// A object containing the parsed version data. protected Version ParseHttpVersion(string versionData) { - if (versionData == null) throw new ArgumentNullException(nameof(versionData)); + if (versionData == null) + { + throw new ArgumentNullException(nameof(versionData)); + } var versionSeparatorIndex = versionData.IndexOf('/'); - if (versionSeparatorIndex <= 0 || versionSeparatorIndex == versionData.Length) throw new ArgumentException("request header line is invalid. Http Version not supplied or incorrect format.", nameof(versionData)); + if (versionSeparatorIndex <= 0 || versionSeparatorIndex == versionData.Length) + { + throw new ArgumentException("request header line is invalid. Http Version not supplied or incorrect format.", nameof(versionData)); + } return Version.Parse(versionData.Substring(versionSeparatorIndex + 1)); } diff --git a/RSSDP/HttpRequestParser.cs b/RSSDP/HttpRequestParser.cs index 31f042791d..6b27fc4df4 100644 --- a/RSSDP/HttpRequestParser.cs +++ b/RSSDP/HttpRequestParser.cs @@ -45,11 +45,21 @@ namespace Rssdp.Infrastructure /// Either a or to assign the parsed values to. protected override void ParseStatusLine(string data, HttpRequestMessage message) { - if (data == null) throw new ArgumentNullException(nameof(data)); - if (message == null) throw new ArgumentNullException(nameof(message)); + if (data == null) + { + throw new ArgumentNullException(nameof(data)); + } + + if (message == null) + { + throw new ArgumentNullException(nameof(message)); + } var parts = data.Split(' '); - if (parts.Length < 2) throw new ArgumentException("Status line is invalid. Insufficient status parts.", nameof(data)); + if (parts.Length < 2) + { + throw new ArgumentException("Status line is invalid. Insufficient status parts.", nameof(data)); + } message.Method = new HttpMethod(parts[0].Trim()); Uri requestUri; diff --git a/RSSDP/HttpResponseParser.cs b/RSSDP/HttpResponseParser.cs index 02c548d724..0337b3e360 100644 --- a/RSSDP/HttpResponseParser.cs +++ b/RSSDP/HttpResponseParser.cs @@ -57,11 +57,21 @@ namespace Rssdp.Infrastructure /// Either a or to assign the parsed values to. protected override void ParseStatusLine(string data, HttpResponseMessage message) { - if (data == null) throw new ArgumentNullException(nameof(data)); - if (message == null) throw new ArgumentNullException(nameof(message)); + if (data == null) + { + throw new ArgumentNullException(nameof(data)); + } + + if (message == null) + { + throw new ArgumentNullException(nameof(message)); + } var parts = data.Split(' '); - if (parts.Length < 2) throw new ArgumentException("data status line is invalid. Insufficient status parts.", nameof(data)); + if (parts.Length < 2) + { + throw new ArgumentException("data status line is invalid. Insufficient status parts.", nameof(data)); + } message.Version = ParseHttpVersion(parts[0].Trim()); diff --git a/RSSDP/IEnumerableExtensions.cs b/RSSDP/IEnumerableExtensions.cs index 371454893d..1f0daad3e1 100644 --- a/RSSDP/IEnumerableExtensions.cs +++ b/RSSDP/IEnumerableExtensions.cs @@ -8,8 +8,15 @@ namespace Rssdp.Infrastructure { public static IEnumerable SelectManyRecursive(this IEnumerable source, Func> selector) { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (selector == null) throw new ArgumentNullException(nameof(selector)); + if (source == null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (selector == null) + { + throw new ArgumentNullException(nameof(selector)); + } return !source.Any() ? source : source.Concat( diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 12ecf24f3b..31ca90424f 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -80,8 +80,15 @@ namespace Rssdp.Infrastructure /// The argument is less than or equal to zero. public SsdpCommunicationsServer(ISocketFactory socketFactory, int localPort, int multicastTimeToLive, INetworkManager networkManager, ILogger logger, bool enableMultiSocketBinding) { - if (socketFactory == null) throw new ArgumentNullException(nameof(socketFactory)); - if (multicastTimeToLive <= 0) throw new ArgumentOutOfRangeException(nameof(multicastTimeToLive), "multicastTimeToLive must be greater than zero."); + if (socketFactory == null) + { + throw new ArgumentNullException(nameof(socketFactory)); + } + + if (multicastTimeToLive <= 0) + { + throw new ArgumentOutOfRangeException(nameof(multicastTimeToLive), "multicastTimeToLive must be greater than zero."); + } _BroadcastListenSocketSynchroniser = new object(); _SendSocketSynchroniser = new object(); @@ -151,7 +158,10 @@ namespace Rssdp.Infrastructure /// public async Task SendMessage(byte[] messageData, IPEndPoint destination, IPAddress fromLocalIpAddress, CancellationToken cancellationToken) { - if (messageData == null) throw new ArgumentNullException(nameof(messageData)); + if (messageData == null) + { + throw new ArgumentNullException(nameof(messageData)); + } ThrowIfDisposed(); @@ -234,7 +244,10 @@ namespace Rssdp.Infrastructure /// public async Task SendMulticastMessage(string message, int sendCount, IPAddress fromLocalIpAddress, CancellationToken cancellationToken) { - if (message == null) throw new ArgumentNullException(nameof(message)); + if (message == null) + { + throw new ArgumentNullException(nameof(message)); + } byte[] messageData = Encoding.UTF8.GetBytes(message); diff --git a/RSSDP/SsdpDevice.cs b/RSSDP/SsdpDevice.cs index 5b7d782b52..42f95862c5 100644 --- a/RSSDP/SsdpDevice.cs +++ b/RSSDP/SsdpDevice.cs @@ -259,9 +259,20 @@ namespace Rssdp /// public void AddDevice(SsdpEmbeddedDevice device) { - if (device == null) throw new ArgumentNullException(nameof(device)); - if (device.RootDevice != null && device.RootDevice != this.ToRootDevice()) throw new InvalidOperationException("This device is already associated with a different root device (has been added as a child in another branch)."); - if (device == this) throw new InvalidOperationException("Can't add device to itself."); + if (device == null) + { + throw new ArgumentNullException(nameof(device)); + } + + if (device.RootDevice != null && device.RootDevice != this.ToRootDevice()) + { + throw new InvalidOperationException("This device is already associated with a different root device (has been added as a child in another branch)."); + } + + if (device == this) + { + throw new InvalidOperationException("Can't add device to itself."); + } bool wasAdded = false; lock (_Devices) @@ -287,7 +298,10 @@ namespace Rssdp /// public void RemoveDevice(SsdpEmbeddedDevice device) { - if (device == null) throw new ArgumentNullException(nameof(device)); + if (device == null) + { + throw new ArgumentNullException(nameof(device)); + } bool wasRemoved = false; lock (_Devices) diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs index b117c0b1e6..a774ee23c8 100644 --- a/RSSDP/SsdpDeviceLocator.cs +++ b/RSSDP/SsdpDeviceLocator.cs @@ -27,7 +27,10 @@ namespace Rssdp.Infrastructure /// public SsdpDeviceLocator(ISsdpCommunicationsServer communicationsServer) { - if (communicationsServer == null) throw new ArgumentNullException(nameof(communicationsServer)); + if (communicationsServer == null) + { + throw new ArgumentNullException(nameof(communicationsServer)); + } _CommunicationsServer = communicationsServer; _CommunicationsServer.ResponseReceived += CommsServer_ResponseReceived; @@ -140,10 +143,25 @@ namespace Rssdp.Infrastructure private Task SearchAsync(string searchTarget, TimeSpan searchWaitTime, CancellationToken cancellationToken) { - if (searchTarget == null) throw new ArgumentNullException(nameof(searchTarget)); - if (searchTarget.Length == 0) throw new ArgumentException("searchTarget cannot be an empty string.", nameof(searchTarget)); - if (searchWaitTime.TotalSeconds < 0) throw new ArgumentException("searchWaitTime must be a positive time."); - if (searchWaitTime.TotalSeconds > 0 && searchWaitTime.TotalSeconds <= 1) throw new ArgumentException("searchWaitTime must be zero (if you are not using the result and relying entirely in the events), or greater than one second."); + if (searchTarget == null) + { + throw new ArgumentNullException(nameof(searchTarget)); + } + + if (searchTarget.Length == 0) + { + throw new ArgumentException("searchTarget cannot be an empty string.", nameof(searchTarget)); + } + + if (searchWaitTime.TotalSeconds < 0) + { + throw new ArgumentException("searchWaitTime must be a positive time."); + } + + if (searchWaitTime.TotalSeconds > 0 && searchWaitTime.TotalSeconds <= 1) + { + throw new ArgumentException("searchWaitTime must be zero (if you are not using the result and relying entirely in the events), or greater than one second."); + } ThrowIfDisposed(); @@ -192,7 +210,10 @@ namespace Rssdp.Infrastructure /// protected virtual void OnDeviceAvailable(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress localIpAddress) { - if (this.IsDisposed) return; + if (this.IsDisposed) + { + return; + } var handlers = this.DeviceAvailable; if (handlers != null) @@ -210,11 +231,16 @@ namespace Rssdp.Infrastructure /// protected virtual void OnDeviceUnavailable(DiscoveredSsdpDevice device, bool expired) { - if (this.IsDisposed) return; + if (this.IsDisposed) + { + return; + } var handlers = this.DeviceUnavailable; if (handlers != null) + { handlers(this, new DeviceUnavailableEventArgs(device, expired)); + } } /// @@ -281,7 +307,10 @@ namespace Rssdp.Infrastructure private void DeviceFound(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress localIpAddress) { - if (!NotificationTypeMatchesFilter(device)) return; + if (!NotificationTypeMatchesFilter(device)) + { + return; + } OnDeviceAvailable(device, isNewDevice, localIpAddress); } @@ -318,7 +347,10 @@ namespace Rssdp.Infrastructure private void ProcessSearchResponseMessage(HttpResponseMessage message, IPAddress localIpAddress) { - if (!message.IsSuccessStatusCode) return; + if (!message.IsSuccessStatusCode) + { + return; + } var location = GetFirstHeaderUriValue("Location", message); if (location != null) @@ -339,13 +371,20 @@ namespace Rssdp.Infrastructure private void ProcessNotificationMessage(HttpRequestMessage message, IPAddress localIpAddress) { - if (String.Compare(message.Method.Method, "Notify", StringComparison.OrdinalIgnoreCase) != 0) return; + if (String.Compare(message.Method.Method, "Notify", StringComparison.OrdinalIgnoreCase) != 0) + { + return; + } var notificationType = GetFirstHeaderStringValue("NTS", message); if (String.Compare(notificationType, SsdpConstants.SsdpKeepAliveNotification, StringComparison.OrdinalIgnoreCase) == 0) + { ProcessAliveNotification(message, localIpAddress); + } else if (String.Compare(notificationType, SsdpConstants.SsdpByeByeNotification, StringComparison.OrdinalIgnoreCase) == 0) + { ProcessByeByeNotification(message); + } } private void ProcessAliveNotification(HttpRequestMessage message, IPAddress localIpAddress) @@ -454,14 +493,20 @@ namespace Rssdp.Infrastructure private TimeSpan CacheAgeFromHeader(System.Net.Http.Headers.CacheControlHeaderValue headerValue) { - if (headerValue == null) return TimeSpan.Zero; + if (headerValue == null) + { + return TimeSpan.Zero; + } return (TimeSpan)(headerValue.MaxAge ?? headerValue.SharedMaxAge ?? TimeSpan.Zero); } private void RemoveExpiredDevicesFromCache() { - if (this.IsDisposed) return; + if (this.IsDisposed) + { + return; + } DiscoveredSsdpDevice[] expiredDevices = null; lock (_Devices) @@ -470,7 +515,10 @@ namespace Rssdp.Infrastructure foreach (var device in expiredDevices) { - if (this.IsDisposed) return; + if (this.IsDisposed) + { + return; + } _Devices.Remove(device); } @@ -481,7 +529,10 @@ namespace Rssdp.Infrastructure // problems. foreach (var expiredUsn in (from expiredDevice in expiredDevices select expiredDevice.Usn).Distinct()) { - if (this.IsDisposed) return; + if (this.IsDisposed) + { + return; + } DeviceDied(expiredUsn, true); } @@ -495,7 +546,10 @@ namespace Rssdp.Infrastructure existingDevices = FindExistingDeviceNotifications(_Devices, deviceUsn); foreach (var existingDevice in existingDevices) { - if (this.IsDisposed) return true; + if (this.IsDisposed) + { + return true; + } _Devices.Remove(existingDevice); } diff --git a/RSSDP/SsdpDevicePublisher.cs b/RSSDP/SsdpDevicePublisher.cs index b4cf2fb484..1b64d230dd 100644 --- a/RSSDP/SsdpDevicePublisher.cs +++ b/RSSDP/SsdpDevicePublisher.cs @@ -40,12 +40,35 @@ namespace Rssdp.Infrastructure public SsdpDevicePublisher(ISsdpCommunicationsServer communicationsServer, INetworkManager networkManager, string osName, string osVersion, bool sendOnlyMatchedHost) { - if (communicationsServer == null) throw new ArgumentNullException(nameof(communicationsServer)); - if (networkManager == null) throw new ArgumentNullException(nameof(networkManager)); - if (osName == null) throw new ArgumentNullException(nameof(osName)); - if (osName.Length == 0) throw new ArgumentException("osName cannot be an empty string.", nameof(osName)); - if (osVersion == null) throw new ArgumentNullException(nameof(osVersion)); - if (osVersion.Length == 0) throw new ArgumentException("osVersion cannot be an empty string.", nameof(osName)); + if (communicationsServer == null) + { + throw new ArgumentNullException(nameof(communicationsServer)); + } + + if (networkManager == null) + { + throw new ArgumentNullException(nameof(networkManager)); + } + + if (osName == null) + { + throw new ArgumentNullException(nameof(osName)); + } + + if (osName.Length == 0) + { + throw new ArgumentException("osName cannot be an empty string.", nameof(osName)); + } + + if (osVersion == null) + { + throw new ArgumentNullException(nameof(osVersion)); + } + + if (osVersion.Length == 0) + { + throw new ArgumentException("osVersion cannot be an empty string.", nameof(osName)); + } _SupportPnpRootDevice = true; _Devices = new List(); @@ -82,7 +105,10 @@ namespace Rssdp.Infrastructure [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "t", Justification = "Capture task to local variable supresses compiler warning, but task is not really needed.")] public void AddDevice(SsdpRootDevice device) { - if (device == null) throw new ArgumentNullException(nameof(device)); + if (device == null) + { + throw new ArgumentNullException(nameof(device)); + } ThrowIfDisposed(); @@ -115,7 +141,10 @@ namespace Rssdp.Infrastructure /// Thrown if the argument is null. public async Task RemoveDevice(SsdpRootDevice device) { - if (device == null) throw new ArgumentNullException(nameof(device)); + if (device == null) + { + throw new ArgumentNullException(nameof(device)); + } bool wasRemoved = false; lock (_Devices) @@ -227,10 +256,15 @@ namespace Rssdp.Infrastructure // return; } - if (!Int32.TryParse(mx, out maxWaitInterval) || maxWaitInterval <= 0) return; + if (!Int32.TryParse(mx, out maxWaitInterval) || maxWaitInterval <= 0) + { + return; + } if (maxWaitInterval > 120) + { maxWaitInterval = _Random.Next(0, 120); + } // Do not block synchronously as that may tie up a threadpool thread for several seconds. Task.Delay(_Random.Next(16, (maxWaitInterval * 1000))).ContinueWith((parentTask) => @@ -240,13 +274,21 @@ namespace Rssdp.Infrastructure lock (_Devices) { if (String.Compare(SsdpConstants.SsdpDiscoverAllSTHeader, searchTarget, StringComparison.OrdinalIgnoreCase) == 0) + { devices = GetAllDevicesAsFlatEnumerable().ToArray(); + } else if (String.Compare(SsdpConstants.UpnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 || (this.SupportPnpRootDevice && String.Compare(SsdpConstants.PnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0)) + { devices = _Devices.ToArray(); + } else if (searchTarget.Trim().StartsWith("uuid:", StringComparison.OrdinalIgnoreCase)) + { devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.Uuid, searchTarget.Substring(5), StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray(); + } else if (searchTarget.StartsWith("urn:", StringComparison.OrdinalIgnoreCase)) + { devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.FullDeviceType, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray(); + } } if (devices != null) @@ -382,7 +424,10 @@ namespace Rssdp.Infrastructure { try { - if (IsDisposed) return; + if (IsDisposed) + { + return; + } // WriteTrace("Begin Sending Alive Notifications For All Devices"); @@ -394,7 +439,10 @@ namespace Rssdp.Infrastructure foreach (var device in devices) { - if (IsDisposed) return; + if (IsDisposed) + { + return; + } SendAliveNotifications(device, true, CancellationToken.None); } @@ -547,7 +595,10 @@ namespace Rssdp.Infrastructure private void CommsServer_RequestReceived(object sender, RequestReceivedEventArgs e) { - if (this.IsDisposed) return; + if (this.IsDisposed) + { + return; + } if (string.Equals(e.Message.Method.Method, SsdpConstants.MSearchMethod, StringComparison.OrdinalIgnoreCase)) { -- cgit v1.2.3 From 7f307f9082cb4be296e745c2c066334858f000af Mon Sep 17 00:00:00 2001 From: telans Date: Sat, 20 Jun 2020 21:12:36 +1200 Subject: brace multiline if statements --- Emby.Dlna/DlnaManager.cs | 18 +++++ Emby.Dlna/PlayTo/Device.cs | 14 ++++ .../Library/Resolvers/Books/BookResolver.cs | 4 ++ .../Services/ResponseHelper.cs | 2 + .../Services/ServiceExec.cs | 4 ++ .../Services/ServicePath.cs | 2 + .../Sorting/DateCreatedComparer.cs | 4 ++ .../Sorting/RuntimeComparer.cs | 4 ++ .../Sorting/SortNameComparer.cs | 4 ++ MediaBrowser.Controller/Entities/BaseItem.cs | 2 + MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs | 3 + MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs | 58 +++++++++++++++ .../Dlna/MediaFormatProfileResolver.cs | 83 +++++++++++++++++++++- RSSDP/HttpParserBase.cs | 12 ++++ RSSDP/HttpRequestParser.cs | 4 ++ RSSDP/HttpResponseParser.cs | 4 ++ RSSDP/SsdpCommunicationsServer.cs | 4 ++ RSSDP/SsdpDevice.cs | 12 ++++ RSSDP/SsdpDeviceLocator.cs | 16 +++++ RSSDP/SsdpDevicePublisher.cs | 31 ++++++-- 20 files changed, 280 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index cbe4ea643c..5911a73ef1 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -140,55 +140,73 @@ namespace Emby.Dlna if (!string.IsNullOrEmpty(profileInfo.DeviceDescription)) { if (deviceInfo.DeviceDescription == null || !IsRegexMatch(deviceInfo.DeviceDescription, profileInfo.DeviceDescription)) + { return false; + } } if (!string.IsNullOrEmpty(profileInfo.FriendlyName)) { if (deviceInfo.FriendlyName == null || !IsRegexMatch(deviceInfo.FriendlyName, profileInfo.FriendlyName)) + { return false; + } } if (!string.IsNullOrEmpty(profileInfo.Manufacturer)) { if (deviceInfo.Manufacturer == null || !IsRegexMatch(deviceInfo.Manufacturer, profileInfo.Manufacturer)) + { return false; + } } if (!string.IsNullOrEmpty(profileInfo.ManufacturerUrl)) { if (deviceInfo.ManufacturerUrl == null || !IsRegexMatch(deviceInfo.ManufacturerUrl, profileInfo.ManufacturerUrl)) + { return false; + } } if (!string.IsNullOrEmpty(profileInfo.ModelDescription)) { if (deviceInfo.ModelDescription == null || !IsRegexMatch(deviceInfo.ModelDescription, profileInfo.ModelDescription)) + { return false; + } } if (!string.IsNullOrEmpty(profileInfo.ModelName)) { if (deviceInfo.ModelName == null || !IsRegexMatch(deviceInfo.ModelName, profileInfo.ModelName)) + { return false; + } } if (!string.IsNullOrEmpty(profileInfo.ModelNumber)) { if (deviceInfo.ModelNumber == null || !IsRegexMatch(deviceInfo.ModelNumber, profileInfo.ModelNumber)) + { return false; + } } if (!string.IsNullOrEmpty(profileInfo.ModelUrl)) { if (deviceInfo.ModelUrl == null || !IsRegexMatch(deviceInfo.ModelUrl, profileInfo.ModelUrl)) + { return false; + } } if (!string.IsNullOrEmpty(profileInfo.SerialNumber)) { if (deviceInfo.SerialNumber == null || !IsRegexMatch(deviceInfo.SerialNumber, profileInfo.SerialNumber)) + { return false; + } } return true; diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index c86fc4f374..c5080b90f3 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -208,7 +208,9 @@ namespace Emby.Dlna.PlayTo var command = rendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetMute"); if (command == null) + { return false; + } var service = GetServiceRenderingControl(); @@ -237,7 +239,9 @@ namespace Emby.Dlna.PlayTo var command = rendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetVolume"); if (command == null) + { return; + } var service = GetServiceRenderingControl(); @@ -260,7 +264,9 @@ namespace Emby.Dlna.PlayTo var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Seek"); if (command == null) + { return; + } var service = GetAvTransportService(); @@ -285,7 +291,9 @@ namespace Emby.Dlna.PlayTo var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetAVTransportURI"); if (command == null) + { return; + } var dictionary = new Dictionary { @@ -452,7 +460,9 @@ namespace Emby.Dlna.PlayTo _connectFailureCount = 0; if (_disposed) + { return; + } // If we're not playing anything make sure we don't get data more often than neccessry to keep the Session alive if (transportState.Value == TRANSPORTSTATE.STOPPED) @@ -472,7 +482,9 @@ namespace Emby.Dlna.PlayTo catch (Exception ex) { if (_disposed) + { return; + } _logger.LogError(ex, "Error updating device info for {DeviceName}", Properties.Name); @@ -573,7 +585,9 @@ namespace Emby.Dlna.PlayTo cancellationToken: cancellationToken).ConfigureAwait(false); if (result == null || result.Document == null) + { return; + } var valueNode = result.Document.Descendants(uPnpNamespaces.RenderingControl + "GetMuteResponse") .Select(i => i.Element("CurrentMute")) diff --git a/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs index 503de0b4e9..86a5d8b7d8 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs @@ -19,7 +19,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books // Only process items that are in a collection folder containing books if (!string.Equals(collectionType, CollectionType.Books, StringComparison.OrdinalIgnoreCase)) + { return null; + } if (args.IsDirectory) { @@ -55,7 +57,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books // Don't return a Book if there is more (or less) than one document in the directory if (bookFiles.Count != 1) + { return null; + } return new Book { diff --git a/Emby.Server.Implementations/Services/ResponseHelper.cs b/Emby.Server.Implementations/Services/ResponseHelper.cs index 3f1672e94b..a329b531d6 100644 --- a/Emby.Server.Implementations/Services/ResponseHelper.cs +++ b/Emby.Server.Implementations/Services/ResponseHelper.cs @@ -40,7 +40,9 @@ namespace Emby.Server.Implementations.Services if (httpResult != null) { if (httpResult.RequestContext == null) + { httpResult.RequestContext = request; + } response.StatusCode = httpResult.Status; } diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs index 18d7ab46e7..cbc4b754d2 100644 --- a/Emby.Server.Implementations/Services/ServiceExec.cs +++ b/Emby.Server.Implementations/Services/ServiceExec.cs @@ -42,11 +42,15 @@ namespace Emby.Server.Implementations.Services } if (mi.GetParameters().Length != 1) + { continue; + } var actionName = mi.Name; if (!AllVerbs.Contains(actionName, StringComparer.OrdinalIgnoreCase)) + { continue; + } list.Add(mi); } diff --git a/Emby.Server.Implementations/Services/ServicePath.cs b/Emby.Server.Implementations/Services/ServicePath.cs index eb07441893..89538ae729 100644 --- a/Emby.Server.Implementations/Services/ServicePath.cs +++ b/Emby.Server.Implementations/Services/ServicePath.cs @@ -445,12 +445,14 @@ namespace Emby.Server.Implementations.Services && requestComponents.Length >= this.TotalComponentsCount - this.wildcardCount; if (!isValidWildCardPath) + { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "Path Mismatch: Request Path '{0}' has invalid number of components compared to: '{1}'", pathInfo, this.restPath)); + } } var requestKeyValuesMap = new Dictionary(); diff --git a/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs b/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs index ea981e8402..cbca300d2f 100644 --- a/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs +++ b/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs @@ -19,10 +19,14 @@ namespace Emby.Server.Implementations.Sorting public int Compare(BaseItem x, BaseItem y) { if (x == null) + { throw new ArgumentNullException(nameof(x)); + } if (y == null) + { throw new ArgumentNullException(nameof(y)); + } return DateTime.Compare(x.DateCreated, y.DateCreated); } diff --git a/Emby.Server.Implementations/Sorting/RuntimeComparer.cs b/Emby.Server.Implementations/Sorting/RuntimeComparer.cs index f165123eab..dde44333d5 100644 --- a/Emby.Server.Implementations/Sorting/RuntimeComparer.cs +++ b/Emby.Server.Implementations/Sorting/RuntimeComparer.cs @@ -19,10 +19,14 @@ namespace Emby.Server.Implementations.Sorting public int Compare(BaseItem x, BaseItem y) { if (x == null) + { throw new ArgumentNullException(nameof(x)); + } if (y == null) + { throw new ArgumentNullException(nameof(y)); + } return (x.RunTimeTicks ?? 0).CompareTo(y.RunTimeTicks ?? 0); } diff --git a/Emby.Server.Implementations/Sorting/SortNameComparer.cs b/Emby.Server.Implementations/Sorting/SortNameComparer.cs index 93389fc3e8..f745e193b4 100644 --- a/Emby.Server.Implementations/Sorting/SortNameComparer.cs +++ b/Emby.Server.Implementations/Sorting/SortNameComparer.cs @@ -19,10 +19,14 @@ namespace Emby.Server.Implementations.Sorting public int Compare(BaseItem x, BaseItem y) { if (x == null) + { throw new ArgumentNullException(nameof(x)); + } if (y == null) + { throw new ArgumentNullException(nameof(y)); + } return string.Compare(x.SortName, y.SortName, StringComparison.CurrentCultureIgnoreCase); } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 2ad1c717cf..8e0e63ff0b 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -2951,7 +2951,9 @@ namespace MediaBrowser.Controller.Entities public IEnumerable GetTrailers() { if (this is IHasTrailers) + { return ((IHasTrailers)this).LocalTrailerIds.Select(LibraryManager.GetItemById).Where(i => i != null).OrderBy(i => i.SortName); + } else return Array.Empty(); } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs index a8d383a2ad..728efa788d 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs @@ -58,7 +58,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles var endTime = time[1]; var idx = endTime.IndexOf(" ", StringComparison.Ordinal); if (idx > 0) + { endTime = endTime.Substring(0, idx); + } + subEvent.EndPositionTicks = GetTicks(endTime); var multiline = new List(); while ((line = reader.ReadLine()) != null) diff --git a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs index 9a8fcc4316..630a3dce07 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs @@ -41,7 +41,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles lineNumber++; if (!eventsStarted) + { header.AppendLine(line); + } if (line.Trim().ToLowerInvariant() == "[events]") { @@ -62,17 +64,29 @@ namespace MediaBrowser.MediaEncoding.Subtitles for (int i = 0; i < format.Length; i++) { if (format[i].Trim().ToLowerInvariant() == "layer") + { indexLayer = i; + } else if (format[i].Trim().ToLowerInvariant() == "start") + { indexStart = i; + } else if (format[i].Trim().ToLowerInvariant() == "end") + { indexEnd = i; + } else if (format[i].Trim().ToLowerInvariant() == "text") + { indexText = i; + } else if (format[i].Trim().ToLowerInvariant() == "effect") + { indexEffect = i; + } else if (format[i].Trim().ToLowerInvariant() == "style") + { indexStyle = i; + } } } } @@ -89,28 +103,48 @@ namespace MediaBrowser.MediaEncoding.Subtitles string[] splittedLine; if (s.StartsWith("dialogue:")) + { splittedLine = line.Substring(10).Split(','); + } else + { splittedLine = line.Split(','); + } for (int i = 0; i < splittedLine.Length; i++) { if (i == indexStart) + { start = splittedLine[i].Trim(); + } else if (i == indexEnd) + { end = splittedLine[i].Trim(); + } else if (i == indexLayer) + { layer = splittedLine[i]; + } else if (i == indexEffect) + { effect = splittedLine[i]; + } else if (i == indexText) + { text = splittedLine[i]; + } else if (i == indexStyle) + { style = splittedLine[i]; + } else if (i == indexName) + { name = splittedLine[i]; + } else if (i > indexText) + { text += "," + splittedLine[i]; + } } try @@ -169,13 +203,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles CheckAndAddSubTags(ref fontName, ref extraTags, out italic); text = text.Remove(start, end - start + 1); if (italic) + { text = text.Insert(start, ""); + } else text = text.Insert(start, ""); int indexOfEndTag = text.IndexOf("{\\fn}", start); if (indexOfEndTag > 0) + { text = text.Remove(indexOfEndTag, "{\\fn}".Length).Insert(indexOfEndTag, ""); + } else text += ""; } @@ -194,13 +232,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles { text = text.Remove(start, end - start + 1); if (italic) + { text = text.Insert(start, ""); + } else text = text.Insert(start, ""); int indexOfEndTag = text.IndexOf("{\\fs}", start); if (indexOfEndTag > 0) + { text = text.Remove(indexOfEndTag, "{\\fs}".Length).Insert(indexOfEndTag, ""); + } else text += ""; } @@ -226,12 +268,16 @@ namespace MediaBrowser.MediaEncoding.Subtitles text = text.Remove(start, end - start + 1); if (italic) + { text = text.Insert(start, ""); + } else text = text.Insert(start, ""); int indexOfEndTag = text.IndexOf("{\\c}", start); if (indexOfEndTag > 0) + { text = text.Remove(indexOfEndTag, "{\\c}".Length).Insert(indexOfEndTag, ""); + } else text += ""; } @@ -256,7 +302,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles text = text.Remove(start, end - start + 1); if (italic) + { text = text.Insert(start, ""); + } else text = text.Insert(start, ""); text += ""; @@ -268,19 +316,25 @@ namespace MediaBrowser.MediaEncoding.Subtitles text = text.Replace(@"{\i0}", ""); text = text.Replace(@"{\i}", ""); if (CountTagInText(text, "") > CountTagInText(text, "")) + { text += ""; + } text = text.Replace(@"{\u1}", ""); text = text.Replace(@"{\u0}", ""); text = text.Replace(@"{\u}", ""); if (CountTagInText(text, "") > CountTagInText(text, "")) + { text += ""; + } text = text.Replace(@"{\b1}", ""); text = text.Replace(@"{\b0}", ""); text = text.Replace(@"{\b}", ""); if (CountTagInText(text, "") > CountTagInText(text, "")) + { text += ""; + } return text; } @@ -288,7 +342,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles private static bool IsInteger(string s) { if (int.TryParse(s, out var i)) + { return true; + } return false; } @@ -300,7 +356,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles { count++; if (index == text.Length) + { return count; + } index = text.IndexOf(tag, index + 1); } diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs index 47cc892107..df10f8c532 100644 --- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs +++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs @@ -32,18 +32,25 @@ namespace MediaBrowser.Model.Dlna } if (string.Equals(container, "avi", StringComparison.OrdinalIgnoreCase)) + { return new MediaFormatProfile[] { MediaFormatProfile.AVI }; + } if (string.Equals(container, "mkv", StringComparison.OrdinalIgnoreCase)) + { return new MediaFormatProfile[] { MediaFormatProfile.MATROSKA }; + } if (string.Equals(container, "mpeg2ps", StringComparison.OrdinalIgnoreCase) || string.Equals(container, "ts", StringComparison.OrdinalIgnoreCase)) - + { return new MediaFormatProfile[] { MediaFormatProfile.MPEG_PS_NTSC, MediaFormatProfile.MPEG_PS_PAL }; + } if (string.Equals(container, "mpeg1video", StringComparison.OrdinalIgnoreCase)) + { return new MediaFormatProfile[] { MediaFormatProfile.MPEG1 }; + } if (string.Equals(container, "mpeg2ts", StringComparison.OrdinalIgnoreCase) || string.Equals(container, "mpegts", StringComparison.OrdinalIgnoreCase) || @@ -54,10 +61,14 @@ namespace MediaBrowser.Model.Dlna } if (string.Equals(container, "flv", StringComparison.OrdinalIgnoreCase)) + { return new MediaFormatProfile[] { MediaFormatProfile.FLV }; + } if (string.Equals(container, "wtv", StringComparison.OrdinalIgnoreCase)) + { return new MediaFormatProfile[] { MediaFormatProfile.WTV }; + } if (string.Equals(container, "3gp", StringComparison.OrdinalIgnoreCase)) { @@ -66,7 +77,9 @@ namespace MediaBrowser.Model.Dlna } if (string.Equals(container, "ogv", StringComparison.OrdinalIgnoreCase) || string.Equals(container, "ogg", StringComparison.OrdinalIgnoreCase)) + { return new MediaFormatProfile[] { MediaFormatProfile.OGV }; + } return Array.Empty(); } @@ -111,7 +124,9 @@ namespace MediaBrowser.Model.Dlna if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase)) { if (string.Equals(audioCodec, "lpcm", StringComparison.OrdinalIgnoreCase)) + { return new MediaFormatProfile[] { MediaFormatProfile.AVC_TS_HD_50_LPCM_T }; + } if (string.Equals(audioCodec, "dts", StringComparison.OrdinalIgnoreCase)) { @@ -134,14 +149,20 @@ namespace MediaBrowser.Model.Dlna } if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase)) + { return new MediaFormatProfile[] { ValueOf(string.Format("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)) }; + } 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)) }; + } } else if (string.Equals(videoCodec, "vc1", StringComparison.OrdinalIgnoreCase)) { @@ -165,13 +186,24 @@ namespace MediaBrowser.Model.Dlna 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)) }; + } + if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase)) + { return new MediaFormatProfile[] { ValueOf(string.Format("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)) }; + } + if (string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase)) + { return new MediaFormatProfile[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AC3{0}", suffix)) }; + } } return new MediaFormatProfile[] { }; @@ -187,7 +219,9 @@ namespace MediaBrowser.Model.Dlna if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase)) { if (string.Equals(audioCodec, "lpcm", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.AVC_MP4_LPCM; + } if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase)) { @@ -204,12 +238,16 @@ namespace MediaBrowser.Model.Dlna if ((width.Value <= 720) && (height.Value <= 576)) { if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.AVC_MP4_MP_SD_AAC_MULT5; + } } else if ((width.Value <= 1280) && (height.Value <= 720)) { if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.AVC_MP4_MP_HD_720p_AAC; + } } else if ((width.Value <= 1920) && (height.Value <= 1080)) { @@ -226,7 +264,9 @@ namespace MediaBrowser.Model.Dlna if (width.HasValue && height.HasValue && width.Value <= 720 && height.Value <= 576) { if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.MPEG4_P2_MP4_ASP_AAC; + } if (string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase) || string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase)) { return MediaFormatProfile.MPEG4_P2_MP4_NDSD; @@ -250,15 +290,22 @@ namespace MediaBrowser.Model.Dlna if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.AVC_3GPP_BL_QCIF15_AAC; + } } else if (string.Equals(videoCodec, "mpeg4", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "wma", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.MPEG4_P2_3GPP_SP_L0B_AAC; + } + if (string.Equals(audioCodec, "amrnb", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.MPEG4_P2_3GPP_SP_L0B_AMR; + } } else if (string.Equals(videoCodec, "h263", StringComparison.OrdinalIgnoreCase) && string.Equals(audioCodec, "amrnb", StringComparison.OrdinalIgnoreCase)) { @@ -300,11 +347,19 @@ namespace MediaBrowser.Model.Dlna if (width.HasValue && height.HasValue) { if ((width.Value <= 720) && (height.Value <= 576)) + { return MediaFormatProfile.VC1_ASF_AP_L1_WMA; + } + if ((width.Value <= 1280) && (height.Value <= 720)) + { return MediaFormatProfile.VC1_ASF_AP_L2_WMA; + } + if ((width.Value <= 1920) && (height.Value <= 1080)) + { return MediaFormatProfile.VC1_ASF_AP_L3_WMA; + } } } else if (string.Equals(videoCodec, "mpeg2video", StringComparison.OrdinalIgnoreCase)) @@ -318,27 +373,41 @@ namespace MediaBrowser.Model.Dlna public MediaFormatProfile? ResolveAudioFormat(string container, int? bitrate, int? frequency, int? channels) { if (string.Equals(container, "asf", StringComparison.OrdinalIgnoreCase)) + { return ResolveAudioASFFormat(bitrate); + } if (string.Equals(container, "mp3", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.MP3; + } if (string.Equals(container, "lpcm", StringComparison.OrdinalIgnoreCase)) + { return ResolveAudioLPCMFormat(frequency, channels); + } if (string.Equals(container, "mp4", StringComparison.OrdinalIgnoreCase) || string.Equals(container, "aac", StringComparison.OrdinalIgnoreCase)) + { return ResolveAudioMP4Format(bitrate); + } if (string.Equals(container, "adts", StringComparison.OrdinalIgnoreCase)) + { return ResolveAudioADTSFormat(bitrate); + } if (string.Equals(container, "flac", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.FLAC; + } if (string.Equals(container, "oga", StringComparison.OrdinalIgnoreCase) || string.Equals(container, "ogg", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.OGG; + } return null; } @@ -410,13 +479,19 @@ namespace MediaBrowser.Model.Dlna return ResolveImageJPGFormat(width, height); if (string.Equals(container, "png", StringComparison.OrdinalIgnoreCase)) + { return ResolveImagePNGFormat(width, height); + } if (string.Equals(container, "gif", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.GIF_LRG; + } if (string.Equals(container, "raw", StringComparison.OrdinalIgnoreCase)) + { return MediaFormatProfile.RAW; + } return null; } @@ -426,10 +501,14 @@ namespace MediaBrowser.Model.Dlna if (width.HasValue && height.HasValue) { if ((width.Value <= 160) && (height.Value <= 160)) + { return MediaFormatProfile.JPEG_TN; + } if ((width.Value <= 640) && (height.Value <= 480)) + { return MediaFormatProfile.JPEG_SM; + } if ((width.Value <= 1024) && (height.Value <= 768)) { @@ -447,7 +526,9 @@ namespace MediaBrowser.Model.Dlna if (width.HasValue && height.HasValue) { if ((width.Value <= 160) && (height.Value <= 160)) + { return MediaFormatProfile.PNG_TN; + } } return MediaFormatProfile.PNG_LRG; diff --git a/RSSDP/HttpParserBase.cs b/RSSDP/HttpParserBase.cs index 058bfbf555..00c2b7b45a 100644 --- a/RSSDP/HttpParserBase.cs +++ b/RSSDP/HttpParserBase.cs @@ -114,9 +114,13 @@ namespace Rssdp.Infrastructure var headersToAddTo = IsContentHeader(headerName) ? contentHeaders : headers; if (values.Count > 1) + { headersToAddTo.TryAddWithoutValidation(headerName, values); + } else + { headersToAddTo.TryAddWithoutValidation(headerName, values.First()); + } } private int ParseHeaders(System.Net.Http.Headers.HttpHeaders headers, System.Net.Http.Headers.HttpHeaders contentHeaders, string[] lines) @@ -160,7 +164,9 @@ namespace Rssdp.Infrastructure var indexOfSeparator = headerValue.IndexOfAny(SeparatorCharacters); if (indexOfSeparator <= 0) + { values.Add(headerValue); + } else { var segments = headerValue.Split(SeparatorCharacters); @@ -170,7 +176,9 @@ namespace Rssdp.Infrastructure { var segment = segments[segmentIndex]; if (segment.Trim().StartsWith("\"", StringComparison.OrdinalIgnoreCase)) + { segment = CombineQuotedSegments(segments, ref segmentIndex, segment); + } values.Add(segment); } @@ -199,12 +207,16 @@ namespace Rssdp.Infrastructure } if (index + 1 < segments.Length) + { trimmedSegment += "," + segments[index + 1].TrimEnd(); + } } segmentIndex = segments.Length; if (trimmedSegment.StartsWith("\"", StringComparison.OrdinalIgnoreCase) && trimmedSegment.EndsWith("\"", StringComparison.OrdinalIgnoreCase)) + { return trimmedSegment.Substring(1, trimmedSegment.Length - 2); + } else return trimmedSegment; } diff --git a/RSSDP/HttpRequestParser.cs b/RSSDP/HttpRequestParser.cs index 6b27fc4df4..7fa42f4669 100644 --- a/RSSDP/HttpRequestParser.cs +++ b/RSSDP/HttpRequestParser.cs @@ -34,7 +34,9 @@ namespace Rssdp.Infrastructure finally { if (retVal != null) + { retVal.Dispose(); + } } } @@ -64,7 +66,9 @@ namespace Rssdp.Infrastructure message.Method = new HttpMethod(parts[0].Trim()); Uri requestUri; if (Uri.TryCreate(parts[1].Trim(), UriKind.RelativeOrAbsolute, out requestUri)) + { message.RequestUri = requestUri; + } else System.Diagnostics.Debug.WriteLine(parts[1]); diff --git a/RSSDP/HttpResponseParser.cs b/RSSDP/HttpResponseParser.cs index 0337b3e360..0dd4bb45a8 100644 --- a/RSSDP/HttpResponseParser.cs +++ b/RSSDP/HttpResponseParser.cs @@ -34,7 +34,9 @@ namespace Rssdp.Infrastructure catch { if (retVal != null) + { retVal.Dispose(); + } throw; } @@ -77,7 +79,9 @@ namespace Rssdp.Infrastructure int statusCode = -1; if (!Int32.TryParse(parts[1].Trim(), out statusCode)) + { throw new ArgumentException("data status line is invalid. Status code is not a valid integer.", nameof(data)); + } message.StatusCode = (HttpStatusCode)statusCode; diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 31ca90424f..e4c4a2017b 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -480,17 +480,21 @@ namespace Rssdp.Infrastructure var handlers = this.RequestReceived; if (handlers != null) + { handlers(this, new RequestReceivedEventArgs(data, remoteEndPoint, receivedOnLocalIpAddress)); + } } private void OnResponseReceived(HttpResponseMessage data, IPEndPoint endPoint, IPAddress localIpAddress) { var handlers = this.ResponseReceived; if (handlers != null) + { handlers(this, new ResponseReceivedEventArgs(data, endPoint) { LocalIpAddress = localIpAddress }); + } } } } diff --git a/RSSDP/SsdpDevice.cs b/RSSDP/SsdpDevice.cs index 42f95862c5..7030c6ec12 100644 --- a/RSSDP/SsdpDevice.cs +++ b/RSSDP/SsdpDevice.cs @@ -55,7 +55,9 @@ namespace Rssdp var rootDevice = device as SsdpRootDevice; if (rootDevice == null) + { rootDevice = ((SsdpEmbeddedDevice)device).RootDevice; + } return rootDevice; } @@ -163,7 +165,9 @@ namespace Rssdp get { if (String.IsNullOrEmpty(_Udn) && !String.IsNullOrEmpty(this.Uuid)) + { return "uuid:" + this.Uuid; + } else return _Udn; } @@ -283,7 +287,9 @@ namespace Rssdp } if (wasAdded) + { OnDeviceAdded(device); + } } /// @@ -314,7 +320,9 @@ namespace Rssdp } if (wasRemoved) + { OnDeviceRemoved(device); + } } /// @@ -327,7 +335,9 @@ namespace Rssdp { var handlers = this.DeviceAdded; if (handlers != null) + { handlers(this, new DeviceEventArgs(device)); + } } /// @@ -340,7 +350,9 @@ namespace Rssdp { var handlers = this.DeviceRemoved; if (handlers != null) + { handlers(this, new DeviceEventArgs(device)); + } } } } diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs index a774ee23c8..9a31db7a2e 100644 --- a/RSSDP/SsdpDeviceLocator.cs +++ b/RSSDP/SsdpDeviceLocator.cs @@ -217,10 +217,12 @@ namespace Rssdp.Infrastructure var handlers = this.DeviceAvailable; if (handlers != null) + { handlers(this, new DeviceAvailableEventArgs(device, isNewDevice) { LocalIpAddress = localIpAddress }); + } } /// @@ -426,7 +428,9 @@ namespace Rssdp.Infrastructure }; if (NotificationTypeMatchesFilter(deadDevice)) + { OnDeviceUnavailable(deadDevice, false); + } } } } @@ -439,7 +443,9 @@ namespace Rssdp.Infrastructure { message.Headers.TryGetValues(headerName, out values); if (values != null) + { retVal = values.FirstOrDefault(); + } } return retVal; @@ -453,7 +459,9 @@ namespace Rssdp.Infrastructure { message.Headers.TryGetValues(headerName, out values); if (values != null) + { retVal = values.FirstOrDefault(); + } } return retVal; @@ -467,7 +475,9 @@ namespace Rssdp.Infrastructure { request.Headers.TryGetValues(headerName, out values); if (values != null) + { value = values.FirstOrDefault(); + } } Uri retVal; @@ -483,7 +493,9 @@ namespace Rssdp.Infrastructure { response.Headers.TryGetValues(headerName, out values); if (values != null) + { value = values.FirstOrDefault(); + } } Uri retVal; @@ -560,7 +572,9 @@ namespace Rssdp.Infrastructure foreach (var removedDevice in existingDevices) { if (NotificationTypeMatchesFilter(removedDevice)) + { OnDeviceUnavailable(removedDevice, expired); + } } return true; @@ -572,7 +586,9 @@ namespace Rssdp.Infrastructure private TimeSpan SearchTimeToMXValue(TimeSpan searchWaitTime) { if (searchWaitTime.TotalSeconds < 2 || searchWaitTime == TimeSpan.Zero) + { return OneSecond; + } else return searchWaitTime.Subtract(OneSecond); } diff --git a/RSSDP/SsdpDevicePublisher.cs b/RSSDP/SsdpDevicePublisher.cs index 1b64d230dd..7c6e872013 100644 --- a/RSSDP/SsdpDevicePublisher.cs +++ b/RSSDP/SsdpDevicePublisher.cs @@ -215,7 +215,9 @@ namespace Rssdp.Infrastructure if (commsServer != null) { if (!commsServer.IsShared) + { commsServer.Dispose(); + } } _RecentSearchRequests = null; @@ -328,7 +330,9 @@ namespace Rssdp.Infrastructure { SendSearchResponse(SsdpConstants.UpnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), endPoint, receivedOnlocalIpAddress, cancellationToken); if (this.SupportPnpRootDevice) + { SendSearchResponse(SsdpConstants.PnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.PnpDeviceTypeRootDevice), endPoint, receivedOnlocalIpAddress, cancellationToken); + } } SendSearchResponse(device.Udn, device, device.Udn, endPoint, receivedOnlocalIpAddress, cancellationToken); @@ -394,7 +398,9 @@ namespace Rssdp.Infrastructure { var lastRequest = _RecentSearchRequests[newRequest.Key]; if (lastRequest.IsOld()) + { _RecentSearchRequests[newRequest.Key] = newRequest; + } else isDuplicateRequest = true; } @@ -402,7 +408,9 @@ namespace Rssdp.Infrastructure { _RecentSearchRequests.Add(newRequest.Key, newRequest); if (_RecentSearchRequests.Count > 10) + { CleanUpRecentSearchRequestsAsync(); + } } } @@ -462,7 +470,9 @@ namespace Rssdp.Infrastructure { SendAliveNotification(device, SsdpConstants.UpnpDeviceTypeRootDevice, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), cancellationToken); if (this.SupportPnpRootDevice) + { SendAliveNotification(device, SsdpConstants.PnpDeviceTypeRootDevice, GetUsn(device.Udn, SsdpConstants.PnpDeviceTypeRootDevice), cancellationToken); + } } SendAliveNotification(device, device.Udn, device.Udn, cancellationToken); @@ -506,7 +516,9 @@ namespace Rssdp.Infrastructure { tasks.Add(SendByeByeNotification(device, SsdpConstants.UpnpDeviceTypeRootDevice, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), cancellationToken)); if (this.SupportPnpRootDevice) + { tasks.Add(SendByeByeNotification(device, "pnp:rootdevice", GetUsn(device.Udn, "pnp:rootdevice"), cancellationToken)); + } } tasks.Add(SendByeByeNotification(device, device.Udn, device.Udn, cancellationToken)); @@ -547,20 +559,27 @@ namespace Rssdp.Infrastructure var timer = _RebroadcastAliveNotificationsTimer; _RebroadcastAliveNotificationsTimer = null; if (timer != null) + { timer.Dispose(); + } } private TimeSpan GetMinimumNonZeroCacheLifetime() { - var nonzeroCacheLifetimesQuery = (from device - in _Devices - where device.CacheLifetime != TimeSpan.Zero - select device.CacheLifetime).ToList(); + var nonzeroCacheLifetimesQuery = ( + from device + in _Devices + where device.CacheLifetime != TimeSpan.Zero + select device.CacheLifetime).ToList(); if (nonzeroCacheLifetimesQuery.Any()) + { return nonzeroCacheLifetimesQuery.Min(); + } else + { return TimeSpan.Zero; + } } private string GetFirstHeaderValue(System.Net.Http.Headers.HttpRequestHeaders httpRequestHeaders, string headerName) @@ -568,7 +587,9 @@ namespace Rssdp.Infrastructure string retVal = null; IEnumerable values = null; if (httpRequestHeaders.TryGetValues(headerName, out values) && values != null) + { retVal = values.FirstOrDefault(); + } return retVal; } @@ -588,7 +609,9 @@ namespace Rssdp.Infrastructure { var rootDevice = device as SsdpRootDevice; if (rootDevice != null) + { WriteTrace(text + " " + device.DeviceType + " - " + device.Uuid + " - " + rootDevice.Location); + } else WriteTrace(text + " " + device.DeviceType + " - " + device.Uuid); } -- cgit v1.2.3 From 1c78482b480034738516596248955e3e09756dd6 Mon Sep 17 00:00:00 2001 From: David Date: Sat, 20 Jun 2020 18:02:03 +0200 Subject: Use authorization code from api-migration to fix startup wizard --- .../HttpServer/Security/AuthService.cs | 16 ++++ .../HttpServer/Security/AuthorizationContext.cs | 101 ++++++++++++++------- Jellyfin.Api/Auth/CustomAuthenticationHandler.cs | 11 +-- MediaBrowser.Controller/Net/IAuthService.cs | 7 ++ .../Net/IAuthorizationContext.cs | 11 +++ 5 files changed, 108 insertions(+), 38 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs index 2e6ff65a6f..318bc6a248 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs @@ -51,6 +51,22 @@ namespace Emby.Server.Implementations.HttpServer.Security return user; } + public AuthorizationInfo Authenticate(HttpRequest request) + { + var auth = _authorizationContext.GetAuthorizationInfo(request); + if (auth?.User == null) + { + return null; + } + + if (auth.User.HasPermission(PermissionKind.IsDisabled)) + { + throw new SecurityException("User account has been disabled."); + } + + return auth; + } + private User ValidateUser(IRequest request, IAuthenticationAttributes authAttribtues) { // This code is executed before the service diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs index bbade00ff3..078ce0d8a8 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs @@ -8,6 +8,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Security; using MediaBrowser.Model.Services; +using Microsoft.AspNetCore.Http; using Microsoft.Net.Http.Headers; namespace Emby.Server.Implementations.HttpServer.Security @@ -38,6 +39,14 @@ namespace Emby.Server.Implementations.HttpServer.Security return GetAuthorization(requestContext); } + public AuthorizationInfo GetAuthorizationInfo(HttpRequest requestContext) + { + var auth = GetAuthorizationDictionary(requestContext); + var (authInfo, _) = + GetAuthorizationInfoFromDictionary(auth, requestContext.Headers, requestContext.Query); + return authInfo; + } + /// /// Gets the authorization. /// @@ -46,7 +55,23 @@ namespace Emby.Server.Implementations.HttpServer.Security private AuthorizationInfo GetAuthorization(IRequest httpReq) { var auth = GetAuthorizationDictionary(httpReq); + var (authInfo, originalAuthInfo) = + GetAuthorizationInfoFromDictionary(auth, httpReq.Headers, httpReq.QueryString); + + if (originalAuthInfo != null) + { + httpReq.Items["OriginalAuthenticationInfo"] = originalAuthInfo; + } + + httpReq.Items["AuthorizationInfo"] = authInfo; + return authInfo; + } + private (AuthorizationInfo authInfo, AuthenticationInfo originalAuthenticationInfo) GetAuthorizationInfoFromDictionary( + in Dictionary auth, + in IHeaderDictionary headers, + in IQueryCollection queryString) + { string deviceId = null; string device = null; string client = null; @@ -64,20 +89,20 @@ namespace Emby.Server.Implementations.HttpServer.Security if (string.IsNullOrEmpty(token)) { - token = httpReq.Headers["X-Emby-Token"]; + token = headers["X-Emby-Token"]; } if (string.IsNullOrEmpty(token)) { - token = httpReq.Headers["X-MediaBrowser-Token"]; + token = headers["X-MediaBrowser-Token"]; } if (string.IsNullOrEmpty(token)) { - token = httpReq.QueryString["api_key"]; + token = queryString["api_key"]; } - var info = new AuthorizationInfo + var authInfo = new AuthorizationInfo { Client = client, Device = device, @@ -86,6 +111,7 @@ namespace Emby.Server.Implementations.HttpServer.Security Token = token }; + AuthenticationInfo originalAuthenticationInfo = null; if (!string.IsNullOrWhiteSpace(token)) { var result = _authRepo.Get(new AuthenticationInfoQuery @@ -93,81 +119,77 @@ namespace Emby.Server.Implementations.HttpServer.Security AccessToken = token }); - var tokenInfo = result.Items.Count > 0 ? result.Items[0] : null; + originalAuthenticationInfo = result.Items.Count > 0 ? result.Items[0] : null; - if (tokenInfo != null) + if (originalAuthenticationInfo != null) { var updateToken = false; // TODO: Remove these checks for IsNullOrWhiteSpace - if (string.IsNullOrWhiteSpace(info.Client)) + if (string.IsNullOrWhiteSpace(authInfo.Client)) { - info.Client = tokenInfo.AppName; + authInfo.Client = originalAuthenticationInfo.AppName; } - if (string.IsNullOrWhiteSpace(info.DeviceId)) + if (string.IsNullOrWhiteSpace(authInfo.DeviceId)) { - info.DeviceId = tokenInfo.DeviceId; + authInfo.DeviceId = originalAuthenticationInfo.DeviceId; } // Temporary. TODO - allow clients to specify that the token has been shared with a casting device - var allowTokenInfoUpdate = info.Client == null || info.Client.IndexOf("chromecast", StringComparison.OrdinalIgnoreCase) == -1; + var allowTokenInfoUpdate = authInfo.Client == null || authInfo.Client.IndexOf("chromecast", StringComparison.OrdinalIgnoreCase) == -1; - if (string.IsNullOrWhiteSpace(info.Device)) + if (string.IsNullOrWhiteSpace(authInfo.Device)) { - info.Device = tokenInfo.DeviceName; + authInfo.Device = originalAuthenticationInfo.DeviceName; } - else if (!string.Equals(info.Device, tokenInfo.DeviceName, StringComparison.OrdinalIgnoreCase)) + else if (!string.Equals(authInfo.Device, originalAuthenticationInfo.DeviceName, StringComparison.OrdinalIgnoreCase)) { if (allowTokenInfoUpdate) { updateToken = true; - tokenInfo.DeviceName = info.Device; + originalAuthenticationInfo.DeviceName = authInfo.Device; } } - if (string.IsNullOrWhiteSpace(info.Version)) + if (string.IsNullOrWhiteSpace(authInfo.Version)) { - info.Version = tokenInfo.AppVersion; + authInfo.Version = originalAuthenticationInfo.AppVersion; } - else if (!string.Equals(info.Version, tokenInfo.AppVersion, StringComparison.OrdinalIgnoreCase)) + else if (!string.Equals(authInfo.Version, originalAuthenticationInfo.AppVersion, StringComparison.OrdinalIgnoreCase)) { if (allowTokenInfoUpdate) { updateToken = true; - tokenInfo.AppVersion = info.Version; + originalAuthenticationInfo.AppVersion = authInfo.Version; } } - if ((DateTime.UtcNow - tokenInfo.DateLastActivity).TotalMinutes > 3) + if ((DateTime.UtcNow - originalAuthenticationInfo.DateLastActivity).TotalMinutes > 3) { - tokenInfo.DateLastActivity = DateTime.UtcNow; + originalAuthenticationInfo.DateLastActivity = DateTime.UtcNow; updateToken = true; } - if (!tokenInfo.UserId.Equals(Guid.Empty)) + if (!originalAuthenticationInfo.UserId.Equals(Guid.Empty)) { - info.User = _userManager.GetUserById(tokenInfo.UserId); + authInfo.User = _userManager.GetUserById(originalAuthenticationInfo.UserId); - if (info.User != null && !string.Equals(info.User.Username, tokenInfo.UserName, StringComparison.OrdinalIgnoreCase)) + if (authInfo.User != null && !string.Equals(authInfo.User.Username, originalAuthenticationInfo.UserName, StringComparison.OrdinalIgnoreCase)) { - tokenInfo.UserName = info.User.Username; + originalAuthenticationInfo.UserName = authInfo.User.Username; updateToken = true; } } if (updateToken) { - _authRepo.Update(tokenInfo); + _authRepo.Update(originalAuthenticationInfo); } } - - httpReq.Items["OriginalAuthenticationInfo"] = tokenInfo; } - httpReq.Items["AuthorizationInfo"] = info; - - return info; + return (authInfo, originalAuthenticationInfo); } /// @@ -187,6 +209,23 @@ namespace Emby.Server.Implementations.HttpServer.Security return GetAuthorization(auth); } + /// + /// Gets the auth. + /// + /// The HTTP req. + /// Dictionary{System.StringSystem.String}. + private Dictionary GetAuthorizationDictionary(HttpRequest httpReq) + { + var auth = httpReq.Headers["X-Emby-Authorization"]; + + if (string.IsNullOrEmpty(auth)) + { + auth = httpReq.Headers[HeaderNames.Authorization]; + } + + return GetAuthorization(auth); + } + /// /// Gets the authorization. /// diff --git a/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs index 767ba9fd4b..f86f75b1cb 100644 --- a/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs +++ b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs @@ -39,21 +39,18 @@ namespace Jellyfin.Api.Auth /// protected override Task HandleAuthenticateAsync() { - var authenticatedAttribute = new AuthenticatedAttribute(); try { - var user = _authService.Authenticate(Request, authenticatedAttribute); - if (user == null) + var authorizationInfo = _authService.Authenticate(Request); + if (authorizationInfo == null) { return Task.FromResult(AuthenticateResult.Fail("Invalid user")); } var claims = new[] { - new Claim(ClaimTypes.Name, user.Username), - new Claim( - ClaimTypes.Role, - value: user.HasPermission(PermissionKind.IsAdministrator) ? UserRoles.Administrator : UserRoles.User) + new Claim(ClaimTypes.Name, authorizationInfo.User.Username), + new Claim(ClaimTypes.Role, authorizationInfo.User.HasPermission(PermissionKind.IsAdministrator) ? UserRoles.Administrator : UserRoles.User) }; var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); diff --git a/MediaBrowser.Controller/Net/IAuthService.cs b/MediaBrowser.Controller/Net/IAuthService.cs index d8f6d19da0..56737dc65e 100644 --- a/MediaBrowser.Controller/Net/IAuthService.cs +++ b/MediaBrowser.Controller/Net/IAuthService.cs @@ -11,5 +11,12 @@ namespace MediaBrowser.Controller.Net void Authenticate(IRequest request, IAuthenticationAttributes authAttribtues); User? Authenticate(HttpRequest request, IAuthenticationAttributes authAttribtues); + + /// + /// Authenticate request. + /// + /// The request. + /// Authorization information. Null if unauthenticated. + AuthorizationInfo Authenticate(HttpRequest request); } } diff --git a/MediaBrowser.Controller/Net/IAuthorizationContext.cs b/MediaBrowser.Controller/Net/IAuthorizationContext.cs index 61598391ff..37a7425b9d 100644 --- a/MediaBrowser.Controller/Net/IAuthorizationContext.cs +++ b/MediaBrowser.Controller/Net/IAuthorizationContext.cs @@ -1,7 +1,11 @@ using MediaBrowser.Model.Services; +using Microsoft.AspNetCore.Http; namespace MediaBrowser.Controller.Net { + /// + /// IAuthorization context. + /// public interface IAuthorizationContext { /// @@ -17,5 +21,12 @@ namespace MediaBrowser.Controller.Net /// The request context. /// AuthorizationInfo. AuthorizationInfo GetAuthorizationInfo(IRequest requestContext); + + /// + /// Gets the authorization information. + /// + /// The request context. + /// AuthorizationInfo. + AuthorizationInfo GetAuthorizationInfo(HttpRequest requestContext); } } -- cgit v1.2.3 From 1c371812aa06df9ed3047892e0d5e9cf18ee10f5 Mon Sep 17 00:00:00 2001 From: Nitish Raj Uprety Date: Sun, 21 Jun 2020 14:23:47 +0000 Subject: Added translation using Weblate (Nepali) --- Emby.Server.Implementations/Localization/Core/ne.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 Emby.Server.Implementations/Localization/Core/ne.json (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/ne.json b/Emby.Server.Implementations/Localization/Core/ne.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/Emby.Server.Implementations/Localization/Core/ne.json @@ -0,0 +1 @@ +{} -- cgit v1.2.3 From 18602b472420d575447bfaa6931e1d61bb2c448c Mon Sep 17 00:00:00 2001 From: andyguerra Date: Sun, 21 Jun 2020 16:32:47 +0000 Subject: Translated using Weblate (Spanish (Latin America)) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/es_419/ --- Emby.Server.Implementations/Localization/Core/es_419.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/es_419.json b/Emby.Server.Implementations/Localization/Core/es_419.json index b0fdc8386c..0959ef2ca0 100644 --- a/Emby.Server.Implementations/Localization/Core/es_419.json +++ b/Emby.Server.Implementations/Localization/Core/es_419.json @@ -1,5 +1,5 @@ { - "LabelRunningTimeValue": "Duración: {0}", + "LabelRunningTimeValue": "Tiempo en ejecución: {0}", "ValueSpecialEpisodeName": "Especial - {0}", "Sync": "Sincronizar", "Songs": "Canciones", -- cgit v1.2.3 From c3349038c4270c65caa46b148ef6802f083e5e19 Mon Sep 17 00:00:00 2001 From: Nitish Raj Uprety Date: Sun, 21 Jun 2020 14:26:34 +0000 Subject: Translated using Weblate (Nepali) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ne/ --- .../Localization/Core/ne.json | 63 +++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/ne.json b/Emby.Server.Implementations/Localization/Core/ne.json index 0967ef424b..73fae3931e 100644 --- a/Emby.Server.Implementations/Localization/Core/ne.json +++ b/Emby.Server.Implementations/Localization/Core/ne.json @@ -1 +1,62 @@ -{} +{ + "NotificationOptionUserLockedOut": "प्रयोगकर्ता प्रतिबन्धित", + "NotificationOptionTaskFailed": "निर्धारित कार्य विफलता", + "NotificationOptionServerRestartRequired": "सर्भर रिस्टार्ट आवाश्यक छ", + "NotificationOptionPluginUpdateInstalled": "प्लगइन अद्यावधिक स्थापना भयो", + "NotificationOptionPluginUninstalled": "प्लगइन विस्थापित", + "NotificationOptionPluginInstalled": "प्लगइन स्थापना भयो", + "NotificationOptionPluginError": "प्लगइन असफलता", + "NotificationOptionNewLibraryContent": "नयाँ सामग्री थपियो", + "NotificationOptionInstallationFailed": "स्थापना असफलता", + "NotificationOptionCameraImageUploaded": "क्यामेरा फोटो अपलोड गरियो", + "NotificationOptionAudioPlaybackStopped": "ध्वनि प्रक्षेपण रोकियो", + "NotificationOptionAudioPlayback": "ध्वनि प्रक्षेपण शुरू भयो", + "NotificationOptionApplicationUpdateInstalled": "अनुप्रयोग अद्यावधिक स्थापना भयो", + "NotificationOptionApplicationUpdateAvailable": "अनुप्रयोग अपडेट उपलब्ध छ", + "NewVersionIsAvailable": "जेलीफिन सर्भर को नयाँ संस्करण डाउनलोड को लागी उपलब्ध छ।", + "NameSeasonUnknown": "अज्ञात श्रृंखला", + "NameSeasonNumber": "श्रृंखला {0}", + "NameInstallFailed": "{0} स्थापना असफल भयो", + "MusicVideos": "सांगीतिक भिडियोहरू", + "Music": "संगीत", + "Movies": "चलचित्रहरू", + "MixedContent": "मिश्रित सामग्री", + "MessageServerConfigurationUpdated": "सर्भर कन्फिगरेसन अद्यावधिक गरिएको छ", + "MessageNamedServerConfigurationUpdatedWithValue": "सर्भर कन्फिगरेसन विभाग {0} अद्यावधिक गरिएको छ", + "MessageApplicationUpdatedTo": "जेलीफिन सर्भर {0} मा अद्यावधिक गरिएको छ", + "MessageApplicationUpdated": "जेलीफिन सर्भर अपडेट गरिएको छ", + "Latest": "नविनतम", + "LabelRunningTimeValue": "कुल समय: {0}", + "LabelIpAddressValue": "आईपी ठेगाना: {0}", + "ItemRemovedWithName": "{0}लाई पुस्तकालयबाट हटाईयो", + "ItemAddedWithName": "{0} लाईब्रेरीमा थपियो", + "Inherit": "इनहेरिट", + "HomeVideos": "घरेलु भिडियोहरू", + "HeaderRecordingGroups": "रेकर्ड समूहहरू", + "HeaderNextUp": "आगामी", + "HeaderLiveTV": "प्रत्यक्ष टिभी", + "HeaderFavoriteSongs": "मनपर्ने गीतहरू", + "HeaderFavoriteShows": "मनपर्ने कार्यक्रमहरू", + "HeaderFavoriteEpisodes": "मनपर्ने एपिसोडहरू", + "HeaderFavoriteArtists": "मनपर्ने कलाकारहरू", + "HeaderFavoriteAlbums": "मनपर्ने एल्बमहरू", + "HeaderContinueWatching": "हेर्न जारी राख्नुहोस्", + "HeaderCameraUploads": "क्यामेरा अपलोडहरू", + "HeaderAlbumArtists": "एल्बमका कलाकारहरू", + "Genres": "विधाहरू", + "Folders": "फोल्डरहरू", + "Favorites": "मनपर्ने", + "FailedLoginAttemptWithUserName": "{0}को लग इन प्रयास असफल", + "DeviceOnlineWithName": "{0}को साथ जडित", + "DeviceOfflineWithName": "{0}बाट विच्छेदन भयो", + "Collections": "संग्रह", + "ChapterNameValue": "अध्याय {0}", + "Channels": "च्यानलहरू", + "AppDeviceValues": "अनुप्रयोग: {0}, उपकरण: {1}", + "AuthenticationSucceededWithUserName": "{0} सफलतापूर्वक प्रमाणीकरण गरियो", + "CameraImageUploadedFrom": "{0}बाट नयाँ क्यामेरा छवि अपलोड गरिएको छ", + "Books": "पुस्तकहरु", + "Artists": "कलाकारहरू", + "Application": "अनुप्रयोगहरू", + "Albums": "एल्बमहरू" +} -- cgit v1.2.3 From f75024fadea23f374fc865c8da07814cc9b3b3c9 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Mon, 22 Jun 2020 10:06:35 +0200 Subject: Fix scan crashed --- Emby.Server.Implementations/Library/LibraryManager.cs | 3 ++- MediaBrowser.Providers/Manager/ItemImageProvider.cs | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index edb58e9102..6a20a015ad 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -2897,7 +2897,8 @@ namespace Emby.Server.Implementations.Library } catch (HttpException ex) { - if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound) + if (ex.StatusCode.HasValue + && (ex.StatusCode.Value == HttpStatusCode.NotFound || ex.StatusCode.Value == HttpStatusCode.Forbidden)) { continue; } diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index 32f1a7b2da..6cc3ca3691 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -475,7 +475,8 @@ namespace MediaBrowser.Providers.Manager catch (HttpException ex) { // Sometimes providers send back bad url's. Just move to the next image - if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound) + if (ex.StatusCode.HasValue + && (ex.StatusCode.Value == HttpStatusCode.NotFound || ex.StatusCode.Value == HttpStatusCode.Forbidden)) { continue; } @@ -589,7 +590,8 @@ namespace MediaBrowser.Providers.Manager catch (HttpException ex) { // Sometimes providers send back bad urls. Just move onto the next image - if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound) + if (ex.StatusCode.HasValue + && (ex.StatusCode.Value == HttpStatusCode.NotFound || ex.StatusCode.Value == HttpStatusCode.Forbidden)) { continue; } -- cgit v1.2.3 From c20400fa40d88329b1187aed84ead66e8cae4dde Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 22 Jun 2020 10:13:28 +0100 Subject: Prevent system plugins from being uninstalled --- Emby.Server.Implementations/Updates/InstallationManager.cs | 6 ++++++ MediaBrowser.Common/Plugins/BasePlugin.cs | 9 ++++++++- MediaBrowser.Common/Plugins/IPlugin.cs | 5 +++++ MediaBrowser.Model/Plugins/PluginInfo.cs | 6 ++++++ 4 files changed, 25 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 80326fddf2..0e912dfe9c 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -402,6 +402,12 @@ namespace Emby.Server.Implementations.Updates /// The plugin. public void UninstallPlugin(IPlugin plugin) { + if (!plugin.CanUninstall) + { + _logger.LogInformation("Attempt to delete non removable plugin {0}", plugin.Name); + return; + } + plugin.OnUninstalling(); // Remove it the quick way for now diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index 9e4a360c38..aab07c1fb6 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -2,6 +2,7 @@ using System; using System.IO; +using System.Reflection; using MediaBrowser.Common.Configuration; using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Serialization; @@ -49,6 +50,11 @@ namespace MediaBrowser.Common.Plugins /// The data folder path. public string DataFolderPath { get; private set; } + /// + /// Gets a value indicating whether the plugin can be uninstalled. + /// + public bool CanUninstall => !Path.GetDirectoryName(AssemblyFilePath).Equals(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), StringComparison.InvariantCulture); + /// /// Gets the plugin info. /// @@ -60,7 +66,8 @@ namespace MediaBrowser.Common.Plugins Name = Name, Version = Version.ToString(), Description = Description, - Id = Id.ToString() + Id = Id.ToString(), + CanUninstall = CanUninstall }; return info; diff --git a/MediaBrowser.Common/Plugins/IPlugin.cs b/MediaBrowser.Common/Plugins/IPlugin.cs index d348209613..7bd37d2106 100644 --- a/MediaBrowser.Common/Plugins/IPlugin.cs +++ b/MediaBrowser.Common/Plugins/IPlugin.cs @@ -40,6 +40,11 @@ namespace MediaBrowser.Common.Plugins /// The assembly file path. string AssemblyFilePath { get; } + /// + /// Gets a value indicating whether the plugin can be uninstalled. + /// + bool CanUninstall { get; } + /// /// Gets the full path to the data folder, where the plugin can store any miscellaneous files needed. /// diff --git a/MediaBrowser.Model/Plugins/PluginInfo.cs b/MediaBrowser.Model/Plugins/PluginInfo.cs index c13f1a89f1..dd215192f9 100644 --- a/MediaBrowser.Model/Plugins/PluginInfo.cs +++ b/MediaBrowser.Model/Plugins/PluginInfo.cs @@ -35,6 +35,12 @@ namespace MediaBrowser.Model.Plugins /// /// The unique id. public string Id { get; set; } + + /// + /// Gets or sets a value indicating whether the plugin can be uninstalled. + /// + public bool CanUninstall { get; set; } + /// /// Gets or sets the image URL. /// -- cgit v1.2.3 From a20fd341618499fe151e623e0c40e975ea708ad1 Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 22 Jun 2020 11:04:20 +0100 Subject: Update Emby.Server.Implementations/Updates/InstallationManager.cs Co-authored-by: Vasily --- Emby.Server.Implementations/Updates/InstallationManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 0e912dfe9c..fbbc97029c 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -404,7 +404,7 @@ namespace Emby.Server.Implementations.Updates { if (!plugin.CanUninstall) { - _logger.LogInformation("Attempt to delete non removable plugin {0}", plugin.Name); + _logger.LogWarning("Attempt to delete non removable plugin {0}, ignoring request", plugin.Name); return; } -- cgit v1.2.3 From 3d42f3753889f15f7013d0216f577a7ba6e3120c Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Mon, 22 Jun 2020 15:35:53 +0200 Subject: Minor changes --- .../Updates/InstallationManager.cs | 18 +++++---------- .../Updates/IInstallationManager.cs | 3 +-- .../Configuration/BaseApplicationConfiguration.cs | 26 +++++++++++----------- MediaBrowser.Model/Updates/RepositoryInfo.cs | 7 ++---- 4 files changed, 22 insertions(+), 32 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index b1bab8cdd2..b8769cd239 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -1,7 +1,6 @@ #pragma warning disable CS1591 using System; -using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; @@ -17,12 +16,10 @@ using MediaBrowser.Common.Net; using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Updates; using MediaBrowser.Controller.Configuration; -using MediaBrowser.Model.Events; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Updates; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Updates @@ -49,7 +46,6 @@ namespace Emby.Server.Implementations.Updates private readonly IApplicationHost _applicationHost; private readonly IZipClient _zipClient; - private readonly IConfiguration _appConfig; private readonly object _currentInstallationsLock = new object(); @@ -71,8 +67,7 @@ namespace Emby.Server.Implementations.Updates IJsonSerializer jsonSerializer, IServerConfigurationManager config, IFileSystem fileSystem, - IZipClient zipClient, - IConfiguration appConfig) + IZipClient zipClient) { if (logger == null) { @@ -90,7 +85,6 @@ namespace Emby.Server.Implementations.Updates _config = config; _fileSystem = fileSystem; _zipClient = zipClient; - _appConfig = appConfig; } /// @@ -118,7 +112,7 @@ namespace Emby.Server.Implementations.Updates public IEnumerable CompletedInstallations => _completedInstallationsInternal; /// - public async Task> GetPackages(string manifest, CancellationToken cancellationToken = default) + public async Task> GetPackages(string manifest, CancellationToken cancellationToken = default) { try { @@ -140,19 +134,19 @@ namespace Emby.Server.Implementations.Updates catch (SerializationException ex) { _logger.LogError(ex, "Failed to deserialize the plugin manifest retrieved from {Manifest}", manifest); - return Enumerable.Empty(); + return Array.Empty(); } } } catch (UriFormatException ex) { _logger.LogError(ex, "The URL configured for the plugin repository manifest URL is not valid: {Manifest}", manifest); - return Enumerable.Empty(); + return Array.Empty(); } catch (HttpException ex) { _logger.LogError(ex, "An error occurred while accessing the plugin manifest: {Manifest}", manifest); - return Enumerable.Empty(); + return Array.Empty(); } } @@ -165,7 +159,7 @@ namespace Emby.Server.Implementations.Updates result.AddRange(await GetPackages(repository.Url, cancellationToken).ConfigureAwait(true)); } - return result.AsReadOnly(); + return result; } /// diff --git a/MediaBrowser.Common/Updates/IInstallationManager.cs b/MediaBrowser.Common/Updates/IInstallationManager.cs index a5025aee96..4b4030bc27 100644 --- a/MediaBrowser.Common/Updates/IInstallationManager.cs +++ b/MediaBrowser.Common/Updates/IInstallationManager.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Plugins; -using MediaBrowser.Model.Events; using MediaBrowser.Model.Updates; namespace MediaBrowser.Common.Updates @@ -46,7 +45,7 @@ namespace MediaBrowser.Common.Updates /// The URL to query. /// The cancellation token. /// Task{IReadOnlyList{PackageInfo}}. - Task> GetPackages(string manifest, CancellationToken cancellationToken = default); + Task> GetPackages(string manifest, CancellationToken cancellationToken = default); /// /// Gets all available packages. diff --git a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs index 54f4fb293c..66f3e1a94b 100644 --- a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs +++ b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs @@ -12,7 +12,15 @@ namespace MediaBrowser.Model.Configuration public class BaseApplicationConfiguration { /// - /// The number of days we should retain log files. + /// Initializes a new instance of the class. + /// + public BaseApplicationConfiguration() + { + LogFileRetentionDays = 3; + } + + /// + /// Gets or sets the number of days we should retain log files. /// /// The log file retention days. public int LogFileRetentionDays { get; set; } @@ -30,29 +38,21 @@ namespace MediaBrowser.Model.Configuration public string CachePath { get; set; } /// - /// Last known version that was ran using the configuration. + /// Gets or sets the last known version that was ran using the configuration. /// /// The version from previous run. [XmlIgnore] public Version PreviousVersion { get; set; } /// - /// Stringified PreviousVersion to be stored/loaded, - /// because System.Version itself isn't xml-serializable + /// Gets or sets the stringified PreviousVersion to be stored/loaded, + /// because System.Version itself isn't xml-serializable. /// - /// String value of PreviousVersion + /// String value of PreviousVersion. public string PreviousVersionStr { get => PreviousVersion?.ToString(); set => PreviousVersion = Version.Parse(value); } - - /// - /// Initializes a new instance of the class. - /// - public BaseApplicationConfiguration() - { - LogFileRetentionDays = 3; - } } } diff --git a/MediaBrowser.Model/Updates/RepositoryInfo.cs b/MediaBrowser.Model/Updates/RepositoryInfo.cs index 905327c368..bd42e77f0f 100644 --- a/MediaBrowser.Model/Updates/RepositoryInfo.cs +++ b/MediaBrowser.Model/Updates/RepositoryInfo.cs @@ -1,6 +1,3 @@ -#nullable disable -using System; - namespace MediaBrowser.Model.Updates { /// @@ -12,12 +9,12 @@ namespace MediaBrowser.Model.Updates /// Gets or sets the name. /// /// The name. - public string Name { get; set; } + public string? Name { get; set; } /// /// Gets or sets the URL. /// /// The URL. - public string Url { get; set; } + public string? Url { get; set; } } } -- cgit v1.2.3 From 5b0c1829084b8f54cd5356880d82b75723badf81 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 24 Jun 2020 14:31:17 +0100 Subject: Added logging and broadcast = true Not intended for merge into the fork. --- Emby.Server.Implementations/Net/SocketFactory.cs | 15 ++++++++++++++- MediaBrowser.Model/Net/ISocketFactory.cs | 5 ++++- RSSDP/SsdpCommunicationsServer.cs | 14 +++++++++----- 3 files changed, 27 insertions(+), 7 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index 1777216584..bed79a9adc 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -4,6 +4,7 @@ using System; using System.Net; using System.Net.Sockets; using MediaBrowser.Model.Net; +using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Net { @@ -67,7 +68,7 @@ namespace Emby.Server.Implementations.Net /// The multicast time to live value for the acceptSocket. /// The number of the local port to bind to. /// - public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) + public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger _logger) { if (ipAddress == null) { @@ -89,6 +90,8 @@ namespace Emby.Server.Implementations.Net throw new ArgumentException("localPort cannot be less than zero.", nameof(localPort)); } + _logger.LogError("Created"); + var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try @@ -100,6 +103,8 @@ namespace Emby.Server.Implementations.Net { } + _logger.LogError("Exclusive false"); + try { // seeing occasional exceptions thrown on qnap @@ -110,8 +115,14 @@ namespace Emby.Server.Implementations.Net { } + _logger.LogError("Reused"); + try { + retVal.EnableBroadcast = true; // CHANGE + + _logger.LogError("Broadcast"); + // retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicastTimeToLive); @@ -120,6 +131,8 @@ namespace Emby.Server.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); retVal.MulticastLoopback = true; + _logger.LogError("Sorted"); + return new UdpSocket(retVal, localPort, localIp); } catch diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index 363abefc19..3a19590a9b 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -1,6 +1,7 @@ #pragma warning disable CS1591 using System.Net; +using Microsoft.Extensions.Logging; namespace MediaBrowser.Model.Net { @@ -22,7 +23,9 @@ namespace MediaBrowser.Model.Net /// The multicast IP address to bind to. /// The multicast time to live value. Actually a maximum number of network hops for UDP packets. /// The local port to bind to. + /// /// A implementation. - ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); + ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger logger); + } } diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 8fde700e0c..34b67a945f 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -338,9 +338,12 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { - var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort, _logger); - _ = ListenToSocketInternal(socket); + // TODO: remove this try and logging - testing purposes only. + _logger.LogError("Socket Created."); + + _ = ListenToSocketInternal(socket, _logger); return socket; } @@ -374,16 +377,16 @@ namespace Rssdp.Infrastructure foreach (var socket in sockets) { - _ = ListenToSocketInternal(socket); + _ = ListenToSocketInternal(socket, _logger); } return sockets; } - private async Task ListenToSocketInternal(ISocket socket) + private async Task ListenToSocketInternal(ISocket socket, ILogger logger) { var cancelled = false; - var receiveBuffer = new byte[8192]; + var receiveBuffer = new byte[8192]; while (!cancelled && !IsDisposed) { @@ -393,6 +396,7 @@ namespace Rssdp.Infrastructure if (result.ReceivedBytes > 0) { + _logger.LogError("processing..."); // Strange cannot convert compiler error here if I don't explicitly // assign or cast to Action first. Assignment is easier to read, // so went with that. -- cgit v1.2.3 From c07d8abfd57fbdc67ad2a0189e1c6149b8244a65 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 24 Jun 2020 17:11:02 +0100 Subject: Removed debugging info --- Emby.Server.Implementations/Net/SocketFactory.cs | 18 ++++-------------- MediaBrowser.Model/Net/ISocketFactory.cs | 3 +-- RSSDP/SsdpCommunicationsServer.cs | 13 ++++--------- 3 files changed, 9 insertions(+), 25 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index bed79a9adc..e79a63ff25 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -20,6 +20,7 @@ namespace Emby.Server.Implementations.Net var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try { + retVal.EnableBroadcast = true; retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); @@ -47,6 +48,7 @@ namespace Emby.Server.Implementations.Net var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try { + retVal.EnableBroadcast = true; retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4); @@ -68,7 +70,7 @@ namespace Emby.Server.Implementations.Net /// The multicast time to live value for the acceptSocket. /// The number of the local port to bind to. /// - public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger _logger) + public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) { if (ipAddress == null) { @@ -90,8 +92,6 @@ namespace Emby.Server.Implementations.Net throw new ArgumentException("localPort cannot be less than zero.", nameof(localPort)); } - _logger.LogError("Created"); - var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try @@ -103,8 +103,6 @@ namespace Emby.Server.Implementations.Net { } - _logger.LogError("Exclusive false"); - try { // seeing occasional exceptions thrown on qnap @@ -115,14 +113,9 @@ namespace Emby.Server.Implementations.Net { } - _logger.LogError("Reused"); - try { - retVal.EnableBroadcast = true; // CHANGE - - _logger.LogError("Broadcast"); - + retVal.EnableBroadcast = true; // retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicastTimeToLive); @@ -130,9 +123,6 @@ namespace Emby.Server.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); retVal.MulticastLoopback = true; - - _logger.LogError("Sorted"); - return new UdpSocket(retVal, localPort, localIp); } catch diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index 3a19590a9b..c4e1540645 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -23,9 +23,8 @@ namespace MediaBrowser.Model.Net /// The multicast IP address to bind to. /// The multicast time to live value. Actually a maximum number of network hops for UDP packets. /// The local port to bind to. - /// /// A implementation. - ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger logger); + ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); } } diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 34b67a945f..0ff56ebacf 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -338,12 +338,8 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { - var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort, _logger); - - // TODO: remove this try and logging - testing purposes only. - _logger.LogError("Socket Created."); - - _ = ListenToSocketInternal(socket, _logger); + var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + _ = ListenToSocketInternal(socket); return socket; } @@ -377,13 +373,13 @@ namespace Rssdp.Infrastructure foreach (var socket in sockets) { - _ = ListenToSocketInternal(socket, _logger); + _ = ListenToSocketInternal(socket); } return sockets; } - private async Task ListenToSocketInternal(ISocket socket, ILogger logger) + private async Task ListenToSocketInternal(ISocket socket) { var cancelled = false; var receiveBuffer = new byte[8192]; @@ -396,7 +392,6 @@ namespace Rssdp.Infrastructure if (result.ReceivedBytes > 0) { - _logger.LogError("processing..."); // Strange cannot convert compiler error here if I don't explicitly // assign or cast to Action first. Assignment is easier to read, // so went with that. -- cgit v1.2.3 From f01baad05e5abc8875fa36f9075f8684857115e7 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 24 Jun 2020 17:23:16 +0100 Subject: Sending multicasts out of Sockets without setting the broadcast to true - causes the error "Bad value for ai_flags" on some systems (#3404) The underlying cause looks to be https://github.com/dotnet/runtime/issues/28630. Basically, it's an access denied bug. It looks like multicasts need the same access rights as broadcasts on some systems. --- Emby.Server.Implementations/Net/SocketFactory.cs | 2 +- MediaBrowser.Model/Net/ISocketFactory.cs | 2 -- RSSDP/SsdpCommunicationsServer.cs | 5 +++-- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index e79a63ff25..0781a0e333 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -4,7 +4,6 @@ using System; using System.Net; using System.Net.Sockets; using MediaBrowser.Model.Net; -using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Net { @@ -123,6 +122,7 @@ namespace Emby.Server.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); retVal.MulticastLoopback = true; + return new UdpSocket(retVal, localPort, localIp); } catch diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index c4e1540645..363abefc19 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -1,7 +1,6 @@ #pragma warning disable CS1591 using System.Net; -using Microsoft.Extensions.Logging; namespace MediaBrowser.Model.Net { @@ -25,6 +24,5 @@ namespace MediaBrowser.Model.Net /// The local port to bind to. /// A implementation. ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); - } } diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 0ff56ebacf..3c52a0c2f4 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -338,7 +338,8 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { - var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + _ = ListenToSocketInternal(socket); return socket; @@ -382,7 +383,7 @@ namespace Rssdp.Infrastructure private async Task ListenToSocketInternal(ISocket socket) { var cancelled = false; - var receiveBuffer = new byte[8192]; + var receiveBuffer = new byte[8192]; while (!cancelled && !IsDisposed) { -- cgit v1.2.3 From d5dad64e61535152bc781caf6f2275e48fdf7bf6 Mon Sep 17 00:00:00 2001 From: Sasa Date: Wed, 24 Jun 2020 14:11:51 +0000 Subject: Translated using Weblate (Croatian) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/hr/ --- .../Localization/Core/hr.json | 52 ++++++++++++++-------- 1 file changed, 33 insertions(+), 19 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/hr.json b/Emby.Server.Implementations/Localization/Core/hr.json index c169a35e79..97c77017b5 100644 --- a/Emby.Server.Implementations/Localization/Core/hr.json +++ b/Emby.Server.Implementations/Localization/Core/hr.json @@ -5,23 +5,23 @@ "Artists": "Izvođači", "AuthenticationSucceededWithUserName": "{0} uspješno ovjerena", "Books": "Knjige", - "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}", + "CameraImageUploadedFrom": "Nova fotografija sa kamere je uploadana iz {0}", "Channels": "Kanali", "ChapterNameValue": "Poglavlje {0}", "Collections": "Kolekcije", "DeviceOfflineWithName": "{0} se odspojilo", "DeviceOnlineWithName": "{0} je spojeno", "FailedLoginAttemptWithUserName": "Neuspjeli pokušaj prijave za {0}", - "Favorites": "Omiljeni", + "Favorites": "Favoriti", "Folders": "Mape", "Genres": "Žanrovi", - "HeaderAlbumArtists": "Izvođači albuma", - "HeaderCameraUploads": "Camera Uploads", - "HeaderContinueWatching": "Continue Watching", + "HeaderAlbumArtists": "Izvođači na albumu", + "HeaderCameraUploads": "Uvoz sa kamere", + "HeaderContinueWatching": "Nastavi gledati", "HeaderFavoriteAlbums": "Omiljeni albumi", "HeaderFavoriteArtists": "Omiljeni izvođači", "HeaderFavoriteEpisodes": "Omiljene epizode", - "HeaderFavoriteShows": "Omiljene emisije", + "HeaderFavoriteShows": "Omiljene serije", "HeaderFavoriteSongs": "Omiljene pjesme", "HeaderLiveTV": "TV uživo", "HeaderNextUp": "Sljedeće je", @@ -34,23 +34,23 @@ "LabelRunningTimeValue": "Vrijeme rada: {0}", "Latest": "Najnovije", "MessageApplicationUpdated": "Jellyfin Server je ažuriran", - "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}", + "MessageApplicationUpdatedTo": "Jellyfin Server je ažuriran na {0}", "MessageNamedServerConfigurationUpdatedWithValue": "Odjeljak postavka servera {0} je ažuriran", "MessageServerConfigurationUpdated": "Postavke servera su ažurirane", "MixedContent": "Miješani sadržaj", "Movies": "Filmovi", "Music": "Glazba", "MusicVideos": "Glazbeni spotovi", - "NameInstallFailed": "{0} installation failed", + "NameInstallFailed": "{0} neuspješnih instalacija", "NameSeasonNumber": "Sezona {0}", - "NameSeasonUnknown": "Season Unknown", - "NewVersionIsAvailable": "A new version of Jellyfin Server is available for download.", + "NameSeasonUnknown": "Nepoznata sezona", + "NewVersionIsAvailable": "Nova verzija Jellyfin servera je dostupna za preuzimanje.", "NotificationOptionApplicationUpdateAvailable": "Dostupno ažuriranje aplikacije", "NotificationOptionApplicationUpdateInstalled": "Instalirano ažuriranje aplikacije", "NotificationOptionAudioPlayback": "Reprodukcija glazbe započeta", "NotificationOptionAudioPlaybackStopped": "Reprodukcija audiozapisa je zaustavljena", "NotificationOptionCameraImageUploaded": "Slike kamere preuzete", - "NotificationOptionInstallationFailed": "Instalacija nije izvršena", + "NotificationOptionInstallationFailed": "Instalacija neuspješna", "NotificationOptionNewLibraryContent": "Novi sadržaj je dodan", "NotificationOptionPluginError": "Dodatak otkazao", "NotificationOptionPluginInstalled": "Dodatak instaliran", @@ -62,7 +62,7 @@ "NotificationOptionVideoPlayback": "Reprodukcija videa započeta", "NotificationOptionVideoPlaybackStopped": "Reprodukcija videozapisa je zaustavljena", "Photos": "Slike", - "Playlists": "Popisi", + "Playlists": "Popis za reprodukciju", "Plugin": "Dodatak", "PluginInstalledWithName": "{0} je instalirano", "PluginUninstalledWithName": "{0} je deinstalirano", @@ -70,15 +70,15 @@ "ProviderValue": "Pružitelj: {0}", "ScheduledTaskFailedWithName": "{0} neuspjelo", "ScheduledTaskStartedWithName": "{0} pokrenuto", - "ServerNameNeedsToBeRestarted": "{0} needs to be restarted", - "Shows": "Shows", + "ServerNameNeedsToBeRestarted": "{0} treba biti ponovno pokrenuto", + "Shows": "Serije", "Songs": "Pjesme", "StartupEmbyServerIsLoading": "Jellyfin Server se učitava. Pokušajte ponovo kasnije.", "SubtitleDownloadFailureForItem": "Titlovi prijevoda nisu preuzeti za {0}", - "SubtitleDownloadFailureFromForItem": "Subtitles failed to download from {0} for {1}", + "SubtitleDownloadFailureFromForItem": "Prijevodi nisu uspješno preuzeti {0} od {1}", "Sync": "Sink.", "System": "Sistem", - "TvShows": "TV Shows", + "TvShows": "Serije", "User": "Korisnik", "UserCreatedWithName": "Korisnik {0} je stvoren", "UserDeletedWithName": "Korisnik {0} je obrisan", @@ -87,10 +87,10 @@ "UserOfflineFromDevice": "{0} se odspojilo od {1}", "UserOnlineFromDevice": "{0} je online od {1}", "UserPasswordChangedWithName": "Lozinka je promijenjena za korisnika {0}", - "UserPolicyUpdatedWithName": "User policy has been updated for {0}", + "UserPolicyUpdatedWithName": "Pravila za korisnika su ažurirana za {0}", "UserStartedPlayingItemWithValues": "{0} je pokrenuo {1}", "UserStoppedPlayingItemWithValues": "{0} je zaustavio {1}", - "ValueHasBeenAddedToLibrary": "{0} has been added to your media library", + "ValueHasBeenAddedToLibrary": "{0} je dodano u medijsku biblioteku", "ValueSpecialEpisodeName": "Specijal - {0}", "VersionNumber": "Verzija {0}", "TaskRefreshLibraryDescription": "Skenira vašu medijsku knjižnicu sa novim datotekama i osvježuje metapodatke.", @@ -100,5 +100,19 @@ "TaskCleanCacheDescription": "Briše priručne datoteke nepotrebne za sistem.", "TaskCleanCache": "Očisti priručnu memoriju", "TasksApplicationCategory": "Aplikacija", - "TasksMaintenanceCategory": "Održavanje" + "TasksMaintenanceCategory": "Održavanje", + "TaskDownloadMissingSubtitlesDescription": "Pretraživanje interneta za prijevodima koji nedostaju bazirano na konfiguraciji meta podataka.", + "TaskDownloadMissingSubtitles": "Preuzimanje prijevoda koji nedostaju", + "TaskRefreshChannelsDescription": "Osvježava informacije o internet kanalima.", + "TaskRefreshChannels": "Osvježi kanale", + "TaskCleanTranscodeDescription": "Briše transkodirane fajlove starije od jednog dana.", + "TaskCleanTranscode": "Očisti direktorij za transkodiranje", + "TaskUpdatePluginsDescription": "Preuzima i instalira ažuriranja za dodatke koji su podešeni da se ažuriraju automatski.", + "TaskUpdatePlugins": "Ažuriraj dodatke", + "TaskRefreshPeopleDescription": "Ažurira meta podatke za glumce i redatelje u vašoj medijskoj biblioteci.", + "TaskRefreshPeople": "Osvježi ljude", + "TaskCleanLogsDescription": "Briši logove koji su stariji od {0} dana.", + "TaskCleanLogs": "Očisti direktorij sa logovima", + "TasksChannelsCategory": "Internet kanali", + "TasksLibraryCategory": "Biblioteka" } -- cgit v1.2.3 From ef8bec23c4f1ce9b97a155913ed57bc387184e22 Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 24 Jun 2020 15:09:15 -0600 Subject: revert missing session fields --- Emby.Server.Implementations/Session/SessionManager.cs | 3 ++- MediaBrowser.Controller/Session/SessionInfo.cs | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 75fdedd107..d069d1ada8 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -502,7 +502,8 @@ namespace Emby.Server.Implementations.Session Client = appName, DeviceId = deviceId, ApplicationVersion = appVersion, - Id = key.GetMD5().ToString("N", CultureInfo.InvariantCulture) + Id = key.GetMD5().ToString("N", CultureInfo.InvariantCulture), + ServerId = _appHost.SystemId }; var username = user?.Username; diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index 36bc11be4f..4b088998cd 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -108,6 +108,12 @@ namespace MediaBrowser.Controller.Session /// The name of the device. public string DeviceName { get; set; } + /// + /// Gets or sets the type of the device. + /// + /// The type of the device. + public string DeviceType { get; set; } + /// /// Gets or sets the now playing item. /// @@ -215,8 +221,17 @@ namespace MediaBrowser.Controller.Session public string PlaylistItemId { get; set; } + public string ServerId { get; set; } + public string UserPrimaryImageTag { get; set; } + /// + /// Gets or sets the supported commands. + /// + /// The supported commands. + public string[] SupportedCommands + => Capabilities == null ? Array.Empty() : Capabilities.SupportedCommands; + public Tuple EnsureController(Func factory) { var controllers = SessionControllers.ToList(); -- cgit v1.2.3 From 7da49d57b1e976ca9af7dbd226d9887de5c7ffad Mon Sep 17 00:00:00 2001 From: Pedro Nave Date: Wed, 24 Jun 2020 22:58:32 +0000 Subject: Translated using Weblate (Portuguese) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/pt/ --- Emby.Server.Implementations/Localization/Core/pt.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/pt.json b/Emby.Server.Implementations/Localization/Core/pt.json index 25c5b9053f..5365fff232 100644 --- a/Emby.Server.Implementations/Localization/Core/pt.json +++ b/Emby.Server.Implementations/Localization/Core/pt.json @@ -101,7 +101,8 @@ "TaskCleanLogsDescription": "Deletar arquivos de log que existe a mais de {0} dias.", "TaskCleanLogs": "Limpar diretório de log", "TaskRefreshLibrary": "Escanear biblioteca de mídias", - "TaskRefreshChapterImagesDescription": "Criar miniaturas para videos que tem capítulos.", - "TaskCleanCacheDescription": "Deletar arquivos de cache que não são mais usados pelo sistema.", - "TasksChannelsCategory": "Canais de Internet" + "TaskRefreshChapterImagesDescription": "Cria miniaturas para vídeos que têm capítulos.", + "TaskCleanCacheDescription": "Apaga ficheiros em cache que já não são usados pelo sistema.", + "TasksChannelsCategory": "Canais de Internet", + "TaskRefreshChapterImages": "Extrair Imagens do Capítulo" } -- cgit v1.2.3 From d0162bbe5a7d9dd8984829d8ecec048c48466566 Mon Sep 17 00:00:00 2001 From: peberis Date: Thu, 25 Jun 2020 01:28:59 +0000 Subject: Translated using Weblate (Nepali) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ne/ --- .../Localization/Core/ne.json | 26 +++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/ne.json b/Emby.Server.Implementations/Localization/Core/ne.json index 73fae3931e..38c0737098 100644 --- a/Emby.Server.Implementations/Localization/Core/ne.json +++ b/Emby.Server.Implementations/Localization/Core/ne.json @@ -58,5 +58,29 @@ "Books": "पुस्तकहरु", "Artists": "कलाकारहरू", "Application": "अनुप्रयोगहरू", - "Albums": "एल्बमहरू" + "Albums": "एल्बमहरू", + "TasksLibraryCategory": "पुस्तकालय", + "TasksApplicationCategory": "अनुप्रयोग", + "TasksMaintenanceCategory": "मर्मत", + "UserPolicyUpdatedWithName": "प्रयोगकर्ता नीति को लागी अद्यावधिक गरिएको छ {0}", + "UserPasswordChangedWithName": "पासवर्ड प्रयोगकर्ताका लागि परिवर्तन गरिएको छ {0}", + "UserOnlineFromDevice": "{0} बाट अनलाइन छ {1}", + "UserOfflineFromDevice": "{0} बाट विच्छेदन भएको छ {1}", + "UserLockedOutWithName": "प्रयोगकर्ता {0} लक गरिएको छ", + "UserDeletedWithName": "प्रयोगकर्ता {0} हटाइएको छ", + "UserCreatedWithName": "प्रयोगकर्ता {0} सिर्जना गरिएको छ", + "User": "प्रयोगकर्ता", + "PluginInstalledWithName": "", + "StartupEmbyServerIsLoading": "Jellyfin सर्भर लोड हुँदैछ। कृपया छिट्टै फेरि प्रयास गर्नुहोस्।", + "Songs": "गीतहरू", + "Shows": "शोहरू", + "ServerNameNeedsToBeRestarted": "{0} लाई पुन: सुरु गर्नु पर्छ", + "ScheduledTaskStartedWithName": "{0} सुरु भयो", + "ScheduledTaskFailedWithName": "{0} असफल", + "ProviderValue": "प्रदायक: {0}", + "Plugin": "प्लगइनहरू", + "Playlists": "प्लेलिस्टहरू", + "Photos": "तस्बिरहरु", + "NotificationOptionVideoPlaybackStopped": "भिडियो प्लेब्याक रोकियो", + "NotificationOptionVideoPlayback": "भिडियो प्लेब्याक सुरु भयो" } -- cgit v1.2.3 From 91c51ae6752720d6272e6a0c651edd3780e150ac Mon Sep 17 00:00:00 2001 From: Franco Castillo Date: Thu, 25 Jun 2020 03:06:54 +0000 Subject: Translated using Weblate (Spanish (Argentina)) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/es_AR/ --- Emby.Server.Implementations/Localization/Core/es-AR.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/es-AR.json b/Emby.Server.Implementations/Localization/Core/es-AR.json index fc9a10f276..ac96c788c1 100644 --- a/Emby.Server.Implementations/Localization/Core/es-AR.json +++ b/Emby.Server.Implementations/Localization/Core/es-AR.json @@ -20,7 +20,7 @@ "HeaderContinueWatching": "Seguir viendo", "HeaderFavoriteAlbums": "Álbumes favoritos", "HeaderFavoriteArtists": "Artistas favoritos", - "HeaderFavoriteEpisodes": "Episodios favoritos", + "HeaderFavoriteEpisodes": "Capítulos favoritos", "HeaderFavoriteShows": "Programas favoritos", "HeaderFavoriteSongs": "Canciones favoritas", "HeaderLiveTV": "TV en vivo", -- cgit v1.2.3 From 9dee1eef83d80801cf2781b8b0c2393ec0a3b82d Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Thu, 25 Jun 2020 11:31:43 +0200 Subject: Never ignore application folders --- .../Library/CoreResolutionIgnoreRule.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs index e140009ea9..77b2c0a694 100644 --- a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs +++ b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; @@ -13,19 +14,28 @@ namespace Emby.Server.Implementations.Library public class CoreResolutionIgnoreRule : IResolverIgnoreRule { private readonly ILibraryManager _libraryManager; + private readonly IServerApplicationPaths _serverApplicationPaths; /// /// Initializes a new instance of the class. /// /// The library manager. - public CoreResolutionIgnoreRule(ILibraryManager libraryManager) + /// The server application paths. + public CoreResolutionIgnoreRule(ILibraryManager libraryManager, IServerApplicationPaths serverApplicationPaths) { _libraryManager = libraryManager; + _serverApplicationPaths = serverApplicationPaths; } /// public bool ShouldIgnore(FileSystemMetadata fileInfo, BaseItem parent) { + // Don't ignore application folders + if (fileInfo.FullName.Contains(_serverApplicationPaths.RootFolderPath, StringComparison.InvariantCulture)) + { + return false; + } + // Don't ignore top level folders if (fileInfo.IsDirectory && parent is AggregateFolder) { -- cgit v1.2.3 From 0f07b19ca5d6433a8574363cfe3c20fbfd285514 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Thu, 25 Jun 2020 11:33:10 +0200 Subject: Remove AllowIgnorePath --- Emby.Server.Implementations/Library/LibraryManager.cs | 13 ++++++------- MediaBrowser.Controller/Library/ILibraryManager.cs | 4 +--- 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index edb58e9102..9b8091aa7a 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -514,8 +514,8 @@ namespace Emby.Server.Implementations.Library return key.GetMD5(); } - public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null, bool allowIgnorePath = true) - => ResolvePath(fileInfo, new DirectoryService(_fileSystem), null, parent, allowIgnorePath: allowIgnorePath); + public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null) + => ResolvePath(fileInfo, new DirectoryService(_fileSystem), null, parent); private BaseItem ResolvePath( FileSystemMetadata fileInfo, @@ -523,8 +523,7 @@ namespace Emby.Server.Implementations.Library IItemResolver[] resolvers, Folder parent = null, string collectionType = null, - LibraryOptions libraryOptions = null, - bool allowIgnorePath = true) + LibraryOptions libraryOptions = null) { if (fileInfo == null) { @@ -548,7 +547,7 @@ namespace Emby.Server.Implementations.Library }; // Return null if ignore rules deem that we should do so - if (allowIgnorePath && IgnoreFile(args.FileInfo, args.Parent)) + if (IgnoreFile(args.FileInfo, args.Parent)) { return null; } @@ -713,7 +712,7 @@ namespace Emby.Server.Implementations.Library Directory.CreateDirectory(rootFolderPath); var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ?? - ((Folder) ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath), allowIgnorePath: false)) + ((Folder) ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath))) .DeepCopy(); // In case program data folder was moved @@ -795,7 +794,7 @@ namespace Emby.Server.Implementations.Library if (tmpItem == null) { _logger.LogDebug("Creating new userRootFolder with DeepCopy"); - tmpItem = ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(userRootPath), allowIgnorePath: false)).DeepCopy(); + tmpItem = ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(userRootPath))).DeepCopy(); } // In case program data folder was moved diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 47c080ebdc..9d6646857e 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -30,12 +30,10 @@ namespace MediaBrowser.Controller.Library /// /// The file information. /// The parent. - /// Allow the path to be ignored. /// BaseItem. BaseItem ResolvePath( FileSystemMetadata fileInfo, - Folder parent = null, - bool allowIgnorePath = true); + Folder parent = null); /// /// Resolves a set of files into a list of BaseItem. -- cgit v1.2.3 From 9eba11379a3695eda732a481634fbac620ac0624 Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 25 Jun 2020 12:10:33 -0600 Subject: catch skia errors when getting image dimensions --- Emby.Server.Implementations/Library/LibraryManager.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 6a20a015ad..b2c9638b2b 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1894,9 +1894,19 @@ namespace Emby.Server.Implementations.Library } } - ImageDimensions size = _imageProcessor.GetImageDimensions(item, image); - image.Width = size.Width; - image.Height = size.Height; + try + { + ImageDimensions size = _imageProcessor.GetImageDimensions(item, image); + image.Width = size.Width; + image.Height = size.Height; + } + catch (Exception ex) + { + _logger.LogError(ex, "Cannnot get image dimensions for {0}", image.Path); + image.Width = 0; + image.Height = 0; + continue; + } try { -- cgit v1.2.3 From 83ae4d074dc9f665c992eefd1cf4ed78eb5a8dd1 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 27 Jun 2020 00:22:27 +0900 Subject: use constructor to set optimal config values --- .../Collections/CollectionManager.cs | 56 --------------------- .../Configuration/ServerConfigurationManager.cs | 57 ---------------------- Jellyfin.Api/Controllers/StartupController.cs | 1 - .../Configuration/IServerConfigurationManager.cs | 2 - .../Configuration/ServerConfiguration.cs | 6 ++- 5 files changed, 4 insertions(+), 118 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs index 8fb9520d6d..ac2edc1e2e 100644 --- a/Emby.Server.Implementations/Collections/CollectionManager.cs +++ b/Emby.Server.Implementations/Collections/CollectionManager.cs @@ -363,60 +363,4 @@ namespace Emby.Server.Implementations.Collections return results.Values; } } - - /// - /// The collection manager entry point. - /// - public sealed class CollectionManagerEntryPoint : IServerEntryPoint - { - private readonly CollectionManager _collectionManager; - private readonly IServerConfigurationManager _config; - private readonly ILogger _logger; - - /// - /// Initializes a new instance of the class. - /// - /// The collection manager. - /// The server configuration manager. - /// The logger. - public CollectionManagerEntryPoint( - ICollectionManager collectionManager, - IServerConfigurationManager config, - ILogger logger) - { - _collectionManager = (CollectionManager)collectionManager; - _config = config; - _logger = logger; - } - - /// - public async Task RunAsync() - { - if (!_config.Configuration.CollectionsUpgraded && _config.Configuration.IsStartupWizardCompleted) - { - var path = _collectionManager.GetCollectionsFolderPath(); - - if (Directory.Exists(path)) - { - try - { - await _collectionManager.EnsureLibraryFolder(path, true).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error creating camera uploads library"); - } - - _config.Configuration.CollectionsUpgraded = true; - _config.SaveConfiguration(); - } - } - } - - /// - public void Dispose() - { - // Nothing to dispose - } - } } diff --git a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs index 94ee1ced71..a15295fca4 100644 --- a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -109,7 +109,6 @@ namespace Emby.Server.Implementations.Configuration if (!string.IsNullOrWhiteSpace(newPath) && !string.Equals(Configuration.CertificatePath, newPath, StringComparison.Ordinal)) { - // Validate if (!File.Exists(newPath)) { throw new FileNotFoundException( @@ -133,7 +132,6 @@ namespace Emby.Server.Implementations.Configuration if (!string.IsNullOrWhiteSpace(newPath) && !string.Equals(Configuration.MetadataPath, newPath, StringComparison.Ordinal)) { - // Validate if (!Directory.Exists(newPath)) { throw new DirectoryNotFoundException( @@ -146,60 +144,5 @@ namespace Emby.Server.Implementations.Configuration EnsureWriteAccess(newPath); } } - - /// - /// Sets all configuration values to their optimal values. - /// - /// If the configuration changed. - public bool SetOptimalValues() - { - var config = Configuration; - - var changed = false; - - if (!config.EnableCaseSensitiveItemIds) - { - config.EnableCaseSensitiveItemIds = true; - changed = true; - } - - if (!config.SkipDeserializationForBasicTypes) - { - config.SkipDeserializationForBasicTypes = true; - changed = true; - } - - if (!config.EnableSimpleArtistDetection) - { - config.EnableSimpleArtistDetection = true; - changed = true; - } - - if (!config.EnableNormalizedItemByNameIds) - { - config.EnableNormalizedItemByNameIds = true; - changed = true; - } - - if (!config.DisableLiveTvChannelUserDataName) - { - config.DisableLiveTvChannelUserDataName = true; - changed = true; - } - - if (!config.EnableNewOmdbSupport) - { - config.EnableNewOmdbSupport = true; - changed = true; - } - - if (!config.CollectionsUpgraded) - { - config.CollectionsUpgraded = true; - changed = true; - } - - return changed; - } } } diff --git a/Jellyfin.Api/Controllers/StartupController.cs b/Jellyfin.Api/Controllers/StartupController.cs index 6ec0a4e26f..04f134b8bf 100644 --- a/Jellyfin.Api/Controllers/StartupController.cs +++ b/Jellyfin.Api/Controllers/StartupController.cs @@ -36,7 +36,6 @@ namespace Jellyfin.Api.Controllers public void CompleteWizard() { _config.Configuration.IsStartupWizardCompleted = true; - _config.SetOptimalValues(); _config.SaveConfiguration(); } diff --git a/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs b/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs index a5c5e3bccf..43ad04dbac 100644 --- a/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs +++ b/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs @@ -19,7 +19,5 @@ namespace MediaBrowser.Controller.Configuration /// /// The configuration. ServerConfiguration Configuration { get; } - - bool SetOptimalValues(); } } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index b87c8fbab2..bb4ca34fd0 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -82,8 +82,6 @@ namespace MediaBrowser.Model.Configuration public bool EnableRemoteAccess { get; set; } - public bool CollectionsUpgraded { get; set; } - /// /// Gets or sets a value indicating whether [enable case sensitive item ids]. /// @@ -269,6 +267,7 @@ namespace MediaBrowser.Model.Configuration PathSubstitutions = Array.Empty(); IgnoreVirtualInterfaces = false; EnableSimpleArtistDetection = false; + SkipDeserializationForBasicTypes = true; DisplaySpecialsWithinSeasons = true; EnableExternalContentInSuggestions = true; @@ -282,6 +281,9 @@ namespace MediaBrowser.Model.Configuration EnableHttps = false; EnableDashboardResponseCaching = true; EnableCaseSensitiveItemIds = true; + EnableNormalizedItemByNameIds = true; + DisableLiveTvChannelUserDataName = true; + EnableNewOmdbSupport = true; AutoRunWebApp = true; EnableRemoteAccess = true; -- cgit v1.2.3 From 9772749d8fa2c86089ff1e3e0b8443633193106a Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 26 Jun 2020 11:04:35 -0600 Subject: Add more ignorepatterns and tests --- .../Library/IgnorePatterns.cs | 28 +++++++++++++++++++--- .../Library/IgnorePatternsTests.cs | 7 ++++++ 2 files changed, 32 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/IgnorePatterns.cs b/Emby.Server.Implementations/Library/IgnorePatterns.cs index 8c40989489..cd5c5f19db 100644 --- a/Emby.Server.Implementations/Library/IgnorePatterns.cs +++ b/Emby.Server.Implementations/Library/IgnorePatterns.cs @@ -11,7 +11,7 @@ namespace Emby.Server.Implementations.Library /// /// Files matching these glob patterns will be ignored. /// - public static readonly string[] Patterns = new string[] + private static readonly string[] _patterns = { "**/small.jpg", "**/albumart.jpg", @@ -19,32 +19,51 @@ namespace Emby.Server.Implementations.Library // Directories "**/metadata/**", + "**/metadata", "**/ps3_update/**", + "**/ps3_update", "**/ps3_vprm/**", + "**/ps3_vprm", "**/extrafanart/**", + "**/extrafanart", "**/extrathumbs/**", + "**/extrathumbs", "**/.actors/**", + "**/.actors", "**/.wd_tv/**", + "**/.wd_tv", "**/lost+found/**", + "**/lost+found", // WMC temp recording directories that will constantly be written to "**/TempRec/**", + "**/TempRec", "**/TempSBE/**", + "**/TempSBE", // Synology "**/eaDir/**", + "**/eaDir", "**/@eaDir/**", + "**/@eaDir", "**/#recycle/**", + "**/#recycle", // Qnap "**/@Recycle/**", + "**/@Recycle", "**/.@__thumb/**", + "**/.@__thumb", "**/$RECYCLE.BIN/**", + "**/$RECYCLE.BIN", "**/System Volume Information/**", + "**/System Volume Information", "**/.grab/**", + "**/.grab", // Unix hidden files and directories "**/.*/**", + "**/.*", // thumbs.db "**/thumbs.db", @@ -56,16 +75,19 @@ namespace Emby.Server.Implementations.Library private static readonly GlobOptions _globOptions = new GlobOptions { - Evaluation = { + Evaluation = + { CaseInsensitive = true } }; - private static readonly Glob[] _globs = Patterns.Select(p => Glob.Parse(p, _globOptions)).ToArray(); + private static readonly Glob[] _globs = _patterns.Select(p => Glob.Parse(p, _globOptions)).ToArray(); /// /// Returns true if the supplied path should be ignored. /// + /// The path to test. + /// Whether to ignore the path. public static bool ShouldIgnore(string path) { return _globs.Any(g => g.IsMatch(path)); diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs index 26dee38c6d..c145ddc9d7 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs @@ -7,12 +7,19 @@ namespace Jellyfin.Server.Implementations.Tests.Library { [Theory] [InlineData("/media/small.jpg", true)] + [InlineData("/media/albumart.jpg", true)] + [InlineData("/media/movie.sample.mp4", true)] [InlineData("/media/movies/#Recycle/test.txt", true)] [InlineData("/media/movies/#recycle/", true)] + [InlineData("/media/movies/#recycle", true)] [InlineData("thumbs.db", true)] [InlineData(@"C:\media\movies\movie.avi", false)] [InlineData("/media/.hiddendir/file.mp4", true)] [InlineData("/media/dir/.hiddenfile.mp4", true)] + [InlineData("/volume1/video/Series/@eaDir", true)] + [InlineData("/volume1/video/Series/@eaDir/file.txt", true)] + [InlineData("/directory/@Recycle", true)] + [InlineData("/directory/@Recycle/file.mp3", true)] public void PathIgnored(string path, bool expected) { Assert.Equal(expected, IgnorePatterns.ShouldIgnore(path)); -- cgit v1.2.3 From cb193b6afd339ab62a76644e02e9459962756c00 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sat, 27 Jun 2020 11:32:57 +0200 Subject: Add support for ReadOnlySpan in IgnorePatterns --- Emby.Server.Implementations/Library/IgnorePatterns.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/IgnorePatterns.cs b/Emby.Server.Implementations/Library/IgnorePatterns.cs index cd5c5f19db..6e6ef1359a 100644 --- a/Emby.Server.Implementations/Library/IgnorePatterns.cs +++ b/Emby.Server.Implementations/Library/IgnorePatterns.cs @@ -1,3 +1,6 @@ +#nullable enable + +using System; using System.Linq; using DotNet.Globbing; @@ -88,9 +91,18 @@ namespace Emby.Server.Implementations.Library /// /// The path to test. /// Whether to ignore the path. - public static bool ShouldIgnore(string path) + public static bool ShouldIgnore(ReadOnlySpan path) { - return _globs.Any(g => g.IsMatch(path)); + int len = _globs.Length; + for (int i = 0; i < len; i++) + { + if (_globs[i].IsMatch(path)) + { + return true; + } + } + + return false; } } } -- cgit v1.2.3 From 332527cf8c84b1b2d30a67d80de3d9bd7aa8d1dc Mon Sep 17 00:00:00 2001 From: Gonzalo Seguel Date: Sun, 28 Jun 2020 03:59:24 +0000 Subject: Translated using Weblate (Spanish (Mexico)) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/es_MX/ --- Emby.Server.Implementations/Localization/Core/es-MX.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/es-MX.json b/Emby.Server.Implementations/Localization/Core/es-MX.json index 20b37ec9f2..4ba324aa1b 100644 --- a/Emby.Server.Implementations/Localization/Core/es-MX.json +++ b/Emby.Server.Implementations/Localization/Core/es-MX.json @@ -31,7 +31,7 @@ "ItemAddedWithName": "{0} fue agregado a la biblioteca", "ItemRemovedWithName": "{0} fue removido de la biblioteca", "LabelIpAddressValue": "Dirección IP: {0}", - "LabelRunningTimeValue": "Duración: {0}", + "LabelRunningTimeValue": "Tiempo de reproducción: {0}", "Latest": "Recientes", "MessageApplicationUpdated": "El servidor Jellyfin ha sido actualizado", "MessageApplicationUpdatedTo": "El servidor Jellyfin ha sido actualizado a {0}", -- cgit v1.2.3 From 438977350892179d5dc2259316b0fe27ceb1e5da Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 29 Jun 2020 17:08:20 +0100 Subject: Respect FFMpeg path passed via Environment Variable --- Emby.Server.Implementations/ApplicationHost.cs | 3 +-- Jellyfin.Server/StartupOptions.cs | 5 +++++ MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs | 5 +++++ MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 7 ++++--- 4 files changed, 15 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 14267b5613..8d213ac57d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -568,8 +568,7 @@ namespace Emby.Server.Implementations // TODO: Refactor to eliminate the circular dependency here so that Lazy isn't required // TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); - serviceCollection.AddSingleton(provider => - ActivatorUtilities.CreateInstance(provider, _startupOptions.FFmpegPath ?? string.Empty)); + serviceCollection.AddSingleton(); // TODO: Refactor to eliminate the circular dependencies here so that Lazy isn't required serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); diff --git a/Jellyfin.Server/StartupOptions.cs b/Jellyfin.Server/StartupOptions.cs index a26114e778..41a1430d26 100644 --- a/Jellyfin.Server/StartupOptions.cs +++ b/Jellyfin.Server/StartupOptions.cs @@ -101,6 +101,11 @@ namespace Jellyfin.Server config.Add(UdpServer.AddressOverrideConfigKey, PublishedServerUrl.ToString()); } + if (FFmpegPath != null) + { + config.Add(ConfigurationExtensions.FfmpegPathKey, FFmpegPath); + } + return config; } } diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs index c0043c0efa..c2932cc4c4 100644 --- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs @@ -23,6 +23,11 @@ namespace MediaBrowser.Controller.Extensions /// public const string FfmpegAnalyzeDurationKey = "FFmpeg:analyzeduration"; + /// + /// The key for the FFmpeg path option. + /// + public const string FfmpegPathKey = "ffmpeg"; + /// /// The key for a setting that indicates whether playlists should allow duplicate entries. /// diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 9397a347f3..af99f2521d 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -21,6 +21,7 @@ using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.System; using Microsoft.Extensions.Logging; using System.Diagnostics; +using Microsoft.Extensions.Configuration; namespace MediaBrowser.MediaEncoding.Encoder { @@ -46,7 +47,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly object _runningProcessesLock = new object(); private readonly List _runningProcesses = new List(); - private string _ffmpegPath; + private string _ffmpegPath = string.Empty; private string _ffprobePath; public MediaEncoder( @@ -55,14 +56,14 @@ namespace MediaBrowser.MediaEncoding.Encoder IFileSystem fileSystem, ILocalizationManager localization, Lazy encodingHelperFactory, - string startupOptionsFFmpegPath) + IConfiguration config) { _logger = logger; _configurationManager = configurationManager; _fileSystem = fileSystem; _localization = localization; _encodingHelperFactory = encodingHelperFactory; - _startupOptionFFmpegPath = startupOptionsFFmpegPath; + _startupOptionFFmpegPath = config.GetValue(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? ""; } private EncodingHelper EncodingHelper => _encodingHelperFactory.Value; -- cgit v1.2.3 From 4748df26b6b690f58867dbc2c39f23c44553f7a5 Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 29 Jun 2020 17:25:12 +0100 Subject: Remove un-needed comment --- Emby.Server.Implementations/ApplicationHost.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8d213ac57d..18b6834ef5 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -566,7 +566,6 @@ namespace Emby.Server.Implementations serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); // TODO: Refactor to eliminate the circular dependency here so that Lazy isn't required - // TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); serviceCollection.AddSingleton(); -- cgit v1.2.3 From 1140bcc669f040027cac2c083f0d84f3187e1ffe Mon Sep 17 00:00:00 2001 From: Zyzto Date: Wed, 1 Jul 2020 00:24:14 +0000 Subject: Translated using Weblate (Arabic) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ar/ --- Emby.Server.Implementations/Localization/Core/ar.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/ar.json b/Emby.Server.Implementations/Localization/Core/ar.json index d68928fce4..4eac8e75de 100644 --- a/Emby.Server.Implementations/Localization/Core/ar.json +++ b/Emby.Server.Implementations/Localization/Core/ar.json @@ -1,5 +1,5 @@ { - "Albums": "ألبومات", + "Albums": "البومات", "AppDeviceValues": "تطبيق: {0}, جهاز: {1}", "Application": "تطبيق", "Artists": "الفنانين", @@ -14,7 +14,7 @@ "FailedLoginAttemptWithUserName": "عملية تسجيل الدخول فشلت من {0}", "Favorites": "المفضلة", "Folders": "المجلدات", - "Genres": "الأنواع", + "Genres": "التضنيفات", "HeaderAlbumArtists": "فناني الألبومات", "HeaderCameraUploads": "تحميلات الكاميرا", "HeaderContinueWatching": "استئناف", @@ -50,7 +50,7 @@ "NotificationOptionAudioPlayback": "بدأ تشغيل المقطع الصوتي", "NotificationOptionAudioPlaybackStopped": "تم إيقاف تشغيل المقطع الصوتي", "NotificationOptionCameraImageUploaded": "تم رفع صورة الكاميرا", - "NotificationOptionInstallationFailed": "فشل في التثبيت", + "NotificationOptionInstallationFailed": "فشل التثبيت", "NotificationOptionNewLibraryContent": "تم إضافة محتوى جديد", "NotificationOptionPluginError": "فشل في البرنامج المضاف", "NotificationOptionPluginInstalled": "تم تثبيت الملحق", -- cgit v1.2.3 From af334f96d64fe8fdc91ea2a8cc5f880ed54e3fa5 Mon Sep 17 00:00:00 2001 From: Anthony Lavado Date: Fri, 3 Jul 2020 14:11:38 -0400 Subject: Use newer Jellyfin.XmlTv for Guide Fixes --- Emby.Server.Implementations/Emby.Server.Implementations.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index e75b662934..f7ad59c10f 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -25,7 +25,7 @@ - + -- cgit v1.2.3 From ae6eaa7f02bcd7faf30613f1472e16d03f5637d5 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sat, 4 Jul 2020 22:06:27 +0200 Subject: Minor fixes --- Emby.Server.Implementations/ApplicationHost.cs | 26 +++++++++------------- Jellyfin.Server/Program.cs | 4 ++-- MediaBrowser.Model/Dlna/StreamInfo.cs | 2 +- .../Plugins/Tmdb/Movies/TmdbMovieProvider.cs | 12 +++++----- 4 files changed, 20 insertions(+), 24 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 18b6834ef5..531775302b 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -43,9 +43,9 @@ using Emby.Server.Implementations.Security; using Emby.Server.Implementations.Serialization; using Emby.Server.Implementations.Services; using Emby.Server.Implementations.Session; +using Emby.Server.Implementations.SyncPlay; using Emby.Server.Implementations.TV; using Emby.Server.Implementations.Updates; -using Emby.Server.Implementations.SyncPlay; using MediaBrowser.Api; using MediaBrowser.Common; using MediaBrowser.Common.Configuration; @@ -78,8 +78,8 @@ using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Sorting; using MediaBrowser.Controller.Subtitles; -using MediaBrowser.Controller.TV; using MediaBrowser.Controller.SyncPlay; +using MediaBrowser.Controller.TV; using MediaBrowser.LocalMetadata.Savers; using MediaBrowser.MediaEncoding.BdInfo; using MediaBrowser.Model.Configuration; @@ -484,12 +484,10 @@ namespace Emby.Server.Implementations foreach (var plugin in Plugins) { - pluginBuilder.AppendLine( - string.Format( - CultureInfo.InvariantCulture, - "{0} {1}", - plugin.Name, - plugin.Version)); + pluginBuilder.Append(plugin.Name) + .Append(' ') + .Append(plugin.Version) + .AppendLine(); } Logger.LogInformation("Plugins: {Plugins}", pluginBuilder.ToString()); @@ -1153,7 +1151,7 @@ namespace Emby.Server.Implementations return null; } - return GetLocalApiUrl(addresses.First()); + return GetLocalApiUrl(addresses[0]); } catch (Exception ex) { @@ -1226,7 +1224,7 @@ namespace Emby.Server.Implementations var addresses = ServerConfigurationManager .Configuration .LocalNetworkAddresses - .Select(NormalizeConfiguredLocalAddress) + .Select(x => NormalizeConfiguredLocalAddress(x)) .Where(i => i != null) .ToList(); @@ -1247,8 +1245,7 @@ namespace Emby.Server.Implementations } } - var valid = await IsLocalIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); - if (valid) + if (await IsLocalIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false)) { resultList.Add(address); @@ -1262,13 +1259,12 @@ namespace Emby.Server.Implementations return resultList; } - public IPAddress NormalizeConfiguredLocalAddress(string address) + public IPAddress NormalizeConfiguredLocalAddress(ReadOnlySpan address) { var index = address.Trim('/').IndexOf('/'); - if (index != -1) { - address = address.Substring(index + 1); + address = address.Slice(index + 1); } if (IPAddress.TryParse(address.Trim('/'), out IPAddress result)) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 4d898ff5e3..ef3ebe90cb 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -274,10 +274,10 @@ namespace Jellyfin.Server var addresses = appHost.ServerConfigurationManager .Configuration .LocalNetworkAddresses - .Select(appHost.NormalizeConfiguredLocalAddress) + .Select(x => appHost.NormalizeConfiguredLocalAddress(x)) .Where(i => i != null) .ToHashSet(); - if (addresses.Any() && !addresses.Contains(IPAddress.Any)) + if (addresses.Count > 0 && !addresses.Contains(IPAddress.Any)) { if (!addresses.Contains(IPAddress.Loopback)) { diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index b89e9ce90a..fded0d6ed1 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -144,7 +144,7 @@ namespace MediaBrowser.Model.Dlna public Dictionary StreamOptions { get; private set; } - public string MediaSourceId => MediaSource == null ? null : MediaSource.Id; + public string MediaSourceId => MediaSource?.Id; public bool IsDirectStream => PlayMethod == PlayMethod.DirectStream || diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs index 5e2b83294a..df471896f9 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs @@ -148,7 +148,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies using (HttpResponseInfo response = await GetMovieDbResponse(new HttpRequestOptions { - Url = string.Format(TmdbConfigUrl, TmdbUtils.ApiKey), + Url = string.Format(CultureInfo.InvariantCulture, TmdbConfigUrl, TmdbUtils.ApiKey), CancellationToken = cancellationToken, AcceptHeader = TmdbUtils.AcceptHeader }).ConfigureAwait(false)) @@ -245,7 +245,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies preferredLanguage = "alllang"; } - var filename = string.Format("all-{0}.json", preferredLanguage); + var filename = string.Format(CultureInfo.InvariantCulture, "all-{0}.json", preferredLanguage); return Path.Combine(path, filename); } @@ -276,7 +276,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies languages.Add("en"); } - return string.Join(",", languages.ToArray()); + return string.Join(",", languages); } public static string NormalizeLanguage(string language) @@ -321,11 +321,11 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies /// Task{CompleteMovieData}. internal async Task FetchMainResult(string id, bool isTmdbId, string language, CancellationToken cancellationToken) { - var url = string.Format(GetMovieInfo3, id, TmdbUtils.ApiKey); + var url = string.Format(CultureInfo.InvariantCulture, GetMovieInfo3, id, TmdbUtils.ApiKey); if (!string.IsNullOrEmpty(language)) { - url += string.Format("&language={0}", NormalizeLanguage(language)); + url += string.Format(CultureInfo.InvariantCulture, "&language={0}", NormalizeLanguage(language)); // Get images in english and with no language url += "&include_image_language=" + GetImageLanguagesParam(language); @@ -377,7 +377,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies { _logger.LogInformation("MovieDbProvider couldn't find meta for language " + language + ". Trying English..."); - url = string.Format(GetMovieInfo3, id, TmdbUtils.ApiKey) + "&language=en"; + url = string.Format(CultureInfo.InvariantCulture,GetMovieInfo3, id, TmdbUtils.ApiKey) + "&language=en"; if (!string.IsNullOrEmpty(language)) { -- cgit v1.2.3 From ab10f210274ff46bf68b5af752a817bbd90f749a Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sun, 5 Jul 2020 17:47:23 +0100 Subject: Part 1 of a multi-PR change for Emby.DLNA --- Emby.Server.Implementations/ApplicationHost.cs | 40 +++++++++++++++++++++- .../HttpServer/HttpListenerHost.cs | 5 +++ .../Services/ServiceController.cs | 4 +-- MediaBrowser.Common/IApplicationHost.cs | 8 +++++ 4 files changed, 54 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 18b6834ef5..f10ebdd01e 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -351,6 +351,42 @@ namespace Emby.Server.Implementations public object CreateInstance(Type type) => ActivatorUtilities.CreateInstance(ServiceProvider, type); + /// + /// Creates an instance of type and resolves all constructor dependencies. + /// + /// The type. + /// Additional argument for the constructor. + /// + public object CreateInstance(Type type, object parameter) + { + ConstructorInfo constructor = type.GetConstructors()[0]; + if (constructor != null) + { + ParameterInfo[] argInfo = constructor + .GetParameters(); + + object[] args = argInfo + .Select(o => o.ParameterType) + .Select(o => ServiceProvider.GetService(o)) + .ToArray(); + + if (parameter != null) + { + // Assumption is that the is always the last in the constructor's parameter list. + int argsLen = args.Length; + var argType = argInfo[argsLen - 1].ParameterType; + var paramType = parameter.GetType(); + if (argType.IsAssignableFrom(paramType) || argType == paramType) + { + args[argsLen - 1] = parameter; + return ActivatorUtilities.CreateInstance(ServiceProvider, type, args); + } + } + } + + return ActivatorUtilities.CreateInstance(ServiceProvider, type); + } + /// /// Creates an instance of type and resolves all constructor dependencies. /// @@ -566,8 +602,10 @@ namespace Emby.Server.Implementations serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); // TODO: Refactor to eliminate the circular dependency here so that Lazy isn't required + // TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); - serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(provider => + ActivatorUtilities.CreateInstance(provider, _startupOptions.FFmpegPath ?? string.Empty)); // TODO: Refactor to eliminate the circular dependencies here so that Lazy isn't required serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index c3428ee62a..6860b7ecdf 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -107,6 +107,11 @@ namespace Emby.Server.Implementations.HttpServer return _appHost.CreateInstance(type); } + public object CreateInstance(Type type, object parameter) + { + return _appHost.CreateInstance(type, parameter); + } + private static string NormalizeUrlPath(string path) { if (path.Length > 0 && path[0] == '/') diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs index 857df591a1..2a780feb58 100644 --- a/Emby.Server.Implementations/Services/ServiceController.cs +++ b/Emby.Server.Implementations/Services/ServiceController.cs @@ -177,8 +177,8 @@ namespace Emby.Server.Implementations.Services var serviceType = httpHost.GetServiceTypeByRequest(requestType); - var service = httpHost.CreateInstance(serviceType); - + var service = httpHost.CreateInstance(serviceType, req); + var serviceRequiresContext = service as IRequiresRequest; if (serviceRequiresContext != null) { diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs index e8d9282e40..cf4954eef1 100644 --- a/MediaBrowser.Common/IApplicationHost.cs +++ b/MediaBrowser.Common/IApplicationHost.cs @@ -125,5 +125,13 @@ namespace MediaBrowser.Common /// The type. /// System.Object. object CreateInstance(Type type); + + /// + /// Creates a new instance of a class. + /// + /// The type to create. + /// An addtional parameter. + /// Created instance. + object CreateInstance(Type type, object parameter); } } -- cgit v1.2.3 From 70c638d1d48178bc1458fe86a48b2b60b06b7171 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sun, 5 Jul 2020 18:12:56 +0100 Subject: Updated code as per jellyfin/master as version i amended didn't execute. --- Emby.Server.Implementations/ApplicationHost.cs | 3 +-- Emby.Server.Implementations/Services/ServiceController.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index f10ebdd01e..4d99bd759d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -604,8 +604,7 @@ namespace Emby.Server.Implementations // TODO: Refactor to eliminate the circular dependency here so that Lazy isn't required // TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); - serviceCollection.AddSingleton(provider => - ActivatorUtilities.CreateInstance(provider, _startupOptions.FFmpegPath ?? string.Empty)); + serviceCollection.AddSingleton(); // TODO: Refactor to eliminate the circular dependencies here so that Lazy isn't required serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs index 2a780feb58..b1f2a68273 100644 --- a/Emby.Server.Implementations/Services/ServiceController.cs +++ b/Emby.Server.Implementations/Services/ServiceController.cs @@ -178,7 +178,7 @@ namespace Emby.Server.Implementations.Services var serviceType = httpHost.GetServiceTypeByRequest(requestType); var service = httpHost.CreateInstance(serviceType, req); - + var serviceRequiresContext = service as IRequiresRequest; if (serviceRequiresContext != null) { @@ -189,5 +189,4 @@ namespace Emby.Server.Implementations.Services return ServiceExecGeneral.Execute(serviceType, req, service, requestDto, requestType.GetMethodName()); } } - } -- cgit v1.2.3 From 942c733d4f13046cedd19fa849eec88b13d2d2c7 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sun, 5 Jul 2020 15:36:29 -0400 Subject: Fix TypeLoadException during plugin load --- Emby.Server.Implementations/ApplicationHost.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 18b6834ef5..fe1961b702 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -871,6 +871,11 @@ namespace Emby.Server.Implementations Logger.LogError(ex, "Error getting exported types from {Assembly}", ass.FullName); continue; } + catch (TypeLoadException ex) + { + Logger.LogError(ex, "Error loading types from {Assembly}.", ass.FullName); + continue; + } foreach (Type type in exportedTypes) { -- cgit v1.2.3 From 3cca8db9059e7c0316d829f85d05dcb03ae70a95 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 7 Jul 2020 18:20:17 -0400 Subject: Fix log spam from EF Core --- Emby.Server.Implementations/Session/SessionManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index d069d1ada8..ca9f95c707 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -296,7 +296,7 @@ namespace Emby.Server.Implementations.Session } catch (DbUpdateConcurrencyException e) { - _logger.LogWarning(e, "Error updating user's last activity date."); + _logger.LogDebug(e, "Error updating user's last activity date."); } } } -- cgit v1.2.3 From 172203b5ccfe8e0647af78deb347dc42e6132c93 Mon Sep 17 00:00:00 2001 From: rhythm493 Date: Wed, 8 Jul 2020 16:23:26 +0000 Subject: Translated using Weblate (Marathi) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/mr/ --- Emby.Server.Implementations/Localization/Core/mr.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/mr.json b/Emby.Server.Implementations/Localization/Core/mr.json index 50b6360d8f..b6db2b0f29 100644 --- a/Emby.Server.Implementations/Localization/Core/mr.json +++ b/Emby.Server.Implementations/Localization/Core/mr.json @@ -57,5 +57,7 @@ "HeaderCameraUploads": "कॅमेरा अपलोड", "CameraImageUploadedFrom": "एक नवीन कॅमेरा चित्र {0} येथून अपलोड केले आहे", "Application": "अ‍ॅप्लिकेशन", - "AppDeviceValues": "अ‍ॅप: {0}, यंत्र: {1}" + "AppDeviceValues": "अ‍ॅप: {0}, यंत्र: {1}", + "Collections": "संग्रह", + "ChapterNameValue": "धडा {0}" } -- cgit v1.2.3 From 5e706ba7cee116ecd7a99fccfebec5fc275a8993 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 13 Jul 2020 06:55:03 +0900 Subject: keep playstate during syncplay group creation --- .../SyncPlay/SyncPlayController.cs | 32 ++++++++++------------ .../SyncPlay/SyncPlayManager.cs | 10 ++++--- MediaBrowser.Api/SyncPlay/SyncPlayService.cs | 25 +++-------------- MediaBrowser.Controller/SyncPlay/GroupInfo.cs | 22 +++++++-------- MediaBrowser.Controller/SyncPlay/GroupMember.cs | 2 +- .../SyncPlay/ISyncPlayController.cs | 2 +- MediaBrowser.Model/SyncPlay/JoinGroupRequest.cs | 6 ---- MediaBrowser.Model/SyncPlay/PlaybackRequestType.cs | 6 ++-- 8 files changed, 41 insertions(+), 64 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs index b1f8fd330c..e596d99005 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs @@ -194,26 +194,24 @@ namespace Emby.Server.Implementations.SyncPlay } /// - public void InitGroup(SessionInfo session, CancellationToken cancellationToken) + public void CreateGroup(SessionInfo session, CancellationToken cancellationToken) { _group.AddSession(session); _syncPlayManager.AddSessionToGroup(session, this); _group.PlayingItem = session.FullNowPlayingItem; - _group.IsPaused = true; + _group.IsPaused = session.PlayState.IsPaused; _group.PositionTicks = session.PlayState.PositionTicks ?? 0; _group.LastActivity = DateTime.UtcNow; var updateSession = NewSyncPlayGroupUpdate(GroupUpdateType.GroupJoined, DateToUTCString(DateTime.UtcNow)); SendGroupUpdate(session, BroadcastType.CurrentSession, updateSession, cancellationToken); - var pauseCommand = NewSyncPlayCommand(SendCommandType.Pause); - SendCommand(session, BroadcastType.CurrentSession, pauseCommand, cancellationToken); } /// public void SessionJoin(SessionInfo session, JoinGroupRequest request, CancellationToken cancellationToken) { - if (session.NowPlayingItem?.Id == _group.PlayingItem.Id && request.PlayingItemId == _group.PlayingItem.Id) + if (session.NowPlayingItem?.Id == _group.PlayingItem.Id) { _group.AddSession(session); _syncPlayManager.AddSessionToGroup(session, this); @@ -224,7 +222,7 @@ namespace Emby.Server.Implementations.SyncPlay var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserJoined, session.UserName); SendGroupUpdate(session, BroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken); - // Client join and play, syncing will happen client side + // syncing will happen client side if (!_group.IsPaused) { var playCommand = NewSyncPlayCommand(SendCommandType.Play); @@ -262,10 +260,9 @@ namespace Emby.Server.Implementations.SyncPlay /// public void HandleRequest(SessionInfo session, PlaybackRequest request, CancellationToken cancellationToken) { - // The server's job is to mantain a consistent state to which clients refer to, - // as also to notify clients of state changes. - // The actual syncing of media playback happens client side. - // Clients are aware of the server's time and use it to sync. + // The server's job is to maintain a consistent state for clients to reference + // and notify clients of state changes. The actual syncing of media playback + // happens client side. Clients are aware of the server's time and use it to sync. switch (request.Type) { case PlaybackRequestType.Play: @@ -277,13 +274,13 @@ namespace Emby.Server.Implementations.SyncPlay case PlaybackRequestType.Seek: HandleSeekRequest(session, request, cancellationToken); break; - case PlaybackRequestType.Buffering: + case PlaybackRequestType.Buffer: HandleBufferingRequest(session, request, cancellationToken); break; - case PlaybackRequestType.BufferingDone: + case PlaybackRequestType.Ready: HandleBufferingDoneRequest(session, request, cancellationToken); break; - case PlaybackRequestType.UpdatePing: + case PlaybackRequestType.Ping: HandlePingUpdateRequest(session, request); break; } @@ -301,7 +298,7 @@ namespace Emby.Server.Implementations.SyncPlay { // Pick a suitable time that accounts for latency var delay = _group.GetHighestPing() * 2; - delay = delay < _group.DefaulPing ? _group.DefaulPing : delay; + delay = delay < _group.DefaultPing ? _group.DefaultPing : delay; // Unpause group and set starting point in future // Clients will start playback at LastActivity (datetime) from PositionTicks (playback position) @@ -337,8 +334,9 @@ namespace Emby.Server.Implementations.SyncPlay var currentTime = DateTime.UtcNow; var elapsedTime = currentTime - _group.LastActivity; _group.LastActivity = currentTime; + // Seek only if playback actually started - // (a pause request may be issued during the delay added to account for latency) + // Pause request may be issued during the delay added to account for latency _group.PositionTicks += elapsedTime.Ticks > 0 ? elapsedTime.Ticks : 0; var command = NewSyncPlayCommand(SendCommandType.Pause); @@ -451,7 +449,7 @@ namespace Emby.Server.Implementations.SyncPlay { // Client, that was buffering, resumed playback but did not update others in time delay = _group.GetHighestPing() * 2; - delay = delay < _group.DefaulPing ? _group.DefaulPing : delay; + delay = delay < _group.DefaultPing ? _group.DefaultPing : delay; _group.LastActivity = currentTime.AddMilliseconds( delay); @@ -495,7 +493,7 @@ namespace Emby.Server.Implementations.SyncPlay private void HandlePingUpdateRequest(SessionInfo session, PlaybackRequest request) { // Collected pings are used to account for network latency when unpausing playback - _group.UpdatePing(session, request.Ping ?? _group.DefaulPing); + _group.UpdatePing(session, request.Ping ?? _group.DefaultPing); } /// diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs index 45a43fd789..966ed5024e 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs @@ -170,10 +170,11 @@ namespace Emby.Server.Implementations.SyncPlay { _logger.LogWarning("NewGroup: {0} does not have permission to create groups.", session.Id); - var error = new GroupUpdate() + var error = new GroupUpdate { Type = GroupUpdateType.CreateGroupDenied }; + _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -188,7 +189,7 @@ namespace Emby.Server.Implementations.SyncPlay var group = new SyncPlayController(_sessionManager, this); _groups[group.GetGroupId()] = group; - group.InitGroup(session, cancellationToken); + group.CreateGroup(session, cancellationToken); } } @@ -205,6 +206,7 @@ namespace Emby.Server.Implementations.SyncPlay { Type = GroupUpdateType.JoinGroupDenied }; + _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -300,9 +302,9 @@ namespace Emby.Server.Implementations.SyncPlay group => group.GetPlayingItemId().Equals(filterItemId) && HasAccessToItem(user, group.GetPlayingItemId())).Select( group => group.GetInfo()).ToList(); } - // Otherwise show all available groups else { + // Otherwise show all available groups return _groups.Values.Where( group => HasAccessToItem(user, group.GetPlayingItemId())).Select( group => group.GetInfo()).ToList(); @@ -322,6 +324,7 @@ namespace Emby.Server.Implementations.SyncPlay { Type = GroupUpdateType.JoinGroupDenied }; + _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -366,7 +369,6 @@ namespace Emby.Server.Implementations.SyncPlay } _sessionToGroupMap.Remove(session.Id, out var tempGroup); - if (!tempGroup.GetGroupId().Equals(group.GetGroupId())) { throw new InvalidOperationException("Session was in wrong group!"); diff --git a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs index 18983ea5ba..daa1b521f4 100644 --- a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs +++ b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs @@ -27,13 +27,6 @@ namespace MediaBrowser.Api.SyncPlay /// The Group id to join. [ApiMember(Name = "GroupId", Description = "Group Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] public string GroupId { get; set; } - - /// - /// Gets or sets the playing item id. - /// - /// The client's currently playing item id. - [ApiMember(Name = "PlayingItemId", Description = "Client's playing item id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] - public string PlayingItemId { get; set; } } [Route("/SyncPlay/Leave", "POST", Summary = "Leave joined SyncPlay group")] @@ -89,7 +82,7 @@ namespace MediaBrowser.Api.SyncPlay public long PositionTicks { get; set; } /// - /// Gets or sets whether this is a buffering or a buffering-done request. + /// Gets or sets whether this is a buffering or a ready request. /// /// true if buffering is complete; false otherwise. [ApiMember(Name = "BufferingDone", IsRequired = true, DataType = "bool", ParameterType = "query", Verb = "POST")] @@ -150,25 +143,15 @@ namespace MediaBrowser.Api.SyncPlay var currentSession = GetSession(_sessionContext); Guid groupId; - Guid playingItemId = Guid.Empty; - if (!Guid.TryParse(request.GroupId, out groupId)) { Logger.LogError("JoinGroup: {0} is not a valid format for GroupId. Ignoring request.", request.GroupId); return; } - // Both null and empty strings mean that client isn't playing anything - if (!string.IsNullOrEmpty(request.PlayingItemId) && !Guid.TryParse(request.PlayingItemId, out playingItemId)) - { - Logger.LogError("JoinGroup: {0} is not a valid format for PlayingItemId. Ignoring request.", request.PlayingItemId); - return; - } - var joinRequest = new JoinGroupRequest() { - GroupId = groupId, - PlayingItemId = playingItemId + GroupId = groupId }; _syncPlayManager.JoinGroup(currentSession, groupId, joinRequest, CancellationToken.None); @@ -254,7 +237,7 @@ namespace MediaBrowser.Api.SyncPlay var currentSession = GetSession(_sessionContext); var syncPlayRequest = new PlaybackRequest() { - Type = request.BufferingDone ? PlaybackRequestType.BufferingDone : PlaybackRequestType.Buffering, + Type = request.BufferingDone ? PlaybackRequestType.Ready : PlaybackRequestType.Buffer, When = DateTime.Parse(request.When), PositionTicks = request.PositionTicks }; @@ -270,7 +253,7 @@ namespace MediaBrowser.Api.SyncPlay var currentSession = GetSession(_sessionContext); var syncPlayRequest = new PlaybackRequest() { - Type = PlaybackRequestType.UpdatePing, + Type = PlaybackRequestType.Ping, Ping = Convert.ToInt64(request.Ping) }; _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None); diff --git a/MediaBrowser.Controller/SyncPlay/GroupInfo.cs b/MediaBrowser.Controller/SyncPlay/GroupInfo.cs index d0fac1efa3..e742df5179 100644 --- a/MediaBrowser.Controller/SyncPlay/GroupInfo.cs +++ b/MediaBrowser.Controller/SyncPlay/GroupInfo.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Controller.SyncPlay /// /// Gets the default ping value used for sessions. /// - public long DefaulPing { get; } = 500; + public long DefaultPing { get; } = 500; /// /// Gets or sets the group identifier. @@ -70,16 +70,16 @@ namespace MediaBrowser.Controller.SyncPlay /// The session. public void AddSession(SessionInfo session) { - if (ContainsSession(session.Id.ToString())) + if (ContainsSession(session.Id)) { return; } var member = new GroupMember(); member.Session = session; - member.Ping = DefaulPing; + member.Ping = DefaultPing; member.IsBuffering = false; - Participants[session.Id.ToString()] = member; + Participants[session.Id] = member; } /// @@ -88,12 +88,12 @@ namespace MediaBrowser.Controller.SyncPlay /// The session. public void RemoveSession(SessionInfo session) { - if (!ContainsSession(session.Id.ToString())) + if (!ContainsSession(session.Id)) { return; } - Participants.Remove(session.Id.ToString(), out _); + Participants.Remove(session.Id, out _); } /// @@ -103,12 +103,12 @@ namespace MediaBrowser.Controller.SyncPlay /// The ping. public void UpdatePing(SessionInfo session, long ping) { - if (!ContainsSession(session.Id.ToString())) + if (!ContainsSession(session.Id)) { return; } - Participants[session.Id.ToString()].Ping = ping; + Participants[session.Id].Ping = ping; } /// @@ -117,7 +117,7 @@ namespace MediaBrowser.Controller.SyncPlay /// The highest ping in the group. public long GetHighestPing() { - long max = Int64.MinValue; + long max = long.MinValue; foreach (var session in Participants.Values) { max = Math.Max(max, session.Ping); @@ -133,12 +133,12 @@ namespace MediaBrowser.Controller.SyncPlay /// The state. public void SetBuffering(SessionInfo session, bool isBuffering) { - if (!ContainsSession(session.Id.ToString())) + if (!ContainsSession(session.Id)) { return; } - Participants[session.Id.ToString()].IsBuffering = isBuffering; + Participants[session.Id].IsBuffering = isBuffering; } /// diff --git a/MediaBrowser.Controller/SyncPlay/GroupMember.cs b/MediaBrowser.Controller/SyncPlay/GroupMember.cs index a3975c334c..cde6f8e8ce 100644 --- a/MediaBrowser.Controller/SyncPlay/GroupMember.cs +++ b/MediaBrowser.Controller/SyncPlay/GroupMember.cs @@ -8,7 +8,7 @@ namespace MediaBrowser.Controller.SyncPlay public class GroupMember { /// - /// Gets or sets whether this member is buffering. + /// Gets or sets a value indicating whether this member is buffering. /// /// true if member is buffering; false otherwise. public bool IsBuffering { get; set; } diff --git a/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs b/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs index de1fcd2591..45c5438061 100644 --- a/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs +++ b/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.SyncPlay /// /// The session. /// The cancellation token. - void InitGroup(SessionInfo session, CancellationToken cancellationToken); + void CreateGroup(SessionInfo session, CancellationToken cancellationToken); /// /// Adds the session to the group. diff --git a/MediaBrowser.Model/SyncPlay/JoinGroupRequest.cs b/MediaBrowser.Model/SyncPlay/JoinGroupRequest.cs index d67b6bd555..0c77a61322 100644 --- a/MediaBrowser.Model/SyncPlay/JoinGroupRequest.cs +++ b/MediaBrowser.Model/SyncPlay/JoinGroupRequest.cs @@ -12,11 +12,5 @@ namespace MediaBrowser.Model.SyncPlay /// /// The Group id to join. public Guid GroupId { get; set; } - - /// - /// Gets or sets the playing item id. - /// - /// The client's currently playing item id. - public Guid PlayingItemId { get; set; } } } diff --git a/MediaBrowser.Model/SyncPlay/PlaybackRequestType.cs b/MediaBrowser.Model/SyncPlay/PlaybackRequestType.cs index 671f4e01ff..e89efeed8a 100644 --- a/MediaBrowser.Model/SyncPlay/PlaybackRequestType.cs +++ b/MediaBrowser.Model/SyncPlay/PlaybackRequestType.cs @@ -23,16 +23,16 @@ namespace MediaBrowser.Model.SyncPlay /// /// A user is signaling that playback is buffering. /// - Buffering = 3, + Buffer = 3, /// /// A user is signaling that playback resumed. /// - BufferingDone = 4, + Ready = 4, /// /// A user is reporting its ping. /// - UpdatePing = 5 + Ping = 5 } } -- cgit v1.2.3 From 52290380aa5e3cafc5208a9e4b5ebf1b93f52d38 Mon Sep 17 00:00:00 2001 From: kanenses Date: Mon, 13 Jul 2020 00:30:14 +0000 Subject: Translated using Weblate (Portuguese) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/pt/ --- Emby.Server.Implementations/Localization/Core/pt.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/pt.json b/Emby.Server.Implementations/Localization/Core/pt.json index 5365fff232..b534d0bbeb 100644 --- a/Emby.Server.Implementations/Localization/Core/pt.json +++ b/Emby.Server.Implementations/Localization/Core/pt.json @@ -104,5 +104,14 @@ "TaskRefreshChapterImagesDescription": "Cria miniaturas para vídeos que têm capítulos.", "TaskCleanCacheDescription": "Apaga ficheiros em cache que já não são usados pelo sistema.", "TasksChannelsCategory": "Canais de Internet", - "TaskRefreshChapterImages": "Extrair Imagens do Capítulo" + "TaskRefreshChapterImages": "Extrair Imagens do Capítulo", + "TaskDownloadMissingSubtitlesDescription": "Pesquisa na Internet as legendas em falta com base na configuração de metadados.", + "TaskDownloadMissingSubtitles": "Download das legendas em falta", + "TaskRefreshChannelsDescription": "Atualiza as informações do canal da Internet.", + "TaskCleanTranscodeDescription": "Apagar os ficheiros com mais de um dia, de Transcode.", + "TaskCleanTranscode": "Limpar o diretório de Transcode", + "TaskUpdatePluginsDescription": "Download e instala as atualizações para plug-ins configurados para atualização automática.", + "TaskRefreshPeopleDescription": "Atualiza os metadados para atores e diretores na tua biblioteca de media.", + "TaskRefreshPeople": "Atualizar pessoas", + "TaskRefreshLibraryDescription": "Pesquisa a tua biblioteca de media por novos ficheiros e atualiza os metadados." } -- cgit v1.2.3 From 359b0044b848cf49e8c52bb30fb1a3e8cf8f16b7 Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 13 Jul 2020 15:12:51 +0100 Subject: Prevent failure to bind to Auto Discover port being a fatal error --- .../EntryPoints/UdpServerEntryPoint.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index b207397bda..a9e84c2384 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -48,8 +48,16 @@ namespace Emby.Server.Implementations.EntryPoints /// public Task RunAsync() { - _udpServer = new UdpServer(_logger, _appHost, _config); - _udpServer.Start(PortNumber, _cancellationTokenSource.Token); + try + { + _udpServer = new UdpServer(_logger, _appHost, _config); + _udpServer.Start(PortNumber, _cancellationTokenSource.Token); + } + catch (System.Net.Sockets.SocketException ex) + { + _logger.LogWarning($"Unable to start AutoDiscovery listener on UDP port {PortNumber} - {ex.Message}"); + } + return Task.CompletedTask; } -- cgit v1.2.3 From 25e382748899dd1a0e001530fbffa80b8f4451a8 Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 13 Jul 2020 15:39:14 +0100 Subject: Update Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs Update log format message and log exception Co-authored-by: Cody Robibero --- Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index a9e84c2384..946b9a87b8 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -55,7 +55,7 @@ namespace Emby.Server.Implementations.EntryPoints } catch (System.Net.Sockets.SocketException ex) { - _logger.LogWarning($"Unable to start AutoDiscovery listener on UDP port {PortNumber} - {ex.Message}"); + _logger.LogWarning(ex, "Unable to start AutoDiscovery listener on UDP port {PortNumber}", PortNumber); } return Task.CompletedTask; -- cgit v1.2.3 From da8eb1f15b034b946e6533baffca8ffa17bcb3a7 Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 13 Jul 2020 16:33:39 +0100 Subject: using System.Net.Sockets --- Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index 946b9a87b8..9486874d58 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -1,3 +1,4 @@ +using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.Udp; @@ -53,7 +54,7 @@ namespace Emby.Server.Implementations.EntryPoints _udpServer = new UdpServer(_logger, _appHost, _config); _udpServer.Start(PortNumber, _cancellationTokenSource.Token); } - catch (System.Net.Sockets.SocketException ex) + catch (SocketException ex) { _logger.LogWarning(ex, "Unable to start AutoDiscovery listener on UDP port {PortNumber}", PortNumber); } -- cgit v1.2.3 From 3b085f6a03bfe945e12b104bb042be1d00981cd2 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Wed, 17 Jun 2020 10:24:25 -0400 Subject: Remove UserManager.AddParts --- Emby.Server.Implementations/ApplicationHost.cs | 4 ++- .../Users/UserManager.cs | 35 +++++++++++----------- MediaBrowser.Controller/Library/IUserManager.cs | 3 -- 3 files changed, 20 insertions(+), 22 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index f6077400d6..908fe4b302 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -547,6 +547,9 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(ServerConfigurationManager); + serviceCollection.AddSingleton>>(() => GetExports()); + serviceCollection.AddSingleton>>(() => GetExports()); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -795,7 +798,6 @@ namespace Emby.Server.Implementations Resolve().AddParts(GetExports()); Resolve().AddParts(GetExports(), GetExports()); - Resolve().AddParts(GetExports(), GetExports()); Resolve().AddParts(GetExports()); } diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 6283a1bca5..d4b91f3c53 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -39,12 +39,11 @@ namespace Jellyfin.Server.Implementations.Users private readonly IApplicationHost _appHost; private readonly IImageProcessor _imageProcessor; private readonly ILogger _logger; - - private IAuthenticationProvider[] _authenticationProviders = null!; - private DefaultAuthenticationProvider _defaultAuthenticationProvider = null!; - private InvalidAuthProvider _invalidAuthProvider = null!; - private IPasswordResetProvider[] _passwordResetProviders = null!; - private DefaultPasswordResetProvider _defaultPasswordResetProvider = null!; + private readonly IReadOnlyCollection _passwordResetProviders; + private readonly IReadOnlyCollection _authenticationProviders; + private readonly InvalidAuthProvider _invalidAuthProvider; + private readonly DefaultAuthenticationProvider _defaultAuthenticationProvider; + private readonly DefaultPasswordResetProvider _defaultPasswordResetProvider; /// /// Initializes a new instance of the class. @@ -55,13 +54,17 @@ namespace Jellyfin.Server.Implementations.Users /// The application host. /// The image processor. /// The logger. + /// A function that returns available password reset providers. + /// A function that returns available authentication providers. public UserManager( JellyfinDbProvider dbProvider, ICryptoProvider cryptoProvider, INetworkManager networkManager, IApplicationHost appHost, IImageProcessor imageProcessor, - ILogger logger) + ILogger logger, + Func> passwordResetProviders, + Func> authenticationProviders) { _dbProvider = dbProvider; _cryptoProvider = cryptoProvider; @@ -69,6 +72,13 @@ namespace Jellyfin.Server.Implementations.Users _appHost = appHost; _imageProcessor = imageProcessor; _logger = logger; + + _passwordResetProviders = passwordResetProviders.Invoke(); + _authenticationProviders = authenticationProviders.Invoke(); + + _invalidAuthProvider = _authenticationProviders.OfType().First(); + _defaultAuthenticationProvider = _authenticationProviders.OfType().First(); + _defaultPasswordResetProvider = _passwordResetProviders.OfType().First(); } /// @@ -557,17 +567,6 @@ namespace Jellyfin.Server.Implementations.Users }; } - /// - public void AddParts(IEnumerable authenticationProviders, IEnumerable passwordResetProviders) - { - _authenticationProviders = authenticationProviders.ToArray(); - _passwordResetProviders = passwordResetProviders.ToArray(); - - _invalidAuthProvider = _authenticationProviders.OfType().First(); - _defaultAuthenticationProvider = _authenticationProviders.OfType().First(); - _defaultPasswordResetProvider = _passwordResetProviders.OfType().First(); - } - /// public void Initialize() { diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index e73fe71205..88b96ddbf8 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using Jellyfin.Data.Entities; -using MediaBrowser.Controller.Authentication; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Events; @@ -166,8 +165,6 @@ namespace MediaBrowser.Controller.Library /// true if XXXX, false otherwise. Task RedeemPasswordResetPin(string pin); - void AddParts(IEnumerable authenticationProviders, IEnumerable passwordResetProviders); - NameIdPair[] GetAuthenticationProviders(); NameIdPair[] GetPasswordResetProviders(); -- cgit v1.2.3 From 303c175714db50bf865939fd12c66dcbda229431 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sat, 20 Jun 2020 17:58:09 -0400 Subject: Fix circular dependency --- Emby.Server.Implementations/ApplicationHost.cs | 3 --- .../Users/DefaultPasswordResetProvider.cs | 16 +++++++++------- Jellyfin.Server.Implementations/Users/UserManager.cs | 17 +++++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 908fe4b302..1ff14bdb5c 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -547,9 +547,6 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(ServerConfigurationManager); - serviceCollection.AddSingleton>>(() => GetExports()); - serviceCollection.AddSingleton>>(() => GetExports()); - serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); diff --git a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs index cf5a01f083..007c296436 100644 --- a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs +++ b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs @@ -6,6 +6,7 @@ using System.IO; using System.Security.Cryptography; using System.Threading.Tasks; using Jellyfin.Data.Entities; +using MediaBrowser.Common; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Authentication; using MediaBrowser.Controller.Configuration; @@ -23,7 +24,7 @@ namespace Jellyfin.Server.Implementations.Users private const string BaseResetFileName = "passwordreset"; private readonly IJsonSerializer _jsonSerializer; - private readonly IUserManager _userManager; + private readonly IApplicationHost _appHost; private readonly string _passwordResetFileBase; private readonly string _passwordResetFileBaseDir; @@ -33,16 +34,17 @@ namespace Jellyfin.Server.Implementations.Users /// /// The configuration manager. /// The JSON serializer. - /// The user manager. + /// The application host. public DefaultPasswordResetProvider( IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, - IUserManager userManager) + IApplicationHost appHost) { _passwordResetFileBaseDir = configurationManager.ApplicationPaths.ProgramDataPath; _passwordResetFileBase = Path.Combine(_passwordResetFileBaseDir, BaseResetFileName); _jsonSerializer = jsonSerializer; - _userManager = userManager; + _appHost = appHost; + // TODO: Remove the circular dependency on UserManager } /// @@ -54,6 +56,7 @@ namespace Jellyfin.Server.Implementations.Users /// public async Task RedeemPasswordResetPin(string pin) { + var userManager = _appHost.Resolve(); var usersReset = new List(); foreach (var resetFile in Directory.EnumerateFiles(_passwordResetFileBaseDir, $"{BaseResetFileName}*")) { @@ -72,10 +75,10 @@ namespace Jellyfin.Server.Implementations.Users pin.Replace("-", string.Empty, StringComparison.Ordinal), StringComparison.InvariantCultureIgnoreCase)) { - var resetUser = _userManager.GetUserByName(spr.UserName) + var resetUser = userManager.GetUserByName(spr.UserName) ?? throw new ResourceNotFoundException($"User with a username of {spr.UserName} not found"); - await _userManager.ChangePassword(resetUser, pin).ConfigureAwait(false); + await userManager.ChangePassword(resetUser, pin).ConfigureAwait(false); usersReset.Add(resetUser.Username); File.Delete(resetFile); } @@ -121,7 +124,6 @@ namespace Jellyfin.Server.Implementations.Users } user.EasyPassword = pin; - await _userManager.UpdateUserAsync(user).ConfigureAwait(false); return new ForgotPasswordResult { diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index d4b91f3c53..988b0c430b 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -54,17 +54,13 @@ namespace Jellyfin.Server.Implementations.Users /// The application host. /// The image processor. /// The logger. - /// A function that returns available password reset providers. - /// A function that returns available authentication providers. public UserManager( JellyfinDbProvider dbProvider, ICryptoProvider cryptoProvider, INetworkManager networkManager, IApplicationHost appHost, IImageProcessor imageProcessor, - ILogger logger, - Func> passwordResetProviders, - Func> authenticationProviders) + ILogger logger) { _dbProvider = dbProvider; _cryptoProvider = cryptoProvider; @@ -73,8 +69,8 @@ namespace Jellyfin.Server.Implementations.Users _imageProcessor = imageProcessor; _logger = logger; - _passwordResetProviders = passwordResetProviders.Invoke(); - _authenticationProviders = authenticationProviders.Invoke(); + _passwordResetProviders = appHost.GetExports(); + _authenticationProviders = appHost.GetExports(); _invalidAuthProvider = _authenticationProviders.OfType().First(); _defaultAuthenticationProvider = _authenticationProviders.OfType().First(); @@ -537,7 +533,12 @@ namespace Jellyfin.Server.Implementations.Users if (user != null && isInNetwork) { var passwordResetProvider = GetPasswordResetProvider(user); - return await passwordResetProvider.StartForgotPasswordProcess(user, isInNetwork).ConfigureAwait(false); + var result = await passwordResetProvider + .StartForgotPasswordProcess(user, isInNetwork) + .ConfigureAwait(false); + + await UpdateUserAsync(user).ConfigureAwait(false); + return result; } return new ForgotPasswordResult -- cgit v1.2.3 From bf09bbeacd78c53d881174d82e35412fb33bd492 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 14 Jul 2020 08:25:02 +0900 Subject: update comment Co-authored-by: Patrick Barron <18354464+barronpm@users.noreply.github.com> --- Emby.Server.Implementations/SyncPlay/SyncPlayController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs index e596d99005..39d17833ff 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs @@ -222,7 +222,7 @@ namespace Emby.Server.Implementations.SyncPlay var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserJoined, session.UserName); SendGroupUpdate(session, BroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken); - // syncing will happen client side + // Syncing will happen client-side if (!_group.IsPaused) { var playCommand = NewSyncPlayCommand(SendCommandType.Play); -- cgit v1.2.3 From eddce72c5228f423d8f2e738ced5cc4c3cccae66 Mon Sep 17 00:00:00 2001 From: Raif Coonjah Date: Tue, 14 Jul 2020 11:21:09 +0000 Subject: Translated using Weblate (Afrikaans) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/af/ --- Emby.Server.Implementations/Localization/Core/af.json | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/af.json b/Emby.Server.Implementations/Localization/Core/af.json index 20447347b3..e587c37d53 100644 --- a/Emby.Server.Implementations/Localization/Core/af.json +++ b/Emby.Server.Implementations/Localization/Core/af.json @@ -19,8 +19,8 @@ "Sync": "Sinkroniseer", "HeaderFavoriteSongs": "Gunsteling Liedjies", "Songs": "Liedjies", - "DeviceOnlineWithName": "{0} is verbind", - "DeviceOfflineWithName": "{0} het afgesluit", + "DeviceOnlineWithName": "{0} gekoppel is", + "DeviceOfflineWithName": "{0} is ontkoppel", "Collections": "Versamelings", "Inherit": "Ontvang", "HeaderLiveTV": "Live TV", @@ -91,5 +91,9 @@ "ChapterNameValue": "Hoofstuk", "CameraImageUploadedFrom": "'n Nuwe kamera photo opgelaai van {0}", "AuthenticationSucceededWithUserName": "{0} suksesvol geverifieer", - "Albums": "Albums" + "Albums": "Albums", + "TasksChannelsCategory": "Internet kanale", + "TasksApplicationCategory": "aansoek", + "TasksLibraryCategory": "biblioteek", + "TasksMaintenanceCategory": "onderhoud" } -- cgit v1.2.3 From a23920e2ad45c01439c668fe524ae892af1b1569 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Wed, 15 Jul 2020 13:18:02 +0200 Subject: Only fetch Next Up for episodes that have been fully matched --- Emby.Server.Implementations/TV/TVSeriesManager.cs | 28 ++++++++++------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index 21c12ae79f..552c9d1c1a 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -117,23 +117,19 @@ namespace Emby.Server.Implementations.TV limit = limit.Value + 10; } - var items = _libraryManager.GetItemList(new InternalItemsQuery(user) - { - IncludeItemTypes = new[] { typeof(Episode).Name }, - OrderBy = new[] { new ValueTuple(ItemSortBy.DatePlayed, SortOrder.Descending) }, - SeriesPresentationUniqueKey = presentationUniqueKey, - Limit = limit, - DtoOptions = new DtoOptions + var items = _libraryManager + .GetItemList(new InternalItemsQuery(user) { - Fields = new ItemFields[] - { - ItemFields.SeriesPresentationUniqueKey - }, - EnableImages = false - }, - GroupBySeriesPresentationUniqueKey = true - - }, parentsFolders.ToList()).Cast().Select(GetUniqueSeriesKey); + IncludeItemTypes = new[] {typeof(Episode).Name}, + OrderBy = new[] {new ValueTuple(ItemSortBy.DatePlayed, SortOrder.Descending)}, + SeriesPresentationUniqueKey = presentationUniqueKey, + Limit = limit, + DtoOptions = new DtoOptions {Fields = new ItemFields[] {ItemFields.SeriesPresentationUniqueKey}, EnableImages = false}, + GroupBySeriesPresentationUniqueKey = true + }, parentsFolders.ToList()) + .Cast() + .Where(episode => !string.IsNullOrEmpty(episode.SeriesPresentationUniqueKey)) + .Select(GetUniqueSeriesKey); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items, dtoOptions); -- cgit v1.2.3 From 90fa1149fa8d7b770c91fd881bf150fd3fec521e Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Wed, 15 Jul 2020 19:04:36 +0200 Subject: Fix warnings --- Emby.Server.Implementations/TV/TVSeriesManager.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index 552c9d1c1a..d1818deff4 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -118,15 +118,16 @@ namespace Emby.Server.Implementations.TV } var items = _libraryManager - .GetItemList(new InternalItemsQuery(user) - { - IncludeItemTypes = new[] {typeof(Episode).Name}, - OrderBy = new[] {new ValueTuple(ItemSortBy.DatePlayed, SortOrder.Descending)}, - SeriesPresentationUniqueKey = presentationUniqueKey, - Limit = limit, - DtoOptions = new DtoOptions {Fields = new ItemFields[] {ItemFields.SeriesPresentationUniqueKey}, EnableImages = false}, - GroupBySeriesPresentationUniqueKey = true - }, parentsFolders.ToList()) + .GetItemList( + new InternalItemsQuery(user) + { + IncludeItemTypes = new[] { typeof(Episode).Name }, + OrderBy = new[] { new ValueTuple(ItemSortBy.DatePlayed, SortOrder.Descending) }, + SeriesPresentationUniqueKey = presentationUniqueKey, + Limit = limit, + DtoOptions = new DtoOptions { Fields = new[] { ItemFields.SeriesPresentationUniqueKey }, EnableImages = false }, + GroupBySeriesPresentationUniqueKey = true + }, parentsFolders.ToList()) .Cast() .Where(episode => !string.IsNullOrEmpty(episode.SeriesPresentationUniqueKey)) .Select(GetUniqueSeriesKey); -- cgit v1.2.3 From f40bcff1134bf45495aaa877df348a9daff891ee Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 16 Jul 2020 08:28:31 -0600 Subject: Catch HttpRequestException when requesting plugins --- Emby.Server.Implementations/Updates/InstallationManager.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 146ebaf25b..4f54c06dd2 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -148,6 +148,11 @@ namespace Emby.Server.Implementations.Updates _logger.LogError(ex, "An error occurred while accessing the plugin manifest: {Manifest}", manifest); return Array.Empty(); } + catch (HttpRequestException ex) + { + _logger.LogError(ex, "An error occurred while accessing the plugin manifest: {Manifest}", manifest); + return Array.Empty(); + } } /// -- cgit v1.2.3 From 0c64ad9b1634d37c09d1160411eb75f98f7a47ce Mon Sep 17 00:00:00 2001 From: ADRI IDZWAN MANSOR Date: Thu, 16 Jul 2020 11:36:39 +0000 Subject: Translated using Weblate (Malay) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ms/ --- .../Localization/Core/ms.json | 64 +++++++++++----------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/ms.json b/Emby.Server.Implementations/Localization/Core/ms.json index 79d078d4a8..7f8df12895 100644 --- a/Emby.Server.Implementations/Localization/Core/ms.json +++ b/Emby.Server.Implementations/Localization/Core/ms.json @@ -5,47 +5,47 @@ "Artists": "Artis", "AuthenticationSucceededWithUserName": "{0} berjaya disahkan", "Books": "Buku-buku", - "CameraImageUploadedFrom": "A new camera image has been uploaded from {0}", + "CameraImageUploadedFrom": "Ada gambar dari kamera yang baru dimuat naik melalui {0}", "Channels": "Saluran", - "ChapterNameValue": "Chapter {0}", + "ChapterNameValue": "Bab {0}", "Collections": "Koleksi", - "DeviceOfflineWithName": "{0} has disconnected", - "DeviceOnlineWithName": "{0} is connected", + "DeviceOfflineWithName": "{0} telah diputuskan sambungan", + "DeviceOnlineWithName": "{0} telah disambung", "FailedLoginAttemptWithUserName": "Cubaan log masuk gagal dari {0}", - "Favorites": "Favorites", - "Folders": "Folders", + "Favorites": "Kegemaran", + "Folders": "Fail-fail", "Genres": "Genre-genre", - "HeaderAlbumArtists": "Album Artists", + "HeaderAlbumArtists": "Album Artis-artis", "HeaderCameraUploads": "Muatnaik Kamera", "HeaderContinueWatching": "Terus Menonton", - "HeaderFavoriteAlbums": "Favorite Albums", - "HeaderFavoriteArtists": "Favorite Artists", - "HeaderFavoriteEpisodes": "Favorite Episodes", - "HeaderFavoriteShows": "Favorite Shows", - "HeaderFavoriteSongs": "Favorite Songs", - "HeaderLiveTV": "Live TV", - "HeaderNextUp": "Next Up", - "HeaderRecordingGroups": "Recording Groups", - "HomeVideos": "Home videos", - "Inherit": "Inherit", - "ItemAddedWithName": "{0} was added to the library", - "ItemRemovedWithName": "{0} was removed from the library", + "HeaderFavoriteAlbums": "Album-album Kegemaran", + "HeaderFavoriteArtists": "Artis-artis Kegemaran", + "HeaderFavoriteEpisodes": "Episod-episod Kegemaran", + "HeaderFavoriteShows": "Rancangan-rancangan Kegemaran", + "HeaderFavoriteSongs": "Lagu-lagu Kegemaran", + "HeaderLiveTV": "TV Siaran Langsung", + "HeaderNextUp": "Seterusnya", + "HeaderRecordingGroups": "Kumpulan-kumpulan Rakaman", + "HomeVideos": "Video Personal", + "Inherit": "Mewarisi", + "ItemAddedWithName": "{0} telah ditambahkan ke dalam pustaka", + "ItemRemovedWithName": "{0} telah dibuang daripada pustaka", "LabelIpAddressValue": "Alamat IP: {0}", - "LabelRunningTimeValue": "Running time: {0}", - "Latest": "Latest", - "MessageApplicationUpdated": "Jellyfin Server has been updated", - "MessageApplicationUpdatedTo": "Jellyfin Server has been updated to {0}", - "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated", - "MessageServerConfigurationUpdated": "Server configuration has been updated", - "MixedContent": "Mixed content", - "Movies": "Movies", + "LabelRunningTimeValue": "Masa berjalan: {0}", + "Latest": "Terbaru", + "MessageApplicationUpdated": "Jellyfin Server telah dikemas kini", + "MessageApplicationUpdatedTo": "Jellyfin Server telah dikemas kini ke {0}", + "MessageNamedServerConfigurationUpdatedWithValue": "Konfigurasi pelayan di bahagian {0} telah dikemas kini", + "MessageServerConfigurationUpdated": "Konfigurasi pelayan telah dikemas kini", + "MixedContent": "Kandungan campuran", + "Movies": "Filem", "Music": "Muzik", "MusicVideos": "Video muzik", - "NameInstallFailed": "{0} installation failed", - "NameSeasonNumber": "Season {0}", - "NameSeasonUnknown": "Season Unknown", - "NewVersionIsAvailable": "A new version of Jellyfin Server is available for download.", - "NotificationOptionApplicationUpdateAvailable": "Application update available", + "NameInstallFailed": "{0} pemasangan gagal", + "NameSeasonNumber": "Musim {0}", + "NameSeasonUnknown": "Musim Tidak Diketahui", + "NewVersionIsAvailable": "Versi terbaru Jellyfin Server bersedia untuk dimuat turunkan.", + "NotificationOptionApplicationUpdateAvailable": "Kemas kini aplikasi telah sedia", "NotificationOptionApplicationUpdateInstalled": "Application update installed", "NotificationOptionAudioPlayback": "Audio playback started", "NotificationOptionAudioPlaybackStopped": "Audio playback stopped", -- cgit v1.2.3 From 7e53bc5ec5eb511e4326d576e97997974ce47328 Mon Sep 17 00:00:00 2001 From: Akachai Bunsorn Date: Fri, 17 Jul 2020 09:26:26 +0000 Subject: Translated using Weblate (Thai) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/th/ --- Emby.Server.Implementations/Localization/Core/th.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/th.json b/Emby.Server.Implementations/Localization/Core/th.json index 32538ac035..576aaeb1bb 100644 --- a/Emby.Server.Implementations/Localization/Core/th.json +++ b/Emby.Server.Implementations/Localization/Core/th.json @@ -67,5 +67,7 @@ "Artists": "นักแสดง", "Application": "แอปพลิเคชั่น", "AppDeviceValues": "App: {0}, อุปกรณ์: {1}", - "Albums": "อัลบั้ม" + "Albums": "อัลบั้ม", + "ScheduledTaskStartedWithName": "{0} เริ่มต้น", + "ScheduledTaskFailedWithName": "{0} ล้มเหลว" } -- cgit v1.2.3 From 31ffd00dbd547c42db93df07ab9b1c87034bab13 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 17 Jul 2020 12:51:55 +0100 Subject: Update ApplicationHost.cs --- Emby.Server.Implementations/ApplicationHost.cs | 36 -------------------------- 1 file changed, 36 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 4d99bd759d..8d213ac57d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -351,42 +351,6 @@ namespace Emby.Server.Implementations public object CreateInstance(Type type) => ActivatorUtilities.CreateInstance(ServiceProvider, type); - /// - /// Creates an instance of type and resolves all constructor dependencies. - /// - /// The type. - /// Additional argument for the constructor. - /// - public object CreateInstance(Type type, object parameter) - { - ConstructorInfo constructor = type.GetConstructors()[0]; - if (constructor != null) - { - ParameterInfo[] argInfo = constructor - .GetParameters(); - - object[] args = argInfo - .Select(o => o.ParameterType) - .Select(o => ServiceProvider.GetService(o)) - .ToArray(); - - if (parameter != null) - { - // Assumption is that the is always the last in the constructor's parameter list. - int argsLen = args.Length; - var argType = argInfo[argsLen - 1].ParameterType; - var paramType = parameter.GetType(); - if (argType.IsAssignableFrom(paramType) || argType == paramType) - { - args[argsLen - 1] = parameter; - return ActivatorUtilities.CreateInstance(ServiceProvider, type, args); - } - } - } - - return ActivatorUtilities.CreateInstance(ServiceProvider, type); - } - /// /// Creates an instance of type and resolves all constructor dependencies. /// -- cgit v1.2.3 From 02d3bb758866b7707971b282e40529e196a42880 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 17 Jul 2020 12:53:20 +0100 Subject: Update ApplicationHost.cs --- Emby.Server.Implementations/ApplicationHost.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8d213ac57d..18b6834ef5 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -566,7 +566,6 @@ namespace Emby.Server.Implementations serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); // TODO: Refactor to eliminate the circular dependency here so that Lazy isn't required - // TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); serviceCollection.AddSingleton(); -- cgit v1.2.3 From a44309f56f300cfc670ca2fb62e93f5571aac66a Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 17 Jul 2020 12:53:50 +0100 Subject: Update HttpListenerHost.cs --- Emby.Server.Implementations/HttpServer/HttpListenerHost.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 6860b7ecdf..7c0d06fb29 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -106,12 +106,7 @@ namespace Emby.Server.Implementations.HttpServer { return _appHost.CreateInstance(type); } - - public object CreateInstance(Type type, object parameter) - { - return _appHost.CreateInstance(type, parameter); - } - + private static string NormalizeUrlPath(string path) { if (path.Length > 0 && path[0] == '/') -- cgit v1.2.3 From 7cd4ae3b6e5d1d921132b55e46d3db4f3aefe59f Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 17 Jul 2020 12:54:13 +0100 Subject: Update HttpListenerHost.cs --- Emby.Server.Implementations/HttpServer/HttpListenerHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 7c0d06fb29..c3428ee62a 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.HttpServer { return _appHost.CreateInstance(type); } - + private static string NormalizeUrlPath(string path) { if (path.Length > 0 && path[0] == '/') -- cgit v1.2.3 From 912847ae8c9bf1bc951a0d1d293c05b9ff06bb0a Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 17 Jul 2020 12:54:28 +0100 Subject: Update ServiceController.cs --- Emby.Server.Implementations/Services/ServiceController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs index b1f2a68273..d884d4f379 100644 --- a/Emby.Server.Implementations/Services/ServiceController.cs +++ b/Emby.Server.Implementations/Services/ServiceController.cs @@ -177,7 +177,7 @@ namespace Emby.Server.Implementations.Services var serviceType = httpHost.GetServiceTypeByRequest(requestType); - var service = httpHost.CreateInstance(serviceType, req); + var service = httpHost.CreateInstance(serviceType); var serviceRequiresContext = service as IRequiresRequest; if (serviceRequiresContext != null) -- cgit v1.2.3 From 06beecc4f84971c75f4b1f015dd5ed74a55fe5df Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 17 Jul 2020 12:56:52 +0100 Subject: Update ServiceHandler.cs --- Emby.Server.Implementations/Services/ServiceHandler.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index a42f88ea09..c544c86f5b 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -78,7 +78,8 @@ namespace Emby.Server.Implementations.Services var request = await CreateRequest(httpHost, httpReq, _restPath, logger).ConfigureAwait(false); httpHost.ApplyRequestFilters(httpReq, httpRes, request); - + + httpRes.HttpContext.Items["ServiceStackRequest"] = httpReq; var response = await httpHost.ServiceController.Execute(httpHost, request, httpReq).ConfigureAwait(false); // Apply response filters -- cgit v1.2.3 From 0140262e2fdd3e773e7773620d1c4e5743c3204d Mon Sep 17 00:00:00 2001 From: David Date: Fri, 17 Jul 2020 11:19:27 +0000 Subject: Translated using Weblate (German) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/de/ --- Emby.Server.Implementations/Localization/Core/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Localization/Core/de.json b/Emby.Server.Implementations/Localization/Core/de.json index 82df43be11..a6e9779c95 100644 --- a/Emby.Server.Implementations/Localization/Core/de.json +++ b/Emby.Server.Implementations/Localization/Core/de.json @@ -3,7 +3,7 @@ "AppDeviceValues": "App: {0}, Gerät: {1}", "Application": "Anwendung", "Artists": "Interpreten", - "AuthenticationSucceededWithUserName": "{0} hat sich erfolgreich authentifiziert", + "AuthenticationSucceededWithUserName": "{0} hat sich erfolgreich angemeldet", "Books": "Bücher", "CameraImageUploadedFrom": "Ein neues Foto wurde von {0} hochgeladen", "Channels": "Kanäle", -- cgit v1.2.3 From fd2f18899b8ea4db5152d98d9822d6cff6d7d892 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 17 Jul 2020 16:06:32 +0100 Subject: Update ServiceHandler.cs --- Emby.Server.Implementations/Services/ServiceHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index c544c86f5b..3997a5ddb7 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -79,7 +79,7 @@ namespace Emby.Server.Implementations.Services httpHost.ApplyRequestFilters(httpReq, httpRes, request); - httpRes.HttpContext.Items["ServiceStackRequest"] = httpReq; + httpRes.HttpContext.SetServiceStackRequest(httpReq); var response = await httpHost.ServiceController.Execute(httpHost, request, httpReq).ConfigureAwait(false); // Apply response filters -- cgit v1.2.3 From 24c1776ff61481b85b016cc0fcfef0a319589fdc Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 17 Jul 2020 16:06:52 +0100 Subject: Add files via upload --- .../Services/HttpContextExtension.cs | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Emby.Server.Implementations/Services/HttpContextExtension.cs (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Services/HttpContextExtension.cs b/Emby.Server.Implementations/Services/HttpContextExtension.cs new file mode 100644 index 0000000000..6d3a600ab5 --- /dev/null +++ b/Emby.Server.Implementations/Services/HttpContextExtension.cs @@ -0,0 +1,33 @@ +using MediaBrowser.Model.Services; +using Microsoft.AspNetCore.Http; + +namespace Emby.Server.Implementations.Services +{ + /// + /// Extention to enable the service stack request to be stored in the HttpRequest object. + /// + public static class HttpContextExtension + { + private const string SERVICESTACKREQUEST = "ServiceRequestStack"; + + /// + /// Set the service stack request. + /// + /// The HttpContext instance. + /// The IRequest instance. + public static void SetServiceStackRequest(this HttpContext httpContext, IRequest request) + { + httpContext.Items[SERVICESTACKREQUEST] = request; + } + + /// + /// Get the service stack request. + /// + /// The HttpContext instance. + /// The service stack request instance. + public static IRequest GetServiceStack(this HttpContext httpContext) + { + return (IRequest)httpContext.Items[SERVICESTACKREQUEST]; + } + } +} -- cgit v1.2.3 From e152a6c82fae97be6bdfae0813e883ea05c68f15 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 17 Jul 2020 15:53:10 -0600 Subject: Increase delete logging --- Emby.Server.Implementations/Library/LibraryManager.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 77d44e1313..06cfc78b3a 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -341,7 +341,7 @@ namespace Emby.Server.Implementations.Library if (item is LiveTvProgram) { _logger.LogDebug( - "Deleting item, Type: {0}, Name: {1}, Path: {2}, Id: {3}", + "Removing item, Type: {0}, Name: {1}, Path: {2}, Id: {3}", item.GetType().Name, item.Name ?? "Unknown name", item.Path ?? string.Empty, @@ -350,7 +350,7 @@ namespace Emby.Server.Implementations.Library else { _logger.LogInformation( - "Deleting item, Type: {0}, Name: {1}, Path: {2}, Id: {3}", + "Removing item, Type: {0}, Name: {1}, Path: {2}, Id: {3}", item.GetType().Name, item.Name ?? "Unknown name", item.Path ?? string.Empty, @@ -368,7 +368,12 @@ namespace Emby.Server.Implementations.Library continue; } - _logger.LogDebug("Deleting path {MetadataPath}", metadataPath); + _logger.LogDebug( + "Deleting metadata path, Type: {0}, Name: {1}, Path: {2}, Id: {3}", + item.GetType().Name, + item.Name ?? "Unknown name", + metadataPath, + item.Id); try { @@ -392,7 +397,13 @@ namespace Emby.Server.Implementations.Library { try { - _logger.LogDebug("Deleting path {path}", fileSystemInfo.FullName); + _logger.LogInformation( + "Deleting item path, Type: {0}, Name: {1}, Path: {2}, Id: {3}", + item.GetType().Name, + item.Name ?? "Unknown name", + fileSystemInfo.FullName, + item.Id); + if (fileSystemInfo.IsDirectory) { Directory.Delete(fileSystemInfo.FullName, true); -- cgit v1.2.3 From 4742ddbb711e9c7b0141b592b9b005f85e85c0df Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Fri, 17 Jul 2020 19:48:11 -0400 Subject: Update .NET Core to 3.1.6 --- Emby.Server.Implementations/Emby.Server.Implementations.csproj | 8 ++++---- Jellyfin.Api/Jellyfin.Api.csproj | 2 +- Jellyfin.Data/Jellyfin.Data.csproj | 4 ++-- .../Jellyfin.Server.Implementations.csproj | 4 ++-- Jellyfin.Server/Jellyfin.Server.csproj | 4 ++-- MediaBrowser.Common/MediaBrowser.Common.csproj | 4 ++-- MediaBrowser.Controller/MediaBrowser.Controller.csproj | 4 ++-- MediaBrowser.Model/MediaBrowser.Model.csproj | 2 +- MediaBrowser.Providers/MediaBrowser.Providers.csproj | 4 ++-- tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj | 2 +- tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj | 2 +- 11 files changed, 20 insertions(+), 20 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index f7ad59c10f..4351b9aa59 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -34,10 +34,10 @@ - - - - + + + + diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj index 93c4612b66..3693d5122a 100644 --- a/Jellyfin.Api/Jellyfin.Api.csproj +++ b/Jellyfin.Api/Jellyfin.Api.csproj @@ -14,7 +14,7 @@ - + diff --git a/Jellyfin.Data/Jellyfin.Data.csproj b/Jellyfin.Data/Jellyfin.Data.csproj index 58d1ba2f36..8ce0f3848c 100644 --- a/Jellyfin.Data/Jellyfin.Data.csproj +++ b/Jellyfin.Data/Jellyfin.Data.csproj @@ -19,8 +19,8 @@ - - + + diff --git a/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj index dcac1b34b1..21748ca192 100644 --- a/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj +++ b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj @@ -24,11 +24,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj index 6a2d252ab7..b1bd38cffb 100644 --- a/Jellyfin.Server/Jellyfin.Server.csproj +++ b/Jellyfin.Server/Jellyfin.Server.csproj @@ -41,8 +41,8 @@ - - + + diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index c9ca153c71..7380f39fda 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 73e966344f..67f17f7a52 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 83bd0c07e6..902e29b20b 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -23,7 +23,7 @@ - + diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 446e27df65..42c7cec535 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -16,8 +16,8 @@ - - + + diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index 2190208886..132050e7b2 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj b/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj index a767c00397..8309faebd1 100644 --- a/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj +++ b/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj @@ -8,7 +8,7 @@ - + -- cgit v1.2.3 From f9b0816b80793965ef044f6871a7ffd80e91d303 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sat, 18 Jul 2020 16:54:23 +0100 Subject: Changes a suggested. --- Emby.Dlna/Api/DlnaServerService.cs | 3 +- .../Services/HttpContextExtension.cs | 33 --------------------- .../Services/ServiceHandler.cs | 1 + .../Extensions/HttpContextExtensions.cs | 34 ++++++++++++++++++++++ 4 files changed, 36 insertions(+), 35 deletions(-) delete mode 100644 Emby.Server.Implementations/Services/HttpContextExtension.cs create mode 100644 MediaBrowser.Common/Extensions/HttpContextExtensions.cs (limited to 'Emby.Server.Implementations') diff --git a/Emby.Dlna/Api/DlnaServerService.cs b/Emby.Dlna/Api/DlnaServerService.cs index 7e5eb8f907..a61a8d5abb 100644 --- a/Emby.Dlna/Api/DlnaServerService.cs +++ b/Emby.Dlna/Api/DlnaServerService.cs @@ -134,8 +134,7 @@ namespace Emby.Dlna.Api _dlnaManager = dlnaManager; _resultFactory = httpResultFactory; _configurationManager = configurationManager; - object request = httpContextAccessor?.HttpContext.Items["ServiceStackRequest"] ?? throw new ArgumentNullException(nameof(httpContextAccessor)); - Request = (IRequest)request; + Request = httpContextAccessor?.HttpContext.GetServiceStack() ?? throw new ArgumentNullException(nameof(httpContextAccessor)); } private string GetHeader(string name) diff --git a/Emby.Server.Implementations/Services/HttpContextExtension.cs b/Emby.Server.Implementations/Services/HttpContextExtension.cs deleted file mode 100644 index 6d3a600ab5..0000000000 --- a/Emby.Server.Implementations/Services/HttpContextExtension.cs +++ /dev/null @@ -1,33 +0,0 @@ -using MediaBrowser.Model.Services; -using Microsoft.AspNetCore.Http; - -namespace Emby.Server.Implementations.Services -{ - /// - /// Extention to enable the service stack request to be stored in the HttpRequest object. - /// - public static class HttpContextExtension - { - private const string SERVICESTACKREQUEST = "ServiceRequestStack"; - - /// - /// Set the service stack request. - /// - /// The HttpContext instance. - /// The IRequest instance. - public static void SetServiceStackRequest(this HttpContext httpContext, IRequest request) - { - httpContext.Items[SERVICESTACKREQUEST] = request; - } - - /// - /// Get the service stack request. - /// - /// The HttpContext instance. - /// The service stack request instance. - public static IRequest GetServiceStack(this HttpContext httpContext) - { - return (IRequest)httpContext.Items[SERVICESTACKREQUEST]; - } - } -} diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index 3997a5ddb7..3d4e1ca77b 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.HttpServer; +using MediaBrowser.Common.Extensions; using MediaBrowser.Model.Services; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; diff --git a/MediaBrowser.Common/Extensions/HttpContextExtensions.cs b/MediaBrowser.Common/Extensions/HttpContextExtensions.cs new file mode 100644 index 0000000000..4bab42cc12 --- /dev/null +++ b/MediaBrowser.Common/Extensions/HttpContextExtensions.cs @@ -0,0 +1,34 @@ +using MediaBrowser.Model.Services; +using Microsoft.AspNetCore.Http; + +namespace MediaBrowser.Common.Extensions +{ + /// + /// Extention to enable the service stack request to be stored in the HttpRequest object. + /// Static class containing extension methods for . + /// + public static class HttpContextExtensions + { + private const string SERVICESTACKREQUEST = "ServiceStackRequest"; + + /// + /// Set the ServiceStack request. + /// + /// The HttpContext instance. + /// The service stack request instance. + public static void SetServiceStackRequest(this HttpContext httpContext, IRequest request) + { + httpContext.Items[SERVICESTACKREQUEST] = request; + } + + /// + /// Get the ServiceStack request. + /// + /// The HttpContext instance. + /// The service stack request instance. + public static IRequest GetServiceStack(this HttpContext httpContext) + { + return (IRequest)httpContext.Items[SERVICESTACKREQUEST]; + } + } +} -- cgit v1.2.3 From b53bf2cd16f1e64b4a35d0f510ac30239a2e2cdb Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sat, 18 Jul 2020 16:21:01 -0400 Subject: Remove obsolete network path code --- .../Library/LibraryManager.cs | 25 ---------------------- 1 file changed, 25 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 06cfc78b3a..c27b73c74e 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -3011,21 +3011,6 @@ namespace Emby.Server.Implementations.Library }); } - private static bool ValidateNetworkPath(string path) - { - // if (Environment.OSVersion.Platform == PlatformID.Win32NT) - //{ - // // We can't validate protocol-based paths, so just allow them - // if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) == -1) - // { - // return Directory.Exists(path); - // } - //} - - // Without native support for unc, we cannot validate this when running under mono - return true; - } - private const string ShortcutFileExtension = ".mblink"; public void AddMediaPath(string virtualFolderName, MediaPathInfo pathInfo) @@ -3052,11 +3037,6 @@ namespace Emby.Server.Implementations.Library throw new FileNotFoundException("The path does not exist."); } - if (!string.IsNullOrWhiteSpace(pathInfo.NetworkPath) && !ValidateNetworkPath(pathInfo.NetworkPath)) - { - throw new FileNotFoundException("The network path does not exist."); - } - var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath; var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName); @@ -3095,11 +3075,6 @@ namespace Emby.Server.Implementations.Library throw new ArgumentNullException(nameof(pathInfo)); } - if (!string.IsNullOrWhiteSpace(pathInfo.NetworkPath) && !ValidateNetworkPath(pathInfo.NetworkPath)) - { - throw new FileNotFoundException("The network path does not exist."); - } - var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath; var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName); -- cgit v1.2.3 From d719ca78b40695b02b03c912b636652545eff3e8 Mon Sep 17 00:00:00 2001 From: Ken Date: Sat, 18 Jul 2020 19:39:31 -0600 Subject: Spacing standard on Emby.Server.Implementations/IO/ManagedFileSystem.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/IO/ManagedFileSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 530c16195a..08e0cf447e 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -247,7 +247,7 @@ namespace Emby.Server.Implementations.IO result.Length = fileInfo.Length; // Issue #2354 get the size of files behind symbolic links - if(fileInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)) + if (fileInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)) { using (Stream thisFileStream = File.OpenRead(fileInfo.ToString())) { -- cgit v1.2.3 From eea142cad1d3bfe49f3fb804902b3346174c31ea Mon Sep 17 00:00:00 2001 From: Ken Date: Sat, 18 Jul 2020 19:40:28 -0600 Subject: FullName property instead of ToString in Emby.Server.Implementations/IO/ManagedFileSystem.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/IO/ManagedFileSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 08e0cf447e..ab6483bf9f 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -249,7 +249,7 @@ namespace Emby.Server.Implementations.IO // Issue #2354 get the size of files behind symbolic links if (fileInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)) { - using (Stream thisFileStream = File.OpenRead(fileInfo.ToString())) + using (Stream thisFileStream = File.OpenRead(fileInfo.FullName)) { result.Length = thisFileStream.Length; } -- cgit v1.2.3 From 7324b44c4371b2c9543bc834e665daf6e764b554 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 20 Jul 2020 11:01:37 +0200 Subject: Fix warnings --- .../Library/CoreResolutionIgnoreRule.cs | 2 +- .../Library/ExclusiveLiveStream.cs | 24 +-- .../Library/LibraryManager.cs | 214 ++++++++++----------- .../Library/LiveStreamHelper.cs | 24 +-- .../Library/MediaSourceManager.cs | 17 +- .../Library/MediaStreamSelector.cs | 2 +- .../Library/SearchEngine.cs | 18 +- MediaBrowser.Controller/Library/ILibraryManager.cs | 2 +- 8 files changed, 144 insertions(+), 159 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs index 77b2c0a694..3380e29d48 100644 --- a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs +++ b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs @@ -77,7 +77,7 @@ namespace Emby.Server.Implementations.Library if (parent != null) { // Don't resolve these into audio files - if (string.Equals(Path.GetFileNameWithoutExtension(filename), BaseItem.ThemeSongFilename) + if (string.Equals(Path.GetFileNameWithoutExtension(filename), BaseItem.ThemeSongFilename, StringComparison.Ordinal) && _libraryManager.IsAudioFile(filename)) { return true; diff --git a/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs b/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs index ab39a7223d..236453e805 100644 --- a/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs +++ b/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs @@ -11,6 +11,17 @@ namespace Emby.Server.Implementations.Library { public class ExclusiveLiveStream : ILiveStream { + private readonly Func _closeFn; + + public ExclusiveLiveStream(MediaSourceInfo mediaSource, Func closeFn) + { + MediaSource = mediaSource; + EnableStreamSharing = false; + _closeFn = closeFn; + ConsumerCount = 1; + UniqueId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); + } + public int ConsumerCount { get; set; } public string OriginalStreamId { get; set; } @@ -21,18 +32,7 @@ namespace Emby.Server.Implementations.Library public MediaSourceInfo MediaSource { get; set; } - public string UniqueId { get; private set; } - - private Func _closeFn; - - public ExclusiveLiveStream(MediaSourceInfo mediaSource, Func closeFn) - { - MediaSource = mediaSource; - EnableStreamSharing = false; - _closeFn = closeFn; - ConsumerCount = 1; - UniqueId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); - } + public string UniqueId { get; } public Task Close() { diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index c27b73c74e..10e6119e94 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -60,6 +60,8 @@ namespace Emby.Server.Implementations.Library /// public class LibraryManager : ILibraryManager { + private const string ShortcutFileExtension = ".mblink"; + private readonly ILogger _logger; private readonly ITaskManager _taskManager; private readonly IUserManager _userManager; @@ -75,63 +77,24 @@ namespace Emby.Server.Implementations.Library private readonly ConcurrentDictionary _libraryItemsCache; private readonly IImageProcessor _imageProcessor; - private NamingOptions _namingOptions; - private string[] _videoFileExtensions; - - private ILibraryMonitor LibraryMonitor => _libraryMonitorFactory.Value; - - private IProviderManager ProviderManager => _providerManagerFactory.Value; - - private IUserViewManager UserViewManager => _userviewManagerFactory.Value; - - /// - /// Gets or sets the postscan tasks. - /// - /// The postscan tasks. - private ILibraryPostScanTask[] PostscanTasks { get; set; } - - /// - /// Gets or sets the intro providers. - /// - /// The intro providers. - private IIntroProvider[] IntroProviders { get; set; } - - /// - /// Gets or sets the list of entity resolution ignore rules. - /// - /// The entity resolution ignore rules. - private IResolverIgnoreRule[] EntityResolutionIgnoreRules { get; set; } - - /// - /// Gets or sets the list of currently registered entity resolvers. - /// - /// The entity resolvers enumerable. - private IItemResolver[] EntityResolvers { get; set; } - - private IMultiItemResolver[] MultiItemResolvers { get; set; } - /// - /// Gets or sets the comparers. + /// The _root folder sync lock. /// - /// The comparers. - private IBaseItemComparer[] Comparers { get; set; } + private readonly object _rootFolderSyncLock = new object(); + private readonly object _userRootFolderSyncLock = new object(); - /// - /// Occurs when [item added]. - /// - public event EventHandler ItemAdded; + private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(24); - /// - /// Occurs when [item updated]. - /// - public event EventHandler ItemUpdated; + private NamingOptions _namingOptions; + private string[] _videoFileExtensions; /// - /// Occurs when [item removed]. + /// The _root folder. /// - public event EventHandler ItemRemoved; + private volatile AggregateFolder _rootFolder; + private volatile UserRootFolder _userRootFolder; - public bool IsScanRunning { get; private set; } + private bool _wizardCompleted; /// /// Initializes a new instance of the class. @@ -186,37 +149,19 @@ namespace Emby.Server.Implementations.Library } /// - /// Adds the parts. + /// Occurs when [item added]. /// - /// The rules. - /// The resolvers. - /// The intro providers. - /// The item comparers. - /// The post scan tasks. - public void AddParts( - IEnumerable rules, - IEnumerable resolvers, - IEnumerable introProviders, - IEnumerable itemComparers, - IEnumerable postscanTasks) - { - EntityResolutionIgnoreRules = rules.ToArray(); - EntityResolvers = resolvers.OrderBy(i => i.Priority).ToArray(); - MultiItemResolvers = EntityResolvers.OfType().ToArray(); - IntroProviders = introProviders.ToArray(); - Comparers = itemComparers.ToArray(); - PostscanTasks = postscanTasks.ToArray(); - } + public event EventHandler ItemAdded; /// - /// The _root folder. + /// Occurs when [item updated]. /// - private volatile AggregateFolder _rootFolder; + public event EventHandler ItemUpdated; /// - /// The _root folder sync lock. + /// Occurs when [item removed]. /// - private readonly object _rootFolderSyncLock = new object(); + public event EventHandler ItemRemoved; /// /// Gets the root folder. @@ -241,7 +186,68 @@ namespace Emby.Server.Implementations.Library } } - private bool _wizardCompleted; + private ILibraryMonitor LibraryMonitor => _libraryMonitorFactory.Value; + + private IProviderManager ProviderManager => _providerManagerFactory.Value; + + private IUserViewManager UserViewManager => _userviewManagerFactory.Value; + + /// + /// Gets or sets the postscan tasks. + /// + /// The postscan tasks. + private ILibraryPostScanTask[] PostscanTasks { get; set; } + + /// + /// Gets or sets the intro providers. + /// + /// The intro providers. + private IIntroProvider[] IntroProviders { get; set; } + + /// + /// Gets or sets the list of entity resolution ignore rules. + /// + /// The entity resolution ignore rules. + private IResolverIgnoreRule[] EntityResolutionIgnoreRules { get; set; } + + /// + /// Gets or sets the list of currently registered entity resolvers. + /// + /// The entity resolvers enumerable. + private IItemResolver[] EntityResolvers { get; set; } + + private IMultiItemResolver[] MultiItemResolvers { get; set; } + + /// + /// Gets or sets the comparers. + /// + /// The comparers. + private IBaseItemComparer[] Comparers { get; set; } + + public bool IsScanRunning { get; private set; } + + /// + /// Adds the parts. + /// + /// The rules. + /// The resolvers. + /// The intro providers. + /// The item comparers. + /// The post scan tasks. + public void AddParts( + IEnumerable rules, + IEnumerable resolvers, + IEnumerable introProviders, + IEnumerable itemComparers, + IEnumerable postscanTasks) + { + EntityResolutionIgnoreRules = rules.ToArray(); + EntityResolvers = resolvers.OrderBy(i => i.Priority).ToArray(); + MultiItemResolvers = EntityResolvers.OfType().ToArray(); + IntroProviders = introProviders.ToArray(); + Comparers = itemComparers.ToArray(); + PostscanTasks = postscanTasks.ToArray(); + } /// /// Records the configuration values. @@ -512,7 +518,7 @@ namespace Emby.Server.Implementations.Library // Try to normalize paths located underneath program-data in an attempt to make them more portable key = key.Substring(_configurationManager.ApplicationPaths.ProgramDataPath.Length) .TrimStart(new[] { '/', '\\' }) - .Replace("/", "\\"); + .Replace('/', '\\'); } if (forceCaseInsensitive || !_configurationManager.Configuration.EnableCaseSensitiveItemIds) @@ -775,14 +781,11 @@ namespace Emby.Server.Implementations.Library return rootFolder; } - private volatile UserRootFolder _userRootFolder; - private readonly object _syncLock = new object(); - public Folder GetUserRootFolder() { if (_userRootFolder == null) { - lock (_syncLock) + lock (_userRootFolderSyncLock) { if (_userRootFolder == null) { @@ -1332,7 +1335,7 @@ namespace Emby.Server.Implementations.Library return new QueryResult { - Items = _itemRepository.GetItemList(query).ToArray() + Items = _itemRepository.GetItemList(query) }; } @@ -1463,11 +1466,9 @@ namespace Emby.Server.Implementations.Library return _itemRepository.GetItems(query); } - var list = _itemRepository.GetItemList(query); - return new QueryResult { - Items = list + Items = _itemRepository.GetItemList(query) }; } @@ -1945,12 +1946,9 @@ namespace Emby.Server.Implementations.Library /// /// Updates the item. /// - public void UpdateItems(IEnumerable items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken) + public void UpdateItems(IReadOnlyList items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken) { - // Don't iterate multiple times - var itemsList = items.ToList(); - - foreach (var item in itemsList) + foreach (var item in items) { if (item.IsFileProtocol) { @@ -1962,11 +1960,11 @@ namespace Emby.Server.Implementations.Library UpdateImages(item, updateReason >= ItemUpdateType.ImageUpdate); } - _itemRepository.SaveItems(itemsList, cancellationToken); + _itemRepository.SaveItems(items, cancellationToken); if (ItemUpdated != null) { - foreach (var item in itemsList) + foreach (var item in items) { // With the live tv guide this just creates too much noise if (item.SourceType != SourceType.Library) @@ -2189,8 +2187,6 @@ namespace Emby.Server.Implementations.Library .FirstOrDefault(i => !string.IsNullOrEmpty(i)); } - private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(24); - public UserView GetNamedView( User user, string name, @@ -2488,14 +2484,9 @@ namespace Emby.Server.Implementations.Library var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd; - var episodeInfo = episode.IsFileProtocol ? - resolver.Resolve(episode.Path, isFolder, null, null, isAbsoluteNaming) : - new Naming.TV.EpisodeInfo(); - - if (episodeInfo == null) - { - episodeInfo = new Naming.TV.EpisodeInfo(); - } + var episodeInfo = episode.IsFileProtocol + ? resolver.Resolve(episode.Path, isFolder, null, null, isAbsoluteNaming) ?? new Naming.TV.EpisodeInfo() + : new Naming.TV.EpisodeInfo(); try { @@ -2503,11 +2494,13 @@ namespace Emby.Server.Implementations.Library if (libraryOptions.EnableEmbeddedEpisodeInfos && string.Equals(episodeInfo.Container, "mp4", StringComparison.OrdinalIgnoreCase)) { // Read from metadata - var mediaInfo = _mediaEncoder.GetMediaInfo(new MediaInfoRequest - { - MediaSource = episode.GetMediaSources(false)[0], - MediaType = DlnaProfileType.Video - }, CancellationToken.None).GetAwaiter().GetResult(); + var mediaInfo = _mediaEncoder.GetMediaInfo( + new MediaInfoRequest + { + MediaSource = episode.GetMediaSources(false)[0], + MediaType = DlnaProfileType.Video + }, + CancellationToken.None).GetAwaiter().GetResult(); if (mediaInfo.ParentIndexNumber > 0) { episodeInfo.SeasonNumber = mediaInfo.ParentIndexNumber; @@ -2665,7 +2658,7 @@ namespace Emby.Server.Implementations.Library var videos = videoListResolver.Resolve(fileSystemChildren); - var currentVideo = videos.FirstOrDefault(i => string.Equals(owner.Path, i.Files.First().Path, StringComparison.OrdinalIgnoreCase)); + var currentVideo = videos.FirstOrDefault(i => string.Equals(owner.Path, i.Files[0].Path, StringComparison.OrdinalIgnoreCase)); if (currentVideo != null) { @@ -2682,9 +2675,7 @@ namespace Emby.Server.Implementations.Library .Select(video => { // Try to retrieve it from the db. If we don't find it, use the resolved version - var dbItem = GetItemById(video.Id) as Trailer; - - if (dbItem != null) + if (GetItemById(video.Id) is Trailer dbItem) { video = dbItem; } @@ -3011,8 +3002,6 @@ namespace Emby.Server.Implementations.Library }); } - private const string ShortcutFileExtension = ".mblink"; - public void AddMediaPath(string virtualFolderName, MediaPathInfo pathInfo) { AddMediaPathInternal(virtualFolderName, pathInfo, true); @@ -3206,7 +3195,8 @@ namespace Emby.Server.Implementations.Library if (!Directory.Exists(virtualFolderPath)) { - throw new FileNotFoundException(string.Format("The media collection {0} does not exist", virtualFolderName)); + throw new FileNotFoundException( + string.Format(CultureInfo.InvariantCulture, "The media collection {0} does not exist", virtualFolderName)); } var shortcut = _fileSystem.GetFilePaths(virtualFolderPath, true) diff --git a/Emby.Server.Implementations/Library/LiveStreamHelper.cs b/Emby.Server.Implementations/Library/LiveStreamHelper.cs index 9b9f53049c..041619d1e5 100644 --- a/Emby.Server.Implementations/Library/LiveStreamHelper.cs +++ b/Emby.Server.Implementations/Library/LiveStreamHelper.cs @@ -23,9 +23,8 @@ namespace Emby.Server.Implementations.Library { private readonly IMediaEncoder _mediaEncoder; private readonly ILogger _logger; - - private IJsonSerializer _json; - private IApplicationPaths _appPaths; + private readonly IJsonSerializer _json; + private readonly IApplicationPaths _appPaths; public LiveStreamHelper(IMediaEncoder mediaEncoder, ILogger logger, IJsonSerializer json, IApplicationPaths appPaths) { @@ -72,13 +71,14 @@ namespace Emby.Server.Implementations.Library mediaSource.AnalyzeDurationMs = 3000; - mediaInfo = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest - { - MediaSource = mediaSource, - MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video, - ExtractChapters = false - - }, cancellationToken).ConfigureAwait(false); + mediaInfo = await _mediaEncoder.GetMediaInfo( + new MediaInfoRequest + { + MediaSource = mediaSource, + MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video, + ExtractChapters = false + }, + cancellationToken).ConfigureAwait(false); if (cacheFilePath != null) { @@ -126,7 +126,7 @@ namespace Emby.Server.Implementations.Library mediaSource.RunTimeTicks = null; } - var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaBrowser.Model.Entities.MediaStreamType.Audio); + var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); if (audioStream == null || audioStream.Index == -1) { @@ -137,7 +137,7 @@ namespace Emby.Server.Implementations.Library mediaSource.DefaultAudioStreamIndex = audioStream.Index; } - var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaBrowser.Model.Entities.MediaStreamType.Video); + var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); if (videoStream != null) { if (!videoStream.BitRate.HasValue) diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index ceb36b389b..4e1316abf2 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -29,6 +29,9 @@ namespace Emby.Server.Implementations.Library { public class MediaSourceManager : IMediaSourceManager, IDisposable { + // Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message. + private const char LiveStreamIdDelimeter = '_'; + private readonly IItemRepository _itemRepo; private readonly IUserManager _userManager; private readonly ILibraryManager _libraryManager; @@ -40,6 +43,11 @@ namespace Emby.Server.Implementations.Library private readonly ILocalizationManager _localizationManager; private readonly IApplicationPaths _appPaths; + private readonly Dictionary _openStreams = new Dictionary(StringComparer.OrdinalIgnoreCase); + private readonly SemaphoreSlim _liveStreamSemaphore = new SemaphoreSlim(1, 1); + + private readonly object _disposeLock = new object(); + private IMediaSourceProvider[] _providers; public MediaSourceManager( @@ -368,7 +376,6 @@ namespace Emby.Server.Implementations.Library } } - var preferredSubs = string.IsNullOrEmpty(user.SubtitleLanguagePreference) ? Array.Empty() : NormalizeLanguage(user.SubtitleLanguagePreference); @@ -451,9 +458,6 @@ namespace Emby.Server.Implementations.Library .ToList(); } - private readonly Dictionary _openStreams = new Dictionary(StringComparer.OrdinalIgnoreCase); - private readonly SemaphoreSlim _liveStreamSemaphore = new SemaphoreSlim(1, 1); - public async Task> OpenLiveStreamInternal(LiveStreamRequest request, CancellationToken cancellationToken) { await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); @@ -855,9 +859,6 @@ namespace Emby.Server.Implementations.Library } } - // Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message. - private const char LiveStreamIdDelimeter = '_'; - private Tuple GetProvider(string key) { if (string.IsNullOrEmpty(key)) @@ -881,9 +882,9 @@ namespace Emby.Server.Implementations.Library public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } - private readonly object _disposeLock = new object(); /// /// Releases unmanaged and - optionally - managed resources. /// diff --git a/Emby.Server.Implementations/Library/MediaStreamSelector.cs b/Emby.Server.Implementations/Library/MediaStreamSelector.cs index ca904c4ec9..179e0ed986 100644 --- a/Emby.Server.Implementations/Library/MediaStreamSelector.cs +++ b/Emby.Server.Implementations/Library/MediaStreamSelector.cs @@ -89,7 +89,7 @@ namespace Emby.Server.Implementations.Library } // load forced subs if we have found no suitable full subtitles - stream = stream ?? streams.FirstOrDefault(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase)); + stream ??= streams.FirstOrDefault(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase)); if (stream != null) { diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs index 3df9cc06f1..d67c9e5426 100644 --- a/Emby.Server.Implementations/Library/SearchEngine.cs +++ b/Emby.Server.Implementations/Library/SearchEngine.cs @@ -20,13 +20,11 @@ namespace Emby.Server.Implementations.Library { public class SearchEngine : ISearchEngine { - private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; private readonly IUserManager _userManager; - public SearchEngine(ILogger logger, ILibraryManager libraryManager, IUserManager userManager) + public SearchEngine(ILibraryManager libraryManager, IUserManager userManager) { - _logger = logger; _libraryManager = libraryManager; _userManager = userManager; } @@ -34,11 +32,7 @@ namespace Emby.Server.Implementations.Library public QueryResult GetSearchHints(SearchQuery query) { User user = null; - - if (query.UserId.Equals(Guid.Empty)) - { - } - else + if (query.UserId != Guid.Empty) { user = _userManager.GetUserById(query.UserId); } @@ -48,19 +42,19 @@ namespace Emby.Server.Implementations.Library if (query.StartIndex.HasValue) { - results = results.Skip(query.StartIndex.Value).ToList(); + results = results.GetRange(query.StartIndex.Value, totalRecordCount - query.StartIndex.Value); } if (query.Limit.HasValue) { - results = results.Take(query.Limit.Value).ToList(); + results = results.GetRange(0, query.Limit.Value); } return new QueryResult { TotalRecordCount = totalRecordCount, - Items = results.ToArray() + Items = results }; } @@ -85,7 +79,7 @@ namespace Emby.Server.Implementations.Library if (string.IsNullOrEmpty(searchTerm)) { - throw new ArgumentNullException("SearchTerm can't be empty.", nameof(searchTerm)); + throw new ArgumentException("SearchTerm can't be empty.", nameof(query)); } searchTerm = searchTerm.Trim().RemoveDiacritics(); diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 9d6646857e..bb56c83c23 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -199,7 +199,7 @@ namespace MediaBrowser.Controller.Library /// /// Updates the item. /// - void UpdateItems(IEnumerable items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken); + void UpdateItems(IReadOnlyList items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken); void UpdateItem(BaseItem item, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken); -- cgit v1.2.3 From bde1a38a88150b79e624fa20c6658cc783226135 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 20 Jul 2020 16:59:04 +0100 Subject: Two fixes --- Emby.Server.Implementations/Networking/NetworkManager.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 6aa1dfbc9b..54d0e29eda 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -152,6 +152,11 @@ namespace Emby.Server.Implementations.Networking return true; } + if (!IPAddress.TryParse(endpoint, out _)) + { + return false; + } + byte[] octet = IPAddress.Parse(endpoint).GetAddressBytes(); if ((octet[0] == 10) || @@ -268,6 +273,12 @@ namespace Emby.Server.Implementations.Networking string excludeAddress = "[" + addressString + "]"; var subnets = LocalSubnetsFn(); + // Include any address if LAN subnets aren't specified + if (subnets.Length == 0) + { + return true; + } + // Exclude any addresses if they appear in the LAN list in [ ] if (Array.IndexOf(subnets, excludeAddress) != -1) { -- cgit v1.2.3 From f983ea95d12f8924da4b5b0fdcc499e80d939da9 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Mon, 20 Jul 2020 17:18:50 +0100 Subject: Update Emby.Server.Implementations/Networking/NetworkManager.cs Co-authored-by: Cody Robibero --- Emby.Server.Implementations/Networking/NetworkManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 54d0e29eda..50cb44b284 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -152,12 +152,12 @@ namespace Emby.Server.Implementations.Networking return true; } - if (!IPAddress.TryParse(endpoint, out _)) + if (!IPAddress.TryParse(endpoint, out var ipAddress)) { return false; } - byte[] octet = IPAddress.Parse(endpoint).GetAddressBytes(); + byte[] octet = ipAddress.GetAddressBytes(); if ((octet[0] == 10) || (octet[0] == 172 && (octet[1] >= 16 && octet[1] <= 31)) || // RFC1918 -- cgit v1.2.3 From 2fa29527918570a1b100dec5bac78bca8e41e23e Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 21 Jul 2020 16:40:38 -0400 Subject: Skip image processing for live tv sources --- .../Library/LibraryManager.cs | 88 +++++++++++----------- 1 file changed, 46 insertions(+), 42 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index c27b73c74e..e02213710e 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1882,59 +1882,63 @@ namespace Emby.Server.Implementations.Library return; } - foreach (var img in outdated) + // Skip image processing for live tv + if (item.SourceType == SourceType.Library) { - var image = img; - if (!img.IsLocalFile) + foreach (var img in outdated) { - try + var image = img; + if (!img.IsLocalFile) { - var index = item.GetImageIndex(img); - image = ConvertImageToLocal(item, img, index).ConfigureAwait(false).GetAwaiter().GetResult(); + try + { + var index = item.GetImageIndex(img); + image = ConvertImageToLocal(item, img, index).ConfigureAwait(false).GetAwaiter().GetResult(); + } + catch (ArgumentException) + { + _logger.LogWarning("Cannot get image index for {0}", img.Path); + continue; + } + catch (InvalidOperationException) + { + _logger.LogWarning("Cannot fetch image from {0}", img.Path); + continue; + } } - catch (ArgumentException) + + try { - _logger.LogWarning("Cannot get image index for {0}", img.Path); - continue; + ImageDimensions size = _imageProcessor.GetImageDimensions(item, image); + image.Width = size.Width; + image.Height = size.Height; } - catch (InvalidOperationException) + catch (Exception ex) { - _logger.LogWarning("Cannot fetch image from {0}", img.Path); + _logger.LogError(ex, "Cannnot get image dimensions for {0}", image.Path); + image.Width = 0; + image.Height = 0; continue; } - } - - try - { - ImageDimensions size = _imageProcessor.GetImageDimensions(item, image); - image.Width = size.Width; - image.Height = size.Height; - } - catch (Exception ex) - { - _logger.LogError(ex, "Cannnot get image dimensions for {0}", image.Path); - image.Width = 0; - image.Height = 0; - continue; - } - try - { - image.BlurHash = _imageProcessor.GetImageBlurHash(image.Path); - } - catch (Exception ex) - { - _logger.LogError(ex, "Cannot compute blurhash for {0}", image.Path); - image.BlurHash = string.Empty; - } + try + { + image.BlurHash = _imageProcessor.GetImageBlurHash(image.Path); + } + catch (Exception ex) + { + _logger.LogError(ex, "Cannot compute blurhash for {0}", image.Path); + image.BlurHash = string.Empty; + } - try - { - image.DateModified = _fileSystem.GetLastWriteTimeUtc(image.Path); - } - catch (Exception ex) - { - _logger.LogError(ex, "Cannot update DateModified for {0}", image.Path); + try + { + image.DateModified = _fileSystem.GetLastWriteTimeUtc(image.Path); + } + catch (Exception ex) + { + _logger.LogError(ex, "Cannot update DateModified for {0}", image.Path); + } } } -- cgit v1.2.3 From febb6bced6d2eb0941ed30205558ff8cf045720b Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 22 Jul 2020 13:34:51 +0200 Subject: Review usage of string.Substring (part 1) Reduced allocations by replacing string.Substring with ReadOnlySpan.Slice --- Emby.Dlna/Didl/DidlBuilder.cs | 3 +- Emby.Dlna/DlnaManager.cs | 6 ++-- Emby.Drawing/ImageProcessor.cs | 14 ++++----- Emby.Naming/TV/SeasonPathParser.cs | 2 +- .../Library/LibraryManager.cs | 4 +-- .../Library/MediaSourceManager.cs | 3 +- .../LiveTv/Listings/SchedulesDirect.cs | 4 +-- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 9 ++++-- .../LiveTv/TunerHosts/M3uParser.cs | 25 ++++++++------- .../Localization/LocalizationManager.cs | 8 ++--- .../Networking/NetworkManager.cs | 2 +- .../Services/ServiceExec.cs | 8 ++++- .../Services/ServiceHandler.cs | 17 +++++----- .../Services/ServicePath.cs | 2 +- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 16 +++++----- .../MediaEncoding/EncodingHelper.cs | 23 +++++++------- MediaBrowser.MediaEncoding/Subtitles/AssParser.cs | 4 +-- .../Subtitles/ParserValues.cs | 5 ++- MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs | 11 ++++--- MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs | 4 +++ MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs | 36 +++++++++------------- .../Subtitles/SubtitleEncoder.cs | 4 ++- MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs | 9 ++++-- MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs | 2 +- 25 files changed, 124 insertions(+), 99 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 66baa9512c..70e358019a 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -364,7 +364,8 @@ namespace Emby.Dlna.Didl writer.WriteAttributeString("bitrate", totalBitrate.Value.ToString(_usCulture)); } - var mediaProfile = _profile.GetVideoMediaProfile(streamInfo.Container, + var mediaProfile = _profile.GetVideoMediaProfile( + streamInfo.Container, streamInfo.TargetAudioCodec.FirstOrDefault(), streamInfo.TargetVideoCodec.FirstOrDefault(), streamInfo.TargetAudioBitrate, diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index 5911a73ef1..1e20ff92b5 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -387,7 +387,7 @@ namespace Emby.Dlna foreach (var name in _assembly.GetManifestResourceNames()) { - if (!name.StartsWith(namespaceName)) + if (!name.StartsWith(namespaceName, StringComparison.Ordinal)) { continue; } @@ -406,7 +406,7 @@ namespace Emby.Dlna using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read)) { - await stream.CopyToAsync(fileStream); + await stream.CopyToAsync(fileStream).ConfigureAwait(false); } } } @@ -509,7 +509,7 @@ namespace Emby.Dlna return _jsonSerializer.DeserializeFromString(json); } - class InternalProfileInfo + private class InternalProfileInfo { internal DeviceProfileInfo Info { get; set; } diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 8696cb2805..f585b90ca1 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -448,21 +448,21 @@ namespace Emby.Drawing /// or /// filename. /// - public string GetCachePath(string path, string filename) + public string GetCachePath(ReadOnlySpan path, ReadOnlySpan filename) { - if (string.IsNullOrEmpty(path)) + if (path.IsEmpty) { - throw new ArgumentNullException(nameof(path)); + throw new ArgumentException("Path can't be empty.", nameof(path)); } - if (string.IsNullOrEmpty(filename)) + if (path.IsEmpty) { - throw new ArgumentNullException(nameof(filename)); + throw new ArgumentException("Filename can't be empty.", nameof(filename)); } - var prefix = filename.Substring(0, 1); + var prefix = filename.Slice(0, 1); - return Path.Combine(path, prefix, filename); + return Path.Join(path, prefix, filename); } /// diff --git a/Emby.Naming/TV/SeasonPathParser.cs b/Emby.Naming/TV/SeasonPathParser.cs index 2fa6b43531..d2e324dda5 100644 --- a/Emby.Naming/TV/SeasonPathParser.cs +++ b/Emby.Naming/TV/SeasonPathParser.cs @@ -77,7 +77,7 @@ namespace Emby.Naming.TV if (filename.StartsWith("s", StringComparison.OrdinalIgnoreCase)) { - var testFilename = filename.Substring(1); + var testFilename = filename.AsSpan().Slice(1); if (int.TryParse(testFilename, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val)) { diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index c27b73c74e..302d2a0920 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -511,8 +511,8 @@ namespace Emby.Server.Implementations.Library { // Try to normalize paths located underneath program-data in an attempt to make them more portable key = key.Substring(_configurationManager.ApplicationPaths.ProgramDataPath.Length) - .TrimStart(new[] { '/', '\\' }) - .Replace("/", "\\"); + .TrimStart('/', '\\') + .Replace('/', '\\'); } if (forceCaseInsensitive || !_configurationManager.Configuration.EnableCaseSensitiveItemIds) diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index ceb36b389b..e5df206224 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -869,7 +869,7 @@ namespace Emby.Server.Implementations.Library var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture), keys[0], StringComparison.OrdinalIgnoreCase)); - var splitIndex = key.IndexOf(LiveStreamIdDelimeter); + var splitIndex = key.IndexOf(LiveStreamIdDelimeter, StringComparison.Ordinal); var keyId = key.Substring(splitIndex + 1); return new Tuple(provider, keyId); @@ -881,6 +881,7 @@ namespace Emby.Server.Implementations.Library public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } private readonly object _disposeLock = new object(); diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 3709f8fe47..77a7069eb8 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -461,7 +461,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings private async Task> GetImageForPrograms( ListingsProviderInfo info, List programIds, - CancellationToken cancellationToken) + CancellationToken cancellationToken) { if (programIds.Count == 0) { @@ -474,7 +474,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings { var imageId = i.Substring(0, 10); - if (!imageIdString.Contains(imageId)) + if (!imageIdString.Contains(imageId, StringComparison.Ordinal)) { imageIdString += "\"" + imageId + "\","; } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 2e2488e6ec..00420bd2ad 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -195,7 +195,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun while (!sr.EndOfStream) { string line = StripXML(sr.ReadLine()); - if (line.Contains("Channel")) + if (line.Contains("Channel", StringComparison.Ordinal)) { LiveTvTunerStatus status; var index = line.IndexOf("Channel", StringComparison.OrdinalIgnoreCase); @@ -226,6 +226,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun private static string StripXML(string source) { + if (string.IsNullOrEmpty(source)) + { + return string.Empty; + } + char[] buffer = new char[source.Length]; int bufferIndex = 0; bool inside = false; @@ -270,7 +275,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun for (int i = 0; i < model.TunerCount; ++i) { - var name = string.Format("Tuner {0}", i + 1); + var name = string.Format(CultureInfo.InvariantCulture, "Tuner {0}", i + 1); var currentChannel = "none"; // @todo Get current channel and map back to Station Id var isAvailable = await manager.CheckTunerAvailability(ipInfo, i, cancellationToken).ConfigureAwait(false); var status = isAvailable ? LiveTvTunerStatus.Available : LiveTvTunerStatus.LiveTv; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index c798c0a85c..875977219a 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -158,15 +158,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts private string GetChannelNumber(string extInf, Dictionary attributes, string mediaUrl) { var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - var nameInExtInf = nameParts.Length > 1 ? nameParts[nameParts.Length - 1].Trim() : null; + var nameInExtInf = nameParts.Length > 1 ? nameParts[^1].AsSpan().Trim() : ReadOnlySpan.Empty; string numberString = null; string attributeValue; - double doubleValue; if (attributes.TryGetValue("tvg-chno", out attributeValue)) { - if (double.TryParse(attributeValue, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleValue)) + if (double.TryParse(attributeValue, NumberStyles.Any, CultureInfo.InvariantCulture, out _)) { numberString = attributeValue; } @@ -176,36 +175,36 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { if (attributes.TryGetValue("tvg-id", out attributeValue)) { - if (double.TryParse(attributeValue, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleValue)) + if (double.TryParse(attributeValue, NumberStyles.Any, CultureInfo.InvariantCulture, out _)) { numberString = attributeValue; } else if (attributes.TryGetValue("channel-id", out attributeValue)) { - if (double.TryParse(attributeValue, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleValue)) + if (double.TryParse(attributeValue, NumberStyles.Any, CultureInfo.InvariantCulture, out _)) { numberString = attributeValue; } } } - if (String.IsNullOrWhiteSpace(numberString)) + if (string.IsNullOrWhiteSpace(numberString)) { // Using this as a fallback now as this leads to Problems with channels like "5 USA" // where 5 isnt ment to be the channel number // Check for channel number with the format from SatIp // #EXTINF:0,84. VOX Schweiz // #EXTINF:0,84.0 - VOX Schweiz - if (!string.IsNullOrWhiteSpace(nameInExtInf)) + if (!nameInExtInf.IsEmpty && !nameInExtInf.IsWhiteSpace()) { var numberIndex = nameInExtInf.IndexOf(' '); if (numberIndex > 0) { - var numberPart = nameInExtInf.Substring(0, numberIndex).Trim(new[] { ' ', '.' }); + var numberPart = nameInExtInf.Slice(0, numberIndex).Trim(new[] { ' ', '.' }); - if (double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out var number)) + if (double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out _)) { - numberString = numberPart; + numberString = numberPart.ToString(); } } } @@ -231,7 +230,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { try { - numberString = Path.GetFileNameWithoutExtension(mediaUrl.Split('/').Last()); + numberString = Path.GetFileNameWithoutExtension(mediaUrl.Split('/')[^1]); if (!IsValidChannelNumber(numberString)) { @@ -258,7 +257,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return false; } - if (!double.TryParse(numberString, NumberStyles.Any, CultureInfo.InvariantCulture, out var value)) + if (!double.TryParse(numberString, NumberStyles.Any, CultureInfo.InvariantCulture, out _)) { return false; } @@ -281,7 +280,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { var numberPart = nameInExtInf.Substring(0, numberIndex).Trim(new[] { ' ', '.' }); - if (double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out var number)) + if (double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out _)) { // channel.Number = number.ToString(); nameInExtInf = nameInExtInf.Substring(numberIndex + 1).Trim(new[] { ' ', '-' }); diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index 62a23118fb..90e2766b84 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -247,7 +247,7 @@ namespace Emby.Server.Implementations.Localization } // Try splitting by : to handle "Germany: FSK 18" - var index = rating.IndexOf(':'); + var index = rating.IndexOf(':', StringComparison.Ordinal); if (index != -1) { rating = rating.Substring(index).TrimStart(':').Trim(); @@ -312,12 +312,12 @@ namespace Emby.Server.Implementations.Localization throw new ArgumentNullException(nameof(culture)); } - const string prefix = "Core"; - var key = prefix + culture; + const string Prefix = "Core"; + var key = Prefix + culture; return _dictionaries.GetOrAdd( key, - f => GetDictionary(prefix, culture, DefaultCulture + ".json").GetAwaiter().GetResult()); + f => GetDictionary(Prefix, culture, DefaultCulture + ".json").GetAwaiter().GetResult()); } private async Task> GetDictionary(string prefix, string culture, string baseFilename) diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 50cb44b284..ff95302eee 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -390,7 +390,7 @@ namespace Emby.Server.Implementations.Networking var host = uri.DnsSafeHost; _logger.LogDebug("Resolving host {0}", host); - address = GetIpAddresses(host).Result.FirstOrDefault(); + address = GetIpAddresses(host).GetAwaiter().GetResult().FirstOrDefault(); if (address != null) { diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs index cbc4b754d2..947a5cbf8d 100644 --- a/Emby.Server.Implementations/Services/ServiceExec.cs +++ b/Emby.Server.Implementations/Services/ServiceExec.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -105,7 +106,12 @@ namespace Emby.Server.Implementations.Services } var expectedMethodName = actionName.Substring(0, 1) + actionName.Substring(1).ToLowerInvariant(); - throw new NotImplementedException(string.Format("Could not find method named {1}({0}) or Any({0}) on Service {2}", requestDto.GetType().GetMethodName(), expectedMethodName, serviceType.GetMethodName())); + throw new NotImplementedException( + string.Format( + CultureInfo.InvariantCulture, + "Could not find method named {1}({0}) or Any({0}) on Service {2}", + requestDto.GetType().GetMethodName(), + expectedMethodName, serviceType.GetMethodName())); } private static async Task GetTaskResult(Task task) diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index a42f88ea09..e63a80ceea 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -44,7 +44,7 @@ namespace Emby.Server.Implementations.Services var pos = pathInfo.LastIndexOf('.'); if (pos != -1) { - var format = pathInfo.Substring(pos + 1); + var format = pathInfo.AsSpan().Slice(pos + 1); contentType = GetFormatContentType(format); if (contentType != null) { @@ -55,15 +55,18 @@ namespace Emby.Server.Implementations.Services return pathInfo; } - private static string GetFormatContentType(string format) + private static string GetFormatContentType(ReadOnlySpan format) { - // built-in formats - switch (format) + if (format.Equals("json", StringComparison.Ordinal)) { - case "json": return "application/json"; - case "xml": return "application/xml"; - default: return null; + return "application/json"; } + else if (format.Equals("xml", StringComparison.Ordinal)) + { + return "application/xml"; + } + + return null; } public async Task ProcessRequestAsync(HttpListenerHost httpHost, IRequest httpReq, HttpResponse httpRes, ILogger logger, CancellationToken cancellationToken) diff --git a/Emby.Server.Implementations/Services/ServicePath.cs b/Emby.Server.Implementations/Services/ServicePath.cs index 89538ae729..69c6844f83 100644 --- a/Emby.Server.Implementations/Services/ServicePath.cs +++ b/Emby.Server.Implementations/Services/ServicePath.cs @@ -156,7 +156,7 @@ namespace Emby.Server.Implementations.Services { var component = components[i]; - if (component.StartsWith(VariablePrefix)) + if (component.StartsWith(VariablePrefix, StringComparison.Ordinal)) { var variableName = component.Substring(1, component.Length - 2); if (variableName[variableName.Length - 1] == WildCardChar) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index fe5f980b18..6ff96ac565 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -369,7 +369,7 @@ namespace MediaBrowser.Api.Playback.Hls var playlistFilename = Path.GetFileNameWithoutExtension(playlist); - var indexString = Path.GetFileNameWithoutExtension(file.Name).Substring(playlistFilename.Length); + var indexString = Path.GetFileNameWithoutExtension(file.Name).AsSpan().Slice(playlistFilename.Length); return int.Parse(indexString, NumberStyles.Integer, CultureInfo.InvariantCulture); } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 90f62e153b..f34309c400 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -675,11 +675,11 @@ namespace MediaBrowser.Controller.Entities return System.IO.Path.Combine(basePath, "channels", ChannelId.ToString("N", CultureInfo.InvariantCulture), Id.ToString("N", CultureInfo.InvariantCulture)); } - var idString = Id.ToString("N", CultureInfo.InvariantCulture); + ReadOnlySpan idString = Id.ToString("N", CultureInfo.InvariantCulture); basePath = System.IO.Path.Combine(basePath, "library"); - return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString); + return System.IO.Path.Join(basePath, idString.Slice(0, 2), idString); } /// @@ -702,26 +702,27 @@ namespace MediaBrowser.Controller.Entities foreach (var removeChar in ConfigurationManager.Configuration.SortRemoveCharacters) { - sortable = sortable.Replace(removeChar, string.Empty); + sortable = sortable.Replace(removeChar, string.Empty, StringComparison.Ordinal); } foreach (var replaceChar in ConfigurationManager.Configuration.SortReplaceCharacters) { - sortable = sortable.Replace(replaceChar, " "); + sortable = sortable.Replace(replaceChar, " ", StringComparison.Ordinal); } foreach (var search in ConfigurationManager.Configuration.SortRemoveWords) { // Remove from beginning if a space follows - if (sortable.StartsWith(search + " ")) + if (sortable.StartsWith(search + " ", StringComparison.Ordinal)) { sortable = sortable.Remove(0, search.Length + 1); } + // Remove from middle if surrounded by spaces - sortable = sortable.Replace(" " + search + " ", " "); + sortable = sortable.Replace(" " + search + " ", " ", StringComparison.Ordinal); // Remove from end if followed by a space - if (sortable.EndsWith(" " + search)) + if (sortable.EndsWith(" " + search, StringComparison.Ordinal)) { sortable = sortable.Remove(sortable.Length - (search.Length + 1)); } @@ -751,6 +752,7 @@ namespace MediaBrowser.Controller.Entities builder.Append(chunkBuilder); } + // logger.LogDebug("ModifySortChunks Start: {0} End: {1}", name, builder.ToString()); return builder.ToString().RemoveDiacritics(); } diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index ffbda42c31..18fd53ad6f 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1588,7 +1588,7 @@ namespace MediaBrowser.Controller.MediaEncoding { outputVideoCodec ??= string.Empty; - var outputSizeParam = string.Empty; + var outputSizeParam = ReadOnlySpan.Empty; var request = state.BaseRequest; // Add resolution params, if specified @@ -1602,28 +1602,28 @@ namespace MediaBrowser.Controller.MediaEncoding var index = outputSizeParam.IndexOf("hwdownload", StringComparison.OrdinalIgnoreCase); if (index != -1) { - outputSizeParam = outputSizeParam.Substring(index); + outputSizeParam = outputSizeParam.Slice(index); } else { index = outputSizeParam.IndexOf("format", StringComparison.OrdinalIgnoreCase); if (index != -1) { - outputSizeParam = outputSizeParam.Substring(index); + outputSizeParam = outputSizeParam.Slice(index); } else { index = outputSizeParam.IndexOf("yadif", StringComparison.OrdinalIgnoreCase); if (index != -1) { - outputSizeParam = outputSizeParam.Substring(index); + outputSizeParam = outputSizeParam.Slice(index); } else { index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase); if (index != -1) { - outputSizeParam = outputSizeParam.Substring(index); + outputSizeParam = outputSizeParam.Slice(index); } } } @@ -1669,9 +1669,9 @@ namespace MediaBrowser.Controller.MediaEncoding // Setup default filtergraph utilizing FFMpeg overlay() and FFMpeg scale() (see the return of this function for index reference) // Always put the scaler before the overlay for better performance - var retStr = !string.IsNullOrEmpty(outputSizeParam) ? - " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]{3}[base];[base][sub]overlay\"" : - " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay\""; + var retStr = !outputSizeParam.IsEmpty + ? " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]{3}[base];[base][sub]overlay\"" + : " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay\""; // When the input may or may not be hardware VAAPI decodable if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) @@ -1705,7 +1705,7 @@ namespace MediaBrowser.Controller.MediaEncoding */ if (isLinux) { - retStr = !string.IsNullOrEmpty(outputSizeParam) ? + retStr = !outputSizeParam.IsEmpty ? " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]{3}[base];[base][sub]overlay_qsv\"" : " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv\""; } @@ -1717,7 +1717,7 @@ namespace MediaBrowser.Controller.MediaEncoding mapPrefix, subtitleStreamIndex, state.VideoStream.Index, - outputSizeParam, + outputSizeParam.ToString(), videoSizeParam); } @@ -2090,7 +2090,7 @@ namespace MediaBrowser.Controller.MediaEncoding // Add software deinterlace filter before scaling filter if (state.DeInterlace("h264", true) || state.DeInterlace("h265", true) || state.DeInterlace("hevc", true)) { - var deintParam = string.Empty; + string deintParam; var inputFramerate = videoStream?.RealFrameRate; // If it is already 60fps then it will create an output framerate that is much too high for roku and others to handle @@ -2159,7 +2159,6 @@ namespace MediaBrowser.Controller.MediaEncoding return output; } - /// /// Gets the number of threads. /// diff --git a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs index 0e2d70017c..43a45291cc 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs @@ -35,7 +35,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles continue; } - if (line.StartsWith("[")) + if (line[0] == '[') { break; } @@ -62,7 +62,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles return trackInfo; } - long GetTicks(string time) + private long GetTicks(ReadOnlySpan time) { return TimeSpan.TryParseExact(time, @"h\:mm\:ss\.ff", _usCulture, out var span) ? span.Ticks : 0; diff --git a/MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs b/MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs index bf8808eb8a..dca5c1e8ac 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs @@ -1,6 +1,9 @@ +#nullable enable +#pragma warning disable CS1591 + namespace MediaBrowser.MediaEncoding.Subtitles { - public class ParserValues + public static class ParserValues { public const string NewLine = "\r\n"; } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs index 728efa788d..cc35efb3f0 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1591 + using System; using System.Collections.Generic; using System.Globalization; @@ -20,6 +22,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles _logger = logger; } + /// public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken) { var trackInfo = new SubtitleTrackInfo(); @@ -55,11 +58,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles } subEvent.StartPositionTicks = GetTicks(time[0]); - var endTime = time[1]; - var idx = endTime.IndexOf(" ", StringComparison.Ordinal); + var endTime = time[1].AsSpan(); + var idx = endTime.IndexOf(' '); if (idx > 0) { - endTime = endTime.Substring(0, idx); + endTime = endTime.Slice(0, idx); } subEvent.EndPositionTicks = GetTicks(endTime); @@ -88,7 +91,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles return trackInfo; } - long GetTicks(string time) + private long GetTicks(ReadOnlySpan time) { return TimeSpan.TryParseExact(time, @"hh\:mm\:ss\.fff", _usCulture, out var span) ? span.Ticks diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs index 45b317b2ed..143c010b71 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs @@ -8,8 +8,12 @@ using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles { + /// + /// SRT subtitle writer. + /// public class SrtWriter : ISubtitleWriter { + /// public void Write(SubtitleTrackInfo info, Stream stream, CancellationToken cancellationToken) { using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)) diff --git a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs index 77033c6b44..bd330f568b 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs @@ -12,6 +12,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// public class SsaParser : ISubtitleParser { + /// public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken) { var trackInfo = new SubtitleTrackInfo(); @@ -45,7 +46,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles header.AppendLine(line); } - if (line.Trim().ToLowerInvariant() == "[events]") + if (string.Equals(line.Trim(), "[events]", StringComparison.OrdinalIgnoreCase)) { eventsStarted = true; } @@ -63,27 +64,27 @@ namespace MediaBrowser.MediaEncoding.Subtitles format = line.ToLowerInvariant().Substring(8).Split(','); for (int i = 0; i < format.Length; i++) { - if (format[i].Trim().ToLowerInvariant() == "layer") + if (string.Equals(format[i].Trim(), "layer", StringComparison.OrdinalIgnoreCase)) { indexLayer = i; } - else if (format[i].Trim().ToLowerInvariant() == "start") + else if (string.Equals(format[i].Trim(), "start", StringComparison.OrdinalIgnoreCase)) { indexStart = i; } - else if (format[i].Trim().ToLowerInvariant() == "end") + else if (string.Equals(format[i].Trim(), "end", StringComparison.OrdinalIgnoreCase)) { indexEnd = i; } - else if (format[i].Trim().ToLowerInvariant() == "text") + else if (string.Equals(format[i].Trim(), "text", StringComparison.OrdinalIgnoreCase)) { indexText = i; } - else if (format[i].Trim().ToLowerInvariant() == "effect") + else if (string.Equals(format[i].Trim(), "effect", StringComparison.OrdinalIgnoreCase)) { indexEffect = i; } - else if (format[i].Trim().ToLowerInvariant() == "style") + else if (string.Equals(format[i].Trim(), "style", StringComparison.OrdinalIgnoreCase)) { indexStyle = i; } @@ -184,12 +185,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles int.Parse(timeCode[3]) * 10).Ticks; } - public static string GetFormattedText(string text) + private static string GetFormattedText(string text) { text = text.Replace("\\n", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase); - bool italic = false; - for (int i = 0; i < 10; i++) // just look ten times... { if (text.Contains(@"{\fn")) @@ -200,7 +199,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { string fontName = text.Substring(start + 4, end - (start + 4)); string extraTags = string.Empty; - CheckAndAddSubTags(ref fontName, ref extraTags, out italic); + CheckAndAddSubTags(ref fontName, ref extraTags, out bool italic); text = text.Remove(start, end - start + 1); if (italic) { @@ -231,7 +230,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { string fontSize = text.Substring(start + 4, end - (start + 4)); string extraTags = string.Empty; - CheckAndAddSubTags(ref fontSize, ref extraTags, out italic); + CheckAndAddSubTags(ref fontSize, ref extraTags, out bool italic); if (IsInteger(fontSize)) { text = text.Remove(start, end - start + 1); @@ -265,7 +264,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { string color = text.Substring(start + 4, end - (start + 4)); string extraTags = string.Empty; - CheckAndAddSubTags(ref color, ref extraTags, out italic); + CheckAndAddSubTags(ref color, ref extraTags, out bool italic); color = color.Replace("&", string.Empty).TrimStart('H'); color = color.PadLeft(6, '0'); @@ -303,7 +302,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { string color = text.Substring(start + 5, end - (start + 5)); string extraTags = string.Empty; - CheckAndAddSubTags(ref color, ref extraTags, out italic); + CheckAndAddSubTags(ref color, ref extraTags, out bool italic); color = color.Replace("&", string.Empty).TrimStart('H'); color = color.PadLeft(6, '0'); @@ -354,14 +353,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } private static bool IsInteger(string s) - { - if (int.TryParse(s, out var i)) - { - return true; - } - - return false; - } + => int.TryParse(s, out _); private static int CountTagInText(string text, string tag) { diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index f1aa8ea5f8..969ad1b33d 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1591 + using System; using System.Collections.Concurrent; using System.Diagnostics; @@ -365,7 +367,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// System.Object. private SemaphoreSlim GetLock(string filename) { - return _semaphoreLocks.GetOrAdd(filename, key => new SemaphoreSlim(1, 1)); + return _semaphoreLocks.GetOrAdd(filename, _ => new SemaphoreSlim(1, 1)); } /// diff --git a/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs b/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs index 7d3e185784..e5c785bc57 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs @@ -6,8 +6,12 @@ using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles { + /// + /// TTML subtitle writer. + /// public class TtmlWriter : ISubtitleWriter { + /// public void Write(SubtitleTrackInfo info, Stream stream, CancellationToken cancellationToken) { // Example: https://github.com/zmalltalker/ttml2vtt/blob/master/data/sample.xml @@ -36,9 +40,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles text = Regex.Replace(text, @"\\n", "
", RegexOptions.IgnoreCase); - writer.WriteLine("

{2}

", + writer.WriteLine( + "

{2}

", trackEvent.StartPositionTicks, - (trackEvent.EndPositionTicks - trackEvent.StartPositionTicks), + trackEvent.EndPositionTicks - trackEvent.StartPositionTicks, text); } diff --git a/MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs b/MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs index de35acbba9..ad32cb7943 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs @@ -47,7 +47,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles text = Regex.Replace(text, @"\\n", " ", RegexOptions.IgnoreCase); writer.WriteLine(text); - writer.WriteLine(string.Empty); + writer.WriteLine(); } } } -- cgit v1.2.3 From a23292f363c0bae2e9d4dbbf1359234feedd3799 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 22 Jul 2020 13:52:31 +0200 Subject: Address comments --- Emby.Server.Implementations/Services/ServiceExec.cs | 3 ++- Emby.Server.Implementations/Services/ServiceHandler.cs | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs index 947a5cbf8d..7b970627e3 100644 --- a/Emby.Server.Implementations/Services/ServiceExec.cs +++ b/Emby.Server.Implementations/Services/ServiceExec.cs @@ -111,7 +111,8 @@ namespace Emby.Server.Implementations.Services CultureInfo.InvariantCulture, "Could not find method named {1}({0}) or Any({0}) on Service {2}", requestDto.GetType().GetMethodName(), - expectedMethodName, serviceType.GetMethodName())); + expectedMethodName, + serviceType.GetMethodName())); } private static async Task GetTaskResult(Task task) diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index e63a80ceea..e758cdd4d7 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Net.Mime; using System.Reflection; using System.Threading; using System.Threading.Tasks; @@ -59,11 +60,11 @@ namespace Emby.Server.Implementations.Services { if (format.Equals("json", StringComparison.Ordinal)) { - return "application/json"; + return MediaTypeNames.Application.Json; } else if (format.Equals("xml", StringComparison.Ordinal)) { - return "application/xml"; + return MediaTypeNames.Application.Xml; } return null; -- cgit v1.2.3 From 4d681e3cad3e74fa99dae4a483c7e258e345b001 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 22 Jul 2020 14:34:51 +0200 Subject: Optimize StringBuilder.Append calls --- Emby.Dlna/Eventing/EventManager.cs | 14 +++++++++----- Emby.Server.Implementations/Data/SqliteItemRepository.cs | 14 +++++++++----- Emby.Server.Implementations/Services/ServicePath.cs | 6 ++++-- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 6 +++--- 4 files changed, 25 insertions(+), 15 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Dlna/Eventing/EventManager.cs b/Emby.Dlna/Eventing/EventManager.cs index 56c90c8b3a..7d02f5e960 100644 --- a/Emby.Dlna/Eventing/EventManager.cs +++ b/Emby.Dlna/Eventing/EventManager.cs @@ -152,11 +152,15 @@ namespace Emby.Dlna.Eventing builder.Append(""); foreach (var key in stateVariables.Keys) { - builder.Append(""); - builder.Append("<" + key + ">"); - builder.Append(stateVariables[key]); - builder.Append(""); - builder.Append(""); + builder.Append("") + .Append('<') + .Append(key) + .Append('>') + .Append(stateVariables[key]) + .Append("') + .Append(""); } builder.Append(""); diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index a6390b1ef2..9f5566424c 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -1110,7 +1110,8 @@ namespace Emby.Server.Implementations.Data continue; } - str.Append(ToValueString(i) + "|"); + str.Append(ToValueString(i)) + .Append('|'); } str.Length -= 1; // Remove last | @@ -2471,7 +2472,7 @@ namespace Emby.Server.Implementations.Data var item = query.SimilarTo; var builder = new StringBuilder(); - builder.Append("("); + builder.Append('('); if (string.IsNullOrEmpty(item.OfficialRating)) { @@ -2509,7 +2510,7 @@ namespace Emby.Server.Implementations.Data if (!string.IsNullOrEmpty(query.SearchTerm)) { var builder = new StringBuilder(); - builder.Append("("); + builder.Append('('); builder.Append("((CleanName like @SearchTermStartsWith or (OriginalTitle not null and OriginalTitle like @SearchTermStartsWith)) * 10)"); @@ -5238,7 +5239,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type { if (i > 0) { - insertText.Append(","); + insertText.Append(','); } insertText.AppendFormat("(@ItemId, @AncestorId{0}, @AncestorIdText{0})", i.ToString(CultureInfo.InvariantCulture)); @@ -6331,7 +6332,10 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type foreach (var column in _mediaAttachmentSaveColumns.Skip(1)) { - insertText.Append("@" + column + index + ","); + insertText.Append('@') + .Append(column) + .Append(index) + .Append(','); } insertText.Length -= 1; diff --git a/Emby.Server.Implementations/Services/ServicePath.cs b/Emby.Server.Implementations/Services/ServicePath.cs index 89538ae729..bdda7c089e 100644 --- a/Emby.Server.Implementations/Services/ServicePath.cs +++ b/Emby.Server.Implementations/Services/ServicePath.cs @@ -488,7 +488,8 @@ namespace Emby.Server.Implementations.Services sb.Append(value); for (var j = pathIx + 1; j < requestComponents.Length; j++) { - sb.Append(PathSeperatorChar + requestComponents[j]); + sb.Append(PathSeperatorChar) + .Append(requestComponents[j]); } value = sb.ToString(); @@ -505,7 +506,8 @@ namespace Emby.Server.Implementations.Services pathIx++; while (!string.Equals(requestComponents[pathIx], stopLiteral, StringComparison.OrdinalIgnoreCase)) { - sb.Append(PathSeperatorChar + requestComponents[pathIx++]); + sb.Append(PathSeperatorChar) + .Append(requestComponents[pathIx++]); } value = sb.ToString(); diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index ffbda42c31..74ebab6a72 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -372,7 +372,7 @@ namespace MediaBrowser.Controller.MediaEncoding public int GetVideoProfileScore(string profile) { // strip spaces because they may be stripped out on the query string - profile = profile.Replace(" ", ""); + profile = profile.Replace(" ", string.Empty, CultureInfo.InvariantCulture); return Array.FindIndex(_videoProfiles, x => string.Equals(x, profile, StringComparison.OrdinalIgnoreCase)); } @@ -468,13 +468,13 @@ namespace MediaBrowser.Controller.MediaEncoding arg.Append("-hwaccel_output_format vaapi ") .Append("-vaapi_device ") .Append(encodingOptions.VaapiDevice) - .Append(" "); + .Append(' '); } else if (!isVaapiDecoder && isVaapiEncoder) { arg.Append("-vaapi_device ") .Append(encodingOptions.VaapiDevice) - .Append(" "); + .Append(' '); } } -- cgit v1.2.3 From e973757485e1c76979a17f8d2dc94f664f2f5ad0 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 22 Jul 2020 11:32:29 -0400 Subject: Simplify logic --- .../Library/LibraryManager.cs | 91 +++++++++++----------- 1 file changed, 44 insertions(+), 47 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index e02213710e..51c19fde79 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1876,69 +1876,66 @@ namespace Emby.Server.Implementations.Library } var outdated = forceUpdate ? item.ImageInfos.Where(i => i.Path != null).ToArray() : item.ImageInfos.Where(ImageNeedsRefresh).ToArray(); - if (outdated.Length == 0) + // Skip image processing if current or live tv source + if (outdated.Length == 0 || item.SourceType != SourceType.Library) { RegisterItem(item); return; } - // Skip image processing for live tv - if (item.SourceType == SourceType.Library) + foreach (var img in outdated) { - foreach (var img in outdated) + var image = img; + if (!img.IsLocalFile) { - var image = img; - if (!img.IsLocalFile) - { - try - { - var index = item.GetImageIndex(img); - image = ConvertImageToLocal(item, img, index).ConfigureAwait(false).GetAwaiter().GetResult(); - } - catch (ArgumentException) - { - _logger.LogWarning("Cannot get image index for {0}", img.Path); - continue; - } - catch (InvalidOperationException) - { - _logger.LogWarning("Cannot fetch image from {0}", img.Path); - continue; - } - } - try { - ImageDimensions size = _imageProcessor.GetImageDimensions(item, image); - image.Width = size.Width; - image.Height = size.Height; + var index = item.GetImageIndex(img); + image = ConvertImageToLocal(item, img, index).ConfigureAwait(false).GetAwaiter().GetResult(); } - catch (Exception ex) + catch (ArgumentException) { - _logger.LogError(ex, "Cannnot get image dimensions for {0}", image.Path); - image.Width = 0; - image.Height = 0; + _logger.LogWarning("Cannot get image index for {0}", img.Path); continue; } - - try - { - image.BlurHash = _imageProcessor.GetImageBlurHash(image.Path); - } - catch (Exception ex) + catch (InvalidOperationException) { - _logger.LogError(ex, "Cannot compute blurhash for {0}", image.Path); - image.BlurHash = string.Empty; + _logger.LogWarning("Cannot fetch image from {0}", img.Path); + continue; } + } - try - { - image.DateModified = _fileSystem.GetLastWriteTimeUtc(image.Path); - } - catch (Exception ex) - { - _logger.LogError(ex, "Cannot update DateModified for {0}", image.Path); - } + try + { + ImageDimensions size = _imageProcessor.GetImageDimensions(item, image); + image.Width = size.Width; + image.Height = size.Height; + } + catch (Exception ex) + { + _logger.LogError(ex, "Cannnot get image dimensions for {0}", image.Path); + image.Width = 0; + image.Height = 0; + continue; + } + + try + { + image.BlurHash = _imageProcessor.GetImageBlurHash(image.Path); + } + catch (Exception ex) + { + _logger.LogError(ex, "Cannot compute blurhash for {0}", image.Path); + image.BlurHash = string.Empty; + } + + try + { + image.DateModified = _fileSystem.GetLastWriteTimeUtc(image.Path); + } + catch (Exception ex) + { + _logger.LogError(ex, "Cannot update DateModified for {0}", image.Path); } } -- cgit v1.2.3 From 200f36959638187a220ad152d42333a787a83f8e Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Mon, 29 Jun 2020 23:00:46 -0400 Subject: Use interfaces in app host constructors --- Emby.Server.Implementations/ApplicationHost.cs | 4 ++-- Jellyfin.Server/CoreAppHost.cs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index f6077400d6..8e1bf97667 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -192,7 +192,7 @@ namespace Emby.Server.Implementations /// Gets or sets the application paths. /// /// The application paths. - protected ServerApplicationPaths ApplicationPaths { get; set; } + protected IServerApplicationPaths ApplicationPaths { get; set; } /// /// Gets or sets all concrete types. @@ -236,7 +236,7 @@ namespace Emby.Server.Implementations /// Initializes a new instance of the class. /// public ApplicationHost( - ServerApplicationPaths applicationPaths, + IServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory, IStartupOptions options, IFileSystem fileSystem, diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index 207eaa98d1..71b0fd8f35 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -9,6 +9,7 @@ using Jellyfin.Server.Implementations; using Jellyfin.Server.Implementations.Activity; using Jellyfin.Server.Implementations.Users; using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Activity; @@ -33,9 +34,9 @@ namespace Jellyfin.Server /// The to be used by the . /// The to be used by the . public CoreAppHost( - ServerApplicationPaths applicationPaths, + IServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory, - StartupOptions options, + IStartupOptions options, IFileSystem fileSystem, INetworkManager networkManager) : base( -- cgit v1.2.3 From 7adac7561ad814a08a30632fecd296e1b2142112 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Wed, 22 Jul 2020 19:52:14 -0400 Subject: Use System.Text.Json in LiveTvManager --- Emby.Server.Implementations/LiveTv/LiveTvManager.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 4c1de3bccf..1b075d86a8 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.Library; @@ -28,7 +29,6 @@ using MediaBrowser.Model.Globalization; using MediaBrowser.Model.IO; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Querying; -using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Tasks; using Microsoft.Extensions.Logging; using Episode = MediaBrowser.Controller.Entities.TV.Episode; @@ -54,7 +54,6 @@ namespace Emby.Server.Implementations.LiveTv private readonly ILibraryManager _libraryManager; private readonly ITaskManager _taskManager; private readonly ILocalizationManager _localization; - private readonly IJsonSerializer _jsonSerializer; private readonly IFileSystem _fileSystem; private readonly IChannelManager _channelManager; private readonly LiveTvDtoService _tvDtoService; @@ -73,7 +72,6 @@ namespace Emby.Server.Implementations.LiveTv ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, - IJsonSerializer jsonSerializer, IFileSystem fileSystem, IChannelManager channelManager, LiveTvDtoService liveTvDtoService) @@ -85,7 +83,6 @@ namespace Emby.Server.Implementations.LiveTv _libraryManager = libraryManager; _taskManager = taskManager; _localization = localization; - _jsonSerializer = jsonSerializer; _fileSystem = fileSystem; _dtoService = dtoService; _userDataManager = userDataManager; @@ -2234,7 +2231,7 @@ namespace Emby.Server.Implementations.LiveTv public async Task SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true) { - info = _jsonSerializer.DeserializeFromString(_jsonSerializer.SerializeToString(info)); + info = JsonSerializer.Deserialize(JsonSerializer.Serialize(info)); var provider = _tunerHosts.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase)); @@ -2278,7 +2275,7 @@ namespace Emby.Server.Implementations.LiveTv { // Hack to make the object a pure ListingsProviderInfo instead of an AddListingProvider // ServerConfiguration.SaveConfiguration crashes during xml serialization for AddListingProvider - info = _jsonSerializer.DeserializeFromString(_jsonSerializer.SerializeToString(info)); + info = JsonSerializer.Deserialize(JsonSerializer.Serialize(info)); var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase)); -- cgit v1.2.3 From 0aa349fe407465980ca3c6c5c30a01b56082222e Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Thu, 23 Jul 2020 21:42:36 -0400 Subject: Remove unused dependencies. --- Emby.Server.Implementations/HttpServer/FileWriter.cs | 2 -- Emby.Server.Implementations/HttpServer/Security/AuthService.cs | 4 ---- Emby.Server.Implementations/Images/ArtistImageProvider.cs | 10 ++-------- .../Library/Resolvers/TV/SeasonResolver.cs | 5 ----- Emby.Server.Implementations/Library/UserDataManager.cs | 4 ---- Emby.Server.Implementations/ScheduledTasks/TaskManager.cs | 7 +------ .../ScheduledTasks/Tasks/ChapterImagesTask.cs | 8 -------- 7 files changed, 3 insertions(+), 37 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/HttpServer/FileWriter.cs b/Emby.Server.Implementations/HttpServer/FileWriter.cs index 590eee1b48..6fce8de446 100644 --- a/Emby.Server.Implementations/HttpServer/FileWriter.cs +++ b/Emby.Server.Implementations/HttpServer/FileWriter.cs @@ -29,7 +29,6 @@ namespace Emby.Server.Implementations.HttpServer private readonly IStreamHelper _streamHelper; private readonly ILogger _logger; - private readonly IFileSystem _fileSystem; /// /// The _options. @@ -49,7 +48,6 @@ namespace Emby.Server.Implementations.HttpServer } _streamHelper = streamHelper; - _fileSystem = fileSystem; Path = path; _logger = logger; diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs index 318bc6a248..c9f802a513 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs @@ -13,26 +13,22 @@ using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Services; using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.HttpServer.Security { public class AuthService : IAuthService { - private readonly ILogger _logger; private readonly IAuthorizationContext _authorizationContext; private readonly ISessionManager _sessionManager; private readonly IServerConfigurationManager _config; private readonly INetworkManager _networkManager; public AuthService( - ILogger logger, IAuthorizationContext authorizationContext, IServerConfigurationManager config, ISessionManager sessionManager, INetworkManager networkManager) { - _logger = logger; _authorizationContext = authorizationContext; _config = config; _sessionManager = sessionManager; diff --git a/Emby.Server.Implementations/Images/ArtistImageProvider.cs b/Emby.Server.Implementations/Images/ArtistImageProvider.cs index 52896720ed..bf57382ed4 100644 --- a/Emby.Server.Implementations/Images/ArtistImageProvider.cs +++ b/Emby.Server.Implementations/Images/ArtistImageProvider.cs @@ -11,7 +11,6 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; @@ -25,14 +24,9 @@ namespace Emby.Server.Implementations.Images /// public class ArtistImageProvider : BaseDynamicImageProvider { - /// - /// The library manager. - /// - private readonly ILibraryManager _libraryManager; - - public ArtistImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) : base(fileSystem, providerManager, applicationPaths, imageProcessor) + public ArtistImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) + : base(fileSystem, providerManager, applicationPaths, imageProcessor) { - _libraryManager = libraryManager; } /// diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs index c8e41001ab..3332e1806c 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs @@ -1,6 +1,5 @@ using System.Globalization; using Emby.Naming.TV; -using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Globalization; @@ -13,7 +12,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV /// public class SeasonResolver : FolderResolver { - private readonly IServerConfigurationManager _config; private readonly ILibraryManager _libraryManager; private readonly ILocalizationManager _localization; private readonly ILogger _logger; @@ -21,17 +19,14 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV /// /// Initializes a new instance of the class. /// - /// The config. /// The library manager. /// The localization. /// The logger. public SeasonResolver( - IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization, ILogger logger) { - _config = config; _libraryManager = libraryManager; _localization = localization; _logger = logger; diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs index 175b3af572..f9e5e6bbcd 100644 --- a/Emby.Server.Implementations/Library/UserDataManager.cs +++ b/Emby.Server.Implementations/Library/UserDataManager.cs @@ -13,7 +13,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; -using Microsoft.Extensions.Logging; using Book = MediaBrowser.Controller.Entities.Book; namespace Emby.Server.Implementations.Library @@ -28,18 +27,15 @@ namespace Emby.Server.Implementations.Library private readonly ConcurrentDictionary _userData = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - private readonly ILogger _logger; private readonly IServerConfigurationManager _config; private readonly IUserManager _userManager; private readonly IUserDataRepository _repository; public UserDataManager( - ILogger logger, IServerConfigurationManager config, IUserManager userManager, IUserDataRepository repository) { - _logger = logger; _config = config; _userManager = userManager; _repository = repository; diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs index 3fe15ec687..81096026bd 100644 --- a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs +++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs @@ -7,7 +7,6 @@ using System.Linq; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; using MediaBrowser.Model.Events; -using MediaBrowser.Model.IO; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Tasks; using Microsoft.Extensions.Logging; @@ -37,7 +36,6 @@ namespace Emby.Server.Implementations.ScheduledTasks private readonly IJsonSerializer _jsonSerializer; private readonly IApplicationPaths _applicationPaths; private readonly ILogger _logger; - private readonly IFileSystem _fileSystem; /// /// Initializes a new instance of the class. @@ -45,17 +43,14 @@ namespace Emby.Server.Implementations.ScheduledTasks /// The application paths. /// The json serializer. /// The logger. - /// The filesystem manager. public TaskManager( IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, - ILogger logger, - IFileSystem fileSystem) + ILogger logger) { _applicationPaths = applicationPaths; _jsonSerializer = jsonSerializer; _logger = logger; - _fileSystem = fileSystem; ScheduledTasks = Array.Empty(); } diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs index 3854be7034..8439f8a99d 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs @@ -14,7 +14,6 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Tasks; -using Microsoft.Extensions.Logging; using MediaBrowser.Model.Globalization; namespace Emby.Server.Implementations.ScheduledTasks @@ -24,11 +23,6 @@ namespace Emby.Server.Implementations.ScheduledTasks /// public class ChapterImagesTask : IScheduledTask { - /// - /// The _logger. - /// - private readonly ILogger _logger; - /// /// The _library manager. /// @@ -46,7 +40,6 @@ namespace Emby.Server.Implementations.ScheduledTasks /// Initializes a new instance of the class. /// public ChapterImagesTask( - ILoggerFactory loggerFactory, ILibraryManager libraryManager, IItemRepository itemRepo, IApplicationPaths appPaths, @@ -54,7 +47,6 @@ namespace Emby.Server.Implementations.ScheduledTasks IFileSystem fileSystem, ILocalizationManager localization) { - _logger = loggerFactory.CreateLogger(); _libraryManager = libraryManager; _itemRepo = itemRepo; _appPaths = appPaths; -- cgit v1.2.3