continue reworking provider project

This commit is contained in:
Luke Pulverenti 2016-10-27 03:58:33 -04:00
parent 823e558ade
commit 872aec9352
14 changed files with 875 additions and 826 deletions

View File

@ -98,18 +98,6 @@ namespace MediaBrowser.Controller.Library
}
}
/// <summary>
/// Gets a value indicating whether this instance is hidden.
/// </summary>
/// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value>
public bool IsHidden
{
get
{
return FileInfo.IsHidden;
}
}
/// <summary>
/// Gets a value indicating whether this instance is vf.
/// </summary>

View File

@ -52,5 +52,7 @@ namespace MediaBrowser.Model.Globalization
IEnumerable<LocalizatonOption> GetLocalizationOptions();
string RemoveDiacritics(string text);
string NormalizeFormKD(string text);
}
}

View File

@ -863,8 +863,8 @@ namespace MediaBrowser.Providers.Manager
private readonly ConcurrentQueue<Tuple<Guid, MetadataRefreshOptions>> _refreshQueue =
new ConcurrentQueue<Tuple<Guid, MetadataRefreshOptions>>();
private readonly object _refreshTimerLock = new object();
private Timer _refreshTimer;
private readonly object _refreshQueueLock = new object();
private bool _isProcessingRefreshQueue;
public void QueueRefresh(Guid id, MetadataRefreshOptions options)
{
@ -874,38 +874,18 @@ namespace MediaBrowser.Providers.Manager
}
_refreshQueue.Enqueue(new Tuple<Guid, MetadataRefreshOptions>(id, options));
StartRefreshTimer();
}
private void StartRefreshTimer()
{
if (_disposed)
lock (_refreshQueueLock)
{
return;
}
lock (_refreshTimerLock)
{
if (_refreshTimer == null)
if (!_isProcessingRefreshQueue)
{
_refreshTimer = new Timer(RefreshTimerCallback, null, 100, Timeout.Infinite);
_isProcessingRefreshQueue = true;
Task.Run(() => StartProcessingRefreshQueue());
}
}
}
private void StopRefreshTimer()
{
lock (_refreshTimerLock)
{
if (_refreshTimer != null)
{
_refreshTimer.Dispose();
_refreshTimer = null;
}
}
}
private async void RefreshTimerCallback(object state)
private async Task StartProcessingRefreshQueue()
{
Tuple<Guid, MetadataRefreshOptions> refreshItem;
var libraryManager = _libraryManagerFactory();
@ -939,7 +919,10 @@ namespace MediaBrowser.Providers.Manager
}
}
StopRefreshTimer();
lock (_refreshQueueLock)
{
_isProcessingRefreshQueue = false;
}
}
private async Task RefreshItem(BaseItem item, MetadataRefreshOptions options, CancellationToken cancellationToken)
@ -1018,7 +1001,6 @@ namespace MediaBrowser.Providers.Manager
public void Dispose()
{
_disposed = true;
StopRefreshTimer();
}
}
}

View File

@ -131,7 +131,6 @@
<Compile Include="TV\FanArt\FanArtSeasonProvider.cs" />
<Compile Include="TV\FanArt\FanartSeriesProvider.cs" />
<Compile Include="TV\MissingEpisodeProvider.cs" />
<Compile Include="TV\SeriesPostScanTask.cs" />
<Compile Include="TV\TheMovieDb\MovieDbProviderBase.cs" />
<Compile Include="TV\TheMovieDb\MovieDbEpisodeImageProvider.cs" />
<Compile Include="TV\TheMovieDb\MovieDbSeasonProvider.cs" />

View File

