Merge branch 'AirDate' of https://github.com/JackDandy/NzbDrone into set-file-date

This commit is contained in:
Mark McDowall 2014-03-11 22:16:38 -07:00
commit 8478379ff4
24 changed files with 316 additions and 38 deletions

View File

@ -6,6 +6,7 @@ namespace NzbDrone.Api.Config
public class MediaManagementConfigResource : RestResource public class MediaManagementConfigResource : RestResource
{ {
public Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; } public Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
public Boolean FileDateAiredDate { get; set; }
public String RecycleBin { get; set; } public String RecycleBin { get; set; }
public Boolean AutoDownloadPropers { get; set; } public Boolean AutoDownloadPropers { get; set; }
public Boolean CreateEmptySeriesFolders { get; set; } public Boolean CreateEmptySeriesFolders { get; set; }

View File

@ -35,7 +35,7 @@ namespace NzbDrone.Api.Logs
{ {
Id = i + 1, Id = i + 1,
Filename = Path.GetFileName(file), Filename = Path.GetFileName(file),
LastWriteTime = _diskProvider.GetLastFileWrite(file) LastWriteTime = _diskProvider.GetLastFileWriteUTC(file)
}); });
} }

View File

@ -77,6 +77,20 @@ namespace NzbDrone.Common.Disk
} }
public DateTime GetLastFileWrite(string path) public DateTime GetLastFileWrite(string path)
{
PathEnsureFileExists(path);
return new FileInfo(path).LastWriteTime;
}
public DateTime GetLastFileWriteUTC(string path)
{
PathEnsureFileExists(path);
return new FileInfo(path).LastWriteTimeUtc;
}
private void PathEnsureFileExists(string path)
{ {
Ensure.That(path, () => path).IsValidPath(); Ensure.That(path, () => path).IsValidPath();
@ -84,8 +98,6 @@ namespace NzbDrone.Common.Disk
{ {
throw new FileNotFoundException("File doesn't exist: " + path); throw new FileNotFoundException("File doesn't exist: " + path);
} }
return new FileInfo(path).LastWriteTimeUtc;
} }
public void EnsureFolder(string path) public void EnsureFolder(string path)
@ -305,6 +317,26 @@ namespace NzbDrone.Common.Disk
Directory.SetLastWriteTimeUtc(path, dateTime); Directory.SetLastWriteTimeUtc(path, dateTime);
} }
public void FileSetLastWriteTime(string path, DateTime dateTime)
{
Ensure.That(path, () => path).IsValidPath();
File.SetLastWriteTime(path, dateTime);
}
public void FileSetLastAccessTime(string path, DateTime dateTime)
{
Ensure.That(path, () => path).IsValidPath();
File.SetLastAccessTimeUtc(path, dateTime);
}
public void FileSetLastAccessTimeUtc(string path, DateTime dateTime)
{
Ensure.That(path, () => path).IsValidPath();
File.SetLastAccessTimeUtc(path, dateTime);
}
public bool IsFileLocked(string file) public bool IsFileLocked(string file)
{ {
try try

View File

@ -14,6 +14,7 @@ namespace NzbDrone.Common.Disk
DateTime GetLastFolderWrite(string path); DateTime GetLastFolderWrite(string path);
DateTime GetLastFileWrite(string path); DateTime GetLastFileWrite(string path);
DateTime GetLastFileWriteUTC(string path);
void EnsureFolder(string path); void EnsureFolder(string path);
bool FolderExists(string path); bool FolderExists(string path);
bool FileExists(string path); bool FileExists(string path);
@ -33,6 +34,8 @@ namespace NzbDrone.Common.Disk
void WriteAllText(string filename, string contents); void WriteAllText(string filename, string contents);
void FileSetLastWriteTimeUtc(string path, DateTime dateTime); void FileSetLastWriteTimeUtc(string path, DateTime dateTime);
void FolderSetLastWriteTimeUtc(string path, DateTime dateTime); void FolderSetLastWriteTimeUtc(string path, DateTime dateTime);
void FileSetLastWriteTime(string path, DateTime dateTime);
void FileSetLastAccessTime(string path, DateTime dateTime);
bool IsFileLocked(string path); bool IsFileLocked(string path);
string GetPathRoot(string path); string GetPathRoot(string path);
string GetParentFolder(string path); string GetParentFolder(string path);

View File

@ -29,7 +29,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
new MediaCover.MediaCover {CoverType = MediaCoverTypes.Banner} new MediaCover.MediaCover {CoverType = MediaCoverTypes.Banner}
}; };
Mocker.GetMock<IDiskProvider>().Setup(c => c.GetLastFileWrite(It.IsAny<string>())) Mocker.GetMock<IDiskProvider>().Setup(c => c.GetLastFileWriteUTC(It.IsAny<string>()))
.Returns(new DateTime(1234)); .Returns(new DateTime(1234));
Mocker.GetMock<IDiskProvider>().Setup(c => c.FileExists(It.IsAny<string>())) Mocker.GetMock<IDiskProvider>().Setup(c => c.FileExists(It.IsAny<string>()))

