mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-28 02:21:00 +01:00
make provider project portabl
This commit is contained in:
@@ -13,8 +13,9 @@
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<ProductVersion>10.0.0</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -41,13 +42,6 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\SharedVersion.cs">
|
||||
<Link>Properties\SharedVersion.cs</Link>
|
||||
@@ -171,7 +165,7 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="EmitMSBuildWarning" BeforeTargets="Build">
|
||||
<Warning Text="Packages containing MSBuild targets and props files cannot be fully installed in projects targeting multiple frameworks. The MSBuild targets and props files have been ignored." />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -15,6 +15,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Model.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
{
|
||||
@@ -26,15 +27,17 @@ namespace MediaBrowser.Providers.Music
|
||||
private readonly IApplicationHost _appHost;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IJsonSerializer _json;
|
||||
private readonly IXmlReaderSettingsFactory _xmlSettings;
|
||||
|
||||
public static string MusicBrainzBaseUrl = "https://www.musicbrainz.org";
|
||||
|
||||
public MusicBrainzAlbumProvider(IHttpClient httpClient, IApplicationHost appHost, ILogger logger, IJsonSerializer json)
|
||||
public MusicBrainzAlbumProvider(IHttpClient httpClient, IApplicationHost appHost, ILogger logger, IJsonSerializer json, IXmlReaderSettingsFactory xmlSettings)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_appHost = appHost;
|
||||
_logger = logger;
|
||||
_json = json;
|
||||
_xmlSettings = xmlSettings;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
@@ -71,17 +74,18 @@ namespace MediaBrowser.Providers.Music
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
var doc = await GetMusicBrainzResponse(url, isNameSearch, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return GetResultsFromResponse(doc);
|
||||
using (var reader = await GetMusicBrainzResponse(url, isNameSearch, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
return GetResultsFromResponse(reader);
|
||||
}
|
||||
}
|
||||
|
||||
return new List<RemoteSearchResult>();
|
||||
}
|
||||
|
||||
private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc)
|
||||
private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlReader reader)
|
||||
{
|
||||
return ReleaseResult.Parse(doc).Select(i =>
|
||||
return ReleaseResult.Parse(reader).Select(i =>
|
||||
{
|
||||
var result = new RemoteSearchResult
|
||||
{
|
||||
@@ -191,9 +195,10 @@ namespace MediaBrowser.Providers.Music
|
||||
WebUtility.UrlEncode(albumName),
|
||||
artistId);
|
||||
|
||||
var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return ReleaseResult.Parse(doc, 1).FirstOrDefault();
|
||||
using (var reader = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
return ReleaseResult.Parse(reader, 1).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ReleaseResult> GetReleaseResultByArtistName(string albumName, string artistName, CancellationToken cancellationToken)
|
||||
@@ -202,9 +207,10 @@ namespace MediaBrowser.Providers.Music
|
||||
WebUtility.UrlEncode(albumName),
|
||||
WebUtility.UrlEncode(artistName));
|
||||
|
||||
var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return ReleaseResult.Parse(doc, 1).FirstOrDefault();
|
||||
using (var reader = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
return ReleaseResult.Parse(reader, 1).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private class ReleaseResult
|
||||
@@ -215,108 +221,114 @@ namespace MediaBrowser.Providers.Music
|
||||
public string Overview;
|
||||
public int? Year;
|
||||
|
||||
public static List<ReleaseResult> Parse(XmlDocument doc, int? limit = null)
|
||||
public static List<ReleaseResult> Parse(XmlReader reader, int? limit = null)
|
||||
{
|
||||
var docElem = doc.DocumentElement;
|
||||
var list = new List<ReleaseResult>();
|
||||
reader.MoveToContent();
|
||||
|
||||
if (docElem == null)
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
var releaseList = docElem.FirstChild;
|
||||
if (releaseList == null)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
var nodes = releaseList.ChildNodes;
|
||||
|
||||
if (nodes != null)
|
||||
{
|
||||
foreach (var node in nodes.Cast<XmlNode>())
|
||||
switch (reader.Name)
|
||||
{
|
||||
if (string.Equals(node.Name, "release", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var releaseId = node.Attributes["id"].Value;
|
||||
var releaseGroupId = GetReleaseGroupIdFromReleaseNode(node);
|
||||
|
||||
list.Add(new ReleaseResult
|
||||
case "release-list":
|
||||
{
|
||||
ReleaseId = releaseId,
|
||||
ReleaseGroupId = releaseGroupId,
|
||||
Title = GetValueFromReleaseNode(node, "title"),
|
||||
Overview = GetValueFromReleaseNode(node, "annotation"),
|
||||
Year = GetYearFromReleaseNode(node, "date")
|
||||
});
|
||||
|
||||
if (limit.HasValue && list.Count >= limit.Value)
|
||||
using (var subReader = reader.ReadSubtree())
|
||||
{
|
||||
return ParseReleaseList(subReader);
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new List<ReleaseResult>();
|
||||
}
|
||||
|
||||
private static List<ReleaseResult> ParseReleaseList(XmlReader reader)
|
||||
{
|
||||
var list = new List<ReleaseResult>();
|
||||
|
||||
reader.MoveToContent();
|
||||
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "release":
|
||||
{
|
||||
var releaseId = reader.GetAttribute("id");
|
||||
|
||||
using (var subReader = reader.ReadSubtree())
|
||||
{
|
||||
var artist = ParseRelease(subReader, releaseId);
|
||||
list.Add(artist);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static int? GetYearFromReleaseNode(XmlNode node, string name)
|
||||
private static ReleaseResult ParseRelease(XmlReader reader, string releaseId)
|
||||
{
|
||||
var subNodes = node.ChildNodes;
|
||||
if (subNodes != null)
|
||||
var result = new ReleaseResult
|
||||
{
|
||||
foreach (var subNode in subNodes.Cast<XmlNode>())
|
||||
ReleaseId = releaseId
|
||||
};
|
||||
|
||||
reader.MoveToContent();
|
||||
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
if (string.Equals(subNode.Name, name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
DateTime date;
|
||||
if (DateTime.TryParse(subNode.InnerText, out date))
|
||||
case "title":
|
||||
{
|
||||
return date.Year;
|
||||
result.Title = reader.ReadElementContentAsString();
|
||||
break;
|
||||
}
|
||||
case "date":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
DateTime date;
|
||||
if (DateTime.TryParse(val, out date))
|
||||
{
|
||||
result.Year = date.Year;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "annotation":
|
||||
{
|
||||
result.Overview = reader.ReadElementContentAsString();
|
||||
break;
|
||||
}
|
||||
case "release-group":
|
||||
{
|
||||
result.ReleaseGroupId = reader.GetAttribute("id");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetValueFromReleaseNode(XmlNode node, string name)
|
||||
{
|
||||
var subNodes = node.ChildNodes;
|
||||
if (subNodes != null)
|
||||
{
|
||||
foreach (var subNode in subNodes.Cast<XmlNode>())
|
||||
{
|
||||
if (string.Equals(subNode.Name, name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return subNode.InnerText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetReleaseGroupIdFromReleaseNode(XmlNode node)
|
||||
{
|
||||
var subNodes = node.ChildNodes;
|
||||
if (subNodes != null)
|
||||
{
|
||||
foreach (var subNode in subNodes.Cast<XmlNode>())
|
||||
{
|
||||
if (string.Equals(subNode.Name, "release-group", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return subNode.Attributes["id"].Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,33 +342,54 @@ namespace MediaBrowser.Providers.Music
|
||||
{
|
||||
var url = string.Format("/ws/2/release-group/?query=reid:{0}", releaseEntryId);
|
||||
|
||||
var doc = await GetMusicBrainzResponse(url, false, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var docElem = doc.DocumentElement;
|
||||
|
||||
if (docElem == null)
|
||||
using (var reader = await GetMusicBrainzResponse(url, false, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
reader.MoveToContent();
|
||||
|
||||
var releaseList = docElem.FirstChild;
|
||||
if (releaseList == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var nodes = releaseList.ChildNodes;
|
||||
|
||||
if (nodes != null)
|
||||
{
|
||||
foreach (var node in nodes.Cast<XmlNode>())
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
if (string.Equals(node.Name, "release-group", StringComparison.OrdinalIgnoreCase))
|
||||
switch (reader.Name)
|
||||
{
|
||||
return node.Attributes["id"].Value;
|
||||
case "release-group-list":
|
||||
{
|
||||
using (var subReader = reader.ReadSubtree())
|
||||
{
|
||||
return GetFirstReleaseGroupId(subReader);
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetFirstReleaseGroupId(XmlReader reader)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "release-group":
|
||||
{
|
||||
return reader.GetAttribute("id");
|
||||
}
|
||||
default:
|
||||
{
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -432,7 +465,7 @@ namespace MediaBrowser.Providers.Music
|
||||
/// <param name="isSearch">if set to <c>true</c> [is search].</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{XmlDocument}.</returns>
|
||||
internal async Task<XmlDocument> GetMusicBrainzResponse(string url, bool isSearch, CancellationToken cancellationToken)
|
||||
internal async Task<XmlReader> GetMusicBrainzResponse(string url, bool isSearch, CancellationToken cancellationToken)
|
||||
{
|
||||
var urlInfo = await GetMbzUrl().ConfigureAwait(false);
|
||||
|
||||
@@ -444,8 +477,6 @@ namespace MediaBrowser.Providers.Music
|
||||
|
||||
url = urlInfo.url.TrimEnd('/') + url;
|
||||
|
||||
var doc = new XmlDocument();
|
||||
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
@@ -458,11 +489,15 @@ namespace MediaBrowser.Providers.Music
|
||||
{
|
||||
using (var oReader = new StreamReader(xml, Encoding.UTF8))
|
||||
{
|
||||
doc.Load(oReader);
|
||||
var settings = _xmlSettings.Create(false);
|
||||
|
||||
settings.CheckCharacters = false;
|
||||
settings.IgnoreProcessingInstructions = true;
|
||||
settings.IgnoreComments = true;
|
||||
|
||||
return XmlReader.Create(oReader, settings);
|
||||
}
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
public int Order
|
||||
|
||||
@@ -26,10 +26,11 @@ namespace MediaBrowser.Providers.Music
|
||||
{
|
||||
var url = string.Format("/ws/2/artist/?query=arid:{0}", musicBrainzId);
|
||||
|
||||
var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, false, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return GetResultsFromResponse(doc);
|
||||
using (var reader = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, false, cancellationToken)
|
||||
.ConfigureAwait(false))
|
||||
{
|
||||
return GetResultsFromResponse(reader);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -38,13 +39,14 @@ namespace MediaBrowser.Providers.Music
|
||||
|
||||
var url = String.Format("/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch));
|
||||
|
||||
var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var results = GetResultsFromResponse(doc).ToList();
|
||||
|
||||
if (results.Count > 0)
|
||||
using (var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
return results;
|
||||
var results = GetResultsFromResponse(doc).ToList();
|
||||
|
||||
if (results.Count > 0)
|
||||
{
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
if (HasDiacritics(searchInfo.Name))
|
||||
@@ -52,75 +54,123 @@ namespace MediaBrowser.Providers.Music
|
||||
// Try again using the search with accent characters url
|
||||
url = String.Format("/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
|
||||
|
||||
doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return GetResultsFromResponse(doc);
|
||||
using (var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
return GetResultsFromResponse(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new List<RemoteSearchResult>();
|
||||
}
|
||||
|
||||
private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc)
|
||||
private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlReader reader)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "artist-list":
|
||||
{
|
||||
using (var subReader = reader.ReadSubtree())
|
||||
{
|
||||
return ParseArtistList(subReader);
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new List<RemoteSearchResult>();
|
||||
}
|
||||
|
||||
private IEnumerable<RemoteSearchResult> ParseArtistList(XmlReader reader)
|
||||
{
|
||||
var list = new List<RemoteSearchResult>();
|
||||
|
||||
var docElem = doc.DocumentElement;
|
||||
reader.MoveToContent();
|
||||
|
||||
if (docElem == null)
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
var artistList = docElem.FirstChild;
|
||||
if (artistList == null)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
var nodes = artistList.ChildNodes;
|
||||
|
||||
if (nodes != null)
|
||||
{
|
||||
foreach (var node in nodes.Cast<XmlNode>())
|
||||
switch (reader.Name)
|
||||
{
|
||||
if (node.Attributes != null)
|
||||
{
|
||||
string name = null;
|
||||
string overview = null;
|
||||
string mbzId = node.Attributes["id"].Value;
|
||||
|
||||
foreach (var child in node.ChildNodes.Cast<XmlNode>())
|
||||
case "artist":
|
||||
{
|
||||
if (string.Equals(child.Name, "name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
name = child.InnerText;
|
||||
}
|
||||
if (string.Equals(child.Name, "annotation", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
overview = child.InnerText;
|
||||
}
|
||||
}
|
||||
var mbzId = reader.GetAttribute("id");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mbzId) && !string.IsNullOrWhiteSpace(name))
|
||||
using (var subReader = reader.ReadSubtree())
|
||||
{
|
||||
var artist = ParseArtist(subReader, mbzId);
|
||||
list.Add(artist);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
var result = new RemoteSearchResult
|
||||
{
|
||||
Name = name,
|
||||
Overview = overview
|
||||
};
|
||||
|
||||
result.SetProviderId(MetadataProviders.MusicBrainzArtist, mbzId);
|
||||
|
||||
list.Add(result);
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private RemoteSearchResult ParseArtist(XmlReader reader, string artistId)
|
||||
{
|
||||
var result = new RemoteSearchResult();
|
||||
|
||||
reader.MoveToContent();
|
||||
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "name":
|
||||
{
|
||||
result.Name = reader.ReadElementContentAsString();
|
||||
break;
|
||||
}
|
||||
//case "sort-name":
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
//case "tag-list":
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
case "annotation":
|
||||
{
|
||||
result.Overview = reader.ReadElementContentAsString();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.SetProviderId(MetadataProviders.MusicBrainzArtist, artistId);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(artistId) || string.IsNullOrWhiteSpace(result.Name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<MetadataResult<MusicArtist>> GetMetadata(ArtistInfo id, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = new MetadataResult<MusicArtist>
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
// No biggie. Don't blow up
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
catch (IOException)
|
||||
{
|
||||
// No biggie. Don't blow up
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
// No biggie. Don't blow up
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
catch (IOException)
|
||||
{
|
||||
// No biggie. Don't blow up
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Globalization;
|
||||
using MediaBrowser.Model.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
@@ -31,14 +32,16 @@ namespace MediaBrowser.Providers.TV
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
private static readonly SemaphoreSlim _resourceLock = new SemaphoreSlim(1, 1);
|
||||
public static bool IsRunning = false;
|
||||
private readonly IXmlReaderSettingsFactory _xmlSettings;
|
||||
|
||||
public MissingEpisodeProvider(ILogger logger, IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization, IFileSystem fileSystem)
|
||||
public MissingEpisodeProvider(ILogger logger, IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization, IFileSystem fileSystem, IXmlReaderSettingsFactory xmlSettings)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
_libraryManager = libraryManager;
|
||||
_localization = localization;
|
||||
_fileSystem = fileSystem;
|
||||
_xmlSettings = xmlSettings;
|
||||
}
|
||||
|
||||
public async Task Run(List<IGrouping<string, Series>> series, bool addNewItems, CancellationToken cancellationToken)
|
||||
@@ -495,56 +498,59 @@ namespace MediaBrowser.Providers.TV
|
||||
|
||||
DateTime? airDate = null;
|
||||
|
||||
// It appears the best way to filter out invalid entries is to only include those with valid air dates
|
||||
using (var streamReader = new StreamReader(xmlPath, Encoding.UTF8))
|
||||
using (var fileStream = _fileSystem.GetFileStream(xmlPath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
|
||||
{
|
||||
// Use XmlReader for best performance
|
||||
using (var reader = XmlReader.Create(streamReader, new XmlReaderSettings
|
||||
// It appears the best way to filter out invalid entries is to only include those with valid air dates
|
||||
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
||||
{
|
||||
CheckCharacters = false,
|
||||
IgnoreProcessingInstructions = true,
|
||||
IgnoreComments = true,
|
||||
ValidationType = ValidationType.None
|
||||
}))
|
||||
{
|
||||
reader.MoveToContent();
|
||||
var settings = _xmlSettings.Create(false);
|
||||
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
settings.CheckCharacters = false;
|
||||
settings.IgnoreProcessingInstructions = true;
|
||||
settings.IgnoreComments = true;
|
||||
|
||||
// Use XmlReader for best performance
|
||||
using (var reader = XmlReader.Create(streamReader, settings))
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
reader.MoveToContent();
|
||||
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.Name)
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
case "EpisodeName":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (string.IsNullOrWhiteSpace(val))
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "EpisodeName":
|
||||
{
|
||||
// Not valid, ignore these
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "FirstAired":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
DateTime date;
|
||||
if (DateTime.TryParse(val, out date))
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
airDate = date.ToUniversalTime();
|
||||
// Not valid, ignore these
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "FirstAired":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
DateTime date;
|
||||
if (DateTime.TryParse(val, out date))
|
||||
{
|
||||
airDate = date.ToUniversalTime();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
@@ -20,11 +21,13 @@ namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public MovieDbSeriesImageProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient)
|
||||
public MovieDbSeriesImageProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, IFileSystem fileSystem)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_httpClient = httpClient;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public string Name
|
||||
@@ -166,7 +169,7 @@ namespace MediaBrowser.Providers.TV
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
var fileInfo = new FileInfo(path);
|
||||
var fileInfo = _fileSystem.GetFileInfo(path);
|
||||
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Model.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
@@ -50,6 +51,7 @@ namespace MediaBrowser.Providers.TV
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IXmlReaderSettingsFactory _xmlSettings;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TvdbPrescanTask"/> class.
|
||||
@@ -57,13 +59,14 @@ namespace MediaBrowser.Providers.TV
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="httpClient">The HTTP client.</param>
|
||||
/// <param name="config">The config.</param>
|
||||
public TvdbPrescanTask(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config, IFileSystem fileSystem, ILibraryManager libraryManager)
|
||||
public TvdbPrescanTask(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config, IFileSystem fileSystem, ILibraryManager libraryManager, IXmlReaderSettingsFactory xmlSettings)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_config = config;
|
||||
_fileSystem = fileSystem;
|
||||
_libraryManager = libraryManager;
|
||||
_xmlSettings = xmlSettings;
|
||||
}
|
||||
|
||||
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
@@ -103,7 +106,7 @@ namespace MediaBrowser.Providers.TV
|
||||
|
||||
string newUpdateTime;
|
||||
|
||||
var existingDirectories = Directory.EnumerateDirectories(path)
|
||||
var existingDirectories = _fileSystem.GetDirectoryPaths(path)
|
||||
.Select(Path.GetFileName)
|
||||
.ToList();
|
||||
|
||||
@@ -180,13 +183,11 @@ namespace MediaBrowser.Providers.TV
|
||||
/// <returns>System.String.</returns>
|
||||
private string GetUpdateTime(Stream response)
|
||||
{
|
||||
var settings = new XmlReaderSettings
|
||||
{
|
||||
CheckCharacters = false,
|
||||
IgnoreProcessingInstructions = true,
|
||||
IgnoreComments = true,
|
||||
ValidationType = ValidationType.None
|
||||
};
|
||||
var settings = _xmlSettings.Create(false);
|
||||
|
||||
settings.CheckCharacters = false;
|
||||
settings.IgnoreProcessingInstructions = true;
|
||||
settings.IgnoreComments = true;
|
||||
|
||||
using (var streamReader = new StreamReader(response, Encoding.UTF8))
|
||||
{
|
||||
@@ -253,13 +254,11 @@ namespace MediaBrowser.Providers.TV
|
||||
string updateTime = null;
|
||||
var idList = new List<string>();
|
||||
|
||||
var settings = new XmlReaderSettings
|
||||
{
|
||||
CheckCharacters = false,
|
||||
IgnoreProcessingInstructions = true,
|
||||
IgnoreComments = true,
|
||||
ValidationType = ValidationType.None
|
||||
};
|
||||
var settings = _xmlSettings.Create(false);
|
||||
|
||||
settings.CheckCharacters = false;
|
||||
settings.IgnoreProcessingInstructions = true;
|
||||
settings.IgnoreComments = true;
|
||||
|
||||
using (var streamReader = new StreamReader(stream, Encoding.UTF8))
|
||||
{
|
||||
|
||||
17
MediaBrowser.Providers/project.json
Normal file
17
MediaBrowser.Providers/project.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"frameworks":{
|
||||
"netstandard1.6":{
|
||||
"dependencies":{
|
||||
"NETStandard.Library":"1.6.0",
|
||||
}
|
||||
},
|
||||
".NETPortable,Version=v4.5,Profile=Profile7":{
|
||||
"buildOptions": {
|
||||
"define": [ ]
|
||||
},
|
||||
"frameworkAssemblies":{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3965
MediaBrowser.Providers/project.lock.json
Normal file
3965
MediaBrowser.Providers/project.lock.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user