|
|
|
@ -35,12 +35,12 @@ namespace MediaBrowser.Providers.TV
|
|
|
|
|
private readonly IZipClient _zipClient;
|
|
|
|
|
private readonly IHttpClient _httpClient;
|
|
|
|
|
private readonly IFileSystem _fileSystem;
|
|
|
|
|
private readonly IXmlReaderSettingsFactory _xmlSettings;
|
|
|
|
|
private readonly IServerConfigurationManager _config;
|
|
|
|
|
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
|
|
|
|
private readonly ILogger _logger;
|
|
|
|
|
private readonly ILibraryManager _libraryManager;
|
|
|
|
|
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
|
|
|
|
private readonly IXmlReaderSettingsFactory _xmlSettings;
|
|
|
|
|
private readonly ILocalizationManager _localizationManager;
|
|
|
|
|
|
|
|
|
|
public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IMemoryStreamProvider memoryStreamProvider, IXmlReaderSettingsFactory xmlSettings, ILocalizationManager localizationManager)
|
|
|
|
@ -512,9 +512,11 @@ namespace MediaBrowser.Providers.TV
|
|
|
|
|
private async Task<IEnumerable<RemoteSearchResult>> FindSeriesInternal(string name, string language, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
var url = string.Format(SeriesSearchUrl, WebUtility.UrlEncode(name), NormalizeLanguage(language));
|
|
|
|
|
var doc = new XmlDocument();
|
|
|
|
|
var searchResults = new List<RemoteSearchResult>();
|
|
|
|
|
|
|
|
|
|
var comparableName = GetComparableName(name);
|
|
|
|
|
|
|
|
|
|
using (var results = await _httpClient.Get(new HttpRequestOptions
|
|
|
|
|
using (var stream = await _httpClient.Get(new HttpRequestOptions
|
|
|
|
|
{
|
|
|
|
|
Url = url,
|
|
|
|
|
ResourcePool = TvDbResourcePool,
|
|
|
|
@ -522,100 +524,170 @@ namespace MediaBrowser.Providers.TV
|
|
|
|
|
|
|
|
|
|
}).ConfigureAwait(false))
|
|
|
|
|
{
|
|
|
|
|
doc.Load(results);
|
|
|
|
|
}
|
|
|
|
|
var settings = _xmlSettings.Create(false);
|
|
|
|
|
|
|
|
|
|
var searchResults = new List<RemoteSearchResult>();
|
|
|
|
|
settings.CheckCharacters = false;
|
|
|
|
|
settings.IgnoreProcessingInstructions = true;
|
|
|
|
|
settings.IgnoreComments = true;
|
|
|
|
|
|
|
|
|
|
if (doc.HasChildNodes)
|
|
|
|
|
{
|
|
|
|
|
var nodes = doc.SelectNodes("//Series");
|
|
|
|
|
var comparableName = GetComparableName(name);
|
|
|
|
|
if (nodes != null)
|
|
|
|
|
using (var streamReader = new StreamReader(stream, Encoding.UTF8))
|
|
|
|
|
{
|
|
|
|
|
foreach (XmlNode node in nodes)
|
|
|
|
|
// Use XmlReader for best performance
|
|
|
|
|
using (var reader = XmlReader.Create(streamReader, settings))
|
|
|
|
|
{
|
|
|
|
|
var searchResult = new RemoteSearchResult
|
|
|
|
|
reader.MoveToContent();
|
|
|
|
|
|
|
|
|
|
// Loop through each element
|
|
|
|
|
while (reader.Read())
|
|
|
|
|
{
|
|
|
|
|
SearchProviderName = Name
|
|
|
|
|
};
|
|
|
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
|
|
|
|
|
|
|
|
var titles = new List<string>();
|
|
|
|
|
if (reader.NodeType == XmlNodeType.Element)
|
|
|
|
|
{
|
|
|
|
|
switch (reader.Name)
|
|
|
|
|
{
|
|
|
|
|
case "Series":
|
|
|
|
|
{
|
|
|
|
|
using (var subtree = reader.ReadSubtree())
|
|
|
|
|
{
|
|
|
|
|
var searchResult = GetSeriesSearchResultFromSubTree(subtree, comparableName);
|
|
|
|
|
if (searchResult != null)
|
|
|
|
|
{
|
|
|
|
|
searchResult.SearchProviderName = Name;
|
|
|
|
|
searchResults.Add(searchResult);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var nameNode = node.SelectSingleNode("./SeriesName");
|
|
|
|
|
if (nameNode != null)
|
|
|
|
|
{
|
|
|
|
|
titles.Add(GetComparableName(nameNode.InnerText));
|
|
|
|
|
default:
|
|
|
|
|
reader.Skip();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var aliasNode = node.SelectSingleNode("./AliasNames");
|
|
|
|
|
if (aliasNode != null)
|
|
|
|
|
{
|
|
|
|
|
var alias = aliasNode.InnerText.Split('|').Select(GetComparableName);
|
|
|
|
|
titles.AddRange(alias);
|
|
|
|
|
}
|
|
|
|
|
if (searchResults.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
_logger.Info("TVDb Provider - Could not find " + name + ". Check name on Thetvdb.org.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var imdbIdNode = node.SelectSingleNode("./IMDB_ID");
|
|
|
|
|
if (imdbIdNode != null)
|
|
|
|
|
{
|
|
|
|
|
var val = imdbIdNode.InnerText;
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(val))
|
|
|
|
|
return searchResults;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private RemoteSearchResult GetSeriesSearchResultFromSubTree(XmlReader reader, string comparableName)
|
|
|
|
|
{
|
|
|
|
|
var searchResult = new RemoteSearchResult
|
|
|
|
|
{
|
|
|
|
|
SearchProviderName = Name
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var titles = new List<string>();
|
|
|
|
|
string seriesId = null;
|
|
|
|
|
|
|
|
|
|
reader.MoveToContent();
|
|
|
|
|
|
|
|
|
|
while (reader.Read())
|
|
|
|
|
{
|
|
|
|
|
if (reader.NodeType == XmlNodeType.Element)
|
|
|
|
|
{
|
|
|
|
|
switch (reader.Name)
|
|
|
|
|
{
|
|
|
|
|
case "SeriesName":
|
|
|
|
|
{
|
|
|
|
|
searchResult.SetProviderId(MetadataProviders.Imdb, val);
|
|
|
|
|
var val = reader.ReadElementContentAsString();
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(val))
|
|
|
|
|
{
|
|
|
|
|
titles.Add(GetComparableName(val));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bannerNode = node.SelectSingleNode("./banner");
|
|
|
|
|
if (bannerNode != null)
|
|
|
|
|
{
|
|
|
|
|
var val = bannerNode.InnerText;
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(val))
|
|
|
|
|
case "AliasNames":
|
|
|
|
|
{
|
|
|
|
|
searchResult.ImageUrl = TVUtils.BannerUrl + val;
|
|
|
|
|
var val = reader.ReadElementContentAsString();
|
|
|
|
|
|
|
|
|
|
var alias = (val ?? string.Empty).Split(new [] { '|' }, StringSplitOptions.RemoveEmptyEntries).Select(GetComparableName);
|
|
|
|
|
titles.AddRange(alias);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var airDateNode = node.SelectSingleNode("./FirstAired");
|
|
|
|
|
if (airDateNode != null)
|
|
|
|
|
{
|
|
|
|
|
var val = airDateNode.InnerText;
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(val))
|
|
|
|
|
case "IMDB_ID":
|
|
|
|
|
{
|
|
|
|
|
DateTime date;
|
|
|
|
|
if (DateTime.TryParse(val, out date))
|
|
|
|
|
var val = reader.ReadElementContentAsString();
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(val))
|
|
|
|
|
{
|
|
|
|
|
searchResult.ProductionYear = date.Year;
|
|
|
|
|
searchResult.SetProviderId(MetadataProviders.Imdb, val);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var title in titles)
|
|
|
|
|
{
|
|
|
|
|
if (string.Equals(title, comparableName, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
case "banner":
|
|
|
|
|
{
|
|
|
|
|
var id = node.SelectSingleNode("./seriesid") ??
|
|
|
|
|
node.SelectSingleNode("./id");
|
|
|
|
|
var val = reader.ReadElementContentAsString();
|
|
|
|
|
|
|
|
|
|
if (id != null)
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(val))
|
|
|
|
|
{
|
|
|
|
|
searchResult.Name = title;
|
|
|
|
|
searchResult.SetProviderId(MetadataProviders.Tvdb, id.InnerText);
|
|
|
|
|
searchResults.Add(searchResult);
|
|
|
|
|
searchResult.ImageUrl = TVUtils.BannerUrl + val;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
_logger.Info("TVDb Provider - " + title + " did not match " + comparableName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case "FirstAired":
|
|
|
|
|
{
|
|
|
|
|
var val = reader.ReadElementContentAsString();
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(val))
|
|
|
|
|
{
|
|
|
|
|
DateTime date;
|
|
|
|
|
if (DateTime.TryParse(val, out date))
|
|
|
|
|
{
|
|
|
|
|
searchResult.ProductionYear = date.Year;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case "id":
|
|
|
|
|
case "seriesid":
|
|
|
|
|
{
|
|
|
|
|
var val = reader.ReadElementContentAsString();
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(val))
|
|
|
|
|
{
|
|
|
|
|
seriesId = val;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
reader.Skip();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (searchResults.Count == 0)
|
|
|
|
|
foreach (var title in titles)
|
|
|
|
|
{
|
|
|
|
|
_logger.Info("TVDb Provider - Could not find " + name + ". Check name on Thetvdb.org.");
|
|
|
|
|
if (string.Equals(title, comparableName, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(seriesId))
|
|
|
|
|
{
|
|
|
|
|
searchResult.Name = title;
|
|
|
|
|
searchResult.SetProviderId(MetadataProviders.Tvdb, seriesId);
|
|
|
|
|
return searchResult;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
_logger.Info("TVDb Provider - " + title + " did not match " + comparableName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return searchResults;
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|