|
@@ -13,8 +13,6 @@ using MediaBrowser.Controller.Entities.TV;
|
|
|
using MediaBrowser.Controller.Providers;
|
|
|
using MediaBrowser.Model.Entities;
|
|
|
using MediaBrowser.Model.Extensions;
|
|
|
-using MediaBrowser.Model.IO;
|
|
|
-using MediaBrowser.Model.Xml;
|
|
|
using MediaBrowser.XbmcMetadata.Configuration;
|
|
|
using MediaBrowser.XbmcMetadata.Savers;
|
|
|
using Microsoft.Extensions.Logging;
|
|
@@ -28,9 +26,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|
|
/// The logger
|
|
|
/// </summary>
|
|
|
protected ILogger Logger { get; private set; }
|
|
|
- protected IFileSystem FileSystem { get; private set; }
|
|
|
protected IProviderManager ProviderManager { get; private set; }
|
|
|
- protected IXmlReaderSettingsFactory XmlReaderSettingsFactory { get; private set; }
|
|
|
|
|
|
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
|
|
private readonly IConfigurationManager _config;
|
|
@@ -39,13 +35,11 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|
|
/// <summary>
|
|
|
/// Initializes a new instance of the <see cref="BaseNfoParser{T}" /> class.
|
|
|
/// </summary>
|
|
|
- public BaseNfoParser(ILogger logger, IConfigurationManager config, IProviderManager providerManager, IFileSystem fileSystem, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
|
|
|
+ public BaseNfoParser(ILogger logger, IConfigurationManager config, IProviderManager providerManager)
|
|
|
{
|
|
|
Logger = logger;
|
|
|
_config = config;
|
|
|
ProviderManager = providerManager;
|
|
|
- FileSystem = fileSystem;
|
|
|
- XmlReaderSettingsFactory = xmlReaderSettingsFactory;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -68,12 +62,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|
|
throw new ArgumentException("The metadata file was empty or null.", nameof(metadataFile));
|
|
|
}
|
|
|
|
|
|
- var settings = XmlReaderSettingsFactory.Create(false);
|
|
|
-
|
|
|
- settings.CheckCharacters = false;
|
|
|
- settings.IgnoreProcessingInstructions = true;
|
|
|
- settings.IgnoreComments = true;
|
|
|
-
|
|
|
_validProviderIds = _validProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
var idInfos = ProviderManager.GetExternalIdInfos(item.Item);
|
|
@@ -92,7 +80,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|
|
_validProviderIds.Add("tmdbcolid", "TmdbCollection");
|
|
|
_validProviderIds.Add("imdb_id", "Imdb");
|
|
|
|
|
|
- Fetch(item, metadataFile, settings, cancellationToken);
|
|
|
+ Fetch(item, metadataFile, GetXmlReaderSettings(), cancellationToken);
|
|
|
}
|
|
|
|
|
|
protected virtual bool SupportsUrlAfterClosingXmlTag => false;
|
|
@@ -109,31 +97,26 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|
|
if (!SupportsUrlAfterClosingXmlTag)
|
|
|
{
|
|
|
using (var fileStream = File.OpenRead(metadataFile))
|
|
|
+ using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
|
|
+ using (var reader = XmlReader.Create(streamReader, settings))
|
|
|
{
|
|
|
- using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
|
|
- {
|
|
|
- // Use XmlReader for best performance
|
|
|
- using (var reader = XmlReader.Create(streamReader, settings))
|
|
|
- {
|
|
|
- item.ResetPeople();
|
|
|
+ item.ResetPeople();
|
|
|
|
|
|
- reader.MoveToContent();
|
|
|
- reader.Read();
|
|
|
+ reader.MoveToContent();
|
|
|
+ reader.Read();
|
|
|
|
|
|
- // Loop through each element
|
|
|
- while (!reader.EOF && reader.ReadState == ReadState.Interactive)
|
|
|
- {
|
|
|
- cancellationToken.ThrowIfCancellationRequested();
|
|
|
+ // Loop through each element
|
|
|
+ while (!reader.EOF && reader.ReadState == ReadState.Interactive)
|
|
|
+ {
|
|
|
+ cancellationToken.ThrowIfCancellationRequested();
|
|
|
|
|
|
- if (reader.NodeType == XmlNodeType.Element)
|
|
|
- {
|
|
|
- FetchDataFromXmlNode(reader, item);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- reader.Read();
|
|
|
- }
|
|
|
- }
|
|
|
+ if (reader.NodeType == XmlNodeType.Element)
|
|
|
+ {
|
|
|
+ FetchDataFromXmlNode(reader, item);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ reader.Read();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -141,81 +124,76 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|
|
}
|
|
|
|
|
|
using (var fileStream = File.OpenRead(metadataFile))
|
|
|
+ using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
|
|
{
|
|
|
- using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
|
|
- {
|
|
|
- item.ResetPeople();
|
|
|
-
|
|
|
- // Need to handle a url after the xml data
|
|
|
- // http://kodi.wiki/view/NFO_files/movies
|
|
|
+ item.ResetPeople();
|
|
|
|
|
|
- var xml = streamReader.ReadToEnd();
|
|
|
+ // Need to handle a url after the xml data
|
|
|
+ // http://kodi.wiki/view/NFO_files/movies
|
|
|
|
|
|
- // Find last closing Tag
|
|
|
- // Need to do this in two steps to account for random > characters after the closing xml
|
|
|
- var index = xml.LastIndexOf(@"</", StringComparison.Ordinal);
|
|
|
+ var xml = streamReader.ReadToEnd();
|
|
|
|
|
|
- // If closing tag exists, move to end of Tag
|
|
|
- if (index != -1)
|
|
|
- {
|
|
|
- index = xml.IndexOf('>', index);
|
|
|
- }
|
|
|
+ // Find last closing Tag
|
|
|
+ // Need to do this in two steps to account for random > characters after the closing xml
|
|
|
+ var index = xml.LastIndexOf(@"</", StringComparison.Ordinal);
|
|
|
|
|
|
- if (index != -1)
|
|
|
- {
|
|
|
- var endingXml = xml.Substring(index);
|
|
|
+ // If closing tag exists, move to end of Tag
|
|
|
+ if (index != -1)
|
|
|
+ {
|
|
|
+ index = xml.IndexOf('>', index);
|
|
|
+ }
|
|
|
|
|
|
- ParseProviderLinks(item.Item, endingXml);
|
|
|
+ if (index != -1)
|
|
|
+ {
|
|
|
+ var endingXml = xml.Substring(index);
|
|
|
|
|
|
- // If the file is just an imdb url, don't go any further
|
|
|
- if (index == 0)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
+ ParseProviderLinks(item.Item, endingXml);
|
|
|
|
|
|
- xml = xml.Substring(0, index + 1);
|
|
|
- }
|
|
|
- else
|
|
|
+ // If the file is just an imdb url, don't go any further
|
|
|
+ if (index == 0)
|
|
|
{
|
|
|
- // If the file is just an Imdb url, handle that
|
|
|
-
|
|
|
- ParseProviderLinks(item.Item, xml);
|
|
|
-
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // These are not going to be valid xml so no sense in causing the provider to fail and spamming the log with exceptions
|
|
|
- try
|
|
|
+ xml = xml.Substring(0, index + 1);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // If the file is just an Imdb url, handle that
|
|
|
+
|
|
|
+ ParseProviderLinks(item.Item, xml);
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // These are not going to be valid xml so no sense in causing the provider to fail and spamming the log with exceptions
|
|
|
+ try
|
|
|
+ {
|
|
|
+ using (var stringReader = new StringReader(xml))
|
|
|
+ using (var reader = XmlReader.Create(stringReader, settings))
|
|
|
{
|
|
|
- using (var stringReader = new StringReader(xml))
|
|
|
+ reader.MoveToContent();
|
|
|
+ reader.Read();
|
|
|
+
|
|
|
+ // Loop through each element
|
|
|
+ while (!reader.EOF && reader.ReadState == ReadState.Interactive)
|
|
|
{
|
|
|
- // Use XmlReader for best performance
|
|
|
- using (var reader = XmlReader.Create(stringReader, settings))
|
|
|
+ cancellationToken.ThrowIfCancellationRequested();
|
|
|
+
|
|
|
+ if (reader.NodeType == XmlNodeType.Element)
|
|
|
+ {
|
|
|
+ FetchDataFromXmlNode(reader, item);
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- reader.MoveToContent();
|
|
|
reader.Read();
|
|
|
-
|
|
|
- // Loop through each element
|
|
|
- while (!reader.EOF && reader.ReadState == ReadState.Interactive)
|
|
|
- {
|
|
|
- cancellationToken.ThrowIfCancellationRequested();
|
|
|
-
|
|
|
- if (reader.NodeType == XmlNodeType.Element)
|
|
|
- {
|
|
|
- FetchDataFromXmlNode(reader, item);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- reader.Read();
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- catch (XmlException)
|
|
|
- {
|
|
|
+ }
|
|
|
+ catch (XmlException)
|
|
|
+ {
|
|
|
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -920,6 +898,15 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+ internal XmlReaderSettings GetXmlReaderSettings()
|
|
|
+ => new XmlReaderSettings()
|
|
|
+ {
|
|
|
+ ValidationType = ValidationType.None,
|
|
|
+ CheckCharacters = false,
|
|
|
+ IgnoreProcessingInstructions = true,
|
|
|
+ IgnoreComments = true
|
|
|
+ };
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Used to split names of comma or pipe delimeted genres and people
|
|
|
/// </summary>
|
|
@@ -935,19 +922,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|
|
|
|
|
value = value.Trim().Trim(separator);
|
|
|
|
|
|
- return string.IsNullOrWhiteSpace(value) ? Array.Empty<string>() : Split(value, separator, StringSplitOptions.RemoveEmptyEntries);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Provides an additional overload for string.split
|
|
|
- /// </summary>
|
|
|
- /// <param name="val">The val.</param>
|
|
|
- /// <param name="separators">The separators.</param>
|
|
|
- /// <param name="options">The options.</param>
|
|
|
- /// <returns>System.String[][].</returns>
|
|
|
- private string[] Split(string val, char[] separators, StringSplitOptions options)
|
|
|
- {
|
|
|
- return val.Split(separators, options);
|
|
|
+ return string.IsNullOrWhiteSpace(value) ? Array.Empty<string>() : value.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
|
|
}
|
|
|
}
|
|
|
}
|