mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-06-06 23:24:55 -04:00
make provider project portabl
This commit is contained in:
parent
7130d8a78f
commit
e12f27d8ed
@ -30,6 +30,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BDInfo", "BDInfo\BDInfo.csp
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Common.Implementations", "MediaBrowser.Common.Implementations\MediaBrowser.Common.Implementations.csproj", "{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Common.Implementations", "MediaBrowser.Common.Implementations\MediaBrowser.Common.Implementations.csproj", "{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Providers", "MediaBrowser.Providers\MediaBrowser.Providers.csproj", "{442B5058-DCAF-4263-BB6A-F21E31120A1B}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -97,6 +99,12 @@ Global
|
|||||||
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
|
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
|
||||||
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU
|
||||||
|
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU
|
||||||
|
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -112,5 +120,6 @@ Global
|
|||||||
{713F42B5-878E-499D-A878-E4C652B1D5E8} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
|
{713F42B5-878E-499D-A878-E4C652B1D5E8} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
|
||||||
{88AE38DF-19D7-406F-A6A9-09527719A21E} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
|
{88AE38DF-19D7-406F-A6A9-09527719A21E} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
|
||||||
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
|
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
|
||||||
|
{442B5058-DCAF-4263-BB6A-F21E31120A1B} = {8ADD772F-F0A4-4A53-9B2F-AF4A4C585839}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -13,8 +13,9 @@
|
|||||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||||
<ProductVersion>10.0.0</ProductVersion>
|
<ProductVersion>10.0.0</ProductVersion>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
|
||||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@ -41,13 +42,6 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Core" />
|
|
||||||
<Reference Include="System.Net" />
|
|
||||||
<Reference Include="Microsoft.CSharp" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\SharedVersion.cs">
|
<Compile Include="..\SharedVersion.cs">
|
||||||
<Link>Properties\SharedVersion.cs</Link>
|
<Link>Properties\SharedVersion.cs</Link>
|
||||||
@ -171,7 +165,7 @@
|
|||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<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.
|
<!-- 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.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<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.Threading.Tasks;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
|
using MediaBrowser.Model.Xml;
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Music
|
namespace MediaBrowser.Providers.Music
|
||||||
{
|
{
|
||||||
@ -26,15 +27,17 @@ namespace MediaBrowser.Providers.Music
|
|||||||
private readonly IApplicationHost _appHost;
|
private readonly IApplicationHost _appHost;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IJsonSerializer _json;
|
private readonly IJsonSerializer _json;
|
||||||
|
private readonly IXmlReaderSettingsFactory _xmlSettings;
|
||||||
|
|
||||||
public static string MusicBrainzBaseUrl = "https://www.musicbrainz.org";
|
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;
|
_httpClient = httpClient;
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_json = json;
|
_json = json;
|
||||||
|
_xmlSettings = xmlSettings;
|
||||||
Current = this;
|
Current = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,17 +74,18 @@ namespace MediaBrowser.Providers.Music
|
|||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(url))
|
if (!string.IsNullOrWhiteSpace(url))
|
||||||
{
|
{
|
||||||
var doc = await GetMusicBrainzResponse(url, isNameSearch, cancellationToken).ConfigureAwait(false);
|
using (var reader = await GetMusicBrainzResponse(url, isNameSearch, cancellationToken).ConfigureAwait(false))
|
||||||
|
{
|
||||||
return GetResultsFromResponse(doc);
|
return GetResultsFromResponse(reader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<RemoteSearchResult>();
|
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
|
var result = new RemoteSearchResult
|
||||||
{
|
{
|
||||||
@ -191,9 +195,10 @@ namespace MediaBrowser.Providers.Music
|
|||||||
WebUtility.UrlEncode(albumName),
|
WebUtility.UrlEncode(albumName),
|
||||||
artistId);
|
artistId);
|
||||||
|
|
||||||
var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
|
using (var reader = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
|
||||||
|
{
|
||||||
return ReleaseResult.Parse(doc, 1).FirstOrDefault();
|
return ReleaseResult.Parse(reader, 1).FirstOrDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ReleaseResult> GetReleaseResultByArtistName(string albumName, string artistName, CancellationToken cancellationToken)
|
private async Task<ReleaseResult> GetReleaseResultByArtistName(string albumName, string artistName, CancellationToken cancellationToken)
|
||||||
@ -202,9 +207,10 @@ namespace MediaBrowser.Providers.Music
|
|||||||
WebUtility.UrlEncode(albumName),
|
WebUtility.UrlEncode(albumName),
|
||||||
WebUtility.UrlEncode(artistName));
|
WebUtility.UrlEncode(artistName));
|
||||||
|
|
||||||
var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
|
using (var reader = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
|
||||||
|
{
|
||||||
return ReleaseResult.Parse(doc, 1).FirstOrDefault();
|
return ReleaseResult.Parse(reader, 1).FirstOrDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ReleaseResult
|
private class ReleaseResult
|
||||||
@ -215,108 +221,114 @@ namespace MediaBrowser.Providers.Music
|
|||||||
public string Overview;
|
public string Overview;
|
||||||
public int? Year;
|
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;
|
reader.MoveToContent();
|
||||||
var list = new List<ReleaseResult>();
|
|
||||||
|
|
||||||
if (docElem == null)
|
// Loop through each element
|
||||||
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
return list;
|
switch (reader.Name)
|
||||||
}
|
|
||||||
|
|
||||||
var releaseList = docElem.FirstChild;
|
|
||||||
if (releaseList == null)
|
|
||||||
{
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
var nodes = releaseList.ChildNodes;
|
|
||||||
|
|
||||||
if (nodes != null)
|
|
||||||
{
|
|
||||||
foreach (var node in nodes.Cast<XmlNode>())
|
|
||||||
{
|
{
|
||||||
if (string.Equals(node.Name, "release", StringComparison.OrdinalIgnoreCase))
|
case "release-list":
|
||||||
{
|
|
||||||
var releaseId = node.Attributes["id"].Value;
|
|
||||||
var releaseGroupId = GetReleaseGroupIdFromReleaseNode(node);
|
|
||||||
|
|
||||||
list.Add(new ReleaseResult
|
|
||||||
{
|
{
|
||||||
ReleaseId = releaseId,
|
using (var subReader = reader.ReadSubtree())
|
||||||
ReleaseGroupId = releaseGroupId,
|
{
|
||||||
Title = GetValueFromReleaseNode(node, "title"),
|
return ParseReleaseList(subReader);
|
||||||
Overview = GetValueFromReleaseNode(node, "annotation"),
|
}
|
||||||
Year = GetYearFromReleaseNode(node, "date")
|
}
|
||||||
});
|
default:
|
||||||
|
|
||||||
if (limit.HasValue && list.Count >= limit.Value)
|
|
||||||
{
|
{
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int? GetYearFromReleaseNode(XmlNode node, string name)
|
private static ReleaseResult ParseRelease(XmlReader reader, string releaseId)
|
||||||
{
|
{
|
||||||
var subNodes = node.ChildNodes;
|
var result = new ReleaseResult
|
||||||
if (subNodes != null)
|
|
||||||
{
|
{
|
||||||
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))
|
case "title":
|
||||||
{
|
|
||||||
DateTime date;
|
|
||||||
if (DateTime.TryParse(subNode.InnerText, out date))
|
|
||||||
{
|
{
|
||||||
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;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,33 +342,54 @@ namespace MediaBrowser.Providers.Music
|
|||||||
{
|
{
|
||||||
var url = string.Format("/ws/2/release-group/?query=reid:{0}", releaseEntryId);
|
var url = string.Format("/ws/2/release-group/?query=reid:{0}", releaseEntryId);
|
||||||
|
|
||||||
var doc = await GetMusicBrainzResponse(url, false, cancellationToken).ConfigureAwait(false);
|
using (var reader = await GetMusicBrainzResponse(url, false, cancellationToken).ConfigureAwait(false))
|
||||||
|
|
||||||
var docElem = doc.DocumentElement;
|
|
||||||
|
|
||||||
if (docElem == null)
|
|
||||||
{
|
{
|
||||||
return null;
|
reader.MoveToContent();
|
||||||
}
|
|
||||||
|
|
||||||
var releaseList = docElem.FirstChild;
|
// Loop through each element
|
||||||
if (releaseList == null)
|
while (reader.Read())
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var nodes = releaseList.ChildNodes;
|
|
||||||
|
|
||||||
if (nodes != null)
|
|
||||||
{
|
|
||||||
foreach (var node in nodes.Cast<XmlNode>())
|
|
||||||
{
|
{
|
||||||
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,7 +465,7 @@ namespace MediaBrowser.Providers.Music
|
|||||||
/// <param name="isSearch">if set to <c>true</c> [is search].</param>
|
/// <param name="isSearch">if set to <c>true</c> [is search].</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task{XmlDocument}.</returns>
|
/// <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);
|
var urlInfo = await GetMbzUrl().ConfigureAwait(false);
|
||||||
|
|
||||||
@ -444,8 +477,6 @@ namespace MediaBrowser.Providers.Music
|
|||||||
|
|
||||||
url = urlInfo.url.TrimEnd('/') + url;
|
url = urlInfo.url.TrimEnd('/') + url;
|
||||||
|
|
||||||
var doc = new XmlDocument();
|
|
||||||
|
|
||||||
var options = new HttpRequestOptions
|
var options = new HttpRequestOptions
|
||||||
{
|
{
|
||||||
Url = url,
|
Url = url,
|
||||||
@ -458,11 +489,15 @@ namespace MediaBrowser.Providers.Music
|
|||||||
{
|
{
|
||||||
using (var oReader = new StreamReader(xml, Encoding.UTF8))
|
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
|
public int Order
|
||||||
|
@ -26,10 +26,11 @@ namespace MediaBrowser.Providers.Music
|
|||||||
{
|
{
|
||||||
var url = string.Format("/ws/2/artist/?query=arid:{0}", musicBrainzId);
|
var url = string.Format("/ws/2/artist/?query=arid:{0}", musicBrainzId);
|
||||||
|
|
||||||
var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, false, cancellationToken)
|
using (var reader = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, false, cancellationToken)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false))
|
||||||
|
{
|
||||||
return GetResultsFromResponse(doc);
|
return GetResultsFromResponse(reader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -38,13 +39,14 @@ namespace MediaBrowser.Providers.Music
|
|||||||
|
|
||||||
var url = String.Format("/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch));
|
var url = String.Format("/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch));
|
||||||
|
|
||||||
var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
|
using (var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
|
||||||
|
|
||||||
var results = GetResultsFromResponse(doc).ToList();
|
|
||||||
|
|
||||||
if (results.Count > 0)
|
|
||||||
{
|
{
|
||||||
return results;
|
var results = GetResultsFromResponse(doc).ToList();
|
||||||
|
|
||||||
|
if (results.Count > 0)
|
||||||
|
{
|
||||||
|
return results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasDiacritics(searchInfo.Name))
|
if (HasDiacritics(searchInfo.Name))
|
||||||
@ -52,75 +54,123 @@ namespace MediaBrowser.Providers.Music
|
|||||||
// Try again using the search with accent characters url
|
// Try again using the search with accent characters url
|
||||||
url = String.Format("/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
|
url = String.Format("/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
|
||||||
|
|
||||||
doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
|
using (var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
|
||||||
|
{
|
||||||
return GetResultsFromResponse(doc);
|
return GetResultsFromResponse(doc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<RemoteSearchResult>();
|
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 list = new List<RemoteSearchResult>();
|
||||||
|
|
||||||
var docElem = doc.DocumentElement;
|
reader.MoveToContent();
|
||||||
|
|
||||||
if (docElem == null)
|
// Loop through each element
|
||||||
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
return list;
|
switch (reader.Name)
|
||||||
}
|
|
||||||
|
|
||||||
var artistList = docElem.FirstChild;
|
|
||||||
if (artistList == null)
|
|
||||||
{
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
var nodes = artistList.ChildNodes;
|
|
||||||
|
|
||||||
if (nodes != null)
|
|
||||||
{
|
|
||||||
foreach (var node in nodes.Cast<XmlNode>())
|
|
||||||
{
|
{
|
||||||
if (node.Attributes != null)
|
case "artist":
|
||||||
{
|
|
||||||
string name = null;
|
|
||||||
string overview = null;
|
|
||||||
string mbzId = node.Attributes["id"].Value;
|
|
||||||
|
|
||||||
foreach (var child in node.ChildNodes.Cast<XmlNode>())
|
|
||||||
{
|
{
|
||||||
if (string.Equals(child.Name, "name", StringComparison.OrdinalIgnoreCase))
|
var mbzId = reader.GetAttribute("id");
|
||||||
{
|
|
||||||
name = child.InnerText;
|
|
||||||
}
|
|
||||||
if (string.Equals(child.Name, "annotation", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
overview = child.InnerText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
reader.Skip();
|
||||||
{
|
break;
|
||||||
Name = name,
|
|
||||||
Overview = overview
|
|
||||||
};
|
|
||||||
|
|
||||||
result.SetProviderId(MetadataProviders.MusicBrainzArtist, mbzId);
|
|
||||||
|
|
||||||
list.Add(result);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
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)
|
public async Task<MetadataResult<MusicArtist>> GetMetadata(ArtistInfo id, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = new MetadataResult<MusicArtist>
|
var result = new MetadataResult<MusicArtist>
|
||||||
|
@ -103,7 +103,7 @@ namespace MediaBrowser.Providers.TV
|
|||||||
{
|
{
|
||||||
// No biggie. Don't blow up
|
// No biggie. Don't blow up
|
||||||
}
|
}
|
||||||
catch (DirectoryNotFoundException)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
// No biggie. Don't blow up
|
// No biggie. Don't blow up
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ namespace MediaBrowser.Providers.TV
|
|||||||
{
|
{
|
||||||
// No biggie. Don't blow up
|
// No biggie. Don't blow up
|
||||||
}
|
}
|
||||||
catch (DirectoryNotFoundException)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
// No biggie. Don't blow up
|
// No biggie. Don't blow up
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ using MediaBrowser.Common.IO;
|
|||||||
using MediaBrowser.Controller.IO;
|
using MediaBrowser.Controller.IO;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Globalization;
|
using MediaBrowser.Model.Globalization;
|
||||||
|
using MediaBrowser.Model.Xml;
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.TV
|
namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
@ -31,14 +32,16 @@ namespace MediaBrowser.Providers.TV
|
|||||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||||
private static readonly SemaphoreSlim _resourceLock = new SemaphoreSlim(1, 1);
|
private static readonly SemaphoreSlim _resourceLock = new SemaphoreSlim(1, 1);
|
||||||
public static bool IsRunning = false;
|
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;
|
_logger = logger;
|
||||||
_config = config;
|
_config = config;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_localization = localization;
|
_localization = localization;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
_xmlSettings = xmlSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Run(List<IGrouping<string, Series>> series, bool addNewItems, CancellationToken cancellationToken)
|
public async Task Run(List<IGrouping<string, Series>> series, bool addNewItems, CancellationToken cancellationToken)
|
||||||
@ -495,56 +498,59 @@ namespace MediaBrowser.Providers.TV
|
|||||||
|
|
||||||
DateTime? airDate = null;
|
DateTime? airDate = null;
|
||||||
|
|
||||||
// It appears the best way to filter out invalid entries is to only include those with valid air dates
|
using (var fileStream = _fileSystem.GetFileStream(xmlPath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
|
||||||
using (var streamReader = new StreamReader(xmlPath, Encoding.UTF8))
|
|
||||||
{
|
{
|
||||||
// Use XmlReader for best performance
|
// It appears the best way to filter out invalid entries is to only include those with valid air dates
|
||||||
using (var reader = XmlReader.Create(streamReader, new XmlReaderSettings
|
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
||||||
{
|
{
|
||||||
CheckCharacters = false,
|
var settings = _xmlSettings.Create(false);
|
||||||
IgnoreProcessingInstructions = true,
|
|
||||||
IgnoreComments = true,
|
|
||||||
ValidationType = ValidationType.None
|
|
||||||
}))
|
|
||||||
{
|
|
||||||
reader.MoveToContent();
|
|
||||||
|
|
||||||
// Loop through each element
|
settings.CheckCharacters = false;
|
||||||
while (reader.Read())
|
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":
|
switch (reader.Name)
|
||||||
{
|
{
|
||||||
var val = reader.ReadElementContentAsString();
|
case "EpisodeName":
|
||||||
if (string.IsNullOrWhiteSpace(val))
|
|
||||||
{
|
{
|
||||||
// Not valid, ignore these
|
var val = reader.ReadElementContentAsString();
|
||||||
return null;
|
if (string.IsNullOrWhiteSpace(val))
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "FirstAired":
|
|
||||||
{
|
|
||||||
var val = reader.ReadElementContentAsString();
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(val))
|
|
||||||
{
|
|
||||||
DateTime date;
|
|
||||||
if (DateTime.TryParse(val, out date))
|
|
||||||
{
|
{
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
reader.Skip();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Model.IO;
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.TV
|
namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
@ -20,11 +21,13 @@ namespace MediaBrowser.Providers.TV
|
|||||||
{
|
{
|
||||||
private readonly IJsonSerializer _jsonSerializer;
|
private readonly IJsonSerializer _jsonSerializer;
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
|
private readonly IFileSystem _fileSystem;
|
||||||
|
|
||||||
public MovieDbSeriesImageProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient)
|
public MovieDbSeriesImageProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, IFileSystem fileSystem)
|
||||||
{
|
{
|
||||||
_jsonSerializer = jsonSerializer;
|
_jsonSerializer = jsonSerializer;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
|
_fileSystem = fileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
@ -166,7 +169,7 @@ namespace MediaBrowser.Providers.TV
|
|||||||
|
|
||||||
if (!string.IsNullOrEmpty(path))
|
if (!string.IsNullOrEmpty(path))
|
||||||
{
|
{
|
||||||
var fileInfo = new FileInfo(path);
|
var fileInfo = _fileSystem.GetFileInfo(path);
|
||||||
|
|
||||||
if (fileInfo.Exists)
|
if (fileInfo.Exists)
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@ using MediaBrowser.Common.IO;
|
|||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.IO;
|
using MediaBrowser.Controller.IO;
|
||||||
|
using MediaBrowser.Model.Xml;
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.TV
|
namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
@ -50,6 +51,7 @@ namespace MediaBrowser.Providers.TV
|
|||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
private readonly IXmlReaderSettingsFactory _xmlSettings;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TvdbPrescanTask"/> class.
|
/// 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="logger">The logger.</param>
|
||||||
/// <param name="httpClient">The HTTP client.</param>
|
/// <param name="httpClient">The HTTP client.</param>
|
||||||
/// <param name="config">The config.</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;
|
_logger = logger;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_config = config;
|
_config = config;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
_xmlSettings = xmlSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||||
@ -103,7 +106,7 @@ namespace MediaBrowser.Providers.TV
|
|||||||
|
|
||||||
string newUpdateTime;
|
string newUpdateTime;
|
||||||
|
|
||||||
var existingDirectories = Directory.EnumerateDirectories(path)
|
var existingDirectories = _fileSystem.GetDirectoryPaths(path)
|
||||||
.Select(Path.GetFileName)
|
.Select(Path.GetFileName)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@ -180,13 +183,11 @@ namespace MediaBrowser.Providers.TV
|
|||||||
/// <returns>System.String.</returns>
|
/// <returns>System.String.</returns>
|
||||||
private string GetUpdateTime(Stream response)
|
private string GetUpdateTime(Stream response)
|
||||||
{
|
{
|
||||||
var settings = new XmlReaderSettings
|
var settings = _xmlSettings.Create(false);
|
||||||
{
|
|
||||||
CheckCharacters = false,
|
settings.CheckCharacters = false;
|
||||||
IgnoreProcessingInstructions = true,
|
settings.IgnoreProcessingInstructions = true;
|
||||||
IgnoreComments = true,
|
settings.IgnoreComments = true;
|
||||||
ValidationType = ValidationType.None
|
|
||||||
};
|
|
||||||
|
|
||||||
using (var streamReader = new StreamReader(response, Encoding.UTF8))
|
using (var streamReader = new StreamReader(response, Encoding.UTF8))
|
||||||
{
|
{
|
||||||
@ -253,13 +254,11 @@ namespace MediaBrowser.Providers.TV
|
|||||||
string updateTime = null;
|
string updateTime = null;
|
||||||
var idList = new List<string>();
|
var idList = new List<string>();
|
||||||
|
|
||||||
var settings = new XmlReaderSettings
|
var settings = _xmlSettings.Create(false);
|
||||||
{
|
|
||||||
CheckCharacters = false,
|
settings.CheckCharacters = false;
|
||||||
IgnoreProcessingInstructions = true,
|
settings.IgnoreProcessingInstructions = true;
|
||||||
IgnoreComments = true,
|
settings.IgnoreComments = true;
|
||||||
ValidationType = ValidationType.None
|
|
||||||
};
|
|
||||||
|
|
||||||
using (var streamReader = new StreamReader(stream, Encoding.UTF8))
|
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
@ -14,6 +14,7 @@ using MediaBrowser.Model.Globalization;
|
|||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
|
using MediaBrowser.Model.Xml;
|
||||||
using MediaBrowser.Providers.TV;
|
using MediaBrowser.Providers.TV;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.TV
|
namespace MediaBrowser.Server.Implementations.TV
|
||||||
@ -33,14 +34,16 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly ILocalizationManager _localization;
|
private readonly ILocalizationManager _localization;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
|
private readonly IXmlReaderSettingsFactory _xmlSettings;
|
||||||
|
|
||||||
public SeriesPostScanTask(ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, ILocalizationManager localization, IFileSystem fileSystem)
|
public SeriesPostScanTask(ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, ILocalizationManager localization, IFileSystem fileSystem, IXmlReaderSettingsFactory xmlSettings)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_config = config;
|
_config = config;
|
||||||
_localization = localization;
|
_localization = localization;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
|
_xmlSettings = xmlSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
@ -60,7 +63,7 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||||||
|
|
||||||
var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList();
|
var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList();
|
||||||
|
|
||||||
return new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem).Run(seriesGroups, true, cancellationToken);
|
return new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem, _xmlSettings).Run(seriesGroups, true, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static IEnumerable<IGrouping<string, Series>> FindSeriesGroups(List<Series> seriesList)
|
internal static IEnumerable<IGrouping<string, Series>> FindSeriesGroups(List<Series> seriesList)
|
||||||
@ -128,8 +131,9 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||||||
private readonly object _libraryChangedSyncLock = new object();
|
private readonly object _libraryChangedSyncLock = new object();
|
||||||
private const int LibraryUpdateDuration = 180000;
|
private const int LibraryUpdateDuration = 180000;
|
||||||
private readonly ITaskManager _taskManager;
|
private readonly ITaskManager _taskManager;
|
||||||
|
private readonly IXmlReaderSettingsFactory _xmlSettings;
|
||||||
|
|
||||||
public CleanMissingEpisodesEntryPoint(ILibraryManager libraryManager, IServerConfigurationManager config, ILogger logger, ILocalizationManager localization, IFileSystem fileSystem, ITaskManager taskManager)
|
public CleanMissingEpisodesEntryPoint(ILibraryManager libraryManager, IServerConfigurationManager config, ILogger logger, ILocalizationManager localization, IFileSystem fileSystem, ITaskManager taskManager, IXmlReaderSettingsFactory xmlSettings)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_config = config;
|
_config = config;
|
||||||
@ -137,6 +141,7 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||||||
_localization = localization;
|
_localization = localization;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_taskManager = taskManager;
|
_taskManager = taskManager;
|
||||||
|
_xmlSettings = xmlSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Timer LibraryUpdateTimer { get; set; }
|
private Timer LibraryUpdateTimer { get; set; }
|
||||||
@ -190,7 +195,7 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||||||
|
|
||||||
var seriesGroups = SeriesPostScanTask.FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList();
|
var seriesGroups = SeriesPostScanTask.FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList();
|
||||||
|
|
||||||
await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem)
|
await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem, _xmlSettings)
|
||||||
.Run(seriesGroups, false, CancellationToken.None).ConfigureAwait(false);
|
.Run(seriesGroups, false, CancellationToken.None).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
<ProjectReference Include="..\..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
|
<ProjectReference Include="..\..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
|
||||||
<ProjectReference Include="..\..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
|
<ProjectReference Include="..\..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
|
||||||
<ProjectReference Include="..\..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
|
<ProjectReference Include="..\..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
|
||||||
|
<ProjectReference Include="..\..\MediaBrowser.Providers\MediaBrowser.Providers.csproj" />
|
||||||
<ProjectReference Include="..\..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj" />
|
<ProjectReference Include="..\..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj" />
|
||||||
<ProjectReference Include="..\..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj" />
|
<ProjectReference Include="..\..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -88,6 +88,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MediaBrowser.Providers/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"framework": ".NETPortable,Version=v4.5,Profile=Profile7",
|
||||||
|
"compile": {
|
||||||
|
"bin/Debug/MediaBrowser.Providers.dll": {}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"bin/Debug/MediaBrowser.Providers.dll": {}
|
||||||
|
},
|
||||||
|
"contentFiles": {
|
||||||
|
"bin/Debug/MediaBrowser.Providers.pdb": {
|
||||||
|
"buildAction": "None",
|
||||||
|
"codeLanguage": "any",
|
||||||
|
"copyToOutput": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"MediaBrowser.WebDashboard/1.0.0": {
|
"MediaBrowser.WebDashboard/1.0.0": {
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"framework": ".NETPortable,Version=v4.5,Profile=Profile7",
|
"framework": ".NETPortable,Version=v4.5,Profile=Profile7",
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
"MediaBrowser.Model": {
|
"MediaBrowser.Model": {
|
||||||
"target": "project"
|
"target": "project"
|
||||||
},
|
},
|
||||||
|
"MediaBrowser.Providers": {
|
||||||
|
"target": "project"
|
||||||
|
},
|
||||||
"MediaBrowser.WebDashboard": {
|
"MediaBrowser.WebDashboard": {
|
||||||
"target": "project"
|
"target": "project"
|
||||||
},
|
},
|
||||||
|
@ -2175,6 +2175,17 @@
|
|||||||
"NETStandard.Library": "1.6.0"
|
"NETStandard.Library": "1.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MediaBrowser.Providers/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"framework": ".NETStandard,Version=v1.6",
|
||||||
|
"dependencies": {
|
||||||
|
"DvdLib": "1.0.0",
|
||||||
|
"MediaBrowser.Common": "1.0.0",
|
||||||
|
"MediaBrowser.Controller": "1.0.0",
|
||||||
|
"MediaBrowser.Model": "1.0.0",
|
||||||
|
"NETStandard.Library": "1.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"MediaBrowser.WebDashboard/1.0.0": {
|
"MediaBrowser.WebDashboard/1.0.0": {
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"framework": ".NETStandard,Version=v1.6",
|
"framework": ".NETStandard,Version=v1.6",
|
||||||
@ -6953,6 +6964,11 @@
|
|||||||
"path": "../../MediaBrowser.Model/project.json",
|
"path": "../../MediaBrowser.Model/project.json",
|
||||||
"msbuildProject": "../../MediaBrowser.Model/MediaBrowser.Model.csproj"
|
"msbuildProject": "../../MediaBrowser.Model/MediaBrowser.Model.csproj"
|
||||||
},
|
},
|
||||||
|
"MediaBrowser.Providers/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"path": "../../MediaBrowser.Providers/project.json",
|
||||||
|
"msbuildProject": "../../MediaBrowser.Providers/MediaBrowser.Providers.csproj"
|
||||||
|
},
|
||||||
"MediaBrowser.WebDashboard/1.0.0": {
|
"MediaBrowser.WebDashboard/1.0.0": {
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"path": "../../MediaBrowser.WebDashboard/project.json",
|
"path": "../../MediaBrowser.WebDashboard/project.json",
|
||||||
@ -6974,6 +6990,7 @@
|
|||||||
"MediaBrowser.Common",
|
"MediaBrowser.Common",
|
||||||
"MediaBrowser.Controller",
|
"MediaBrowser.Controller",
|
||||||
"MediaBrowser.Model",
|
"MediaBrowser.Model",
|
||||||
|
"MediaBrowser.Providers",
|
||||||
"MediaBrowser.WebDashboard",
|
"MediaBrowser.WebDashboard",
|
||||||
"MediaBrowser.XbmcMetadata"
|
"MediaBrowser.XbmcMetadata"
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user