From 82112b67880265c34f2dcca1ee7f0acf52a156df Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 22 Jan 2020 21:00:07 +0100 Subject: [PATCH 01/22] Improvements to dlna server * Improve response writer * Add analyzers * Error on warnings in release mode * Disable doc warnings --- Emby.Dlna/Api/DlnaServerService.cs | 3 + Emby.Dlna/Api/DlnaService.cs | 3 + Emby.Dlna/Common/Argument.cs | 2 + Emby.Dlna/Common/DeviceIcon.cs | 11 +- Emby.Dlna/Common/DeviceService.cs | 7 +- Emby.Dlna/Common/ServiceAction.cs | 22 +- Emby.Dlna/Common/StateVariable.cs | 18 +- Emby.Dlna/Configuration/DlnaOptions.cs | 27 +- Emby.Dlna/ConfigurationExtension.cs | 3 + .../ConnectionManager/ConnectionManager.cs | 3 + .../ConnectionManagerXmlBuilder.cs | 3 + Emby.Dlna/ConnectionManager/ControlHandler.cs | 40 +- .../ServiceActionListBuilder.cs | 3 + .../ContentDirectory/ContentDirectory.cs | 3 + .../ContentDirectoryXmlBuilder.cs | 3 + Emby.Dlna/ContentDirectory/ControlHandler.cs | 368 ++++++++---------- .../ServiceActionListBuilder.cs | 3 + Emby.Dlna/ControlRequest.cs | 3 + Emby.Dlna/ControlResponse.cs | 13 +- Emby.Dlna/Didl/DidlBuilder.cs | 4 +- Emby.Dlna/Didl/Filter.cs | 3 + Emby.Dlna/Didl/StringWriterWithEncoding.cs | 3 + Emby.Dlna/DlnaManager.cs | 3 + Emby.Dlna/Emby.Dlna.csproj | 13 + Emby.Dlna/EventSubscriptionResponse.cs | 14 +- Emby.Dlna/Eventing/EventManager.cs | 6 +- Emby.Dlna/Eventing/EventSubscription.cs | 7 +- Emby.Dlna/IConnectionManager.cs | 2 + Emby.Dlna/IContentDirectory.cs | 2 + Emby.Dlna/IEventManager.cs | 2 + Emby.Dlna/IMediaReceiverRegistrar.cs | 2 + Emby.Dlna/IUpnpService.cs | 3 + Emby.Dlna/Main/DlnaEntryPoint.cs | 3 + .../MediaReceiverRegistrar/ControlHandler.cs | 54 +-- .../MediaReceiverRegistrar.cs | 3 + .../MediaReceiverRegistrarXmlBuilder.cs | 3 + .../ServiceActionListBuilder.cs | 3 + Emby.Dlna/PlayTo/Device.cs | 33 +- Emby.Dlna/PlayTo/DeviceInfo.cs | 3 + Emby.Dlna/PlayTo/PlayToController.cs | 3 + Emby.Dlna/PlayTo/PlayToManager.cs | 11 +- Emby.Dlna/PlayTo/PlaybackProgressEventArgs.cs | 3 + Emby.Dlna/PlayTo/PlaybackStartEventArgs.cs | 3 + Emby.Dlna/PlayTo/PlaybackStoppedEventArgs.cs | 3 + Emby.Dlna/PlayTo/PlaylistItem.cs | 3 + Emby.Dlna/PlayTo/PlaylistItemFactory.cs | 3 + Emby.Dlna/PlayTo/SsdpHttpClient.cs | 15 +- Emby.Dlna/PlayTo/TRANSPORTSTATE.cs | 3 + Emby.Dlna/PlayTo/TransportCommands.cs | 3 + Emby.Dlna/PlayTo/UpnpContainer.cs | 3 + Emby.Dlna/PlayTo/uBaseObject.cs | 3 + Emby.Dlna/PlayTo/uPnpNamespaces.cs | 3 + Emby.Dlna/Profiles/DefaultProfile.cs | 3 + Emby.Dlna/Profiles/DenonAvrProfile.cs | 3 + Emby.Dlna/Profiles/DirectTvProfile.cs | 3 + Emby.Dlna/Profiles/DishHopperJoeyProfile.cs | 3 + Emby.Dlna/Profiles/Foobar2000Profile.cs | 3 + Emby.Dlna/Profiles/LgTvProfile.cs | 3 + Emby.Dlna/Profiles/LinksysDMA2100Profile.cs | 3 + Emby.Dlna/Profiles/MarantzProfile.cs | 3 + Emby.Dlna/Profiles/MediaMonkeyProfile.cs | 3 + Emby.Dlna/Profiles/PanasonicVieraProfile.cs | 3 + Emby.Dlna/Profiles/PopcornHourProfile.cs | 3 + Emby.Dlna/Profiles/SamsungSmartTvProfile.cs | 3 + Emby.Dlna/Profiles/SharpSmartTvProfile.cs | 3 + Emby.Dlna/Profiles/SonyBlurayPlayer2013.cs | 3 + Emby.Dlna/Profiles/SonyBlurayPlayer2014.cs | 3 + Emby.Dlna/Profiles/SonyBlurayPlayer2015.cs | 3 + Emby.Dlna/Profiles/SonyBlurayPlayer2016.cs | 3 + Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs | 3 + Emby.Dlna/Profiles/SonyBravia2010Profile.cs | 3 + Emby.Dlna/Profiles/SonyBravia2011Profile.cs | 3 + Emby.Dlna/Profiles/SonyBravia2012Profile.cs | 3 + Emby.Dlna/Profiles/SonyBravia2013Profile.cs | 3 + Emby.Dlna/Profiles/SonyBravia2014Profile.cs | 3 + Emby.Dlna/Profiles/SonyPs3Profile.cs | 3 + Emby.Dlna/Profiles/SonyPs4Profile.cs | 3 + Emby.Dlna/Profiles/WdtvLiveProfile.cs | 3 + Emby.Dlna/Profiles/XboxOneProfile.cs | 3 + Emby.Dlna/Server/DescriptionXmlBuilder.cs | 3 + Emby.Dlna/Service/BaseControlHandler.cs | 17 +- Emby.Dlna/Service/BaseService.cs | 3 + Emby.Dlna/Service/ControlErrorHandler.cs | 3 + Emby.Dlna/Service/ServiceXmlBuilder.cs | 3 + Emby.Dlna/Ssdp/DeviceDiscovery.cs | 15 +- Emby.Dlna/Ssdp/Extensions.cs | 3 + 86 files changed, 564 insertions(+), 327 deletions(-) diff --git a/Emby.Dlna/Api/DlnaServerService.cs b/Emby.Dlna/Api/DlnaServerService.cs index a7ff6e9cfd..4d9933a0cb 100644 --- a/Emby.Dlna/Api/DlnaServerService.cs +++ b/Emby.Dlna/Api/DlnaServerService.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.IO; using System.Text; diff --git a/Emby.Dlna/Api/DlnaService.cs b/Emby.Dlna/Api/DlnaService.cs index 7f51f477a7..f10695541d 100644 --- a/Emby.Dlna/Api/DlnaService.cs +++ b/Emby.Dlna/Api/DlnaService.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Linq; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Net; diff --git a/Emby.Dlna/Common/Argument.cs b/Emby.Dlna/Common/Argument.cs index 3e325c41ce..c6ab9959e0 100644 --- a/Emby.Dlna/Common/Argument.cs +++ b/Emby.Dlna/Common/Argument.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 namespace Emby.Dlna.Common { diff --git a/Emby.Dlna/Common/DeviceIcon.cs b/Emby.Dlna/Common/DeviceIcon.cs index 3a91b952ec..49d19992d8 100644 --- a/Emby.Dlna/Common/DeviceIcon.cs +++ b/Emby.Dlna/Common/DeviceIcon.cs @@ -1,3 +1,7 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + +using System.Globalization; namespace Emby.Dlna.Common { @@ -13,9 +17,14 @@ namespace Emby.Dlna.Common public string Depth { get; set; } + /// public override string ToString() { - return string.Format("{0}x{1}", Height, Width); + return string.Format( + CultureInfo.InvariantCulture, + "{0}x{1}", + Height, + Width); } } } diff --git a/Emby.Dlna/Common/DeviceService.cs b/Emby.Dlna/Common/DeviceService.cs index c60d652913..9947ec6b9a 100644 --- a/Emby.Dlna/Common/DeviceService.cs +++ b/Emby.Dlna/Common/DeviceService.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 namespace Emby.Dlna.Common { @@ -13,9 +15,8 @@ namespace Emby.Dlna.Common public string EventSubUrl { get; set; } + /// public override string ToString() - { - return string.Format("{0}", ServiceId); - } + => ServiceId; } } diff --git a/Emby.Dlna/Common/ServiceAction.cs b/Emby.Dlna/Common/ServiceAction.cs index 5e030d396a..15c4be8092 100644 --- a/Emby.Dlna/Common/ServiceAction.cs +++ b/Emby.Dlna/Common/ServiceAction.cs @@ -1,21 +1,25 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; namespace Emby.Dlna.Common { public class ServiceAction { - public string Name { get; set; } - - public List ArgumentList { get; set; } - - public override string ToString() - { - return Name; - } - public ServiceAction() { ArgumentList = new List(); } + + public string Name { get; set; } + + public List ArgumentList { get; set; } + + /// + public override string ToString() + { + return Name; + } } } diff --git a/Emby.Dlna/Common/StateVariable.cs b/Emby.Dlna/Common/StateVariable.cs index 4ca84bf51c..bade28e4bc 100644 --- a/Emby.Dlna/Common/StateVariable.cs +++ b/Emby.Dlna/Common/StateVariable.cs @@ -1,9 +1,17 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; namespace Emby.Dlna.Common { public class StateVariable { + public StateVariable() + { + AllowedValues = Array.Empty(); + } + public string Name { get; set; } public string DataType { get; set; } @@ -12,14 +20,8 @@ namespace Emby.Dlna.Common public string[] AllowedValues { get; set; } + /// public override string ToString() - { - return Name; - } - - public StateVariable() - { - AllowedValues = Array.Empty(); - } + => Name; } } diff --git a/Emby.Dlna/Configuration/DlnaOptions.cs b/Emby.Dlna/Configuration/DlnaOptions.cs index c7cb364a83..84587a7cee 100644 --- a/Emby.Dlna/Configuration/DlnaOptions.cs +++ b/Emby.Dlna/Configuration/DlnaOptions.cs @@ -1,17 +1,10 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 namespace Emby.Dlna.Configuration { public class DlnaOptions { - public bool EnablePlayTo { get; set; } - public bool EnableServer { get; set; } - public bool EnableDebugLog { get; set; } - public bool BlastAliveMessages { get; set; } - public bool SendOnlyMatchedHost { get; set; } - public int ClientDiscoveryIntervalSeconds { get; set; } - public int BlastAliveMessageIntervalSeconds { get; set; } - public string DefaultUserId { get; set; } - public DlnaOptions() { EnablePlayTo = true; @@ -21,5 +14,21 @@ namespace Emby.Dlna.Configuration ClientDiscoveryIntervalSeconds = 60; BlastAliveMessageIntervalSeconds = 1800; } + + public bool EnablePlayTo { get; set; } + + public bool EnableServer { get; set; } + + public bool EnableDebugLog { get; set; } + + public bool BlastAliveMessages { get; set; } + + public bool SendOnlyMatchedHost { get; set; } + + public int ClientDiscoveryIntervalSeconds { get; set; } + + public int BlastAliveMessageIntervalSeconds { get; set; } + + public string DefaultUserId { get; set; } } } diff --git a/Emby.Dlna/ConfigurationExtension.cs b/Emby.Dlna/ConfigurationExtension.cs index 82d726e018..f8125c12c3 100644 --- a/Emby.Dlna/ConfigurationExtension.cs +++ b/Emby.Dlna/ConfigurationExtension.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; using Emby.Dlna.Configuration; using MediaBrowser.Common.Configuration; diff --git a/Emby.Dlna/ConnectionManager/ConnectionManager.cs b/Emby.Dlna/ConnectionManager/ConnectionManager.cs index 934b353c28..365249c54a 100644 --- a/Emby.Dlna/ConnectionManager/ConnectionManager.cs +++ b/Emby.Dlna/ConnectionManager/ConnectionManager.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Threading.Tasks; using Emby.Dlna.Service; using MediaBrowser.Common.Net; diff --git a/Emby.Dlna/ConnectionManager/ConnectionManagerXmlBuilder.cs b/Emby.Dlna/ConnectionManager/ConnectionManagerXmlBuilder.cs index f5873455a6..c8c97c79c0 100644 --- a/Emby.Dlna/ConnectionManager/ConnectionManagerXmlBuilder.cs +++ b/Emby.Dlna/ConnectionManager/ConnectionManagerXmlBuilder.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; using Emby.Dlna.Common; using Emby.Dlna.Service; diff --git a/Emby.Dlna/ConnectionManager/ControlHandler.cs b/Emby.Dlna/ConnectionManager/ControlHandler.cs index 2e11047487..7e6c7eb228 100644 --- a/Emby.Dlna/ConnectionManager/ControlHandler.cs +++ b/Emby.Dlna/ConnectionManager/ControlHandler.cs @@ -1,5 +1,9 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Generic; +using System.Xml; using Emby.Dlna.Service; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; @@ -12,29 +16,27 @@ namespace Emby.Dlna.ConnectionManager { private readonly DeviceProfile _profile; - protected override IEnumerable> GetResult(string methodName, IDictionary methodParams) - { - if (string.Equals(methodName, "GetProtocolInfo", StringComparison.OrdinalIgnoreCase)) - { - return HandleGetProtocolInfo(); - } - - throw new ResourceNotFoundException("Unexpected control request name: " + methodName); - } - - private IEnumerable> HandleGetProtocolInfo() - { - return new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "Source", _profile.ProtocolInfo }, - { "Sink", "" } - }; - } - public ControlHandler(IServerConfigurationManager config, ILogger logger, DeviceProfile profile) : base(config, logger) { _profile = profile; } + + /// + protected override void WriteResult(string methodName, IDictionary methodParams, XmlWriter xmlWriter) + { + if (string.Equals(methodName, "GetProtocolInfo", StringComparison.OrdinalIgnoreCase)) + { + HandleGetProtocolInfo(xmlWriter); + } + + throw new ResourceNotFoundException("Unexpected control request name: " + methodName); + } + + private void HandleGetProtocolInfo(XmlWriter xmlWriter) + { + xmlWriter.WriteElementString("Source", _profile.ProtocolInfo); + xmlWriter.WriteElementString("Sink", string.Empty); + } } } diff --git a/Emby.Dlna/ConnectionManager/ServiceActionListBuilder.cs b/Emby.Dlna/ConnectionManager/ServiceActionListBuilder.cs index b7727b5580..019a0f80f4 100644 --- a/Emby.Dlna/ConnectionManager/ServiceActionListBuilder.cs +++ b/Emby.Dlna/ConnectionManager/ServiceActionListBuilder.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; using Emby.Dlna.Common; diff --git a/Emby.Dlna/ContentDirectory/ContentDirectory.cs b/Emby.Dlna/ContentDirectory/ContentDirectory.cs index a3062b18fd..523430e430 100644 --- a/Emby.Dlna/ContentDirectory/ContentDirectory.cs +++ b/Emby.Dlna/ContentDirectory/ContentDirectory.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Threading.Tasks; using Emby.Dlna.Service; diff --git a/Emby.Dlna/ContentDirectory/ContentDirectoryXmlBuilder.cs b/Emby.Dlna/ContentDirectory/ContentDirectoryXmlBuilder.cs index 15fdb36c4c..282a47c738 100644 --- a/Emby.Dlna/ContentDirectory/ContentDirectoryXmlBuilder.cs +++ b/Emby.Dlna/ContentDirectory/ContentDirectoryXmlBuilder.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; using Emby.Dlna.Common; using Emby.Dlna.Service; diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index 396649c5ea..e5acb92db5 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -1,7 +1,9 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Generic; using System.Globalization; -using System.IO; using System.Linq; using System.Text; using System.Threading; @@ -79,114 +81,129 @@ namespace Emby.Dlna.ContentDirectory _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, Logger, mediaEncoder); } - protected override IEnumerable> GetResult(string methodName, IDictionary methodParams) + /// + protected override void WriteResult(string methodName, IDictionary methodParams, XmlWriter xmlWriter) { - var deviceId = "test"; - - var user = _user; + const string DeviceId = "test"; if (string.Equals(methodName, "GetSearchCapabilities", StringComparison.OrdinalIgnoreCase)) - return HandleGetSearchCapabilities(); + { + HandleGetSearchCapabilities(xmlWriter); + return; + } if (string.Equals(methodName, "GetSortCapabilities", StringComparison.OrdinalIgnoreCase)) - return HandleGetSortCapabilities(); + { + HandleGetSortCapabilities(xmlWriter); + return; + } if (string.Equals(methodName, "GetSortExtensionCapabilities", StringComparison.OrdinalIgnoreCase)) - return HandleGetSortExtensionCapabilities(); + { + HandleGetSortExtensionCapabilities(xmlWriter); + return; + } if (string.Equals(methodName, "GetSystemUpdateID", StringComparison.OrdinalIgnoreCase)) - return HandleGetSystemUpdateID(); + { + HandleGetSystemUpdateID(xmlWriter); + return; + } if (string.Equals(methodName, "Browse", StringComparison.OrdinalIgnoreCase)) - return HandleBrowse(methodParams, user, deviceId); + { + HandleBrowse(xmlWriter, methodParams, DeviceId); + return; + } if (string.Equals(methodName, "X_GetFeatureList", StringComparison.OrdinalIgnoreCase)) - return HandleXGetFeatureList(); + { + HandleXGetFeatureList(xmlWriter); + return; + } if (string.Equals(methodName, "GetFeatureList", StringComparison.OrdinalIgnoreCase)) - return HandleGetFeatureList(); + { + HandleGetFeatureList(xmlWriter); + return; + } if (string.Equals(methodName, "X_SetBookmark", StringComparison.OrdinalIgnoreCase)) - return HandleXSetBookmark(methodParams, user); + { + HandleXSetBookmark(methodParams); + return; + } if (string.Equals(methodName, "Search", StringComparison.OrdinalIgnoreCase)) - return HandleSearch(methodParams, user, deviceId); + { + HandleSearch(xmlWriter, methodParams, DeviceId); + return; + } if (string.Equals(methodName, "X_BrowseByLetter", StringComparison.OrdinalIgnoreCase)) - return HandleX_BrowseByLetter(methodParams, user, deviceId); + { + HandleXBrowseByLetter(xmlWriter, methodParams, DeviceId); + return; + } throw new ResourceNotFoundException("Unexpected control request name: " + methodName); } - private IEnumerable> HandleXSetBookmark(IDictionary sparams, User user) + private void HandleXSetBookmark(IDictionary sparams) { var id = sparams["ObjectID"]; - var serverItem = GetItemFromObjectId(id, user); + var serverItem = GetItemFromObjectId(id, _user); var item = serverItem.Item; var newbookmark = int.Parse(sparams["PosSecond"], _usCulture); - var userdata = _userDataManager.GetUserData(user, item); + var userdata = _userDataManager.GetUserData(_user, item); userdata.PlaybackPositionTicks = TimeSpan.FromSeconds(newbookmark).Ticks; - _userDataManager.SaveUserData(user, item, userdata, UserDataSaveReason.TogglePlayed, + _userDataManager.SaveUserData(_user, item, userdata, UserDataSaveReason.TogglePlayed, CancellationToken.None); - - return new Dictionary(StringComparer.OrdinalIgnoreCase); } - private IEnumerable> HandleGetSearchCapabilities() + private void HandleGetSearchCapabilities(XmlWriter xmlWriter) { - return new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "SearchCaps", "res@resolution,res@size,res@duration,dc:title,dc:creator,upnp:actor,upnp:artist,upnp:genre,upnp:album,dc:date,upnp:class,@id,@refID,@protocolInfo,upnp:author,dc:description,pv:avKeywords" } - }; + xmlWriter.WriteElementString( + "SearchCaps", + "res@resolution,res@size,res@duration,dc:title,dc:creator,upnp:actor,upnp:artist,upnp:genre,upnp:album,dc:date,upnp:class,@id,@refID,@protocolInfo,upnp:author,dc:description,pv:avKeywords"); } - private IEnumerable> HandleGetSortCapabilities() + private void HandleGetSortCapabilities(XmlWriter xmlWriter) { - return new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "SortCaps", "res@duration,res@size,res@bitrate,dc:date,dc:title,dc:size,upnp:album,upnp:artist,upnp:albumArtist,upnp:episodeNumber,upnp:genre,upnp:originalTrackNumber,upnp:rating" } - }; + xmlWriter.WriteElementString( + "SortCaps", + "res@duration,res@size,res@bitrate,dc:date,dc:title,dc:size,upnp:album,upnp:artist,upnp:albumArtist,upnp:episodeNumber,upnp:genre,upnp:originalTrackNumber,upnp:rating"); } - private IEnumerable> HandleGetSortExtensionCapabilities() + private void HandleGetSortExtensionCapabilities(XmlWriter xmlWriter) { - return new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "SortExtensionCaps", "res@duration,res@size,res@bitrate,dc:date,dc:title,dc:size,upnp:album,upnp:artist,upnp:albumArtist,upnp:episodeNumber,upnp:genre,upnp:originalTrackNumber,upnp:rating" } - }; + xmlWriter.WriteElementString( + "SortExtensionCaps", + "res@duration,res@size,res@bitrate,dc:date,dc:title,dc:size,upnp:album,upnp:artist,upnp:albumArtist,upnp:episodeNumber,upnp:genre,upnp:originalTrackNumber,upnp:rating"); } - private IEnumerable> HandleGetSystemUpdateID() + private void HandleGetSystemUpdateID(XmlWriter xmlWriter) { - var headers = new Dictionary(StringComparer.OrdinalIgnoreCase); - headers.Add("Id", _systemUpdateId.ToString(_usCulture)); - return headers; + xmlWriter.WriteElementString("Id", _systemUpdateId.ToString(CultureInfo.InvariantCulture)); } - private IEnumerable> HandleGetFeatureList() + private void HandleGetFeatureList(XmlWriter xmlWriter) { - return new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "FeatureList", GetFeatureListXml() } - }; + xmlWriter.WriteElementString("FeatureList", WriteFeatureListXml()); } - private IEnumerable> HandleXGetFeatureList() - { - return new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "FeatureList", GetFeatureListXml() } - }; - } + private void HandleXGetFeatureList(XmlWriter xmlWriter) + => HandleGetFeatureList(xmlWriter); - private string GetFeatureListXml() + private string WriteFeatureListXml() { + // TODO: clean this up var builder = new StringBuilder(); builder.Append(""); @@ -213,7 +230,7 @@ namespace Emby.Dlna.ContentDirectory return defaultValue; } - private IEnumerable> HandleBrowse(IDictionary sparams, User user, string deviceId) + private void HandleBrowse(XmlWriter xmlWriter, IDictionary sparams, string deviceId) { var id = sparams["ObjectID"]; var flag = sparams["BrowseFlag"]; @@ -237,101 +254,81 @@ namespace Emby.Dlna.ContentDirectory start = startVal; } - var settings = new XmlWriterSettings - { - Encoding = Encoding.UTF8, - CloseOutput = false, - OmitXmlDeclaration = true, - ConformanceLevel = ConformanceLevel.Fragment - }; + xmlWriter.WriteStartElement("Result"); - StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8); + xmlWriter.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); + + xmlWriter.WriteAttributeString("xmlns", "dc", null, NS_DC); + xmlWriter.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); + xmlWriter.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); + //didl.SetAttribute("xmlns:sec", NS_SEC); + + DidlBuilder.WriteXmlRootAttributes(_profile, xmlWriter); + + var serverItem = GetItemFromObjectId(id, _user); + var item = serverItem.Item; int totalCount; - - var dlnaOptions = _config.GetDlnaConfiguration(); - - using (var writer = XmlWriter.Create(builder, settings)) + if (string.Equals(flag, "BrowseMetadata")) { - //writer.WriteStartDocument(); + totalCount = 1; - writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); - - writer.WriteAttributeString("xmlns", "dc", null, NS_DC); - writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); - writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); - //didl.SetAttribute("xmlns:sec", NS_SEC); - - DidlBuilder.WriteXmlRootAttributes(_profile, writer); - - var serverItem = GetItemFromObjectId(id, user); - var item = serverItem.Item; - - if (string.Equals(flag, "BrowseMetadata")) + if (item.IsDisplayedAsFolder || serverItem.StubType.HasValue) { - totalCount = 1; + var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount); - if (item.IsDisplayedAsFolder || serverItem.StubType.HasValue) - { - var childrenResult = GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount); - - _didlBuilder.WriteFolderElement(writer, item, serverItem.StubType, null, childrenResult.TotalRecordCount, filter, id); - } - else - { - _didlBuilder.WriteItemElement(dlnaOptions, writer, item, user, null, null, deviceId, filter); - } - - provided++; + _didlBuilder.WriteFolderElement(xmlWriter, item, serverItem.StubType, null, childrenResult.TotalRecordCount, filter, id); } else { - var childrenResult = GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount); - totalCount = childrenResult.TotalRecordCount; - - provided = childrenResult.Items.Count; - - foreach (var i in childrenResult.Items) - { - var childItem = i.Item; - var displayStubType = i.StubType; - - if (childItem.IsDisplayedAsFolder || displayStubType.HasValue) - { - var childCount = (GetUserItems(childItem, displayStubType, user, sortCriteria, null, 0)) - .TotalRecordCount; - - _didlBuilder.WriteFolderElement(writer, childItem, displayStubType, item, childCount, filter); - } - else - { - _didlBuilder.WriteItemElement(dlnaOptions, writer, childItem, user, item, serverItem.StubType, deviceId, filter); - } - } + var dlnaOptions = _config.GetDlnaConfiguration(); + _didlBuilder.WriteItemElement(dlnaOptions, xmlWriter, item, _user, null, null, deviceId, filter); } - writer.WriteFullEndElement(); - //writer.WriteEndDocument(); + provided++; + } + else + { + var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount); + totalCount = childrenResult.TotalRecordCount; + + provided = childrenResult.Items.Count; + + var dlnaOptions = _config.GetDlnaConfiguration(); + foreach (var i in childrenResult.Items) + { + var childItem = i.Item; + var displayStubType = i.StubType; + + if (childItem.IsDisplayedAsFolder || displayStubType.HasValue) + { + var childCount = GetUserItems(childItem, displayStubType, _user, sortCriteria, null, 0) + .TotalRecordCount; + + _didlBuilder.WriteFolderElement(xmlWriter, childItem, displayStubType, item, childCount, filter); + } + else + { + _didlBuilder.WriteItemElement(dlnaOptions, xmlWriter, childItem, _user, item, serverItem.StubType, deviceId, filter); + } + } } - var resXML = builder.ToString(); + xmlWriter.WriteFullEndElement(); + xmlWriter.WriteFullEndElement(); - return new[] - { - new KeyValuePair("Result", resXML), - new KeyValuePair("NumberReturned", provided.ToString(_usCulture)), - new KeyValuePair("TotalMatches", totalCount.ToString(_usCulture)), - new KeyValuePair("UpdateID", _systemUpdateId.ToString(_usCulture)) - }; + xmlWriter.WriteElementString("NumberReturned", provided.ToString(_usCulture)); + xmlWriter.WriteElementString("TotalMatches", totalCount.ToString(_usCulture)); + xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(_usCulture)); } - private IEnumerable> HandleX_BrowseByLetter(IDictionary sparams, User user, string deviceId) + private void HandleXBrowseByLetter(XmlWriter xmlWriter, IDictionary sparams, string deviceId) { // TODO: Implement this method - return HandleSearch(sparams, user, deviceId); + HandleSearch(xmlWriter, sparams, deviceId); } - private IEnumerable> HandleSearch(IDictionary sparams, User user, string deviceId) + private void HandleSearch(XmlWriter xmlWriter, IDictionary sparams, string deviceId) { var searchCriteria = new SearchCriteria(GetValueOrDefault(sparams, "SearchCriteria", "")); var sortCriteria = new SortCriteria(GetValueOrDefault(sparams, "SortCriteria", "")); @@ -354,99 +351,74 @@ namespace Emby.Dlna.ContentDirectory start = startVal; } - var settings = new XmlWriterSettings + xmlWriter.WriteStartElement("Result"); + + xmlWriter.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); + + xmlWriter.WriteAttributeString("xmlns", "dc", null, NS_DC); + xmlWriter.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); + xmlWriter.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); + //didl.SetAttribute("xmlns:sec", NS_SEC); + + DidlBuilder.WriteXmlRootAttributes(_profile, xmlWriter); + + var serverItem = GetItemFromObjectId(sparams["ContainerID"], _user); + + var item = serverItem.Item; + + var childrenResult = GetChildrenSorted(item, _user, searchCriteria, sortCriteria, start, requestedCount); + + var dlnaOptions = _config.GetDlnaConfiguration(); + + foreach (var i in childrenResult.Items) { - Encoding = Encoding.UTF8, - CloseOutput = false, - OmitXmlDeclaration = true, - ConformanceLevel = ConformanceLevel.Fragment - }; - - StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8); - int totalCount = 0; - int provided = 0; - - using (var writer = XmlWriter.Create(builder, settings)) - { - //writer.WriteStartDocument(); - - writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); - - writer.WriteAttributeString("xmlns", "dc", null, NS_DC); - writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); - writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); - //didl.SetAttribute("xmlns:sec", NS_SEC); - - DidlBuilder.WriteXmlRootAttributes(_profile, writer); - - var serverItem = GetItemFromObjectId(sparams["ContainerID"], user); - - var item = serverItem.Item; - - var childrenResult = (GetChildrenSorted(item, user, searchCriteria, sortCriteria, start, requestedCount)); - - totalCount = childrenResult.TotalRecordCount; - - provided = childrenResult.Items.Count; - - var dlnaOptions = _config.GetDlnaConfiguration(); - - foreach (var i in childrenResult.Items) + if (i.IsDisplayedAsFolder) { - if (i.IsDisplayedAsFolder) - { - var childCount = (GetChildrenSorted(i, user, searchCriteria, sortCriteria, null, 0)) - .TotalRecordCount; + var childCount = GetChildrenSorted(i, _user, searchCriteria, sortCriteria, null, 0) + .TotalRecordCount; - _didlBuilder.WriteFolderElement(writer, i, null, item, childCount, filter); - } - else - { - _didlBuilder.WriteItemElement(dlnaOptions, writer, i, user, item, serverItem.StubType, deviceId, filter); - } + _didlBuilder.WriteFolderElement(xmlWriter, i, null, item, childCount, filter); + } + else + { + _didlBuilder.WriteItemElement(dlnaOptions, xmlWriter, i, _user, item, serverItem.StubType, deviceId, filter); } - - writer.WriteFullEndElement(); - //writer.WriteEndDocument(); } - var resXML = builder.ToString(); + xmlWriter.WriteFullEndElement(); + xmlWriter.WriteFullEndElement(); - return new List> - { - new KeyValuePair("Result", resXML), - new KeyValuePair("NumberReturned", provided.ToString(_usCulture)), - new KeyValuePair("TotalMatches", totalCount.ToString(_usCulture)), - new KeyValuePair("UpdateID", _systemUpdateId.ToString(_usCulture)) - }; + xmlWriter.WriteElementString("NumberReturned", childrenResult.Items.Count.ToString(_usCulture)); + xmlWriter.WriteElementString("TotalMatches", childrenResult.TotalRecordCount.ToString(_usCulture)); + xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(_usCulture)); } private QueryResult GetChildrenSorted(BaseItem item, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit) { var folder = (Folder)item; - var sortOrders = new List<(string, SortOrder)>(); - if (!folder.IsPreSorted) + var sortOrders = folder.IsPreSorted switch { - sortOrders.Add((ItemSortBy.SortName, sort.SortOrder)); - } + true => Array.Empty<(string, SortOrder)>(), + false => new[] { (ItemSortBy.SortName, sort.SortOrder) } + }; - var mediaTypes = new List(); + string[] mediaTypes = Array.Empty(); bool? isFolder = null; if (search.SearchType == SearchType.Audio) { - mediaTypes.Add(MediaType.Audio); + mediaTypes = new[] { MediaType.Audio }; isFolder = false; } else if (search.SearchType == SearchType.Video) { - mediaTypes.Add(MediaType.Video); + mediaTypes = new[] { MediaType.Video }; isFolder = false; } else if (search.SearchType == SearchType.Image) { - mediaTypes.Add(MediaType.Photo); + mediaTypes = new[] { MediaType.Photo }; isFolder = false; } else if (search.SearchType == SearchType.Playlist) @@ -470,7 +442,7 @@ namespace Emby.Dlna.ContentDirectory IsMissing = false, ExcludeItemTypes = new[] { typeof(Book).Name }, IsFolder = isFolder, - MediaTypes = mediaTypes.ToArray(), + MediaTypes = mediaTypes, DtoOptions = GetDtoOptions() }); } @@ -1304,11 +1276,11 @@ namespace Emby.Dlna.ContentDirectory StubType? stubType = null; // After using PlayTo, MediaMonkey sends a request to the server trying to get item info - const string paramsSrch = "Params="; - var paramsIndex = id.IndexOf(paramsSrch, StringComparison.OrdinalIgnoreCase); + const string ParamsSrch = "Params="; + var paramsIndex = id.IndexOf(ParamsSrch, StringComparison.OrdinalIgnoreCase); if (paramsIndex != -1) { - id = id.Substring(paramsIndex + paramsSrch.Length); + id = id.Substring(paramsIndex + ParamsSrch.Length); var parts = id.Split(';'); id = parts[23]; diff --git a/Emby.Dlna/ContentDirectory/ServiceActionListBuilder.cs b/Emby.Dlna/ContentDirectory/ServiceActionListBuilder.cs index e999314fa6..a385a74cfb 100644 --- a/Emby.Dlna/ContentDirectory/ServiceActionListBuilder.cs +++ b/Emby.Dlna/ContentDirectory/ServiceActionListBuilder.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; using Emby.Dlna.Common; diff --git a/Emby.Dlna/ControlRequest.cs b/Emby.Dlna/ControlRequest.cs index 8c227159c4..97ad41c834 100644 --- a/Emby.Dlna/ControlRequest.cs +++ b/Emby.Dlna/ControlRequest.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.IO; using Microsoft.AspNetCore.Http; diff --git a/Emby.Dlna/ControlResponse.cs b/Emby.Dlna/ControlResponse.cs index d2b79fc585..0215a5e387 100644 --- a/Emby.Dlna/ControlResponse.cs +++ b/Emby.Dlna/ControlResponse.cs @@ -1,18 +1,21 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; namespace Emby.Dlna { public class ControlResponse { + public ControlResponse() + { + Headers = new Dictionary(); + } + public IDictionary Headers { get; set; } public string Xml { get; set; } public bool IsSuccessful { get; set; } - - public ControlResponse() - { - Headers = new Dictionary(); - } } } diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 85ef9d4829..f2128d9c6d 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Globalization; using System.IO; @@ -18,7 +21,6 @@ using MediaBrowser.Controller.Playlists; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Net; using Microsoft.Extensions.Logging; diff --git a/Emby.Dlna/Didl/Filter.cs b/Emby.Dlna/Didl/Filter.cs index a0e67870e9..88cf7cb5a6 100644 --- a/Emby.Dlna/Didl/Filter.cs +++ b/Emby.Dlna/Didl/Filter.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using MediaBrowser.Model.Extensions; diff --git a/Emby.Dlna/Didl/StringWriterWithEncoding.cs b/Emby.Dlna/Didl/StringWriterWithEncoding.cs index c3c4bd393b..edc2588995 100644 --- a/Emby.Dlna/Didl/StringWriterWithEncoding.cs +++ b/Emby.Dlna/Didl/StringWriterWithEncoding.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.IO; using System.Text; diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index d5d788021d..14602485af 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Generic; using System.Globalization; diff --git a/Emby.Dlna/Emby.Dlna.csproj b/Emby.Dlna/Emby.Dlna.csproj index 8d6fabdb44..0cabe43d51 100644 --- a/Emby.Dlna/Emby.Dlna.csproj +++ b/Emby.Dlna/Emby.Dlna.csproj @@ -15,6 +15,19 @@ netstandard2.1 false true + true + + + + + + + + + + + + ../jellyfin.ruleset diff --git a/Emby.Dlna/EventSubscriptionResponse.cs b/Emby.Dlna/EventSubscriptionResponse.cs index 6dc1aacf4f..f90d273c4b 100644 --- a/Emby.Dlna/EventSubscriptionResponse.cs +++ b/Emby.Dlna/EventSubscriptionResponse.cs @@ -1,17 +1,21 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; namespace Emby.Dlna { public class EventSubscriptionResponse { - public string Content { get; set; } - public string ContentType { get; set; } - - public Dictionary Headers { get; set; } - public EventSubscriptionResponse() { Headers = new Dictionary(); } + + public string Content { get; set; } + + public string ContentType { get; set; } + + public Dictionary Headers { get; set; } } } diff --git a/Emby.Dlna/Eventing/EventManager.cs b/Emby.Dlna/Eventing/EventManager.cs index b76a0066d1..7881898803 100644 --- a/Emby.Dlna/Eventing/EventManager.cs +++ b/Emby.Dlna/Eventing/EventManager.cs @@ -1,8 +1,12 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Net.Http; using System.Text; using System.Threading.Tasks; using MediaBrowser.Common.Extensions; @@ -164,7 +168,7 @@ namespace Emby.Dlna.Eventing try { - using (await _httpClient.SendAsync(options, "NOTIFY").ConfigureAwait(false)) + using (await _httpClient.SendAsync(options, new HttpMethod("NOTIFY")).ConfigureAwait(false)) { } diff --git a/Emby.Dlna/Eventing/EventSubscription.cs b/Emby.Dlna/Eventing/EventSubscription.cs index eb8781e0cd..108ab48303 100644 --- a/Emby.Dlna/Eventing/EventSubscription.cs +++ b/Emby.Dlna/Eventing/EventSubscription.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; namespace Emby.Dlna.Eventing @@ -13,6 +16,8 @@ namespace Emby.Dlna.Eventing public long TriggerCount { get; set; } + public bool IsExpired => SubscriptionTime.AddSeconds(TimeoutSeconds) >= DateTime.UtcNow; + public void IncrementTriggerCount() { if (TriggerCount == long.MaxValue) @@ -22,7 +27,5 @@ namespace Emby.Dlna.Eventing TriggerCount++; } - - public bool IsExpired => SubscriptionTime.AddSeconds(TimeoutSeconds) >= DateTime.UtcNow; } } diff --git a/Emby.Dlna/IConnectionManager.cs b/Emby.Dlna/IConnectionManager.cs index 855c4454d9..01fb869f57 100644 --- a/Emby.Dlna/IConnectionManager.cs +++ b/Emby.Dlna/IConnectionManager.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 namespace Emby.Dlna { diff --git a/Emby.Dlna/IContentDirectory.cs b/Emby.Dlna/IContentDirectory.cs index b54a17c009..a28ad2b9c8 100644 --- a/Emby.Dlna/IContentDirectory.cs +++ b/Emby.Dlna/IContentDirectory.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 namespace Emby.Dlna { diff --git a/Emby.Dlna/IEventManager.cs b/Emby.Dlna/IEventManager.cs index 4f67a1b9b6..d0960aa16c 100644 --- a/Emby.Dlna/IEventManager.cs +++ b/Emby.Dlna/IEventManager.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 namespace Emby.Dlna { diff --git a/Emby.Dlna/IMediaReceiverRegistrar.cs b/Emby.Dlna/IMediaReceiverRegistrar.cs index 5dde01f58b..d2aaa8f553 100644 --- a/Emby.Dlna/IMediaReceiverRegistrar.cs +++ b/Emby.Dlna/IMediaReceiverRegistrar.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 namespace Emby.Dlna { diff --git a/Emby.Dlna/IUpnpService.cs b/Emby.Dlna/IUpnpService.cs index 0f3d327ed2..289e2df78c 100644 --- a/Emby.Dlna/IUpnpService.cs +++ b/Emby.Dlna/IUpnpService.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Threading.Tasks; namespace Emby.Dlna diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 77bde0ca24..1ee4151e4b 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Net.Sockets; using System.Globalization; diff --git a/Emby.Dlna/MediaReceiverRegistrar/ControlHandler.cs b/Emby.Dlna/MediaReceiverRegistrar/ControlHandler.cs index 7381e52582..815aac5c7c 100644 --- a/Emby.Dlna/MediaReceiverRegistrar/ControlHandler.cs +++ b/Emby.Dlna/MediaReceiverRegistrar/ControlHandler.cs @@ -1,5 +1,9 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Generic; +using System.Xml; using Emby.Dlna.Service; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; @@ -9,35 +13,33 @@ namespace Emby.Dlna.MediaReceiverRegistrar { public class ControlHandler : BaseControlHandler { - protected override IEnumerable> GetResult(string methodName, IDictionary methodParams) - { - if (string.Equals(methodName, "IsAuthorized", StringComparison.OrdinalIgnoreCase)) - return HandleIsAuthorized(); - if (string.Equals(methodName, "IsValidated", StringComparison.OrdinalIgnoreCase)) - return HandleIsValidated(); - - throw new ResourceNotFoundException("Unexpected control request name: " + methodName); - } - - private static IEnumerable> HandleIsAuthorized() - { - return new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "Result", "1" } - }; - } - - private static IEnumerable> HandleIsValidated() - { - return new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "Result", "1" } - }; - } - public ControlHandler(IServerConfigurationManager config, ILogger logger) : base(config, logger) { } + + /// + protected override void WriteResult(string methodName, IDictionary methodParams, XmlWriter xmlWriter) + { + if (string.Equals(methodName, "IsAuthorized", StringComparison.OrdinalIgnoreCase)) + { + HandleIsAuthorized(xmlWriter); + return; + } + + if (string.Equals(methodName, "IsValidated", StringComparison.OrdinalIgnoreCase)) + { + HandleIsValidated(xmlWriter); + return; + } + + throw new ResourceNotFoundException("Unexpected control request name: " + methodName); + } + + private static void HandleIsAuthorized(XmlWriter xmlWriter) + => xmlWriter.WriteElementString("Result", "1"); + + private static void HandleIsValidated(XmlWriter xmlWriter) + => xmlWriter.WriteElementString("Result", "1"); } } diff --git a/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrar.cs b/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrar.cs index 5eab6aee0c..e2d48bc01f 100644 --- a/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrar.cs +++ b/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrar.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Threading.Tasks; using Emby.Dlna.Service; using MediaBrowser.Common.Net; diff --git a/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarXmlBuilder.cs b/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarXmlBuilder.cs index 6413411851..465b08f58e 100644 --- a/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarXmlBuilder.cs +++ b/Emby.Dlna/MediaReceiverRegistrar/MediaReceiverRegistrarXmlBuilder.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; using Emby.Dlna.Common; using Emby.Dlna.Service; diff --git a/Emby.Dlna/MediaReceiverRegistrar/ServiceActionListBuilder.cs b/Emby.Dlna/MediaReceiverRegistrar/ServiceActionListBuilder.cs index 86429f6051..3e8b2dbd88 100644 --- a/Emby.Dlna/MediaReceiverRegistrar/ServiceActionListBuilder.cs +++ b/Emby.Dlna/MediaReceiverRegistrar/ServiceActionListBuilder.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; using Emby.Dlna.Common; diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index 0c5ddee654..61db264a2f 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Generic; using System.Globalization; @@ -221,7 +224,7 @@ namespace Emby.Dlna.PlayTo _logger.LogDebug("Setting mute"); var value = mute ? 1 : 0; - await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value)) + await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value)) .ConfigureAwait(false); IsMuted = mute; @@ -251,7 +254,7 @@ namespace Emby.Dlna.PlayTo // Remote control will perform better Volume = value; - await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value)) + await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType, value)) .ConfigureAwait(false); } @@ -270,7 +273,7 @@ namespace Emby.Dlna.PlayTo throw new InvalidOperationException("Unable to find service"); } - await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, string.Format("{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME")) + await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, string.Format("{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME")) .ConfigureAwait(false); RestartTimer(true); @@ -302,7 +305,7 @@ namespace Emby.Dlna.PlayTo } var post = avCommands.BuildPost(command, service.ServiceType, url, dictionary); - await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, post, header: header) + await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, post, header: header) .ConfigureAwait(false); await Task.Delay(50).ConfigureAwait(false); @@ -344,7 +347,7 @@ namespace Emby.Dlna.PlayTo throw new InvalidOperationException("Unable to find service"); } - return new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)); + return new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)); } public async Task SetPlay(CancellationToken cancellationToken) @@ -368,7 +371,7 @@ namespace Emby.Dlna.PlayTo var service = GetAvTransportService(); - await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) + await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) .ConfigureAwait(false); RestartTimer(true); @@ -386,7 +389,7 @@ namespace Emby.Dlna.PlayTo var service = GetAvTransportService(); - await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) + await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) .ConfigureAwait(false); TransportState = TRANSPORTSTATE.PAUSED; @@ -513,7 +516,7 @@ namespace Emby.Dlna.PlayTo return; } - var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), true) + var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), true) .ConfigureAwait(false); if (result == null || result.Document == null) @@ -559,7 +562,7 @@ namespace Emby.Dlna.PlayTo return; } - var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), true) + var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), true) .ConfigureAwait(false); if (result == null || result.Document == null) @@ -586,7 +589,7 @@ namespace Emby.Dlna.PlayTo return null; } - var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType), false) + var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType), false) .ConfigureAwait(false); if (result == null || result.Document == null) @@ -624,7 +627,7 @@ namespace Emby.Dlna.PlayTo var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); - var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), false) + var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), false) .ConfigureAwait(false); if (result == null || result.Document == null) @@ -687,7 +690,7 @@ namespace Emby.Dlna.PlayTo var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); - var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), false) + var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), false) .ConfigureAwait(false); if (result == null || result.Document == null) @@ -868,7 +871,7 @@ namespace Emby.Dlna.PlayTo string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); - var httpClient = new SsdpHttpClient(_httpClient, _config); + var httpClient = new SsdpHttpClient(_httpClient); var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); @@ -896,7 +899,7 @@ namespace Emby.Dlna.PlayTo string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); - var httpClient = new SsdpHttpClient(_httpClient, _config); + var httpClient = new SsdpHttpClient(_httpClient); _logger.LogDebug("Dlna Device.GetRenderingProtocolAsync"); var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); @@ -931,7 +934,7 @@ namespace Emby.Dlna.PlayTo public static async Task CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, CancellationToken cancellationToken) { - var ssdpHttpClient = new SsdpHttpClient(httpClient, config); + var ssdpHttpClient = new SsdpHttpClient(httpClient); var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false); diff --git a/Emby.Dlna/PlayTo/DeviceInfo.cs b/Emby.Dlna/PlayTo/DeviceInfo.cs index 9e7c04bdb3..c36f890966 100644 --- a/Emby.Dlna/PlayTo/DeviceInfo.cs +++ b/Emby.Dlna/PlayTo/DeviceInfo.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; using Emby.Dlna.Common; using MediaBrowser.Model.Dlna; diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index c58f16438b..ad01f0576d 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Generic; using System.Globalization; diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index 2ca44b7ea2..5d75e33600 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Globalization; using System.Linq; @@ -21,7 +24,7 @@ using Microsoft.Extensions.Logging; namespace Emby.Dlna.PlayTo { - class PlayToManager : IDisposable + public class PlayToManager : IDisposable { private readonly ILogger _logger; private readonly ISessionManager _sessionManager; @@ -64,10 +67,10 @@ namespace Emby.Dlna.PlayTo public void Start() { - _deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered; + _deviceDiscovery.DeviceDiscovered += OnDeviceDiscoveryDeviceDiscovered; } - async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs e) + private async void OnDeviceDiscoveryDeviceDiscovered(object sender, GenericEventArgs e) { if (_disposed) { @@ -231,7 +234,7 @@ namespace Emby.Dlna.PlayTo public void Dispose() { - _deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered; + _deviceDiscovery.DeviceDiscovered -= OnDeviceDiscoveryDeviceDiscovered; try { diff --git a/Emby.Dlna/PlayTo/PlaybackProgressEventArgs.cs b/Emby.Dlna/PlayTo/PlaybackProgressEventArgs.cs index ffa56419bb..bdd2a6c3e4 100644 --- a/Emby.Dlna/PlayTo/PlaybackProgressEventArgs.cs +++ b/Emby.Dlna/PlayTo/PlaybackProgressEventArgs.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; namespace Emby.Dlna.PlayTo diff --git a/Emby.Dlna/PlayTo/PlaybackStartEventArgs.cs b/Emby.Dlna/PlayTo/PlaybackStartEventArgs.cs index 8cd8b47acf..485f7ec103 100644 --- a/Emby.Dlna/PlayTo/PlaybackStartEventArgs.cs +++ b/Emby.Dlna/PlayTo/PlaybackStartEventArgs.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; namespace Emby.Dlna.PlayTo diff --git a/Emby.Dlna/PlayTo/PlaybackStoppedEventArgs.cs b/Emby.Dlna/PlayTo/PlaybackStoppedEventArgs.cs index 2afdc324d9..2eddb125d4 100644 --- a/Emby.Dlna/PlayTo/PlaybackStoppedEventArgs.cs +++ b/Emby.Dlna/PlayTo/PlaybackStoppedEventArgs.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; namespace Emby.Dlna.PlayTo diff --git a/Emby.Dlna/PlayTo/PlaylistItem.cs b/Emby.Dlna/PlayTo/PlaylistItem.cs index 1e62b61e93..42d73c38ca 100644 --- a/Emby.Dlna/PlayTo/PlaylistItem.cs +++ b/Emby.Dlna/PlayTo/PlaylistItem.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.PlayTo diff --git a/Emby.Dlna/PlayTo/PlaylistItemFactory.cs b/Emby.Dlna/PlayTo/PlaylistItemFactory.cs index 446d8e1e6e..8e279da6fc 100644 --- a/Emby.Dlna/PlayTo/PlaylistItemFactory.cs +++ b/Emby.Dlna/PlayTo/PlaylistItemFactory.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Globalization; using System.IO; using System.Linq; diff --git a/Emby.Dlna/PlayTo/SsdpHttpClient.cs b/Emby.Dlna/PlayTo/SsdpHttpClient.cs index 66c634150a..757e713e1c 100644 --- a/Emby.Dlna/PlayTo/SsdpHttpClient.cs +++ b/Emby.Dlna/PlayTo/SsdpHttpClient.cs @@ -1,13 +1,16 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Globalization; using System.IO; +using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; using Emby.Dlna.Common; using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; namespace Emby.Dlna.PlayTo { @@ -19,12 +22,10 @@ namespace Emby.Dlna.PlayTo private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly IHttpClient _httpClient; - private readonly IServerConfigurationManager _config; - public SsdpHttpClient(IHttpClient httpClient, IServerConfigurationManager config) + public SsdpHttpClient(IHttpClient httpClient) { _httpClient = httpClient; - _config = config; } public async Task SendCommandAsync( @@ -64,7 +65,9 @@ namespace Emby.Dlna.PlayTo } if (!serviceUrl.StartsWith("/")) + { serviceUrl = "/" + serviceUrl; + } return baseUrl + serviceUrl; } @@ -90,7 +93,7 @@ namespace Emby.Dlna.PlayTo options.RequestHeaders["NT"] = "upnp:event"; options.RequestHeaders["TIMEOUT"] = "Second-" + timeOut.ToString(_usCulture); - using (await _httpClient.SendAsync(options, "SUBSCRIBE").ConfigureAwait(false)) + using (await _httpClient.SendAsync(options, new HttpMethod("SUBSCRIBE")).ConfigureAwait(false)) { } @@ -110,7 +113,7 @@ namespace Emby.Dlna.PlayTo options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName; - using (var response = await _httpClient.SendAsync(options, "GET").ConfigureAwait(false)) + using (var response = await _httpClient.SendAsync(options, HttpMethod.Get).ConfigureAwait(false)) using (var stream = response.Content) using (var reader = new StreamReader(stream, Encoding.UTF8)) { diff --git a/Emby.Dlna/PlayTo/TRANSPORTSTATE.cs b/Emby.Dlna/PlayTo/TRANSPORTSTATE.cs index 9f1690b04f..b312c8b6ec 100644 --- a/Emby.Dlna/PlayTo/TRANSPORTSTATE.cs +++ b/Emby.Dlna/PlayTo/TRANSPORTSTATE.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + namespace Emby.Dlna.PlayTo { public enum TRANSPORTSTATE diff --git a/Emby.Dlna/PlayTo/TransportCommands.cs b/Emby.Dlna/PlayTo/TransportCommands.cs index 4f9e398e90..a00d154f78 100644 --- a/Emby.Dlna/PlayTo/TransportCommands.cs +++ b/Emby.Dlna/PlayTo/TransportCommands.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Generic; using System.Linq; diff --git a/Emby.Dlna/PlayTo/UpnpContainer.cs b/Emby.Dlna/PlayTo/UpnpContainer.cs index 943e0347b2..9700d8a5d1 100644 --- a/Emby.Dlna/PlayTo/UpnpContainer.cs +++ b/Emby.Dlna/PlayTo/UpnpContainer.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Xml.Linq; using Emby.Dlna.Ssdp; diff --git a/Emby.Dlna/PlayTo/uBaseObject.cs b/Emby.Dlna/PlayTo/uBaseObject.cs index f29a126df7..6e2e31dc47 100644 --- a/Emby.Dlna/PlayTo/uBaseObject.cs +++ b/Emby.Dlna/PlayTo/uBaseObject.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; namespace Emby.Dlna.PlayTo diff --git a/Emby.Dlna/PlayTo/uPnpNamespaces.cs b/Emby.Dlna/PlayTo/uPnpNamespaces.cs index 7132ecd15c..fc0f0f704f 100644 --- a/Emby.Dlna/PlayTo/uPnpNamespaces.cs +++ b/Emby.Dlna/PlayTo/uPnpNamespaces.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Xml.Linq; namespace Emby.Dlna.PlayTo diff --git a/Emby.Dlna/Profiles/DefaultProfile.cs b/Emby.Dlna/Profiles/DefaultProfile.cs index ea50bd4a75..97286e3472 100644 --- a/Emby.Dlna/Profiles/DefaultProfile.cs +++ b/Emby.Dlna/Profiles/DefaultProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Linq; using MediaBrowser.Model.Dlna; diff --git a/Emby.Dlna/Profiles/DenonAvrProfile.cs b/Emby.Dlna/Profiles/DenonAvrProfile.cs index a738851915..3be9805288 100644 --- a/Emby.Dlna/Profiles/DenonAvrProfile.cs +++ b/Emby.Dlna/Profiles/DenonAvrProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/DirectTvProfile.cs b/Emby.Dlna/Profiles/DirectTvProfile.cs index 317c0976a2..33bcae6044 100644 --- a/Emby.Dlna/Profiles/DirectTvProfile.cs +++ b/Emby.Dlna/Profiles/DirectTvProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs b/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs index 8d8ab41cad..26654b803c 100644 --- a/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs +++ b/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/Foobar2000Profile.cs b/Emby.Dlna/Profiles/Foobar2000Profile.cs index 947194bce4..c1aece8c8a 100644 --- a/Emby.Dlna/Profiles/Foobar2000Profile.cs +++ b/Emby.Dlna/Profiles/Foobar2000Profile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/LgTvProfile.cs b/Emby.Dlna/Profiles/LgTvProfile.cs index 145685ab12..63b5b6f311 100644 --- a/Emby.Dlna/Profiles/LgTvProfile.cs +++ b/Emby.Dlna/Profiles/LgTvProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs b/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs index 3f0bb4263d..3a9744e381 100644 --- a/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs +++ b/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/MarantzProfile.cs b/Emby.Dlna/Profiles/MarantzProfile.cs index 162e284be6..05f94a2063 100644 --- a/Emby.Dlna/Profiles/MarantzProfile.cs +++ b/Emby.Dlna/Profiles/MarantzProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/MediaMonkeyProfile.cs b/Emby.Dlna/Profiles/MediaMonkeyProfile.cs index 53cae4e2ff..10218fa563 100644 --- a/Emby.Dlna/Profiles/MediaMonkeyProfile.cs +++ b/Emby.Dlna/Profiles/MediaMonkeyProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/PanasonicVieraProfile.cs b/Emby.Dlna/Profiles/PanasonicVieraProfile.cs index 5f31ec484e..945ec45187 100644 --- a/Emby.Dlna/Profiles/PanasonicVieraProfile.cs +++ b/Emby.Dlna/Profiles/PanasonicVieraProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/PopcornHourProfile.cs b/Emby.Dlna/Profiles/PopcornHourProfile.cs index aefe8c44f3..3765d01dc4 100644 --- a/Emby.Dlna/Profiles/PopcornHourProfile.cs +++ b/Emby.Dlna/Profiles/PopcornHourProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs b/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs index 51a1c81735..61c5f4dce9 100644 --- a/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs +++ b/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SharpSmartTvProfile.cs b/Emby.Dlna/Profiles/SharpSmartTvProfile.cs index f840cfb346..8967dc16a9 100644 --- a/Emby.Dlna/Profiles/SharpSmartTvProfile.cs +++ b/Emby.Dlna/Profiles/SharpSmartTvProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayer2013.cs b/Emby.Dlna/Profiles/SonyBlurayPlayer2013.cs index 2af1d3b501..308d74aa84 100644 --- a/Emby.Dlna/Profiles/SonyBlurayPlayer2013.cs +++ b/Emby.Dlna/Profiles/SonyBlurayPlayer2013.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayer2014.cs b/Emby.Dlna/Profiles/SonyBlurayPlayer2014.cs index 3de0b51922..496c243160 100644 --- a/Emby.Dlna/Profiles/SonyBlurayPlayer2014.cs +++ b/Emby.Dlna/Profiles/SonyBlurayPlayer2014.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayer2015.cs b/Emby.Dlna/Profiles/SonyBlurayPlayer2015.cs index 889484bea5..987a9af4b1 100644 --- a/Emby.Dlna/Profiles/SonyBlurayPlayer2015.cs +++ b/Emby.Dlna/Profiles/SonyBlurayPlayer2015.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayer2016.cs b/Emby.Dlna/Profiles/SonyBlurayPlayer2016.cs index acb90bd01b..560193dedd 100644 --- a/Emby.Dlna/Profiles/SonyBlurayPlayer2016.cs +++ b/Emby.Dlna/Profiles/SonyBlurayPlayer2016.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs b/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs index e1808b2052..c983d98baf 100644 --- a/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs +++ b/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyBravia2010Profile.cs b/Emby.Dlna/Profiles/SonyBravia2010Profile.cs index f8e8faa76d..186c894736 100644 --- a/Emby.Dlna/Profiles/SonyBravia2010Profile.cs +++ b/Emby.Dlna/Profiles/SonyBravia2010Profile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyBravia2011Profile.cs b/Emby.Dlna/Profiles/SonyBravia2011Profile.cs index 111f36e9b5..a29d143f68 100644 --- a/Emby.Dlna/Profiles/SonyBravia2011Profile.cs +++ b/Emby.Dlna/Profiles/SonyBravia2011Profile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyBravia2012Profile.cs b/Emby.Dlna/Profiles/SonyBravia2012Profile.cs index d5efe42707..9bcdd21b8f 100644 --- a/Emby.Dlna/Profiles/SonyBravia2012Profile.cs +++ b/Emby.Dlna/Profiles/SonyBravia2012Profile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyBravia2013Profile.cs b/Emby.Dlna/Profiles/SonyBravia2013Profile.cs index 3b0228694b..900e4ff06e 100644 --- a/Emby.Dlna/Profiles/SonyBravia2013Profile.cs +++ b/Emby.Dlna/Profiles/SonyBravia2013Profile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyBravia2014Profile.cs b/Emby.Dlna/Profiles/SonyBravia2014Profile.cs index e860eae346..963e7993e1 100644 --- a/Emby.Dlna/Profiles/SonyBravia2014Profile.cs +++ b/Emby.Dlna/Profiles/SonyBravia2014Profile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyPs3Profile.cs b/Emby.Dlna/Profiles/SonyPs3Profile.cs index 88d0646955..31a764d8d3 100644 --- a/Emby.Dlna/Profiles/SonyPs3Profile.cs +++ b/Emby.Dlna/Profiles/SonyPs3Profile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/SonyPs4Profile.cs b/Emby.Dlna/Profiles/SonyPs4Profile.cs index 499cf88038..9376a564ba 100644 --- a/Emby.Dlna/Profiles/SonyPs4Profile.cs +++ b/Emby.Dlna/Profiles/SonyPs4Profile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/WdtvLiveProfile.cs b/Emby.Dlna/Profiles/WdtvLiveProfile.cs index bf7b1ab47e..8e056792a6 100644 --- a/Emby.Dlna/Profiles/WdtvLiveProfile.cs +++ b/Emby.Dlna/Profiles/WdtvLiveProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Profiles/XboxOneProfile.cs b/Emby.Dlna/Profiles/XboxOneProfile.cs index 710b891e3d..364c433549 100644 --- a/Emby.Dlna/Profiles/XboxOneProfile.cs +++ b/Emby.Dlna/Profiles/XboxOneProfile.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles diff --git a/Emby.Dlna/Server/DescriptionXmlBuilder.cs b/Emby.Dlna/Server/DescriptionXmlBuilder.cs index 03d8f80abb..df48246377 100644 --- a/Emby.Dlna/Server/DescriptionXmlBuilder.cs +++ b/Emby.Dlna/Server/DescriptionXmlBuilder.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Generic; using System.Globalization; diff --git a/Emby.Dlna/Service/BaseControlHandler.cs b/Emby.Dlna/Service/BaseControlHandler.cs index 49129f6ffd..0125c0528a 100644 --- a/Emby.Dlna/Service/BaseControlHandler.cs +++ b/Emby.Dlna/Service/BaseControlHandler.cs @@ -1,7 +1,9 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; @@ -66,8 +68,6 @@ namespace Emby.Dlna.Service Logger.LogDebug("Received control request {0}", requestInfo.LocalName); - var result = GetResult(requestInfo.LocalName, requestInfo.Headers); - var settings = new XmlWriterSettings { Encoding = Encoding.UTF8, @@ -85,12 +85,9 @@ namespace Emby.Dlna.Service writer.WriteStartElement("SOAP-ENV", "Body", NS_SOAPENV); writer.WriteStartElement("u", requestInfo.LocalName + "Response", requestInfo.NamespaceURI); - foreach (var i in result) - { - writer.WriteStartElement(i.Key); - writer.WriteString(i.Value); - writer.WriteFullEndElement(); - } + + WriteResult(requestInfo.LocalName, requestInfo.Headers, writer); + writer.WriteFullEndElement(); writer.WriteFullEndElement(); @@ -219,7 +216,7 @@ namespace Emby.Dlna.Service public Dictionary Headers { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase); } - protected abstract IEnumerable> GetResult(string methodName, IDictionary methodParams); + protected abstract void WriteResult(string methodName, IDictionary methodParams, XmlWriter xmlWriter); private void LogRequest(ControlRequest request) { diff --git a/Emby.Dlna/Service/BaseService.cs b/Emby.Dlna/Service/BaseService.cs index 5359e94c44..d7e5c541d9 100644 --- a/Emby.Dlna/Service/BaseService.cs +++ b/Emby.Dlna/Service/BaseService.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using Emby.Dlna.Eventing; using MediaBrowser.Common.Net; using Microsoft.Extensions.Logging; diff --git a/Emby.Dlna/Service/ControlErrorHandler.cs b/Emby.Dlna/Service/ControlErrorHandler.cs index bbf975f384..a2f5057fb0 100644 --- a/Emby.Dlna/Service/ControlErrorHandler.cs +++ b/Emby.Dlna/Service/ControlErrorHandler.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.IO; using System.Text; diff --git a/Emby.Dlna/Service/ServiceXmlBuilder.cs b/Emby.Dlna/Service/ServiceXmlBuilder.cs index bd1f0bf05c..0787b8df94 100644 --- a/Emby.Dlna/Service/ServiceXmlBuilder.cs +++ b/Emby.Dlna/Service/ServiceXmlBuilder.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Collections.Generic; using System.Text; using Emby.Dlna.Common; diff --git a/Emby.Dlna/Ssdp/DeviceDiscovery.cs b/Emby.Dlna/Ssdp/DeviceDiscovery.cs index c5f3593da8..c5e57d0ff0 100644 --- a/Emby.Dlna/Ssdp/DeviceDiscovery.cs +++ b/Emby.Dlna/Ssdp/DeviceDiscovery.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System; using System.Collections.Generic; using System.Linq; @@ -9,16 +12,16 @@ using Rssdp.Infrastructure; namespace Emby.Dlna.Ssdp { - public class DeviceDiscovery : IDeviceDiscovery + public sealed class DeviceDiscovery : IDeviceDiscovery, IDisposable { - private bool _disposed; + private readonly object _syncLock = new object(); private readonly IServerConfigurationManager _config; - private event EventHandler> DeviceDiscoveredInternal; - private int _listenerCount; - private object _syncLock = new object(); + private bool _disposed; + + private event EventHandler> DeviceDiscoveredInternal; /// public event EventHandler> DeviceDiscovered @@ -33,6 +36,7 @@ namespace Emby.Dlna.Ssdp StartInternal(); } + remove { lock (_syncLock) @@ -130,6 +134,7 @@ namespace Emby.Dlna.Ssdp DeviceLeft?.Invoke(this, args); } + /// public void Dispose() { if (!_disposed) diff --git a/Emby.Dlna/Ssdp/Extensions.cs b/Emby.Dlna/Ssdp/Extensions.cs index c680c123ed..836d4abfd2 100644 --- a/Emby.Dlna/Ssdp/Extensions.cs +++ b/Emby.Dlna/Ssdp/Extensions.cs @@ -1,3 +1,6 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + using System.Xml.Linq; namespace Emby.Dlna.Ssdp From 3a338c1899c754610560d8760bbf8d960666d664 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sun, 26 Jan 2020 17:37:47 +0100 Subject: [PATCH 02/22] Address comments --- Emby.Dlna/ContentDirectory/ControlHandler.cs | 23 +++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index e5acb92db5..699fb33c6c 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -46,7 +46,6 @@ namespace Emby.Dlna.ContentDirectory private const string NS_UPNP = "urn:schemas-upnp-org:metadata-1-0/upnp/"; private readonly int _systemUpdateId; - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly DidlBuilder _didlBuilder; @@ -157,7 +156,7 @@ namespace Emby.Dlna.ContentDirectory var item = serverItem.Item; - var newbookmark = int.Parse(sparams["PosSecond"], _usCulture); + var newbookmark = int.Parse(sparams["PosSecond"], CultureInfo.InvariantCulture); var userdata = _userDataManager.GetUserData(_user, item); @@ -317,9 +316,9 @@ namespace Emby.Dlna.ContentDirectory xmlWriter.WriteFullEndElement(); xmlWriter.WriteFullEndElement(); - xmlWriter.WriteElementString("NumberReturned", provided.ToString(_usCulture)); - xmlWriter.WriteElementString("TotalMatches", totalCount.ToString(_usCulture)); - xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(_usCulture)); + xmlWriter.WriteElementString("NumberReturned", provided.ToString(CultureInfo.InvariantCulture)); + xmlWriter.WriteElementString("TotalMatches", totalCount.ToString(CultureInfo.InvariantCulture)); + xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(CultureInfo.InvariantCulture)); } private void HandleXBrowseByLetter(XmlWriter xmlWriter, IDictionary sparams, string deviceId) @@ -388,20 +387,18 @@ namespace Emby.Dlna.ContentDirectory xmlWriter.WriteFullEndElement(); xmlWriter.WriteFullEndElement(); - xmlWriter.WriteElementString("NumberReturned", childrenResult.Items.Count.ToString(_usCulture)); - xmlWriter.WriteElementString("TotalMatches", childrenResult.TotalRecordCount.ToString(_usCulture)); - xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(_usCulture)); + xmlWriter.WriteElementString("NumberReturned", childrenResult.Items.Count.ToString(CultureInfo.InvariantCulture)); + xmlWriter.WriteElementString("TotalMatches", childrenResult.TotalRecordCount.ToString(CultureInfo.InvariantCulture)); + xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(CultureInfo.InvariantCulture)); } private QueryResult GetChildrenSorted(BaseItem item, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit) { var folder = (Folder)item; - var sortOrders = folder.IsPreSorted switch - { - true => Array.Empty<(string, SortOrder)>(), - false => new[] { (ItemSortBy.SortName, sort.SortOrder) } - }; + var sortOrders = folder.IsPreSorted + ? Array.Empty<(string, SortOrder)>() + : new[] { (ItemSortBy.SortName, sort.SortOrder) }; string[] mediaTypes = Array.Empty(); bool? isFolder = null; From bade35958aadd6992b276aca278459ef5562d4ae Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sun, 26 Jan 2020 17:41:34 +0100 Subject: [PATCH 03/22] Fix --- Emby.Dlna/ConnectionManager/ControlHandler.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Emby.Dlna/ConnectionManager/ControlHandler.cs b/Emby.Dlna/ConnectionManager/ControlHandler.cs index 7e6c7eb228..b390515b87 100644 --- a/Emby.Dlna/ConnectionManager/ControlHandler.cs +++ b/Emby.Dlna/ConnectionManager/ControlHandler.cs @@ -28,6 +28,7 @@ namespace Emby.Dlna.ConnectionManager if (string.Equals(methodName, "GetProtocolInfo", StringComparison.OrdinalIgnoreCase)) { HandleGetProtocolInfo(xmlWriter); + return; } throw new ResourceNotFoundException("Unexpected control request name: " + methodName); From fc578de3b3370676090da5063faaf126ea50d2ec Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 27 Jan 2020 22:43:58 +0100 Subject: [PATCH 04/22] Try possible solutions --- Emby.Dlna/Didl/DidlBuilder.cs | 2 +- Emby.Dlna/Service/BaseControlHandler.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index f2128d9c6d..338c69d8c2 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -882,7 +882,7 @@ namespace Emby.Dlna.Didl var albumartUrlInfo = GetImageUrl(imageInfo, _profile.MaxAlbumArtWidth, _profile.MaxAlbumArtHeight, "jpg"); - writer.WriteStartElement("upnp", "albumArtURI", NS_UPNP); + writer.WriteStartElement("albumArtURI", NS_UPNP); writer.WriteAttributeString("dlna", "profileID", NS_DLNA, _profile.AlbumArtPn); writer.WriteString(albumartUrlInfo.Url); writer.WriteFullEndElement(); diff --git a/Emby.Dlna/Service/BaseControlHandler.cs b/Emby.Dlna/Service/BaseControlHandler.cs index 0125c0528a..2dc25f6bb5 100644 --- a/Emby.Dlna/Service/BaseControlHandler.cs +++ b/Emby.Dlna/Service/BaseControlHandler.cs @@ -71,7 +71,8 @@ namespace Emby.Dlna.Service var settings = new XmlWriterSettings { Encoding = Encoding.UTF8, - CloseOutput = false + CloseOutput = false, + NamespaceHandling = NamespaceHandling.OmitDuplicates }; StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8); From 6b68521bae63ecd2c8dd3d5a912b70756c1c5e49 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 27 Jan 2020 23:34:40 +0100 Subject: [PATCH 05/22] Try again --- Emby.Dlna/ContentDirectory/ControlHandler.cs | 2 +- Emby.Dlna/Didl/DidlBuilder.cs | 4 ++-- Emby.Dlna/Service/BaseControlHandler.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index 699fb33c6c..bb42b93dcd 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -268,7 +268,7 @@ namespace Emby.Dlna.ContentDirectory var item = serverItem.Item; int totalCount; - if (string.Equals(flag, "BrowseMetadata")) + if (string.Equals(flag, "BrowseMetadata", StringComparison.Ordinal)) { totalCount = 1; diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 338c69d8c2..145639ab0e 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -634,7 +634,7 @@ namespace Emby.Dlna.Didl { if (item.PremiereDate.HasValue) { - AddValue(writer, "dc", "date", item.PremiereDate.Value.ToString("o"), NS_DC); + AddValue(writer, "dc", "date", item.PremiereDate.Value.ToString("o", CultureInfo.InvariantCulture), NS_DC); } } @@ -882,7 +882,7 @@ namespace Emby.Dlna.Didl var albumartUrlInfo = GetImageUrl(imageInfo, _profile.MaxAlbumArtWidth, _profile.MaxAlbumArtHeight, "jpg"); - writer.WriteStartElement("albumArtURI", NS_UPNP); + writer.WriteStartElement("upnp", "albumArtURI", NS_UPNP); writer.WriteAttributeString("dlna", "profileID", NS_DLNA, _profile.AlbumArtPn); writer.WriteString(albumartUrlInfo.Url); writer.WriteFullEndElement(); diff --git a/Emby.Dlna/Service/BaseControlHandler.cs b/Emby.Dlna/Service/BaseControlHandler.cs index 2dc25f6bb5..97e63167d8 100644 --- a/Emby.Dlna/Service/BaseControlHandler.cs +++ b/Emby.Dlna/Service/BaseControlHandler.cs @@ -72,7 +72,7 @@ namespace Emby.Dlna.Service { Encoding = Encoding.UTF8, CloseOutput = false, - NamespaceHandling = NamespaceHandling.OmitDuplicates + ConformanceLevel = ConformanceLevel.Fragment }; StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8); @@ -96,7 +96,7 @@ namespace Emby.Dlna.Service writer.WriteEndDocument(); } - var xml = builder.ToString().Replace("xmlns:m=", "xmlns:u="); + var xml = builder.ToString().Replace("xmlns:m=", "xmlns:u=", StringComparison.Ordinal); var controlResponse = new ControlResponse { From 36d62c30930fa5b536fa5c7d1f4c85243a4b3fea Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Tue, 28 Jan 2020 13:19:25 +0100 Subject: [PATCH 06/22] Fix? --- Emby.Dlna/ContentDirectory/ControlHandler.cs | 177 +++++++++++-------- 1 file changed, 101 insertions(+), 76 deletions(-) diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index bb42b93dcd..2efa53d49b 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Text; using System.Threading; @@ -253,68 +254,80 @@ namespace Emby.Dlna.ContentDirectory start = startVal; } - xmlWriter.WriteStartElement("Result"); - - xmlWriter.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); - - xmlWriter.WriteAttributeString("xmlns", "dc", null, NS_DC); - xmlWriter.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); - xmlWriter.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); - //didl.SetAttribute("xmlns:sec", NS_SEC); - - DidlBuilder.WriteXmlRootAttributes(_profile, xmlWriter); - - var serverItem = GetItemFromObjectId(id, _user); - var item = serverItem.Item; - int totalCount; - if (string.Equals(flag, "BrowseMetadata", StringComparison.Ordinal)) + + var settings = new XmlWriterSettings() { - totalCount = 1; + Encoding = Encoding.UTF8, + CloseOutput = false, + OmitXmlDeclaration = true, + ConformanceLevel = ConformanceLevel.Fragment + }; - if (item.IsDisplayedAsFolder || serverItem.StubType.HasValue) - { - var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount); - - _didlBuilder.WriteFolderElement(xmlWriter, item, serverItem.StubType, null, childrenResult.TotalRecordCount, filter, id); - } - else - { - var dlnaOptions = _config.GetDlnaConfiguration(); - _didlBuilder.WriteItemElement(dlnaOptions, xmlWriter, item, _user, null, null, deviceId, filter); - } - - provided++; - } - else + using (StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8)) + using (var writer = XmlWriter.Create(builder, settings)) { - var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount); - totalCount = childrenResult.TotalRecordCount; + writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); - provided = childrenResult.Items.Count; + writer.WriteAttributeString("xmlns", "dc", null, NS_DC); + writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); + writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); - var dlnaOptions = _config.GetDlnaConfiguration(); - foreach (var i in childrenResult.Items) + DidlBuilder.WriteXmlRootAttributes(_profile, writer); + + var serverItem = GetItemFromObjectId(id, _user); + var item = serverItem.Item; + + + if (string.Equals(flag, "BrowseMetadata", StringComparison.Ordinal)) { - var childItem = i.Item; - var displayStubType = i.StubType; + totalCount = 1; - if (childItem.IsDisplayedAsFolder || displayStubType.HasValue) + if (item.IsDisplayedAsFolder || serverItem.StubType.HasValue) { - var childCount = GetUserItems(childItem, displayStubType, _user, sortCriteria, null, 0) - .TotalRecordCount; + var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount); - _didlBuilder.WriteFolderElement(xmlWriter, childItem, displayStubType, item, childCount, filter); + _didlBuilder.WriteFolderElement(writer, item, serverItem.StubType, null, childrenResult.TotalRecordCount, filter, id); } else { - _didlBuilder.WriteItemElement(dlnaOptions, xmlWriter, childItem, _user, item, serverItem.StubType, deviceId, filter); + var dlnaOptions = _config.GetDlnaConfiguration(); + _didlBuilder.WriteItemElement(dlnaOptions, writer, item, _user, null, null, deviceId, filter); + } + + provided++; + } + else + { + var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount); + totalCount = childrenResult.TotalRecordCount; + + provided = childrenResult.Items.Count; + + var dlnaOptions = _config.GetDlnaConfiguration(); + foreach (var i in childrenResult.Items) + { + var childItem = i.Item; + var displayStubType = i.StubType; + + if (childItem.IsDisplayedAsFolder || displayStubType.HasValue) + { + var childCount = GetUserItems(childItem, displayStubType, _user, sortCriteria, null, 0) + .TotalRecordCount; + + _didlBuilder.WriteFolderElement(writer, childItem, displayStubType, item, childCount, filter); + } + else + { + _didlBuilder.WriteItemElement(dlnaOptions, writer, childItem, _user, item, serverItem.StubType, deviceId, filter); + } } } - } - xmlWriter.WriteFullEndElement(); - xmlWriter.WriteFullEndElement(); + writer.WriteFullEndElement(); + + xmlWriter.WriteElementString("Result", builder.ToString()); + } xmlWriter.WriteElementString("NumberReturned", provided.ToString(CultureInfo.InvariantCulture)); xmlWriter.WriteElementString("TotalMatches", totalCount.ToString(CultureInfo.InvariantCulture)); @@ -350,43 +363,55 @@ namespace Emby.Dlna.ContentDirectory start = startVal; } - xmlWriter.WriteStartElement("Result"); + QueryResult childrenResult; - xmlWriter.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); - - xmlWriter.WriteAttributeString("xmlns", "dc", null, NS_DC); - xmlWriter.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); - xmlWriter.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); - //didl.SetAttribute("xmlns:sec", NS_SEC); - - DidlBuilder.WriteXmlRootAttributes(_profile, xmlWriter); - - var serverItem = GetItemFromObjectId(sparams["ContainerID"], _user); - - var item = serverItem.Item; - - var childrenResult = GetChildrenSorted(item, _user, searchCriteria, sortCriteria, start, requestedCount); - - var dlnaOptions = _config.GetDlnaConfiguration(); - - foreach (var i in childrenResult.Items) + var settings = new XmlWriterSettings() { - if (i.IsDisplayedAsFolder) - { - var childCount = GetChildrenSorted(i, _user, searchCriteria, sortCriteria, null, 0) - .TotalRecordCount; + Encoding = Encoding.UTF8, + CloseOutput = false, + OmitXmlDeclaration = true, + ConformanceLevel = ConformanceLevel.Fragment + }; - _didlBuilder.WriteFolderElement(xmlWriter, i, null, item, childCount, filter); - } - else + using (StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8)) + using (var writer = XmlWriter.Create(builder, settings)) + { + writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); + + writer.WriteAttributeString("xmlns", "dc", null, NS_DC); + writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); + writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); + + DidlBuilder.WriteXmlRootAttributes(_profile, writer); + + var serverItem = GetItemFromObjectId(sparams["ContainerID"], _user); + + var item = serverItem.Item; + + childrenResult = GetChildrenSorted(item, _user, searchCriteria, sortCriteria, start, requestedCount); + + var dlnaOptions = _config.GetDlnaConfiguration(); + + foreach (var i in childrenResult.Items) { - _didlBuilder.WriteItemElement(dlnaOptions, xmlWriter, i, _user, item, serverItem.StubType, deviceId, filter); + if (i.IsDisplayedAsFolder) + { + var childCount = GetChildrenSorted(i, _user, searchCriteria, sortCriteria, null, 0) + .TotalRecordCount; + + _didlBuilder.WriteFolderElement(writer, i, null, item, childCount, filter); + } + else + { + _didlBuilder.WriteItemElement(dlnaOptions, writer, i, _user, item, serverItem.StubType, deviceId, filter); + } } + + writer.WriteFullEndElement(); + + xmlWriter.WriteElementString("Result", builder.ToString()); } - xmlWriter.WriteFullEndElement(); - xmlWriter.WriteFullEndElement(); - xmlWriter.WriteElementString("NumberReturned", childrenResult.Items.Count.ToString(CultureInfo.InvariantCulture)); xmlWriter.WriteElementString("TotalMatches", childrenResult.TotalRecordCount.ToString(CultureInfo.InvariantCulture)); xmlWriter.WriteElementString("UpdateID", _systemUpdateId.ToString(CultureInfo.InvariantCulture)); From ae9c1e29e7ef8e2498bd8185f591ef589526105e Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Tue, 28 Jan 2020 17:50:25 +0100 Subject: [PATCH 07/22] My bad --- Emby.Dlna/Service/BaseControlHandler.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Emby.Dlna/Service/BaseControlHandler.cs b/Emby.Dlna/Service/BaseControlHandler.cs index 97e63167d8..4704ecbe69 100644 --- a/Emby.Dlna/Service/BaseControlHandler.cs +++ b/Emby.Dlna/Service/BaseControlHandler.cs @@ -71,8 +71,7 @@ namespace Emby.Dlna.Service var settings = new XmlWriterSettings { Encoding = Encoding.UTF8, - CloseOutput = false, - ConformanceLevel = ConformanceLevel.Fragment + CloseOutput = false }; StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8); From 6ee04855cd112255d4b73b24cb5511a41c1db1f9 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Tue, 28 Jan 2020 21:54:51 +0100 Subject: [PATCH 08/22] Style --- Emby.Dlna/ContentDirectory/ControlHandler.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index 2efa53d49b..2590a92a70 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -60,7 +60,8 @@ namespace Emby.Dlna.ContentDirectory string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, - User user, int systemUpdateId, + User user, + int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, From d69870680b9a12118b2e5b5e9944c91b886a12c9 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Wed, 29 Jan 2020 17:30:27 +0100 Subject: [PATCH 09/22] Close xmlwriter first --- Emby.Dlna/ContentDirectory/ControlHandler.cs | 180 ++++++++++--------- 1 file changed, 92 insertions(+), 88 deletions(-) diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index 2590a92a70..1278b367c7 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -257,75 +257,77 @@ namespace Emby.Dlna.ContentDirectory int totalCount; - var settings = new XmlWriterSettings() - { - Encoding = Encoding.UTF8, - CloseOutput = false, - OmitXmlDeclaration = true, - ConformanceLevel = ConformanceLevel.Fragment - }; - using (StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8)) - using (var writer = XmlWriter.Create(builder, settings)) { - writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); - - writer.WriteAttributeString("xmlns", "dc", null, NS_DC); - writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); - writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); - - DidlBuilder.WriteXmlRootAttributes(_profile, writer); - - var serverItem = GetItemFromObjectId(id, _user); - var item = serverItem.Item; - - - if (string.Equals(flag, "BrowseMetadata", StringComparison.Ordinal)) + var settings = new XmlWriterSettings() { - totalCount = 1; + Encoding = Encoding.UTF8, + CloseOutput = false, + OmitXmlDeclaration = true, + ConformanceLevel = ConformanceLevel.Fragment + }; - if (item.IsDisplayedAsFolder || serverItem.StubType.HasValue) - { - var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount); - - _didlBuilder.WriteFolderElement(writer, item, serverItem.StubType, null, childrenResult.TotalRecordCount, filter, id); - } - else - { - var dlnaOptions = _config.GetDlnaConfiguration(); - _didlBuilder.WriteItemElement(dlnaOptions, writer, item, _user, null, null, deviceId, filter); - } - - provided++; - } - else + using (var writer = XmlWriter.Create(builder, settings)) { - var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount); - totalCount = childrenResult.TotalRecordCount; + writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); - provided = childrenResult.Items.Count; + writer.WriteAttributeString("xmlns", "dc", null, NS_DC); + writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); + writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); - var dlnaOptions = _config.GetDlnaConfiguration(); - foreach (var i in childrenResult.Items) + DidlBuilder.WriteXmlRootAttributes(_profile, writer); + + var serverItem = GetItemFromObjectId(id, _user); + var item = serverItem.Item; + + + if (string.Equals(flag, "BrowseMetadata", StringComparison.Ordinal)) { - var childItem = i.Item; - var displayStubType = i.StubType; + totalCount = 1; - if (childItem.IsDisplayedAsFolder || displayStubType.HasValue) + if (item.IsDisplayedAsFolder || serverItem.StubType.HasValue) { - var childCount = GetUserItems(childItem, displayStubType, _user, sortCriteria, null, 0) - .TotalRecordCount; + var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount); - _didlBuilder.WriteFolderElement(writer, childItem, displayStubType, item, childCount, filter); + _didlBuilder.WriteFolderElement(writer, item, serverItem.StubType, null, childrenResult.TotalRecordCount, filter, id); } else { - _didlBuilder.WriteItemElement(dlnaOptions, writer, childItem, _user, item, serverItem.StubType, deviceId, filter); + var dlnaOptions = _config.GetDlnaConfiguration(); + _didlBuilder.WriteItemElement(dlnaOptions, writer, item, _user, null, null, deviceId, filter); + } + + provided++; + } + else + { + var childrenResult = GetUserItems(item, serverItem.StubType, _user, sortCriteria, start, requestedCount); + totalCount = childrenResult.TotalRecordCount; + + provided = childrenResult.Items.Count; + + var dlnaOptions = _config.GetDlnaConfiguration(); + foreach (var i in childrenResult.Items) + { + var childItem = i.Item; + var displayStubType = i.StubType; + + if (childItem.IsDisplayedAsFolder || displayStubType.HasValue) + { + var childCount = GetUserItems(childItem, displayStubType, _user, sortCriteria, null, 0) + .TotalRecordCount; + + _didlBuilder.WriteFolderElement(writer, childItem, displayStubType, item, childCount, filter); + } + else + { + _didlBuilder.WriteItemElement(dlnaOptions, writer, childItem, _user, item, serverItem.StubType, deviceId, filter); + } } } - } - writer.WriteFullEndElement(); + writer.WriteFullEndElement(); + } xmlWriter.WriteElementString("Result", builder.ToString()); } @@ -366,50 +368,52 @@ namespace Emby.Dlna.ContentDirectory QueryResult childrenResult; - var settings = new XmlWriterSettings() - { - Encoding = Encoding.UTF8, - CloseOutput = false, - OmitXmlDeclaration = true, - ConformanceLevel = ConformanceLevel.Fragment - }; - using (StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8)) - using (var writer = XmlWriter.Create(builder, settings)) { - writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); - - writer.WriteAttributeString("xmlns", "dc", null, NS_DC); - writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); - writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); - - DidlBuilder.WriteXmlRootAttributes(_profile, writer); - - var serverItem = GetItemFromObjectId(sparams["ContainerID"], _user); - - var item = serverItem.Item; - - childrenResult = GetChildrenSorted(item, _user, searchCriteria, sortCriteria, start, requestedCount); - - var dlnaOptions = _config.GetDlnaConfiguration(); - - foreach (var i in childrenResult.Items) + var settings = new XmlWriterSettings() { - if (i.IsDisplayedAsFolder) - { - var childCount = GetChildrenSorted(i, _user, searchCriteria, sortCriteria, null, 0) - .TotalRecordCount; + Encoding = Encoding.UTF8, + CloseOutput = false, + OmitXmlDeclaration = true, + ConformanceLevel = ConformanceLevel.Fragment + }; - _didlBuilder.WriteFolderElement(writer, i, null, item, childCount, filter); - } - else + using (var writer = XmlWriter.Create(builder, settings)) + { + writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); + + writer.WriteAttributeString("xmlns", "dc", null, NS_DC); + writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); + writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); + + DidlBuilder.WriteXmlRootAttributes(_profile, writer); + + var serverItem = GetItemFromObjectId(sparams["ContainerID"], _user); + + var item = serverItem.Item; + + childrenResult = GetChildrenSorted(item, _user, searchCriteria, sortCriteria, start, requestedCount); + + var dlnaOptions = _config.GetDlnaConfiguration(); + + foreach (var i in childrenResult.Items) { - _didlBuilder.WriteItemElement(dlnaOptions, writer, i, _user, item, serverItem.StubType, deviceId, filter); + if (i.IsDisplayedAsFolder) + { + var childCount = GetChildrenSorted(i, _user, searchCriteria, sortCriteria, null, 0) + .TotalRecordCount; + + _didlBuilder.WriteFolderElement(writer, i, null, item, childCount, filter); + } + else + { + _didlBuilder.WriteItemElement(dlnaOptions, writer, i, _user, item, serverItem.StubType, deviceId, filter); + } } + + writer.WriteFullEndElement(); } - writer.WriteFullEndElement(); - xmlWriter.WriteElementString("Result", builder.ToString()); } From 6341d986a95be928a85ecd81c08fefdc5c3ec3b6 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 2 Feb 2020 00:07:46 +0900 Subject: [PATCH 10/22] fix a few warnings --- .../Session/SessionManager.cs | 30 +++++++++---------- MediaBrowser.Api/Session/SessionsService.cs | 10 ++----- .../UserLibrary/PlaystateService.cs | 4 --- MediaBrowser.Api/UserService.cs | 2 +- .../Session/SessionInfo.cs | 7 ----- 5 files changed, 19 insertions(+), 34 deletions(-) diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index b1d513dd4f..ec3e875732 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -67,15 +67,15 @@ namespace Emby.Server.Implementations.Session public event EventHandler> AuthenticationSucceeded; /// - /// Occurs when [playback start]. + /// Occurs when playback has started. /// public event EventHandler PlaybackStart; /// - /// Occurs when [playback progress]. + /// Occurs when playback has progressed. /// public event EventHandler PlaybackProgress; /// - /// Occurs when [playback stopped]. + /// Occurs when playback has stopped. /// public event EventHandler PlaybackStopped; @@ -685,7 +685,7 @@ namespace Emby.Server.Implementations.Session } /// - /// Used to report playback progress for an item + /// Used to report playback progress for an item. /// /// Task. public async Task OnPlaybackProgress(PlaybackProgressInfo info, bool isAutomated) @@ -1435,14 +1435,13 @@ namespace Emby.Server.Implementations.Session DeviceId = deviceId, UserId = user.Id, Limit = 1 - }).Items.FirstOrDefault(); - var allExistingForDevice = _authRepo.Get(new AuthenticationInfoQuery - { - DeviceId = deviceId - - }).Items; + var allExistingForDevice = _authRepo.Get( + new AuthenticationInfoQuery + { + DeviceId = deviceId + }).Items; foreach (var auth in allExistingForDevice) { @@ -1499,8 +1498,7 @@ namespace Emby.Server.Implementations.Session { Limit = 1, AccessToken = accessToken - - }).Items.FirstOrDefault(); + }).Items[0]; if (existing != null) { @@ -1708,7 +1706,8 @@ namespace Emby.Server.Implementations.Session public void ReportTranscodingInfo(string deviceId, TranscodingInfo info) { - var session = Sessions.FirstOrDefault(i => string.Equals(i.DeviceId, deviceId)); + var session = Sessions.FirstOrDefault(i => + string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase)); if (session != null) { @@ -1723,8 +1722,9 @@ namespace Emby.Server.Implementations.Session public SessionInfo GetSession(string deviceId, string client, string version) { - return Sessions.FirstOrDefault(i => string.Equals(i.DeviceId, deviceId) && - string.Equals(i.Client, client)); + return Sessions.FirstOrDefault(i => + string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase) + && string.Equals(i.Client, client, StringComparison.OrdinalIgnoreCase)); } public SessionInfo GetSessionByAuthenticationToken(AuthenticationInfo info, string deviceId, string remoteEndpoint, string appVersion) diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs index 700861c554..8e53490ffc 100644 --- a/MediaBrowser.Api/Session/SessionsService.cs +++ b/MediaBrowser.Api/Session/SessionsService.cs @@ -276,7 +276,7 @@ namespace MediaBrowser.Api.Session public class SessionsService : BaseApiService { /// - /// The _session manager. + /// The session manager. /// private readonly ISessionManager _sessionManager; @@ -438,14 +438,12 @@ namespace MediaBrowser.Api.Session public Task Post(SendSystemCommand request) { var name = request.Command; - if (Enum.TryParse(name, true, out GeneralCommandType commandType)) { name = commandType.ToString(); } var currentSession = GetSession(_sessionContext); - var command = new GeneralCommand { Name = name, @@ -518,16 +516,13 @@ namespace MediaBrowser.Api.Session { request.Id = GetSession(_sessionContext).Id; } + _sessionManager.ReportCapabilities(request.Id, new ClientCapabilities { PlayableMediaTypes = SplitValue(request.PlayableMediaTypes, ','), - SupportedCommands = SplitValue(request.SupportedCommands, ','), - SupportsMediaControl = request.SupportsMediaControl, - SupportsSync = request.SupportsSync, - SupportsPersistentIdentifier = request.SupportsPersistentIdentifier }); } @@ -538,6 +533,7 @@ namespace MediaBrowser.Api.Session { request.Id = GetSession(_sessionContext).Id; } + _sessionManager.ReportCapabilities(request.Id, request); } } diff --git a/MediaBrowser.Api/UserLibrary/PlaystateService.cs b/MediaBrowser.Api/UserLibrary/PlaystateService.cs index 9d1cf5d9ee..d0faca163b 100644 --- a/MediaBrowser.Api/UserLibrary/PlaystateService.cs +++ b/MediaBrowser.Api/UserLibrary/PlaystateService.cs @@ -103,10 +103,6 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "MediaSourceId", Description = "The id of the MediaSource", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] public string MediaSourceId { get; set; } - /// - /// Gets or sets a value indicating whether this is likes. - /// - /// true if likes; otherwise, false. [ApiMember(Name = "CanSeek", Description = "Indicates if the client can seek", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")] public bool CanSeek { get; set; } diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index e1b01b012c..3b82dd9dd8 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -240,7 +240,7 @@ namespace MediaBrowser.Api public class UserService : BaseApiService { /// - /// The _user manager + /// The user manager. /// private readonly IUserManager _userManager; private readonly ISessionManager _sessionMananger; diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index acda6a4166..964fc9b191 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using System.Text.Json.Serialization; using System.Threading; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dto; @@ -123,7 +122,6 @@ namespace MediaBrowser.Controller.Session /// Gets or sets the session controller. /// /// The session controller. - [JsonIgnore] public ISessionController[] SessionControllers { get; set; } /// @@ -245,11 +243,6 @@ namespace MediaBrowser.Controller.Session SessionControllers = controllers.ToArray(); } - public bool ContainsUser(string userId) - { - return ContainsUser(new Guid(userId)); - } - public bool ContainsUser(Guid userId) { if (UserId.Equals(userId)) From 26dd67a441d251bef56c14d8058e7068e38e06af Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 2 Feb 2020 00:09:18 +0900 Subject: [PATCH 11/22] change authentication flow --- .../Session/SessionManager.cs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index ec3e875732..659483a361 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1379,20 +1379,16 @@ namespace Emby.Server.Implementations.Session user = _userManager.GetUserByName(request.Username); } - if (user != null) - { - // TODO: Move this to userManager? - if (!string.IsNullOrEmpty(request.DeviceId) - && !_deviceManager.CanAccessDevice(user, request.DeviceId)) - { - throw new SecurityException("User is not allowed access from this device."); - } - } - if (user == null) { AuthenticationFailed?.Invoke(this, new GenericEventArgs(request)); - throw new SecurityException("Invalid user or password entered."); + throw new SecurityException("Invalid username or password entered."); + } + + if (!string.IsNullOrEmpty(request.DeviceId) + && !_deviceManager.CanAccessDevice(user, request.DeviceId)) + { + throw new SecurityException("User is not allowed access from this device."); } if (enforcePassword) From 1bc8ca25421dd3b66a58e1ff0938ee7874d8448e Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 2 Feb 2020 00:16:11 +0900 Subject: [PATCH 12/22] add session view endpoint --- .../Session/SessionManager.cs | 10 +++++----- MediaBrowser.Api/Session/SessionsService.cs | 18 ++++++++++++++++++ MediaBrowser.Controller/Session/SessionInfo.cs | 2 ++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 659483a361..8e52f24159 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1686,18 +1686,18 @@ namespace Emby.Server.Implementations.Session throw new ArgumentNullException(nameof(itemId)); } - //var item = _libraryManager.GetItemById(new Guid(itemId)); + var item = _libraryManager.GetItemById(new Guid(itemId)); - //var info = GetItemInfo(item, null, null); + var info = GetItemInfo(item, null); - //ReportNowViewingItem(sessionId, info); + ReportNowViewingItem(sessionId, info); } public void ReportNowViewingItem(string sessionId, BaseItemDto item) { - //var session = GetSession(sessionId); + var session = GetSession(sessionId); - //session.NowViewingItem = item; + session.NowViewingItem = item; } public void ReportTranscodingInfo(string deviceId, TranscodingInfo info) diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs index 8e53490ffc..df816927a5 100644 --- a/MediaBrowser.Api/Session/SessionsService.cs +++ b/MediaBrowser.Api/Session/SessionsService.cs @@ -230,6 +230,17 @@ namespace MediaBrowser.Api.Session public string Id { get; set; } } + [Route("/Sessions/Viewing", "POST", Summary = "Reports that a session is viewing an item")] + [Authenticated] + public class ReportViewing : IReturnVoid + { + [ApiMember(Name = "SessionId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + public string SessionId { get; set; } + + [ApiMember(Name = "ItemId", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] + public string ItemId { get; set; } + } + [Route("/Sessions/Logout", "POST", Summary = "Reports that a session has ended")] [Authenticated] public class ReportSessionEnded : IReturnVoid @@ -536,5 +547,12 @@ namespace MediaBrowser.Api.Session _sessionManager.ReportCapabilities(request.Id, request); } + + public void Post(ReportViewing request) + { + request.SessionId = GetSession(_sessionContext).Id; + + _sessionManager.ReportNowViewingItem(request.SessionId, request.ItemId); + } } } diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index 964fc9b191..7bc50eb413 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -106,6 +106,8 @@ namespace MediaBrowser.Controller.Session public BaseItem FullNowPlayingItem { get; set; } + public BaseItemDto NowViewingItem { get; set; } + /// /// Gets or sets the device id. /// From f93edb7ade68588f4e2e7e05932b3266105ea91a Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 4 Feb 2020 01:29:18 +0900 Subject: [PATCH 13/22] add code suggestions --- Emby.Server.Implementations/Session/SessionManager.cs | 2 +- MediaBrowser.Controller/Session/SessionInfo.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 8e52f24159..4aed226deb 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1494,7 +1494,7 @@ namespace Emby.Server.Implementations.Session { Limit = 1, AccessToken = accessToken - }).Items[0]; + }).Items.FirstOrDefault(); if (existing != null) { diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index 7bc50eb413..cc5160d779 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Text.Json.Serialization; using System.Threading; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dto; @@ -124,6 +125,7 @@ namespace MediaBrowser.Controller.Session /// Gets or sets the session controller. /// /// The session controller. + [JsonIgnore] public ISessionController[] SessionControllers { get; set; } /// From 422c4407439e306dea0eeda3020ad5cbb890c972 Mon Sep 17 00:00:00 2001 From: David Mouse Date: Mon, 10 Feb 2020 04:12:37 -0500 Subject: [PATCH 14/22] Fix Fedora build Fedora builds were broken due to dotnet-sdk-3.1 and dotnet-runtime-3.1 not being available on the @dotnet-sig/dotnet repo as well as a lack of the git package (needed for yarn when installing jellyfin/jellyfin-noto per https://github.com/jellyfin/jellyfin-web/pull/735). Replaces the outdated repo with the official repo found in Microsoft's documentation. --- deployment/fedora-package-x64/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deployment/fedora-package-x64/Dockerfile b/deployment/fedora-package-x64/Dockerfile index f5c3ab7a66..05a4ef21f9 100644 --- a/deployment/fedora-package-x64/Dockerfile +++ b/deployment/fedora-package-x64/Dockerfile @@ -12,11 +12,11 @@ ENV ARTIFACT_DIR=/dist RUN dnf update -y # Install build dependencies -RUN dnf install -y @buildsys-build rpmdevtools dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel nodejs-yarn +RUN dnf install -y @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel nodejs-yarn # Install DotNET SDK -RUN dnf copr enable -y @dotnet-sig/dotnet \ - && rpmdev-setuptree \ +RUN rpm --import https://packages.microsoft.com/keys/microsoft.asc \ + && curl -o /etc/yum.repos.d/microsoft-prod.repo https://packages.microsoft.com/config/fedora/$(rpm -E %fedora)/prod.repo \ && dnf install -y dotnet-sdk-${SDK_VERSION} dotnet-runtime-${SDK_VERSION} # Create symlinks and directories From a381eb884c61ce6661f6490f88e4af7430754dca Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Mon, 10 Feb 2020 10:26:28 +0100 Subject: [PATCH 15/22] add-some-xml-documentation --- .../Configuration/IConfigurationFactory.cs | 25 +++++++++++++++++++ .../Plugins/IServerEntryPoint.cs | 10 ++++++-- .../Services/ApiMemberAttribute.cs | 3 +++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Common/Configuration/IConfigurationFactory.cs b/MediaBrowser.Common/Configuration/IConfigurationFactory.cs index 9b4ed772db..2b4b9b082c 100644 --- a/MediaBrowser.Common/Configuration/IConfigurationFactory.cs +++ b/MediaBrowser.Common/Configuration/IConfigurationFactory.cs @@ -6,20 +6,45 @@ using System.Collections.Generic; namespace MediaBrowser.Common.Configuration { + /// + /// Provides an interface to retrieve a configuration store. Classes with this interface are scanned for at + /// application start to dynamically register configuration for various modules/plugins. + /// public interface IConfigurationFactory { + /// + /// Get the configuration store for this module. + /// + /// The configuration store. IEnumerable GetConfigurations(); } + /// + /// Describes a single entry in the application configuration. + /// public class ConfigurationStore { + /// + /// Gets or sets the unique identifier for the configuration. + /// public string Key { get; set; } + /// + /// Gets or sets the type used to store the data for this configuration entry. + /// public Type ConfigurationType { get; set; } } + /// + /// A configuration store that can be validated. + /// public interface IValidatingConfiguration { + /// + /// Validation method to be invoked before saving the configuration. + /// + /// The old configuration. + /// The new configuration. void Validate(object oldConfig, object newConfig); } } diff --git a/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs b/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs index e57929989a..5b3173ef6a 100644 --- a/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs +++ b/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs @@ -4,16 +4,22 @@ using System.Threading.Tasks; namespace MediaBrowser.Controller.Plugins { /// - /// Interface IServerEntryPoint + /// Represents an entry point for a module in the application. This interface is scanned for automatically and + /// provides a hook to initialize the module at application start. + /// The entry point can additionally be flagged as a pre-startup task by applying the + /// interface. /// public interface IServerEntryPoint : IDisposable { /// - /// Runs this instance. + /// Run the initialization for this module. This method is invoked at application start. /// Task RunAsync(); } + /// + /// Indicates that a should be invoked as a pre-startup task. + /// public interface IRunBeforeStartup { diff --git a/MediaBrowser.Model/Services/ApiMemberAttribute.cs b/MediaBrowser.Model/Services/ApiMemberAttribute.cs index 7267fce247..06a6713ee3 100644 --- a/MediaBrowser.Model/Services/ApiMemberAttribute.cs +++ b/MediaBrowser.Model/Services/ApiMemberAttribute.cs @@ -5,6 +5,9 @@ using System; namespace MediaBrowser.Model.Services { + /// + /// Identifies a single API endpoint. + /// [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)] public class ApiMemberAttribute : Attribute { From 8acfc264fca7f2b35fa6c24ce7ff0628c7f01ade Mon Sep 17 00:00:00 2001 From: artiume Date: Tue, 11 Feb 2020 10:29:26 -0500 Subject: [PATCH 16/22] Update dockerfile to install git for new dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/jellyfin/jellyfin-web/pull/735 I had to install git to get it to build ✌️ --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0bccd9d646..1029a4cee1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ARG FFMPEG_VERSION=latest FROM node:alpine as web-builder ARG JELLYFIN_WEB_VERSION=master -RUN apk add curl \ +RUN apk add curl git \ && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ && cd jellyfin-web-* \ && yarn install \ From e47185160e679a9dd18377c9671fd637fb592887 Mon Sep 17 00:00:00 2001 From: artiume Date: Tue, 11 Feb 2020 10:30:15 -0500 Subject: [PATCH 17/22] Add git to arm --- Dockerfile.arm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.arm b/Dockerfile.arm index e7cbb09094..5151d4cb64 100644 --- a/Dockerfile.arm +++ b/Dockerfile.arm @@ -3,7 +3,7 @@ ARG DOTNET_VERSION=3.1 FROM node:alpine as web-builder ARG JELLYFIN_WEB_VERSION=master -RUN apk add curl \ +RUN apk add curl git \ && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ && cd jellyfin-web-* \ && yarn install \ From 8fb86cb5ffc84abd974c48edbd68b6c7ee2841ad Mon Sep 17 00:00:00 2001 From: artiume Date: Tue, 11 Feb 2020 10:30:30 -0500 Subject: [PATCH 18/22] git to arm64 --- Dockerfile.arm64 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 index a0cd0dacc2..bf9604bbfb 100644 --- a/Dockerfile.arm64 +++ b/Dockerfile.arm64 @@ -3,7 +3,7 @@ ARG DOTNET_VERSION=3.1 FROM node:alpine as web-builder ARG JELLYFIN_WEB_VERSION=master -RUN apk add curl \ +RUN apk add curl git \ && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ && cd jellyfin-web-* \ && yarn install \ From a7c7d536a7b8714857955a3d794c915f3c0eed4b Mon Sep 17 00:00:00 2001 From: j7johnny Date: Tue, 11 Feb 2020 04:55:51 +0000 Subject: [PATCH 19/22] Translated using Weblate (Chinese (Traditional)) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/zh_Hant/ --- Emby.Server.Implementations/Localization/Core/zh-TW.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Emby.Server.Implementations/Localization/Core/zh-TW.json b/Emby.Server.Implementations/Localization/Core/zh-TW.json index 33bdbfb989..3b0dc4ab25 100644 --- a/Emby.Server.Implementations/Localization/Core/zh-TW.json +++ b/Emby.Server.Implementations/Localization/Core/zh-TW.json @@ -50,10 +50,10 @@ "NotificationOptionCameraImageUploaded": "相機相片已上傳", "NotificationOptionInstallationFailed": "安裝失敗", "NotificationOptionNewLibraryContent": "已新增新內容", - "NotificationOptionPluginError": "外掛失敗", - "NotificationOptionPluginInstalled": "外掛已安裝", - "NotificationOptionPluginUninstalled": "外掛已移除", - "NotificationOptionPluginUpdateInstalled": "已更新外掛", + "NotificationOptionPluginError": "擴充元件安裝失敗", + "NotificationOptionPluginInstalled": "擴充元件已安裝", + "NotificationOptionPluginUninstalled": "擴充元件已移除", + "NotificationOptionPluginUpdateInstalled": "已更新擴充元件", "NotificationOptionServerRestartRequired": "伺服器需要重新啟動", "NotificationOptionTaskFailed": "排程任務失敗", "NotificationOptionUserLockedOut": "使用者已鎖定", From 6813efd1a2cc2a43f123f938adcbf39a687ffa71 Mon Sep 17 00:00:00 2001 From: Johan Date: Mon, 10 Feb 2020 19:52:09 +0000 Subject: [PATCH 20/22] Translated using Weblate (Finnish) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/fi/ --- .../Localization/Core/fi.json | 68 ++++++++++++++++--- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/Emby.Server.Implementations/Localization/Core/fi.json b/Emby.Server.Implementations/Localization/Core/fi.json index 1bd906b8e3..7d6ca0d799 100644 --- a/Emby.Server.Implementations/Localization/Core/fi.json +++ b/Emby.Server.Implementations/Localization/Core/fi.json @@ -1,6 +1,6 @@ { - "HeaderLiveTV": "Netti-TV", - "NewVersionIsAvailable": "Uusi versio Jellyfin palvelimesta on ladattavissa", + "HeaderLiveTV": "TV-lähetykset", + "NewVersionIsAvailable": "Uusi versio Jellyfin palvelimesta on ladattavissa.", "NameSeasonUnknown": "Tuntematon Kausi", "NameSeasonNumber": "Kausi {0}", "NameInstallFailed": "{0} asennus epäonnistui", @@ -8,9 +8,9 @@ "Music": "Musiikki", "Movies": "Elokuvat", "MixedContent": "Sekoitettu sisältö", - "MessageServerConfigurationUpdated": "Palvelimen konfiguraatio on päivitetty", - "MessageNamedServerConfigurationUpdatedWithValue": "Palvelimen konfiguraatio-osa {0} on päivitetty", - "MessageApplicationUpdatedTo": "Jellyfin palvelin on päivitetty {0}", + "MessageServerConfigurationUpdated": "Palvelimen asetukset on päivitetty", + "MessageNamedServerConfigurationUpdatedWithValue": "Palvelimen asetusryhmä {0} on päivitetty", + "MessageApplicationUpdatedTo": "Jellyfin palvelin on päivitetty versioon {0}", "MessageApplicationUpdated": "Jellyfin palvelin on päivitetty", "Latest": "Viimeisin", "LabelRunningTimeValue": "Kesto: {0}", @@ -24,12 +24,12 @@ "HeaderFavoriteSongs": "Lempikappaleet", "HeaderFavoriteShows": "Lempisarjat", "HeaderFavoriteEpisodes": "Lempijaksot", - "HeaderCameraUploads": "Kamera lataukset", + "HeaderCameraUploads": "Kamerasta lähetetyt", "HeaderFavoriteArtists": "Lempiartistit", "HeaderFavoriteAlbums": "Lempialbumit", - "HeaderContinueWatching": "Jatka Katsomista", - "HeaderAlbumArtists": "Albumiartistit", - "Genres": "Lajipiiri", + "HeaderContinueWatching": "Jatka katsomista", + "HeaderAlbumArtists": "Albumin artistit", + "Genres": "Tyylilaji", "Folders": "Kansiot", "Favorites": "Suosikit", "FailedLoginAttemptWithUserName": "Epäonnistunut kirjautumisyritys kohteesta {0}", @@ -44,5 +44,53 @@ "Artists": "Artistit", "Application": "Sovellus", "AppDeviceValues": "Sovellus: {0}, Laite: {1}", - "Albums": "Albumit" + "Albums": "Albumit", + "User": "Käyttäjä", + "System": "Järjestelmä", + "ScheduledTaskFailedWithName": "{0} epäonnistui", + "PluginUpdatedWithName": "{0} päivitetty", + "PluginInstalledWithName": "{0} asennettu", + "Photos": "Kuvat", + "ScheduledTaskStartedWithName": "{0} aloitettu", + "PluginUninstalledWithName": "{0} poistettu", + "Playlists": "Soittolistat", + "VersionNumber": "Versio {0}", + "ValueSpecialEpisodeName": "Erikois - {0}", + "ValueHasBeenAddedToLibrary": "{0} lisättiin mediakirjastoon", + "UserStoppedPlayingItemWithValues": "{0} toistaminen valmistui {1} laitteella {2}", + "UserStartedPlayingItemWithValues": "{0} toistaa {1} laitteella {2}", + "UserPolicyUpdatedWithName": "Käyttöoikeudet päivitetty käyttäjälle {0}", + "UserPasswordChangedWithName": "Salasana vaihdettu käyttäjälle {0}", + "UserOnlineFromDevice": "{0} on paikalla osoitteesta {1}", + "UserOfflineFromDevice": "{0} yhteys katkaistu {1}", + "UserLockedOutWithName": "Käyttäjä {0} kirjautui ulos", + "UserDownloadingItemWithValues": "{0} latautumassa {1}", + "UserDeletedWithName": "Poistettiin käyttäjä {0}", + "UserCreatedWithName": "Luotiin käyttäjä {0}", + "TvShows": "TV-Ohjelmat", + "Sync": "Synkronoi", + "SubtitlesDownloadedForItem": "Tekstitys ladattu {0}", + "SubtitleDownloadFailureFromForItem": "Tekstityksen lataaminen epäonnistui {0} - {1}", + "StartupEmbyServerIsLoading": "Jellyfin palvelin latautuu. Kokeile hetken kuluttua uudelleen.", + "Songs": "Kappaleet", + "Shows": "Ohjelmat", + "ServerNameNeedsToBeRestarted": "{0} vaatii uudelleenkäynnistyksen", + "ProviderValue": "Palveluntarjoaja: {0}", + "Plugin": "Laajennus", + "NotificationOptionVideoPlaybackStopped": "Videon toistaminen pysäytetty", + "NotificationOptionVideoPlayback": "Videon toistaminen aloitettu", + "NotificationOptionUserLockedOut": "Käyttäjä kirjautui ulos", + "NotificationOptionTaskFailed": "Ajastetun tehtävän ongelma", + "NotificationOptionServerRestartRequired": "Palvelimen uudelleenkäynnistys vaaditaan", + "NotificationOptionPluginUpdateInstalled": "Laajennuksen päivitys asennettu", + "NotificationOptionPluginUninstalled": "Laajennus poistettu", + "NotificationOptionPluginInstalled": "Laajennus asennettu", + "NotificationOptionPluginError": "Ongelma laajennuksessa", + "NotificationOptionNewLibraryContent": "Uusi sisältö lisätty", + "NotificationOptionInstallationFailed": "Asennusvirhe", + "NotificationOptionCameraImageUploaded": "Kameran kuva lisätty", + "NotificationOptionAudioPlaybackStopped": "Äänen toistaminen pysäytetty", + "NotificationOptionAudioPlayback": "Äänen toistaminen aloitettu", + "NotificationOptionApplicationUpdateInstalled": "Ohjelmistopäivitys asennettu", + "NotificationOptionApplicationUpdateAvailable": "Ohjelmistopäivitys saatavilla" } From 33761c3658c7c2867cb55fb1c96d441c24e81f89 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Wed, 12 Feb 2020 14:08:06 +0100 Subject: [PATCH 21/22] Use "implement" instead of "apply" when referring to an interface --- MediaBrowser.Controller/Plugins/IServerEntryPoint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs b/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs index 5b3173ef6a..1e8654c4dc 100644 --- a/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs +++ b/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs @@ -6,7 +6,7 @@ namespace MediaBrowser.Controller.Plugins /// /// Represents an entry point for a module in the application. This interface is scanned for automatically and /// provides a hook to initialize the module at application start. - /// The entry point can additionally be flagged as a pre-startup task by applying the + /// The entry point can additionally be flagged as a pre-startup task by implementing the /// interface. /// public interface IServerEntryPoint : IDisposable From 8ffb073ccb7f6661c04e64836d90d86228937962 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Wed, 12 Feb 2020 20:05:26 +0100 Subject: [PATCH 22/22] Enable documentation warnings for fully documented files --- MediaBrowser.Common/Configuration/IConfigurationFactory.cs | 3 --- MediaBrowser.Model/Services/ApiMemberAttribute.cs | 3 --- 2 files changed, 6 deletions(-) diff --git a/MediaBrowser.Common/Configuration/IConfigurationFactory.cs b/MediaBrowser.Common/Configuration/IConfigurationFactory.cs index 2b4b9b082c..07ca2b58ba 100644 --- a/MediaBrowser.Common/Configuration/IConfigurationFactory.cs +++ b/MediaBrowser.Common/Configuration/IConfigurationFactory.cs @@ -1,6 +1,3 @@ -#pragma warning disable CS1591 -#pragma warning disable SA1600 - using System; using System.Collections.Generic; diff --git a/MediaBrowser.Model/Services/ApiMemberAttribute.cs b/MediaBrowser.Model/Services/ApiMemberAttribute.cs index 06a6713ee3..8e50836f4d 100644 --- a/MediaBrowser.Model/Services/ApiMemberAttribute.cs +++ b/MediaBrowser.Model/Services/ApiMemberAttribute.cs @@ -1,6 +1,3 @@ -#pragma warning disable CS1591 -#pragma warning disable SA1600 - using System; namespace MediaBrowser.Model.Services