From 7e44ee5020041ced05c59d094a3a9ad67bd29d08 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 17 May 2011 22:32:23 -0700 Subject: [PATCH] Merge with Kayone's branch. --- NzbDrone.Core.Test/MediaFileProviderTests.cs | 62 +++++++++++++++++ NzbDrone.Core/CentralDispatch.cs | 1 - NzbDrone.Core/NzbDrone.Core.csproj | 1 - .../Providers/Jobs/MediaFileScanJob.cs | 2 +- NzbDrone.Core/Providers/MediaFileProvider.cs | 69 +++++++++---------- NzbDrone.Core/Repository/Season.cs | 4 +- NzbDrone.Web/Controllers/SeriesController.cs | 7 +- NzbDrone.sln | 13 ---- 8 files changed, 99 insertions(+), 60 deletions(-) diff --git a/NzbDrone.Core.Test/MediaFileProviderTests.cs b/NzbDrone.Core.Test/MediaFileProviderTests.cs index becfc86b0..dbb363255 100644 --- a/NzbDrone.Core.Test/MediaFileProviderTests.cs +++ b/NzbDrone.Core.Test/MediaFileProviderTests.cs @@ -1,12 +1,17 @@ using System; +using System.Collections.Generic; +using System.IO; using System.Linq.Expressions; +using System.Linq; using AutoMoq; using FizzWare.NBuilder; using MbUnit.Framework; using Moq; using Moq.Linq; +using NzbDrone.Core.Model.Notification; using NzbDrone.Core.Providers; using NzbDrone.Core.Providers.Core; +using NzbDrone.Core.Providers.Jobs; using NzbDrone.Core.Repository; using NzbDrone.Core.Repository.Quality; using SubSonic.Repository; @@ -271,5 +276,62 @@ namespace NzbDrone.Core.Test Assert.IsNull(result); mocker.GetMock().Verify(r => r.Add(result), Times.Never()); } + + [Test] + public void scan_series_should_update_last_scan_date() + { + + var mocker = new AutoMoqer(); + mocker.GetMock() + .Setup(c => c.UpdateSeries(It.Is(s => s.LastDiskSync != null))).Verifiable(); + + mocker.Resolve().Scan(new Series()); + + mocker.VerifyAllMocks(); + + } + + + [Test] + public void scan_media_job_should_not_scan_new_series() + { + var mocker = new AutoMoqer(); + mocker.GetMock() + .Setup(c => c.GetAllSeries()) + .Returns(Builder.CreateListOfSize(2) + .WhereTheFirst(1).Has(c => c.LastInfoSync = DateTime.Now).Build().AsQueryable()); + mocker.GetMock(MockBehavior.Strict) + .Setup(c => c.Scan(It.Is(s => s.LastInfoSync != null))).Returns(new List()).Verifiable(); + + mocker.Resolve().Start(new ProgressNotification("test"), 0); + + mocker.VerifyAllMocks(); + } + + [Test] + public void get_season_files() + { + var episodes = Builder.CreateListOfSize(20) + .WhereTheFirst(8) + .Has(c => c.EpisodeFile = new EpisodeFile()) + .AndTheRemaining() + .Has(c => c.EpisodeFile = null) + .Build().ToList(); + + var mocker = new AutoMoqer(); + mocker.GetMock() + .Setup(c => c.GetSeason(12)) + .Returns(Builder.CreateNew().With(c => c.Episodes = episodes).Build()) + .Verifiable(); + + + var result = mocker.Resolve().GetSeasonFiles(12); + + Assert.Count(8, result); + Assert.DoesNotContain(result, null); + mocker.VerifyAllMocks(); + + + } } } \ No newline at end of file diff --git a/NzbDrone.Core/CentralDispatch.cs b/NzbDrone.Core/CentralDispatch.cs index daee295a2..73c0cf34a 100644 --- a/NzbDrone.Core/CentralDispatch.cs +++ b/NzbDrone.Core/CentralDispatch.cs @@ -90,7 +90,6 @@ namespace NzbDrone.Core _kernel.Bind().ToSelf().InSingletonScope(); _kernel.Bind().ToSelf().InSingletonScope(); _kernel.Bind().ToSelf().InSingletonScope(); - _kernel.Bind().ToSelf().InSingletonScope(); _kernel.Bind().To().InSingletonScope(); _kernel.Bind().ToSelf().InSingletonScope(); _kernel.Bind().ToSelf().InSingletonScope(); diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 8fc58d7c9..9d844f434 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -203,7 +203,6 @@ - diff --git a/NzbDrone.Core/Providers/Jobs/MediaFileScanJob.cs b/NzbDrone.Core/Providers/Jobs/MediaFileScanJob.cs index a53a10672..5638638ad 100644 --- a/NzbDrone.Core/Providers/Jobs/MediaFileScanJob.cs +++ b/NzbDrone.Core/Providers/Jobs/MediaFileScanJob.cs @@ -40,7 +40,7 @@ namespace NzbDrone.Core.Providers.Jobs seriesToScan = new List() { _seriesProvider.GetSeries(targetId) }; } - foreach (var series in seriesToScan) + foreach (var series in seriesToScan.Where(c => c.LastInfoSync != null)) { notification.CurrentMessage = string.Format("Scanning disk for '{0}'", series.Title); _mediaFileProvider.Scan(series); diff --git a/NzbDrone.Core/Providers/MediaFileProvider.cs b/NzbDrone.Core/Providers/MediaFileProvider.cs index 4ddb5de1a..6f1046af2 100644 --- a/NzbDrone.Core/Providers/MediaFileProvider.cs +++ b/NzbDrone.Core/Providers/MediaFileProvider.cs @@ -15,25 +15,27 @@ namespace NzbDrone.Core.Providers private static readonly string[] MediaExtentions = new[] { "*.mkv", "*.avi", "*.wmv", "*.mp4" }; private readonly DiskProvider _diskProvider; private readonly EpisodeProvider _episodeProvider; + private readonly SeriesProvider _seriesProvider; + private readonly SeasonProvider _seasonProvider; private readonly IRepository _repository; public MediaFileProvider(IRepository repository, DiskProvider diskProvider, - EpisodeProvider episodeProvider) + EpisodeProvider episodeProvider, SeriesProvider seriesProvider, SeasonProvider seasonProvider) { _repository = repository; _diskProvider = diskProvider; _episodeProvider = episodeProvider; + _seriesProvider = seriesProvider; + _seasonProvider = seasonProvider; } - public MediaFileProvider() - { - } + public MediaFileProvider() { } /// /// Scans the specified series folder for media files /// /// The series to be scanned - public List Scan(Series series) + public virtual List Scan(Series series) { var mediaFileList = GetMediaFileList(series.Path); var fileList = new List(); @@ -44,28 +46,14 @@ namespace NzbDrone.Core.Providers if (file != null) fileList.Add(file); } - return fileList; - } - /// - /// Scans the specified series folder for media files - /// - /// The series to be scanned - public List Scan(Series series, string path) - { - var mediaFileList = GetMediaFileList(path); - var fileList = new List(); + series.LastDiskSync = DateTime.Now; + _seriesProvider.UpdateSeries(series); - foreach (var filePath in mediaFileList) - { - var file = ImportFile(series, filePath); - if (file != null) - fileList.Add(file); - } return fileList; } - public EpisodeFile ImportFile(Series series, string filePath) + public virtual EpisodeFile ImportFile(Series series, string filePath) { Logger.Trace("Importing file to database [{0}]", filePath); @@ -76,10 +64,11 @@ namespace NzbDrone.Core.Providers //If Size is less than 50MB and contains sample. Check for Size to ensure its not an episode with sample in the title if (size < 40000000 && filePath.ToLower().Contains("sample")) { - Logger.Trace("[{0}] appears to be a sample... skipping.", filePath); + Logger.Trace("[{0}] appears to be a sample. skipping.", filePath); return null; } + //Check to see if file already exists in the database if (!_repository.Exists(e => e.Path == Parser.NormalizePath(filePath))) { var parseResult = Parser.ParseEpisodeInfo(filePath); @@ -90,6 +79,7 @@ namespace NzbDrone.Core.Providers //Stores the list of episodes to add to the EpisodeFile var episodes = new List(); + //Check for daily shows if (parseResult.Episodes == null) { var episode = _episodeProvider.GetEpisode(series.SeriesId, parseResult.AirDate.Date); @@ -98,9 +88,10 @@ namespace NzbDrone.Core.Providers { episodes.Add(episode); } - else + { Logger.Warn("Unable to find '{0}' in the database. File:{1}", parseResult, filePath); + } } else { @@ -113,14 +104,15 @@ namespace NzbDrone.Core.Providers { episodes.Add(episode); } - else + { Logger.Warn("Unable to find '{0}' in the database. File:{1}", parseResult, filePath); + } } } //Return null if no Episodes exist in the DB for the parsed episodes from file - if (episodes.Count < 1) + if (episodes.Count <= 0) return null; var episodeFile = new EpisodeFile(); @@ -160,7 +152,7 @@ namespace NzbDrone.Core.Providers /// Removes files that no longer exist from the database /// /// list of files to verify - public void CleanUp(List files) + public virtual void CleanUp(List files) { //TODO: remove orphaned files. in files table but not linked to from episode table. foreach (var episodeFile in files) @@ -173,30 +165,31 @@ namespace NzbDrone.Core.Providers } } - public void DeleteFromDb(int fileId) + + + public virtual void Update(EpisodeFile episodeFile) { - _repository.Delete(fileId); + _repository.Update(episodeFile); } - public void DeleteFromDisk(int fileId, string path) + public virtual EpisodeFile GetEpisodeFile(int episodeFileId) { - _diskProvider.DeleteFile(path); - _repository.Delete(fileId); + return _repository.Single(episodeFileId); } - public void Update(EpisodeFile episodeFile) + public virtual List GetEpisodeFiles() { - _repository.Update(episodeFile); + return _repository.All().ToList(); } - public EpisodeFile GetEpisodeFile(int episodeFileId) + public virtual IEnumerable GetSeasonFiles(int seasonId) { - return _repository.Single(episodeFileId); + return _seasonProvider.GetSeason(seasonId).Episodes.Where(c => c.EpisodeFile != null).Select(c => c.EpisodeFile); } - public List GetEpisodeFiles() + public virtual IEnumerable GetSeriesFiles(int seriesId) { - return _repository.All().ToList(); + return _seriesProvider.GetSeries(seriesId).Episodes.Where(c => c.EpisodeFile != null).Select(c => c.EpisodeFile); } private List GetMediaFileList(string path) diff --git a/NzbDrone.Core/Repository/Season.cs b/NzbDrone.Core/Repository/Season.cs index f75dff0dd..35baf9bf8 100644 --- a/NzbDrone.Core/Repository/Season.cs +++ b/NzbDrone.Core/Repository/Season.cs @@ -18,9 +18,9 @@ namespace NzbDrone.Core.Repository public DayOfWeek? LastDiskSync { get; set; } [SubSonicToManyRelation] - public virtual List Episodes { get; protected set; } + public virtual List Episodes { get; set; } [SubSonicToOneRelation(ThisClassContainsJoinKey = true)] - public virtual Series Series { get; protected set; } + public virtual Series Series { get; set; } } } \ No newline at end of file diff --git a/NzbDrone.Web/Controllers/SeriesController.cs b/NzbDrone.Web/Controllers/SeriesController.cs index 80ba05d0f..0f716c715 100644 --- a/NzbDrone.Web/Controllers/SeriesController.cs +++ b/NzbDrone.Web/Controllers/SeriesController.cs @@ -76,7 +76,7 @@ namespace NzbDrone.Web.Controllers SeasonNumber = s.SeasonNumber, SeasonString = GetSeasonString(s.SeasonNumber), Monitored = s.Monitored - }).OrderBy(s=> s.SeasonNumber).ToList(); + }).OrderBy(s => s.SeasonNumber).ToList(); return View(model); } @@ -120,7 +120,7 @@ namespace NzbDrone.Web.Controllers //Start removing this series _jobProvider.QueueJob(typeof(DeleteSeriesJob), id); - + var series = GetSeriesModels(seriesInDb); return View(new GridModel(series)); } @@ -265,8 +265,7 @@ namespace NzbDrone.Web.Controllers public ActionResult SyncEpisodesOnDisk(int seriesId) { //Syncs the episodes on disk for the specified series - var series = _seriesProvider.GetSeries(seriesId); - _mediaFileProvider.Scan(series); + _jobProvider.QueueJob(typeof(MediaFileScanJob), seriesId); return RedirectToAction("Details", new { seriesId }); } diff --git a/NzbDrone.sln b/NzbDrone.sln index 16b90b117..5f2f23734 100644 --- a/NzbDrone.sln +++ b/NzbDrone.sln @@ -11,8 +11,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Core.Test", "NzbDr EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{57A04B72-8088-4F75-A582-1158CF8291F7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.PostProcessor", "NzbDrone.PostProcessor\NzbDrone.PostProcessor.csproj", "{0C679573-736D-4F77-B934-FD8931AC1AA1}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -79,17 +77,6 @@ Global {193ADD3B-792B-4173-8E4C-5A3F8F0237F0}.Release|Mixed Platforms.Build.0 = Release|Any CPU {193ADD3B-792B-4173-8E4C-5A3F8F0237F0}.Release|x64.ActiveCfg = Release|Any CPU {193ADD3B-792B-4173-8E4C-5A3F8F0237F0}.Release|x86.ActiveCfg = Release|Any CPU - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Debug|Any CPU.ActiveCfg = Debug|x86 - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Debug|x64.ActiveCfg = Debug|x86 - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Debug|x86.ActiveCfg = Debug|x86 - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Debug|x86.Build.0 = Debug|x86 - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Release|Any CPU.ActiveCfg = Release|x86 - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Release|Mixed Platforms.Build.0 = Release|x86 - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Release|x64.ActiveCfg = Release|x86 - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Release|x86.ActiveCfg = Release|x86 - {0C679573-736D-4F77-B934-FD8931AC1AA1}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE