Metadata will be called when needed #ND-21

Import/Rename episode files
Import series/update series info
pull/6/head
Mark McDowall 12 years ago
parent eee24aff1d
commit b122f1135e

@ -212,7 +212,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, false);
//Assert
result.Should().BeFalse();
result.Should().BeNull();
}
[Test]
@ -368,7 +368,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, true);
//Assert
result.Should().BeTrue();
result.Should().NotBeNull();
Mocker.GetMock<ExternalNotificationProvider>()
.Verify(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny<Series>()), Times.Once());
}

@ -123,14 +123,14 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata
public void should_not_blowup()
{
WithSingleEpisodeFile();
Mocker.Resolve<Xbmc>().ForEpisodeFile(episodeFile, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForEpisodeFile(episodeFile, tvdbSeries);
}
[Test]
public void should_call_diskprovider_writeAllText_once_for_single_episode()
{
WithSingleEpisodeFile();
Mocker.Resolve<Xbmc>().ForEpisodeFile(episodeFile, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForEpisodeFile(episodeFile, tvdbSeries);
Mocker.GetMock<DiskProvider>().Verify(v => v.WriteAllText(episodeFile.Path.Replace("avi", "nfo"), It.IsAny<string>()), Times.Once());
}
@ -138,7 +138,7 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata
public void should_call_diskprovider_writeAllText_once_for_multi_episode()
{
WithMultiEpisodeFile();
Mocker.Resolve<Xbmc>().ForEpisodeFile(episodeFile, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForEpisodeFile(episodeFile, tvdbSeries);
Mocker.GetMock<DiskProvider>().Verify(v => v.WriteAllText(episodeFile.Path.Replace("avi", "nfo"), It.IsAny<string>()), Times.Once());
}
@ -146,7 +146,7 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata
public void should_download_thumbnail_when_thumbnail_path_is_not_null()
{
WithSingleEpisodeFile();
Mocker.Resolve<Xbmc>().ForEpisodeFile(episodeFile, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForEpisodeFile(episodeFile, tvdbSeries);
Mocker.GetMock<BannerProvider>().Verify(v => v.Download(tvdbSeries.Episodes.First().BannerPath, episodeFile.Path.Replace("avi", "tbn")), Times.Once());
}
}

@ -78,27 +78,27 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata
[Test]
public void should_not_blowup()
{
Mocker.Resolve<Xbmc>().ForSeries(series, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForSeries(series, tvdbSeries);
}
[Test]
public void should_call_diskprovider_writeAllText()
{
Mocker.Resolve<Xbmc>().ForSeries(series, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForSeries(series, tvdbSeries);
Mocker.GetMock<DiskProvider>().Verify(v => v.WriteAllText(Path.Combine(series.Path, "tvshow.nfo"), It.IsAny<string>()), Times.Once());
}
[Test]
public void should_download_fanart()
{
Mocker.Resolve<Xbmc>().ForSeries(series, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForSeries(series, tvdbSeries);
Mocker.GetMock<BannerProvider>().Verify(v => v.Download(tvdbSeries.FanartPath, Path.Combine(series.Path, "fanart.jpg")), Times.Once());
}
[Test]
public void should_download_poster_when_useBanners_is_false()
{
Mocker.Resolve<Xbmc>().ForSeries(series, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForSeries(series, tvdbSeries);
Mocker.GetMock<BannerProvider>().Verify(v => v.Download(tvdbSeries.PosterPath, Path.Combine(series.Path, "folder.jpg")), Times.Once());
}
@ -106,14 +106,14 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata
public void should_download_banner_when_useBanners_is_true()
{
WithUseBanners();
Mocker.Resolve<Xbmc>().ForSeries(series, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForSeries(series, tvdbSeries);
Mocker.GetMock<BannerProvider>().Verify(v => v.Download(tvdbSeries.BannerPath, Path.Combine(series.Path, "folder.jpg")), Times.Once());
}
[Test]
public void should_download_season_poster_when_useBanners_is_false()
{
Mocker.Resolve<Xbmc>().ForSeries(series, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForSeries(series, tvdbSeries);
Mocker.GetMock<BannerProvider>().Verify(v => v.Download(It.Is<string>(s => !s.Contains("banners")), It.IsRegex(@"season\d{2}\.tbn")), Times.Exactly(2));
}
@ -121,7 +121,7 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata
public void should_download_season_banner_when_useBanners_is_true()
{
WithUseBanners();
Mocker.Resolve<Xbmc>().ForSeries(series, tvdbSeries);
Mocker.Resolve<Xbmc>().CreateForSeries(series, tvdbSeries);
Mocker.GetMock<BannerProvider>().Verify(v => v.Download(It.Is<string>(s => s.Contains("banners")), It.IsRegex(@"season\d{2}\.tbn")), Times.Exactly(2));
}
}

@ -210,7 +210,7 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveDirectory(droppedFolder.FullName, taggedFolder));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize + 10.Megabytes());
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(fakeEpisodeFiles);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(true);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile());
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
@ -281,9 +281,10 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
Mocker.GetMock<SeriesProvider>().Setup(s => s.FindSeries("office")).Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.CleanUpDropFolder(droppedFolder.FullName));
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(fakeEpisodeFiles);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(true);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile());
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize - 1.Megabytes());
Mocker.GetMock<DiskProvider>().Setup(s => s.DeleteFolder(droppedFolder.FullName, true));
Mocker.GetMock<MetadataProvider>().Setup(s => s.CreateForEpisodeFiles(It.IsAny<List<EpisodeFile>>()));
//Act
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);

@ -1,9 +1,11 @@
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
{
@ -13,17 +15,20 @@ namespace NzbDrone.Core.Jobs
private readonly DiskScanProvider _diskScanProvider;
private readonly ExternalNotificationProvider _externalNotificationProvider;
private readonly SeriesProvider _seriesProvider;
private readonly MetadataProvider _metadataProvider;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
[Inject]
public RenameSeasonJob(MediaFileProvider mediaFileProvider, DiskScanProvider diskScanProvider,
ExternalNotificationProvider externalNotificationProvider, SeriesProvider seriesProvider)
ExternalNotificationProvider externalNotificationProvider, SeriesProvider seriesProvider,
MetadataProvider metadataProvider)
{
_mediaFileProvider = mediaFileProvider;
_diskScanProvider = diskScanProvider;
_externalNotificationProvider = externalNotificationProvider;
_seriesProvider = seriesProvider;
_metadataProvider = metadataProvider;
}
public string Name
@ -57,18 +62,32 @@ namespace NzbDrone.Core.Jobs
return;
}
var newEpisodeFiles = new List<EpisodeFile>();
var oldEpisodeFiles = new List<EpisodeFile>();
foreach (var episodeFile in episodeFiles)
{
try
{
_diskScanProvider.MoveEpisodeFile(episodeFile);
var newFile = _diskScanProvider.MoveEpisodeFile(episodeFile);
if (newFile != null)
{
newEpisodeFiles.Add(newFile);
oldEpisodeFiles.Add(episodeFile);
}
}
catch (Exception exception)
catch (Exception e)
{
logger.WarnException("An error has occurred while renaming file", exception);
logger.WarnException("An error has occurred while renaming file", e);
}
}
//Remove & Create Metadata for episode files
_metadataProvider.RemoveForEpisodeFiles(oldEpisodeFiles);
_metadataProvider.CreateForEpisodeFiles(newEpisodeFiles);
//Start AfterRename
var message = String.Format("Renamed: Series {0}, Season: {1}", series.Title, secondaryTargetId);

