diff --git a/NzbDrone.Core/Jobs/RefreshEpsiodeMetadata.cs b/NzbDrone.Core/Jobs/RefreshEpsiodeMetadata.cs new file mode 100644 index 000000000..2de60d63c --- /dev/null +++ b/NzbDrone.Core/Jobs/RefreshEpsiodeMetadata.cs @@ -0,0 +1,81 @@ +using System.Collections.Generic; +using System.Linq; +using System; +using NLog; +using Ninject; +using NzbDrone.Core.Model.Notification; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Repository; + +namespace NzbDrone.Core.Jobs +{ + public class RefreshEpisodeMetadata : IJob + { + private readonly MediaFileProvider _mediaFileProvider; + private readonly SeriesProvider _seriesProvider; + private readonly MetadataProvider _metadataProvider; + + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + [Inject] + public RefreshEpisodeMetadata(MediaFileProvider mediaFileProvider, SeriesProvider seriesProvider, + MetadataProvider metadataProvider) + { + _mediaFileProvider = mediaFileProvider; + _seriesProvider = seriesProvider; + _metadataProvider = metadataProvider; + } + + public string Name + { + get { return "Refresh Episode Metadata"; } + } + + public TimeSpan DefaultInterval + { + get { return TimeSpan.FromTicks(0); } + } + + public void Start(ProgressNotification notification, int targetId, int secondaryTargetId) + { + if (targetId <= 0) + { + var allSeries = _seriesProvider.GetAllSeries(); + + foreach(var s in allSeries) + { + RefreshMetadata(notification, s); + } + } + + var series = _seriesProvider.GetSeries(targetId); + RefreshMetadata(notification, series); + } + + private void RefreshMetadata(ProgressNotification notification, Series series) + { + notification.CurrentMessage = String.Format("Refreshing episode metadata for '{0}'", series.Title); + + Logger.Debug("Getting episodes from database for series: {0}", series.SeriesId); + var episodeFiles = _mediaFileProvider.GetSeriesFiles(series.SeriesId); + + if (episodeFiles == null || episodeFiles.Count == 0) + { + Logger.Warn("No episodes in database found for series: {0}", series.SeriesId); + return; + } + + try + { + _metadataProvider.CreateForEpisodeFiles(episodeFiles.ToList()); + } + + catch (Exception e) + { + Logger.WarnException("An error has occurred while refreshing episode metadata", e); + } + + notification.CurrentMessage = String.Format("Epsiode metadata refresh completed for {0}", series.Title); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 61643737a..3fbdebb49 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -249,6 +249,7 @@ + diff --git a/NzbDrone.Core/Providers/Metadata/Xbmc.cs b/NzbDrone.Core/Providers/Metadata/Xbmc.cs index f1a585352..f81978f1a 100644 --- a/NzbDrone.Core/Providers/Metadata/Xbmc.cs +++ b/NzbDrone.Core/Providers/Metadata/Xbmc.cs @@ -66,25 +66,31 @@ namespace NzbDrone.Core.Providers.Metadata _diskProvider.WriteAllText(Path.Combine(series.Path, "tvshow.nfo"), doc.ToString()); } - _logger.Debug("Downloading fanart for: {0}", series.Title); - _bannerProvider.Download(tvDbSeries.FanartPath, Path.Combine(series.Path, "fanart.jpg")); - - if (_configProvider.MetadataUseBanners) + if (!_diskProvider.FileExists(Path.Combine(series.Path, "fanart.jpg"))) { - _logger.Debug("Downloading series banner for: {0}", series.Title); - _bannerProvider.Download(tvDbSeries.BannerPath, Path.Combine(series.Path, "folder.jpg")); - - _logger.Debug("Downloading Season banners for {0}", series.Title); - DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.seasonwide); + _logger.Debug("Downloading fanart for: {0}", series.Title); + _bannerProvider.Download(tvDbSeries.FanartPath, Path.Combine(series.Path, "fanart.jpg")); } - else + if (!_diskProvider.FileExists(Path.Combine(series.Path, "folder.jpg"))) { - _logger.Debug("Downloading series thumbnail for: {0}", series.Title); - _bannerProvider.Download(tvDbSeries.PosterPath, Path.Combine(series.Path, "folder.jpg")); + if(_configProvider.MetadataUseBanners) + { + _logger.Debug("Downloading series banner for: {0}", series.Title); + _bannerProvider.Download(tvDbSeries.BannerPath, Path.Combine(series.Path, "folder.jpg")); - _logger.Debug("Downloading Season posters for {0}", series.Title); - DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.season); + _logger.Debug("Downloading Season banners for {0}", series.Title); + DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.seasonwide); + } + + else + { + _logger.Debug("Downloading series thumbnail for: {0}", series.Title); + _bannerProvider.Download(tvDbSeries.PosterPath, Path.Combine(series.Path, "folder.jpg")); + + _logger.Debug("Downloading Season posters for {0}", series.Title); + DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.season); + } } } @@ -109,9 +115,13 @@ namespace NzbDrone.Core.Providers.Metadata _logger.Debug("No thumbnail is available for this episode"); return; } - - _logger.Debug("Downloading episode thumbnail for: {0}", episodeFile.EpisodeFileId); - _bannerProvider.Download(episodeFileThumbnail.BannerPath, episodeFile.Path.Replace(Path.GetExtension(episodeFile.Path), ".tbn")); + + if (!_diskProvider.FileExists(episodeFile.Path.Replace(Path.GetExtension(episodeFile.Path), ".tbn"))) + { + _logger.Debug("Downloading episode thumbnail for: {0}", episodeFile.EpisodeFileId); + _bannerProvider.Download(episodeFileThumbnail.BannerPath, + episodeFile.Path.Replace(Path.GetExtension(episodeFile.Path), ".tbn")); + } _logger.Debug("Generating filename.nfo for: {0}", episodeFile.EpisodeFileId); @@ -231,14 +241,20 @@ namespace NzbDrone.Core.Providers.Metadata if (season == 0) { - _bannerProvider.Download(banner.BannerPath, - Path.Combine(series.Path, "season-specials.tbn")); + if (!_diskProvider.FileExists(Path.Combine(series.Path, "season-specials.tbn"))) + { + _bannerProvider.Download(banner.BannerPath, + Path.Combine(series.Path, "season-specials.tbn")); + } } else { - _bannerProvider.Download(banner.BannerPath, - Path.Combine(series.Path, String.Format("season{0:00}.tbn", season))); + if (!_diskProvider.FileExists(Path.Combine(series.Path, String.Format("season{0:00}.tbn", season)))) + { + _bannerProvider.Download(banner.BannerPath, + Path.Combine(series.Path, String.Format("season{0:00}.tbn", season))); + } } } } diff --git a/NzbDrone.Web/Controllers/CommandController.cs b/NzbDrone.Web/Controllers/CommandController.cs index 5521a7999..971c46d69 100644 --- a/NzbDrone.Web/Controllers/CommandController.cs +++ b/NzbDrone.Web/Controllers/CommandController.cs @@ -62,6 +62,16 @@ namespace NzbDrone.Web.Controllers { _jobProvider.QueueJob(typeof(UpdateInfoJob), seriesId); _jobProvider.QueueJob(typeof(DiskScanJob), seriesId); + _jobProvider.QueueJob(typeof(RefreshEpisodeMetadata), seriesId); + + return JsonNotificationResult.Queued("Episode update/Disk scan"); + } + + public JsonResult ForceRefreshAll() + { + _jobProvider.QueueJob(typeof(UpdateInfoJob)); + _jobProvider.QueueJob(typeof(DiskScanJob)); + _jobProvider.QueueJob(typeof(RefreshEpisodeMetadata)); return JsonNotificationResult.Queued("Episode update/Disk scan"); } diff --git a/NzbDrone.Web/Views/Series/Editor.cshtml b/NzbDrone.Web/Views/Series/Editor.cshtml index 3aa755817..3a4ab3f29 100644 --- a/NzbDrone.Web/Views/Series/Editor.cshtml +++ b/NzbDrone.Web/Views/Series/Editor.cshtml @@ -54,6 +54,13 @@ } +@section ActionMenu +{ + +} + @using (Html.BeginForm("SaveEditor", "Series", FormMethod.Post, new { id = "SeriesEditor", name = "SeriesEditor" })) {