diff --git a/src/Microsoft.AspNet.SignalR.Core/Microsoft.AspNet.SignalR.Core.csproj b/src/Microsoft.AspNet.SignalR.Core/Microsoft.AspNet.SignalR.Core.csproj index be784e000..f9d7a747e 100644 --- a/src/Microsoft.AspNet.SignalR.Core/Microsoft.AspNet.SignalR.Core.csproj +++ b/src/Microsoft.AspNet.SignalR.Core/Microsoft.AspNet.SignalR.Core.csproj @@ -275,6 +275,7 @@ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Target Name="AfterBuild"> </Target> + <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> diff --git a/src/Microsoft.AspNet.SignalR.Owin/Microsoft.AspNet.SignalR.Owin.csproj b/src/Microsoft.AspNet.SignalR.Owin/Microsoft.AspNet.SignalR.Owin.csproj index c56d9ad68..0f98f2e7e 100644 --- a/src/Microsoft.AspNet.SignalR.Owin/Microsoft.AspNet.SignalR.Owin.csproj +++ b/src/Microsoft.AspNet.SignalR.Owin/Microsoft.AspNet.SignalR.Owin.csproj @@ -101,6 +101,7 @@ </ItemGroup> <Import Project="..\Common\Microsoft.AspNet.SignalR.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> diff --git a/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs b/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs index 279955620..8958fe905 100644 --- a/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs +++ b/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs @@ -1,15 +1,16 @@ using System; using NzbDrone.Api.REST; +using NzbDrone.Core.MediaFiles; namespace NzbDrone.Api.Config { public class MediaManagementConfigResource : RestResource { public Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; } - public Boolean FileDateAiredDate { get; set; } public String RecycleBin { get; set; } public Boolean AutoDownloadPropers { get; set; } public Boolean CreateEmptySeriesFolders { get; set; } + public FileDateType FileDate { get; set; } public Boolean SetPermissionsLinux { get; set; } public String FileChmod { get; set; } diff --git a/src/NzbDrone.Api/Logs/LogFileModule.cs b/src/NzbDrone.Api/Logs/LogFileModule.cs index 544866a1d..5e63bb036 100644 --- a/src/NzbDrone.Api/Logs/LogFileModule.cs +++ b/src/NzbDrone.Api/Logs/LogFileModule.cs @@ -35,7 +35,7 @@ namespace NzbDrone.Api.Logs { Id = i + 1, Filename = Path.GetFileName(file), - LastWriteTime = _diskProvider.GetLastFileWriteUTC(file) + LastWriteTime = _diskProvider.FileGetLastWriteUtc(file) }); } diff --git a/src/NzbDrone.Common.Test/DiskProviderTests/DiskProviderFixtureBase.cs b/src/NzbDrone.Common.Test/DiskProviderTests/DiskProviderFixtureBase.cs index 90ab30574..e4a953fce 100644 --- a/src/NzbDrone.Common.Test/DiskProviderTests/DiskProviderFixtureBase.cs +++ b/src/NzbDrone.Common.Test/DiskProviderTests/DiskProviderFixtureBase.cs @@ -144,7 +144,7 @@ namespace NzbDrone.Common.Test.DiskProviderTests public void empty_folder_should_return_folder_modified_date() { var tempfolder = new DirectoryInfo(TempFolder); - Subject.GetLastFolderWrite(TempFolder).Should().Be(tempfolder.LastWriteTimeUtc); + Subject.FolderGetLastWrite(TempFolder).Should().Be(tempfolder.LastWriteTimeUtc); } [Test] @@ -159,8 +159,8 @@ namespace NzbDrone.Common.Test.DiskProviderTests Subject.WriteAllText(testFile, "Test"); - Subject.GetLastFolderWrite(SandboxFolder).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-1)); - Subject.GetLastFolderWrite(SandboxFolder).Should().BeBefore(DateTime.UtcNow.AddMinutes(1)); + Subject.FolderGetLastWrite(SandboxFolder).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-1)); + Subject.FolderGetLastWrite(SandboxFolder).Should().BeBefore(DateTime.UtcNow.AddMinutes(1)); } [Test] @@ -208,7 +208,7 @@ namespace NzbDrone.Common.Test.DiskProviderTests [Explicit] public void check_last_write() { - Console.WriteLine(Subject.GetLastFolderWrite(_binFolder.FullName)); + Console.WriteLine(Subject.FolderGetLastWrite(_binFolder.FullName)); Console.WriteLine(_binFolder.LastWriteTimeUtc); } diff --git a/src/NzbDrone.Common/Disk/DiskProviderBase.cs b/src/NzbDrone.Common/Disk/DiskProviderBase.cs index 42aadc7c9..98c1c7924 100644 --- a/src/NzbDrone.Common/Disk/DiskProviderBase.cs +++ b/src/NzbDrone.Common/Disk/DiskProviderBase.cs @@ -56,7 +56,7 @@ namespace NzbDrone.Common.Disk return false; } - public DateTime GetLastFolderWrite(string path) + public DateTime FolderGetLastWrite(string path) { Ensure.That(path, () => path).IsValidPath(); @@ -76,14 +76,14 @@ namespace NzbDrone.Common.Disk .Max(c => c.LastWriteTimeUtc); } - public DateTime GetLastFileWrite(string path) + public DateTime FileGetLastWrite(string path) { PathEnsureFileExists(path); return new FileInfo(path).LastWriteTime; } - public DateTime GetLastFileWriteUTC(string path) + public DateTime FileGetLastWriteUtc(string path) { PathEnsureFileExists(path); diff --git a/src/NzbDrone.Common/Disk/IDiskProvider.cs b/src/NzbDrone.Common/Disk/IDiskProvider.cs index fa7abc2b0..896f393bb 100644 --- a/src/NzbDrone.Common/Disk/IDiskProvider.cs +++ b/src/NzbDrone.Common/Disk/IDiskProvider.cs @@ -12,9 +12,9 @@ namespace NzbDrone.Common.Disk void SetPermissions(string path, string mask, string user, string group); long? GetTotalSize(string path); - DateTime GetLastFolderWrite(string path); - DateTime GetLastFileWrite(string path); - DateTime GetLastFileWriteUTC(string path); + DateTime FolderGetLastWrite(string path); + DateTime FileGetLastWrite(string path); + DateTime FileGetLastWriteUtc(string path); void EnsureFolder(string path); bool FolderExists(string path); bool FileExists(string path); diff --git a/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs b/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs index ad3d58fa7..b12c94540 100644 --- a/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs +++ b/src/NzbDrone.Core.Test/MediaCoverTests/MediaCoverServiceFixture.cs @@ -29,7 +29,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests new MediaCover.MediaCover {CoverType = MediaCoverTypes.Banner} }; - Mocker.GetMock<IDiskProvider>().Setup(c => c.GetLastFileWriteUTC(It.IsAny<string>())) + Mocker.GetMock<IDiskProvider>().Setup(c => c.FileGetLastWriteUtc(It.IsAny<string>())) .Returns(new DateTime(1234)); Mocker.GetMock<IDiskProvider>().Setup(c => c.FileExists(It.IsAny<string>())) diff --git a/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/NotUnpackingSpecificationFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/NotUnpackingSpecificationFixture.cs index 275f52601..0f4019163 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/NotUnpackingSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/NotUnpackingSpecificationFixture.cs @@ -42,7 +42,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications private void GivenLastWriteTimeUtc(DateTime time) { Mocker.GetMock<IDiskProvider>() - .Setup(s => s.GetLastFileWriteUTC(It.IsAny<string>())) + .Setup(s => s.FileGetLastWriteUtc(It.IsAny<string>())) .Returns(time); } diff --git a/src/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs b/src/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs index 32b673728..9436770ae 100644 --- a/src/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs +++ b/src/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs @@ -18,19 +18,19 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests private void WithExpired() { - Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>())) + Mocker.GetMock<IDiskProvider>().Setup(s => s.FolderGetLastWrite(It.IsAny<String>())) .Returns(DateTime.UtcNow.AddDays(-10)); - Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFileWriteUTC(It.IsAny<String>())) + Mocker.GetMock<IDiskProvider>().Setup(s => s.FileGetLastWriteUtc(It.IsAny<String>())) .Returns(DateTime.UtcNow.AddDays(-10)); } private void WithNonExpired() { - Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>())) + Mocker.GetMock<IDiskProvider>().Setup(s => s.FolderGetLastWrite(It.IsAny<String>())) .Returns(DateTime.UtcNow.AddDays(-3)); - Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFileWriteUTC(It.IsAny<String>())) + Mocker.GetMock<IDiskProvider>().Setup(s => s.FileGetLastWriteUtc(It.IsAny<String>())) .Returns(DateTime.UtcNow.AddDays(-3)); } diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs index 6a39a8191..2e6d62858 100644 --- a/src/NzbDrone.Core/Configuration/ConfigService.cs +++ b/src/NzbDrone.Core/Configuration/ConfigService.cs @@ -4,9 +4,7 @@ using System.Linq; using NLog; using NzbDrone.Common.EnsureThat; using NzbDrone.Core.Configuration.Events; -using NzbDrone.Core.Download; -using NzbDrone.Core.Download.Clients.Nzbget; -using NzbDrone.Core.Download.Clients.Sabnzbd; +using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Messaging.Events; @@ -86,12 +84,6 @@ namespace NzbDrone.Core.Configuration set { SetValue("AutoUnmonitorPreviouslyDownloadedEpisodes", value); } } - public bool FileDateAiredDate - { - get { return GetValueBoolean("FileDateAiredDate"); } - set { SetValue("FileDateAiredDate", value); } - } - public int Retention { get { return GetValueInt("Retention", 0); } @@ -147,12 +139,18 @@ namespace NzbDrone.Core.Configuration public Boolean CreateEmptySeriesFolders { - //TODO: only create if the parent folder exists (check first) get { return GetValueBoolean("CreateEmptySeriesFolders", false); } set { SetValue("CreateEmptySeriesFolders", value); } } + public FileDateType FileDate + { + get { return GetValueEnum("FileDate", FileDateType.None); } + + set { SetValue("FileDate", value); } + } + public String DownloadClientWorkingFolders { get { return GetValue("DownloadClientWorkingFolders", "_UNPACK_|_FAILED_"); } diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs index 22993f8be..6540ebf45 100644 --- a/src/NzbDrone.Core/Configuration/IConfigService.cs +++ b/src/NzbDrone.Core/Configuration/IConfigService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using NzbDrone.Core.MediaFiles; namespace NzbDrone.Core.Configuration { @@ -20,10 +21,10 @@ namespace NzbDrone.Core.Configuration //Media Management Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; } - Boolean FileDateAiredDate { get; set; } String RecycleBin { get; set; } Boolean AutoDownloadPropers { get; set; } Boolean CreateEmptySeriesFolders { get; set; } + FileDateType FileDate { get; set; } //Permissions (Media Management) Boolean SetPermissionsLinux { get; set; } diff --git a/src/NzbDrone.Core/MediaCover/MediaCoverService.cs b/src/NzbDrone.Core/MediaCover/MediaCoverService.cs index 540d99a76..554a3dc51 100644 --- a/src/NzbDrone.Core/MediaCover/MediaCoverService.cs +++ b/src/NzbDrone.Core/MediaCover/MediaCoverService.cs @@ -67,7 +67,7 @@ namespace NzbDrone.Core.MediaCover if (_diskProvider.FileExists(filePath)) { - var lastWrite = _diskProvider.GetLastFileWriteUTC(filePath); + var lastWrite = _diskProvider.FileGetLastWriteUtc(filePath); mediaCover.Url += "?lastWrite=" + lastWrite.Ticks; } } diff --git a/src/NzbDrone.Core/MediaFiles/Commands/AirDateSeriesCommand.cs b/src/NzbDrone.Core/MediaFiles/Commands/AirDateSeriesCommand.cs deleted file mode 100644 index ed1fd5f81..000000000 --- a/src/NzbDrone.Core/MediaFiles/Commands/AirDateSeriesCommand.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; -using NzbDrone.Core.Messaging.Commands; - -namespace NzbDrone.Core.MediaFiles.Commands -{ - public class AirDateSeriesCommand : Command - { - public List<int> SeriesIds { get; set; } - - public override bool SendUpdatesToClient - { - get - { - return true; - } - } - } -} diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs b/src/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs index df8e3e9f3..95fcd49bc 100644 --- a/src/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs +++ b/src/NzbDrone.Core/MediaFiles/EpisodeFileMovingService.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using NLog; @@ -51,7 +52,7 @@ namespace NzbDrone.Core.MediaFiles _logger.Trace("Renaming episode file: {0} to {1}", episodeFile, filePath); - return MoveFile(episodeFile, series, filePath); + return MoveFile(episodeFile, series, episodes, filePath); } public EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, LocalEpisode localEpisode) @@ -61,10 +62,10 @@ namespace NzbDrone.Core.MediaFiles _logger.Trace("Moving episode file: {0} to {1}", episodeFile, filePath); - return MoveFile(episodeFile, localEpisode.Series, filePath); + return MoveFile(episodeFile, localEpisode.Series, localEpisode.Episodes, filePath); } - private EpisodeFile MoveFile(EpisodeFile episodeFile, Series series, string destinationFilename) + private EpisodeFile MoveFile(EpisodeFile episodeFile, Series series, List<Episode> episodes, string destinationFilename) { Ensure.That(episodeFile, () => episodeFile).IsNotNull(); Ensure.That(series,() => series).IsNotNull(); @@ -105,10 +106,7 @@ namespace NzbDrone.Core.MediaFiles _diskProvider.MoveFile(episodeFile.Path, destinationFilename); episodeFile.Path = destinationFilename; - if (_configService.FileDateAiredDate) - { - _updateEpisodeFileService.ChangeFileDateToAirdate(episodeFile, series); - } + _updateEpisodeFileService.ChangeFileDateForFile(episodeFile, series, episodes); try { diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/NotUnpackingSpecification.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/NotUnpackingSpecification.cs index b3b00a931..129cd07fc 100644 --- a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/NotUnpackingSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/NotUnpackingSpecification.cs @@ -42,7 +42,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications return false; } - if (_diskProvider.GetLastFileWriteUTC(localEpisode.Path) > DateTime.UtcNow.AddMinutes(-5)) + if (_diskProvider.FileGetLastWriteUtc(localEpisode.Path) > DateTime.UtcNow.AddMinutes(-5)) { _logger.Trace("{0} appears to be unpacking still", localEpisode.Path); return false; diff --git a/src/NzbDrone.Core/MediaFiles/Events/SeriesAirDatedEvent.cs b/src/NzbDrone.Core/MediaFiles/Events/SeriesAirDatedEvent.cs deleted file mode 100644 index d830dabb8..000000000 --- a/src/NzbDrone.Core/MediaFiles/Events/SeriesAirDatedEvent.cs +++ /dev/null @@ -1,15 +0,0 @@ -using NzbDrone.Common.Messaging; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Core.MediaFiles.Events -{ - public class SeriesAirDatedEvent : IEvent - { - public Series Series { get; private set; } - - public SeriesAirDatedEvent(Series series) - { - Series = series; - } - } -} diff --git a/src/NzbDrone.Core/MediaFiles/FileDateType.cs b/src/NzbDrone.Core/MediaFiles/FileDateType.cs new file mode 100644 index 000000000..6d78be960 --- /dev/null +++ b/src/NzbDrone.Core/MediaFiles/FileDateType.cs @@ -0,0 +1,9 @@ +namespace NzbDrone.Core.MediaFiles +{ + public enum FileDateType + { + None = 0, + LocalAirDate = 1, + UtcAirDate = 2 + } +} diff --git a/src/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs b/src/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs index a7e546f22..b722df537 100644 --- a/src/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs +++ b/src/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs @@ -128,7 +128,7 @@ namespace NzbDrone.Core.MediaFiles foreach (var folder in _diskProvider.GetDirectories(_configService.RecycleBin)) { - if (_diskProvider.GetLastFolderWrite(folder).AddDays(7) > DateTime.UtcNow) + if (_diskProvider.FolderGetLastWrite(folder).AddDays(7) > DateTime.UtcNow) { logger.Trace("Folder hasn't expired yet, skipping: {0}", folder); continue; @@ -139,7 +139,7 @@ namespace NzbDrone.Core.MediaFiles foreach (var file in _diskProvider.GetFiles(_configService.RecycleBin, SearchOption.TopDirectoryOnly)) { - if (_diskProvider.GetLastFileWriteUTC(file).AddDays(7) > DateTime.UtcNow) + if (_diskProvider.FileGetLastWriteUtc(file).AddDays(7) > DateTime.UtcNow) { logger.Trace("File hasn't expired yet, skipping: {0}", file); continue; diff --git a/src/NzbDrone.Core/MediaFiles/UpdateEpisodeFileService.cs b/src/NzbDrone.Core/MediaFiles/UpdateEpisodeFileService.cs index 318bce24b..735b3bbb0 100644 --- a/src/NzbDrone.Core/MediaFiles/UpdateEpisodeFileService.cs +++ b/src/NzbDrone.Core/MediaFiles/UpdateEpisodeFileService.cs @@ -1,16 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using NLog; +using NzbDrone.Common; using NzbDrone.Common.Disk; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Instrumentation; using NzbDrone.Core.Configuration; using NzbDrone.Core.Instrumentation; -using NzbDrone.Core.MediaFiles.Commands; using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Tv; @@ -18,124 +14,119 @@ namespace NzbDrone.Core.MediaFiles { public interface IUpdateEpisodeFileService { - void ChangeFileDateToAirdate(EpisodeFile episodeFile, Series series); + void ChangeFileDateForFile(EpisodeFile episodeFile, Series series, List<Episode> episodes); } public class UpdateEpisodeFileService : IUpdateEpisodeFileService, - IExecute<AirDateSeriesCommand>, IHandle<SeriesScannedEvent> { private readonly IDiskProvider _diskProvider; private readonly IConfigService _configService; - private readonly ISeriesService _seriesService; private readonly IEpisodeService _episodeService; - private readonly IEventAggregator _eventAggregator; private readonly Logger _logger; public UpdateEpisodeFileService(IDiskProvider diskProvider, IConfigService configService, - ISeriesService seriesService, IEpisodeService episodeService, - IEventAggregator eventAggregator, Logger logger) { _diskProvider = diskProvider; _configService = configService; - _seriesService = seriesService; _episodeService = episodeService; - _eventAggregator = eventAggregator; _logger = logger; } - public void ChangeFileDateToAirdate(EpisodeFile episodeFile, Series series) + public void ChangeFileDateForFile(EpisodeFile episodeFile, Series series, List<Episode> episodes) { - var episode = new Episode(); - episode.AirDate = episodeFile.Episodes.Value.First().AirDate; - episode.EpisodeFile = episodeFile; - episode.EpisodeFileId = 1; - - var episodes = new List<Episode>(); - episodes.Add(episode); - - ChangeFileDateToAirdate(episodes, series); + ChangeFileDate(episodeFile, series, episodes); } - private void ChangeFileDateToAirdate(List<Episode> episodes, Series series) + private bool ChangeFileDate(EpisodeFile episodeFile, Series series, List<Episode> episodes) { - if (!episodes.Any()) + switch (_configService.FileDate) { - _logger.ProgressDebug("{0} has no media files available to update with air dates", series.Title); - } - - else - { - var done = new List<Episode>(); - - _logger.ProgressDebug("{0} ... checking {1} media file dates match air date", series.Title, episodes.Count); - - foreach (var episode in episodes) + case FileDateType.LocalAirDate: { - if (episode.HasFile - && episode.EpisodeFile.IsLoaded - && ChangeFileDate(episode.EpisodeFile.Value.Path, episode.AirDate, series.AirTime)) + var airDate = episodes.First().AirDate; + var airTime = series.AirTime; + + if (airDate.IsNullOrWhiteSpace() || airTime.IsNullOrWhiteSpace()) { - done.Add(episode); + return false; } + + return ChangeFileDateToLocalAirDate(episodeFile.Path, airDate, airTime); } - if (done.Any()) + case FileDateType.UtcAirDate: { - _eventAggregator.PublishEvent(new SeriesAirDatedEvent(series)); - _logger.ProgressDebug("{0} had {1} of {2} media file dates changed to the date and time the episode aired", series.Title, done.Count, episodes.Count); - } + var airDateUtc = episodes.First().AirDateUtc; - else - { - _logger.ProgressDebug("{0} has all its media file dates matching the date each aired", series.Title); + if (!airDateUtc.HasValue) + { + return false; + } + + return ChangeFileDateToUtcAirDate(episodeFile.Path, airDateUtc.Value); } } - } - public void Execute(AirDateSeriesCommand message) - { - var seriesToAirDate = _seriesService.GetSeries(message.SeriesIds); - - foreach (var series in seriesToAirDate) - { - var episodes = _episodeService.EpisodesWithFiles(series.Id); - - ChangeFileDateToAirdate(episodes, series); - } + return false; } public void Handle(SeriesScannedEvent message) { - if (_configService.FileDateAiredDate) - { - var episodes = _episodeService.EpisodesWithFiles(message.Series.Id); + if (_configService.FileDate == FileDateType.None) + { + return; + } - ChangeFileDateToAirdate(episodes, message.Series); - } + var episodes = _episodeService.EpisodesWithFiles(message.Series.Id); + + var episodeFiles = new List<EpisodeFile>(); + var updated = new List<EpisodeFile>(); + + foreach (var group in episodes.GroupBy(e => e.EpisodeFileId)) + { + var episodesInFile = group.Select(e => e).ToList(); + var episodeFile = episodesInFile.First().EpisodeFile; + + episodeFiles.Add(episodeFile); + + if (ChangeFileDate(episodeFile, message.Series, episodesInFile)) + { + updated.Add(episodeFile); + } + } + + if (updated.Any()) + { + _logger.ProgressDebug("Changed file date for {0} files of {1} in {2}", updated.Count, episodeFiles.Count, message.Series.Title); + } + + else + { + _logger.ProgressDebug("No file dates changed for {0}", message.Series.Title); + } } - private bool ChangeFileDate(String filePath, String fileDate, String fileTime) + private bool ChangeFileDateToLocalAirDate(string filePath, string fileDate, string fileTime) { - DateTime dateTime, oldDateTime; - bool result = false; + DateTime airDate; - if (DateTime.TryParse(fileDate + ' ' + fileTime, out dateTime)) + if (DateTime.TryParse(fileDate + ' ' + fileTime, out airDate)) { // avoiding false +ve checks and set date skewing by not using UTC (Windows) - oldDateTime = _diskProvider.GetLastFileWrite(filePath); + DateTime oldDateTime = _diskProvider.FileGetLastWriteUtc(filePath); - if (!DateTime.Equals(dateTime, oldDateTime)) + if (!DateTime.Equals(airDate, oldDateTime)) { try { - _diskProvider.FileSetLastWriteTime(filePath, dateTime); - _diskProvider.FileSetLastAccessTime(filePath, dateTime); - _logger.Info("Date of file [{0}] changed from \"{1}\" to \"{2}\"", filePath, oldDateTime, dateTime); - result = true; + _diskProvider.FileSetLastWriteTime(filePath, airDate); + _logger.Debug("Date of file [{0}] changed from '{1}' to '{2}'", filePath, oldDateTime, airDate); + + return true; } catch (Exception ex) @@ -147,10 +138,33 @@ namespace NzbDrone.Core.MediaFiles else { - _logger.Warn("Could not create valid date to set [{0}]", filePath); + _logger.Debug("Could not create valid date to change file [{0}]", filePath); } - return result; + return false; + } + + private bool ChangeFileDateToUtcAirDate(string filePath, DateTime airDateUtc) + { + DateTime oldLastWrite = _diskProvider.FileGetLastWriteUtc(filePath); + + if (!DateTime.Equals(airDateUtc, oldLastWrite)) + { + try + { + _diskProvider.FileSetLastWriteTime(filePath, airDateUtc); + _logger.Debug("Date of file [{0}] changed from '{1}' to '{2}'", filePath, oldLastWrite, airDateUtc); + + return true; + } + + catch (Exception ex) + { + _logger.WarnException("Unable to set date of file [" + filePath + "]", ex); + } + } + + return false; } } } diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index bf7965de1..63df96700 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -308,7 +308,6 @@ <Compile Include="Instrumentation\Commands\DeleteLogFilesCommand.cs" /> <Compile Include="Instrumentation\Commands\TrimLogCommand.cs" /> <Compile Include="Instrumentation\DeleteLogFilesService.cs" /> - <Compile Include="MediaFiles\Commands\AirDateSeriesCommand.cs" /> <Compile Include="MediaFiles\Commands\RenameSeriesCommand.cs" /> <Compile Include="MediaFiles\Commands\RescanSeriesCommand.cs" /> <Compile Include="Lifecycle\Commands\ShutdownCommand.cs" /> @@ -319,7 +318,7 @@ <Compile Include="MediaFiles\EpisodeFileMoveResult.cs" /> <Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecification.cs" /> <Compile Include="MediaFiles\Events\SeriesScannedEvent.cs" /> - <Compile Include="MediaFiles\Events\SeriesAirDatedEvent.cs" /> + <Compile Include="MediaFiles\FileDateType.cs" /> <Compile Include="MediaFiles\MediaFileExtensions.cs" /> <Compile Include="MediaFiles\MediaInfo\VideoFileInfoReader.cs" /> <Compile Include="MediaFiles\RenameEpisodeFilePreview.cs" /> diff --git a/src/UI/Series/Editor/UpdateFiles/UpdateFilesSeriesView.js b/src/UI/Series/Editor/Organize/OrganizeFilesView.js similarity index 56% rename from src/UI/Series/Editor/UpdateFiles/UpdateFilesSeriesView.js rename to src/UI/Series/Editor/Organize/OrganizeFilesView.js index e0e7b55ba..4be006dde 100644 --- a/src/UI/Series/Editor/UpdateFiles/UpdateFilesSeriesView.js +++ b/src/UI/Series/Editor/Organize/OrganizeFilesView.js @@ -9,11 +9,10 @@ define( ], function (_, vent, Backbone, Marionette, CommandController) { return Marionette.ItemView.extend({ - template: 'Series/Editor/UpdateFiles/UpdateFilesSeriesViewTemplate', + template: 'Series/Editor/Organize/OrganizeFilesViewTemplate', events: { - 'click .x-confirm-rename': '_rename', - 'click .x-confirm-airdate': '_setFileAirDate' + 'click .x-confirm-organize': '_organize' }, initialize: function (options) { @@ -22,7 +21,7 @@ define( this.templateHelpers = { numberOfSeries: this.series.length, series: new Backbone.Collection(this.series).toJSON() }; }, - _rename: function () { + _organize: function () { var seriesIds = _.pluck(this.series, 'id'); CommandController.Execute('renameSeries', { @@ -30,19 +29,7 @@ define( seriesIds : seriesIds }); - this.trigger('updatingFiles'); - vent.trigger(vent.Commands.CloseModalCommand); - }, - - _setFileAirDate: function () { - var seriesIds = _.pluck(this.series, 'id'); - - CommandController.Execute('AirDateSeries', { - name: 'AirDateSeries', - seriesIds: seriesIds - }); - - this.trigger('updatingFiles'); + this.trigger('organizingFiles'); vent.trigger(vent.Commands.CloseModalCommand); } }); diff --git a/src/UI/Series/Editor/UpdateFiles/UpdateFilesSeriesViewTemplate.html b/src/UI/Series/Editor/Organize/OrganizeFilesViewTemplate.html similarity index 79% rename from src/UI/Series/Editor/UpdateFiles/UpdateFilesSeriesViewTemplate.html rename to src/UI/Series/Editor/Organize/OrganizeFilesViewTemplate.html index 836c70310..09465b198 100644 --- a/src/UI/Series/Editor/UpdateFiles/UpdateFilesSeriesViewTemplate.html +++ b/src/UI/Series/Editor/Organize/OrganizeFilesViewTemplate.html @@ -1,6 +1,6 @@ <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> - <h3>Update Files of Selected Series</h3> + <h3>Organize of Selected Series</h3> </div> <div class="modal-body update-files-series-modal"> <div class="alert alert-info"> @@ -19,6 +19,5 @@ </div> <div class="modal-footer"> <button class="btn" data-dismiss="modal">cancel</button> - <button class="btn btn-danger x-confirm-rename">rename</button> - <button class="btn btn-danger x-confirm-airdate">set file date to air date</button> + <button class="btn btn-danger x-confirm-organize">organize</button> </div> diff --git a/src/UI/Series/Editor/SeriesEditorFooterView.js b/src/UI/Series/Editor/SeriesEditorFooterView.js index 0efc65562..4a33d51f6 100644 --- a/src/UI/Series/Editor/SeriesEditorFooterView.js +++ b/src/UI/Series/Editor/SeriesEditorFooterView.js @@ -10,7 +10,7 @@ define( 'AddSeries/RootFolders/RootFolderCollection', 'Shared/Toolbar/ToolbarLayout', 'AddSeries/RootFolders/RootFolderLayout', - 'Series/Editor/UpdateFiles/UpdateFilesSeriesView', + 'Series/Editor/Organize/OrganizeFilesView', 'Config' ], function (_, Marionette, @@ -27,20 +27,20 @@ define( template: 'Series/Editor/SeriesEditorFooterViewTemplate', ui: { - monitored : '.x-monitored', - qualityProfile : '.x-quality-profiles', - seasonFolder : '.x-season-folder', - rootFolder : '.x-root-folder', - selectedCount : '.x-selected-count', - saveButton : '.x-save', - updateFilesButton: '.x-update-files', - container : '.series-editor-footer' + monitored : '.x-monitored', + qualityProfile : '.x-quality-profiles', + seasonFolder : '.x-season-folder', + rootFolder : '.x-root-folder', + selectedCount : '.x-selected-count', + saveButton : '.x-save', + organizeFilesButton : '.x-organize-files', + container : '.series-editor-footer' }, events: { - 'click .x-save' : '_updateAndSave', - 'change .x-root-folder': '_rootFolderChanged', - 'click .x-update-files': '_updateFiles' + 'click .x-save' : '_updateAndSave', + 'change .x-root-folder' : '_rootFolderChanged', + 'click .x-organize-files' : '_organizeFiles' }, templateHelpers: function () { @@ -119,7 +119,7 @@ define( this.ui.seasonFolder.attr('disabled', ''); this.ui.rootFolder.attr('disabled', ''); this.ui.saveButton.attr('disabled', ''); - this.ui.updateFilesButton.attr('disabled', ''); + this.ui.organizeFilesButton.attr('disabled', ''); } else { @@ -128,7 +128,7 @@ define( this.ui.seasonFolder.removeAttr('disabled', ''); this.ui.rootFolder.removeAttr('disabled', ''); this.ui.saveButton.removeAttr('disabled', ''); - this.ui.updateFilesButton.removeAttr('disabled', ''); + this.ui.organizeFilesButton.removeAttr('disabled', ''); } }, @@ -162,7 +162,7 @@ define( }); }, - _updateFiles: function () { + _organizeFiles: function () { var selected = this.editorGrid.getSelectedModels(); var updateFilesSeriesView = new UpdateFilesSeriesView({ series: selected }); this.listenToOnce(updateFilesSeriesView, 'updatingFiles', this._afterSave); diff --git a/src/UI/Series/Editor/SeriesEditorFooterViewTemplate.html b/src/UI/Series/Editor/SeriesEditorFooterViewTemplate.html index 48995092d..b6827fbb5 100644 --- a/src/UI/Series/Editor/SeriesEditorFooterViewTemplate.html +++ b/src/UI/Series/Editor/SeriesEditorFooterViewTemplate.html @@ -45,7 +45,7 @@ <span class="pull-right"> <span class="selected-count x-selected-count">0 series selected</span> <button class="btn btn-primary x-save">Save</button> - <button class="btn btn-danger x-update-files">Update Files</button> + <button class="btn btn-danger x-organize-files">Organize</button> </span> </div> </div> \ No newline at end of file diff --git a/src/UI/Settings/MediaManagement/FileManagement/FileManagementViewTemplate.html b/src/UI/Settings/MediaManagement/FileManagement/FileManagementViewTemplate.html index 0d1339c57..6e7de342c 100644 --- a/src/UI/Settings/MediaManagement/FileManagement/FileManagementViewTemplate.html +++ b/src/UI/Settings/MediaManagement/FileManagement/FileManagementViewTemplate.html @@ -21,23 +21,6 @@ </div> </div> - <div class="control-group"> - <label class="control-label">Set File Date to Airdate</label> - <div class="controls"> - <label class="checkbox toggle well"> - <input type="checkbox" name="fileDateAiredDate" /> - <p> - <span>Yes</span> - <span>No</span> - </p> - <div class="btn btn-primary slide-button" /> - </label> - <span class="help-inline-checkbox"> - <i class="icon-nd-form-info" title="Adjust added media file dates to the original episode aired date" /> - </span> - </div> - </div> - <div class="control-group"> <label class="control-label">Download Propers</label> @@ -68,4 +51,19 @@ </span> </div> </div> + + <div class="control-group"> + <label class="control-label">Change File Date</label> + + <div class="controls"> + <select class="inputClass" name="fileDate"> + <option value="none">None</option> + <option value="localAirDate">Local Air Date</option> + <option value="utcAirDate">UTC Air Date</option> + </select> + <span class="help-inline"> + <i class="icon-nd-form-info" title="Change file date on import/rescan"/> + </span> + </div> + </div> </fieldset>