From 15046e5703dac844e536adf2b6da4f1fc4d74a22 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 10 Oct 2013 12:55:07 -0400 Subject: [PATCH] tv metadata fixes --- .../Providers/BaseMetadataProvider.cs | 20 +++--- .../Games/GameProviderFromXml.cs | 19 ++--- .../Movies/MovieProviderFromXml.cs | 21 +++--- .../TV/EpisodeProviderFromXml.cs | 22 +++--- .../TV/RemoteEpisodeProvider.cs | 2 +- .../TV/RemoteSeriesProvider.cs | 72 +++++++++++++++++-- .../EntryPoints/UserDataChangeNotifier.cs | 2 +- 7 files changed, 112 insertions(+), 46 deletions(-) diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs index ad6be94814..2d49708fe2 100644 --- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs @@ -233,6 +233,16 @@ namespace MediaBrowser.Controller.Providers throw new ArgumentNullException("providerInfo"); } + if (NeedsRefreshBasedOnCompareDate(item, providerInfo)) + { + return true; + } + + if (RefreshOnFileSystemStampChange && item.LocationType == LocationType.FileSystem && HasFileSystemStampChanged(item, providerInfo)) + { + return true; + } + if (RefreshOnVersionChange && !String.Equals(ProviderVersion, providerInfo.ProviderVersion)) { return true; @@ -248,16 +258,6 @@ namespace MediaBrowser.Controller.Providers return true; } - if (NeedsRefreshBasedOnCompareDate(item, providerInfo)) - { - return true; - } - - if (RefreshOnFileSystemStampChange && item.LocationType == LocationType.FileSystem && HasFileSystemStampChanged(item, providerInfo)) - { - return true; - } - return false; } diff --git a/MediaBrowser.Providers/Games/GameProviderFromXml.cs b/MediaBrowser.Providers/Games/GameProviderFromXml.cs index f982e56586..6292cec465 100644 --- a/MediaBrowser.Providers/Games/GameProviderFromXml.cs +++ b/MediaBrowser.Providers/Games/GameProviderFromXml.cs @@ -72,15 +72,18 @@ namespace MediaBrowser.Providers.Games var metaFile = GameXmlSaver.GetGameSavePath(game); - await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + if (File.Exists(metaFile)) + { + await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - try - { - new BaseItemXmlParser(Logger).Fetch(game, metaFile, cancellationToken); - } - finally - { - XmlParsingResourcePool.Release(); + try + { + new BaseItemXmlParser(Logger).Fetch(game, metaFile, cancellationToken); + } + finally + { + XmlParsingResourcePool.Release(); + } } SetLastRefreshed(game, DateTime.UtcNow); diff --git a/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs b/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs index 9ae6cfa43e..941706b305 100644 --- a/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs +++ b/MediaBrowser.Providers/Movies/MovieProviderFromXml.cs @@ -92,17 +92,20 @@ namespace MediaBrowser.Providers.Movies var path = MovieXmlSaver.GetMovieSavePath(item); - await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - - try + if (File.Exists(path)) { - var video = (Video)item; + await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - await new MovieXmlParser(Logger, _itemRepo).FetchAsync(video, path, cancellationToken).ConfigureAwait(false); - } - finally - { - XmlParsingResourcePool.Release(); + try + { + var video = (Video)item; + + await new MovieXmlParser(Logger, _itemRepo).FetchAsync(video, path, cancellationToken).ConfigureAwait(false); + } + finally + { + XmlParsingResourcePool.Release(); + } } SetLastRefreshed(item, DateTime.UtcNow); diff --git a/MediaBrowser.Providers/TV/EpisodeProviderFromXml.cs b/MediaBrowser.Providers/TV/EpisodeProviderFromXml.cs index c7f85358ca..9862f10fee 100644 --- a/MediaBrowser.Providers/TV/EpisodeProviderFromXml.cs +++ b/MediaBrowser.Providers/TV/EpisodeProviderFromXml.cs @@ -93,20 +93,18 @@ namespace MediaBrowser.Providers.TV var file = item.ResolveArgs.Parent.ResolveArgs.GetMetaFileByPath(metadataFile); - if (file == null) + if (file != null) { - return false; - } + await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - await new EpisodeXmlParser(Logger, _itemRepo).FetchAsync((Episode)item, metadataFile, cancellationToken).ConfigureAwait(false); - } - finally - { - XmlParsingResourcePool.Release(); + try + { + await new EpisodeXmlParser(Logger, _itemRepo).FetchAsync((Episode)item, metadataFile, cancellationToken).ConfigureAwait(false); + } + finally + { + XmlParsingResourcePool.Release(); + } } SetLastRefreshed(item, DateTime.UtcNow); diff --git a/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs b/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs index aeca42938c..e34c41238b 100644 --- a/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs @@ -120,7 +120,7 @@ namespace MediaBrowser.Providers.TV protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo) { // Don't proceed if there's local metadata - if (HasLocalMeta(item) && !ConfigurationManager.Configuration.EnableTvDbUpdates) + if (!ConfigurationManager.Configuration.EnableTvDbUpdates && HasLocalMeta(item)) { return false; } diff --git a/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs b/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs index 0d2360d5bf..a921e2036a 100644 --- a/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -162,7 +163,7 @@ namespace MediaBrowser.Providers.TV } } - protected override DateTime CompareDate(BaseItem item) + protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo) { var seriesId = item.GetProviderId(MetadataProviders.Tvdb); @@ -180,16 +181,17 @@ namespace MediaBrowser.Providers.TV if (files.Count > 0) { - return files.Max(); + return files.Max() > providerInfo.LastRefreshed; } } catch (DirectoryNotFoundException) { // Don't blow up + return true; } } - - return base.CompareDate(item); + + return base.NeedsRefreshBasedOnCompareDate(item, providerInfo); } /// @@ -298,6 +300,66 @@ namespace MediaBrowser.Providers.TV _zipClient.ExtractAll(ms, seriesDataPath, true); } } + + foreach (var file in Directory.EnumerateFiles(seriesDataPath, "*.xml", SearchOption.AllDirectories).ToList()) + { + await SanitizeXmlFile(file).ConfigureAwait(false); + } + } + + /// + /// Sanitizes the XML file. + /// + /// The file. + /// Task. + private async Task SanitizeXmlFile(string file) + { + string validXml; + + using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true)) + { + using (var reader = new StreamReader(fileStream)) + { + var xml = await reader.ReadToEndAsync().ConfigureAwait(false); + + validXml = StripInvalidXmlCharacters(xml); + } + } + + using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true)) + { + using (var writer = new StreamWriter(fileStream)) + { + await writer.WriteAsync(validXml).ConfigureAwait(false); + } + } + } + + /// + /// Strips the invalid XML characters. + /// + /// The in string. + /// System.String. + public static string StripInvalidXmlCharacters(string inString) + { + if (inString == null) return null; + + var sbOutput = new StringBuilder(); + char ch; + + for (int i = 0; i < inString.Length; i++) + { + ch = inString[i]; + if ((ch >= 0x0020 && ch <= 0xD7FF) || + (ch >= 0xE000 && ch <= 0xFFFD) || + ch == 0x0009 || + ch == 0x000A || + ch == 0x000D) + { + sbOutput.Append(ch); + } + } + return sbOutput.ToString(); } /// @@ -320,7 +382,7 @@ namespace MediaBrowser.Providers.TV /// System.String. internal static string GetSeriesDataPath(IApplicationPaths appPaths) { - var dataPath = Path.Combine(appPaths.DataPath, "tvdb"); + var dataPath = Path.Combine(appPaths.DataPath, "tvdb-v2"); return dataPath; } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index fc35e040df..c3766b9fef 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly object _syncLock = new object(); private Timer UpdateTimer { get; set; } - private const int UpdateDuration = 2000; + private const int UpdateDuration = 500; private readonly Dictionary> _changedKeys = new Dictionary>();