@ -134,23 +134,6 @@ namespace MediaBrowser.Providers.MediaInfo
{
cancellationToken.ThrowIfCancellationRequested();
//var idString = item.Id.ToString("N");
//var cachePath = Path.Combine(_appPaths.CachePath,
// "ffprobe-video",
// idString.Substring(0, 2), idString, "v" + SchemaVersion + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json");
try
{
//return _json.DeserializeFromFile<Model.MediaInfo.MediaInfo>(cachePath);
}
catch (FileNotFoundException)
{
}
catch (DirectoryNotFoundException)
{
}
var protocol = item.LocationType == LocationType.Remote
? MediaProtocol.Http
: MediaProtocol.File;
@ -655,7 +638,7 @@ namespace MediaBrowser.Providers.MediaInfo
/// <returns>System.Nullable{IsoType}.</returns>
private IsoType? DetermineIsoType(IIsoMount isoMount)
{
var fileSystemEntries = Directory.EnumerateFileSystemEntries(isoMount.MountedPath).Select(Path.GetFileName).ToList();
var fileSystemEntries = _fileSystem.GetFileSystemEntryPaths(isoMount.MountedPath).Select(Path.GetFileName).ToList();
if (fileSystemEntries.Contains("video_ts", StringComparer.OrdinalIgnoreCase) ||
fileSystemEntries.Contains("VIDEO_TS.IFO", StringComparer.OrdinalIgnoreCase))

View File

@ -12,6 +12,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using MediaBrowser.Controller.Extensions;
namespace MediaBrowser.Providers.Music
{
@ -159,21 +160,7 @@ namespace MediaBrowser.Providers.Music
/// <returns><c>true</c> if the specified text has diacritics; otherwise, <c>false</c>.</returns>
private bool HasDiacritics(string text)
{
return !String.Equals(text, RemoveDiacritics(text), StringComparison.Ordinal);
}
/// <summary>
/// Removes the diacritics.
/// </summary>
/// <param name="text">The text.</param>
/// <returns>System.String.</returns>
private string RemoveDiacritics(string text)
{
return String.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
return !String.Equals(text, text.RemoveDiacritics(), StringComparison.Ordinal);
}
/// <summary>

View File

@ -20,7 +20,7 @@ using MediaBrowser.Model.Globalization;
namespace MediaBrowser.Providers.TV
{
class MissingEpisodeProvider
public class MissingEpisodeProvider
{
private readonly IServerConfigurationManager _config;
private readonly ILogger _logger;
@ -56,7 +56,7 @@ namespace MediaBrowser.Providers.TV
{
break;
}
catch (DirectoryNotFoundException)
catch (IOException)
{
//_logger.Warn("Series files missing for series id {0}", seriesGroup.Key);
}
@ -80,7 +80,8 @@ namespace MediaBrowser.Providers.TV
var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesProviderIds);
var episodeFiles = Directory.EnumerateFiles(seriesDataPath, "*.xml", SearchOption.TopDirectoryOnly)
var episodeFiles = _fileSystem.GetFilePaths(seriesDataPath)
.Where(i => string.Equals(Path.GetExtension(i), ".xml", StringComparison.OrdinalIgnoreCase))
.Select(Path.GetFileNameWithoutExtension)
.Where(i => i.StartsWith("episode-", StringComparison.OrdinalIgnoreCase))
.ToList();

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ using System.Xml;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.Providers.TV
{
@ -29,12 +30,14 @@ namespace MediaBrowser.Providers.TV
private readonly IServerConfigurationManager _config;
private readonly IHttpClient _httpClient;
private readonly IFileSystem _fileSystem;
private readonly IXmlReaderSettingsFactory _xmlSettings;
public TvdbSeasonImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
public TvdbSeasonImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IXmlReaderSettingsFactory xmlSettings)
{
_config = config;
_httpClient = httpClient;
_fileSystem = fileSystem;
_xmlSettings = xmlSettings;
}
public string Name
@ -80,13 +83,13 @@ namespace MediaBrowser.Providers.TV
try
{
return GetImages(path, item.GetPreferredMetadataLanguage(), seasonNumber, cancellationToken);
return GetImages(path, item.GetPreferredMetadataLanguage(), seasonNumber, _xmlSettings, _fileSystem, cancellationToken);
}
catch (FileNotFoundException)
{
// No tvdb data yet. Don't blow up
}
catch (DirectoryNotFoundException)
catch (IOException)
{
// No tvdb data yet. Don't blow up
}
@ -105,45 +108,46 @@ namespace MediaBrowser.Providers.TV
return seasonNumber;
}
internal static IEnumerable<RemoteImageInfo> GetImages(string xmlPath, string preferredLanguage, int seasonNumber, CancellationToken cancellationToken)
internal static IEnumerable<RemoteImageInfo> GetImages(string xmlPath, string preferredLanguage, int seasonNumber, IXmlReaderSettingsFactory xmlReaderSettingsFactory, IFileSystem fileSystem, CancellationToken cancellationToken)
{
var settings = new XmlReaderSettings
{
CheckCharacters = false,
IgnoreProcessingInstructions = true,
IgnoreComments = true,
ValidationType = ValidationType.None
};
var settings = xmlReaderSettingsFactory.Create(false);
settings.CheckCharacters = false;
settings.IgnoreProcessingInstructions = true;
settings.IgnoreComments = true;
var list = new List<RemoteImageInfo>();
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, settings))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
{
reader.MoveToContent();
// Loop through each element
while (reader.Read())
// Use XmlReader for best performance
using (var reader = XmlReader.Create(streamReader, settings))
{
cancellationToken.ThrowIfCancellationRequested();
reader.MoveToContent();
if (reader.NodeType == XmlNodeType.Element)
// Loop through each element
while (reader.Read())
{
switch (reader.Name)
cancellationToken.ThrowIfCancellationRequested();
if (reader.NodeType == XmlNodeType.Element)
{
case "Banner":
{
using (var subtree = reader.ReadSubtree())
switch (reader.Name)
{
case "Banner":
{
AddImage(subtree, list, seasonNumber);
using (var subtree = reader.ReadSubtree())
{
AddImage(subtree, list, seasonNumber);
}
break;
}
default:
reader.Skip();
break;
}
default:
reader.Skip();
break;
}
}
}
}

View File

@ -19,6 +19,7 @@ using System.Xml;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.Providers.TV
{
@ -28,12 +29,14 @@ namespace MediaBrowser.Providers.TV
private readonly IHttpClient _httpClient;
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
private readonly IFileSystem _fileSystem;
private readonly IXmlReaderSettingsFactory _xmlReaderSettingsFactory;
public TvdbSeriesImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
public TvdbSeriesImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
{
_config = config;
_httpClient = httpClient;
_fileSystem = fileSystem;
_xmlReaderSettingsFactory = xmlReaderSettingsFactory;
}
public string Name
@ -75,7 +78,7 @@ namespace MediaBrowser.Providers.TV
{
var seriesOffset = TvdbSeriesProvider.GetSeriesOffset(item.ProviderIds);
if (seriesOffset != null && seriesOffset.Value != 0)
return TvdbSeasonImageProvider.GetImages(path, language, seriesOffset.Value + 1, cancellationToken);
return TvdbSeasonImageProvider.GetImages(path, language, seriesOffset.Value + 1, _xmlReaderSettingsFactory, _fileSystem, cancellationToken);
return GetImages(path, language, cancellationToken);
}
@ -83,7 +86,7 @@ namespace MediaBrowser.Providers.TV
{
// No tvdb data yet. Don't blow up
}
catch (DirectoryNotFoundException)
catch (IOException)
{
// No tvdb data yet. Don't blow up
}
@ -94,43 +97,44 @@ namespace MediaBrowser.Providers.TV
private IEnumerable<RemoteImageInfo> GetImages(string xmlPath, string preferredLanguage, CancellationToken cancellationToken)
{
var settings = new XmlReaderSettings
{
CheckCharacters = false,
IgnoreProcessingInstructions = true,
IgnoreComments = true,
ValidationType = ValidationType.None
};
var settings = _xmlReaderSettingsFactory.Create(false);
settings.CheckCharacters = false;
settings.IgnoreProcessingInstructions = true;
settings.IgnoreComments = true;
var list = new List<RemoteImageInfo>();
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, settings))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
{
reader.MoveToContent();
// Loop through each element
while (reader.Read())
// Use XmlReader for best performance
using (var reader = XmlReader.Create(streamReader, settings))
{
cancellationToken.ThrowIfCancellationRequested();
reader.MoveToContent();
if (reader.NodeType == XmlNodeType.Element)
// Loop through each element
while (reader.Read())
{
switch (reader.Name)
cancellationToken.ThrowIfCancellationRequested();
if (reader.NodeType == XmlNodeType.Element)
{
case "Banner":
{
using (var subtree = reader.ReadSubtree())
switch (reader.Name)
{
case "Banner":
{
AddImage(subtree, list);
using (var subtree = reader.ReadSubtree())
{
AddImage(subtree, list);
}
break;
}
default:
reader.Skip();
break;
}
default:
reader.Skip();
break;
}
}
}
}

View File

@ -20,9 +20,8 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using MediaBrowser.Model.IO;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.Providers.TV
{
@ -41,8 +40,10 @@ namespace MediaBrowser.Providers.TV
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)
public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IMemoryStreamProvider memoryStreamProvider, IXmlReaderSettingsFactory xmlSettings, ILocalizationManager localizationManager)
{
_zipClient = zipClient;
_httpClient = httpClient;
@ -51,6 +52,8 @@ namespace MediaBrowser.Providers.TV
_logger = logger;
_libraryManager = libraryManager;
_memoryStreamProvider = memoryStreamProvider;
_xmlSettings = xmlSettings;
_localizationManager = localizationManager;
Current = this;
}
@ -252,7 +255,8 @@ namespace MediaBrowser.Providers.TV
}
// Sanitize all files, except for extracted episode files
foreach (var file in Directory.EnumerateFiles(seriesDataPath, "*.xml", SearchOption.AllDirectories).ToList()
foreach (var file in _fileSystem.GetFilePaths(seriesDataPath, true).ToList()
.Where(i => string.Equals(Path.GetExtension(i), ".xml", StringComparison.OrdinalIgnoreCase))
.Where(i => !Path.GetFileName(i).StartsWith("episode-", StringComparison.OrdinalIgnoreCase)))
{
await SanitizeXmlFile(file).ConfigureAwait(false);
@ -281,20 +285,78 @@ namespace MediaBrowser.Providers.TV
}).ConfigureAwait(false))
{
var doc = new XmlDocument();
doc.Load(result);
return FindSeriesId(result);
}
}
if (doc.HasChildNodes)
private string FindSeriesId(Stream stream)
{
using (var streamReader = new StreamReader(stream, Encoding.UTF8))
{
var settings = _xmlSettings.Create(false);
settings.CheckCharacters = false;
settings.IgnoreProcessingInstructions = true;
settings.IgnoreComments = true;
// Use XmlReader for best performance
using (var reader = XmlReader.Create(streamReader, settings))
{
var node = doc.SelectSingleNode("//Series/seriesid");
reader.MoveToContent();
if (node != null)
// Loop through each element
while (reader.Read())
{
var idResult = node.InnerText;
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "Series":
{
using (var subtree = reader.ReadSubtree())
{
return FindSeriesId(subtree);
}
}
_logger.Info("Tvdb GetSeriesByRemoteId produced id of {0}", idResult ?? string.Empty);
default:
reader.Skip();
break;
}
}
}
}
}
return idResult;
return null;
}
private string FindSeriesId(XmlReader reader)
{
reader.MoveToContent();
// Loop through each element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "seriesid":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
return val;
}
return null;
}
default:
reader.Skip();
break;
}
}
}
@ -402,11 +464,11 @@ namespace MediaBrowser.Providers.TV
}
return true;
}
catch (DirectoryNotFoundException)
catch (FileNotFoundException)
{
return false;
}
catch (FileNotFoundException)
catch (IOException)
{
return false;
}
@ -570,10 +632,10 @@ namespace MediaBrowser.Providers.TV
/// </summary>
/// <param name="name">The name.</param>
/// <returns>System.String.</returns>
internal static string GetComparableName(string name)
private string GetComparableName(string name)
{
name = name.ToLower();
name = name.Normalize(NormalizationForm.FormKD);
name = _localizationManager.NormalizeFormKD(name);
var sb = new StringBuilder();
foreach (var c in name)
{
@ -615,58 +677,59 @@ namespace MediaBrowser.Providers.TV
private void FetchSeriesInfo(MetadataResult<Series> result, string seriesXmlPath, CancellationToken cancellationToken)
{
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;
var episiodeAirDates = new List<DateTime>();
using (var streamReader = new StreamReader(seriesXmlPath, Encoding.UTF8))
using (var fileStream = _fileSystem.GetFileStream(seriesXmlPath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
{
// Use XmlReader for best performance
using (var reader = XmlReader.Create(streamReader, settings))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
{
reader.MoveToContent();
// Loop through each element
while (reader.Read())
// Use XmlReader for best performance
using (var reader = XmlReader.Create(streamReader, settings))
{
cancellationToken.ThrowIfCancellationRequested();
reader.MoveToContent();
if (reader.NodeType == XmlNodeType.Element)
// Loop through each element
while (reader.Read())
{
switch (reader.Name)
cancellationToken.ThrowIfCancellationRequested();
if (reader.NodeType == XmlNodeType.Element)
{
case "Series":
{
using (var subtree = reader.ReadSubtree())
switch (reader.Name)
{
case "Series":
{
FetchDataFromSeriesNode(result, subtree, cancellationToken);
}
break;
}
case "Episode":
{
using (var subtree = reader.ReadSubtree())
{
var date = GetFirstAiredDateFromEpisodeNode(subtree, cancellationToken);
if (date.HasValue)
using (var subtree = reader.ReadSubtree())
{
episiodeAirDates.Add(date.Value);
FetchDataFromSeriesNode(result, subtree, cancellationToken);
}
break;
}
break;
}
default:
reader.Skip();
break;
case "Episode":
{
using (var subtree = reader.ReadSubtree())
{
var date = GetFirstAiredDateFromEpisodeNode(subtree, cancellationToken);
if (date.HasValue)
{
episiodeAirDates.Add(date.Value);
}
}
break;
}
default:
reader.Skip();
break;
}
}
}
}
@ -751,39 +814,40 @@ namespace MediaBrowser.Providers.TV
/// <param name="actorsXmlPath">The actors XML path.</param>
private void FetchActors(MetadataResult<Series> result, string actorsXmlPath)
{
var settings = new XmlReaderSettings
{
CheckCharacters = false,
IgnoreProcessingInstructions = true,
IgnoreComments = true,
ValidationType = ValidationType.None
};
var settings = _xmlSettings.Create(false);
using (var streamReader = new StreamReader(actorsXmlPath, Encoding.UTF8))
settings.CheckCharacters = false;
settings.IgnoreProcessingInstructions = true;
settings.IgnoreComments = true;
using (var fileStream = _fileSystem.GetFileStream(actorsXmlPath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
{
// Use XmlReader for best performance
using (var reader = XmlReader.Create(streamReader, settings))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
{
reader.MoveToContent();
// Loop through each element
while (reader.Read())
// 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 "Actor":
{
using (var subtree = reader.ReadSubtree())
switch (reader.Name)
{
case "Actor":
{
FetchDataFromActorNode(result, subtree);
using (var subtree = reader.ReadSubtree())
{
FetchDataFromActorNode(result, subtree);
}
break;
}
default:
reader.Skip();
break;
}
default:
reader.Skip();
break;
}
}
}
}
@ -1112,39 +1176,40 @@ namespace MediaBrowser.Providers.TV
/// <returns>Task.</returns>
private async Task ExtractEpisodes(string seriesDataPath, string xmlFile, long? lastTvDbUpdateTime)
{
var settings = new XmlReaderSettings
{
CheckCharacters = false,
IgnoreProcessingInstructions = true,
IgnoreComments = true,
ValidationType = ValidationType.None
};
var settings = _xmlSettings.Create(false);
using (var streamReader = new StreamReader(xmlFile, Encoding.UTF8))
settings.CheckCharacters = false;
settings.IgnoreProcessingInstructions = true;
settings.IgnoreComments = true;
using (var fileStream = _fileSystem.GetFileStream(xmlFile, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
{
// Use XmlReader for best performance
using (var reader = XmlReader.Create(streamReader, settings))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
{
reader.MoveToContent();
// Loop through each element
while (reader.Read())
// 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 "Episode":
{
var outerXml = reader.ReadOuterXml();
switch (reader.Name)
{
case "Episode":
{
var outerXml = reader.ReadOuterXml();
await SaveEpsiodeXml(seriesDataPath, outerXml, lastTvDbUpdateTime).ConfigureAwait(false);
await SaveEpsiodeXml(seriesDataPath, outerXml, lastTvDbUpdateTime).ConfigureAwait(false);
break;
}
default:
reader.Skip();
break;
}
default:
reader.Skip();
break;
}
}
}
}
@ -1154,13 +1219,11 @@ namespace MediaBrowser.Providers.TV
private async Task SaveEpsiodeXml(string seriesDataPath, string xml, long? lastTvDbUpdateTime)
{
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;
var seasonNumber = -1;
var episodeNumber = -1;
@ -1253,13 +1316,16 @@ namespace MediaBrowser.Providers.TV
// Only save the file if not already there, or if the episode has changed
if (hasEpisodeChanged || !_fileSystem.FileExists(file))
{
using (var writer = XmlWriter.Create(file, new XmlWriterSettings
using (var fileStream = _fileSystem.GetFileStream(file, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None, true))
{
Encoding = Encoding.UTF8,
Async = true
}))
{
await writer.WriteRawAsync(xml).ConfigureAwait(false);
using (var writer = XmlWriter.Create(fileStream, new XmlWriterSettings
{
Encoding = Encoding.UTF8,
Async = true
}))
{
await writer.WriteRawAsync(xml).ConfigureAwait(false);
}
}
}
@ -1270,13 +1336,16 @@ namespace MediaBrowser.Providers.TV
// Only save the file if not already there, or if the episode has changed
if (hasEpisodeChanged || !_fileSystem.FileExists(file))
{
using (var writer = XmlWriter.Create(file, new XmlWriterSettings
using (var fileStream = _fileSystem.GetFileStream(file, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.None, true))
{
Encoding = Encoding.UTF8,
Async = true
}))
{
await writer.WriteRawAsync(xml).ConfigureAwait(false);
using (var writer = XmlWriter.Create(fileStream, new XmlWriterSettings
{
Encoding = Encoding.UTF8,
Async = true
}))
{
await writer.WriteRawAsync(xml).ConfigureAwait(false);
}
}
}
}
@ -1339,7 +1408,7 @@ namespace MediaBrowser.Providers.TV
_fileSystem.DeleteFile(file);
}
}
catch (DirectoryNotFoundException)
catch (IOException)
{
// No biggie
}

View File

@ -118,6 +118,11 @@ namespace MediaBrowser.Server.Implementations.Localization
).Normalize(NormalizationForm.FormC);
}
public string NormalizeFormKD(string text)
{
return text.Normalize(NormalizationForm.FormKD);
}
/// <summary>
/// Gets the cultures.
/// </summary>

View File

@ -278,6 +278,7 @@
<Compile Include="Sync\SyncJobOptions.cs" />
<Compile Include="Sync\SyncNotificationEntryPoint.cs" />
<Compile Include="Threading\PeriodicTimer.cs" />
<Compile Include="TV\SeriesPostScanTask.cs" />
<Compile Include="UserViews\CollectionFolderImageProvider.cs" />
<Compile Include="UserViews\DynamicImageProvider.cs" />
<Compile Include="News\NewsEntryPoint.cs" />
@ -383,6 +384,10 @@
<Project>{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Providers\MediaBrowser.Providers.csproj">
<Project>{442b5058-dcaf-4263-bb6a-f21e31120a1b}</Project>
<Name>MediaBrowser.Providers</Name>
</ProjectReference>
<ProjectReference Include="..\Mono.Nat\Mono.Nat.csproj">
<Project>{d7453b88-2266-4805-b39b-2b5a2a33e1ba}</Project>
<Name>Mono.Nat</Name>

View File

@ -1,23 +1,22 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Providers.TV;
namespace MediaBrowser.Providers.TV
namespace MediaBrowser.Server.Implementations.TV
{
class SeriesGroup : List<Series>, IGrouping<string, Series>
{