@ -1,9 +1,11 @@
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
{
@ -13,17 +15,20 @@ namespace NzbDrone.Core.Jobs
private readonly DiskScanProvider _diskScanProvider;
private readonly ExternalNotificationProvider _externalNotificationProvider;
private readonly SeriesProvider _seriesProvider;
private readonly MetadataProvider _metadataProvider;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[Inject]
public RenameSeriesJob(MediaFileProvider mediaFileProvider, DiskScanProvider diskScanProvider,
ExternalNotificationProvider externalNotificationProvider, SeriesProvider seriesProvider)
ExternalNotificationProvider externalNotificationProvider, SeriesProvider seriesProvider,
MetadataProvider metadataProvider)
{
_mediaFileProvider = mediaFileProvider;
_diskScanProvider = diskScanProvider;
_externalNotificationProvider = externalNotificationProvider;
_seriesProvider = seriesProvider;
_metadataProvider = metadataProvider;
}
public string Name
@ -54,19 +59,32 @@ namespace NzbDrone.Core.Jobs
return;
}
var newEpisodeFiles = new List<EpisodeFile>();
var oldEpisodeFiles = new List<EpisodeFile>();
foreach (var episodeFile in episodeFiles)
{
try
{
_diskScanProvider.MoveEpisodeFile(episodeFile);
var newFile = _diskScanProvider.MoveEpisodeFile(episodeFile);
if (newFile != null)
{
newEpisodeFiles.Add(newFile);
oldEpisodeFiles.Add(episodeFile);
}
}
catch(Exception e)
{
Logger.WarnException("An error has occurred while renaming file", e);
}
}
}
//Remove & Create Metadata for episode files
_metadataProvider.RemoveForEpisodeFiles(oldEpisodeFiles);
_metadataProvider.CreateForEpisodeFiles(newEpisodeFiles);
//Start AfterRename
var message = String.Format("Renamed: Series {0}", series.Title);

