diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-10-14 11:08:33 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-10-14 11:08:33 -0400 |
| commit | 85928ea2b42d9aac1d9bc18006f9f24a5a682980 (patch) | |
| tree | 9034d1157e3f0ececc278030ed5bbc798f97dc3f | |
| parent | b5059152fefe68ae47252dba3b7785cc9770629e (diff) | |
only update episodes that have been changed
| -rw-r--r-- | MediaBrowser.Providers/MediaBrowser.Providers.csproj | 2 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Music/AlbumDynamicInfoProvider.cs (renamed from MediaBrowser.Providers/Music/MusicAlbumDynamicInfoProvider.cs) | 4 | ||||
| -rw-r--r-- | MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs | 90 | ||||
| -rw-r--r-- | MediaBrowser.Providers/TV/RemoteSeriesProvider.cs | 64 | ||||
| -rw-r--r-- | MediaBrowser.Providers/TV/TvdbPrescanTask.cs | 27 | ||||
| -rw-r--r-- | MediaBrowser.Server.Mono/Program.cs | 16 |
6 files changed, 166 insertions, 37 deletions
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 972578b7d..fead8e8a8 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -82,7 +82,7 @@ <Compile Include="Music\LastfmArtistProvider.cs" /> <Compile Include="Music\LastfmBaseProvider.cs" /> <Compile Include="Music\LastfmHelper.cs" /> - <Compile Include="Music\MusicAlbumDynamicInfoProvider.cs" /> + <Compile Include="Music\AlbumDynamicInfoProvider.cs" /> <Compile Include="Music\MusicVideoXmlParser.cs" /> <Compile Include="Music\SoundtrackPostScanTask.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> diff --git a/MediaBrowser.Providers/Music/MusicAlbumDynamicInfoProvider.cs b/MediaBrowser.Providers/Music/AlbumDynamicInfoProvider.cs index 521d29d89..085ff9b54 100644 --- a/MediaBrowser.Providers/Music/MusicAlbumDynamicInfoProvider.cs +++ b/MediaBrowser.Providers/Music/AlbumDynamicInfoProvider.cs @@ -13,14 +13,14 @@ namespace MediaBrowser.Providers.Music /// <summary> /// Class MusicAlbumDynamicInfoProvider /// </summary> - public class MusicAlbumDynamicInfoProvider : BaseMetadataProvider, IDynamicInfoProvider + public class AlbumDynamicInfoProvider : BaseMetadataProvider, IDynamicInfoProvider { /// <summary> /// Initializes a new instance of the <see cref="BaseMetadataProvider" /> class. /// </summary> /// <param name="logManager">The log manager.</param> /// <param name="configurationManager">The configuration manager.</param> - public MusicAlbumDynamicInfoProvider(ILogManager logManager, IServerConfigurationManager configurationManager) + public AlbumDynamicInfoProvider(ILogManager logManager, IServerConfigurationManager configurationManager) : base(logManager, configurationManager) { } diff --git a/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs b/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs index ea4ef5e21..be7ff192e 100644 --- a/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Net; +using System.Collections.Generic; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; @@ -127,7 +128,7 @@ namespace MediaBrowser.Providers.TV return base.NeedsRefreshInternal(item, providerInfo); } - protected override DateTime CompareDate(BaseItem item) + protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo) { var episode = (Episode)item; @@ -136,17 +137,90 @@ namespace MediaBrowser.Providers.TV if (!string.IsNullOrEmpty(seriesId)) { // Process images - var seriesXmlPath = Path.Combine(RemoteSeriesProvider.GetSeriesDataPath(ConfigurationManager.ApplicationPaths, seriesId), ConfigurationManager.Configuration.PreferredMetadataLanguage.ToLower() + ".xml"); + var seriesDataPath = RemoteSeriesProvider.GetSeriesDataPath(ConfigurationManager.ApplicationPaths, seriesId); - var seriesXmlFileInfo = new FileInfo(seriesXmlPath); + var files = GetEpisodeXmlFiles(episode, seriesDataPath); - if (seriesXmlFileInfo.Exists) + if (files.Count > 0) { - return seriesXmlFileInfo.LastWriteTimeUtc; + return files.Select(i => i.LastWriteTimeUtc).Max() > providerInfo.LastRefreshed; } } + + return false; + } + + /// <summary> + /// Gets the episode XML files. + /// </summary> + /// <param name="episode">The episode.</param> + /// <param name="seriesDataPath">The series data path.</param> + /// <returns>List{FileInfo}.</returns> + private List<FileInfo> GetEpisodeXmlFiles(Episode episode, string seriesDataPath) + { + var files = new List<FileInfo>(); + + if (episode.IndexNumber == null) + { + return files; + } + + var episodeNumber = episode.IndexNumber.Value; + var seasonNumber = episode.ParentIndexNumber; + + if (seasonNumber == null) + { + return files; + } + + var file = Path.Combine(seriesDataPath, string.Format("episode-{0}-{1}.xml", seasonNumber.Value, episodeNumber)); + + var fileInfo = new FileInfo(file); + var usingAbsoluteData = false; + + if (fileInfo.Exists) + { + files.Add(fileInfo); + } + else + { + file = Path.Combine(seriesDataPath, string.Format("episode-abs-{0}.xml", episodeNumber)); + fileInfo = new FileInfo(file); + if (fileInfo.Exists) + { + files.Add(fileInfo); + usingAbsoluteData = true; + } + } + + var end = episode.IndexNumberEnd ?? episodeNumber; + episodeNumber++; + + while (episodeNumber <= end) + { + if (usingAbsoluteData) + { + file = Path.Combine(seriesDataPath, string.Format("episode-abs-{0}.xml", episodeNumber)); + } + else + { + file = Path.Combine(seriesDataPath, string.Format("episode-{0}-{1}.xml", seasonNumber.Value, episodeNumber)); + } + + fileInfo = new FileInfo(file); + if (fileInfo.Exists) + { + files.Add(fileInfo); + } + else + { + break; + } + + episodeNumber++; + } - return base.CompareDate(item); + return files; } /// <summary> @@ -213,7 +287,7 @@ namespace MediaBrowser.Providers.TV } var episodeNumber = episode.IndexNumber.Value; - var seasonNumber = episode.ParentIndexNumber ?? TVUtils.GetSeasonNumberFromEpisodeFile(episode.Path); + var seasonNumber = episode.ParentIndexNumber; if (seasonNumber == null) { diff --git a/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs b/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs index e86e53e3b..161348935 100644 --- a/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs @@ -252,7 +252,7 @@ namespace MediaBrowser.Providers.TV // The prescan task will take care of updates so we don't need to re-download here if (!files.Contains("banners.xml", StringComparer.OrdinalIgnoreCase) || !files.Contains("actors.xml", StringComparer.OrdinalIgnoreCase) || !files.Contains(seriesXmlFilename, StringComparer.OrdinalIgnoreCase)) { - await DownloadSeriesZip(seriesId, seriesDataPath, cancellationToken).ConfigureAwait(false); + await DownloadSeriesZip(seriesId, seriesDataPath, null, cancellationToken).ConfigureAwait(false); } // Examine if there's no local metadata, or save local is on (to get updates) @@ -279,7 +279,7 @@ namespace MediaBrowser.Providers.TV /// <param name="seriesDataPath">The series data path.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - internal async Task DownloadSeriesZip(string seriesId, string seriesDataPath, CancellationToken cancellationToken) + internal async Task DownloadSeriesZip(string seriesId, string seriesDataPath, long? lastTvDbUpdateTime, CancellationToken cancellationToken) { var url = string.Format(SeriesGetZip, TVUtils.TvdbApiKey, seriesId, ConfigurationManager.Configuration.PreferredMetadataLanguage); @@ -301,12 +301,14 @@ namespace MediaBrowser.Providers.TV } } - foreach (var file in Directory.EnumerateFiles(seriesDataPath, "*.xml", SearchOption.AllDirectories).ToList()) + // Sanitize all files, except for extracted episode files + foreach (var file in Directory.EnumerateFiles(seriesDataPath, "*.xml", SearchOption.AllDirectories).ToList() + .Where(i => !Path.GetFileName(i).StartsWith("episode-", StringComparison.OrdinalIgnoreCase))) { await SanitizeXmlFile(file).ConfigureAwait(false); } - await ExtractEpisodes(seriesDataPath, Path.Combine(seriesDataPath, ConfigurationManager.Configuration.PreferredMetadataLanguage + ".xml")).ConfigureAwait(false); + await ExtractEpisodes(seriesDataPath, Path.Combine(seriesDataPath, ConfigurationManager.Configuration.PreferredMetadataLanguage + ".xml"), lastTvDbUpdateTime).ConfigureAwait(false); } /// <summary> @@ -369,8 +371,9 @@ namespace MediaBrowser.Providers.TV /// </summary> /// <param name="seriesDataPath">The series data path.</param> /// <param name="xmlFile">The XML file.</param> + /// <param name="lastTvDbUpdateTime">The last tv db update time.</param> /// <returns>Task.</returns> - private async Task ExtractEpisodes(string seriesDataPath, string xmlFile) + private async Task ExtractEpisodes(string seriesDataPath, string xmlFile, long? lastTvDbUpdateTime) { var settings = new XmlReaderSettings { @@ -398,7 +401,7 @@ namespace MediaBrowser.Providers.TV { var outerXml = reader.ReadOuterXml(); - await SaveEpsiodeXml(seriesDataPath, outerXml).ConfigureAwait(false); + await SaveEpsiodeXml(seriesDataPath, outerXml, lastTvDbUpdateTime).ConfigureAwait(false); break; } @@ -412,7 +415,7 @@ namespace MediaBrowser.Providers.TV } } - private async Task SaveEpsiodeXml(string seriesDataPath, string xml) + private async Task SaveEpsiodeXml(string seriesDataPath, string xml, long? lastTvDbUpdateTime) { var settings = new XmlReaderSettings { @@ -425,6 +428,7 @@ namespace MediaBrowser.Providers.TV var seasonNumber = -1; var episodeNumber = -1; var absoluteNumber = -1; + var lastUpdateString = string.Empty; using (var streamReader = new StringReader(xml)) { @@ -440,6 +444,12 @@ namespace MediaBrowser.Providers.TV { switch (reader.Name) { + case "lastupdated": + { + lastUpdateString = reader.ReadElementContentAsString(); + break; + } + case "EpisodeNumber": { var val = reader.ReadElementContentAsString(); @@ -491,21 +501,21 @@ namespace MediaBrowser.Providers.TV } } - var file = Path.Combine(seriesDataPath, string.Format("episode-{0}-{1}.xml", seasonNumber, episodeNumber)); - - using (var writer = XmlWriter.Create(file, new XmlWriterSettings - { - Encoding = Encoding.UTF8, - Async = true - })) + var hasEpisodeChanged = true; + if (!string.IsNullOrEmpty(lastUpdateString) && lastTvDbUpdateTime.HasValue) { - await writer.WriteRawAsync(xml).ConfigureAwait(false); + long num; + if (long.TryParse(lastUpdateString, NumberStyles.Any, UsCulture, out num)) + { + hasEpisodeChanged = num >= lastTvDbUpdateTime.Value; + } } - if (absoluteNumber != -1) - { - file = Path.Combine(seriesDataPath, string.Format("episode-abs-{0}.xml", absoluteNumber)); + var file = Path.Combine(seriesDataPath, string.Format("episode-{0}-{1}.xml", seasonNumber, episodeNumber)); + // Only save the file if not already there, or if the episode has changed + if (hasEpisodeChanged || !File.Exists(file)) + { using (var writer = XmlWriter.Create(file, new XmlWriterSettings { Encoding = Encoding.UTF8, @@ -515,6 +525,24 @@ namespace MediaBrowser.Providers.TV await writer.WriteRawAsync(xml).ConfigureAwait(false); } } + + if (absoluteNumber != -1) + { + file = Path.Combine(seriesDataPath, string.Format("episode-abs-{0}.xml", absoluteNumber)); + + // Only save the file if not already there, or if the episode has changed + if (hasEpisodeChanged || !File.Exists(file)) + { + using (var writer = XmlWriter.Create(file, new XmlWriterSettings + { + Encoding = Encoding.UTF8, + Async = true + })) + { + await writer.WriteRawAsync(xml).ConfigureAwait(false); + } + } + } } /// <summary> diff --git a/MediaBrowser.Providers/TV/TvdbPrescanTask.cs b/MediaBrowser.Providers/TV/TvdbPrescanTask.cs index 0bc7cc3e7..94f857d9c 100644 --- a/MediaBrowser.Providers/TV/TvdbPrescanTask.cs +++ b/MediaBrowser.Providers/TV/TvdbPrescanTask.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Net; +using System.Globalization; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; @@ -55,6 +56,8 @@ namespace MediaBrowser.Providers.TV _config = config; } + protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); + /// <summary> /// Runs the specified progress. /// </summary> @@ -72,7 +75,7 @@ namespace MediaBrowser.Providers.TV var path = RemoteSeriesProvider.GetSeriesDataPath(_config.CommonApplicationPaths); Directory.CreateDirectory(path); - + var timestampFile = Path.Combine(path, "time.txt"); var timestampFileInfo = new FileInfo(timestampFile); @@ -106,7 +109,7 @@ namespace MediaBrowser.Providers.TV newUpdateTime = GetUpdateTime(stream); } - await UpdateSeries(existingDirectories, path, progress, cancellationToken).ConfigureAwait(false); + await UpdateSeries(existingDirectories, path, null, progress, cancellationToken).ConfigureAwait(false); } else { @@ -114,7 +117,13 @@ namespace MediaBrowser.Providers.TV newUpdateTime = seriesToUpdate.Item2; - await UpdateSeries(seriesToUpdate.Item1, path, progress, cancellationToken).ConfigureAwait(false); + long lastUpdateValue; + + long.TryParse(lastUpdateTime, NumberStyles.Any, UsCulture, out lastUpdateValue); + + var nullableUpdateValue = lastUpdateValue == 0 ? (long?)null : lastUpdateValue; + + await UpdateSeries(seriesToUpdate.Item1, path, nullableUpdateValue, progress, cancellationToken).ConfigureAwait(false); } File.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8); @@ -251,10 +260,11 @@ namespace MediaBrowser.Providers.TV /// </summary> /// <param name="seriesIds">The series ids.</param> /// <param name="seriesDataPath">The series data path.</param> + /// <param name="lastTvDbUpdateTime">The last tv db update time.</param> /// <param name="progress">The progress.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - private async Task UpdateSeries(IEnumerable<string> seriesIds, string seriesDataPath, IProgress<double> progress, CancellationToken cancellationToken) + private async Task UpdateSeries(IEnumerable<string> seriesIds, string seriesDataPath, long? lastTvDbUpdateTime, IProgress<double> progress, CancellationToken cancellationToken) { var list = seriesIds.ToList(); var numComplete = 0; @@ -263,7 +273,7 @@ namespace MediaBrowser.Providers.TV { try { - await UpdateSeries(seriesId, seriesDataPath, cancellationToken).ConfigureAwait(false); + await UpdateSeries(seriesId, seriesDataPath, lastTvDbUpdateTime, cancellationToken).ConfigureAwait(false); } catch (HttpException ex) { @@ -289,9 +299,10 @@ namespace MediaBrowser.Providers.TV /// </summary> /// <param name="id">The id.</param> /// <param name="seriesDataPath">The series data path.</param> + /// <param name="lastTvDbUpdateTime">The last tv db update time.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - private Task UpdateSeries(string id, string seriesDataPath, CancellationToken cancellationToken) + private Task UpdateSeries(string id, string seriesDataPath, long? lastTvDbUpdateTime, CancellationToken cancellationToken) { _logger.Info("Updating series " + id); @@ -299,7 +310,7 @@ namespace MediaBrowser.Providers.TV Directory.CreateDirectory(seriesDataPath); - return RemoteSeriesProvider.Current.DownloadSeriesZip(id, seriesDataPath, cancellationToken); + return RemoteSeriesProvider.Current.DownloadSeriesZip(id, seriesDataPath, lastTvDbUpdateTime, cancellationToken); } } } diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs index ea6cca6ff..6d3cbcf26 100644 --- a/MediaBrowser.Server.Mono/Program.cs +++ b/MediaBrowser.Server.Mono/Program.cs @@ -11,6 +11,9 @@ using System.Diagnostics; using System.IO; using System.Threading; using System.Windows; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; using Gtk; using Gdk; using System.Threading.Tasks; @@ -90,12 +93,17 @@ namespace MediaBrowser.Server.Mono } } + private static RemoteCertificateValidationCallback _ignoreCertificates = new RemoteCertificateValidationCallback(delegate { return true; }); + private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager) { // TODO: Show splash here SystemEvents.SessionEnding += SystemEvents_SessionEnding; + // Allow all https requests + ServicePointManager.ServerCertificateValidationCallback = _ignoreCertificates; + _appHost = new ApplicationHost(appPaths, logManager); var task = _appHost.Init(); @@ -264,4 +272,12 @@ namespace MediaBrowser.Server.Mono Shutdown (); } } + + class NoCheckCertificatePolicy : ICertificatePolicy + { + public bool CheckValidationResult (ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) + { + return true; + } + } } |
