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 banners for {0}", series.Title);
+ DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.seasonwide);
+ }
- _logger.Debug("Downloading Season posters for {0}", series.Title);
- DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.season);
+ 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" }))
{