@ -168,7 +168,7 @@ namespace NzbDrone.Core.Providers
return episodeFile;
}
public virtual bool MoveEpisodeFile(EpisodeFile episodeFile, bool newDownload = false)
public virtual EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, bool newDownload = false)
{
if (episodeFile == null)
throw new ArgumentNullException("episodeFile");
@ -182,14 +182,14 @@ namespace NzbDrone.Core.Providers
if (DiskProvider.PathEquals(episodeFile.Path, newFile.FullName))
{
Logger.Debug("Skipping file rename, source and destination are the same: {0}", episodeFile.Path);
return false;
return null;
}
_diskProvider.CreateDirectory(newFile.DirectoryName);
Logger.Debug("Moving [{0}] > [{1}]", episodeFile.Path, newFile.FullName);
_diskProvider.MoveFile(episodeFile.Path, newFile.FullName);
_diskProvider.InheritFolderPermissions(newFile.FullName);
episodeFile.Path = newFile.FullName;
@ -213,7 +213,7 @@ namespace NzbDrone.Core.Providers
_externalNotificationProvider.OnRename(message, series);
}
return true;
return episodeFile;
}
/// <summary>

@ -36,14 +36,26 @@ namespace NzbDrone.Core.Providers.Metadata
/// </summary>
/// <param name = "series">The series to create the metadata for</param>
/// <param name = "tvDbSeries">Series information from TheTvDb</param>
public abstract void ForSeries(Series series, TvdbSeries tvDbSeries);
public abstract void CreateForSeries(Series series, TvdbSeries tvDbSeries);
/// <summary>
/// Creates metadata for the episode file
/// </summary>
/// <param name = "episodeFile">The episode file to create the metadata</param>
/// <param name = "tvDbSeries">Series information from TheTvDb</param>
public abstract void ForEpisodeFile(EpisodeFile episodeFile, TvdbSeries tvDbSeries);
public abstract void CreateForEpisodeFile(EpisodeFile episodeFile, TvdbSeries tvDbSeries);
/// <summary>
/// Removes metadata for a series
/// </summary>
/// <param name = "series">The series to create the metadata for</param>
public abstract void RemoveForSeries(Series series);
/// <summary>
/// Removes metadata for the episode file
/// </summary>
/// <param name = "episodeFile">The episode file to create the metadata</param>
public abstract void RemoveForEpisodeFile(EpisodeFile episodeFile);
public virtual string GetEpisodeGuideUrl(int seriesId)
{

@ -28,9 +28,9 @@ namespace NzbDrone.Core.Providers.Metadata
get { return "XBMC"; }
}
public override void ForSeries(Series series, TvdbSeries tvDbSeries)
public override void CreateForSeries(Series series, TvdbSeries tvDbSeries)
{
//Create tvshow.nfo, fanart.jpg, folder.jpg and searon##.tbn
//Create tvshow.nfo, fanart.jpg, folder.jpg and season##.tbn
var episodeGuideUrl = GetEpisodeGuideUrl(series.SeriesId);
_logger.Debug("Generating tvshow.nfo for: {0}", series.Title);
@ -90,10 +90,9 @@ namespace NzbDrone.Core.Providers.Metadata
}
}
public override void ForEpisodeFile(EpisodeFile episodeFile, TvdbSeries tvDbSeries)
public override void CreateForEpisodeFile(EpisodeFile episodeFile, TvdbSeries tvDbSeries)
{
//Download filename.tbn and filename.nfo
//Use BannerPath for Thumbnail
//Create filename.tbn and filename.nfo
var episodes = _episodeProvider.GetEpisodesByFileId(episodeFile.EpisodeFileId);
if (!episodes.Any())
@ -191,6 +190,37 @@ namespace NzbDrone.Core.Providers.Metadata
_diskProvider.WriteAllText(filename, xmlResult);
}
public override void RemoveForSeries(Series series)
{
//Remove tvshow.nfo, fanart.jpg, folder.jpg and season##.tbn
_logger.Debug("Deleting series metadata for: ", series.Title);
_diskProvider.DeleteFile(Path.Combine(series.Path, "tvshow.nfo"));
_diskProvider.DeleteFile(Path.Combine(series.Path, "fanart.jpg"));
_diskProvider.DeleteFile(Path.Combine(series.Path, "fanart.jpg"));
foreach (var file in _diskProvider.GetFiles(series.Path, SearchOption.TopDirectoryOnly))
{
if (Path.GetExtension(file) != ".tbn")
continue;
if (!Path.GetFileName(file).StartsWith("season"))
continue;
_logger.Debug("Deleting season thumbnail: {0}", file);
_diskProvider.DeleteFile(file);
}
}
public override void RemoveForEpisodeFile(EpisodeFile episodeFile)
{
//Remove filename.tbn and filename.nfo
_logger.Debug("Deleting episode metadata for: {0}", episodeFile);
_diskProvider.DeleteFile(episodeFile.Path.Replace(Path.GetExtension(episodeFile.Path), ".nfo"));
_diskProvider.DeleteFile(episodeFile.Path.Replace(Path.GetExtension(episodeFile.Path), ".tbn"));
}
private void DownloadSeasonThumbnails(Series series, TvdbSeries tvDbSeries, TvdbSeasonBanner.Type bannerType)
{
var seasons = tvDbSeries.SeasonBanners.Where(s => s.BannerType == bannerType).Select(s => s.Season);

@ -100,7 +100,7 @@ namespace NzbDrone.Core.Providers
{
foreach (var provider in _metadataProviders.Where(i => GetSettings(i.GetType()).Enable))
{
provider.ForSeries(series, tvDbSeries);
provider.CreateForSeries(series, tvDbSeries);
}
}
@ -108,10 +108,60 @@ namespace NzbDrone.Core.Providers
{
var tvDbSeries = _tvDbProvider.GetSeries(episodeFile.SeriesId, true, true);
CreateForEpisodeFile(episodeFile, tvDbSeries);
}
public virtual void CreateForEpisodeFile(EpisodeFile episodeFile, TvdbSeries tvDbSeries)
{
foreach (var provider in _metadataProviders.Where(i => GetSettings(i.GetType()).Enable))
{
provider.CreateForEpisodeFile(episodeFile, tvDbSeries);
}
}
public virtual void CreateForEpisodeFiles(List<EpisodeFile> episodeFiles)
{
var tvDbSeries = _tvDbProvider.GetSeries(episodeFiles.First().SeriesId, true, true);
foreach(var episodeFile in episodeFiles)
{
foreach (var provider in _metadataProviders.Where(i => GetSettings(i.GetType()).Enable))
{
provider.CreateForEpisodeFile(episodeFile, tvDbSeries);
}
}
}
public virtual void RemoveForSeries(Series series)
{
foreach (var provider in _metadataProviders.Where(i => GetSettings(i.GetType()).Enable))
{
provider.ForEpisodeFile(episodeFile, tvDbSeries);
provider.RemoveForSeries(series);
}
}
public virtual void RemoveForEpisodeFile(EpisodeFile episodeFile)
{
foreach (var provider in _metadataProviders.Where(i => GetSettings(i.GetType()).Enable))
{
provider.RemoveForEpisodeFile(episodeFile);
}
}
public virtual void RemoveForEpisodeFiles(List<EpisodeFile> episodeFiles)
{
foreach (var episodeFile in episodeFiles)
{
foreach (var provider in _metadataProviders.Where(i => GetSettings(i.GetType()).Enable))
{
provider.RemoveForEpisodeFile(episodeFile);
}
}
}
public virtual void RenameForEpisodeFile(EpisodeFile episodeFile)
{
}
}
}

@ -16,14 +16,16 @@ namespace NzbDrone.Core.Providers
private readonly DiskProvider _diskProvider;
private readonly DiskScanProvider _diskScanProvider;
private readonly SeriesProvider _seriesProvider;
private readonly MetadataProvider _metadataProvider;
[Inject]
public PostDownloadProvider(DiskProvider diskProvider, DiskScanProvider diskScanProvider,
SeriesProvider seriesProvider)
SeriesProvider seriesProvider, MetadataProvider metadataProvider)
{
_diskProvider = diskProvider;
_diskScanProvider = diskScanProvider;
_seriesProvider = seriesProvider;
_metadataProvider = metadataProvider;
}
public PostDownloadProvider()
@ -71,6 +73,9 @@ namespace NzbDrone.Core.Providers
var importedFiles = _diskScanProvider.Scan(series, subfolderInfo.FullName);
importedFiles.ForEach(file => _diskScanProvider.MoveEpisodeFile(file, true));
//Create Metadata for all the episode files found
_metadataProvider.CreateForEpisodeFiles(importedFiles);
//Delete the folder only if folder is small enough
if (_diskProvider.GetDirectorySize(subfolderInfo.FullName) < Constants.IgnoreFileSize)
{

Loading…
Cancel
Save