View File

@ -42,7 +42,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
private void GivenLastWriteTimeUtc(DateTime time) private void GivenLastWriteTimeUtc(DateTime time)
{ {
Mocker.GetMock<IDiskProvider>() Mocker.GetMock<IDiskProvider>()
.Setup(s => s.GetLastFileWrite(It.IsAny<string>())) .Setup(s => s.GetLastFileWriteUTC(It.IsAny<string>()))
.Returns(time); .Returns(time);
} }

View File

@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>())) Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow.AddDays(-10)); .Returns(DateTime.UtcNow.AddDays(-10));
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>())) Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFileWriteUTC(It.IsAny<String>()))
.Returns(DateTime.UtcNow.AddDays(-10)); .Returns(DateTime.UtcNow.AddDays(-10));
} }
@ -30,7 +30,7 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>())) Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow.AddDays(-3)); .Returns(DateTime.UtcNow.AddDays(-3));
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>())) Mocker.GetMock<IDiskProvider>().Setup(s => s.GetLastFileWriteUTC(It.IsAny<String>()))
.Returns(DateTime.UtcNow.AddDays(-3)); .Returns(DateTime.UtcNow.AddDays(-3));
} }

View File

@ -86,6 +86,12 @@ namespace NzbDrone.Core.Configuration
set { SetValue("AutoUnmonitorPreviouslyDownloadedEpisodes", value); } set { SetValue("AutoUnmonitorPreviouslyDownloadedEpisodes", value); }
} }
public bool FileDateAiredDate
{
get { return GetValueBoolean("FileDateAiredDate"); }
set { SetValue("FileDateAiredDate", value); }
}
public int Retention public int Retention
{ {
get { return GetValueInt("Retention", 0); } get { return GetValueInt("Retention", 0); }

View File

@ -20,6 +20,7 @@ namespace NzbDrone.Core.Configuration
//Media Management //Media Management
Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; } Boolean AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
Boolean FileDateAiredDate { get; set; }
String RecycleBin { get; set; } String RecycleBin { get; set; }
Boolean AutoDownloadPropers { get; set; } Boolean AutoDownloadPropers { get; set; }
Boolean CreateEmptySeriesFolders { get; set; } Boolean CreateEmptySeriesFolders { get; set; }

View File

@ -67,7 +67,7 @@ namespace NzbDrone.Core.MediaCover
if (_diskProvider.FileExists(filePath)) if (_diskProvider.FileExists(filePath))
{ {
var lastWrite = _diskProvider.GetLastFileWrite(filePath); var lastWrite = _diskProvider.GetLastFileWriteUTC(filePath);
mediaCover.Url += "?lastWrite=" + lastWrite.Ticks; mediaCover.Url += "?lastWrite=" + lastWrite.Ticks;
} }
} }

View File

@ -0,0 +1,18 @@
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;
}
}
}
}

View File

