From bdca4ed322a6eaa1fa1810e3187aa7948a574c60 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Fri, 6 Oct 2023 12:46:35 -0400 Subject: [PATCH] Add XmlReader.GetPersonFromXmlNode --- .../Extensions/XmlReaderExtensions.cs | 107 ++++++++++++++++ .../Parsers/BaseItemXmlParser.cs | 100 +-------------- .../Parsers/BaseNfoParser.cs | 119 +----------------- 3 files changed, 116 insertions(+), 210 deletions(-) create mode 100644 MediaBrowser.Controller/Extensions/XmlReaderExtensions.cs diff --git a/MediaBrowser.Controller/Extensions/XmlReaderExtensions.cs b/MediaBrowser.Controller/Extensions/XmlReaderExtensions.cs new file mode 100644 index 0000000000..cd7db91dd4 --- /dev/null +++ b/MediaBrowser.Controller/Extensions/XmlReaderExtensions.cs @@ -0,0 +1,107 @@ +using System; +using System.Globalization; +using System.Xml; +using Jellyfin.Data.Enums; +using MediaBrowser.Controller.Entities; + +namespace MediaBrowser.Controller.Extensions; + +/// +/// Provides extension methods for to parse 's. +/// +public static class XmlReaderExtensions +{ + /// + /// Parses a from the xml node. + /// + /// The . + /// A , or null if none is found. + public static PersonInfo? GetPersonFromXmlNode(this XmlReader reader) + { + ArgumentNullException.ThrowIfNull(reader); + + if (reader.IsEmptyElement) + { + reader.Read(); + return null; + } + + var name = string.Empty; + var type = PersonKind.Actor; // If type is not specified assume actor + var role = string.Empty; + int? sortOrder = null; + string? imageUrl = null; + + using var subtree = reader.ReadSubtree(); + subtree.MoveToContent(); + subtree.Read(); + + while (subtree is { EOF: false, ReadState: ReadState.Interactive }) + { + if (subtree.NodeType != XmlNodeType.Element) + { + subtree.Read(); + continue; + } + + switch (subtree.Name) + { + case "name": + case "Name": + name = subtree.ReadElementContentAsString(); + break; + case "role": + case "Role": + var roleValue = subtree.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(roleValue)) + { + role = roleValue; + } + + break; + case "type": + case "Type": + Enum.TryParse(subtree.ReadElementContentAsString(), true, out type); + break; + case "order": + case "sortorder": + case "SortOrder": + if (int.TryParse( + subtree.ReadElementContentAsString(), + NumberStyles.Integer, + CultureInfo.InvariantCulture, + out var intVal)) + { + sortOrder = intVal; + } + + break; + case "thumb": + var thumb = subtree.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(thumb)) + { + imageUrl = thumb; + } + + break; + default: + subtree.Skip(); + break; + } + } + + if (string.IsNullOrWhiteSpace(name)) + { + return null; + } + + return new PersonInfo + { + Name = name.Trim(), + Role = role, + Type = type, + SortOrder = sortOrder, + ImageUrl = imageUrl + }; + } +} diff --git a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs index cb369d8377..df4d40a100 100644 --- a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs @@ -9,6 +9,7 @@ using System.Xml; using Jellyfin.Data.Enums; using Jellyfin.Extensions; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Extensions; using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; @@ -929,29 +930,13 @@ namespace MediaBrowser.LocalMetadata.Parsers { case "Person": case "Actor": - { - if (reader.IsEmptyElement) + var person = reader.GetPersonFromXmlNode(); + if (person is not null) { - reader.Read(); - continue; - } - - using (var subtree = reader.ReadSubtree()) - { - foreach (var person in GetPersonsFromXmlNode(subtree)) - { - if (string.IsNullOrWhiteSpace(person.Name)) - { - continue; - } - - item.AddPerson(person); - } + item.AddPerson(person); } break; - } - default: reader.Skip(); break; @@ -1041,83 +1026,6 @@ namespace MediaBrowser.LocalMetadata.Parsers } } - /// - /// Gets the persons from XML node. - /// - /// The reader. - /// IEnumerable{PersonInfo}. - private IEnumerable GetPersonsFromXmlNode(XmlReader reader) - { - var name = string.Empty; - var type = PersonKind.Actor; // If type is not specified assume actor - var role = string.Empty; - int? sortOrder = null; - - reader.MoveToContent(); - reader.Read(); - - // Loop through each element - while (!reader.EOF && reader.ReadState == ReadState.Interactive) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Name": - name = reader.ReadElementContentAsString(); - break; - - case "Type": - { - var val = reader.ReadElementContentAsString(); - _ = Enum.TryParse(val, true, out type); - - break; - } - - case "Role": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - role = val; - } - - break; - } - - case "SortOrder": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - if (int.TryParse(val, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intVal)) - { - sortOrder = intVal; - } - } - - break; - } - - default: - reader.Skip(); - break; - } - } - else - { - reader.Read(); - } - } - - var personInfo = new PersonInfo { Name = name.Trim(), Role = role, Type = type, SortOrder = sortOrder }; - - return new[] { personInfo }; - } - /// /// Get linked child. /// diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index 5b68924acb..e11378c786 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -13,6 +13,7 @@ using MediaBrowser.Common.Providers; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Extensions; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; @@ -581,27 +582,13 @@ namespace MediaBrowser.XbmcMetadata.Parsers } case "actor": + var person = reader.GetPersonFromXmlNode(); + if (person is not null) { - if (!reader.IsEmptyElement) - { - using (var subtree = reader.ReadSubtree()) - { - var person = GetPersonFromXmlNode(subtree); - - if (!string.IsNullOrWhiteSpace(person.Name)) - { - itemResult.AddPerson(person); - } - } - } - else - { - reader.Read(); - } - - break; + itemResult.AddPerson(person); } + break; case "trailer": { var val = reader.ReadElementContentAsString(); @@ -1196,102 +1183,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers } } - /// - /// Gets the persons from a XML node. - /// - /// The . - /// IEnumerable{PersonInfo}. - private PersonInfo GetPersonFromXmlNode(XmlReader reader) - { - var name = string.Empty; - var type = PersonKind.Actor; // If type is not specified assume actor - var role = string.Empty; - int? sortOrder = null; - string? imageUrl = null; - - reader.MoveToContent(); - reader.Read(); - - // Loop through each element - while (!reader.EOF && reader.ReadState == ReadState.Interactive) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "name": - name = reader.ReadElementContentAsString(); - break; - - case "role": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - role = val; - } - - break; - } - - case "type": - { - var val = reader.ReadElementContentAsString(); - if (!Enum.TryParse(val, true, out type)) - { - type = PersonKind.Actor; - } - - break; - } - - case "order": - case "sortorder": - { - var val = reader.ReadElementContentAsString(); - - if (int.TryParse(val, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intVal)) - { - sortOrder = intVal; - } - - break; - } - - case "thumb": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - imageUrl = val; - } - - break; - } - - default: - reader.Skip(); - break; - } - } - else - { - reader.Read(); - } - } - - return new PersonInfo - { - Name = name.Trim(), - Role = role, - Type = type, - SortOrder = sortOrder, - ImageUrl = imageUrl - }; - } - internal XmlReaderSettings GetXmlReaderSettings() => new XmlReaderSettings() {