diff --git a/MediaBrowser.Controller/Extensions/XmlReaderExtensions.cs b/MediaBrowser.Controller/Extensions/XmlReaderExtensions.cs index cd7db91dd4..8e4b7c8594 100644 --- a/MediaBrowser.Controller/Extensions/XmlReaderExtensions.cs +++ b/MediaBrowser.Controller/Extensions/XmlReaderExtensions.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Xml; using Jellyfin.Data.Enums; using MediaBrowser.Controller.Entities; @@ -104,4 +106,40 @@ public static class XmlReaderExtensions ImageUrl = imageUrl }; } + + /// + /// Used to split names of comma or pipe delimited genres and people. + /// + /// The . + /// IEnumerable{System.String}. + public static IEnumerable GetStringArray(this XmlReader reader) + { + ArgumentNullException.ThrowIfNull(reader); + var value = reader.ReadElementContentAsString(); + + // Only split by comma if there is no pipe in the string + // We have to be careful to not split names like Matthew, Jr. + var separator = !value.Contains('|', StringComparison.Ordinal) + && !value.Contains(';', StringComparison.Ordinal) + ? new[] { ',' } + : new[] { '|', ';' }; + + foreach (var part in value.Trim().Trim(separator).Split(separator)) + { + if (!string.IsNullOrWhiteSpace(part)) + { + yield return part.Trim(); + } + } + } + + /// + /// Parses a array from the xml node. + /// + /// The . + /// The . + /// The . + public static IEnumerable GetPersonArray(this XmlReader reader, PersonKind personKind) + => reader.GetStringArray() + .Select(part => new PersonInfo { Name = part, Type = personKind }); } diff --git a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs index df4d40a100..d62862be40 100644 --- a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs @@ -354,93 +354,40 @@ namespace MediaBrowser.LocalMetadata.Parsers } case "Network": - { - foreach (var name in SplitNames(reader.ReadElementContentAsString())) + foreach (var name in reader.GetStringArray()) { - if (string.IsNullOrWhiteSpace(name)) - { - continue; - } - item.AddStudio(name); } break; - } - case "Director": - { - foreach (var p in SplitNames(reader.ReadElementContentAsString()).Select(v => new PersonInfo { Name = v.Trim(), Type = PersonKind.Director })) + foreach (var director in reader.GetPersonArray(PersonKind.Director)) { - if (string.IsNullOrWhiteSpace(p.Name)) - { - continue; - } - - itemResult.AddPerson(p); + itemResult.AddPerson(director); } break; - } - case "Writer": - { - foreach (var p in SplitNames(reader.ReadElementContentAsString()).Select(v => new PersonInfo { Name = v.Trim(), Type = PersonKind.Writer })) + foreach (var writer in reader.GetPersonArray(PersonKind.Writer)) { - if (string.IsNullOrWhiteSpace(p.Name)) - { - continue; - } - - itemResult.AddPerson(p); + itemResult.AddPerson(writer); } break; - } - case "Actors": - { - var actors = reader.ReadInnerXml(); - - if (actors.Contains('<', StringComparison.Ordinal)) + foreach (var actor in reader.GetPersonArray(PersonKind.Actor)) { - // This is one of the mis-named "Actors" full nodes created by MB2 - // Create a reader and pass it to the persons node processor - using var xmlReader = XmlReader.Create(new StringReader($"{actors}")); - FetchDataFromPersonsNode(xmlReader, itemResult); - } - else - { - // Old-style piped string - foreach (var p in SplitNames(actors).Select(v => new PersonInfo { Name = v.Trim(), Type = PersonKind.Actor })) - { - if (string.IsNullOrWhiteSpace(p.Name)) - { - continue; - } - - itemResult.AddPerson(p); - } + itemResult.AddPerson(actor); } break; - } - case "GuestStars": - { - foreach (var p in SplitNames(reader.ReadElementContentAsString()).Select(v => new PersonInfo { Name = v.Trim(), Type = PersonKind.GuestStar })) + foreach (var guestStar in reader.GetPersonArray(PersonKind.GuestStar)) { - if (string.IsNullOrWhiteSpace(p.Name)) - { - continue; - } - - itemResult.AddPerson(p); + itemResult.AddPerson(guestStar); } break; - } - case "Trailer": { var val = reader.ReadElementContentAsString(); @@ -1129,34 +1076,5 @@ namespace MediaBrowser.LocalMetadata.Parsers return null; } - - /// - /// Used to split names of comma or pipe delimited genres and people. - /// - /// The value. - /// IEnumerable{System.String}. - private IEnumerable SplitNames(string value) - { - // Only split by comma if there is no pipe in the string - // We have to be careful to not split names like Matthew, Jr. - var separator = !value.Contains('|', StringComparison.Ordinal) - && !value.Contains(';', StringComparison.Ordinal) ? new[] { ',' } : new[] { '|', ';' }; - - value = value.Trim().Trim(separator); - - return string.IsNullOrWhiteSpace(value) ? Array.Empty() : Split(value, separator, StringSplitOptions.RemoveEmptyEntries); - } - - /// - /// Provides an additional overload for string.split. - /// - /// The val. - /// The separators. - /// The options. - /// System.String[][]. - private string[] Split(string val, char[] separators, StringSplitOptions options) - { - return val.Split(separators, options); - } } } diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index e11378c786..797ce59e05 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -527,21 +527,12 @@ namespace MediaBrowser.XbmcMetadata.Parsers } case "director": + foreach (var director in reader.GetPersonArray(PersonKind.Director)) { - var val = reader.ReadElementContentAsString(); - foreach (var p in SplitNames(val).Select(v => new PersonInfo { Name = v.Trim(), Type = PersonKind.Director })) - { - if (string.IsNullOrWhiteSpace(p.Name)) - { - continue; - } - - itemResult.AddPerson(p); - } - - break; + itemResult.AddPerson(director); } + break; case "credits": { var val = reader.ReadElementContentAsString(); @@ -566,21 +557,12 @@ namespace MediaBrowser.XbmcMetadata.Parsers } case "writer": + foreach (var writer in reader.GetPersonArray(PersonKind.Writer)) { - var val = reader.ReadElementContentAsString(); - foreach (var p in SplitNames(val).Select(v => new PersonInfo { Name = v.Trim(), Type = PersonKind.Writer })) - { - if (string.IsNullOrWhiteSpace(p.Name)) - { - continue; - } - - itemResult.AddPerson(p); - } - - break; + itemResult.AddPerson(writer); } + break; case "actor": var person = reader.GetPersonFromXmlNode(); if (person is not null) @@ -1192,24 +1174,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers IgnoreComments = true }; - /// - /// Used to split names of comma or pipe delimited genres and people. - /// - /// The value. - /// IEnumerable{System.String}. - private IEnumerable SplitNames(string value) - { - // Only split by comma if there is no pipe in the string - // We have to be careful to not split names like Matthew, Jr. - var separator = !value.Contains('|', StringComparison.Ordinal) && !value.Contains(';', StringComparison.Ordinal) - ? new[] { ',' } - : new[] { '|', ';' }; - - value = value.Trim().Trim(separator); - - return string.IsNullOrWhiteSpace(value) ? Array.Empty() : value.Split(separator, StringSplitOptions.RemoveEmptyEntries); - } - /// /// Parses the from the NFO aspect property. ///