@ -22,18 +22,21 @@ namespace NzbDrone.Core.MediaFiles
public class EpisodeFileMovingService : IMoveEpisodeFiles public class EpisodeFileMovingService : IMoveEpisodeFiles
{ {
private readonly IEpisodeService _episodeService; private readonly IEpisodeService _episodeService;
private readonly IUpdateEpisodeFileService _updateEpisodeFileService;
private readonly IBuildFileNames _buildFileNames; private readonly IBuildFileNames _buildFileNames;
private readonly IDiskProvider _diskProvider; private readonly IDiskProvider _diskProvider;
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly Logger _logger; private readonly Logger _logger;
public EpisodeFileMovingService(IEpisodeService episodeService, public EpisodeFileMovingService(IEpisodeService episodeService,
IUpdateEpisodeFileService updateEpisodeFileService,
IBuildFileNames buildFileNames, IBuildFileNames buildFileNames,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IConfigService configService, IConfigService configService,
Logger logger) Logger logger)
{ {
_episodeService = episodeService; _episodeService = episodeService;
_updateEpisodeFileService = updateEpisodeFileService;
_buildFileNames = buildFileNames; _buildFileNames = buildFileNames;
_diskProvider = diskProvider; _diskProvider = diskProvider;
_configService = configService; _configService = configService;
@ -102,6 +105,11 @@ namespace NzbDrone.Core.MediaFiles
_diskProvider.MoveFile(episodeFile.Path, destinationFilename); _diskProvider.MoveFile(episodeFile.Path, destinationFilename);
episodeFile.Path = destinationFilename; episodeFile.Path = destinationFilename;
if (_configService.FileDateAiredDate)
{
_updateEpisodeFileService.ChangeFileDateToAirdate(episodeFile, series);
}
try try
{ {
_logger.Trace("Setting last write time on series folder: {0}", series.Path); _logger.Trace("Setting last write time on series folder: {0}", series.Path);

View File

@ -42,7 +42,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
return false; return false;
} }
if (_diskProvider.GetLastFileWrite(localEpisode.Path) > DateTime.UtcNow.AddMinutes(-5)) if (_diskProvider.GetLastFileWriteUTC(localEpisode.Path) > DateTime.UtcNow.AddMinutes(-5))
{ {
_logger.Trace("{0} appears to be unpacking still", localEpisode.Path); _logger.Trace("{0} appears to be unpacking still", localEpisode.Path);
return false; return false;

View File

@ -0,0 +1,15 @@
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;
}
}
}

View File

@ -139,7 +139,7 @@ namespace NzbDrone.Core.MediaFiles
foreach (var file in _diskProvider.GetFiles(_configService.RecycleBin, SearchOption.TopDirectoryOnly)) foreach (var file in _diskProvider.GetFiles(_configService.RecycleBin, SearchOption.TopDirectoryOnly))
{ {
if (_diskProvider.GetLastFileWrite(file).AddDays(7) > DateTime.UtcNow) if (_diskProvider.GetLastFileWriteUTC(file).AddDays(7) > DateTime.UtcNow)
{ {
logger.Trace("File hasn't expired yet, skipping: {0}", file); logger.Trace("File hasn't expired yet, skipping: {0}", file);
continue; continue;

View File

@ -0,0 +1,156 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
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;
namespace NzbDrone.Core.MediaFiles
{
public interface IUpdateEpisodeFileService
{
void ChangeFileDateToAirdate(EpisodeFile episodeFile, Series series);
}
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)
{
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);
}
private void ChangeFileDateToAirdate(List<Episode> episodes, Series series)
{
if (!episodes.Any())
{
_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)
{
if (episode.HasFile
&& episode.EpisodeFile.IsLoaded
&& ChangeFileDate(episode.EpisodeFile.Value.Path, episode.AirDate, series.AirTime))
{
done.Add(episode);
}
}
if (done.Any())
{
_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);
}
else
{
_logger.ProgressDebug("{0} has all its media file dates matching the date each aired", series.Title);
}
}
}
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);
}
}
public void Handle(SeriesScannedEvent message)
{
if (_configService.FileDateAiredDate)
{
var episodes = _episodeService.EpisodesWithFiles(message.Series.Id);
ChangeFileDateToAirdate(episodes, message.Series);
}
}
private bool ChangeFileDate(String filePath, String fileDate, String fileTime)
{
DateTime dateTime, oldDateTime;
bool result = false;
if (DateTime.TryParse(fileDate + ' ' + fileTime, out dateTime))
{
// avoiding false +ve checks and set date skewing by not using UTC (Windows)
oldDateTime = _diskProvider.GetLastFileWrite(filePath);
if (!DateTime.Equals(dateTime, 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;
}
catch (Exception ex)
{
_logger.WarnException("Unable to set date of file [" + filePath + "]", ex);
}
}
}
else
{
_logger.Warn("Could not create valid date to set [{0}]", filePath);
}
return result;
}
}
}

View File

@ -78,7 +78,7 @@ namespace NzbDrone.Core.MetadataSource
series.Overview = show.overview; series.Overview = show.overview;
series.Runtime = show.runtime; series.Runtime = show.runtime;
series.Network = show.network; series.Network = show.network;
series.AirTime = show.air_time_utc; series.AirTime = show.air_time;
series.TitleSlug = show.url.ToLower().Replace("http://trakt.tv/show/", ""); series.TitleSlug = show.url.ToLower().Replace("http://trakt.tv/show/", "");
series.Status = GetSeriesStatus(show.status, show.ended); series.Status = GetSeriesStatus(show.status, show.ended);
series.Ratings = GetRatings(show.ratings); series.Ratings = GetRatings(show.ratings);

View File

@ -308,6 +308,7 @@
<Compile Include="Instrumentation\Commands\DeleteLogFilesCommand.cs" /> <Compile Include="Instrumentation\Commands\DeleteLogFilesCommand.cs" />
<Compile Include="Instrumentation\Commands\TrimLogCommand.cs" /> <Compile Include="Instrumentation\Commands\TrimLogCommand.cs" />
<Compile Include="Instrumentation\DeleteLogFilesService.cs" /> <Compile Include="Instrumentation\DeleteLogFilesService.cs" />
<Compile Include="MediaFiles\Commands\AirDateSeriesCommand.cs" />
<Compile Include="MediaFiles\Commands\RenameSeriesCommand.cs" /> <Compile Include="MediaFiles\Commands\RenameSeriesCommand.cs" />
<Compile Include="MediaFiles\Commands\RescanSeriesCommand.cs" /> <Compile Include="MediaFiles\Commands\RescanSeriesCommand.cs" />
<Compile Include="Lifecycle\Commands\ShutdownCommand.cs" /> <Compile Include="Lifecycle\Commands\ShutdownCommand.cs" />
@ -318,9 +319,11 @@
<Compile Include="MediaFiles\EpisodeFileMoveResult.cs" /> <Compile Include="MediaFiles\EpisodeFileMoveResult.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecification.cs" /> <Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecification.cs" />
<Compile Include="MediaFiles\Events\SeriesScannedEvent.cs" /> <Compile Include="MediaFiles\Events\SeriesScannedEvent.cs" />
<Compile Include="MediaFiles\Events\SeriesAirDatedEvent.cs" />
<Compile Include="MediaFiles\MediaFileExtensions.cs" /> <Compile Include="MediaFiles\MediaFileExtensions.cs" />
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReader.cs" /> <Compile Include="MediaFiles\MediaInfo\VideoFileInfoReader.cs" />
<Compile Include="MediaFiles\RenameEpisodeFilePreview.cs" /> <Compile Include="MediaFiles\RenameEpisodeFilePreview.cs" />
<Compile Include="MediaFiles\UpdateEpisodeFileService.cs" />
<Compile Include="Messaging\Commands\CommandExecutor.cs" /> <Compile Include="Messaging\Commands\CommandExecutor.cs" />
<Compile Include="Messaging\Commands\ICommandExecutor.cs" /> <Compile Include="Messaging\Commands\ICommandExecutor.cs" />
<Compile Include="Messaging\Commands\IExecute.cs" /> <Compile Include="Messaging\Commands\IExecute.cs" />

View File

@ -10,7 +10,7 @@ define(
'AddSeries/RootFolders/RootFolderCollection', 'AddSeries/RootFolders/RootFolderCollection',
'Shared/Toolbar/ToolbarLayout', 'Shared/Toolbar/ToolbarLayout',
'AddSeries/RootFolders/RootFolderLayout', 'AddSeries/RootFolders/RootFolderLayout',
'Series/Editor/Rename/RenameSeriesView', 'Series/Editor/UpdateFiles/UpdateFilesSeriesView',
'Config' 'Config'
], function (_, ], function (_,
Marionette, Marionette,
@ -21,26 +21,26 @@ define(
RootFolders, RootFolders,
ToolbarLayout, ToolbarLayout,
RootFolderLayout, RootFolderLayout,
RenameSeriesView, UpdateFilesSeriesView,
Config) { Config) {
return Marionette.ItemView.extend({ return Marionette.ItemView.extend({
template: 'Series/Editor/SeriesEditorFooterViewTemplate', template: 'Series/Editor/SeriesEditorFooterViewTemplate',
ui: { ui: {
monitored : '.x-monitored', monitored : '.x-monitored',
qualityProfile: '.x-quality-profiles', qualityProfile : '.x-quality-profiles',
seasonFolder : '.x-season-folder', seasonFolder : '.x-season-folder',
rootFolder : '.x-root-folder', rootFolder : '.x-root-folder',
selectedCount : '.x-selected-count', selectedCount : '.x-selected-count',
saveButton : '.x-save', saveButton : '.x-save',
renameButton : '.x-rename', updateFilesButton: '.x-update-files',
container : '.series-editor-footer' container : '.series-editor-footer'
}, },
events: { events: {
'click .x-save' : '_updateAndSave', 'click .x-save' : '_updateAndSave',
'change .x-root-folder': '_rootFolderChanged', 'change .x-root-folder': '_rootFolderChanged',
'click .x-rename' : '_rename' 'click .x-update-files': '_updateFiles'
}, },
templateHelpers: function () { templateHelpers: function () {
@ -119,7 +119,7 @@ define(
this.ui.seasonFolder.attr('disabled', ''); this.ui.seasonFolder.attr('disabled', '');
this.ui.rootFolder.attr('disabled', ''); this.ui.rootFolder.attr('disabled', '');
this.ui.saveButton.attr('disabled', ''); this.ui.saveButton.attr('disabled', '');
this.ui.renameButton.attr('disabled', ''); this.ui.updateFilesButton.attr('disabled', '');
} }
else { else {
@ -128,7 +128,7 @@ define(
this.ui.seasonFolder.removeAttr('disabled', ''); this.ui.seasonFolder.removeAttr('disabled', '');
this.ui.rootFolder.removeAttr('disabled', ''); this.ui.rootFolder.removeAttr('disabled', '');
this.ui.saveButton.removeAttr('disabled', ''); this.ui.saveButton.removeAttr('disabled', '');
this.ui.renameButton.removeAttr('disabled', ''); this.ui.updateFilesButton.removeAttr('disabled', '');
} }
}, },
@ -162,12 +162,12 @@ define(
}); });
}, },
_rename: function () { _updateFiles: function () {
var selected = this.editorGrid.getSelectedModels(); var selected = this.editorGrid.getSelectedModels();
var renameSeriesView = new RenameSeriesView({ series: selected }); var updateFilesSeriesView = new UpdateFilesSeriesView({ series: selected });
this.listenToOnce(renameSeriesView, 'seriesRenamed', this._afterSave); this.listenToOnce(updateFilesSeriesView, 'updatingFiles', this._afterSave);
vent.trigger(vent.Commands.OpenModalCommand, renameSeriesView); vent.trigger(vent.Commands.OpenModalCommand, updateFilesSeriesView);
} }
}); });
}); });

View File

@ -45,7 +45,7 @@
<span class="pull-right"> <span class="pull-right">
<span class="selected-count x-selected-count">0 series selected</span> <span class="selected-count x-selected-count">0 series selected</span>
<button class="btn btn-primary x-save">Save</button> <button class="btn btn-primary x-save">Save</button>
<button class="btn btn-danger x-rename">Rename</button> <button class="btn btn-danger x-update-files">Update Files</button>
</span> </span>
</div> </div>
</div> </div>

View File

@ -9,10 +9,11 @@ define(
], function (_, vent, Backbone, Marionette, CommandController) { ], function (_, vent, Backbone, Marionette, CommandController) {
return Marionette.ItemView.extend({ return Marionette.ItemView.extend({
template: 'Series/Editor/Rename/RenameSeriesViewTemplate', template: 'Series/Editor/UpdateFiles/UpdateFilesSeriesViewTemplate',
events: { events: {
'click .x-confirm-rename': '_rename' 'click .x-confirm-rename': '_rename',
'click .x-confirm-airdate': '_setFileAirDate'
}, },
initialize: function (options) { initialize: function (options) {
@ -29,7 +30,19 @@ define(
seriesIds : seriesIds seriesIds : seriesIds
}); });
this.trigger('seriesRenamed'); 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');
vent.trigger(vent.Commands.CloseModalCommand); vent.trigger(vent.Commands.CloseModalCommand);
} }
}); });

View File

@ -1,14 +1,14 @@
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>Rename Selected Series</h3> <h3>Update Files of Selected Series</h3>
</div> </div>
<div class="modal-body rename-series-modal"> <div class="modal-body update-files-series-modal">
<div class="alert alert-info"> <div class="alert alert-info">
<button type="button" class="close" data-dismiss="alert">&times;</button> <button type="button" class="close" data-dismiss="alert">&times;</button>
You can use the rename function for an individual series to preview the rename Tip: To preview a rename... select "Cancel" then any series title and use the <i data-original-title="" class="icon-nd-rename" title=""></i>
</div> </div>
Are you sure you want to rename all files in the {{numberOfSeries}} selected series? Are you sure you want to update all files in the {{numberOfSeries}} selected series?
{{debug}} {{debug}}
<ul class="selected-series"> <ul class="selected-series">
@ -20,4 +20,5 @@
<div class="modal-footer"> <div class="modal-footer">
<button class="btn" data-dismiss="modal">cancel</button> <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-rename">rename</button>
<button class="btn btn-danger x-confirm-airdate">set file date to air date</button>
</div> </div>

View File

@ -314,9 +314,13 @@
.row { .row {
margin-left: -40px; margin-left: -40px;
} }
.span2 {
width: 160px;
}
} }
.rename-series-modal { .update-files-series-modal {
.selected-series { .selected-series {
margin-top: 15px; margin-top: 15px;
} }

View File

@ -21,6 +21,23 @@
</div> </div>
</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"> <div class="control-group">
<label class="control-label">Download Propers</label> <label class="control-label">Download Propers</label>